diff options
author | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-21 03:01:47 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-21 03:01:47 -0500 |
commit | de9b2fccb6a1efdf1665ebbcb28cad61467b308a (patch) | |
tree | eeaf8e24a6b323be04da5b04e44b79daf8f6d05a /drivers | |
parent | fb34d203d0b5ac1b8284973eb0db3fdff101fc5e (diff) | |
parent | 031f30d2bc69f78cf542c0e5874a9d67c03d0ffe (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/pci-2.6
* 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
...
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ide/pci/atiixp.c | 1 | ||||
-rw-r--r-- | drivers/pci/hotplug/acpiphp_glue.c | 2 | ||||
-rw-r--r-- | drivers/pci/hotplug/rpaphp_slot.c | 47 | ||||
-rw-r--r-- | drivers/pci/hotplug/shpchp.h | 238 | ||||
-rw-r--r-- | drivers/pci/hotplug/shpchp_core.c | 116 | ||||
-rw-r--r-- | drivers/pci/hotplug/shpchp_ctrl.c | 21 | ||||
-rw-r--r-- | drivers/pci/hotplug/shpchp_hpc.c | 223 | ||||
-rw-r--r-- | drivers/pci/htirq.c | 9 | ||||
-rw-r--r-- | drivers/pci/pci-driver.c | 12 | ||||
-rw-r--r-- | drivers/pci/pci.c | 112 | ||||
-rw-r--r-- | drivers/pci/pcie/portdrv_pci.c | 2 | ||||
-rw-r--r-- | drivers/pci/probe.c | 11 | ||||
-rw-r--r-- | drivers/pci/quirks.c | 217 | ||||
-rw-r--r-- | drivers/pci/search.c | 38 | ||||
-rw-r--r-- | drivers/pci/setup-res.c | 19 |
15 files changed, 472 insertions, 596 deletions
diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c index d55b938b1aeb..ffdffb6379ef 100644 --- a/drivers/ide/pci/atiixp.c +++ b/drivers/ide/pci/atiixp.c | |||
@@ -368,7 +368,6 @@ static struct pci_device_id atiixp_pci_tbl[] = { | |||
368 | { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 368 | { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
369 | { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 369 | { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
370 | { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 370 | { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
371 | { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, PCI_ANY_ID, PCI_ANY_ID, (PCI_CLASS_STORAGE_IDE<<8)|0x8a, 0xffff05, 1}, | ||
372 | { 0, }, | 371 | { 0, }, |
373 | }; | 372 | }; |
374 | MODULE_DEVICE_TABLE(pci, atiixp_pci_tbl); | 373 | MODULE_DEVICE_TABLE(pci, atiixp_pci_tbl); |
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 0b9d0db1590a..bd1faebf61a0 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -1682,7 +1682,7 @@ int __init acpiphp_glue_init(void) | |||
1682 | * | 1682 | * |
1683 | * This function frees all data allocated in acpiphp_glue_init() | 1683 | * This function frees all data allocated in acpiphp_glue_init() |
1684 | */ | 1684 | */ |
1685 | void __exit acpiphp_glue_exit(void) | 1685 | void acpiphp_glue_exit(void) |
1686 | { | 1686 | { |
1687 | acpi_pci_unregister_driver(&acpi_pci_hp_driver); | 1687 | acpi_pci_unregister_driver(&acpi_pci_hp_driver); |
1688 | } | 1688 | } |
diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c index b771196a654e..3009193f0058 100644 --- a/drivers/pci/hotplug/rpaphp_slot.c +++ b/drivers/pci/hotplug/rpaphp_slot.c | |||
@@ -47,21 +47,11 @@ static ssize_t location_read_file (struct hotplug_slot *php_slot, char *buf) | |||
47 | return retval; | 47 | return retval; |
48 | } | 48 | } |
49 | 49 | ||
50 | static struct hotplug_slot_attribute hotplug_slot_attr_location = { | 50 | static struct hotplug_slot_attribute php_attr_location = { |
51 | .attr = {.name = "phy_location", .mode = S_IFREG | S_IRUGO}, | 51 | .attr = {.name = "phy_location", .mode = S_IFREG | S_IRUGO}, |
52 | .show = location_read_file, | 52 | .show = location_read_file, |
53 | }; | 53 | }; |
54 | 54 | ||
55 | static void rpaphp_sysfs_add_attr_location (struct hotplug_slot *slot) | ||
56 | { | ||
57 | sysfs_create_file(&slot->kobj, &hotplug_slot_attr_location.attr); | ||
58 | } | ||
59 | |||
60 | static void rpaphp_sysfs_remove_attr_location (struct hotplug_slot *slot) | ||
61 | { | ||
62 | sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_location.attr); | ||
63 | } | ||
64 | |||
65 | /* free up the memory used by a slot */ | 55 | /* free up the memory used by a slot */ |
66 | static void rpaphp_release_slot(struct hotplug_slot *hotplug_slot) | 56 | static void rpaphp_release_slot(struct hotplug_slot *hotplug_slot) |
67 | { | 57 | { |
@@ -145,7 +135,7 @@ int rpaphp_deregister_slot(struct slot *slot) | |||
145 | list_del(&slot->rpaphp_slot_list); | 135 | list_del(&slot->rpaphp_slot_list); |
146 | 136 | ||
147 | /* remove "phy_location" file */ | 137 | /* remove "phy_location" file */ |
148 | rpaphp_sysfs_remove_attr_location(php_slot); | 138 | sysfs_remove_file(&php_slot->kobj, &php_attr_location.attr); |
149 | 139 | ||
150 | retval = pci_hp_deregister(php_slot); | 140 | retval = pci_hp_deregister(php_slot); |
151 | if (retval) | 141 | if (retval) |
@@ -160,36 +150,45 @@ EXPORT_SYMBOL_GPL(rpaphp_deregister_slot); | |||
160 | 150 | ||
161 | int rpaphp_register_slot(struct slot *slot) | 151 | int rpaphp_register_slot(struct slot *slot) |
162 | { | 152 | { |
153 | struct hotplug_slot *php_slot = slot->hotplug_slot; | ||
163 | int retval; | 154 | int retval; |
164 | 155 | ||
165 | dbg("%s registering slot:path[%s] index[%x], name[%s] pdomain[%x] type[%d]\n", | 156 | dbg("%s registering slot:path[%s] index[%x], name[%s] pdomain[%x] type[%d]\n", |
166 | __FUNCTION__, slot->dn->full_name, slot->index, slot->name, | 157 | __FUNCTION__, slot->dn->full_name, slot->index, slot->name, |
167 | slot->power_domain, slot->type); | 158 | slot->power_domain, slot->type); |
159 | |||
168 | /* should not try to register the same slot twice */ | 160 | /* should not try to register the same slot twice */ |
169 | if (is_registered(slot)) { /* should't be here */ | 161 | if (is_registered(slot)) { |
170 | err("rpaphp_register_slot: slot[%s] is already registered\n", slot->name); | 162 | err("rpaphp_register_slot: slot[%s] is already registered\n", slot->name); |
171 | rpaphp_release_slot(slot->hotplug_slot); | 163 | retval = -EAGAIN; |
172 | return -EAGAIN; | 164 | goto register_fail; |
173 | } | 165 | } |
174 | retval = pci_hp_register(slot->hotplug_slot); | 166 | |
167 | retval = pci_hp_register(php_slot); | ||
175 | if (retval) { | 168 | if (retval) { |
176 | err("pci_hp_register failed with error %d\n", retval); | 169 | err("pci_hp_register failed with error %d\n", retval); |
177 | rpaphp_release_slot(slot->hotplug_slot); | 170 | goto register_fail; |
178 | return retval; | ||
179 | } | 171 | } |
180 | |||
181 | /* create "phy_locatoin" file */ | ||
182 | rpaphp_sysfs_add_attr_location(slot->hotplug_slot); | ||
183 | 172 | ||
184 | /* add slot to our internal list */ | 173 | /* create "phy_location" file */ |
185 | dbg("%s adding slot[%s] to rpaphp_slot_list\n", | 174 | retval = sysfs_create_file(&php_slot->kobj, &php_attr_location.attr); |
186 | __FUNCTION__, slot->name); | 175 | if (retval) { |
176 | err("sysfs_create_file failed with error %d\n", retval); | ||
177 | goto sysfs_fail; | ||
178 | } | ||
187 | 179 | ||
180 | /* add slot to our internal list */ | ||
188 | list_add(&slot->rpaphp_slot_list, &rpaphp_slot_head); | 181 | list_add(&slot->rpaphp_slot_list, &rpaphp_slot_head); |
189 | info("Slot [%s](PCI location=%s) registered\n", slot->name, | 182 | info("Slot [%s](PCI location=%s) registered\n", slot->name, |
190 | slot->location); | 183 | slot->location); |
191 | num_slots++; | 184 | num_slots++; |
192 | return 0; | 185 | return 0; |
186 | |||
187 | sysfs_fail: | ||
188 | pci_hp_deregister(php_slot); | ||
189 | register_fail: | ||
190 | rpaphp_release_slot(php_slot); | ||
191 | return retval; | ||
193 | } | 192 | } |
194 | 193 | ||
195 | int rpaphp_get_power_status(struct slot *slot, u8 * value) | 194 | int rpaphp_get_power_status(struct slot *slot, u8 * value) |
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index 50757695844f..3ca6a4f574b3 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h | |||
@@ -47,11 +47,17 @@ extern int shpchp_poll_time; | |||
47 | extern int shpchp_debug; | 47 | extern int shpchp_debug; |
48 | extern struct workqueue_struct *shpchp_wq; | 48 | extern struct workqueue_struct *shpchp_wq; |
49 | 49 | ||
50 | /*#define dbg(format, arg...) do { if (shpchp_debug) printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); } while (0)*/ | 50 | #define dbg(format, arg...) \ |
51 | #define dbg(format, arg...) do { if (shpchp_debug) printk("%s: " format, MY_NAME , ## arg); } while (0) | 51 | do { \ |
52 | #define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME , ## arg) | 52 | if (shpchp_debug) \ |
53 | #define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg) | 53 | printk("%s: " format, MY_NAME , ## arg); \ |
54 | #define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg) | 54 | } while (0) |
55 | #define err(format, arg...) \ | ||
56 | printk(KERN_ERR "%s: " format, MY_NAME , ## arg) | ||
57 | #define info(format, arg...) \ | ||
58 | printk(KERN_INFO "%s: " format, MY_NAME , ## arg) | ||
59 | #define warn(format, arg...) \ | ||
60 | printk(KERN_WARNING "%s: " format, MY_NAME , ## arg) | ||
55 | 61 | ||
56 | #define SLOT_NAME_SIZE 10 | 62 | #define SLOT_NAME_SIZE 10 |
57 | struct slot { | 63 | struct slot { |
@@ -83,34 +89,27 @@ struct event_info { | |||
83 | struct controller { | 89 | struct controller { |
84 | struct mutex crit_sect; /* critical section mutex */ | 90 | struct mutex crit_sect; /* critical section mutex */ |
85 | struct mutex cmd_lock; /* command lock */ | 91 | struct mutex cmd_lock; /* command lock */ |
86 | struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */ | ||
87 | int num_slots; /* Number of slots on ctlr */ | 92 | int num_slots; /* Number of slots on ctlr */ |
88 | int slot_num_inc; /* 1 or -1 */ | 93 | int slot_num_inc; /* 1 or -1 */ |
89 | struct pci_dev *pci_dev; | 94 | struct pci_dev *pci_dev; |
90 | struct list_head slot_list; | 95 | struct list_head slot_list; |
91 | struct hpc_ops *hpc_ops; | 96 | struct hpc_ops *hpc_ops; |
92 | wait_queue_head_t queue; /* sleep & wake process */ | 97 | wait_queue_head_t queue; /* sleep & wake process */ |
93 | u8 bus; | ||
94 | u8 device; | ||
95 | u8 function; | ||
96 | u8 slot_device_offset; | 98 | u8 slot_device_offset; |
97 | u8 add_support; | ||
98 | u32 pcix_misc2_reg; /* for amd pogo errata */ | 99 | u32 pcix_misc2_reg; /* for amd pogo errata */ |
99 | enum pci_bus_speed speed; | ||
100 | u32 first_slot; /* First physical slot number */ | 100 | u32 first_slot; /* First physical slot number */ |
101 | u8 slot_bus; /* Bus where the slots handled by this controller sit */ | ||
102 | u32 cap_offset; | 101 | u32 cap_offset; |
103 | unsigned long mmio_base; | 102 | unsigned long mmio_base; |
104 | unsigned long mmio_size; | 103 | unsigned long mmio_size; |
104 | void __iomem *creg; | ||
105 | struct timer_list poll_timer; | ||
105 | }; | 106 | }; |
106 | 107 | ||
107 | |||
108 | /* Define AMD SHPC ID */ | 108 | /* Define AMD SHPC ID */ |
109 | #define PCI_DEVICE_ID_AMD_GOLAM_7450 0x7450 | 109 | #define PCI_DEVICE_ID_AMD_GOLAM_7450 0x7450 |
110 | #define PCI_DEVICE_ID_AMD_POGO_7458 0x7458 | 110 | #define PCI_DEVICE_ID_AMD_POGO_7458 0x7458 |
111 | 111 | ||
112 | /* AMD PCIX bridge registers */ | 112 | /* AMD PCIX bridge registers */ |
113 | |||
114 | #define PCIX_MEM_BASE_LIMIT_OFFSET 0x1C | 113 | #define PCIX_MEM_BASE_LIMIT_OFFSET 0x1C |
115 | #define PCIX_MISCII_OFFSET 0x48 | 114 | #define PCIX_MISCII_OFFSET 0x48 |
116 | #define PCIX_MISC_BRIDGE_ERRORS_OFFSET 0x80 | 115 | #define PCIX_MISC_BRIDGE_ERRORS_OFFSET 0x80 |
@@ -145,8 +144,6 @@ struct controller { | |||
145 | #define POWERON_STATE 3 | 144 | #define POWERON_STATE 3 |
146 | #define POWEROFF_STATE 4 | 145 | #define POWEROFF_STATE 4 |
147 | 146 | ||
148 | #define PCI_TO_PCI_BRIDGE_CLASS 0x00060400 | ||
149 | |||
150 | /* Error messages */ | 147 | /* Error messages */ |
151 | #define INTERLOCK_OPEN 0x00000002 | 148 | #define INTERLOCK_OPEN 0x00000002 |
152 | #define ADD_NOT_SUPPORTED 0x00000003 | 149 | #define ADD_NOT_SUPPORTED 0x00000003 |
@@ -158,50 +155,32 @@ struct controller { | |||
158 | #define WRONG_BUS_FREQUENCY 0x0000000D | 155 | #define WRONG_BUS_FREQUENCY 0x0000000D |
159 | #define POWER_FAILURE 0x0000000E | 156 | #define POWER_FAILURE 0x0000000E |
160 | 157 | ||
161 | #define REMOVE_NOT_SUPPORTED 0x00000003 | ||
162 | |||
163 | #define DISABLE_CARD 1 | ||
164 | |||
165 | /* | ||
166 | * error Messages | ||
167 | */ | ||
168 | #define msg_initialization_err "Initialization failure, error=%d\n" | ||
169 | #define msg_button_on "PCI slot #%s - powering on due to button press.\n" | ||
170 | #define msg_button_off "PCI slot #%s - powering off due to button press.\n" | ||
171 | #define msg_button_cancel "PCI slot #%s - action canceled due to button press.\n" | ||
172 | |||
173 | /* sysfs functions for the hotplug controller info */ | ||
174 | extern int __must_check shpchp_create_ctrl_files(struct controller *ctrl); | 158 | extern int __must_check shpchp_create_ctrl_files(struct controller *ctrl); |
175 | 159 | extern void shpchp_remove_ctrl_files(struct controller *ctrl); | |
176 | extern int shpchp_sysfs_enable_slot(struct slot *slot); | 160 | extern int shpchp_sysfs_enable_slot(struct slot *slot); |
177 | extern int shpchp_sysfs_disable_slot(struct slot *slot); | 161 | extern int shpchp_sysfs_disable_slot(struct slot *slot); |
178 | 162 | extern u8 shpchp_handle_attention_button(u8 hp_slot, struct controller *ctrl); | |
179 | extern u8 shpchp_handle_attention_button(u8 hp_slot, void *inst_id); | 163 | extern u8 shpchp_handle_switch_change(u8 hp_slot, struct controller *ctrl); |
180 | extern u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id); | 164 | extern u8 shpchp_handle_presence_change(u8 hp_slot, struct controller *ctrl); |
181 | extern u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id); | 165 | extern u8 shpchp_handle_power_fault(u8 hp_slot, struct controller *ctrl); |
182 | extern u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id); | 166 | extern int shpchp_configure_device(struct slot *p_slot); |
183 | 167 | extern int shpchp_unconfigure_device(struct slot *p_slot); | |
184 | /* pci functions */ | 168 | extern void cleanup_slots(struct controller *ctrl); |
185 | extern int shpchp_save_config(struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num); | 169 | extern void queue_pushbutton_work(struct work_struct *work); |
186 | extern int shpchp_configure_device(struct slot *p_slot); | 170 | extern int shpc_init( struct controller *ctrl, struct pci_dev *pdev); |
187 | extern int shpchp_unconfigure_device(struct slot *p_slot); | ||
188 | extern void shpchp_remove_ctrl_files(struct controller *ctrl); | ||
189 | extern void cleanup_slots(struct controller *ctrl); | ||
190 | extern void queue_pushbutton_work(struct work_struct *work); | ||
191 | |||
192 | 171 | ||
193 | #ifdef CONFIG_ACPI | 172 | #ifdef CONFIG_ACPI |
194 | static inline int get_hp_params_from_firmware(struct pci_dev *dev, | 173 | static inline int get_hp_params_from_firmware(struct pci_dev *dev, |
195 | struct hotplug_params *hpp) | 174 | struct hotplug_params *hpp) |
196 | { | 175 | { |
197 | if (ACPI_FAILURE(acpi_get_hp_params_from_firmware(dev->bus, hpp))) | 176 | if (ACPI_FAILURE(acpi_get_hp_params_from_firmware(dev->bus, hpp))) |
198 | return -ENODEV; | 177 | return -ENODEV; |
199 | return 0; | 178 | return 0; |
200 | } | 179 | } |
201 | #define get_hp_hw_control_from_firmware(pdev) \ | 180 | #define get_hp_hw_control_from_firmware(pdev) \ |
202 | do { \ | 181 | do { \ |
203 | if (DEVICE_ACPI_HANDLE(&(pdev->dev))) \ | 182 | if (DEVICE_ACPI_HANDLE(&(pdev->dev))) \ |
204 | acpi_run_oshp(DEVICE_ACPI_HANDLE(&(pdev->dev))); \ | 183 | acpi_run_oshp(DEVICE_ACPI_HANDLE(&(pdev->dev)));\ |
205 | } while (0) | 184 | } while (0) |
206 | #else | 185 | #else |
207 | #define get_hp_params_from_firmware(dev, hpp) (-ENODEV) | 186 | #define get_hp_params_from_firmware(dev, hpp) (-ENODEV) |
@@ -222,108 +201,40 @@ struct ctrl_reg { | |||
222 | volatile u32 serr_loc; | 201 | volatile u32 serr_loc; |
223 | volatile u32 serr_intr_enable; | 202 | volatile u32 serr_intr_enable; |
224 | volatile u32 slot1; | 203 | volatile u32 slot1; |
225 | volatile u32 slot2; | ||
226 | volatile u32 slot3; | ||
227 | volatile u32 slot4; | ||
228 | volatile u32 slot5; | ||
229 | volatile u32 slot6; | ||
230 | volatile u32 slot7; | ||
231 | volatile u32 slot8; | ||
232 | volatile u32 slot9; | ||
233 | volatile u32 slot10; | ||
234 | volatile u32 slot11; | ||
235 | volatile u32 slot12; | ||
236 | } __attribute__ ((packed)); | 204 | } __attribute__ ((packed)); |
237 | 205 | ||
238 | /* offsets to the controller registers based on the above structure layout */ | 206 | /* offsets to the controller registers based on the above structure layout */ |
239 | enum ctrl_offsets { | 207 | enum ctrl_offsets { |
240 | BASE_OFFSET = offsetof(struct ctrl_reg, base_offset), | 208 | BASE_OFFSET = offsetof(struct ctrl_reg, base_offset), |
241 | SLOT_AVAIL1 = offsetof(struct ctrl_reg, slot_avail1), | 209 | SLOT_AVAIL1 = offsetof(struct ctrl_reg, slot_avail1), |
242 | SLOT_AVAIL2 = offsetof(struct ctrl_reg, slot_avail2), | 210 | SLOT_AVAIL2 = offsetof(struct ctrl_reg, slot_avail2), |
243 | SLOT_CONFIG = offsetof(struct ctrl_reg, slot_config), | 211 | SLOT_CONFIG = offsetof(struct ctrl_reg, slot_config), |
244 | SEC_BUS_CONFIG = offsetof(struct ctrl_reg, sec_bus_config), | 212 | SEC_BUS_CONFIG = offsetof(struct ctrl_reg, sec_bus_config), |
245 | MSI_CTRL = offsetof(struct ctrl_reg, msi_ctrl), | 213 | MSI_CTRL = offsetof(struct ctrl_reg, msi_ctrl), |
246 | PROG_INTERFACE = offsetof(struct ctrl_reg, prog_interface), | 214 | PROG_INTERFACE = offsetof(struct ctrl_reg, prog_interface), |
247 | CMD = offsetof(struct ctrl_reg, cmd), | 215 | CMD = offsetof(struct ctrl_reg, cmd), |
248 | CMD_STATUS = offsetof(struct ctrl_reg, cmd_status), | 216 | CMD_STATUS = offsetof(struct ctrl_reg, cmd_status), |
249 | INTR_LOC = offsetof(struct ctrl_reg, intr_loc), | 217 | INTR_LOC = offsetof(struct ctrl_reg, intr_loc), |
250 | SERR_LOC = offsetof(struct ctrl_reg, serr_loc), | 218 | SERR_LOC = offsetof(struct ctrl_reg, serr_loc), |
251 | SERR_INTR_ENABLE = offsetof(struct ctrl_reg, serr_intr_enable), | 219 | SERR_INTR_ENABLE = offsetof(struct ctrl_reg, serr_intr_enable), |
252 | SLOT1 = offsetof(struct ctrl_reg, slot1), | 220 | SLOT1 = offsetof(struct ctrl_reg, slot1), |
253 | SLOT2 = offsetof(struct ctrl_reg, slot2), | ||
254 | SLOT3 = offsetof(struct ctrl_reg, slot3), | ||
255 | SLOT4 = offsetof(struct ctrl_reg, slot4), | ||
256 | SLOT5 = offsetof(struct ctrl_reg, slot5), | ||
257 | SLOT6 = offsetof(struct ctrl_reg, slot6), | ||
258 | SLOT7 = offsetof(struct ctrl_reg, slot7), | ||
259 | SLOT8 = offsetof(struct ctrl_reg, slot8), | ||
260 | SLOT9 = offsetof(struct ctrl_reg, slot9), | ||
261 | SLOT10 = offsetof(struct ctrl_reg, slot10), | ||
262 | SLOT11 = offsetof(struct ctrl_reg, slot11), | ||
263 | SLOT12 = offsetof(struct ctrl_reg, slot12), | ||
264 | }; | ||
265 | typedef u8(*php_intr_callback_t) (u8 hp_slot, void *instance_id); | ||
266 | struct php_ctlr_state_s { | ||
267 | struct php_ctlr_state_s *pnext; | ||
268 | struct pci_dev *pci_dev; | ||
269 | unsigned int irq; | ||
270 | unsigned long flags; /* spinlock's */ | ||
271 | u32 slot_device_offset; | ||
272 | u32 num_slots; | ||
273 | struct timer_list int_poll_timer; /* Added for poll event */ | ||
274 | php_intr_callback_t attention_button_callback; | ||
275 | php_intr_callback_t switch_change_callback; | ||
276 | php_intr_callback_t presence_change_callback; | ||
277 | php_intr_callback_t power_fault_callback; | ||
278 | void *callback_instance_id; | ||
279 | void __iomem *creg; /* Ptr to controller register space */ | ||
280 | }; | 221 | }; |
281 | /* Inline functions */ | ||
282 | 222 | ||
283 | 223 | static inline struct slot *get_slot(struct hotplug_slot *hotplug_slot) | |
284 | /* Inline functions to check the sanity of a pointer that is passed to us */ | ||
285 | static inline int slot_paranoia_check (struct slot *slot, const char *function) | ||
286 | { | ||
287 | if (!slot) { | ||
288 | dbg("%s - slot == NULL", function); | ||
289 | return -1; | ||
290 | } | ||
291 | if (!slot->hotplug_slot) { | ||
292 | dbg("%s - slot->hotplug_slot == NULL!", function); | ||
293 | return -1; | ||
294 | } | ||
295 | return 0; | ||
296 | } | ||
297 | |||
298 | static inline struct slot *get_slot (struct hotplug_slot *hotplug_slot, const char *function) | ||
299 | { | 224 | { |
300 | struct slot *slot; | 225 | return hotplug_slot->private; |
301 | |||
302 | if (!hotplug_slot) { | ||
303 | dbg("%s - hotplug_slot == NULL\n", function); | ||
304 | return NULL; | ||
305 | } | ||
306 | |||
307 | slot = (struct slot *)hotplug_slot->private; | ||
308 | if (slot_paranoia_check (slot, function)) | ||
309 | return NULL; | ||
310 | return slot; | ||
311 | } | 226 | } |
312 | 227 | ||
313 | static inline struct slot *shpchp_find_slot (struct controller *ctrl, u8 device) | 228 | static inline struct slot *shpchp_find_slot(struct controller *ctrl, u8 device) |
314 | { | 229 | { |
315 | struct slot *slot; | 230 | struct slot *slot; |
316 | 231 | ||
317 | if (!ctrl) | ||
318 | return NULL; | ||
319 | |||
320 | list_for_each_entry(slot, &ctrl->slot_list, slot_list) { | 232 | list_for_each_entry(slot, &ctrl->slot_list, slot_list) { |
321 | if (slot->device == device) | 233 | if (slot->device == device) |
322 | return slot; | 234 | return slot; |
323 | } | 235 | } |
324 | 236 | ||
325 | err("%s: slot (device=0x%x) not found\n", __FUNCTION__, device); | 237 | err("%s: slot (device=0x%x) not found\n", __FUNCTION__, device); |
326 | |||
327 | return NULL; | 238 | return NULL; |
328 | } | 239 | } |
329 | 240 | ||
@@ -400,44 +311,27 @@ static inline void amd_pogo_errata_restore_misc_reg(struct slot *p_slot) | |||
400 | pci_write_config_dword(p_slot->ctrl->pci_dev, PCIX_MISCII_OFFSET, pcix_misc2_temp); | 311 | pci_write_config_dword(p_slot->ctrl->pci_dev, PCIX_MISCII_OFFSET, pcix_misc2_temp); |
401 | } | 312 | } |
402 | 313 | ||
403 | enum php_ctlr_type { | ||
404 | PCI, | ||
405 | ISA, | ||
406 | ACPI | ||
407 | }; | ||
408 | |||
409 | int shpc_init( struct controller *ctrl, struct pci_dev *pdev); | ||
410 | |||
411 | int shpc_get_ctlr_slot_config( struct controller *ctrl, | ||
412 | int *num_ctlr_slots, | ||
413 | int *first_device_num, | ||
414 | int *physical_slot_num, | ||
415 | int *updown, | ||
416 | int *flags); | ||
417 | |||
418 | struct hpc_ops { | 314 | struct hpc_ops { |
419 | int (*power_on_slot ) (struct slot *slot); | 315 | int (*power_on_slot)(struct slot *slot); |
420 | int (*slot_enable ) (struct slot *slot); | 316 | int (*slot_enable)(struct slot *slot); |
421 | int (*slot_disable ) (struct slot *slot); | 317 | int (*slot_disable)(struct slot *slot); |
422 | int (*set_bus_speed_mode) (struct slot *slot, enum pci_bus_speed speed); | 318 | int (*set_bus_speed_mode)(struct slot *slot, enum pci_bus_speed speed); |
423 | int (*get_power_status) (struct slot *slot, u8 *status); | 319 | int (*get_power_status)(struct slot *slot, u8 *status); |
424 | int (*get_attention_status) (struct slot *slot, u8 *status); | 320 | int (*get_attention_status)(struct slot *slot, u8 *status); |
425 | int (*set_attention_status) (struct slot *slot, u8 status); | 321 | int (*set_attention_status)(struct slot *slot, u8 status); |
426 | int (*get_latch_status) (struct slot *slot, u8 *status); | 322 | int (*get_latch_status)(struct slot *slot, u8 *status); |
427 | int (*get_adapter_status) (struct slot *slot, u8 *status); | 323 | int (*get_adapter_status)(struct slot *slot, u8 *status); |
428 | 324 | int (*get_max_bus_speed)(struct slot *slot, enum pci_bus_speed *speed); | |
429 | int (*get_max_bus_speed) (struct slot *slot, enum pci_bus_speed *speed); | 325 | int (*get_cur_bus_speed)(struct slot *slot, enum pci_bus_speed *speed); |
430 | int (*get_cur_bus_speed) (struct slot *slot, enum pci_bus_speed *speed); | 326 | int (*get_adapter_speed)(struct slot *slot, enum pci_bus_speed *speed); |
431 | int (*get_adapter_speed) (struct slot *slot, enum pci_bus_speed *speed); | 327 | int (*get_mode1_ECC_cap)(struct slot *slot, u8 *mode); |
432 | int (*get_mode1_ECC_cap) (struct slot *slot, u8 *mode); | 328 | int (*get_prog_int)(struct slot *slot, u8 *prog_int); |
433 | int (*get_prog_int) (struct slot *slot, u8 *prog_int); | 329 | int (*query_power_fault)(struct slot *slot); |
434 | 330 | void (*green_led_on)(struct slot *slot); | |
435 | int (*query_power_fault) (struct slot *slot); | 331 | void (*green_led_off)(struct slot *slot); |
436 | void (*green_led_on) (struct slot *slot); | 332 | void (*green_led_blink)(struct slot *slot); |
437 | void (*green_led_off) (struct slot *slot); | 333 | void (*release_ctlr)(struct controller *ctrl); |
438 | void (*green_led_blink) (struct slot *slot); | 334 | int (*check_cmd_status)(struct controller *ctrl); |
439 | void (*release_ctlr) (struct controller *ctrl); | ||
440 | int (*check_cmd_status) (struct controller *ctrl); | ||
441 | }; | 335 | }; |
442 | 336 | ||
443 | #endif /* _SHPCHP_H */ | 337 | #endif /* _SHPCHP_H */ |
diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c index 4eac85b3d90e..590cd3cbe010 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c | |||
@@ -104,23 +104,6 @@ static void make_slot_name(struct slot *slot) | |||
104 | slot->bus, slot->number); | 104 | slot->bus, slot->number); |
105 | } | 105 | } |
106 | 106 | ||
107 | |||
108 | |||
109 | |||
110 | static int | ||
111 | shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, | ||
112 | u8 busnum, u8 devnum) | ||
113 | { | ||
114 | int offset = devnum - ctrl->slot_device_offset; | ||
115 | |||
116 | dbg("%s: ctrl->slot_num_inc %d, offset %d\n", __FUNCTION__, | ||
117 | ctrl->slot_num_inc, offset); | ||
118 | *sun = (u8) (ctrl->first_slot + ctrl->slot_num_inc *offset); | ||
119 | return 0; | ||
120 | } | ||
121 | |||
122 | |||
123 | |||
124 | static int init_slots(struct controller *ctrl) | 107 | static int init_slots(struct controller *ctrl) |
125 | { | 108 | { |
126 | struct slot *slot; | 109 | struct slot *slot; |
@@ -128,7 +111,6 @@ static int init_slots(struct controller *ctrl) | |||
128 | struct hotplug_slot_info *info; | 111 | struct hotplug_slot_info *info; |
129 | int retval = -ENOMEM; | 112 | int retval = -ENOMEM; |
130 | int i; | 113 | int i; |
131 | u32 sun; | ||
132 | 114 | ||
133 | for (i = 0; i < ctrl->num_slots; i++) { | 115 | for (i = 0; i < ctrl->num_slots; i++) { |
134 | slot = kzalloc(sizeof(*slot), GFP_KERNEL); | 116 | slot = kzalloc(sizeof(*slot), GFP_KERNEL); |
@@ -149,16 +131,11 @@ static int init_slots(struct controller *ctrl) | |||
149 | 131 | ||
150 | slot->hp_slot = i; | 132 | slot->hp_slot = i; |
151 | slot->ctrl = ctrl; | 133 | slot->ctrl = ctrl; |
152 | slot->bus = ctrl->slot_bus; | 134 | slot->bus = ctrl->pci_dev->subordinate->number; |
153 | slot->device = ctrl->slot_device_offset + i; | 135 | slot->device = ctrl->slot_device_offset + i; |
154 | slot->hpc_ops = ctrl->hpc_ops; | 136 | slot->hpc_ops = ctrl->hpc_ops; |
137 | slot->number = ctrl->first_slot + (ctrl->slot_num_inc * i); | ||
155 | mutex_init(&slot->lock); | 138 | mutex_init(&slot->lock); |
156 | |||
157 | if (shpchprm_get_physical_slot_number(ctrl, &sun, | ||
158 | slot->bus, slot->device)) | ||
159 | goto error_info; | ||
160 | |||
161 | slot->number = sun; | ||
162 | INIT_DELAYED_WORK(&slot->work, queue_pushbutton_work); | 139 | INIT_DELAYED_WORK(&slot->work, queue_pushbutton_work); |
163 | 140 | ||
164 | /* register this slot with the hotplug pci core */ | 141 | /* register this slot with the hotplug pci core */ |
@@ -211,42 +188,12 @@ void cleanup_slots(struct controller *ctrl) | |||
211 | } | 188 | } |
212 | } | 189 | } |
213 | 190 | ||
214 | static int get_ctlr_slot_config(struct controller *ctrl) | ||
215 | { | ||
216 | int num_ctlr_slots; | ||
217 | int first_device_num; | ||
218 | int physical_slot_num; | ||
219 | int updown; | ||
220 | int rc; | ||
221 | int flags; | ||
222 | |||
223 | rc = shpc_get_ctlr_slot_config(ctrl, &num_ctlr_slots, | ||
224 | &first_device_num, &physical_slot_num, | ||
225 | &updown, &flags); | ||
226 | if (rc) { | ||
227 | err("%s: get_ctlr_slot_config fail for b:d (%x:%x)\n", | ||
228 | __FUNCTION__, ctrl->bus, ctrl->device); | ||
229 | return -1; | ||
230 | } | ||
231 | |||
232 | ctrl->num_slots = num_ctlr_slots; | ||
233 | ctrl->slot_device_offset = first_device_num; | ||
234 | ctrl->first_slot = physical_slot_num; | ||
235 | ctrl->slot_num_inc = updown; /* either -1 or 1 */ | ||
236 | |||
237 | dbg("%s: num_slot(0x%x) 1st_dev(0x%x) psn(0x%x) updown(%d) for b:d " | ||
238 | "(%x:%x)\n", __FUNCTION__, num_ctlr_slots, first_device_num, | ||
239 | physical_slot_num, updown, ctrl->bus, ctrl->device); | ||
240 | |||
241 | return 0; | ||
242 | } | ||
243 | |||
244 | /* | 191 | /* |
245 | * set_attention_status - Turns the Amber LED for a slot on, off or blink | 192 | * set_attention_status - Turns the Amber LED for a slot on, off or blink |
246 | */ | 193 | */ |
247 | static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status) | 194 | static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status) |
248 | { | 195 | { |
249 | struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); | 196 | struct slot *slot = get_slot(hotplug_slot); |
250 | 197 | ||
251 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); | 198 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); |
252 | 199 | ||
@@ -258,7 +205,7 @@ static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status) | |||
258 | 205 | ||
259 | static int enable_slot (struct hotplug_slot *hotplug_slot) | 206 | static int enable_slot (struct hotplug_slot *hotplug_slot) |
260 | { | 207 | { |
261 | struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); | 208 | struct slot *slot = get_slot(hotplug_slot); |
262 | 209 | ||
263 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); | 210 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); |
264 | 211 | ||
@@ -267,7 +214,7 @@ static int enable_slot (struct hotplug_slot *hotplug_slot) | |||
267 | 214 | ||
268 | static int disable_slot (struct hotplug_slot *hotplug_slot) | 215 | static int disable_slot (struct hotplug_slot *hotplug_slot) |
269 | { | 216 | { |
270 | struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); | 217 | struct slot *slot = get_slot(hotplug_slot); |
271 | 218 | ||
272 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); | 219 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); |
273 | 220 | ||
@@ -276,7 +223,7 @@ static int disable_slot (struct hotplug_slot *hotplug_slot) | |||
276 | 223 | ||
277 | static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value) | 224 | static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value) |
278 | { | 225 | { |
279 | struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); | 226 | struct slot *slot = get_slot(hotplug_slot); |
280 | int retval; | 227 | int retval; |
281 | 228 | ||
282 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); | 229 | 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) | |||
290 | 237 | ||
291 | static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value) | 238 | static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value) |
292 | { | 239 | { |
293 | struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); | 240 | struct slot *slot = get_slot(hotplug_slot); |
294 | int retval; | 241 | int retval; |
295 | 242 | ||
296 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); | 243 | 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) | |||
304 | 251 | ||
305 | static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value) | 252 | static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value) |
306 | { | 253 | { |
307 | struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); | 254 | struct slot *slot = get_slot(hotplug_slot); |
308 | int retval; | 255 | int retval; |
309 | 256 | ||
310 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); | 257 | 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) | |||
318 | 265 | ||
319 | static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value) | 266 | static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value) |
320 | { | 267 | { |
321 | struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); | 268 | struct slot *slot = get_slot(hotplug_slot); |
322 | int retval; | 269 | int retval; |
323 | 270 | ||
324 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); | 271 | 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) | |||
332 | 279 | ||
333 | static int get_address (struct hotplug_slot *hotplug_slot, u32 *value) | 280 | static int get_address (struct hotplug_slot *hotplug_slot, u32 *value) |
334 | { | 281 | { |
335 | struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); | 282 | struct slot *slot = get_slot(hotplug_slot); |
336 | struct pci_bus *bus = slot->ctrl->pci_dev->subordinate; | 283 | struct pci_bus *bus = slot->ctrl->pci_dev->subordinate; |
337 | 284 | ||
338 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); | 285 | 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) | |||
344 | 291 | ||
345 | static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) | 292 | static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) |
346 | { | 293 | { |
347 | struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); | 294 | struct slot *slot = get_slot(hotplug_slot); |
348 | int retval; | 295 | int retval; |
349 | 296 | ||
350 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); | 297 | 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 | |||
358 | 305 | ||
359 | static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) | 306 | static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) |
360 | { | 307 | { |
361 | struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); | 308 | struct slot *slot = get_slot(hotplug_slot); |
362 | int retval; | 309 | int retval; |
363 | 310 | ||
364 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); | 311 | 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) | |||
385 | { | 332 | { |
386 | int rc; | 333 | int rc; |
387 | struct controller *ctrl; | 334 | struct controller *ctrl; |
388 | struct slot *t_slot; | ||
389 | int first_device_num; /* first PCI device number */ | ||
390 | int num_ctlr_slots; /* number of slots implemented */ | ||
391 | 335 | ||
392 | if (!is_shpc_capable(pdev)) | 336 | if (!is_shpc_capable(pdev)) |
393 | return -ENODEV; | 337 | return -ENODEV; |
@@ -408,47 +352,13 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
408 | 352 | ||
409 | pci_set_drvdata(pdev, ctrl); | 353 | pci_set_drvdata(pdev, ctrl); |
410 | 354 | ||
411 | ctrl->bus = pdev->bus->number; | ||
412 | ctrl->slot_bus = pdev->subordinate->number; | ||
413 | ctrl->device = PCI_SLOT(pdev->devfn); | ||
414 | ctrl->function = PCI_FUNC(pdev->devfn); | ||
415 | |||
416 | dbg("ctrl bus=0x%x, device=%x, function=%x, irq=%x\n", | ||
417 | ctrl->bus, ctrl->device, ctrl->function, pdev->irq); | ||
418 | |||
419 | /* | ||
420 | * Save configuration headers for this and subordinate PCI buses | ||
421 | */ | ||
422 | rc = get_ctlr_slot_config(ctrl); | ||
423 | if (rc) { | ||
424 | err(msg_initialization_err, rc); | ||
425 | goto err_out_release_ctlr; | ||
426 | } | ||
427 | first_device_num = ctrl->slot_device_offset; | ||
428 | num_ctlr_slots = ctrl->num_slots; | ||
429 | |||
430 | ctrl->add_support = 1; | ||
431 | |||
432 | /* Setup the slot information structures */ | 355 | /* Setup the slot information structures */ |
433 | rc = init_slots(ctrl); | 356 | rc = init_slots(ctrl); |
434 | if (rc) { | 357 | if (rc) { |
435 | err(msg_initialization_err, 6); | 358 | err("%s: slot initialization failed\n", SHPC_MODULE_NAME); |
436 | goto err_out_release_ctlr; | 359 | goto err_out_release_ctlr; |
437 | } | 360 | } |
438 | 361 | ||
439 | /* Now hpc_functions (slot->hpc_ops->functions) are ready */ | ||
440 | t_slot = shpchp_find_slot(ctrl, first_device_num); | ||
441 | |||
442 | /* Check for operation bus speed */ | ||
443 | rc = t_slot->hpc_ops->get_cur_bus_speed(t_slot, &ctrl->speed); | ||
444 | dbg("%s: t_slot->hp_slot %x\n", __FUNCTION__,t_slot->hp_slot); | ||
445 | |||
446 | if (rc || ctrl->speed == PCI_SPEED_UNKNOWN) { | ||
447 | err(SHPC_MODULE_NAME ": Can't get current bus speed. " | ||
448 | "Set to 33MHz PCI.\n"); | ||
449 | ctrl->speed = PCI_SPEED_33MHz; | ||
450 | } | ||
451 | |||
452 | rc = shpchp_create_ctrl_files(ctrl); | 362 | rc = shpchp_create_ctrl_files(ctrl); |
453 | if (rc) | 363 | if (rc) |
454 | goto err_cleanup_slots; | 364 | goto err_cleanup_slots; |
diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c index 158ac7836096..6bb84734cd6c 100644 --- a/drivers/pci/hotplug/shpchp_ctrl.c +++ b/drivers/pci/hotplug/shpchp_ctrl.c | |||
@@ -57,9 +57,8 @@ static int queue_interrupt_event(struct slot *p_slot, u32 event_type) | |||
57 | return 0; | 57 | return 0; |
58 | } | 58 | } |
59 | 59 | ||
60 | u8 shpchp_handle_attention_button(u8 hp_slot, void *inst_id) | 60 | u8 shpchp_handle_attention_button(u8 hp_slot, struct controller *ctrl) |
61 | { | 61 | { |
62 | struct controller *ctrl = (struct controller *) inst_id; | ||
63 | struct slot *p_slot; | 62 | struct slot *p_slot; |
64 | u32 event_type; | 63 | u32 event_type; |
65 | 64 | ||
@@ -81,9 +80,8 @@ u8 shpchp_handle_attention_button(u8 hp_slot, void *inst_id) | |||
81 | 80 | ||
82 | } | 81 | } |
83 | 82 | ||
84 | u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id) | 83 | u8 shpchp_handle_switch_change(u8 hp_slot, struct controller *ctrl) |
85 | { | 84 | { |
86 | struct controller *ctrl = (struct controller *) inst_id; | ||
87 | struct slot *p_slot; | 85 | struct slot *p_slot; |
88 | u8 getstatus; | 86 | u8 getstatus; |
89 | u32 event_type; | 87 | u32 event_type; |
@@ -120,9 +118,8 @@ u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id) | |||
120 | return 1; | 118 | return 1; |
121 | } | 119 | } |
122 | 120 | ||
123 | u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id) | 121 | u8 shpchp_handle_presence_change(u8 hp_slot, struct controller *ctrl) |
124 | { | 122 | { |
125 | struct controller *ctrl = (struct controller *) inst_id; | ||
126 | struct slot *p_slot; | 123 | struct slot *p_slot; |
127 | u32 event_type; | 124 | u32 event_type; |
128 | 125 | ||
@@ -154,9 +151,8 @@ u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id) | |||
154 | return 1; | 151 | return 1; |
155 | } | 152 | } |
156 | 153 | ||
157 | u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id) | 154 | u8 shpchp_handle_power_fault(u8 hp_slot, struct controller *ctrl) |
158 | { | 155 | { |
159 | struct controller *ctrl = (struct controller *) inst_id; | ||
160 | struct slot *p_slot; | 156 | struct slot *p_slot; |
161 | u32 event_type; | 157 | u32 event_type; |
162 | 158 | ||
@@ -497,10 +493,12 @@ static void handle_button_press_event(struct slot *p_slot) | |||
497 | p_slot->hpc_ops->get_power_status(p_slot, &getstatus); | 493 | p_slot->hpc_ops->get_power_status(p_slot, &getstatus); |
498 | if (getstatus) { | 494 | if (getstatus) { |
499 | p_slot->state = BLINKINGOFF_STATE; | 495 | p_slot->state = BLINKINGOFF_STATE; |
500 | info(msg_button_off, p_slot->name); | 496 | info("PCI slot #%s - powering off due to button " |
497 | "press.\n", p_slot->name); | ||
501 | } else { | 498 | } else { |
502 | p_slot->state = BLINKINGON_STATE; | 499 | p_slot->state = BLINKINGON_STATE; |
503 | info(msg_button_on, p_slot->name); | 500 | info("PCI slot #%s - powering on due to button " |
501 | "press.\n", p_slot->name); | ||
504 | } | 502 | } |
505 | /* blink green LED and turn off amber */ | 503 | /* blink green LED and turn off amber */ |
506 | p_slot->hpc_ops->green_led_blink(p_slot); | 504 | p_slot->hpc_ops->green_led_blink(p_slot); |
@@ -523,7 +521,8 @@ static void handle_button_press_event(struct slot *p_slot) | |||
523 | else | 521 | else |
524 | p_slot->hpc_ops->green_led_off(p_slot); | 522 | p_slot->hpc_ops->green_led_off(p_slot); |
525 | p_slot->hpc_ops->set_attention_status(p_slot, 0); | 523 | p_slot->hpc_ops->set_attention_status(p_slot, 0); |
526 | info(msg_button_cancel, p_slot->name); | 524 | info("PCI slot #%s - action canceled due to button press\n", |
525 | p_slot->name); | ||
527 | p_slot->state = STATIC_STATE; | 526 | p_slot->state = STATIC_STATE; |
528 | break; | 527 | break; |
529 | case POWEROFF_STATE: | 528 | case POWEROFF_STATE: |
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c index 83a5226ba9ed..b7bede4b7c27 100644 --- a/drivers/pci/hotplug/shpchp_hpc.c +++ b/drivers/pci/hotplug/shpchp_hpc.c | |||
@@ -212,44 +212,40 @@ | |||
212 | #define SLOT_SERR_INT_MASK 0x3 | 212 | #define SLOT_SERR_INT_MASK 0x3 |
213 | 213 | ||
214 | DEFINE_DBG_BUFFER /* Debug string buffer for entire HPC defined here */ | 214 | DEFINE_DBG_BUFFER /* Debug string buffer for entire HPC defined here */ |
215 | static struct php_ctlr_state_s *php_ctlr_list_head; /* HPC state linked list */ | ||
216 | static int ctlr_seq_num = 0; /* Controller sequenc # */ | ||
217 | static spinlock_t list_lock; | ||
218 | |||
219 | static atomic_t shpchp_num_controllers = ATOMIC_INIT(0); | 215 | static atomic_t shpchp_num_controllers = ATOMIC_INIT(0); |
220 | 216 | ||
221 | static irqreturn_t shpc_isr(int irq, void *dev_id); | 217 | static irqreturn_t shpc_isr(int irq, void *dev_id); |
222 | static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int sec); | 218 | static void start_int_poll_timer(struct controller *ctrl, int sec); |
223 | static int hpc_check_cmd_status(struct controller *ctrl); | 219 | static int hpc_check_cmd_status(struct controller *ctrl); |
224 | 220 | ||
225 | static inline u8 shpc_readb(struct controller *ctrl, int reg) | 221 | static inline u8 shpc_readb(struct controller *ctrl, int reg) |
226 | { | 222 | { |
227 | return readb(ctrl->hpc_ctlr_handle->creg + reg); | 223 | return readb(ctrl->creg + reg); |
228 | } | 224 | } |
229 | 225 | ||
230 | static inline void shpc_writeb(struct controller *ctrl, int reg, u8 val) | 226 | static inline void shpc_writeb(struct controller *ctrl, int reg, u8 val) |
231 | { | 227 | { |
232 | writeb(val, ctrl->hpc_ctlr_handle->creg + reg); | 228 | writeb(val, ctrl->creg + reg); |
233 | } | 229 | } |
234 | 230 | ||
235 | static inline u16 shpc_readw(struct controller *ctrl, int reg) | 231 | static inline u16 shpc_readw(struct controller *ctrl, int reg) |
236 | { | 232 | { |
237 | return readw(ctrl->hpc_ctlr_handle->creg + reg); | 233 | return readw(ctrl->creg + reg); |
238 | } | 234 | } |
239 | 235 | ||
240 | static inline void shpc_writew(struct controller *ctrl, int reg, u16 val) | 236 | static inline void shpc_writew(struct controller *ctrl, int reg, u16 val) |
241 | { | 237 | { |
242 | writew(val, ctrl->hpc_ctlr_handle->creg + reg); | 238 | writew(val, ctrl->creg + reg); |
243 | } | 239 | } |
244 | 240 | ||
245 | static inline u32 shpc_readl(struct controller *ctrl, int reg) | 241 | static inline u32 shpc_readl(struct controller *ctrl, int reg) |
246 | { | 242 | { |
247 | return readl(ctrl->hpc_ctlr_handle->creg + reg); | 243 | return readl(ctrl->creg + reg); |
248 | } | 244 | } |
249 | 245 | ||
250 | static inline void shpc_writel(struct controller *ctrl, int reg, u32 val) | 246 | static inline void shpc_writel(struct controller *ctrl, int reg, u32 val) |
251 | { | 247 | { |
252 | writel(val, ctrl->hpc_ctlr_handle->creg + reg); | 248 | writel(val, ctrl->creg + reg); |
253 | } | 249 | } |
254 | 250 | ||
255 | static inline int shpc_indirect_read(struct controller *ctrl, int index, | 251 | 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, | |||
268 | /* | 264 | /* |
269 | * This is the interrupt polling timeout function. | 265 | * This is the interrupt polling timeout function. |
270 | */ | 266 | */ |
271 | static void int_poll_timeout(unsigned long lphp_ctlr) | 267 | static void int_poll_timeout(unsigned long data) |
272 | { | 268 | { |
273 | struct php_ctlr_state_s *php_ctlr = | 269 | struct controller *ctrl = (struct controller *)data; |
274 | (struct php_ctlr_state_s *)lphp_ctlr; | ||
275 | 270 | ||
276 | DBG_ENTER_ROUTINE | 271 | DBG_ENTER_ROUTINE |
277 | 272 | ||
278 | /* Poll for interrupt events. regs == NULL => polling */ | 273 | /* Poll for interrupt events. regs == NULL => polling */ |
279 | shpc_isr(0, php_ctlr->callback_instance_id); | 274 | shpc_isr(0, ctrl); |
280 | 275 | ||
281 | init_timer(&php_ctlr->int_poll_timer); | 276 | init_timer(&ctrl->poll_timer); |
282 | if (!shpchp_poll_time) | 277 | if (!shpchp_poll_time) |
283 | shpchp_poll_time = 2; /* default polling interval is 2 sec */ | 278 | shpchp_poll_time = 2; /* default polling interval is 2 sec */ |
284 | 279 | ||
285 | start_int_poll_timer(php_ctlr, shpchp_poll_time); | 280 | start_int_poll_timer(ctrl, shpchp_poll_time); |
286 | 281 | ||
287 | DBG_LEAVE_ROUTINE | 282 | DBG_LEAVE_ROUTINE |
288 | } | 283 | } |
@@ -290,16 +285,16 @@ static void int_poll_timeout(unsigned long lphp_ctlr) | |||
290 | /* | 285 | /* |
291 | * This function starts the interrupt polling timer. | 286 | * This function starts the interrupt polling timer. |
292 | */ | 287 | */ |
293 | static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int sec) | 288 | static void start_int_poll_timer(struct controller *ctrl, int sec) |
294 | { | 289 | { |
295 | /* Clamp to sane value */ | 290 | /* Clamp to sane value */ |
296 | if ((sec <= 0) || (sec > 60)) | 291 | if ((sec <= 0) || (sec > 60)) |
297 | sec = 2; | 292 | sec = 2; |
298 | 293 | ||
299 | php_ctlr->int_poll_timer.function = &int_poll_timeout; | 294 | ctrl->poll_timer.function = &int_poll_timeout; |
300 | php_ctlr->int_poll_timer.data = (unsigned long)php_ctlr; | 295 | ctrl->poll_timer.data = (unsigned long)ctrl; |
301 | php_ctlr->int_poll_timer.expires = jiffies + sec * HZ; | 296 | ctrl->poll_timer.expires = jiffies + sec * HZ; |
302 | add_timer(&php_ctlr->int_poll_timer); | 297 | add_timer(&ctrl->poll_timer); |
303 | } | 298 | } |
304 | 299 | ||
305 | static inline int is_ctrl_busy(struct controller *ctrl) | 300 | static inline int is_ctrl_busy(struct controller *ctrl) |
@@ -666,33 +661,8 @@ static void hpc_set_green_led_blink(struct slot *slot) | |||
666 | shpc_write_cmd(slot, slot->hp_slot, SET_PWR_BLINK); | 661 | shpc_write_cmd(slot, slot->hp_slot, SET_PWR_BLINK); |
667 | } | 662 | } |
668 | 663 | ||
669 | int shpc_get_ctlr_slot_config(struct controller *ctrl, | ||
670 | int *num_ctlr_slots, /* number of slots in this HPC */ | ||
671 | int *first_device_num, /* PCI dev num of the first slot in this SHPC */ | ||
672 | int *physical_slot_num, /* phy slot num of the first slot in this SHPC */ | ||
673 | int *updown, /* physical_slot_num increament: 1 or -1 */ | ||
674 | int *flags) | ||
675 | { | ||
676 | u32 slot_config; | ||
677 | |||
678 | DBG_ENTER_ROUTINE | ||
679 | |||
680 | slot_config = shpc_readl(ctrl, SLOT_CONFIG); | ||
681 | *first_device_num = (slot_config & FIRST_DEV_NUM) >> 8; | ||
682 | *num_ctlr_slots = slot_config & SLOT_NUM; | ||
683 | *physical_slot_num = (slot_config & PSN) >> 16; | ||
684 | *updown = ((slot_config & UPDOWN) >> 29) ? 1 : -1; | ||
685 | |||
686 | dbg("%s: physical_slot_num = %x\n", __FUNCTION__, *physical_slot_num); | ||
687 | |||
688 | DBG_LEAVE_ROUTINE | ||
689 | return 0; | ||
690 | } | ||
691 | |||
692 | static void hpc_release_ctlr(struct controller *ctrl) | 664 | static void hpc_release_ctlr(struct controller *ctrl) |
693 | { | 665 | { |
694 | struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle; | ||
695 | struct php_ctlr_state_s *p, *p_prev; | ||
696 | int i; | 666 | int i; |
697 | u32 slot_reg, serr_int; | 667 | u32 slot_reg, serr_int; |
698 | 668 | ||
@@ -722,40 +692,15 @@ static void hpc_release_ctlr(struct controller *ctrl) | |||
722 | serr_int &= ~SERR_INTR_RSVDZ_MASK; | 692 | serr_int &= ~SERR_INTR_RSVDZ_MASK; |
723 | shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int); | 693 | shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int); |
724 | 694 | ||
725 | if (shpchp_poll_mode) { | 695 | if (shpchp_poll_mode) |
726 | del_timer(&php_ctlr->int_poll_timer); | 696 | del_timer(&ctrl->poll_timer); |
727 | } else { | 697 | else { |
728 | if (php_ctlr->irq) { | 698 | free_irq(ctrl->pci_dev->irq, ctrl); |
729 | free_irq(php_ctlr->irq, ctrl); | 699 | pci_disable_msi(ctrl->pci_dev); |
730 | php_ctlr->irq = 0; | ||
731 | pci_disable_msi(php_ctlr->pci_dev); | ||
732 | } | ||
733 | } | ||
734 | |||
735 | if (php_ctlr->pci_dev) { | ||
736 | iounmap(php_ctlr->creg); | ||
737 | release_mem_region(ctrl->mmio_base, ctrl->mmio_size); | ||
738 | php_ctlr->pci_dev = NULL; | ||
739 | } | ||
740 | |||
741 | spin_lock(&list_lock); | ||
742 | p = php_ctlr_list_head; | ||
743 | p_prev = NULL; | ||
744 | while (p) { | ||
745 | if (p == php_ctlr) { | ||
746 | if (p_prev) | ||
747 | p_prev->pnext = p->pnext; | ||
748 | else | ||
749 | php_ctlr_list_head = p->pnext; | ||
750 | break; | ||
751 | } else { | ||
752 | p_prev = p; | ||
753 | p = p->pnext; | ||
754 | } | ||
755 | } | 700 | } |
756 | spin_unlock(&list_lock); | ||
757 | 701 | ||
758 | kfree(php_ctlr); | 702 | iounmap(ctrl->creg); |
703 | release_mem_region(ctrl->mmio_base, ctrl->mmio_size); | ||
759 | 704 | ||
760 | /* | 705 | /* |
761 | * If this is the last controller to be released, destroy the | 706 | * If this is the last controller to be released, destroy the |
@@ -764,8 +709,7 @@ static void hpc_release_ctlr(struct controller *ctrl) | |||
764 | if (atomic_dec_and_test(&shpchp_num_controllers)) | 709 | if (atomic_dec_and_test(&shpchp_num_controllers)) |
765 | destroy_workqueue(shpchp_wq); | 710 | destroy_workqueue(shpchp_wq); |
766 | 711 | ||
767 | DBG_LEAVE_ROUTINE | 712 | DBG_LEAVE_ROUTINE |
768 | |||
769 | } | 713 | } |
770 | 714 | ||
771 | static int hpc_power_on_slot(struct slot * slot) | 715 | 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) | |||
891 | static irqreturn_t shpc_isr(int irq, void *dev_id) | 835 | static irqreturn_t shpc_isr(int irq, void *dev_id) |
892 | { | 836 | { |
893 | struct controller *ctrl = (struct controller *)dev_id; | 837 | struct controller *ctrl = (struct controller *)dev_id; |
894 | struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle; | ||
895 | u32 serr_int, slot_reg, intr_loc, intr_loc2; | 838 | u32 serr_int, slot_reg, intr_loc, intr_loc2; |
896 | int hp_slot; | 839 | int hp_slot; |
897 | 840 | ||
@@ -942,20 +885,16 @@ static irqreturn_t shpc_isr(int irq, void *dev_id) | |||
942 | __FUNCTION__, hp_slot, slot_reg); | 885 | __FUNCTION__, hp_slot, slot_reg); |
943 | 886 | ||
944 | if (slot_reg & MRL_CHANGE_DETECTED) | 887 | if (slot_reg & MRL_CHANGE_DETECTED) |
945 | php_ctlr->switch_change_callback( | 888 | shpchp_handle_switch_change(hp_slot, ctrl); |
946 | hp_slot, php_ctlr->callback_instance_id); | ||
947 | 889 | ||
948 | if (slot_reg & BUTTON_PRESS_DETECTED) | 890 | if (slot_reg & BUTTON_PRESS_DETECTED) |
949 | php_ctlr->attention_button_callback( | 891 | shpchp_handle_attention_button(hp_slot, ctrl); |
950 | hp_slot, php_ctlr->callback_instance_id); | ||
951 | 892 | ||
952 | if (slot_reg & PRSNT_CHANGE_DETECTED) | 893 | if (slot_reg & PRSNT_CHANGE_DETECTED) |
953 | php_ctlr->presence_change_callback( | 894 | shpchp_handle_presence_change(hp_slot, ctrl); |
954 | hp_slot , php_ctlr->callback_instance_id); | ||
955 | 895 | ||
956 | if (slot_reg & (ISO_PFAULT_DETECTED | CON_PFAULT_DETECTED)) | 896 | if (slot_reg & (ISO_PFAULT_DETECTED | CON_PFAULT_DETECTED)) |
957 | php_ctlr->power_fault_callback( | 897 | shpchp_handle_power_fault(hp_slot, ctrl); |
958 | hp_slot, php_ctlr->callback_instance_id); | ||
959 | 898 | ||
960 | /* Clear all slot events */ | 899 | /* Clear all slot events */ |
961 | slot_reg &= ~SLOT_REG_RSVDZ_MASK; | 900 | slot_reg &= ~SLOT_REG_RSVDZ_MASK; |
@@ -1114,10 +1053,8 @@ static struct hpc_ops shpchp_hpc_ops = { | |||
1114 | .release_ctlr = hpc_release_ctlr, | 1053 | .release_ctlr = hpc_release_ctlr, |
1115 | }; | 1054 | }; |
1116 | 1055 | ||
1117 | int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | 1056 | int shpc_init(struct controller *ctrl, struct pci_dev *pdev) |
1118 | { | 1057 | { |
1119 | struct php_ctlr_state_s *php_ctlr, *p; | ||
1120 | void *instance_id = ctrl; | ||
1121 | int rc = -1, num_slots = 0; | 1058 | int rc = -1, num_slots = 0; |
1122 | u8 hp_slot; | 1059 | u8 hp_slot; |
1123 | u32 shpc_base_offset; | 1060 | u32 shpc_base_offset; |
@@ -1128,16 +1065,6 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | |||
1128 | 1065 | ||
1129 | ctrl->pci_dev = pdev; /* pci_dev of the P2P bridge */ | 1066 | ctrl->pci_dev = pdev; /* pci_dev of the P2P bridge */ |
1130 | 1067 | ||
1131 | spin_lock_init(&list_lock); | ||
1132 | php_ctlr = kzalloc(sizeof(*php_ctlr), GFP_KERNEL); | ||
1133 | |||
1134 | if (!php_ctlr) { /* allocate controller state data */ | ||
1135 | err("%s: HPC controller memory allocation error!\n", __FUNCTION__); | ||
1136 | goto abort; | ||
1137 | } | ||
1138 | |||
1139 | php_ctlr->pci_dev = pdev; /* save pci_dev in context */ | ||
1140 | |||
1141 | if ((pdev->vendor == PCI_VENDOR_ID_AMD) || (pdev->device == | 1068 | if ((pdev->vendor == PCI_VENDOR_ID_AMD) || (pdev->device == |
1142 | PCI_DEVICE_ID_AMD_GOLAM_7450)) { | 1069 | PCI_DEVICE_ID_AMD_GOLAM_7450)) { |
1143 | /* amd shpc driver doesn't use Base Offset; assume 0 */ | 1070 | /* amd shpc driver doesn't use Base Offset; assume 0 */ |
@@ -1147,20 +1074,20 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | |||
1147 | ctrl->cap_offset = pci_find_capability(pdev, PCI_CAP_ID_SHPC); | 1074 | ctrl->cap_offset = pci_find_capability(pdev, PCI_CAP_ID_SHPC); |
1148 | if (!ctrl->cap_offset) { | 1075 | if (!ctrl->cap_offset) { |
1149 | err("%s : cap_offset == 0\n", __FUNCTION__); | 1076 | err("%s : cap_offset == 0\n", __FUNCTION__); |
1150 | goto abort_free_ctlr; | 1077 | goto abort; |
1151 | } | 1078 | } |
1152 | dbg("%s: cap_offset = %x\n", __FUNCTION__, ctrl->cap_offset); | 1079 | dbg("%s: cap_offset = %x\n", __FUNCTION__, ctrl->cap_offset); |
1153 | 1080 | ||
1154 | rc = shpc_indirect_read(ctrl, 0, &shpc_base_offset); | 1081 | rc = shpc_indirect_read(ctrl, 0, &shpc_base_offset); |
1155 | if (rc) { | 1082 | if (rc) { |
1156 | err("%s: cannot read base_offset\n", __FUNCTION__); | 1083 | err("%s: cannot read base_offset\n", __FUNCTION__); |
1157 | goto abort_free_ctlr; | 1084 | goto abort; |
1158 | } | 1085 | } |
1159 | 1086 | ||
1160 | rc = shpc_indirect_read(ctrl, 3, &tempdword); | 1087 | rc = shpc_indirect_read(ctrl, 3, &tempdword); |
1161 | if (rc) { | 1088 | if (rc) { |
1162 | err("%s: cannot read slot config\n", __FUNCTION__); | 1089 | err("%s: cannot read slot config\n", __FUNCTION__); |
1163 | goto abort_free_ctlr; | 1090 | goto abort; |
1164 | } | 1091 | } |
1165 | num_slots = tempdword & SLOT_NUM; | 1092 | num_slots = tempdword & SLOT_NUM; |
1166 | dbg("%s: num_slots (indirect) %x\n", __FUNCTION__, num_slots); | 1093 | dbg("%s: num_slots (indirect) %x\n", __FUNCTION__, num_slots); |
@@ -1170,7 +1097,7 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | |||
1170 | if (rc) { | 1097 | if (rc) { |
1171 | err("%s: cannot read creg (index = %d)\n", | 1098 | err("%s: cannot read creg (index = %d)\n", |
1172 | __FUNCTION__, i); | 1099 | __FUNCTION__, i); |
1173 | goto abort_free_ctlr; | 1100 | goto abort; |
1174 | } | 1101 | } |
1175 | dbg("%s: offset %d: value %x\n", __FUNCTION__,i, | 1102 | dbg("%s: offset %d: value %x\n", __FUNCTION__,i, |
1176 | tempdword); | 1103 | tempdword); |
@@ -1187,24 +1114,24 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | |||
1187 | rc = pci_enable_device(pdev); | 1114 | rc = pci_enable_device(pdev); |
1188 | if (rc) { | 1115 | if (rc) { |
1189 | err("%s: pci_enable_device failed\n", __FUNCTION__); | 1116 | err("%s: pci_enable_device failed\n", __FUNCTION__); |
1190 | goto abort_free_ctlr; | 1117 | goto abort; |
1191 | } | 1118 | } |
1192 | 1119 | ||
1193 | if (!request_mem_region(ctrl->mmio_base, ctrl->mmio_size, MY_NAME)) { | 1120 | if (!request_mem_region(ctrl->mmio_base, ctrl->mmio_size, MY_NAME)) { |
1194 | err("%s: cannot reserve MMIO region\n", __FUNCTION__); | 1121 | err("%s: cannot reserve MMIO region\n", __FUNCTION__); |
1195 | rc = -1; | 1122 | rc = -1; |
1196 | goto abort_free_ctlr; | 1123 | goto abort; |
1197 | } | 1124 | } |
1198 | 1125 | ||
1199 | php_ctlr->creg = ioremap(ctrl->mmio_base, ctrl->mmio_size); | 1126 | ctrl->creg = ioremap(ctrl->mmio_base, ctrl->mmio_size); |
1200 | if (!php_ctlr->creg) { | 1127 | if (!ctrl->creg) { |
1201 | err("%s: cannot remap MMIO region %lx @ %lx\n", __FUNCTION__, | 1128 | err("%s: cannot remap MMIO region %lx @ %lx\n", __FUNCTION__, |
1202 | ctrl->mmio_size, ctrl->mmio_base); | 1129 | ctrl->mmio_size, ctrl->mmio_base); |
1203 | release_mem_region(ctrl->mmio_base, ctrl->mmio_size); | 1130 | release_mem_region(ctrl->mmio_base, ctrl->mmio_size); |
1204 | rc = -1; | 1131 | rc = -1; |
1205 | goto abort_free_ctlr; | 1132 | goto abort; |
1206 | } | 1133 | } |
1207 | dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg); | 1134 | dbg("%s: ctrl->creg %p\n", __FUNCTION__, ctrl->creg); |
1208 | 1135 | ||
1209 | mutex_init(&ctrl->crit_sect); | 1136 | mutex_init(&ctrl->crit_sect); |
1210 | mutex_init(&ctrl->cmd_lock); | 1137 | mutex_init(&ctrl->cmd_lock); |
@@ -1212,23 +1139,14 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | |||
1212 | /* Setup wait queue */ | 1139 | /* Setup wait queue */ |
1213 | init_waitqueue_head(&ctrl->queue); | 1140 | init_waitqueue_head(&ctrl->queue); |
1214 | 1141 | ||
1215 | /* Find the IRQ */ | ||
1216 | php_ctlr->irq = pdev->irq; | ||
1217 | php_ctlr->attention_button_callback = shpchp_handle_attention_button, | ||
1218 | php_ctlr->switch_change_callback = shpchp_handle_switch_change; | ||
1219 | php_ctlr->presence_change_callback = shpchp_handle_presence_change; | ||
1220 | php_ctlr->power_fault_callback = shpchp_handle_power_fault; | ||
1221 | php_ctlr->callback_instance_id = instance_id; | ||
1222 | |||
1223 | ctrl->hpc_ctlr_handle = php_ctlr; | ||
1224 | ctrl->hpc_ops = &shpchp_hpc_ops; | 1142 | ctrl->hpc_ops = &shpchp_hpc_ops; |
1225 | 1143 | ||
1226 | /* Return PCI Controller Info */ | 1144 | /* Return PCI Controller Info */ |
1227 | slot_config = shpc_readl(ctrl, SLOT_CONFIG); | 1145 | slot_config = shpc_readl(ctrl, SLOT_CONFIG); |
1228 | php_ctlr->slot_device_offset = (slot_config & FIRST_DEV_NUM) >> 8; | 1146 | ctrl->slot_device_offset = (slot_config & FIRST_DEV_NUM) >> 8; |
1229 | php_ctlr->num_slots = slot_config & SLOT_NUM; | 1147 | ctrl->num_slots = slot_config & SLOT_NUM; |
1230 | dbg("%s: slot_device_offset %x\n", __FUNCTION__, php_ctlr->slot_device_offset); | 1148 | ctrl->first_slot = (slot_config & PSN) >> 16; |
1231 | dbg("%s: num_slots %x\n", __FUNCTION__, php_ctlr->num_slots); | 1149 | ctrl->slot_num_inc = ((slot_config & UPDOWN) >> 29) ? 1 : -1; |
1232 | 1150 | ||
1233 | /* Mask Global Interrupt Mask & Command Complete Interrupt Mask */ | 1151 | /* Mask Global Interrupt Mask & Command Complete Interrupt Mask */ |
1234 | tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE); | 1152 | tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE); |
@@ -1243,7 +1161,7 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | |||
1243 | /* Mask the MRL sensor SERR Mask of individual slot in | 1161 | /* Mask the MRL sensor SERR Mask of individual slot in |
1244 | * Slot SERR-INT Mask & clear all the existing event if any | 1162 | * Slot SERR-INT Mask & clear all the existing event if any |
1245 | */ | 1163 | */ |
1246 | for (hp_slot = 0; hp_slot < php_ctlr->num_slots; hp_slot++) { | 1164 | for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) { |
1247 | slot_reg = shpc_readl(ctrl, SLOT_REG(hp_slot)); | 1165 | slot_reg = shpc_readl(ctrl, SLOT_REG(hp_slot)); |
1248 | dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__, | 1166 | dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__, |
1249 | hp_slot, slot_reg); | 1167 | hp_slot, slot_reg); |
@@ -1255,24 +1173,27 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | |||
1255 | shpc_writel(ctrl, SLOT_REG(hp_slot), slot_reg); | 1173 | shpc_writel(ctrl, SLOT_REG(hp_slot), slot_reg); |
1256 | } | 1174 | } |
1257 | 1175 | ||
1258 | if (shpchp_poll_mode) {/* Install interrupt polling code */ | 1176 | if (shpchp_poll_mode) { |
1259 | /* Install and start the interrupt polling timer */ | 1177 | /* Install interrupt polling timer. Start with 10 sec delay */ |
1260 | init_timer(&php_ctlr->int_poll_timer); | 1178 | init_timer(&ctrl->poll_timer); |
1261 | start_int_poll_timer( php_ctlr, 10 ); /* start with 10 second delay */ | 1179 | start_int_poll_timer(ctrl, 10); |
1262 | } else { | 1180 | } else { |
1263 | /* Installs the interrupt handler */ | 1181 | /* Installs the interrupt handler */ |
1264 | rc = pci_enable_msi(pdev); | 1182 | rc = pci_enable_msi(pdev); |
1265 | if (rc) { | 1183 | if (rc) { |
1266 | info("Can't get msi for the hotplug controller\n"); | 1184 | info("Can't get msi for the hotplug controller\n"); |
1267 | info("Use INTx for the hotplug controller\n"); | 1185 | info("Use INTx for the hotplug controller\n"); |
1268 | } else | 1186 | } |
1269 | php_ctlr->irq = pdev->irq; | ||
1270 | 1187 | ||
1271 | rc = request_irq(php_ctlr->irq, shpc_isr, IRQF_SHARED, MY_NAME, (void *) ctrl); | 1188 | rc = request_irq(ctrl->pci_dev->irq, shpc_isr, IRQF_SHARED, |
1272 | dbg("%s: request_irq %d for hpc%d (returns %d)\n", __FUNCTION__, php_ctlr->irq, ctlr_seq_num, rc); | 1189 | MY_NAME, (void *)ctrl); |
1190 | dbg("%s: request_irq %d for hpc%d (returns %d)\n", | ||
1191 | __FUNCTION__, ctrl->pci_dev->irq, | ||
1192 | atomic_read(&shpchp_num_controllers), rc); | ||
1273 | if (rc) { | 1193 | if (rc) { |
1274 | err("Can't get irq %d for the hotplug controller\n", php_ctlr->irq); | 1194 | err("Can't get irq %d for the hotplug controller\n", |
1275 | goto abort_free_ctlr; | 1195 | ctrl->pci_dev->irq); |
1196 | goto abort_iounmap; | ||
1276 | } | 1197 | } |
1277 | } | 1198 | } |
1278 | dbg("%s: HPC at b:d:f:irq=0x%x:%x:%x:%x\n", __FUNCTION__, | 1199 | 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) | |||
1280 | PCI_FUNC(pdev->devfn), pdev->irq); | 1201 | PCI_FUNC(pdev->devfn), pdev->irq); |
1281 | get_hp_hw_control_from_firmware(pdev); | 1202 | get_hp_hw_control_from_firmware(pdev); |
1282 | 1203 | ||
1283 | /* Add this HPC instance into the HPC list */ | ||
1284 | spin_lock(&list_lock); | ||
1285 | if (php_ctlr_list_head == 0) { | ||
1286 | php_ctlr_list_head = php_ctlr; | ||
1287 | p = php_ctlr_list_head; | ||
1288 | p->pnext = NULL; | ||
1289 | } else { | ||
1290 | p = php_ctlr_list_head; | ||
1291 | |||
1292 | while (p->pnext) | ||
1293 | p = p->pnext; | ||
1294 | |||
1295 | p->pnext = php_ctlr; | ||
1296 | } | ||
1297 | spin_unlock(&list_lock); | ||
1298 | |||
1299 | ctlr_seq_num++; | ||
1300 | |||
1301 | /* | 1204 | /* |
1302 | * If this is the first controller to be initialized, | 1205 | * If this is the first controller to be initialized, |
1303 | * initialize the shpchpd work queue | 1206 | * initialize the shpchpd work queue |
@@ -1306,14 +1209,14 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | |||
1306 | shpchp_wq = create_singlethread_workqueue("shpchpd"); | 1209 | shpchp_wq = create_singlethread_workqueue("shpchpd"); |
1307 | if (!shpchp_wq) { | 1210 | if (!shpchp_wq) { |
1308 | rc = -ENOMEM; | 1211 | rc = -ENOMEM; |
1309 | goto abort_free_ctlr; | 1212 | goto abort_iounmap; |
1310 | } | 1213 | } |
1311 | } | 1214 | } |
1312 | 1215 | ||
1313 | /* | 1216 | /* |
1314 | * Unmask all event interrupts of all slots | 1217 | * Unmask all event interrupts of all slots |
1315 | */ | 1218 | */ |
1316 | for (hp_slot = 0; hp_slot < php_ctlr->num_slots; hp_slot++) { | 1219 | for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) { |
1317 | slot_reg = shpc_readl(ctrl, SLOT_REG(hp_slot)); | 1220 | slot_reg = shpc_readl(ctrl, SLOT_REG(hp_slot)); |
1318 | dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__, | 1221 | dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__, |
1319 | hp_slot, slot_reg); | 1222 | hp_slot, slot_reg); |
@@ -1336,10 +1239,8 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) | |||
1336 | return 0; | 1239 | return 0; |
1337 | 1240 | ||
1338 | /* We end up here for the many possible ways to fail this API. */ | 1241 | /* We end up here for the many possible ways to fail this API. */ |
1339 | abort_free_ctlr: | 1242 | abort_iounmap: |
1340 | if (php_ctlr->creg) | 1243 | iounmap(ctrl->creg); |
1341 | iounmap(php_ctlr->creg); | ||
1342 | kfree(php_ctlr); | ||
1343 | abort: | 1244 | abort: |
1344 | DBG_LEAVE_ROUTINE | 1245 | DBG_LEAVE_ROUTINE |
1345 | return rc; | 1246 | return rc; |
diff --git a/drivers/pci/htirq.c b/drivers/pci/htirq.c index 0a8d1cce9fa0..279c940a0039 100644 --- a/drivers/pci/htirq.c +++ b/drivers/pci/htirq.c | |||
@@ -99,14 +99,7 @@ int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update) | |||
99 | int pos; | 99 | int pos; |
100 | int irq; | 100 | int irq; |
101 | 101 | ||
102 | pos = pci_find_capability(dev, PCI_CAP_ID_HT); | 102 | pos = pci_find_ht_capability(dev, HT_CAPTYPE_IRQ); |
103 | while (pos) { | ||
104 | u8 subtype; | ||
105 | pci_read_config_byte(dev, pos + 3, &subtype); | ||
106 | if (subtype == HT_CAPTYPE_IRQ) | ||
107 | break; | ||
108 | pos = pci_find_next_capability(dev, pos, PCI_CAP_ID_HT); | ||
109 | } | ||
110 | if (!pos) | 103 | if (!pos) |
111 | return -EINVAL; | 104 | return -EINVAL; |
112 | 105 | ||
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index e5ae3a0c13bb..b8d2385e29bc 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
@@ -162,14 +162,9 @@ const struct pci_device_id *pci_match_id(const struct pci_device_id *ids, | |||
162 | const struct pci_device_id *pci_match_device(struct pci_driver *drv, | 162 | const struct pci_device_id *pci_match_device(struct pci_driver *drv, |
163 | struct pci_dev *dev) | 163 | struct pci_dev *dev) |
164 | { | 164 | { |
165 | const struct pci_device_id *id; | ||
166 | struct pci_dynid *dynid; | 165 | struct pci_dynid *dynid; |
167 | 166 | ||
168 | id = pci_match_id(drv->id_table, dev); | 167 | /* Look at the dynamic ids first, before the static ones */ |
169 | if (id) | ||
170 | return id; | ||
171 | |||
172 | /* static ids didn't match, lets look at the dynamic ones */ | ||
173 | spin_lock(&drv->dynids.lock); | 168 | spin_lock(&drv->dynids.lock); |
174 | list_for_each_entry(dynid, &drv->dynids.list, node) { | 169 | list_for_each_entry(dynid, &drv->dynids.list, node) { |
175 | if (pci_match_one_device(&dynid->id, dev)) { | 170 | if (pci_match_one_device(&dynid->id, dev)) { |
@@ -178,7 +173,8 @@ const struct pci_device_id *pci_match_device(struct pci_driver *drv, | |||
178 | } | 173 | } |
179 | } | 174 | } |
180 | spin_unlock(&drv->dynids.lock); | 175 | spin_unlock(&drv->dynids.lock); |
181 | return NULL; | 176 | |
177 | return pci_match_id(drv->id_table, dev); | ||
182 | } | 178 | } |
183 | 179 | ||
184 | static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev, | 180 | 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) | |||
357 | struct pci_dev * pci_dev = to_pci_dev(dev); | 353 | struct pci_dev * pci_dev = to_pci_dev(dev); |
358 | struct pci_driver * drv = pci_dev->driver; | 354 | struct pci_driver * drv = pci_dev->driver; |
359 | 355 | ||
356 | pci_fixup_device(pci_fixup_resume, pci_dev); | ||
357 | |||
360 | if (drv && drv->resume_early) | 358 | if (drv && drv->resume_early) |
361 | error = drv->resume_early(pci_dev); | 359 | error = drv->resume_early(pci_dev); |
362 | return error; | 360 | return error; |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 5a14b73cf3a1..6bfb942428e4 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -68,12 +68,14 @@ pci_max_busnr(void) | |||
68 | 68 | ||
69 | #endif /* 0 */ | 69 | #endif /* 0 */ |
70 | 70 | ||
71 | static int __pci_find_next_cap(struct pci_bus *bus, unsigned int devfn, u8 pos, int cap) | 71 | #define PCI_FIND_CAP_TTL 48 |
72 | |||
73 | static int __pci_find_next_cap_ttl(struct pci_bus *bus, unsigned int devfn, | ||
74 | u8 pos, int cap, int *ttl) | ||
72 | { | 75 | { |
73 | u8 id; | 76 | u8 id; |
74 | int ttl = 48; | ||
75 | 77 | ||
76 | while (ttl--) { | 78 | while ((*ttl)--) { |
77 | pci_bus_read_config_byte(bus, devfn, pos, &pos); | 79 | pci_bus_read_config_byte(bus, devfn, pos, &pos); |
78 | if (pos < 0x40) | 80 | if (pos < 0x40) |
79 | break; | 81 | break; |
@@ -89,6 +91,14 @@ static int __pci_find_next_cap(struct pci_bus *bus, unsigned int devfn, u8 pos, | |||
89 | return 0; | 91 | return 0; |
90 | } | 92 | } |
91 | 93 | ||
94 | static int __pci_find_next_cap(struct pci_bus *bus, unsigned int devfn, | ||
95 | u8 pos, int cap) | ||
96 | { | ||
97 | int ttl = PCI_FIND_CAP_TTL; | ||
98 | |||
99 | return __pci_find_next_cap_ttl(bus, devfn, pos, cap, &ttl); | ||
100 | } | ||
101 | |||
92 | int pci_find_next_capability(struct pci_dev *dev, u8 pos, int cap) | 102 | int pci_find_next_capability(struct pci_dev *dev, u8 pos, int cap) |
93 | { | 103 | { |
94 | return __pci_find_next_cap(dev->bus, dev->devfn, | 104 | 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) | |||
96 | } | 106 | } |
97 | EXPORT_SYMBOL_GPL(pci_find_next_capability); | 107 | EXPORT_SYMBOL_GPL(pci_find_next_capability); |
98 | 108 | ||
99 | static int __pci_bus_find_cap(struct pci_bus *bus, unsigned int devfn, u8 hdr_type, int cap) | 109 | static int __pci_bus_find_cap_start(struct pci_bus *bus, |
110 | unsigned int devfn, u8 hdr_type) | ||
100 | { | 111 | { |
101 | u16 status; | 112 | u16 status; |
102 | u8 pos; | ||
103 | 113 | ||
104 | pci_bus_read_config_word(bus, devfn, PCI_STATUS, &status); | 114 | pci_bus_read_config_word(bus, devfn, PCI_STATUS, &status); |
105 | if (!(status & PCI_STATUS_CAP_LIST)) | 115 | 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 | |||
108 | switch (hdr_type) { | 118 | switch (hdr_type) { |
109 | case PCI_HEADER_TYPE_NORMAL: | 119 | case PCI_HEADER_TYPE_NORMAL: |
110 | case PCI_HEADER_TYPE_BRIDGE: | 120 | case PCI_HEADER_TYPE_BRIDGE: |
111 | pos = PCI_CAPABILITY_LIST; | 121 | return PCI_CAPABILITY_LIST; |
112 | break; | ||
113 | case PCI_HEADER_TYPE_CARDBUS: | 122 | case PCI_HEADER_TYPE_CARDBUS: |
114 | pos = PCI_CB_CAPABILITY_LIST; | 123 | return PCI_CB_CAPABILITY_LIST; |
115 | break; | ||
116 | default: | 124 | default: |
117 | return 0; | 125 | return 0; |
118 | } | 126 | } |
119 | return __pci_find_next_cap(bus, devfn, pos, cap); | 127 | |
128 | return 0; | ||
120 | } | 129 | } |
121 | 130 | ||
122 | /** | 131 | /** |
@@ -140,7 +149,13 @@ static int __pci_bus_find_cap(struct pci_bus *bus, unsigned int devfn, u8 hdr_ty | |||
140 | */ | 149 | */ |
141 | int pci_find_capability(struct pci_dev *dev, int cap) | 150 | int pci_find_capability(struct pci_dev *dev, int cap) |
142 | { | 151 | { |
143 | return __pci_bus_find_cap(dev->bus, dev->devfn, dev->hdr_type, cap); | 152 | int pos; |
153 | |||
154 | pos = __pci_bus_find_cap_start(dev->bus, dev->devfn, dev->hdr_type); | ||
155 | if (pos) | ||
156 | pos = __pci_find_next_cap(dev->bus, dev->devfn, pos, cap); | ||
157 | |||
158 | return pos; | ||
144 | } | 159 | } |
145 | 160 | ||
146 | /** | 161 | /** |
@@ -158,11 +173,16 @@ int pci_find_capability(struct pci_dev *dev, int cap) | |||
158 | */ | 173 | */ |
159 | int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap) | 174 | int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap) |
160 | { | 175 | { |
176 | int pos; | ||
161 | u8 hdr_type; | 177 | u8 hdr_type; |
162 | 178 | ||
163 | pci_bus_read_config_byte(bus, devfn, PCI_HEADER_TYPE, &hdr_type); | 179 | pci_bus_read_config_byte(bus, devfn, PCI_HEADER_TYPE, &hdr_type); |
164 | 180 | ||
165 | return __pci_bus_find_cap(bus, devfn, hdr_type & 0x7f, cap); | 181 | pos = __pci_bus_find_cap_start(bus, devfn, hdr_type & 0x7f); |
182 | if (pos) | ||
183 | pos = __pci_find_next_cap(bus, devfn, pos, cap); | ||
184 | |||
185 | return pos; | ||
166 | } | 186 | } |
167 | 187 | ||
168 | /** | 188 | /** |
@@ -214,6 +234,74 @@ int pci_find_ext_capability(struct pci_dev *dev, int cap) | |||
214 | } | 234 | } |
215 | EXPORT_SYMBOL_GPL(pci_find_ext_capability); | 235 | EXPORT_SYMBOL_GPL(pci_find_ext_capability); |
216 | 236 | ||
237 | static int __pci_find_next_ht_cap(struct pci_dev *dev, int pos, int ht_cap) | ||
238 | { | ||
239 | int rc, ttl = PCI_FIND_CAP_TTL; | ||
240 | u8 cap, mask; | ||
241 | |||
242 | if (ht_cap == HT_CAPTYPE_SLAVE || ht_cap == HT_CAPTYPE_HOST) | ||
243 | mask = HT_3BIT_CAP_MASK; | ||
244 | else | ||
245 | mask = HT_5BIT_CAP_MASK; | ||
246 | |||
247 | pos = __pci_find_next_cap_ttl(dev->bus, dev->devfn, pos, | ||
248 | PCI_CAP_ID_HT, &ttl); | ||
249 | while (pos) { | ||
250 | rc = pci_read_config_byte(dev, pos + 3, &cap); | ||
251 | if (rc != PCIBIOS_SUCCESSFUL) | ||
252 | return 0; | ||
253 | |||
254 | if ((cap & mask) == ht_cap) | ||
255 | return pos; | ||
256 | |||
257 | pos = __pci_find_next_cap_ttl(dev->bus, dev->devfn, pos, | ||
258 | PCI_CAP_ID_HT, &ttl); | ||
259 | } | ||
260 | |||
261 | return 0; | ||
262 | } | ||
263 | /** | ||
264 | * pci_find_next_ht_capability - query a device's Hypertransport capabilities | ||
265 | * @dev: PCI device to query | ||
266 | * @pos: Position from which to continue searching | ||
267 | * @ht_cap: Hypertransport capability code | ||
268 | * | ||
269 | * To be used in conjunction with pci_find_ht_capability() to search for | ||
270 | * all capabilities matching @ht_cap. @pos should always be a value returned | ||
271 | * from pci_find_ht_capability(). | ||
272 | * | ||
273 | * NB. To be 100% safe against broken PCI devices, the caller should take | ||
274 | * steps to avoid an infinite loop. | ||
275 | */ | ||
276 | int pci_find_next_ht_capability(struct pci_dev *dev, int pos, int ht_cap) | ||
277 | { | ||
278 | return __pci_find_next_ht_cap(dev, pos + PCI_CAP_LIST_NEXT, ht_cap); | ||
279 | } | ||
280 | EXPORT_SYMBOL_GPL(pci_find_next_ht_capability); | ||
281 | |||
282 | /** | ||
283 | * pci_find_ht_capability - query a device's Hypertransport capabilities | ||
284 | * @dev: PCI device to query | ||
285 | * @ht_cap: Hypertransport capability code | ||
286 | * | ||
287 | * Tell if a device supports a given Hypertransport capability. | ||
288 | * Returns an address within the device's PCI configuration space | ||
289 | * or 0 in case the device does not support the request capability. | ||
290 | * The address points to the PCI capability, of type PCI_CAP_ID_HT, | ||
291 | * which has a Hypertransport capability matching @ht_cap. | ||
292 | */ | ||
293 | int pci_find_ht_capability(struct pci_dev *dev, int ht_cap) | ||
294 | { | ||
295 | int pos; | ||
296 | |||
297 | pos = __pci_bus_find_cap_start(dev->bus, dev->devfn, dev->hdr_type); | ||
298 | if (pos) | ||
299 | pos = __pci_find_next_ht_cap(dev, pos, ht_cap); | ||
300 | |||
301 | return pos; | ||
302 | } | ||
303 | EXPORT_SYMBOL_GPL(pci_find_ht_capability); | ||
304 | |||
217 | /** | 305 | /** |
218 | * pci_find_parent_resource - return resource region of parent bus of given region | 306 | * pci_find_parent_resource - return resource region of parent bus of given region |
219 | * @dev: PCI device structure contains resources to be searched | 307 | * @dev: PCI device structure contains resources to be searched |
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index b4da7954611e..f17e7ed2b2a5 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c | |||
@@ -90,7 +90,7 @@ static int __devinit pcie_portdrv_probe (struct pci_dev *dev, | |||
90 | return -ENODEV; | 90 | return -ENODEV; |
91 | 91 | ||
92 | pci_set_master(dev); | 92 | pci_set_master(dev); |
93 | if (!dev->irq) { | 93 | if (!dev->irq && dev->pin) { |
94 | printk(KERN_WARNING | 94 | printk(KERN_WARNING |
95 | "%s->Dev[%04x:%04x] has invalid IRQ. Check vendor BIOS\n", | 95 | "%s->Dev[%04x:%04x] has invalid IRQ. Check vendor BIOS\n", |
96 | __FUNCTION__, dev->device, dev->vendor); | 96 | __FUNCTION__, dev->device, dev->vendor); |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 6a3c1e728900..1ae9c3f50ffa 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -649,6 +649,9 @@ static void pci_read_irq(struct pci_dev *dev) | |||
649 | * Returns 0 on success and -1 if unknown type of device (not normal, bridge | 649 | * Returns 0 on success and -1 if unknown type of device (not normal, bridge |
650 | * or CardBus). | 650 | * or CardBus). |
651 | */ | 651 | */ |
652 | |||
653 | #define LEGACY_IO_RESOURCE (IORESOURCE_IO | IORESOURCE_PCI_FIXED) | ||
654 | |||
652 | static int pci_setup_device(struct pci_dev * dev) | 655 | static int pci_setup_device(struct pci_dev * dev) |
653 | { | 656 | { |
654 | u32 class; | 657 | u32 class; |
@@ -692,18 +695,18 @@ static int pci_setup_device(struct pci_dev * dev) | |||
692 | if ((progif & 1) == 0) { | 695 | if ((progif & 1) == 0) { |
693 | dev->resource[0].start = 0x1F0; | 696 | dev->resource[0].start = 0x1F0; |
694 | dev->resource[0].end = 0x1F7; | 697 | dev->resource[0].end = 0x1F7; |
695 | dev->resource[0].flags = IORESOURCE_IO; | 698 | dev->resource[0].flags = LEGACY_IO_RESOURCE; |
696 | dev->resource[1].start = 0x3F6; | 699 | dev->resource[1].start = 0x3F6; |
697 | dev->resource[1].end = 0x3F6; | 700 | dev->resource[1].end = 0x3F6; |
698 | dev->resource[1].flags = IORESOURCE_IO; | 701 | dev->resource[1].flags = LEGACY_IO_RESOURCE; |
699 | } | 702 | } |
700 | if ((progif & 4) == 0) { | 703 | if ((progif & 4) == 0) { |
701 | dev->resource[2].start = 0x170; | 704 | dev->resource[2].start = 0x170; |
702 | dev->resource[2].end = 0x177; | 705 | dev->resource[2].end = 0x177; |
703 | dev->resource[2].flags = IORESOURCE_IO; | 706 | dev->resource[2].flags = LEGACY_IO_RESOURCE; |
704 | dev->resource[3].start = 0x376; | 707 | dev->resource[3].start = 0x376; |
705 | dev->resource[3].end = 0x376; | 708 | dev->resource[3].end = 0x376; |
706 | dev->resource[3].flags = IORESOURCE_IO; | 709 | dev->resource[3].flags = LEGACY_IO_RESOURCE; |
707 | } | 710 | } |
708 | } | 711 | } |
709 | break; | 712 | break; |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 9ca9b9bf6160..8f0322d6f3bf 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -36,7 +36,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_MELLANOX,PCI_DEVICE_ID_MELLANOX_TAVOR_BRID | |||
36 | 36 | ||
37 | /* Deal with broken BIOS'es that neglect to enable passive release, | 37 | /* Deal with broken BIOS'es that neglect to enable passive release, |
38 | which can cause problems in combination with the 82441FX/PPro MTRRs */ | 38 | which can cause problems in combination with the 82441FX/PPro MTRRs */ |
39 | static void __devinit quirk_passive_release(struct pci_dev *dev) | 39 | static void quirk_passive_release(struct pci_dev *dev) |
40 | { | 40 | { |
41 | struct pci_dev *d = NULL; | 41 | struct pci_dev *d = NULL; |
42 | unsigned char dlc; | 42 | unsigned char dlc; |
@@ -53,6 +53,7 @@ static void __devinit quirk_passive_release(struct pci_dev *dev) | |||
53 | } | 53 | } |
54 | } | 54 | } |
55 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, quirk_passive_release ); | 55 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, quirk_passive_release ); |
56 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, quirk_passive_release ); | ||
56 | 57 | ||
57 | /* The VIA VP2/VP3/MVP3 seem to have some 'features'. There may be a workaround | 58 | /* The VIA VP2/VP3/MVP3 seem to have some 'features'. There may be a workaround |
58 | but VIA don't answer queries. If you happen to have good contacts at VIA | 59 | 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 | |||
134 | * Updated based on further information from the site and also on | 135 | * Updated based on further information from the site and also on |
135 | * information provided by VIA | 136 | * information provided by VIA |
136 | */ | 137 | */ |
137 | static void __devinit quirk_vialatency(struct pci_dev *dev) | 138 | static void quirk_vialatency(struct pci_dev *dev) |
138 | { | 139 | { |
139 | struct pci_dev *p; | 140 | struct pci_dev *p; |
140 | u8 rev; | 141 | u8 rev; |
@@ -185,6 +186,10 @@ exit: | |||
185 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, quirk_vialatency ); | 186 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, quirk_vialatency ); |
186 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8371_1, quirk_vialatency ); | 187 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8371_1, quirk_vialatency ); |
187 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, quirk_vialatency ); | 188 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, quirk_vialatency ); |
189 | /* Must restore this on a resume from RAM */ | ||
190 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, quirk_vialatency ); | ||
191 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8371_1, quirk_vialatency ); | ||
192 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, quirk_vialatency ); | ||
188 | 193 | ||
189 | /* | 194 | /* |
190 | * VIA Apollo VP3 needs ETBF on BT848/878 | 195 | * 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 | |||
532 | * TODO: When we have device-specific interrupt routers, | 537 | * TODO: When we have device-specific interrupt routers, |
533 | * this code will go away from quirks. | 538 | * this code will go away from quirks. |
534 | */ | 539 | */ |
535 | static void __devinit quirk_via_ioapic(struct pci_dev *dev) | 540 | static void quirk_via_ioapic(struct pci_dev *dev) |
536 | { | 541 | { |
537 | u8 tmp; | 542 | u8 tmp; |
538 | 543 | ||
@@ -548,6 +553,7 @@ static void __devinit quirk_via_ioapic(struct pci_dev *dev) | |||
548 | pci_write_config_byte (dev, 0x58, tmp); | 553 | pci_write_config_byte (dev, 0x58, tmp); |
549 | } | 554 | } |
550 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_ioapic ); | 555 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_ioapic ); |
556 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_ioapic ); | ||
551 | 557 | ||
552 | /* | 558 | /* |
553 | * VIA 8237: Some BIOSs don't set the 'Bypass APIC De-Assert Message' Bit. | 559 | * 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 | |||
555 | * Set this bit to get rid of cycle wastage. | 561 | * Set this bit to get rid of cycle wastage. |
556 | * Otherwise uncritical. | 562 | * Otherwise uncritical. |
557 | */ | 563 | */ |
558 | static void __devinit quirk_via_vt8237_bypass_apic_deassert(struct pci_dev *dev) | 564 | static void quirk_via_vt8237_bypass_apic_deassert(struct pci_dev *dev) |
559 | { | 565 | { |
560 | u8 misc_control2; | 566 | u8 misc_control2; |
561 | #define BYPASS_APIC_DEASSERT 8 | 567 | #define BYPASS_APIC_DEASSERT 8 |
@@ -567,6 +573,7 @@ static void __devinit quirk_via_vt8237_bypass_apic_deassert(struct pci_dev *dev) | |||
567 | } | 573 | } |
568 | } | 574 | } |
569 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_vt8237_bypass_apic_deassert); | 575 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_vt8237_bypass_apic_deassert); |
576 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_vt8237_bypass_apic_deassert); | ||
570 | 577 | ||
571 | /* | 578 | /* |
572 | * The AMD io apic can hang the box when an apic irq is masked. | 579 | * 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 ); | |||
600 | #define AMD8131_revB0 0x11 | 607 | #define AMD8131_revB0 0x11 |
601 | #define AMD8131_MISC 0x40 | 608 | #define AMD8131_MISC 0x40 |
602 | #define AMD8131_NIOAMODE_BIT 0 | 609 | #define AMD8131_NIOAMODE_BIT 0 |
603 | static void __init quirk_amd_8131_ioapic(struct pci_dev *dev) | 610 | static void quirk_amd_8131_ioapic(struct pci_dev *dev) |
604 | { | 611 | { |
605 | unsigned char revid, tmp; | 612 | unsigned char revid, tmp; |
606 | 613 | ||
@@ -616,6 +623,7 @@ static void __init quirk_amd_8131_ioapic(struct pci_dev *dev) | |||
616 | } | 623 | } |
617 | } | 624 | } |
618 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic); | 625 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic); |
626 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic); | ||
619 | #endif /* CONFIG_X86_IO_APIC */ | 627 | #endif /* CONFIG_X86_IO_APIC */ |
620 | 628 | ||
621 | 629 | ||
@@ -641,65 +649,84 @@ static void __devinit quirk_via_acpi(struct pci_dev *d) | |||
641 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_via_acpi ); | 649 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_via_acpi ); |
642 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_via_acpi ); | 650 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_via_acpi ); |
643 | 651 | ||
644 | /* | ||
645 | * Via 686A/B: The PCI_INTERRUPT_LINE register for the on-chip | ||
646 | * devices, USB0/1, AC97, MC97, and ACPI, has an unusual feature: | ||
647 | * when written, it makes an internal connection to the PIC. | ||
648 | * For these devices, this register is defined to be 4 bits wide. | ||
649 | * Normally this is fine. However for IO-APIC motherboards, or | ||
650 | * non-x86 architectures (yes Via exists on PPC among other places), | ||
651 | * we must mask the PCI_INTERRUPT_LINE value versus 0xf to get | ||
652 | * interrupts delivered properly. | ||
653 | * | ||
654 | * Some of the on-chip devices are actually '586 devices' so they are | ||
655 | * listed here. | ||
656 | */ | ||
657 | |||
658 | static int via_irq_fixup_needed = -1; | ||
659 | 652 | ||
660 | /* | 653 | /* |
661 | * As some VIA hardware is available in PCI-card form, we need to restrict | 654 | * VIA bridges which have VLink |
662 | * this quirk to VIA PCI hardware built onto VIA-based motherboards only. | ||
663 | * We try to locate a VIA southbridge before deciding whether the quirk | ||
664 | * should be applied. | ||
665 | */ | 655 | */ |
666 | static const struct pci_device_id via_irq_fixup_tbl[] = { | 656 | |
667 | { | 657 | static const struct pci_device_id via_vlink_fixup_tbl[] = { |
668 | .vendor = PCI_VENDOR_ID_VIA, | 658 | /* Internal devices need IRQ line routing, pre VLink */ |
669 | .device = PCI_ANY_ID, | 659 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C686), 0 }, |
670 | .subvendor = PCI_ANY_ID, | 660 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8231), 17 }, |
671 | .subdevice = PCI_ANY_ID, | 661 | /* Devices with VLink */ |
672 | .class = PCI_CLASS_BRIDGE_ISA << 8, | 662 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8233_0), 17}, |
673 | .class_mask = 0xffff00, | 663 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8233A), 17 }, |
674 | }, | 664 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8233C_0), 17 }, |
665 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8235), 16 }, | ||
666 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8237), 15 }, | ||
667 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8237A), 15 }, | ||
675 | { 0, }, | 668 | { 0, }, |
676 | }; | 669 | }; |
677 | 670 | ||
678 | static void quirk_via_irq(struct pci_dev *dev) | 671 | /** |
672 | * quirk_via_vlink - VIA VLink IRQ number update | ||
673 | * @dev: PCI device | ||
674 | * | ||
675 | * If the device we are dealing with is on a PIC IRQ we need to | ||
676 | * ensure that the IRQ line register which usually is not relevant | ||
677 | * for PCI cards, is actually written so that interrupts get sent | ||
678 | * to the right place | ||
679 | */ | ||
680 | |||
681 | static void quirk_via_vlink(struct pci_dev *dev) | ||
679 | { | 682 | { |
683 | const struct pci_device_id *via_vlink_fixup; | ||
684 | static int dev_lo = -1, dev_hi = 18; | ||
680 | u8 irq, new_irq; | 685 | u8 irq, new_irq; |
681 | 686 | ||
682 | if (via_irq_fixup_needed == -1) | 687 | /* Check if we have VLink and cache the result */ |
683 | via_irq_fixup_needed = pci_dev_present(via_irq_fixup_tbl); | ||
684 | 688 | ||
685 | if (!via_irq_fixup_needed) | 689 | /* Checked already - no */ |
690 | if (dev_lo == -2) | ||
686 | return; | 691 | return; |
687 | 692 | ||
693 | /* Not checked - see what bridge we have and find the device | ||
694 | ranges */ | ||
695 | |||
696 | if (dev_lo == -1) { | ||
697 | via_vlink_fixup = pci_find_present(via_vlink_fixup_tbl); | ||
698 | if (via_vlink_fixup == NULL) { | ||
699 | dev_lo = -2; | ||
700 | return; | ||
701 | } | ||
702 | dev_lo = via_vlink_fixup->driver_data; | ||
703 | /* 82C686 is special - 0/0 */ | ||
704 | if (dev_lo == 0) | ||
705 | dev_hi = 0; | ||
706 | } | ||
688 | new_irq = dev->irq; | 707 | new_irq = dev->irq; |
689 | 708 | ||
690 | /* Don't quirk interrupts outside the legacy IRQ range */ | 709 | /* Don't quirk interrupts outside the legacy IRQ range */ |
691 | if (!new_irq || new_irq > 15) | 710 | if (!new_irq || new_irq > 15) |
692 | return; | 711 | return; |
693 | 712 | ||
713 | /* Internal device ? */ | ||
714 | if (dev->bus->number != 0 || PCI_SLOT(dev->devfn) > dev_hi || | ||
715 | PCI_SLOT(dev->devfn) < dev_lo) | ||
716 | return; | ||
717 | |||
718 | /* This is an internal VLink device on a PIC interrupt. The BIOS | ||
719 | ought to have set this but may not have, so we redo it */ | ||
720 | |||
694 | pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); | 721 | pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); |
695 | if (new_irq != irq) { | 722 | if (new_irq != irq) { |
696 | printk(KERN_INFO "PCI: VIA IRQ fixup for %s, from %d to %d\n", | 723 | printk(KERN_INFO "PCI: VIA VLink IRQ fixup for %s, from %d to %d\n", |
697 | pci_name(dev), irq, new_irq); | 724 | pci_name(dev), irq, new_irq); |
698 | udelay(15); /* unknown if delay really needed */ | 725 | udelay(15); /* unknown if delay really needed */ |
699 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq); | 726 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq); |
700 | } | 727 | } |
701 | } | 728 | } |
702 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irq); | 729 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_vlink); |
703 | 730 | ||
704 | /* | 731 | /* |
705 | * VIA VT82C598 has its device ID settable and many BIOSes | 732 | * 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 | |||
720 | * do this even if the Linux CardBus driver is not loaded, because | 747 | * do this even if the Linux CardBus driver is not loaded, because |
721 | * the Linux i82365 driver does not (and should not) handle CardBus. | 748 | * the Linux i82365 driver does not (and should not) handle CardBus. |
722 | */ | 749 | */ |
723 | static void __devinit quirk_cardbus_legacy(struct pci_dev *dev) | 750 | static void quirk_cardbus_legacy(struct pci_dev *dev) |
724 | { | 751 | { |
725 | if ((PCI_CLASS_BRIDGE_CARDBUS << 8) ^ dev->class) | 752 | if ((PCI_CLASS_BRIDGE_CARDBUS << 8) ^ dev->class) |
726 | return; | 753 | return; |
727 | pci_write_config_dword(dev, PCI_CB_LEGACY_MODE_BASE, 0); | 754 | pci_write_config_dword(dev, PCI_CB_LEGACY_MODE_BASE, 0); |
728 | } | 755 | } |
729 | DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy); | 756 | DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy); |
757 | DECLARE_PCI_FIXUP_RESUME(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy); | ||
730 | 758 | ||
731 | /* | 759 | /* |
732 | * Following the PCI ordering rules is optional on the AMD762. I'm not | 760 | * 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); | |||
735 | * To be fair to AMD, it follows the spec by default, its BIOS people | 763 | * To be fair to AMD, it follows the spec by default, its BIOS people |
736 | * who turn it off! | 764 | * who turn it off! |
737 | */ | 765 | */ |
738 | static void __devinit quirk_amd_ordering(struct pci_dev *dev) | 766 | static void quirk_amd_ordering(struct pci_dev *dev) |
739 | { | 767 | { |
740 | u32 pcic; | 768 | u32 pcic; |
741 | pci_read_config_dword(dev, 0x4C, &pcic); | 769 | pci_read_config_dword(dev, 0x4C, &pcic); |
@@ -749,6 +777,7 @@ static void __devinit quirk_amd_ordering(struct pci_dev *dev) | |||
749 | } | 777 | } |
750 | } | 778 | } |
751 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering ); | 779 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering ); |
780 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering ); | ||
752 | 781 | ||
753 | /* | 782 | /* |
754 | * DreamWorks provided workaround for Dunord I-3000 problem | 783 | * DreamWorks provided workaround for Dunord I-3000 problem |
@@ -784,7 +813,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TOSHIBA, 0x605, quirk_transparent_bridge | |||
784 | * datasheets found at http://www.national.com/ds/GX for info on what | 813 | * datasheets found at http://www.national.com/ds/GX for info on what |
785 | * these bits do. <christer@weinigel.se> | 814 | * these bits do. <christer@weinigel.se> |
786 | */ | 815 | */ |
787 | static void __init quirk_mediagx_master(struct pci_dev *dev) | 816 | static void quirk_mediagx_master(struct pci_dev *dev) |
788 | { | 817 | { |
789 | u8 reg; | 818 | u8 reg; |
790 | pci_read_config_byte(dev, 0x41, ®); | 819 | pci_read_config_byte(dev, 0x41, ®); |
@@ -795,13 +824,14 @@ static void __init quirk_mediagx_master(struct pci_dev *dev) | |||
795 | } | 824 | } |
796 | } | 825 | } |
797 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_PCI_MASTER, quirk_mediagx_master ); | 826 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_PCI_MASTER, quirk_mediagx_master ); |
827 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_PCI_MASTER, quirk_mediagx_master ); | ||
798 | 828 | ||
799 | /* | 829 | /* |
800 | * Ensure C0 rev restreaming is off. This is normally done by | 830 | * Ensure C0 rev restreaming is off. This is normally done by |
801 | * the BIOS but in the odd case it is not the results are corruption | 831 | * the BIOS but in the odd case it is not the results are corruption |
802 | * hence the presence of a Linux check | 832 | * hence the presence of a Linux check |
803 | */ | 833 | */ |
804 | static void __init quirk_disable_pxb(struct pci_dev *pdev) | 834 | static void quirk_disable_pxb(struct pci_dev *pdev) |
805 | { | 835 | { |
806 | u16 config; | 836 | u16 config; |
807 | u8 rev; | 837 | u8 rev; |
@@ -817,7 +847,25 @@ static void __init quirk_disable_pxb(struct pci_dev *pdev) | |||
817 | } | 847 | } |
818 | } | 848 | } |
819 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb ); | 849 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb ); |
850 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb ); | ||
851 | |||
852 | |||
853 | static void __devinit quirk_sb600_sata(struct pci_dev *pdev) | ||
854 | { | ||
855 | /* set sb600 sata to ahci mode */ | ||
856 | if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) { | ||
857 | u8 tmp; | ||
820 | 858 | ||
859 | pci_read_config_byte(pdev, 0x40, &tmp); | ||
860 | pci_write_config_byte(pdev, 0x40, tmp|1); | ||
861 | pci_write_config_byte(pdev, 0x9, 1); | ||
862 | pci_write_config_byte(pdev, 0xa, 6); | ||
863 | pci_write_config_byte(pdev, 0x40, tmp); | ||
864 | |||
865 | pdev->class = 0x010601; | ||
866 | } | ||
867 | } | ||
868 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_sb600_sata); | ||
821 | 869 | ||
822 | /* | 870 | /* |
823 | * Serverworks CSB5 IDE does not fully support native mode | 871 | * 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 | |||
874 | * runs everywhere at present we suppress the printk output in most | 922 | * runs everywhere at present we suppress the printk output in most |
875 | * irrelevant cases. | 923 | * irrelevant cases. |
876 | */ | 924 | */ |
877 | static void __init k8t_sound_hostbridge(struct pci_dev *dev) | 925 | static void k8t_sound_hostbridge(struct pci_dev *dev) |
878 | { | 926 | { |
879 | unsigned char val; | 927 | unsigned char val; |
880 | 928 | ||
@@ -893,8 +941,8 @@ static void __init k8t_sound_hostbridge(struct pci_dev *dev) | |||
893 | } | 941 | } |
894 | } | 942 | } |
895 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, k8t_sound_hostbridge); | 943 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, k8t_sound_hostbridge); |
944 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, k8t_sound_hostbridge); | ||
896 | 945 | ||
897 | #ifndef CONFIG_ACPI_SLEEP | ||
898 | /* | 946 | /* |
899 | * On ASUS P4B boards, the SMBus PCI Device within the ICH2/4 southbridge | 947 | * On ASUS P4B boards, the SMBus PCI Device within the ICH2/4 southbridge |
900 | * is not activated. The myth is that Asus said that they do not want the | 948 | * 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 | |||
906 | * bridge. Unfortunately, this device has no subvendor/subdevice ID. So it | 954 | * bridge. Unfortunately, this device has no subvendor/subdevice ID. So it |
907 | * becomes necessary to do this tweak in two steps -- I've chosen the Host | 955 | * becomes necessary to do this tweak in two steps -- I've chosen the Host |
908 | * bridge as trigger. | 956 | * bridge as trigger. |
909 | * | ||
910 | * Actually, leaving it unhidden and not redoing the quirk over suspend2ram | ||
911 | * will cause thermal management to break down, and causing machine to | ||
912 | * overheat. | ||
913 | */ | 957 | */ |
914 | static int __initdata asus_hides_smbus; | 958 | static int __initdata asus_hides_smbus; |
915 | 959 | ||
@@ -1019,7 +1063,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855PM_HB, as | |||
1019 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855GM_HB, asus_hides_smbus_hostbridge ); | 1063 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855GM_HB, asus_hides_smbus_hostbridge ); |
1020 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82915GM_HB, asus_hides_smbus_hostbridge ); | 1064 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82915GM_HB, asus_hides_smbus_hostbridge ); |
1021 | 1065 | ||
1022 | static void __init asus_hides_smbus_lpc(struct pci_dev *dev) | 1066 | static void asus_hides_smbus_lpc(struct pci_dev *dev) |
1023 | { | 1067 | { |
1024 | u16 val; | 1068 | u16 val; |
1025 | 1069 | ||
@@ -1042,8 +1086,14 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, asu | |||
1042 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc ); | 1086 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc ); |
1043 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc ); | 1087 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc ); |
1044 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc ); | 1088 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc ); |
1089 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, asus_hides_smbus_lpc ); | ||
1090 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, asus_hides_smbus_lpc ); | ||
1091 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, asus_hides_smbus_lpc ); | ||
1092 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc ); | ||
1093 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc ); | ||
1094 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc ); | ||
1045 | 1095 | ||
1046 | static void __init asus_hides_smbus_lpc_ich6(struct pci_dev *dev) | 1096 | static void asus_hides_smbus_lpc_ich6(struct pci_dev *dev) |
1047 | { | 1097 | { |
1048 | u32 val, rcba; | 1098 | u32 val, rcba; |
1049 | void __iomem *base; | 1099 | void __iomem *base; |
@@ -1059,13 +1109,12 @@ static void __init asus_hides_smbus_lpc_ich6(struct pci_dev *dev) | |||
1059 | printk(KERN_INFO "PCI: Enabled ICH6/i801 SMBus device\n"); | 1109 | printk(KERN_INFO "PCI: Enabled ICH6/i801 SMBus device\n"); |
1060 | } | 1110 | } |
1061 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6 ); | 1111 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6 ); |
1062 | 1112 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6 ); | |
1063 | #endif | ||
1064 | 1113 | ||
1065 | /* | 1114 | /* |
1066 | * SiS 96x south bridge: BIOS typically hides SMBus device... | 1115 | * SiS 96x south bridge: BIOS typically hides SMBus device... |
1067 | */ | 1116 | */ |
1068 | static void __init quirk_sis_96x_smbus(struct pci_dev *dev) | 1117 | static void quirk_sis_96x_smbus(struct pci_dev *dev) |
1069 | { | 1118 | { |
1070 | u8 val = 0; | 1119 | u8 val = 0; |
1071 | printk(KERN_INFO "Enabling SiS 96x SMBus.\n"); | 1120 | printk(KERN_INFO "Enabling SiS 96x SMBus.\n"); |
@@ -1086,7 +1135,7 @@ static int __devinitdata sis_96x_compatible = 0; | |||
1086 | 1135 | ||
1087 | #define SIS_DETECT_REGISTER 0x40 | 1136 | #define SIS_DETECT_REGISTER 0x40 |
1088 | 1137 | ||
1089 | static void __init quirk_sis_503(struct pci_dev *dev) | 1138 | static void quirk_sis_503(struct pci_dev *dev) |
1090 | { | 1139 | { |
1091 | u8 reg; | 1140 | u8 reg; |
1092 | u16 devid; | 1141 | u16 devid; |
@@ -1122,13 +1171,14 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_651, quirk_sis_96x_ | |||
1122 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_735, quirk_sis_96x_compatible ); | 1171 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_735, quirk_sis_96x_compatible ); |
1123 | 1172 | ||
1124 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503 ); | 1173 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503 ); |
1174 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503 ); | ||
1125 | /* | 1175 | /* |
1126 | * On ASUS A8V and A8V Deluxe boards, the onboard AC97 audio controller | 1176 | * On ASUS A8V and A8V Deluxe boards, the onboard AC97 audio controller |
1127 | * and MC97 modem controller are disabled when a second PCI soundcard is | 1177 | * and MC97 modem controller are disabled when a second PCI soundcard is |
1128 | * present. This patch, tweaking the VT8237 ISA bridge, enables them. | 1178 | * present. This patch, tweaking the VT8237 ISA bridge, enables them. |
1129 | * -- bjd | 1179 | * -- bjd |
1130 | */ | 1180 | */ |
1131 | static void __init asus_hides_ac97_lpc(struct pci_dev *dev) | 1181 | static void asus_hides_ac97_lpc(struct pci_dev *dev) |
1132 | { | 1182 | { |
1133 | u8 val; | 1183 | u8 val; |
1134 | int asus_hides_ac97 = 0; | 1184 | 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_ | |||
1159 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus ); | 1209 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus ); |
1160 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus ); | 1210 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus ); |
1161 | 1211 | ||
1212 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc ); | ||
1213 | |||
1214 | |||
1215 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_961, quirk_sis_96x_smbus ); | ||
1216 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_smbus ); | ||
1217 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus ); | ||
1218 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus ); | ||
1219 | |||
1162 | #if defined(CONFIG_ATA) || defined(CONFIG_ATA_MODULE) | 1220 | #if defined(CONFIG_ATA) || defined(CONFIG_ATA_MODULE) |
1163 | 1221 | ||
1164 | /* | 1222 | /* |
@@ -1167,7 +1225,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_ | |||
1167 | * the PCI scanning. | 1225 | * the PCI scanning. |
1168 | */ | 1226 | */ |
1169 | 1227 | ||
1170 | static void __devinit quirk_jmicron_dualfn(struct pci_dev *pdev) | 1228 | static void quirk_jmicron_dualfn(struct pci_dev *pdev) |
1171 | { | 1229 | { |
1172 | u32 conf; | 1230 | u32 conf; |
1173 | u8 hdr; | 1231 | u8 hdr; |
@@ -1205,6 +1263,7 @@ static void __devinit quirk_jmicron_dualfn(struct pci_dev *pdev) | |||
1205 | } | 1263 | } |
1206 | 1264 | ||
1207 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, quirk_jmicron_dualfn); | 1265 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, quirk_jmicron_dualfn); |
1266 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, quirk_jmicron_dualfn); | ||
1208 | 1267 | ||
1209 | #endif | 1268 | #endif |
1210 | 1269 | ||
@@ -1532,6 +1591,8 @@ extern struct pci_fixup __start_pci_fixups_final[]; | |||
1532 | extern struct pci_fixup __end_pci_fixups_final[]; | 1591 | extern struct pci_fixup __end_pci_fixups_final[]; |
1533 | extern struct pci_fixup __start_pci_fixups_enable[]; | 1592 | extern struct pci_fixup __start_pci_fixups_enable[]; |
1534 | extern struct pci_fixup __end_pci_fixups_enable[]; | 1593 | extern struct pci_fixup __end_pci_fixups_enable[]; |
1594 | extern struct pci_fixup __start_pci_fixups_resume[]; | ||
1595 | extern struct pci_fixup __end_pci_fixups_resume[]; | ||
1535 | 1596 | ||
1536 | 1597 | ||
1537 | void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) | 1598 | 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) | |||
1559 | end = __end_pci_fixups_enable; | 1620 | end = __end_pci_fixups_enable; |
1560 | break; | 1621 | break; |
1561 | 1622 | ||
1623 | case pci_fixup_resume: | ||
1624 | start = __start_pci_fixups_resume; | ||
1625 | end = __end_pci_fixups_resume; | ||
1626 | break; | ||
1627 | |||
1562 | default: | 1628 | default: |
1563 | /* stupid compiler warning, you would think with an enum... */ | 1629 | /* stupid compiler warning, you would think with an enum... */ |
1564 | return; | 1630 | return; |
@@ -1596,7 +1662,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1460, quirk_p64h2_1k_io); | |||
1596 | * Force it to be linked by setting the corresponding control bit in the | 1662 | * Force it to be linked by setting the corresponding control bit in the |
1597 | * config space. | 1663 | * config space. |
1598 | */ | 1664 | */ |
1599 | static void __devinit quirk_nvidia_ck804_pcie_aer_ext_cap(struct pci_dev *dev) | 1665 | static void quirk_nvidia_ck804_pcie_aer_ext_cap(struct pci_dev *dev) |
1600 | { | 1666 | { |
1601 | uint8_t b; | 1667 | uint8_t b; |
1602 | if (pci_read_config_byte(dev, 0xf41, &b) == 0) { | 1668 | 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) | |||
1610 | } | 1676 | } |
1611 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, | 1677 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, |
1612 | quirk_nvidia_ck804_pcie_aer_ext_cap); | 1678 | quirk_nvidia_ck804_pcie_aer_ext_cap); |
1679 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, | ||
1680 | quirk_nvidia_ck804_pcie_aer_ext_cap); | ||
1613 | 1681 | ||
1614 | #ifdef CONFIG_PCI_MSI | 1682 | #ifdef CONFIG_PCI_MSI |
1615 | /* To disable MSI globally */ | 1683 | /* To disable MSI globally */ |
@@ -1644,19 +1712,23 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_ | |||
1644 | * return 1 if a HT MSI capability is found and enabled */ | 1712 | * return 1 if a HT MSI capability is found and enabled */ |
1645 | static int __devinit msi_ht_cap_enabled(struct pci_dev *dev) | 1713 | static int __devinit msi_ht_cap_enabled(struct pci_dev *dev) |
1646 | { | 1714 | { |
1647 | u8 pos; | 1715 | int pos, ttl = 48; |
1648 | int ttl; | 1716 | |
1649 | for (pos = pci_find_capability(dev, PCI_CAP_ID_HT), ttl = 48; | 1717 | pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING); |
1650 | pos && ttl; | 1718 | while (pos && ttl--) { |
1651 | pos = pci_find_next_capability(dev, pos, PCI_CAP_ID_HT), ttl--) { | 1719 | u8 flags; |
1652 | u32 cap_hdr; | 1720 | |
1653 | /* MSI mapping section according to Hypertransport spec */ | 1721 | if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, |
1654 | if (pci_read_config_dword(dev, pos, &cap_hdr) == 0 | 1722 | &flags) == 0) |
1655 | && (cap_hdr & 0xf8000000) == 0xa8000000 /* MSI mapping */) { | 1723 | { |
1656 | printk(KERN_INFO "PCI: Found HT MSI mapping on %s with capability %s\n", | 1724 | printk(KERN_INFO "PCI: Found %s HT MSI Mapping on %s\n", |
1657 | pci_name(dev), cap_hdr & 0x10000 ? "enabled" : "disabled"); | 1725 | flags & HT_MSI_FLAGS_ENABLE ? |
1658 | return (cap_hdr & 0x10000) != 0; /* MSI mapping cap enabled */ | 1726 | "enabled" : "disabled", pci_name(dev)); |
1727 | return (flags & HT_MSI_FLAGS_ENABLE) != 0; | ||
1659 | } | 1728 | } |
1729 | |||
1730 | pos = pci_find_next_ht_capability(dev, pos, | ||
1731 | HT_CAPTYPE_MSI_MAPPING); | ||
1660 | } | 1732 | } |
1661 | return 0; | 1733 | return 0; |
1662 | } | 1734 | } |
@@ -1688,8 +1760,9 @@ static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev) | |||
1688 | * a single one having MSI is enough to be sure that MSI are supported. | 1760 | * a single one having MSI is enough to be sure that MSI are supported. |
1689 | */ | 1761 | */ |
1690 | pdev = pci_get_slot(dev->bus, 0); | 1762 | pdev = pci_get_slot(dev->bus, 0); |
1691 | if (dev->subordinate && !msi_ht_cap_enabled(dev) | 1763 | if (!pdev) |
1692 | && !msi_ht_cap_enabled(pdev)) { | 1764 | return; |
1765 | if (!msi_ht_cap_enabled(dev) && !msi_ht_cap_enabled(pdev)) { | ||
1693 | printk(KERN_WARNING "PCI: MSI quirk detected. " | 1766 | printk(KERN_WARNING "PCI: MSI quirk detected. " |
1694 | "MSI disabled on chipset %s.\n", | 1767 | "MSI disabled on chipset %s.\n", |
1695 | pci_name(dev)); | 1768 | pci_name(dev)); |
diff --git a/drivers/pci/search.c b/drivers/pci/search.c index 2f13eba5d5ae..45f2b20ef513 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c | |||
@@ -413,6 +413,24 @@ exit: | |||
413 | return dev; | 413 | return dev; |
414 | } | 414 | } |
415 | 415 | ||
416 | const struct pci_device_id *pci_find_present(const struct pci_device_id *ids) | ||
417 | { | ||
418 | struct pci_dev *dev; | ||
419 | const struct pci_device_id *found = NULL; | ||
420 | |||
421 | WARN_ON(in_interrupt()); | ||
422 | down_read(&pci_bus_sem); | ||
423 | while (ids->vendor || ids->subvendor || ids->class_mask) { | ||
424 | list_for_each_entry(dev, &pci_devices, global_list) { | ||
425 | if ((found = pci_match_one_device(ids, dev)) != NULL) | ||
426 | break; | ||
427 | } | ||
428 | ids++; | ||
429 | } | ||
430 | up_read(&pci_bus_sem); | ||
431 | return found; | ||
432 | } | ||
433 | |||
416 | /** | 434 | /** |
417 | * pci_dev_present - Returns 1 if device matching the device list is present, 0 if not. | 435 | * pci_dev_present - Returns 1 if device matching the device list is present, 0 if not. |
418 | * @ids: A pointer to a null terminated list of struct pci_device_id structures | 436 | * @ids: A pointer to a null terminated list of struct pci_device_id structures |
@@ -426,25 +444,11 @@ exit: | |||
426 | */ | 444 | */ |
427 | int pci_dev_present(const struct pci_device_id *ids) | 445 | int pci_dev_present(const struct pci_device_id *ids) |
428 | { | 446 | { |
429 | struct pci_dev *dev; | 447 | return pci_find_present(ids) == NULL ? 0 : 1; |
430 | int found = 0; | ||
431 | |||
432 | WARN_ON(in_interrupt()); | ||
433 | down_read(&pci_bus_sem); | ||
434 | while (ids->vendor || ids->subvendor || ids->class_mask) { | ||
435 | list_for_each_entry(dev, &pci_devices, global_list) { | ||
436 | if (pci_match_one_device(ids, dev)) { | ||
437 | found = 1; | ||
438 | goto exit; | ||
439 | } | ||
440 | } | ||
441 | ids++; | ||
442 | } | ||
443 | exit: | ||
444 | up_read(&pci_bus_sem); | ||
445 | return found; | ||
446 | } | 448 | } |
449 | |||
447 | EXPORT_SYMBOL(pci_dev_present); | 450 | EXPORT_SYMBOL(pci_dev_present); |
451 | EXPORT_SYMBOL(pci_find_present); | ||
448 | 452 | ||
449 | EXPORT_SYMBOL(pci_find_device); | 453 | EXPORT_SYMBOL(pci_find_device); |
450 | EXPORT_SYMBOL(pci_find_device_reverse); | 454 | EXPORT_SYMBOL(pci_find_device_reverse); |
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index ab78e4bbdd83..cb4ced3560e9 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c | |||
@@ -33,11 +33,22 @@ pci_update_resource(struct pci_dev *dev, struct resource *res, int resno) | |||
33 | u32 new, check, mask; | 33 | u32 new, check, mask; |
34 | int reg; | 34 | int reg; |
35 | 35 | ||
36 | /* Ignore resources for unimplemented BARs and unused resource slots | 36 | /* |
37 | for 64 bit BARs. */ | 37 | * Ignore resources for unimplemented BARs and unused resource slots |
38 | * for 64 bit BARs. | ||
39 | */ | ||
38 | if (!res->flags) | 40 | if (!res->flags) |
39 | return; | 41 | return; |
40 | 42 | ||
43 | /* | ||
44 | * Ignore non-moveable resources. This might be legacy resources for | ||
45 | * which no functional BAR register exists or another important | ||
46 | * system resource we should better not move around in system address | ||
47 | * space. | ||
48 | */ | ||
49 | if (res->flags & IORESOURCE_PCI_FIXED) | ||
50 | return; | ||
51 | |||
41 | pcibios_resource_to_bus(dev, ®ion, res); | 52 | pcibios_resource_to_bus(dev, ®ion, res); |
42 | 53 | ||
43 | pr_debug(" got res [%llx:%llx] bus [%lx:%lx] flags %lx for " | 54 | 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) | |||
212 | resource_size_t r_align; | 223 | resource_size_t r_align; |
213 | 224 | ||
214 | r = &dev->resource[i]; | 225 | r = &dev->resource[i]; |
226 | |||
227 | if (r->flags & IORESOURCE_PCI_FIXED) | ||
228 | continue; | ||
229 | |||
215 | r_align = r->end - r->start; | 230 | r_align = r->end - r->start; |
216 | 231 | ||
217 | if (!(r->flags) || r->parent) | 232 | if (!(r->flags) || r->parent) |