Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/pci-2.6
authorLinus Torvalds <torvalds@woody.osdl.org>
Thu, 21 Dec 2006 08:01:47 +0000 (00:01 -0800)
committerLinus Torvalds <torvalds@woody.osdl.org>
Thu, 21 Dec 2006 08:01:47 +0000 (00:01 -0800)
* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/pci-2.6: (22 commits)
  acpiphp: Link-time error for PCI Hotplug
  shpchp: cleanup shpchp.h
  shpchp: remove shpchprm_get_physical_slot_number
  shpchp: cleanup struct controller
  shpchp: remove unnecessary struct php_ctlr
  PCI: ATI sb600 sata quirk
  PCI legacy resource fix
  PCI: don't export device IDs to userspace
  PCI: Be a bit defensive in quirk_nvidia_ck804() so we don't risk dereferencing a NULL pdev.
  PCI: Fix multiple problems with VIA hardware
  PCI: Only check the HT capability bits in mpic.c
  PCI: Use pci_find_ht_capability() in drivers/pci/quirks.c
  PCI: Add #defines for Hypertransport MSI fields
  PCI: Use pci_find_ht_capability() in drivers/pci/htirq.c
  PCI: Add pci_find_ht_capability() for finding Hypertransport capabilities
  PCI: Create __pci_bus_find_cap_start() from __pci_bus_find_cap()
  pci: Introduce pci_find_present
  PCI: pcieport-driver: remove invalid warning message
  rpaphp: compiler warning cleanup
  PCI quirks: remove redundant check
  ...

23 files changed:
arch/i386/pci/fixup.c
arch/powerpc/sysdev/mpic.c
drivers/ide/pci/atiixp.c
drivers/pci/hotplug/acpiphp_glue.c
drivers/pci/hotplug/rpaphp_slot.c
drivers/pci/hotplug/shpchp.h
drivers/pci/hotplug/shpchp_core.c
drivers/pci/hotplug/shpchp_ctrl.c
drivers/pci/hotplug/shpchp_hpc.c
drivers/pci/htirq.c
drivers/pci/pci-driver.c
drivers/pci/pci.c
drivers/pci/pcie/portdrv_pci.c
drivers/pci/probe.c
drivers/pci/quirks.c
drivers/pci/search.c
drivers/pci/setup-res.c
include/asm-generic/vmlinux.lds.h
include/linux/Kbuild
include/linux/ioport.h
include/linux/pci.h
include/linux/pci_ids.h
include/linux/pci_regs.h

index cde1170..8053b17 100644 (file)
@@ -115,7 +115,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, pci
 #define VIA_8363_KL133_REVISION_ID 0x81
 #define VIA_8363_KM133_REVISION_ID 0x84
 
-static void __devinit pci_fixup_via_northbridge_bug(struct pci_dev *d)
+static void pci_fixup_via_northbridge_bug(struct pci_dev *d)
 {
        u8 v;
        u8 revision;
@@ -151,6 +151,10 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, pci_fixup_
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8622, pci_fixup_via_northbridge_bug);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, pci_fixup_via_northbridge_bug);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8367_0, pci_fixup_via_northbridge_bug);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, pci_fixup_via_northbridge_bug);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8622, pci_fixup_via_northbridge_bug);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, pci_fixup_via_northbridge_bug);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8367_0, pci_fixup_via_northbridge_bug);
 
 /*
  * For some reasons Intel decided that certain parts of their
@@ -181,7 +185,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_fixup_transparent_
  * issue another HALT within 80 ns of the initial HALT, the failure condition
  * is avoided.
  */
-static void __init pci_fixup_nforce2(struct pci_dev *dev)
+static void pci_fixup_nforce2(struct pci_dev *dev)
 {
        u32 val;
 
@@ -204,6 +208,7 @@ static void __init pci_fixup_nforce2(struct pci_dev *dev)
        }
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2, pci_fixup_nforce2);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2, pci_fixup_nforce2);
 
 /* Max PCI Express root ports */
 #define MAX_PCIEROOT   6
@@ -419,7 +424,7 @@ DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_TI, 0x8032,
  * Prevent the BIOS trapping accesses to the Cyrix CS5530A video device
  * configuration space.
  */
-static void __devinit pci_early_fixup_cyrix_5530(struct pci_dev *dev)
+static void pci_early_fixup_cyrix_5530(struct pci_dev *dev)
 {
        u8 r;
        /* clear 'F4 Video Configuration Trap' bit */
@@ -429,3 +434,5 @@ static void __devinit pci_early_fixup_cyrix_5530(struct pci_dev *dev)
 }
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY,
                        pci_early_fixup_cyrix_5530);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY,
+                       pci_early_fixup_cyrix_5530);
index 411480d..d01ced1 100644 (file)
@@ -390,7 +390,7 @@ static void __init mpic_scan_ht_pic(struct mpic *mpic, u8 __iomem *devbase,
                u8 id = readb(devbase + pos + PCI_CAP_LIST_ID);
                if (id == PCI_CAP_ID_HT) {
                        id = readb(devbase + pos + 3);
-                       if (id == HT_CAPTYPE_IRQ)
+                       if ((id & HT_5BIT_CAP_MASK) == HT_CAPTYPE_IRQ)
                                break;
                }
        }
index d55b938..ffdffb6 100644 (file)
@@ -368,7 +368,6 @@ static struct pci_device_id atiixp_pci_tbl[] = {
        { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
        { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
        { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-       { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, PCI_ANY_ID, PCI_ANY_ID, (PCI_CLASS_STORAGE_IDE<<8)|0x8a, 0xffff05, 1},
        { 0, },
 };
 MODULE_DEVICE_TABLE(pci, atiixp_pci_tbl);
index 0b9d0db..bd1faeb 100644 (file)
@@ -1682,7 +1682,7 @@ int __init acpiphp_glue_init(void)
  *
  * This function frees all data allocated in acpiphp_glue_init()
  */
-void __exit acpiphp_glue_exit(void)
+void  acpiphp_glue_exit(void)
 {
        acpi_pci_unregister_driver(&acpi_pci_hp_driver);
 }
index b771196..3009193 100644 (file)
@@ -47,21 +47,11 @@ static ssize_t location_read_file (struct hotplug_slot *php_slot, char *buf)
        return retval;
 }
 
-static struct hotplug_slot_attribute hotplug_slot_attr_location = {
+static struct hotplug_slot_attribute php_attr_location = {
        .attr = {.name = "phy_location", .mode = S_IFREG | S_IRUGO},
        .show = location_read_file,
 };
 
-static void rpaphp_sysfs_add_attr_location (struct hotplug_slot *slot)
-{
-       sysfs_create_file(&slot->kobj, &hotplug_slot_attr_location.attr);
-}
-
-static void rpaphp_sysfs_remove_attr_location (struct hotplug_slot *slot)
-{
-       sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_location.attr);
-}
-
 /* free up the memory used by a slot */
 static void rpaphp_release_slot(struct hotplug_slot *hotplug_slot)
 {
@@ -145,7 +135,7 @@ int rpaphp_deregister_slot(struct slot *slot)
        list_del(&slot->rpaphp_slot_list);
        
        /* remove "phy_location" file */
-       rpaphp_sysfs_remove_attr_location(php_slot);
+       sysfs_remove_file(&php_slot->kobj, &php_attr_location.attr);
 
        retval = pci_hp_deregister(php_slot);
        if (retval)
@@ -160,36 +150,45 @@ EXPORT_SYMBOL_GPL(rpaphp_deregister_slot);
 
 int rpaphp_register_slot(struct slot *slot)
 {
+       struct hotplug_slot *php_slot = slot->hotplug_slot;
        int retval;
 
        dbg("%s registering slot:path[%s] index[%x], name[%s] pdomain[%x] type[%d]\n", 
                __FUNCTION__, slot->dn->full_name, slot->index, slot->name, 
                slot->power_domain, slot->type);
+
        /* should not try to register the same slot twice */
-       if (is_registered(slot)) { /* should't be here */
+       if (is_registered(slot)) {
                err("rpaphp_register_slot: slot[%s] is already registered\n", slot->name);
-               rpaphp_release_slot(slot->hotplug_slot);
-               return -EAGAIN;
+               retval = -EAGAIN;
+               goto register_fail;
        }       
-       retval = pci_hp_register(slot->hotplug_slot);
+
+       retval = pci_hp_register(php_slot);
        if (retval) {
                err("pci_hp_register failed with error %d\n", retval);
-               rpaphp_release_slot(slot->hotplug_slot);
-               return retval;
+               goto register_fail;
        }
-       
-       /* create "phy_locatoin" file */
-       rpaphp_sysfs_add_attr_location(slot->hotplug_slot);     
 
-       /* add slot to our internal list */
-       dbg("%s adding slot[%s] to rpaphp_slot_list\n",
-           __FUNCTION__, slot->name);
+       /* create "phy_location" file */
+       retval = sysfs_create_file(&php_slot->kobj, &php_attr_location.attr);
+       if (retval) {
+               err("sysfs_create_file failed with error %d\n", retval);
+               goto sysfs_fail;
+       }
 
+       /* add slot to our internal list */
        list_add(&slot->rpaphp_slot_list, &rpaphp_slot_head);
        info("Slot [%s](PCI location=%s) registered\n", slot->name,
                        slot->location);
        num_slots++;
        return 0;
+
+sysfs_fail:
+       pci_hp_deregister(php_slot);
+register_fail:
+       rpaphp_release_slot(php_slot);
+       return retval;
 }
 
 int rpaphp_get_power_status(struct slot *slot, u8 * value)
index 5075769..3ca6a4f 100644 (file)
@@ -47,11 +47,17 @@ extern int shpchp_poll_time;
 extern int shpchp_debug;
 extern struct workqueue_struct *shpchp_wq;
 
-/*#define dbg(format, arg...) do { if (shpchp_debug) printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); } while (0)*/
-#define dbg(format, arg...) do { if (shpchp_debug) printk("%s: " format, MY_NAME , ## arg); } while (0)
-#define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME , ## arg)
-#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
-#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
+#define dbg(format, arg...)                                            \
+       do {                                                            \
+               if (shpchp_debug)                                       \
+                       printk("%s: " format, MY_NAME , ## arg);        \
+       } while (0)
+#define err(format, arg...)                                            \
+       printk(KERN_ERR "%s: " format, MY_NAME , ## arg)
+#define info(format, arg...)                                           \
+       printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
+#define warn(format, arg...)                                           \
+       printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
 
 #define SLOT_NAME_SIZE 10
 struct slot {
@@ -83,34 +89,27 @@ struct event_info {
 struct controller {
        struct mutex crit_sect;         /* critical section mutex */
        struct mutex cmd_lock;          /* command lock */
-       struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */
        int num_slots;                  /* Number of slots on ctlr */
        int slot_num_inc;               /* 1 or -1 */
        struct pci_dev *pci_dev;
        struct list_head slot_list;
        struct hpc_ops *hpc_ops;
        wait_queue_head_t queue;        /* sleep & wake process */
-       u8 bus;
-       u8 device;
-       u8 function;
        u8 slot_device_offset;
-       u8 add_support;
        u32 pcix_misc2_reg;     /* for amd pogo errata */
-       enum pci_bus_speed speed;
        u32 first_slot;         /* First physical slot number */
-       u8 slot_bus;            /* Bus where the slots handled by this controller sit */
        u32 cap_offset;
        unsigned long mmio_base;
        unsigned long mmio_size;
+       void __iomem *creg;
+       struct timer_list poll_timer;
 };
 
-
 /* Define AMD SHPC ID  */
 #define PCI_DEVICE_ID_AMD_GOLAM_7450   0x7450 
 #define PCI_DEVICE_ID_AMD_POGO_7458    0x7458
 
 /* AMD PCIX bridge registers */
-
 #define PCIX_MEM_BASE_LIMIT_OFFSET     0x1C
 #define PCIX_MISCII_OFFSET             0x48
 #define PCIX_MISC_BRIDGE_ERRORS_OFFSET 0x80
@@ -145,8 +144,6 @@ struct controller {
 #define POWERON_STATE                  3
 #define POWEROFF_STATE                 4
 
-#define PCI_TO_PCI_BRIDGE_CLASS                0x00060400
-
 /* Error messages */
 #define INTERLOCK_OPEN                 0x00000002
 #define ADD_NOT_SUPPORTED              0x00000003
@@ -158,50 +155,32 @@ struct controller {
 #define WRONG_BUS_FREQUENCY            0x0000000D
 #define POWER_FAILURE                  0x0000000E
 
-#define REMOVE_NOT_SUPPORTED           0x00000003
-
-#define DISABLE_CARD                   1
-
-/*
- * error Messages
- */
-#define msg_initialization_err "Initialization failure, error=%d\n"
-#define msg_button_on          "PCI slot #%s - powering on due to button press.\n"
-#define msg_button_off         "PCI slot #%s - powering off due to button press.\n"
-#define msg_button_cancel      "PCI slot #%s - action canceled due to button press.\n"
-
-/* sysfs functions for the hotplug controller info */
 extern int __must_check shpchp_create_ctrl_files(struct controller *ctrl);
-
-extern int     shpchp_sysfs_enable_slot(struct slot *slot);
-extern int     shpchp_sysfs_disable_slot(struct slot *slot);
-
-extern u8      shpchp_handle_attention_button(u8 hp_slot, void *inst_id);
-extern u8      shpchp_handle_switch_change(u8 hp_slot, void *inst_id);
-extern u8      shpchp_handle_presence_change(u8 hp_slot, void *inst_id);
-extern u8      shpchp_handle_power_fault(u8 hp_slot, void *inst_id);
-
-/* pci functions */
-extern int     shpchp_save_config(struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num);
-extern int     shpchp_configure_device(struct slot *p_slot);
-extern int     shpchp_unconfigure_device(struct slot *p_slot);
-extern void    shpchp_remove_ctrl_files(struct controller *ctrl);
-extern void    cleanup_slots(struct controller *ctrl);
-extern void    queue_pushbutton_work(struct work_struct *work);
-
+extern void shpchp_remove_ctrl_files(struct controller *ctrl);
+extern int shpchp_sysfs_enable_slot(struct slot *slot);
+extern int shpchp_sysfs_disable_slot(struct slot *slot);
+extern u8 shpchp_handle_attention_button(u8 hp_slot, struct controller *ctrl);
+extern u8 shpchp_handle_switch_change(u8 hp_slot, struct controller *ctrl);
+extern u8 shpchp_handle_presence_change(u8 hp_slot, struct controller *ctrl);
+extern u8 shpchp_handle_power_fault(u8 hp_slot, struct controller *ctrl);
+extern int shpchp_configure_device(struct slot *p_slot);
+extern int shpchp_unconfigure_device(struct slot *p_slot);
+extern void cleanup_slots(struct controller *ctrl);
+extern void queue_pushbutton_work(struct work_struct *work);
+extern int shpc_init( struct controller *ctrl, struct pci_dev *pdev);
 
 #ifdef CONFIG_ACPI
 static inline int get_hp_params_from_firmware(struct pci_dev *dev,
-                       struct hotplug_params *hpp)
+                                             struct hotplug_params *hpp)
 {
        if (ACPI_FAILURE(acpi_get_hp_params_from_firmware(dev->bus, hpp)))
                        return -ENODEV;
        return 0;
 }
-#define get_hp_hw_control_from_firmware(pdev) \
-       do { \
-               if (DEVICE_ACPI_HANDLE(&(pdev->dev))) \
-                       acpi_run_oshp(DEVICE_ACPI_HANDLE(&(pdev->dev))); \
+#define get_hp_hw_control_from_firmware(pdev)                          \
+       do {                                                            \
+               if (DEVICE_ACPI_HANDLE(&(pdev->dev)))                   \
+                       acpi_run_oshp(DEVICE_ACPI_HANDLE(&(pdev->dev)));\
        } while (0)
 #else
 #define get_hp_params_from_firmware(dev, hpp) (-ENODEV)
@@ -222,108 +201,40 @@ struct ctrl_reg {
        volatile u32 serr_loc;
        volatile u32 serr_intr_enable;
        volatile u32 slot1;
-       volatile u32 slot2;
-       volatile u32 slot3;
-       volatile u32 slot4;
-       volatile u32 slot5;
-       volatile u32 slot6;
-       volatile u32 slot7;
-       volatile u32 slot8;
-       volatile u32 slot9;
-       volatile u32 slot10;
-       volatile u32 slot11;
-       volatile u32 slot12;
 } __attribute__ ((packed));
 
 /* offsets to the controller registers based on the above structure layout */
 enum ctrl_offsets {
-       BASE_OFFSET =   offsetof(struct ctrl_reg, base_offset),
-       SLOT_AVAIL1 =   offsetof(struct ctrl_reg, slot_avail1),
-       SLOT_AVAIL2     =       offsetof(struct ctrl_reg, slot_avail2),
-       SLOT_CONFIG =   offsetof(struct ctrl_reg, slot_config),
-       SEC_BUS_CONFIG =        offsetof(struct ctrl_reg, sec_bus_config),
-       MSI_CTRL        =       offsetof(struct ctrl_reg, msi_ctrl),
-       PROG_INTERFACE =        offsetof(struct ctrl_reg, prog_interface),
-       CMD             =       offsetof(struct ctrl_reg, cmd),
-       CMD_STATUS      =       offsetof(struct ctrl_reg, cmd_status),
-       INTR_LOC        =       offsetof(struct ctrl_reg, intr_loc),
-       SERR_LOC        =       offsetof(struct ctrl_reg, serr_loc),
-       SERR_INTR_ENABLE =      offsetof(struct ctrl_reg, serr_intr_enable),
-       SLOT1 =         offsetof(struct ctrl_reg, slot1),
-       SLOT2 =         offsetof(struct ctrl_reg, slot2),
-       SLOT3 =         offsetof(struct ctrl_reg, slot3),
-       SLOT4 =         offsetof(struct ctrl_reg, slot4),
-       SLOT5 =         offsetof(struct ctrl_reg, slot5),
-       SLOT6 =         offsetof(struct ctrl_reg, slot6),               
-       SLOT7 =         offsetof(struct ctrl_reg, slot7),
-       SLOT8 =         offsetof(struct ctrl_reg, slot8),
-       SLOT9 =         offsetof(struct ctrl_reg, slot9),
-       SLOT10 =        offsetof(struct ctrl_reg, slot10),
-       SLOT11 =        offsetof(struct ctrl_reg, slot11),
-       SLOT12 =        offsetof(struct ctrl_reg, slot12),
-};
-typedef u8(*php_intr_callback_t) (u8 hp_slot, void *instance_id);
-struct php_ctlr_state_s {
-       struct php_ctlr_state_s *pnext;
-       struct pci_dev *pci_dev;
-       unsigned int irq;
-       unsigned long flags;    /* spinlock's */
-       u32 slot_device_offset;
-       u32 num_slots;
-       struct timer_list       int_poll_timer; /* Added for poll event */
-       php_intr_callback_t attention_button_callback;
-       php_intr_callback_t switch_change_callback;
-       php_intr_callback_t presence_change_callback;
-       php_intr_callback_t power_fault_callback;
-       void *callback_instance_id;
-       void __iomem *creg;                     /* Ptr to controller register space */
+       BASE_OFFSET      = offsetof(struct ctrl_reg, base_offset),
+       SLOT_AVAIL1      = offsetof(struct ctrl_reg, slot_avail1),
+       SLOT_AVAIL2      = offsetof(struct ctrl_reg, slot_avail2),
+       SLOT_CONFIG      = offsetof(struct ctrl_reg, slot_config),
+       SEC_BUS_CONFIG   = offsetof(struct ctrl_reg, sec_bus_config),
+       MSI_CTRL         = offsetof(struct ctrl_reg, msi_ctrl),
+       PROG_INTERFACE   = offsetof(struct ctrl_reg, prog_interface),
+       CMD              = offsetof(struct ctrl_reg, cmd),
+       CMD_STATUS       = offsetof(struct ctrl_reg, cmd_status),
+       INTR_LOC         = offsetof(struct ctrl_reg, intr_loc),
+       SERR_LOC         = offsetof(struct ctrl_reg, serr_loc),
+       SERR_INTR_ENABLE = offsetof(struct ctrl_reg, serr_intr_enable),
+       SLOT1            = offsetof(struct ctrl_reg, slot1),
 };
-/* Inline functions */
 
-
-/* Inline functions to check the sanity of a pointer that is passed to us */
-static inline int slot_paranoia_check (struct slot *slot, const char *function)
-{
-       if (!slot) {
-               dbg("%s - slot == NULL", function);
-               return -1;
-       }
-       if (!slot->hotplug_slot) {
-               dbg("%s - slot->hotplug_slot == NULL!", function);
-               return -1;
-       }
-       return 0;
-}
-
-static inline struct slot *get_slot (struct hotplug_slot *hotplug_slot, const char *function)
+static inline struct slot *get_slot(struct hotplug_slot *hotplug_slot)
 { 
-       struct slot *slot;
-
-       if (!hotplug_slot) {
-               dbg("%s - hotplug_slot == NULL\n", function);
-               return NULL;
-       }
-
-       slot = (struct slot *)hotplug_slot->private;
-       if (slot_paranoia_check (slot, function))
-                return NULL;
-       return slot;
+       return hotplug_slot->private;
 }
 
-static inline struct slot *shpchp_find_slot (struct controller *ctrl, u8 device)
+static inline struct slot *shpchp_find_slot(struct controller *ctrl, u8 device)
 {
        struct slot *slot;
 
-       if (!ctrl)
-               return NULL;
-
        list_for_each_entry(slot, &ctrl->slot_list, slot_list) {
                if (slot->device == device)
                        return slot;
        }
 
        err("%s: slot (device=0x%x) not found\n", __FUNCTION__, device);
-
        return NULL;
 }
 
@@ -400,44 +311,27 @@ static inline void amd_pogo_errata_restore_misc_reg(struct slot *p_slot)
        pci_write_config_dword(p_slot->ctrl->pci_dev, PCIX_MISCII_OFFSET, pcix_misc2_temp);
 }
 
-enum php_ctlr_type {
-       PCI,
-       ISA,
-       ACPI
-};
-
-int shpc_init( struct controller *ctrl, struct pci_dev *pdev);
-
-int shpc_get_ctlr_slot_config( struct controller *ctrl,
-               int *num_ctlr_slots,
-               int *first_device_num,
-               int *physical_slot_num,
-               int *updown,
-               int *flags);
-
 struct hpc_ops {
-       int     (*power_on_slot )               (struct slot *slot);
-       int     (*slot_enable )                 (struct slot *slot);
-       int     (*slot_disable )                (struct slot *slot);
-       int     (*set_bus_speed_mode)   (struct slot *slot, enum pci_bus_speed speed);
-       int     (*get_power_status)             (struct slot *slot, u8 *status);
-       int     (*get_attention_status) (struct slot *slot, u8 *status);
-       int     (*set_attention_status) (struct slot *slot, u8 status);
-       int     (*get_latch_status)             (struct slot *slot, u8 *status);
-       int     (*get_adapter_status)   (struct slot *slot, u8 *status);
-
-       int     (*get_max_bus_speed)    (struct slot *slot, enum pci_bus_speed *speed);
-       int     (*get_cur_bus_speed)    (struct slot *slot, enum pci_bus_speed *speed);
-       int     (*get_adapter_speed)    (struct slot *slot, enum pci_bus_speed *speed);
-       int     (*get_mode1_ECC_cap)    (struct slot *slot, u8 *mode);
-       int     (*get_prog_int)                 (struct slot *slot, u8 *prog_int);
-
-       int     (*query_power_fault)    (struct slot *slot);
-       void    (*green_led_on)         (struct slot *slot);
-       void    (*green_led_off)        (struct slot *slot);
-       void    (*green_led_blink)      (struct slot *slot);
-       void    (*release_ctlr)         (struct controller *ctrl);
-       int (*check_cmd_status)         (struct controller *ctrl);
+       int (*power_on_slot)(struct slot *slot);
+       int (*slot_enable)(struct slot *slot);
+       int (*slot_disable)(struct slot *slot);
+       int (*set_bus_speed_mode)(struct slot *slot, enum pci_bus_speed speed);
+       int (*get_power_status)(struct slot *slot, u8 *status);
+       int (*get_attention_status)(struct slot *slot, u8 *status);
+       int (*set_attention_status)(struct slot *slot, u8 status);
+       int (*get_latch_status)(struct slot *slot, u8 *status);
+       int (*get_adapter_status)(struct slot *slot, u8 *status);
+       int (*get_max_bus_speed)(struct slot *slot, enum pci_bus_speed *speed);
+       int (*get_cur_bus_speed)(struct slot *slot, enum pci_bus_speed *speed);
+       int (*get_adapter_speed)(struct slot *slot, enum pci_bus_speed *speed);
+       int (*get_mode1_ECC_cap)(struct slot *slot, u8 *mode);
+       int (*get_prog_int)(struct slot *slot, u8 *prog_int);
+       int (*query_power_fault)(struct slot *slot);
+       void (*green_led_on)(struct slot *slot);
+       void (*green_led_off)(struct slot *slot);
+       void (*green_led_blink)(struct slot *slot);
+       void (*release_ctlr)(struct controller *ctrl);
+       int (*check_cmd_status)(struct controller *ctrl);
 };
 
 #endif                         /* _SHPCHP_H */
index 4eac85b..590cd3c 100644 (file)
@@ -104,23 +104,6 @@ static void make_slot_name(struct slot *slot)
                 slot->bus, slot->number);
 }
 
-
-
-
-static int
-shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun,
-                               u8 busnum, u8 devnum)
-{
-       int offset = devnum - ctrl->slot_device_offset;
-
-       dbg("%s: ctrl->slot_num_inc %d, offset %d\n", __FUNCTION__,
-                       ctrl->slot_num_inc, offset);
-       *sun = (u8) (ctrl->first_slot + ctrl->slot_num_inc *offset);
-       return 0;
-}
-
-
-
 static int init_slots(struct controller *ctrl)
 {
        struct slot *slot;
@@ -128,7 +111,6 @@ static int init_slots(struct controller *ctrl)
        struct hotplug_slot_info *info;
        int retval = -ENOMEM;
        int i;
-       u32 sun;
 
        for (i = 0; i < ctrl->num_slots; i++) {
                slot = kzalloc(sizeof(*slot), GFP_KERNEL);
@@ -149,16 +131,11 @@ static int init_slots(struct controller *ctrl)
 
                slot->hp_slot = i;
                slot->ctrl = ctrl;
-               slot->bus = ctrl->slot_bus;
+               slot->bus = ctrl->pci_dev->subordinate->number;
                slot->device = ctrl->slot_device_offset + i;
                slot->hpc_ops = ctrl->hpc_ops;
+               slot->number = ctrl->first_slot + (ctrl->slot_num_inc * i);
                mutex_init(&slot->lock);
-
-               if (shpchprm_get_physical_slot_number(ctrl, &sun,
-                                                     slot->bus, slot->device))
-                       goto error_info;
-
-               slot->number = sun;
                INIT_DELAYED_WORK(&slot->work, queue_pushbutton_work);
 
                /* register this slot with the hotplug pci core */
@@ -211,42 +188,12 @@ void cleanup_slots(struct controller *ctrl)
        }
 }
 
-static int get_ctlr_slot_config(struct controller *ctrl)
-{
-       int num_ctlr_slots;
-       int first_device_num;
-       int physical_slot_num;
-       int updown;
-       int rc;
-       int flags;
-
-       rc = shpc_get_ctlr_slot_config(ctrl, &num_ctlr_slots,
-                                      &first_device_num, &physical_slot_num,
-                                      &updown, &flags);
-       if (rc) {
-               err("%s: get_ctlr_slot_config fail for b:d (%x:%x)\n",
-                   __FUNCTION__, ctrl->bus, ctrl->device);
-               return -1;
-       }
-
-       ctrl->num_slots = num_ctlr_slots;
-       ctrl->slot_device_offset = first_device_num;
-       ctrl->first_slot = physical_slot_num;
-       ctrl->slot_num_inc = updown;            /* either -1 or 1 */
-
-       dbg("%s: num_slot(0x%x) 1st_dev(0x%x) psn(0x%x) updown(%d) for b:d "
-           "(%x:%x)\n", __FUNCTION__, num_ctlr_slots, first_device_num,
-           physical_slot_num, updown, ctrl->bus, ctrl->device);
-
-       return 0;
-}
-
 /*
  * set_attention_status - Turns the Amber LED for a slot on, off or blink
  */
 static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status)
 {
-       struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+       struct slot *slot = get_slot(hotplug_slot);
 
        dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
 
@@ -258,7 +205,7 @@ static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status)
 
 static int enable_slot (struct hotplug_slot *hotplug_slot)
 {
-       struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+       struct slot *slot = get_slot(hotplug_slot);
 
        dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
 
@@ -267,7 +214,7 @@ static int enable_slot (struct hotplug_slot *hotplug_slot)
 
 static int disable_slot (struct hotplug_slot *hotplug_slot)
 {
-       struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+       struct slot *slot = get_slot(hotplug_slot);
 
        dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
 
@@ -276,7 +223,7 @@ static int disable_slot (struct hotplug_slot *hotplug_slot)
 
 static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value)
 {
-       struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+       struct slot *slot = get_slot(hotplug_slot);
        int retval;
 
        dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
@@ -290,7 +237,7 @@ static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value)
 
 static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value)
 {
-       struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+       struct slot *slot = get_slot(hotplug_slot);
        int retval;
 
        dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
@@ -304,7 +251,7 @@ static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value)
 
 static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value)
 {
-       struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+       struct slot *slot = get_slot(hotplug_slot);
        int retval;
 
        dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
@@ -318,7 +265,7 @@ static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value)
 
 static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value)
 {
-       struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+       struct slot *slot = get_slot(hotplug_slot);
        int retval;
 
        dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
@@ -332,7 +279,7 @@ static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value)
 
 static int get_address (struct hotplug_slot *hotplug_slot, u32 *value)
 {
-       struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+       struct slot *slot = get_slot(hotplug_slot);
        struct pci_bus *bus = slot->ctrl->pci_dev->subordinate;
 
        dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
@@ -344,7 +291,7 @@ static int get_address (struct hotplug_slot *hotplug_slot, u32 *value)
 
 static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
 {
-       struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+       struct slot *slot = get_slot(hotplug_slot);
        int retval;
 
        dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
@@ -358,7 +305,7 @@ static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_sp
 
 static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
 {
-       struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
+       struct slot *slot = get_slot(hotplug_slot);
        int retval;
 
        dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
@@ -385,9 +332,6 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        int rc;
        struct controller *ctrl;
-       struct slot *t_slot;
-       int first_device_num;   /* first PCI device number */
-       int num_ctlr_slots;     /* number of slots implemented */
 
        if (!is_shpc_capable(pdev))
                return -ENODEV;
@@ -408,47 +352,13 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        pci_set_drvdata(pdev, ctrl);
 
-       ctrl->bus = pdev->bus->number;
-       ctrl->slot_bus = pdev->subordinate->number;
-       ctrl->device = PCI_SLOT(pdev->devfn);
-       ctrl->function = PCI_FUNC(pdev->devfn);
-
-       dbg("ctrl bus=0x%x, device=%x, function=%x, irq=%x\n",
-           ctrl->bus, ctrl->device, ctrl->function, pdev->irq);
-
-       /*
-        * Save configuration headers for this and subordinate PCI buses
-        */
-       rc = get_ctlr_slot_config(ctrl);
-       if (rc) {
-               err(msg_initialization_err, rc);
-               goto err_out_release_ctlr;
-       }
-       first_device_num = ctrl->slot_device_offset;
-       num_ctlr_slots = ctrl->num_slots;
-
-       ctrl->add_support = 1;
-
        /* Setup the slot information structures */
        rc = init_slots(ctrl);
        if (rc) {
-               err(msg_initialization_err, 6);
+               err("%s: slot initialization failed\n", SHPC_MODULE_NAME);
                goto err_out_release_ctlr;
        }
 
-       /* Now hpc_functions (slot->hpc_ops->functions) are ready  */
-       t_slot = shpchp_find_slot(ctrl, first_device_num);
-
-       /* Check for operation bus speed */
-       rc = t_slot->hpc_ops->get_cur_bus_speed(t_slot, &ctrl->speed);
-       dbg("%s: t_slot->hp_slot %x\n", __FUNCTION__,t_slot->hp_slot);
-
-       if (rc || ctrl->speed == PCI_SPEED_UNKNOWN) {
-               err(SHPC_MODULE_NAME ": Can't get current bus speed. "
-                   "Set to 33MHz PCI.\n");
-               ctrl->speed = PCI_SPEED_33MHz;
-       }
-
        rc = shpchp_create_ctrl_files(ctrl);
        if (rc)
                goto err_cleanup_slots;
index 158ac78..6bb8473 100644 (file)
@@ -57,9 +57,8 @@ static int queue_interrupt_event(struct slot *p_slot, u32 event_type)
        return 0;
 }
 
-u8 shpchp_handle_attention_button(u8 hp_slot, void *inst_id)
+u8 shpchp_handle_attention_button(u8 hp_slot, struct controller *ctrl)
 {
-       struct controller *ctrl = (struct controller *) inst_id;
        struct slot *p_slot;
        u32 event_type;
 
@@ -81,9 +80,8 @@ u8 shpchp_handle_attention_button(u8 hp_slot, void *inst_id)
 
 }
 
-u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id)
+u8 shpchp_handle_switch_change(u8 hp_slot, struct controller *ctrl)
 {
-       struct controller *ctrl = (struct controller *) inst_id;
        struct slot *p_slot;
        u8 getstatus;
        u32 event_type;
@@ -120,9 +118,8 @@ u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id)
        return 1;
 }
 
-u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id)
+u8 shpchp_handle_presence_change(u8 hp_slot, struct controller *ctrl)
 {
-       struct controller *ctrl = (struct controller *) inst_id;
        struct slot *p_slot;
        u32 event_type;
 
@@ -154,9 +151,8 @@ u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id)
        return 1;
 }
 
-u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id)
+u8 shpchp_handle_power_fault(u8 hp_slot, struct controller *ctrl)
 {
-       struct controller *ctrl = (struct controller *) inst_id;
        struct slot *p_slot;
        u32 event_type;
 
@@ -497,10 +493,12 @@ static void handle_button_press_event(struct slot *p_slot)
                p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
                if (getstatus) {
                        p_slot->state = BLINKINGOFF_STATE;
-                       info(msg_button_off, p_slot->name);
+                       info("PCI slot #%s - powering off due to button "
+                            "press.\n", p_slot->name);
                } else {
                        p_slot->state = BLINKINGON_STATE;
-                       info(msg_button_on, p_slot->name);
+                       info("PCI slot #%s - powering on due to button "
+                            "press.\n", p_slot->name);
                }
                /* blink green LED and turn off amber */
                p_slot->hpc_ops->green_led_blink(p_slot);
@@ -523,7 +521,8 @@ static void handle_button_press_event(struct slot *p_slot)
                else
                        p_slot->hpc_ops->green_led_off(p_slot);
                p_slot->hpc_ops->set_attention_status(p_slot, 0);
-               info(msg_button_cancel, p_slot->name);
+               info("PCI slot #%s - action canceled due to button press\n",
+                    p_slot->name);
                p_slot->state = STATIC_STATE;
                break;
        case POWEROFF_STATE:
index 83a5226..b7bede4 100644 (file)
 #define SLOT_SERR_INT_MASK     0x3
 
 DEFINE_DBG_BUFFER              /* Debug string buffer for entire HPC defined here */
-static struct php_ctlr_state_s *php_ctlr_list_head;    /* HPC state linked list */
-static int ctlr_seq_num = 0;   /* Controller sequenc # */
-static spinlock_t list_lock;
-
 static atomic_t shpchp_num_controllers = ATOMIC_INIT(0);
 
 static irqreturn_t shpc_isr(int irq, void *dev_id);
-static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int sec);
+static void start_int_poll_timer(struct controller *ctrl, int sec);
 static int hpc_check_cmd_status(struct controller *ctrl);
 
 static inline u8 shpc_readb(struct controller *ctrl, int reg)
 {
-       return readb(ctrl->hpc_ctlr_handle->creg + reg);
+       return readb(ctrl->creg + reg);
 }
 
 static inline void shpc_writeb(struct controller *ctrl, int reg, u8 val)
 {
-       writeb(val, ctrl->hpc_ctlr_handle->creg + reg);
+       writeb(val, ctrl->creg + reg);
 }
 
 static inline u16 shpc_readw(struct controller *ctrl, int reg)
 {
-       return readw(ctrl->hpc_ctlr_handle->creg + reg);
+       return readw(ctrl->creg + reg);
 }
 
 static inline void shpc_writew(struct controller *ctrl, int reg, u16 val)
 {
-       writew(val, ctrl->hpc_ctlr_handle->creg + reg);
+       writew(val, ctrl->creg + reg);
 }
 
 static inline u32 shpc_readl(struct controller *ctrl, int reg)
 {
-       return readl(ctrl->hpc_ctlr_handle->creg + reg);
+       return readl(ctrl->creg + reg);
 }
 
 static inline void shpc_writel(struct controller *ctrl, int reg, u32 val)
 {
-       writel(val, ctrl->hpc_ctlr_handle->creg + reg);
+       writel(val, ctrl->creg + reg);
 }
 
 static inline int shpc_indirect_read(struct controller *ctrl, int index,
@@ -268,21 +264,20 @@ static inline int shpc_indirect_read(struct controller *ctrl, int index,
 /*
  * This is the interrupt polling timeout function.
  */
-static void int_poll_timeout(unsigned long lphp_ctlr)
+static void int_poll_timeout(unsigned long data)
 {
-       struct php_ctlr_state_s *php_ctlr =
-               (struct php_ctlr_state_s *)lphp_ctlr;
+       struct controller *ctrl = (struct controller *)data;
 
        DBG_ENTER_ROUTINE
 
        /* Poll for interrupt events.  regs == NULL => polling */
-       shpc_isr(0, php_ctlr->callback_instance_id);
+       shpc_isr(0, ctrl);
 
-       init_timer(&php_ctlr->int_poll_timer);
+       init_timer(&ctrl->poll_timer);
        if (!shpchp_poll_time)
                shpchp_poll_time = 2; /* default polling interval is 2 sec */
 
-       start_int_poll_timer(php_ctlr, shpchp_poll_time);
+       start_int_poll_timer(ctrl, shpchp_poll_time);
 
        DBG_LEAVE_ROUTINE
 }
@@ -290,16 +285,16 @@ static void int_poll_timeout(unsigned long lphp_ctlr)
 /*
  * This function starts the interrupt polling timer.
  */
-static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int sec)
+static void start_int_poll_timer(struct controller *ctrl, int sec)
 {
        /* Clamp to sane value */
        if ((sec <= 0) || (sec > 60))
                sec = 2;
 
-       php_ctlr->int_poll_timer.function = &int_poll_timeout;
-       php_ctlr->int_poll_timer.data = (unsigned long)php_ctlr;
-       php_ctlr->int_poll_timer.expires = jiffies + sec * HZ;
-       add_timer(&php_ctlr->int_poll_timer);
+       ctrl->poll_timer.function = &int_poll_timeout;
+       ctrl->poll_timer.data = (unsigned long)ctrl;
+       ctrl->poll_timer.expires = jiffies + sec * HZ;
+       add_timer(&ctrl->poll_timer);
 }
 
 static inline int is_ctrl_busy(struct controller *ctrl)
@@ -666,33 +661,8 @@ static void hpc_set_green_led_blink(struct slot *slot)
        shpc_write_cmd(slot, slot->hp_slot, SET_PWR_BLINK);
 }
 
-int shpc_get_ctlr_slot_config(struct controller *ctrl,
-       int *num_ctlr_slots,    /* number of slots in this HPC                  */
-       int *first_device_num,  /* PCI dev num of the first slot in this SHPC   */
-       int *physical_slot_num, /* phy slot num of the first slot in this SHPC  */
-       int *updown,            /* physical_slot_num increament: 1 or -1        */
-       int *flags)
-{
-       u32 slot_config;
-
-       DBG_ENTER_ROUTINE 
-
-       slot_config = shpc_readl(ctrl, SLOT_CONFIG);
-       *first_device_num = (slot_config & FIRST_DEV_NUM) >> 8;
-       *num_ctlr_slots = slot_config & SLOT_NUM;
-       *physical_slot_num = (slot_config & PSN) >> 16;
-       *updown = ((slot_config & UPDOWN) >> 29) ? 1 : -1;
-
-       dbg("%s: physical_slot_num = %x\n", __FUNCTION__, *physical_slot_num);
-
-       DBG_LEAVE_ROUTINE 
-       return 0;
-}
-
 static void hpc_release_ctlr(struct controller *ctrl)
 {
-       struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle;
-       struct php_ctlr_state_s *p, *p_prev;
        int i;
        u32 slot_reg, serr_int;
 
@@ -722,40 +692,15 @@ static void hpc_release_ctlr(struct controller *ctrl)
        serr_int &= ~SERR_INTR_RSVDZ_MASK;
        shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int);
 
-       if (shpchp_poll_mode) {
-           del_timer(&php_ctlr->int_poll_timer);
-       } else {        
-               if (php_ctlr->irq) {
-                       free_irq(php_ctlr->irq, ctrl);
-                       php_ctlr->irq = 0;
-                       pci_disable_msi(php_ctlr->pci_dev);
-               }
-       }
-
-       if (php_ctlr->pci_dev) {
-               iounmap(php_ctlr->creg);
-               release_mem_region(ctrl->mmio_base, ctrl->mmio_size);
-               php_ctlr->pci_dev = NULL;
-       }
-
-       spin_lock(&list_lock);
-       p = php_ctlr_list_head;
-       p_prev = NULL;
-       while (p) {
-               if (p == php_ctlr) {
-                       if (p_prev)
-                               p_prev->pnext = p->pnext;
-                       else
-                               php_ctlr_list_head = p->pnext;
-                       break;
-               } else {
-                       p_prev = p;
-                       p = p->pnext;
-               }
+       if (shpchp_poll_mode)
+               del_timer(&ctrl->poll_timer);
+       else {
+               free_irq(ctrl->pci_dev->irq, ctrl);
+               pci_disable_msi(ctrl->pci_dev);
        }
-       spin_unlock(&list_lock);
 
-       kfree(php_ctlr);
+       iounmap(ctrl->creg);
+       release_mem_region(ctrl->mmio_base, ctrl->mmio_size);
 
        /*
         * If this is the last controller to be released, destroy the
@@ -764,8 +709,7 @@ static void hpc_release_ctlr(struct controller *ctrl)
        if (atomic_dec_and_test(&shpchp_num_controllers))
                destroy_workqueue(shpchp_wq);
 
-DBG_LEAVE_ROUTINE
-                         
+       DBG_LEAVE_ROUTINE
 }
 
 static int hpc_power_on_slot(struct slot * slot)
@@ -891,7 +835,6 @@ static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value)
 static irqreturn_t shpc_isr(int irq, void *dev_id)
 {
        struct controller *ctrl = (struct controller *)dev_id;
-       struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle;
        u32 serr_int, slot_reg, intr_loc, intr_loc2;
        int hp_slot;
 
@@ -942,20 +885,16 @@ static irqreturn_t shpc_isr(int irq, void *dev_id)
                    __FUNCTION__, hp_slot, slot_reg);
 
                if (slot_reg & MRL_CHANGE_DETECTED)
-                       php_ctlr->switch_change_callback(
-                               hp_slot, php_ctlr->callback_instance_id);
+                       shpchp_handle_switch_change(hp_slot, ctrl);
 
                if (slot_reg & BUTTON_PRESS_DETECTED)
-                       php_ctlr->attention_button_callback(
-                               hp_slot, php_ctlr->callback_instance_id);
+                       shpchp_handle_attention_button(hp_slot, ctrl);
 
                if (slot_reg & PRSNT_CHANGE_DETECTED)
-                       php_ctlr->presence_change_callback(
-                               hp_slot , php_ctlr->callback_instance_id);
+                       shpchp_handle_presence_change(hp_slot, ctrl);
 
                if (slot_reg & (ISO_PFAULT_DETECTED | CON_PFAULT_DETECTED))
-                       php_ctlr->power_fault_callback(
-                               hp_slot, php_ctlr->callback_instance_id);
+                       shpchp_handle_power_fault(hp_slot, ctrl);
 
                /* Clear all slot events */
                slot_reg &= ~SLOT_REG_RSVDZ_MASK;
@@ -1114,10 +1053,8 @@ static struct hpc_ops shpchp_hpc_ops = {
        .release_ctlr                   = hpc_release_ctlr,
 };
 
-int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
+int shpc_init(struct controller *ctrl, struct pci_dev *pdev)
 {
-       struct php_ctlr_state_s *php_ctlr, *p;
-       void *instance_id = ctrl;
        int rc = -1, num_slots = 0;
        u8 hp_slot;
        u32 shpc_base_offset;
@@ -1128,16 +1065,6 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
 
        ctrl->pci_dev = pdev;  /* pci_dev of the P2P bridge */
 
-       spin_lock_init(&list_lock);
-       php_ctlr = kzalloc(sizeof(*php_ctlr), GFP_KERNEL);
-
-       if (!php_ctlr) {        /* allocate controller state data */
-               err("%s: HPC controller memory allocation error!\n", __FUNCTION__);
-               goto abort;
-       }
-
-       php_ctlr->pci_dev = pdev;       /* save pci_dev in context */
-
        if ((pdev->vendor == PCI_VENDOR_ID_AMD) || (pdev->device ==
                                PCI_DEVICE_ID_AMD_GOLAM_7450)) {
                /* amd shpc driver doesn't use Base Offset; assume 0 */
@@ -1147,20 +1074,20 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
                ctrl->cap_offset = pci_find_capability(pdev, PCI_CAP_ID_SHPC);
                if (!ctrl->cap_offset) {
                        err("%s : cap_offset == 0\n", __FUNCTION__);
-                       goto abort_free_ctlr;
+                       goto abort;
                }
                dbg("%s: cap_offset = %x\n", __FUNCTION__, ctrl->cap_offset);
 
                rc = shpc_indirect_read(ctrl, 0, &shpc_base_offset);
                if (rc) {
                        err("%s: cannot read base_offset\n", __FUNCTION__);
-                       goto abort_free_ctlr;
+                       goto abort;
                }
 
                rc = shpc_indirect_read(ctrl, 3, &tempdword);
                if (rc) {
                        err("%s: cannot read slot config\n", __FUNCTION__);
-                       goto abort_free_ctlr;
+                       goto abort;
                }
                num_slots = tempdword & SLOT_NUM;
                dbg("%s: num_slots (indirect) %x\n", __FUNCTION__, num_slots);
@@ -1170,7 +1097,7 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
                        if (rc) {
                                err("%s: cannot read creg (index = %d)\n",
                                    __FUNCTION__, i);
-                               goto abort_free_ctlr;
+                               goto abort;
                        }
                        dbg("%s: offset %d: value %x\n", __FUNCTION__,i,
                                        tempdword);
@@ -1187,24 +1114,24 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
        rc = pci_enable_device(pdev);
        if (rc) {
                err("%s: pci_enable_device failed\n", __FUNCTION__);
-               goto abort_free_ctlr;
+               goto abort;
        }
 
        if (!request_mem_region(ctrl->mmio_base, ctrl->mmio_size, MY_NAME)) {
                err("%s: cannot reserve MMIO region\n", __FUNCTION__);
                rc = -1;
-               goto abort_free_ctlr;
+               goto abort;
        }
 
-       php_ctlr->creg = ioremap(ctrl->mmio_base, ctrl->mmio_size);
-       if (!php_ctlr->creg) {
+       ctrl->creg = ioremap(ctrl->mmio_base, ctrl->mmio_size);
+       if (!ctrl->creg) {
                err("%s: cannot remap MMIO region %lx @ %lx\n", __FUNCTION__,
                    ctrl->mmio_size, ctrl->mmio_base);
                release_mem_region(ctrl->mmio_base, ctrl->mmio_size);
                rc = -1;
-               goto abort_free_ctlr;
+               goto abort;
        }
-       dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg);
+       dbg("%s: ctrl->creg %p\n", __FUNCTION__, ctrl->creg);
 
        mutex_init(&ctrl->crit_sect);
        mutex_init(&ctrl->cmd_lock);
@@ -1212,23 +1139,14 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
        /* Setup wait queue */
        init_waitqueue_head(&ctrl->queue);
 
-       /* Find the IRQ */
-       php_ctlr->irq = pdev->irq;
-       php_ctlr->attention_button_callback = shpchp_handle_attention_button,
-       php_ctlr->switch_change_callback = shpchp_handle_switch_change;
-       php_ctlr->presence_change_callback = shpchp_handle_presence_change;
-       php_ctlr->power_fault_callback = shpchp_handle_power_fault;
-       php_ctlr->callback_instance_id = instance_id;
-
-       ctrl->hpc_ctlr_handle = php_ctlr;
        ctrl->hpc_ops = &shpchp_hpc_ops;
 
        /* Return PCI Controller Info */
        slot_config = shpc_readl(ctrl, SLOT_CONFIG);
-       php_ctlr->slot_device_offset = (slot_config & FIRST_DEV_NUM) >> 8;
-       php_ctlr->num_slots = slot_config & SLOT_NUM;
-       dbg("%s: slot_device_offset %x\n", __FUNCTION__, php_ctlr->slot_device_offset);
-       dbg("%s: num_slots %x\n", __FUNCTION__, php_ctlr->num_slots);
+       ctrl->slot_device_offset = (slot_config & FIRST_DEV_NUM) >> 8;
+       ctrl->num_slots = slot_config & SLOT_NUM;
+       ctrl->first_slot = (slot_config & PSN) >> 16;
+       ctrl->slot_num_inc = ((slot_config & UPDOWN) >> 29) ? 1 : -1;
 
        /* Mask Global Interrupt Mask & Command Complete Interrupt Mask */
        tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE);
@@ -1243,7 +1161,7 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
        /* Mask the MRL sensor SERR Mask of individual slot in
         * Slot SERR-INT Mask & clear all the existing event if any
         */
-       for (hp_slot = 0; hp_slot < php_ctlr->num_slots; hp_slot++) {
+       for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) {
                slot_reg = shpc_readl(ctrl, SLOT_REG(hp_slot));
                dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__,
                        hp_slot, slot_reg);
@@ -1255,24 +1173,27 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
                shpc_writel(ctrl, SLOT_REG(hp_slot), slot_reg);
        }
        
-       if (shpchp_poll_mode)  {/* Install interrupt polling code */
-               /* Install and start the interrupt polling timer */
-               init_timer(&php_ctlr->int_poll_timer);
-               start_int_poll_timer( php_ctlr, 10 );   /* start with 10 second delay */
+       if (shpchp_poll_mode) {
+               /* Install interrupt polling timer. Start with 10 sec delay */
+               init_timer(&ctrl->poll_timer);
+               start_int_poll_timer(ctrl, 10);
        } else {
                /* Installs the interrupt handler */
                rc = pci_enable_msi(pdev);
                if (rc) {
                        info("Can't get msi for the hotplug controller\n");
                        info("Use INTx for the hotplug controller\n");
-               } else
-                       php_ctlr->irq = pdev->irq;
+               }
                
-               rc = request_irq(php_ctlr->irq, shpc_isr, IRQF_SHARED, MY_NAME, (void *) ctrl);
-               dbg("%s: request_irq %d for hpc%d (returns %d)\n", __FUNCTION__, php_ctlr->irq, ctlr_seq_num, rc);
+               rc = request_irq(ctrl->pci_dev->irq, shpc_isr, IRQF_SHARED,
+                                MY_NAME, (void *)ctrl);
+               dbg("%s: request_irq %d for hpc%d (returns %d)\n",
+                   __FUNCTION__, ctrl->pci_dev->irq,
+                   atomic_read(&shpchp_num_controllers), rc);
                if (rc) {
-                       err("Can't get irq %d for the hotplug controller\n", php_ctlr->irq);
-                       goto abort_free_ctlr;
+                       err("Can't get irq %d for the hotplug controller\n",
+                           ctrl->pci_dev->irq);
+                       goto abort_iounmap;
                }
        }
        dbg("%s: HPC at b:d:f:irq=0x%x:%x:%x:%x\n", __FUNCTION__,
@@ -1280,24 +1201,6 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
                        PCI_FUNC(pdev->devfn), pdev->irq);
        get_hp_hw_control_from_firmware(pdev);
 
-       /*  Add this HPC instance into the HPC list */
-       spin_lock(&list_lock);
-       if (php_ctlr_list_head == 0) {
-               php_ctlr_list_head = php_ctlr;
-               p = php_ctlr_list_head;
-               p->pnext = NULL;
-       } else {
-               p = php_ctlr_list_head;
-
-               while (p->pnext)
-                       p = p->pnext;
-
-               p->pnext = php_ctlr;
-       }
-       spin_unlock(&list_lock);
-
-       ctlr_seq_num++;
-
        /*
         * If this is the first controller to be initialized,
         * initialize the shpchpd work queue
@@ -1306,14 +1209,14 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
                shpchp_wq = create_singlethread_workqueue("shpchpd");
                if (!shpchp_wq) {
                        rc = -ENOMEM;
-                       goto abort_free_ctlr;
+                       goto abort_iounmap;
                }
        }
 
        /*
         * Unmask all event interrupts of all slots
         */
-       for (hp_slot = 0; hp_slot < php_ctlr->num_slots; hp_slot++) {
+       for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) {
                slot_reg = shpc_readl(ctrl, SLOT_REG(hp_slot));
                dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__,
                        hp_slot, slot_reg);
@@ -1336,10 +1239,8 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
        return 0;
 
        /* We end up here for the many possible ways to fail this API.  */
-abort_free_ctlr:
-       if (php_ctlr->creg)
-               iounmap(php_ctlr->creg);
-       kfree(php_ctlr);
+abort_iounmap:
+       iounmap(ctrl->creg);
 abort:
        DBG_LEAVE_ROUTINE
        return rc;
index 0a8d1cc..279c940 100644 (file)
@@ -99,14 +99,7 @@ int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update)
        int pos;
        int irq;
 
-       pos = pci_find_capability(dev, PCI_CAP_ID_HT);
-       while (pos) {
-               u8 subtype;
-               pci_read_config_byte(dev, pos + 3, &subtype);
-               if (subtype == HT_CAPTYPE_IRQ)
-                       break;
-               pos = pci_find_next_capability(dev, pos, PCI_CAP_ID_HT);
-       }
+       pos = pci_find_ht_capability(dev, HT_CAPTYPE_IRQ);
        if (!pos)
                return -EINVAL;
 
index e5ae3a0..b8d2385 100644 (file)
@@ -162,14 +162,9 @@ const struct pci_device_id *pci_match_id(const struct pci_device_id *ids,
 const struct pci_device_id *pci_match_device(struct pci_driver *drv,
                                             struct pci_dev *dev)
 {
-       const struct pci_device_id *id;
        struct pci_dynid *dynid;
 
-       id = pci_match_id(drv->id_table, dev);
-       if (id)
-               return id;
-
-       /* static ids didn't match, lets look at the dynamic ones */
+       /* Look at the dynamic ids first, before the static ones */
        spin_lock(&drv->dynids.lock);
        list_for_each_entry(dynid, &drv->dynids.list, node) {
                if (pci_match_one_device(&dynid->id, dev)) {
@@ -178,7 +173,8 @@ const struct pci_device_id *pci_match_device(struct pci_driver *drv,
                }
        }
        spin_unlock(&drv->dynids.lock);
-       return NULL;
+
+       return pci_match_id(drv->id_table, dev);
 }
 
 static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
@@ -357,6 +353,8 @@ static int pci_device_resume_early(struct device * dev)
        struct pci_dev * pci_dev = to_pci_dev(dev);
        struct pci_driver * drv = pci_dev->driver;
 
+       pci_fixup_device(pci_fixup_resume, pci_dev);
+
        if (drv && drv->resume_early)
                error = drv->resume_early(pci_dev);
        return error;
index 5a14b73..6bfb942 100644 (file)
@@ -68,12 +68,14 @@ pci_max_busnr(void)
 
 #endif  /*  0  */
 
-static int __pci_find_next_cap(struct pci_bus *bus, unsigned int devfn, u8 pos, int cap)
+#define PCI_FIND_CAP_TTL       48
+
+static int __pci_find_next_cap_ttl(struct pci_bus *bus, unsigned int devfn,
+                                  u8 pos, int cap, int *ttl)
 {
        u8 id;
-       int ttl = 48;
 
-       while (ttl--) {
+       while ((*ttl)--) {
                pci_bus_read_config_byte(bus, devfn, pos, &pos);
                if (pos < 0x40)
                        break;
@@ -89,6 +91,14 @@ static int __pci_find_next_cap(struct pci_bus *bus, unsigned int devfn, u8 pos,
        return 0;
 }
 
+static int __pci_find_next_cap(struct pci_bus *bus, unsigned int devfn,
+                              u8 pos, int cap)
+{
+       int ttl = PCI_FIND_CAP_TTL;
+
+       return __pci_find_next_cap_ttl(bus, devfn, pos, cap, &ttl);
+}
+
 int pci_find_next_capability(struct pci_dev *dev, u8 pos, int cap)
 {
        return __pci_find_next_cap(dev->bus, dev->devfn,
@@ -96,10 +106,10 @@ int pci_find_next_capability(struct pci_dev *dev, u8 pos, int cap)
 }
 EXPORT_SYMBOL_GPL(pci_find_next_capability);
 
-static int __pci_bus_find_cap(struct pci_bus *bus, unsigned int devfn, u8 hdr_type, int cap)
+static int __pci_bus_find_cap_start(struct pci_bus *bus,
+                                   unsigned int devfn, u8 hdr_type)
 {
        u16 status;
-       u8 pos;
 
        pci_bus_read_config_word(bus, devfn, PCI_STATUS, &status);
        if (!(status & PCI_STATUS_CAP_LIST))
@@ -108,15 +118,14 @@ static int __pci_bus_find_cap(struct pci_bus *bus, unsigned int devfn, u8 hdr_ty
        switch (hdr_type) {
        case PCI_HEADER_TYPE_NORMAL:
        case PCI_HEADER_TYPE_BRIDGE:
-               pos = PCI_CAPABILITY_LIST;
-               break;
+               return PCI_CAPABILITY_LIST;
        case PCI_HEADER_TYPE_CARDBUS:
-               pos = PCI_CB_CAPABILITY_LIST;
-               break;
+               return PCI_CB_CAPABILITY_LIST;
        default:
                return 0;
        }
-       return __pci_find_next_cap(bus, devfn, pos, cap);
+
+       return 0;
 }
 
 /**
@@ -140,7 +149,13 @@ static int __pci_bus_find_cap(struct pci_bus *bus, unsigned int devfn, u8 hdr_ty
  */
 int pci_find_capability(struct pci_dev *dev, int cap)
 {
-       return __pci_bus_find_cap(dev->bus, dev->devfn, dev->hdr_type, cap);
+       int pos;
+
+       pos = __pci_bus_find_cap_start(dev->bus, dev->devfn, dev->hdr_type);
+       if (pos)
+               pos = __pci_find_next_cap(dev->bus, dev->devfn, pos, cap);
+
+       return pos;
 }
 
 /**
@@ -158,11 +173,16 @@ int pci_find_capability(struct pci_dev *dev, int cap)
  */
 int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap)
 {
+       int pos;
        u8 hdr_type;
 
        pci_bus_read_config_byte(bus, devfn, PCI_HEADER_TYPE, &hdr_type);
 
-       return __pci_bus_find_cap(bus, devfn, hdr_type & 0x7f, cap);
+       pos = __pci_bus_find_cap_start(bus, devfn, hdr_type & 0x7f);
+       if (pos)
+               pos = __pci_find_next_cap(bus, devfn, pos, cap);
+
+       return pos;
 }
 
 /**
@@ -214,6 +234,74 @@ int pci_find_ext_capability(struct pci_dev *dev, int cap)
 }
 EXPORT_SYMBOL_GPL(pci_find_ext_capability);
 
+static int __pci_find_next_ht_cap(struct pci_dev *dev, int pos, int ht_cap)
+{
+       int rc, ttl = PCI_FIND_CAP_TTL;
+       u8 cap, mask;
+
+       if (ht_cap == HT_CAPTYPE_SLAVE || ht_cap == HT_CAPTYPE_HOST)
+               mask = HT_3BIT_CAP_MASK;
+       else
+               mask = HT_5BIT_CAP_MASK;
+
+       pos = __pci_find_next_cap_ttl(dev->bus, dev->devfn, pos,
+                                     PCI_CAP_ID_HT, &ttl);
+       while (pos) {
+               rc = pci_read_config_byte(dev, pos + 3, &cap);
+               if (rc != PCIBIOS_SUCCESSFUL)
+                       return 0;
+
+               if ((cap & mask) == ht_cap)
+                       return pos;
+
+               pos = __pci_find_next_cap_ttl(dev->bus, dev->devfn, pos,
+                                             PCI_CAP_ID_HT, &ttl);
+       }
+
+       return 0;
+}
+/**
+ * pci_find_next_ht_capability - query a device's Hypertransport capabilities
+ * @dev: PCI device to query
+ * @pos: Position from which to continue searching
+ * @ht_cap: Hypertransport capability code
+ *
+ * To be used in conjunction with pci_find_ht_capability() to search for
+ * all capabilities matching @ht_cap. @pos should always be a value returned
+ * from pci_find_ht_capability().
+ *
+ * NB. To be 100% safe against broken PCI devices, the caller should take
+ * steps to avoid an infinite loop.
+ */
+int pci_find_next_ht_capability(struct pci_dev *dev, int pos, int ht_cap)
+{
+       return __pci_find_next_ht_cap(dev, pos + PCI_CAP_LIST_NEXT, ht_cap);
+}
+EXPORT_SYMBOL_GPL(pci_find_next_ht_capability);
+
+/**
+ * pci_find_ht_capability - query a device's Hypertransport capabilities
+ * @dev: PCI device to query
+ * @ht_cap: Hypertransport capability code
+ *
+ * Tell if a device supports a given Hypertransport capability.
+ * Returns an address within the device's PCI configuration space
+ * or 0 in case the device does not support the request capability.
+ * The address points to the PCI capability, of type PCI_CAP_ID_HT,
+ * which has a Hypertransport capability matching @ht_cap.
+ */
+int pci_find_ht_capability(struct pci_dev *dev, int ht_cap)
+{
+       int pos;
+
+       pos = __pci_bus_find_cap_start(dev->bus, dev->devfn, dev->hdr_type);
+       if (pos)
+               pos = __pci_find_next_ht_cap(dev, pos, ht_cap);
+
+       return pos;
+}
+EXPORT_SYMBOL_GPL(pci_find_ht_capability);
+
 /**
  * pci_find_parent_resource - return resource region of parent bus of given region
  * @dev: PCI device structure contains resources to be searched
index b4da795..f17e7ed 100644 (file)
@@ -90,7 +90,7 @@ static int __devinit pcie_portdrv_probe (struct pci_dev *dev,
                return -ENODEV;
        
        pci_set_master(dev);
-        if (!dev->irq) {
+        if (!dev->irq && dev->pin) {
                printk(KERN_WARNING 
                "%s->Dev[%04x:%04x] has invalid IRQ. Check vendor BIOS\n", 
                __FUNCTION__, dev->device, dev->vendor);
index 6a3c1e7..1ae9c3f 100644 (file)
@@ -649,6 +649,9 @@ static void pci_read_irq(struct pci_dev *dev)
  * Returns 0 on success and -1 if unknown type of device (not normal, bridge
  * or CardBus).
  */
+
+#define LEGACY_IO_RESOURCE     (IORESOURCE_IO | IORESOURCE_PCI_FIXED)
+
 static int pci_setup_device(struct pci_dev * dev)
 {
        u32 class;
@@ -692,18 +695,18 @@ static int pci_setup_device(struct pci_dev * dev)
                        if ((progif & 1) == 0) {
                                dev->resource[0].start = 0x1F0;
                                dev->resource[0].end = 0x1F7;
-                               dev->resource[0].flags = IORESOURCE_IO;
+                               dev->resource[0].flags = LEGACY_IO_RESOURCE;
                                dev->resource[1].start = 0x3F6;
                                dev->resource[1].end = 0x3F6;
-                               dev->resource[1].flags = IORESOURCE_IO;
+                               dev->resource[1].flags = LEGACY_IO_RESOURCE;
                        }
                        if ((progif & 4) == 0) {
                                dev->resource[2].start = 0x170;
                                dev->resource[2].end = 0x177;
-                               dev->resource[2].flags = IORESOURCE_IO;
+                               dev->resource[2].flags = LEGACY_IO_RESOURCE;
                                dev->resource[3].start = 0x376;
                                dev->resource[3].end = 0x376;
-                               dev->resource[3].flags = IORESOURCE_IO;
+                               dev->resource[3].flags = LEGACY_IO_RESOURCE;
                        }
                }
                break;
index 9ca9b9b..8f0322d 100644 (file)
@@ -36,7 +36,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_MELLANOX,PCI_DEVICE_ID_MELLANOX_TAVOR_BRID
 
 /* Deal with broken BIOS'es that neglect to enable passive release,
    which can cause problems in combination with the 82441FX/PPro MTRRs */
-static void __devinit quirk_passive_release(struct pci_dev *dev)
+static void quirk_passive_release(struct pci_dev *dev)
 {
        struct pci_dev *d = NULL;
        unsigned char dlc;
@@ -53,6 +53,7 @@ static void __devinit quirk_passive_release(struct pci_dev *dev)
        }
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82441,      quirk_passive_release );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_82441,      quirk_passive_release );
 
 /*  The VIA VP2/VP3/MVP3 seem to have some 'features'. There may be a workaround
     but VIA don't answer queries. If you happen to have good contacts at VIA
@@ -134,7 +135,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,        PCI_DEVICE_ID_INTEL_82439TX,    quir
  *     Updated based on further information from the site and also on
  *     information provided by VIA 
  */
-static void __devinit quirk_vialatency(struct pci_dev *dev)
+static void quirk_vialatency(struct pci_dev *dev)
 {
        struct pci_dev *p;
        u8 rev;
@@ -185,6 +186,10 @@ exit:
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA,     PCI_DEVICE_ID_VIA_8363_0,       quirk_vialatency );
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA,     PCI_DEVICE_ID_VIA_8371_1,       quirk_vialatency );
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA,     PCI_DEVICE_ID_VIA_8361,         quirk_vialatency );
+/* Must restore this on a resume from RAM */
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA,    PCI_DEVICE_ID_VIA_8363_0,       quirk_vialatency );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA,    PCI_DEVICE_ID_VIA_8371_1,       quirk_vialatency );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA,    PCI_DEVICE_ID_VIA_8361,         quirk_vialatency );
 
 /*
  *     VIA Apollo VP3 needs ETBF on BT848/878
@@ -532,7 +537,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, quirk_vt8235
  * TODO: When we have device-specific interrupt routers,
  * this code will go away from quirks.
  */
-static void __devinit quirk_via_ioapic(struct pci_dev *dev)
+static void quirk_via_ioapic(struct pci_dev *dev)
 {
        u8 tmp;
        
@@ -548,6 +553,7 @@ static void __devinit quirk_via_ioapic(struct pci_dev *dev)
        pci_write_config_byte (dev, 0x58, tmp);
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA,     PCI_DEVICE_ID_VIA_82C686,       quirk_via_ioapic );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA,    PCI_DEVICE_ID_VIA_82C686,       quirk_via_ioapic );
 
 /*
  * VIA 8237: Some BIOSs don't set the 'Bypass APIC De-Assert Message' Bit.
@@ -555,7 +561,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA,  PCI_DEVICE_ID_VIA_82C686,       quirk_via_i
  * Set this bit to get rid of cycle wastage.
  * Otherwise uncritical.
  */
-static void __devinit quirk_via_vt8237_bypass_apic_deassert(struct pci_dev *dev)
+static void quirk_via_vt8237_bypass_apic_deassert(struct pci_dev *dev)
 {
        u8 misc_control2;
 #define BYPASS_APIC_DEASSERT 8
@@ -567,6 +573,7 @@ static void __devinit quirk_via_vt8237_bypass_apic_deassert(struct pci_dev *dev)
        }
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA,     PCI_DEVICE_ID_VIA_8237,         quirk_via_vt8237_bypass_apic_deassert);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA,    PCI_DEVICE_ID_VIA_8237,         quirk_via_vt8237_bypass_apic_deassert);
 
 /*
  * The AMD io apic can hang the box when an apic irq is masked.
@@ -600,7 +607,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI,   PCI_ANY_ID,                     quirk_ioapic_rmw );
 #define AMD8131_revB0        0x11
 #define AMD8131_MISC         0x40
 #define AMD8131_NIOAMODE_BIT 0
-static void __init quirk_amd_8131_ioapic(struct pci_dev *dev) 
+static void quirk_amd_8131_ioapic(struct pci_dev *dev)
 { 
         unsigned char revid, tmp;
         
@@ -616,6 +623,7 @@ static void __init quirk_amd_8131_ioapic(struct pci_dev *dev)
         }
 } 
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic);
 #endif /* CONFIG_X86_IO_APIC */
 
 
@@ -641,65 +649,84 @@ static void __devinit quirk_via_acpi(struct pci_dev *d)
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,    PCI_DEVICE_ID_VIA_82C586_3,     quirk_via_acpi );
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,    PCI_DEVICE_ID_VIA_82C686_4,     quirk_via_acpi );
 
-/*
- * Via 686A/B:  The PCI_INTERRUPT_LINE register for the on-chip
- * devices, USB0/1, AC97, MC97, and ACPI, has an unusual feature:
- * when written, it makes an internal connection to the PIC.
- * For these devices, this register is defined to be 4 bits wide.
- * Normally this is fine.  However for IO-APIC motherboards, or
- * non-x86 architectures (yes Via exists on PPC among other places),
- * we must mask the PCI_INTERRUPT_LINE value versus 0xf to get
- * interrupts delivered properly.
- *
- * Some of the on-chip devices are actually '586 devices' so they are
- * listed here.
- */
-
-static int via_irq_fixup_needed = -1;
 
 /*
- * As some VIA hardware is available in PCI-card form, we need to restrict
- * this quirk to VIA PCI hardware built onto VIA-based motherboards only.
- * We try to locate a VIA southbridge before deciding whether the quirk
- * should be applied.
+ *     VIA bridges which have VLink
  */
-static const struct pci_device_id via_irq_fixup_tbl[] = {
-       {
-               .vendor         = PCI_VENDOR_ID_VIA,
-               .device         = PCI_ANY_ID,
-               .subvendor      = PCI_ANY_ID,
-               .subdevice      = PCI_ANY_ID,
-               .class          = PCI_CLASS_BRIDGE_ISA << 8,
-               .class_mask     = 0xffff00,
-       },
+
+static const struct pci_device_id via_vlink_fixup_tbl[] = {
+       /* Internal devices need IRQ line routing, pre VLink */
+       { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C686), 0 },
+       { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8231), 17 },
+       /* Devices with VLink */
+       { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8233_0), 17},
+       { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8233A), 17 },
+       { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8233C_0), 17 },
+       { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8235), 16 },
+       { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8237), 15 },
+       { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8237A), 15 },
        { 0, },
 };
 
-static void quirk_via_irq(struct pci_dev *dev)
+/**
+ *     quirk_via_vlink         -       VIA VLink IRQ number update
+ *     @dev: PCI device
+ *
+ *     If the device we are dealing with is on a PIC IRQ we need to
+ *     ensure that the IRQ line register which usually is not relevant
+ *     for PCI cards, is actually written so that interrupts get sent
+ *     to the right place
+ */
+
+static void quirk_via_vlink(struct pci_dev *dev)
 {
+       const struct pci_device_id *via_vlink_fixup;
+       static int dev_lo = -1, dev_hi = 18;
        u8 irq, new_irq;
 
-       if (via_irq_fixup_needed == -1)
-               via_irq_fixup_needed = pci_dev_present(via_irq_fixup_tbl);
+       /* Check if we have VLink and cache the result */
 
-       if (!via_irq_fixup_needed)
+       /* Checked already - no */
+       if (dev_lo == -2)
                return;
 
+       /* Not checked - see what bridge we have and find the device
+          ranges */
+
+       if (dev_lo == -1) {
+               via_vlink_fixup = pci_find_present(via_vlink_fixup_tbl);
+               if (via_vlink_fixup == NULL) {
+                       dev_lo = -2;
+                       return;
+               }
+               dev_lo = via_vlink_fixup->driver_data;
+               /* 82C686 is special - 0/0 */
+               if (dev_lo == 0)
+                       dev_hi = 0;
+       }
        new_irq = dev->irq;
 
        /* Don't quirk interrupts outside the legacy IRQ range */
        if (!new_irq || new_irq > 15)
                return;
 
+       /* Internal device ? */
+       if (dev->bus->number != 0 || PCI_SLOT(dev->devfn) > dev_hi ||
+               PCI_SLOT(dev->devfn) < dev_lo)
+               return;
+
+       /* This is an internal VLink device on a PIC interrupt. The BIOS
+          ought to have set this but may not have, so we redo it */
+
        pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
        if (new_irq != irq) {
-               printk(KERN_INFO "PCI: VIA IRQ fixup for %s, from %d to %d\n",
+               printk(KERN_INFO "PCI: VIA VLink IRQ fixup for %s, from %d to %d\n",
                        pci_name(dev), irq, new_irq);
                udelay(15);     /* unknown if delay really needed */
                pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq);
        }
 }
-DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irq);
+DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_vlink);
 
 /*
  * VIA VT82C598 has its device ID settable and many BIOSes
@@ -720,13 +747,14 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,       PCI_DEVICE_ID_VIA_82C597_0,     quirk_vt
  * do this even if the Linux CardBus driver is not loaded, because
  * the Linux i82365 driver does not (and should not) handle CardBus.
  */
-static void __devinit quirk_cardbus_legacy(struct pci_dev *dev)
+static void quirk_cardbus_legacy(struct pci_dev *dev)
 {
        if ((PCI_CLASS_BRIDGE_CARDBUS << 8) ^ dev->class)
                return;
        pci_write_config_dword(dev, PCI_CB_LEGACY_MODE_BASE, 0);
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy);
+DECLARE_PCI_FIXUP_RESUME(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy);
 
 /*
  * Following the PCI ordering rules is optional on the AMD762. I'm not
@@ -735,7 +763,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy);
  * To be fair to AMD, it follows the spec by default, its BIOS people
  * who turn it off!
  */
-static void __devinit quirk_amd_ordering(struct pci_dev *dev)
+static void quirk_amd_ordering(struct pci_dev *dev)
 {
        u32 pcic;
        pci_read_config_dword(dev, 0x4C, &pcic);
@@ -749,6 +777,7 @@ static void __devinit quirk_amd_ordering(struct pci_dev *dev)
        }
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD,     PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD,    PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering );
 
 /*
  *     DreamWorks provided workaround for Dunord I-3000 problem
@@ -784,7 +813,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TOSHIBA,     0x605,  quirk_transparent_bridge
  * datasheets found at http://www.national.com/ds/GX for info on what
  * these bits do.  <christer@weinigel.se>
  */
-static void __init quirk_mediagx_master(struct pci_dev *dev)
+static void quirk_mediagx_master(struct pci_dev *dev)
 {
        u8 reg;
        pci_read_config_byte(dev, 0x41, &reg);
@@ -795,13 +824,14 @@ static void __init quirk_mediagx_master(struct pci_dev *dev)
        }
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CYRIX,   PCI_DEVICE_ID_CYRIX_PCI_MASTER, quirk_mediagx_master );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_CYRIX,  PCI_DEVICE_ID_CYRIX_PCI_MASTER, quirk_mediagx_master );
 
 /*
  *     Ensure C0 rev restreaming is off. This is normally done by
  *     the BIOS but in the odd case it is not the results are corruption
  *     hence the presence of a Linux check
  */
-static void __init quirk_disable_pxb(struct pci_dev *pdev)
+static void quirk_disable_pxb(struct pci_dev *pdev)
 {
        u16 config;
        u8 rev;
@@ -817,7 +847,25 @@ static void __init quirk_disable_pxb(struct pci_dev *pdev)
        }
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82454NX,    quirk_disable_pxb );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_82454NX,    quirk_disable_pxb );
+
+
+static void __devinit quirk_sb600_sata(struct pci_dev *pdev)
+{
+       /* set sb600 sata to ahci mode */
+       if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
+               u8 tmp;
 
+               pci_read_config_byte(pdev, 0x40, &tmp);
+               pci_write_config_byte(pdev, 0x40, tmp|1);
+               pci_write_config_byte(pdev, 0x9, 1);
+               pci_write_config_byte(pdev, 0xa, 6);
+               pci_write_config_byte(pdev, 0x40, tmp);
+
+               pdev->class = 0x010601;
+       }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_sb600_sata);
 
 /*
  *     Serverworks CSB5 IDE does not fully support native mode
@@ -874,7 +922,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,       PCI_DEVICE_ID_INTEL_82375,      quirk_e
  * runs everywhere at present we suppress the printk output in most
  * irrelevant cases.
  */
-static void __init k8t_sound_hostbridge(struct pci_dev *dev)
+static void k8t_sound_hostbridge(struct pci_dev *dev)
 {
        unsigned char val;
 
@@ -893,8 +941,8 @@ static void __init k8t_sound_hostbridge(struct pci_dev *dev)
        }
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, k8t_sound_hostbridge);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, k8t_sound_hostbridge);
 
-#ifndef CONFIG_ACPI_SLEEP
 /*
  * On ASUS P4B boards, the SMBus PCI Device within the ICH2/4 southbridge
  * is not activated. The myth is that Asus said that they do not want the
@@ -906,10 +954,6 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, k8t_sound_ho
  * bridge. Unfortunately, this device has no subvendor/subdevice ID. So it 
  * becomes necessary to do this tweak in two steps -- I've chosen the Host
  * bridge as trigger.
- *
- * Actually, leaving it unhidden and not redoing the quirk over suspend2ram
- * will cause thermal management to break down, and causing machine to
- * overheat.
  */
 static int __initdata asus_hides_smbus;
 
@@ -1019,7 +1063,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,     PCI_DEVICE_ID_INTEL_82855PM_HB, as
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_82855GM_HB, asus_hides_smbus_hostbridge );
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_82915GM_HB, asus_hides_smbus_hostbridge );
 
-static void __init asus_hides_smbus_lpc(struct pci_dev *dev)
+static void asus_hides_smbus_lpc(struct pci_dev *dev)
 {
        u16 val;
        
@@ -1042,8 +1086,14 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82801CA_0,  asu
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc );
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc );
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_82801EB_0,  asus_hides_smbus_lpc );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_82801DB_0,  asus_hides_smbus_lpc );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_82801BA_0,  asus_hides_smbus_lpc );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_82801CA_0,  asus_hides_smbus_lpc );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_82801EB_0,  asus_hides_smbus_lpc );
 
-static void __init asus_hides_smbus_lpc_ich6(struct pci_dev *dev)
+static void asus_hides_smbus_lpc_ich6(struct pci_dev *dev)
 {
        u32 val, rcba;
        void __iomem *base;
@@ -1059,13 +1109,12 @@ static void __init asus_hides_smbus_lpc_ich6(struct pci_dev *dev)
        printk(KERN_INFO "PCI: Enabled ICH6/i801 SMBus device\n");
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_ICH6_1,     asus_hides_smbus_lpc_ich6 );
-
-#endif
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_ICH6_1,     asus_hides_smbus_lpc_ich6 );
 
 /*
  * SiS 96x south bridge: BIOS typically hides SMBus device...
  */
-static void __init quirk_sis_96x_smbus(struct pci_dev *dev)
+static void quirk_sis_96x_smbus(struct pci_dev *dev)
 {
        u8 val = 0;
        printk(KERN_INFO "Enabling SiS 96x SMBus.\n");
@@ -1086,7 +1135,7 @@ static int __devinitdata sis_96x_compatible = 0;
 
 #define SIS_DETECT_REGISTER 0x40
 
-static void __init quirk_sis_503(struct pci_dev *dev)
+static void quirk_sis_503(struct pci_dev *dev)
 {
        u8 reg;
        u16 devid;
@@ -1122,13 +1171,14 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,      PCI_DEVICE_ID_SI_651,           quirk_sis_96x_
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,     PCI_DEVICE_ID_SI_735,           quirk_sis_96x_compatible );
 
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,     PCI_DEVICE_ID_SI_503,           quirk_sis_503 );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI,     PCI_DEVICE_ID_SI_503,           quirk_sis_503 );
 /*
  * On ASUS A8V and A8V Deluxe boards, the onboard AC97 audio controller
  * and MC97 modem controller are disabled when a second PCI soundcard is
  * present. This patch, tweaking the VT8237 ISA bridge, enables them.
  * -- bjd
  */
-static void __init asus_hides_ac97_lpc(struct pci_dev *dev)
+static void asus_hides_ac97_lpc(struct pci_dev *dev)
 {
        u8 val;
        int asus_hides_ac97 = 0;
@@ -1159,6 +1209,14 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,       PCI_DEVICE_ID_SI_962,           quirk_sis_96x_
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,     PCI_DEVICE_ID_SI_963,           quirk_sis_96x_smbus );
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,     PCI_DEVICE_ID_SI_LPC,           quirk_sis_96x_smbus );
 
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA,    PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc );
+
+
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI,     PCI_DEVICE_ID_SI_961,           quirk_sis_96x_smbus );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI,     PCI_DEVICE_ID_SI_962,           quirk_sis_96x_smbus );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI,     PCI_DEVICE_ID_SI_963,           quirk_sis_96x_smbus );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI,     PCI_DEVICE_ID_SI_LPC,           quirk_sis_96x_smbus );
+
 #if defined(CONFIG_ATA) || defined(CONFIG_ATA_MODULE)
 
 /*
@@ -1167,7 +1225,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,        PCI_DEVICE_ID_SI_LPC,           quirk_sis_96x_
  *     the PCI scanning.
  */
 
-static void __devinit quirk_jmicron_dualfn(struct pci_dev *pdev)
+static void quirk_jmicron_dualfn(struct pci_dev *pdev)
 {
        u32 conf;
        u8 hdr;
@@ -1205,6 +1263,7 @@ static void __devinit quirk_jmicron_dualfn(struct pci_dev *pdev)
 }
 
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, quirk_jmicron_dualfn);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, quirk_jmicron_dualfn);
 
 #endif
 
@@ -1532,6 +1591,8 @@ extern struct pci_fixup __start_pci_fixups_final[];
 extern struct pci_fixup __end_pci_fixups_final[];
 extern struct pci_fixup __start_pci_fixups_enable[];
 extern struct pci_fixup __end_pci_fixups_enable[];
+extern struct pci_fixup __start_pci_fixups_resume[];
+extern struct pci_fixup __end_pci_fixups_resume[];
 
 
 void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev)
@@ -1559,6 +1620,11 @@ void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev)
                end = __end_pci_fixups_enable;
                break;
 
+       case pci_fixup_resume:
+               start = __start_pci_fixups_resume;
+               end = __end_pci_fixups_resume;
+               break;
+
        default:
                /* stupid compiler warning, you would think with an enum... */
                return;
@@ -1596,7 +1662,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,     0x1460,         quirk_p64h2_1k_io);
  * Force it to be linked by setting the corresponding control bit in the
  * config space.
  */
-static void __devinit quirk_nvidia_ck804_pcie_aer_ext_cap(struct pci_dev *dev)
+static void quirk_nvidia_ck804_pcie_aer_ext_cap(struct pci_dev *dev)
 {
        uint8_t b;
        if (pci_read_config_byte(dev, 0xf41, &b) == 0) {
@@ -1610,6 +1676,8 @@ static void __devinit quirk_nvidia_ck804_pcie_aer_ext_cap(struct pci_dev *dev)
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA,  PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
                        quirk_nvidia_ck804_pcie_aer_ext_cap);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_NVIDIA,  PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
+                       quirk_nvidia_ck804_pcie_aer_ext_cap);
 
 #ifdef CONFIG_PCI_MSI
 /* To disable MSI globally */
@@ -1644,19 +1712,23 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_
  * return 1 if a HT MSI capability is found and enabled */
 static int __devinit msi_ht_cap_enabled(struct pci_dev *dev)
 {
-       u8 pos;
-       int ttl;
-       for (pos = pci_find_capability(dev, PCI_CAP_ID_HT), ttl = 48;
-            pos && ttl;
-            pos = pci_find_next_capability(dev, pos, PCI_CAP_ID_HT), ttl--) {
-               u32 cap_hdr;
-               /* MSI mapping section according to Hypertransport spec */
-               if (pci_read_config_dword(dev, pos, &cap_hdr) == 0
-                   && (cap_hdr & 0xf8000000) == 0xa8000000 /* MSI mapping */) {
-                       printk(KERN_INFO "PCI: Found HT MSI mapping on %s with capability %s\n",
-                              pci_name(dev), cap_hdr & 0x10000 ? "enabled" : "disabled");
-                       return (cap_hdr & 0x10000) != 0; /* MSI mapping cap enabled */
+       int pos, ttl = 48;
+
+       pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING);
+       while (pos && ttl--) {
+               u8 flags;
+
+               if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS,
+                                        &flags) == 0)
+               {
+                       printk(KERN_INFO "PCI: Found %s HT MSI Mapping on %s\n",
+                               flags & HT_MSI_FLAGS_ENABLE ?
+                               "enabled" : "disabled", pci_name(dev));
+                       return (flags & HT_MSI_FLAGS_ENABLE) != 0;
                }
+
+               pos = pci_find_next_ht_capability(dev, pos,
+                                                 HT_CAPTYPE_MSI_MAPPING);
        }
        return 0;
 }
@@ -1688,8 +1760,9 @@ static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev)
         * a single one having MSI is enough to be sure that MSI are supported.
         */
        pdev = pci_get_slot(dev->bus, 0);
-       if (dev->subordinate && !msi_ht_cap_enabled(dev)
-           && !msi_ht_cap_enabled(pdev)) {
+       if (!pdev)
+               return;
+       if (!msi_ht_cap_enabled(dev) && !msi_ht_cap_enabled(pdev)) {
                printk(KERN_WARNING "PCI: MSI quirk detected. "
                       "MSI disabled on chipset %s.\n",
                       pci_name(dev));
index 2f13eba..45f2b20 100644 (file)
@@ -413,6 +413,24 @@ exit:
        return dev;
 }
 
+const struct pci_device_id *pci_find_present(const struct pci_device_id *ids)
+{
+       struct pci_dev *dev;
+       const struct pci_device_id *found = NULL;
+
+       WARN_ON(in_interrupt());
+       down_read(&pci_bus_sem);
+       while (ids->vendor || ids->subvendor || ids->class_mask) {
+               list_for_each_entry(dev, &pci_devices, global_list) {
+                       if ((found = pci_match_one_device(ids, dev)) != NULL)
+                               break;
+               }
+               ids++;
+       }
+       up_read(&pci_bus_sem);
+       return found;
+}
+
 /**
  * pci_dev_present - Returns 1 if device matching the device list is present, 0 if not.
  * @ids: A pointer to a null terminated list of struct pci_device_id structures
@@ -426,25 +444,11 @@ exit:
  */
 int pci_dev_present(const struct pci_device_id *ids)
 {
-       struct pci_dev *dev;
-       int found = 0;
-
-       WARN_ON(in_interrupt());
-       down_read(&pci_bus_sem);
-       while (ids->vendor || ids->subvendor || ids->class_mask) {
-               list_for_each_entry(dev, &pci_devices, global_list) {
-                       if (pci_match_one_device(ids, dev)) {
-                               found = 1;
-                               goto exit;
-                       }
-               }
-               ids++;
-       }
-exit:
-       up_read(&pci_bus_sem);
-       return found;
+       return pci_find_present(ids) == NULL ? 0 : 1;
 }
+
 EXPORT_SYMBOL(pci_dev_present);
+EXPORT_SYMBOL(pci_find_present);
 
 EXPORT_SYMBOL(pci_find_device);
 EXPORT_SYMBOL(pci_find_device_reverse);
index ab78e4b..cb4ced3 100644 (file)
@@ -33,11 +33,22 @@ pci_update_resource(struct pci_dev *dev, struct resource *res, int resno)
        u32 new, check, mask;
        int reg;
 
-       /* Ignore resources for unimplemented BARs and unused resource slots
-          for 64 bit BARs. */
+       /*
+        * Ignore resources for unimplemented BARs and unused resource slots
+        * for 64 bit BARs.
+        */
        if (!res->flags)
                return;
 
+       /*
+        * Ignore non-moveable resources.  This might be legacy resources for
+        * which no functional BAR register exists or another important
+        * system resource we should better not move around in system address
+        * space.
+        */
+       if (res->flags & IORESOURCE_PCI_FIXED)
+               return;
+
        pcibios_resource_to_bus(dev, &region, res);
 
        pr_debug("  got res [%llx:%llx] bus [%lx:%lx] flags %lx for "
@@ -212,6 +223,10 @@ pdev_sort_resources(struct pci_dev *dev, struct resource_list *head)
                resource_size_t r_align;
 
                r = &dev->resource[i];
+
+               if (r->flags & IORESOURCE_PCI_FIXED)
+                       continue;
+
                r_align = r->end - r->start;
                
                if (!(r->flags) || r->parent)
index 1587121..9fcc8d9 100644 (file)
@@ -35,6 +35,9 @@
                VMLINUX_SYMBOL(__start_pci_fixups_enable) = .;          \
                *(.pci_fixup_enable)                                    \
                VMLINUX_SYMBOL(__end_pci_fixups_enable) = .;            \
+               VMLINUX_SYMBOL(__start_pci_fixups_resume) = .;          \
+               *(.pci_fixup_resume)                                    \
+               VMLINUX_SYMBOL(__end_pci_fixups_resume) = .;            \
        }                                                               \
                                                                        \
        /* RapidIO route ops */                                         \
index a1b04d8..68dd42b 100644 (file)
@@ -119,7 +119,6 @@ header-y += nfs4_mount.h
 header-y += nfs_mount.h
 header-y += oom.h
 header-y += param.h
-header-y += pci_ids.h
 header-y += pci_regs.h
 header-y += personality.h
 header-y += pfkeyv2.h
@@ -162,7 +161,6 @@ header-y += vt.h
 header-y += wireless.h
 header-y += xattr.h
 header-y += x25.h
-header-y += zorro_ids.h
 
 unifdef-y += acct.h
 unifdef-y += adb.h
index cf8696d..15228d7 100644 (file)
@@ -91,6 +91,9 @@ struct resource_list {
 #define IORESOURCE_ROM_COPY            (1<<2)  /* ROM is alloc'd copy, resource field overlaid */
 #define IORESOURCE_ROM_BIOS_COPY       (1<<3)  /* ROM is BIOS copy, resource field overlaid */
 
+/* PCI control bits.  Shares IORESOURCE_BITS with above PCI ROM.  */
+#define IORESOURCE_PCI_FIXED           (1<<4)  /* Do not move resource */
+
 /* PC/ISA/whatever - the normal PC address spaces: IO and memory */
 extern struct resource ioport_resource;
 extern struct resource iomem_resource;
index 01c7072..f3c617e 100644 (file)
@@ -20,9 +20,6 @@
 /* Include the pci register defines */
 #include <linux/pci_regs.h>
 
-/* Include the ID list */
-#include <linux/pci_ids.h>
-
 /*
  * The PCI interface treats multi-function devices as independent
  * devices.  The slot/function address of each device is encoded
@@ -54,6 +51,9 @@
 #include <asm/atomic.h>
 #include <linux/device.h>
 
+/* Include the ID list */
+#include <linux/pci_ids.h>
+
 /* File state for mmap()s on /proc/bus/pci/X/Y */
 enum pci_mmap_state {
        pci_mmap_io,
@@ -396,6 +396,21 @@ struct pci_driver {
  */
 #define pci_module_init        pci_register_driver
 
+/**
+ * PCI_VDEVICE - macro used to describe a specific pci device in short form
+ * @vend: the vendor name
+ * @dev: the 16 bit PCI Device ID
+ *
+ * This macro is used to create a struct pci_device_id that matches a
+ * specific PCI device.  The subvendor, and subdevice fields will be set
+ * to PCI_ANY_ID. The macro allows the next field to follow as the device
+ * private data.
+ */
+
+#define PCI_VDEVICE(vendor, device)            \
+       PCI_VENDOR_ID_##vendor, (device),       \
+       PCI_ANY_ID, PCI_ANY_ID, 0, 0
+
 /* these external functions are only available when PCI support is enabled */
 #ifdef CONFIG_PCI
 
@@ -454,6 +469,8 @@ struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn);
 int pci_find_capability (struct pci_dev *dev, int cap);
 int pci_find_next_capability (struct pci_dev *dev, u8 pos, int cap);
 int pci_find_ext_capability (struct pci_dev *dev, int cap);
+int pci_find_ht_capability (struct pci_dev *dev, int ht_cap);
+int pci_find_next_ht_capability (struct pci_dev *dev, int pos, int ht_cap);
 struct pci_bus *pci_find_next_bus(const struct pci_bus *from);
 
 struct pci_dev *pci_get_device(unsigned int vendor, unsigned int device,
@@ -468,6 +485,7 @@ struct pci_dev *pci_get_slot (struct pci_bus *bus, unsigned int devfn);
 struct pci_dev *pci_get_bus_and_slot (unsigned int bus, unsigned int devfn);
 struct pci_dev *pci_get_class (unsigned int class, struct pci_dev *from);
 int pci_dev_present(const struct pci_device_id *ids);
+const struct pci_device_id *pci_find_present(const struct pci_device_id *ids);
 
 int pci_bus_read_config_byte (struct pci_bus *bus, unsigned int devfn, int where, u8 *val);
 int pci_bus_read_config_word (struct pci_bus *bus, unsigned int devfn, int where, u16 *val);
@@ -681,6 +699,7 @@ static inline struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *
 { return NULL; }
 
 #define pci_dev_present(ids)   (0)
+#define pci_find_present(ids)  (NULL)
 #define pci_dev_put(dev)       do { } while (0)
 
 static inline void pci_set_master(struct pci_dev *dev) { }
@@ -783,6 +802,7 @@ enum pci_fixup_pass {
        pci_fixup_header,       /* After reading configuration header */
        pci_fixup_final,        /* Final phase of device fixups */
        pci_fixup_enable,       /* pci_enable_device() time */
+       pci_fixup_resume,       /* pci_enable_device() time */
 };
 
 /* Anonymous variables would be nice... */
@@ -801,6 +821,9 @@ enum pci_fixup_pass {
 #define DECLARE_PCI_FIXUP_ENABLE(vendor, device, hook)                 \
        DECLARE_PCI_FIXUP_SECTION(.pci_fixup_enable,                    \
                        vendor##device##hook, vendor, device, hook)
+#define DECLARE_PCI_FIXUP_RESUME(vendor, device, hook)                 \
+       DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume,                    \
+                       resume##vendor##device##hook, vendor, device, hook)
 
 
 void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev);
index 95c1e74..778e701 100644 (file)
 #define PCI_CLASS_SERIAL_FIBER         0x0c04
 #define PCI_CLASS_SERIAL_SMBUS         0x0c05
 
+#define PCI_BASE_CLASS_WIRELESS                        0x0d
+#define PCI_CLASS_WIRELESS_RF_CONTROLLER       0x0d10
+#define PCI_CLASS_WIRELESS_WHCI                        0x0d1010
+
 #define PCI_BASE_CLASS_INTELLIGENT     0x0e
 #define PCI_CLASS_INTELLIGENT_I2O      0x0e00
 
index 064b1dc..7a6d34e 100644 (file)
 #define PCI_PWR_CAP            12      /* Capability */
 #define  PCI_PWR_CAP_BUDGET(x) ((x) & 1)       /* Included in system budget */
 
-/* Hypertransport sub capability types */
+/*
+ * Hypertransport sub capability types
+ *
+ * Unfortunately there are both 3 bit and 5 bit capability types defined
+ * in the HT spec, catering for that is a little messy. You probably don't
+ * want to use these directly, just use pci_find_ht_capability() and it
+ * will do the right thing for you.
+ */
+#define HT_3BIT_CAP_MASK       0xE0
 #define HT_CAPTYPE_SLAVE       0x00    /* Slave/Primary link configuration */
 #define HT_CAPTYPE_HOST                0x20    /* Host/Secondary link configuration */
+
+#define HT_5BIT_CAP_MASK       0xF8
 #define HT_CAPTYPE_IRQ         0x80    /* IRQ Configuration */
 #define HT_CAPTYPE_REMAPPING_40        0xA0    /* 40 bit address remapping */
 #define HT_CAPTYPE_REMAPPING_64 0xA2   /* 64 bit address remapping */
 #define HT_CAPTYPE_UNITID_CLUMP        0x90    /* Unit ID clumping */
 #define HT_CAPTYPE_EXTCONF     0x98    /* Extended Configuration Space Access */
 #define HT_CAPTYPE_MSI_MAPPING 0xA8    /* MSI Mapping Capability */
+#define  HT_MSI_FLAGS          0x02            /* Offset to flags */
+#define  HT_MSI_FLAGS_ENABLE   0x1             /* Mapping enable */
+#define  HT_MSI_FLAGS_FIXED    0x2             /* Fixed mapping only */
+#define  HT_MSI_FIXED_ADDR     0x00000000FEE00000ULL   /* Fixed addr */
+#define  HT_MSI_ADDR_LO                0x04            /* Offset to low addr bits */
+#define  HT_MSI_ADDR_LO_MASK   0xFFF00000      /* Low address bit mask */
+#define  HT_MSI_ADDR_HI                0x08            /* Offset to high addr bits */
 #define HT_CAPTYPE_DIRECT_ROUTE        0xB0    /* Direct routing configuration */
 #define HT_CAPTYPE_VCSET       0xB8    /* Virtual Channel configuration */
 #define HT_CAPTYPE_ERROR_RETRY 0xC0    /* Retry on error configuration */