diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-04-29 12:30:25 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-04-29 12:30:25 -0400 |
commit | 96a3e8af5a54c324535472ca946215d5bafe6539 (patch) | |
tree | e59b48aa3fa2b8c6c1f59f76b7b4c71f9c694093 /drivers/pci | |
parent | a87451052fb914744571fc3ab39fcbf4fa4ef944 (diff) | |
parent | d4f09c5d7fbabd1389a5f03f5c9329d790f544e3 (diff) |
Merge tag 'pci-v3.10-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI updates from Bjorn Helgaas:
"PCI changes for the v3.10 merge window:
PCI device hotplug
- Remove ACPI PCI subdrivers (Jiang Liu, Myron Stowe)
- Make acpiphp builtin only, not modular (Jiang Liu)
- Add acpiphp mutual exclusion (Jiang Liu)
Power management
- Skip "PME enabled/disabled" messages when not supported (Rafael
Wysocki)
- Fix fallback to PCI_D0 (Rafael Wysocki)
Miscellaneous
- Factor quirk_io_region (Yinghai Lu)
- Cache MSI capability offsets & cleanup (Gavin Shan, Bjorn Helgaas)
- Clean up EISA resource initialization and logging (Bjorn Helgaas)
- Fix prototype warnings (Andy Shevchenko, Bjorn Helgaas)
- MIPS: Initialize of_node before scanning bus (Gabor Juhos)
- Fix pcibios_get_phb_of_node() declaration "weak" annotation (Gabor
Juhos)
- Add MSI INTX_DISABLE quirks for AR8161/AR8162/etc (Xiong Huang)
- Fix aer_inject return values (Prarit Bhargava)
- Remove PME/ACPI dependency (Andrew Murray)
- Use shared PCI_BUS_NUM() and PCI_DEVID() (Shuah Khan)"
* tag 'pci-v3.10-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (63 commits)
vfio-pci: Use cached MSI/MSI-X capabilities
vfio-pci: Use PCI_MSIX_TABLE_BIR, not PCI_MSIX_FLAGS_BIRMASK
PCI: Remove "extern" from function declarations
PCI: Use PCI_MSIX_TABLE_BIR, not PCI_MSIX_FLAGS_BIRMASK
PCI: Drop msi_mask_reg() and remove drivers/pci/msi.h
PCI: Use msix_table_size() directly, drop multi_msix_capable()
PCI: Drop msix_table_offset_reg() and msix_pba_offset_reg() macros
PCI: Drop is_64bit_address() and is_mask_bit_support() macros
PCI: Drop msi_data_reg() macro
PCI: Drop msi_lower_address_reg() and msi_upper_address_reg() macros
PCI: Drop msi_control_reg() macro and use PCI_MSI_FLAGS directly
PCI: Use cached MSI/MSI-X offsets from dev, not from msi_desc
PCI: Clean up MSI/MSI-X capability #defines
PCI: Use cached MSI-X cap while enabling MSI-X
PCI: Use cached MSI cap while enabling MSI interrupts
PCI: Remove MSI/MSI-X cap check in pci_msi_check_device()
PCI: Cache MSI/MSI-X capability offsets in struct pci_dev
PCI: Use u8, not int, for PM capability offset
[SCSI] megaraid_sas: Use correct #define for MSI-X capability
PCI: Remove "extern" from function declarations
...
Diffstat (limited to 'drivers/pci')
36 files changed, 591 insertions, 791 deletions
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 8647dc6f52d0..748f8f3e9ff5 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c | |||
@@ -202,20 +202,16 @@ void pci_bus_add_devices(const struct pci_bus *bus) | |||
202 | if (dev->is_added) | 202 | if (dev->is_added) |
203 | continue; | 203 | continue; |
204 | retval = pci_bus_add_device(dev); | 204 | retval = pci_bus_add_device(dev); |
205 | if (retval) | ||
206 | dev_err(&dev->dev, "Error adding device (%d)\n", | ||
207 | retval); | ||
205 | } | 208 | } |
206 | 209 | ||
207 | list_for_each_entry(dev, &bus->devices, bus_list) { | 210 | list_for_each_entry(dev, &bus->devices, bus_list) { |
208 | BUG_ON(!dev->is_added); | 211 | BUG_ON(!dev->is_added); |
209 | |||
210 | child = dev->subordinate; | 212 | child = dev->subordinate; |
211 | 213 | if (child) | |
212 | if (!child) | 214 | pci_bus_add_devices(child); |
213 | continue; | ||
214 | pci_bus_add_devices(child); | ||
215 | |||
216 | if (child->is_added) | ||
217 | continue; | ||
218 | child->is_added = 1; | ||
219 | } | 215 | } |
220 | } | 216 | } |
221 | 217 | ||
diff --git a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig index 13e9e63a7266..9fcb87f353d4 100644 --- a/drivers/pci/hotplug/Kconfig +++ b/drivers/pci/hotplug/Kconfig | |||
@@ -52,15 +52,12 @@ config HOTPLUG_PCI_IBM | |||
52 | When in doubt, say N. | 52 | When in doubt, say N. |
53 | 53 | ||
54 | config HOTPLUG_PCI_ACPI | 54 | config HOTPLUG_PCI_ACPI |
55 | tristate "ACPI PCI Hotplug driver" | 55 | bool "ACPI PCI Hotplug driver" |
56 | depends on (!ACPI_DOCK && ACPI) || (ACPI_DOCK) | 56 | depends on HOTPLUG_PCI=y && ((!ACPI_DOCK && ACPI) || (ACPI_DOCK)) |
57 | help | 57 | help |
58 | Say Y here if you have a system that supports PCI Hotplug using | 58 | Say Y here if you have a system that supports PCI Hotplug using |
59 | ACPI. | 59 | ACPI. |
60 | 60 | ||
61 | To compile this driver as a module, choose M here: the | ||
62 | module will be called acpiphp. | ||
63 | |||
64 | When in doubt, say N. | 61 | When in doubt, say N. |
65 | 62 | ||
66 | config HOTPLUG_PCI_ACPI_IBM | 63 | config HOTPLUG_PCI_ACPI_IBM |
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h index b70ac00a117e..6fdd49c6f0b9 100644 --- a/drivers/pci/hotplug/acpiphp.h +++ b/drivers/pci/hotplug/acpiphp.h | |||
@@ -73,8 +73,9 @@ static inline const char *slot_name(struct slot *slot) | |||
73 | */ | 73 | */ |
74 | struct acpiphp_bridge { | 74 | struct acpiphp_bridge { |
75 | struct list_head list; | 75 | struct list_head list; |
76 | struct list_head slots; | ||
77 | struct kref ref; | ||
76 | acpi_handle handle; | 78 | acpi_handle handle; |
77 | struct acpiphp_slot *slots; | ||
78 | 79 | ||
79 | /* Ejectable PCI-to-PCI bridge (PCI bridge and PCI function) */ | 80 | /* Ejectable PCI-to-PCI bridge (PCI bridge and PCI function) */ |
80 | struct acpiphp_func *func; | 81 | struct acpiphp_func *func; |
@@ -97,7 +98,7 @@ struct acpiphp_bridge { | |||
97 | * PCI slot information for each *physical* PCI slot | 98 | * PCI slot information for each *physical* PCI slot |
98 | */ | 99 | */ |
99 | struct acpiphp_slot { | 100 | struct acpiphp_slot { |
100 | struct acpiphp_slot *next; | 101 | struct list_head node; |
101 | struct acpiphp_bridge *bridge; /* parent */ | 102 | struct acpiphp_bridge *bridge; /* parent */ |
102 | struct list_head funcs; /* one slot may have different | 103 | struct list_head funcs; /* one slot may have different |
103 | objects (i.e. for each function) */ | 104 | objects (i.e. for each function) */ |
@@ -119,7 +120,6 @@ struct acpiphp_slot { | |||
119 | */ | 120 | */ |
120 | struct acpiphp_func { | 121 | struct acpiphp_func { |
121 | struct acpiphp_slot *slot; /* parent */ | 122 | struct acpiphp_slot *slot; /* parent */ |
122 | struct acpiphp_bridge *bridge; /* Ejectable PCI-to-PCI bridge */ | ||
123 | 123 | ||
124 | struct list_head sibling; | 124 | struct list_head sibling; |
125 | struct notifier_block nb; | 125 | struct notifier_block nb; |
@@ -146,10 +146,6 @@ struct acpiphp_attention_info | |||
146 | #define ACPI_PCI_HOST_HID "PNP0A03" | 146 | #define ACPI_PCI_HOST_HID "PNP0A03" |
147 | 147 | ||
148 | /* ACPI _STA method value (ignore bit 4; battery present) */ | 148 | /* ACPI _STA method value (ignore bit 4; battery present) */ |
149 | #define ACPI_STA_PRESENT (0x00000001) | ||
150 | #define ACPI_STA_ENABLED (0x00000002) | ||
151 | #define ACPI_STA_SHOW_IN_UI (0x00000004) | ||
152 | #define ACPI_STA_FUNCTIONING (0x00000008) | ||
153 | #define ACPI_STA_ALL (0x0000000f) | 149 | #define ACPI_STA_ALL (0x0000000f) |
154 | 150 | ||
155 | /* bridge flags */ | 151 | /* bridge flags */ |
@@ -174,25 +170,24 @@ struct acpiphp_attention_info | |||
174 | /* function prototypes */ | 170 | /* function prototypes */ |
175 | 171 | ||
176 | /* acpiphp_core.c */ | 172 | /* acpiphp_core.c */ |
177 | extern int acpiphp_register_attention(struct acpiphp_attention_info*info); | 173 | int acpiphp_register_attention(struct acpiphp_attention_info*info); |
178 | extern int acpiphp_unregister_attention(struct acpiphp_attention_info *info); | 174 | int acpiphp_unregister_attention(struct acpiphp_attention_info *info); |
179 | extern int acpiphp_register_hotplug_slot(struct acpiphp_slot *slot); | 175 | int acpiphp_register_hotplug_slot(struct acpiphp_slot *slot); |
180 | extern void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *slot); | 176 | void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *slot); |
181 | 177 | ||
182 | /* acpiphp_glue.c */ | 178 | /* acpiphp_glue.c */ |
183 | extern int acpiphp_glue_init (void); | ||
184 | extern void acpiphp_glue_exit (void); | ||
185 | typedef int (*acpiphp_callback)(struct acpiphp_slot *slot, void *data); | 179 | typedef int (*acpiphp_callback)(struct acpiphp_slot *slot, void *data); |
186 | 180 | ||
187 | extern int acpiphp_enable_slot (struct acpiphp_slot *slot); | 181 | int acpiphp_enable_slot(struct acpiphp_slot *slot); |
188 | extern int acpiphp_disable_slot (struct acpiphp_slot *slot); | 182 | int acpiphp_disable_slot(struct acpiphp_slot *slot); |
189 | extern int acpiphp_eject_slot (struct acpiphp_slot *slot); | 183 | int acpiphp_eject_slot(struct acpiphp_slot *slot); |
190 | extern u8 acpiphp_get_power_status (struct acpiphp_slot *slot); | 184 | u8 acpiphp_get_power_status(struct acpiphp_slot *slot); |
191 | extern u8 acpiphp_get_attention_status (struct acpiphp_slot *slot); | 185 | u8 acpiphp_get_attention_status(struct acpiphp_slot *slot); |
192 | extern u8 acpiphp_get_latch_status (struct acpiphp_slot *slot); | 186 | u8 acpiphp_get_latch_status(struct acpiphp_slot *slot); |
193 | extern u8 acpiphp_get_adapter_status (struct acpiphp_slot *slot); | 187 | u8 acpiphp_get_adapter_status(struct acpiphp_slot *slot); |
194 | 188 | ||
195 | /* variables */ | 189 | /* variables */ |
196 | extern bool acpiphp_debug; | 190 | extern bool acpiphp_debug; |
191 | extern bool acpiphp_disabled; | ||
197 | 192 | ||
198 | #endif /* _ACPIPHP_H */ | 193 | #endif /* _ACPIPHP_H */ |
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c index c2fd3095701f..ca8127950fcd 100644 --- a/drivers/pci/hotplug/acpiphp_core.c +++ b/drivers/pci/hotplug/acpiphp_core.c | |||
@@ -37,6 +37,7 @@ | |||
37 | 37 | ||
38 | #include <linux/kernel.h> | 38 | #include <linux/kernel.h> |
39 | #include <linux/pci.h> | 39 | #include <linux/pci.h> |
40 | #include <linux/pci-acpi.h> | ||
40 | #include <linux/pci_hotplug.h> | 41 | #include <linux/pci_hotplug.h> |
41 | #include <linux/slab.h> | 42 | #include <linux/slab.h> |
42 | #include <linux/smp.h> | 43 | #include <linux/smp.h> |
@@ -48,6 +49,7 @@ | |||
48 | #define SLOT_NAME_SIZE 21 /* {_SUN} */ | 49 | #define SLOT_NAME_SIZE 21 /* {_SUN} */ |
49 | 50 | ||
50 | bool acpiphp_debug; | 51 | bool acpiphp_debug; |
52 | bool acpiphp_disabled; | ||
51 | 53 | ||
52 | /* local variables */ | 54 | /* local variables */ |
53 | static struct acpiphp_attention_info *attention_info; | 55 | static struct acpiphp_attention_info *attention_info; |
@@ -60,7 +62,9 @@ MODULE_AUTHOR(DRIVER_AUTHOR); | |||
60 | MODULE_DESCRIPTION(DRIVER_DESC); | 62 | MODULE_DESCRIPTION(DRIVER_DESC); |
61 | MODULE_LICENSE("GPL"); | 63 | MODULE_LICENSE("GPL"); |
62 | MODULE_PARM_DESC(debug, "Debugging mode enabled or not"); | 64 | MODULE_PARM_DESC(debug, "Debugging mode enabled or not"); |
65 | MODULE_PARM_DESC(disable, "disable acpiphp driver"); | ||
63 | module_param_named(debug, acpiphp_debug, bool, 0644); | 66 | module_param_named(debug, acpiphp_debug, bool, 0644); |
67 | module_param_named(disable, acpiphp_disabled, bool, 0444); | ||
64 | 68 | ||
65 | /* export the attention callback registration methods */ | 69 | /* export the attention callback registration methods */ |
66 | EXPORT_SYMBOL_GPL(acpiphp_register_attention); | 70 | EXPORT_SYMBOL_GPL(acpiphp_register_attention); |
@@ -351,27 +355,9 @@ void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *acpiphp_slot) | |||
351 | } | 355 | } |
352 | 356 | ||
353 | 357 | ||
354 | static int __init acpiphp_init(void) | 358 | void __init acpiphp_init(void) |
355 | { | 359 | { |
356 | info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); | 360 | info(DRIVER_DESC " version: " DRIVER_VERSION "%s\n", |
357 | 361 | acpiphp_disabled ? ", disabled by user; please report a bug" | |
358 | if (acpi_pci_disabled) | 362 | : ""); |
359 | return 0; | ||
360 | |||
361 | /* read all the ACPI info from the system */ | ||
362 | /* initialize internal data structure etc. */ | ||
363 | return acpiphp_glue_init(); | ||
364 | } | ||
365 | |||
366 | |||
367 | static void __exit acpiphp_exit(void) | ||
368 | { | ||
369 | if (acpi_pci_disabled) | ||
370 | return; | ||
371 | |||
372 | /* deallocate internal data structures etc. */ | ||
373 | acpiphp_glue_exit(); | ||
374 | } | 363 | } |
375 | |||
376 | module_init(acpiphp_init); | ||
377 | module_exit(acpiphp_exit); | ||
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 270fdbadc19c..96fed19c6d90 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -54,6 +54,7 @@ | |||
54 | #include "acpiphp.h" | 54 | #include "acpiphp.h" |
55 | 55 | ||
56 | static LIST_HEAD(bridge_list); | 56 | static LIST_HEAD(bridge_list); |
57 | static DEFINE_MUTEX(bridge_mutex); | ||
57 | 58 | ||
58 | #define MY_NAME "acpiphp_glue" | 59 | #define MY_NAME "acpiphp_glue" |
59 | 60 | ||
@@ -61,6 +62,7 @@ static void handle_hotplug_event_bridge (acpi_handle, u32, void *); | |||
61 | static void acpiphp_sanitize_bus(struct pci_bus *bus); | 62 | static void acpiphp_sanitize_bus(struct pci_bus *bus); |
62 | static void acpiphp_set_hpp_values(struct pci_bus *bus); | 63 | static void acpiphp_set_hpp_values(struct pci_bus *bus); |
63 | static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context); | 64 | static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context); |
65 | static void free_bridge(struct kref *kref); | ||
64 | 66 | ||
65 | /* callback routine to check for the existence of a pci dock device */ | 67 | /* callback routine to check for the existence of a pci dock device */ |
66 | static acpi_status | 68 | static acpi_status |
@@ -76,6 +78,39 @@ is_pci_dock_device(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
76 | } | 78 | } |
77 | } | 79 | } |
78 | 80 | ||
81 | static inline void get_bridge(struct acpiphp_bridge *bridge) | ||
82 | { | ||
83 | kref_get(&bridge->ref); | ||
84 | } | ||
85 | |||
86 | static inline void put_bridge(struct acpiphp_bridge *bridge) | ||
87 | { | ||
88 | kref_put(&bridge->ref, free_bridge); | ||
89 | } | ||
90 | |||
91 | static void free_bridge(struct kref *kref) | ||
92 | { | ||
93 | struct acpiphp_bridge *bridge; | ||
94 | struct acpiphp_slot *slot, *next; | ||
95 | struct acpiphp_func *func, *tmp; | ||
96 | |||
97 | bridge = container_of(kref, struct acpiphp_bridge, ref); | ||
98 | |||
99 | list_for_each_entry_safe(slot, next, &bridge->slots, node) { | ||
100 | list_for_each_entry_safe(func, tmp, &slot->funcs, sibling) { | ||
101 | kfree(func); | ||
102 | } | ||
103 | kfree(slot); | ||
104 | } | ||
105 | |||
106 | /* Release reference acquired by acpiphp_bridge_handle_to_function() */ | ||
107 | if ((bridge->flags & BRIDGE_HAS_EJ0) && bridge->func) | ||
108 | put_bridge(bridge->func->slot->bridge); | ||
109 | put_device(&bridge->pci_bus->dev); | ||
110 | pci_dev_put(bridge->pci_dev); | ||
111 | kfree(bridge); | ||
112 | } | ||
113 | |||
79 | /* | 114 | /* |
80 | * the _DCK method can do funny things... and sometimes not | 115 | * the _DCK method can do funny things... and sometimes not |
81 | * hah-hah funny. | 116 | * hah-hah funny. |
@@ -154,9 +189,10 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
154 | acpi_handle tmp; | 189 | acpi_handle tmp; |
155 | acpi_status status = AE_OK; | 190 | acpi_status status = AE_OK; |
156 | unsigned long long adr, sun; | 191 | unsigned long long adr, sun; |
157 | int device, function, retval; | 192 | int device, function, retval, found = 0; |
158 | struct pci_bus *pbus = bridge->pci_bus; | 193 | struct pci_bus *pbus = bridge->pci_bus; |
159 | struct pci_dev *pdev; | 194 | struct pci_dev *pdev; |
195 | u32 val; | ||
160 | 196 | ||
161 | if (!acpi_pci_check_ejectable(pbus, handle) && !is_dock_device(handle)) | 197 | if (!acpi_pci_check_ejectable(pbus, handle) && !is_dock_device(handle)) |
162 | return AE_OK; | 198 | return AE_OK; |
@@ -170,7 +206,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
170 | device = (adr >> 16) & 0xffff; | 206 | device = (adr >> 16) & 0xffff; |
171 | function = adr & 0xffff; | 207 | function = adr & 0xffff; |
172 | 208 | ||
173 | pdev = pbus->self; | 209 | pdev = bridge->pci_dev; |
174 | if (pdev && device_is_managed_by_native_pciehp(pdev)) | 210 | if (pdev && device_is_managed_by_native_pciehp(pdev)) |
175 | return AE_OK; | 211 | return AE_OK; |
176 | 212 | ||
@@ -178,7 +214,6 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
178 | if (!newfunc) | 214 | if (!newfunc) |
179 | return AE_NO_MEMORY; | 215 | return AE_NO_MEMORY; |
180 | 216 | ||
181 | INIT_LIST_HEAD(&newfunc->sibling); | ||
182 | newfunc->handle = handle; | 217 | newfunc->handle = handle; |
183 | newfunc->function = function; | 218 | newfunc->function = function; |
184 | 219 | ||
@@ -207,14 +242,15 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
207 | } | 242 | } |
208 | 243 | ||
209 | /* search for objects that share the same slot */ | 244 | /* search for objects that share the same slot */ |
210 | for (slot = bridge->slots; slot; slot = slot->next) | 245 | list_for_each_entry(slot, &bridge->slots, node) |
211 | if (slot->device == device) { | 246 | if (slot->device == device) { |
212 | if (slot->sun != sun) | 247 | if (slot->sun != sun) |
213 | warn("sibling found, but _SUN doesn't match!\n"); | 248 | warn("sibling found, but _SUN doesn't match!\n"); |
249 | found = 1; | ||
214 | break; | 250 | break; |
215 | } | 251 | } |
216 | 252 | ||
217 | if (!slot) { | 253 | if (!found) { |
218 | slot = kzalloc(sizeof(struct acpiphp_slot), GFP_KERNEL); | 254 | slot = kzalloc(sizeof(struct acpiphp_slot), GFP_KERNEL); |
219 | if (!slot) { | 255 | if (!slot) { |
220 | kfree(newfunc); | 256 | kfree(newfunc); |
@@ -227,9 +263,9 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
227 | INIT_LIST_HEAD(&slot->funcs); | 263 | INIT_LIST_HEAD(&slot->funcs); |
228 | mutex_init(&slot->crit_sect); | 264 | mutex_init(&slot->crit_sect); |
229 | 265 | ||
230 | slot->next = bridge->slots; | 266 | mutex_lock(&bridge_mutex); |
231 | bridge->slots = slot; | 267 | list_add_tail(&slot->node, &bridge->slots); |
232 | 268 | mutex_unlock(&bridge_mutex); | |
233 | bridge->nr_slots++; | 269 | bridge->nr_slots++; |
234 | 270 | ||
235 | dbg("found ACPI PCI Hotplug slot %llu at PCI %04x:%02x:%02x\n", | 271 | dbg("found ACPI PCI Hotplug slot %llu at PCI %04x:%02x:%02x\n", |
@@ -247,13 +283,13 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
247 | } | 283 | } |
248 | 284 | ||
249 | newfunc->slot = slot; | 285 | newfunc->slot = slot; |
286 | mutex_lock(&bridge_mutex); | ||
250 | list_add_tail(&newfunc->sibling, &slot->funcs); | 287 | list_add_tail(&newfunc->sibling, &slot->funcs); |
288 | mutex_unlock(&bridge_mutex); | ||
251 | 289 | ||
252 | pdev = pci_get_slot(pbus, PCI_DEVFN(device, function)); | 290 | if (pci_bus_read_dev_vendor_id(pbus, PCI_DEVFN(device, function), |
253 | if (pdev) { | 291 | &val, 60*1000)) |
254 | slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON); | 292 | slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON); |
255 | pci_dev_put(pdev); | ||
256 | } | ||
257 | 293 | ||
258 | if (is_dock_device(handle)) { | 294 | if (is_dock_device(handle)) { |
259 | /* we don't want to call this device's _EJ0 | 295 | /* we don't want to call this device's _EJ0 |
@@ -290,7 +326,9 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
290 | 326 | ||
291 | err_exit: | 327 | err_exit: |
292 | bridge->nr_slots--; | 328 | bridge->nr_slots--; |
293 | bridge->slots = slot->next; | 329 | mutex_lock(&bridge_mutex); |
330 | list_del(&slot->node); | ||
331 | mutex_unlock(&bridge_mutex); | ||
294 | kfree(slot); | 332 | kfree(slot); |
295 | kfree(newfunc); | 333 | kfree(newfunc); |
296 | 334 | ||
@@ -315,13 +353,17 @@ static void init_bridge_misc(struct acpiphp_bridge *bridge) | |||
315 | acpi_status status; | 353 | acpi_status status; |
316 | 354 | ||
317 | /* must be added to the list prior to calling register_slot */ | 355 | /* must be added to the list prior to calling register_slot */ |
356 | mutex_lock(&bridge_mutex); | ||
318 | list_add(&bridge->list, &bridge_list); | 357 | list_add(&bridge->list, &bridge_list); |
358 | mutex_unlock(&bridge_mutex); | ||
319 | 359 | ||
320 | /* register all slot objects under this bridge */ | 360 | /* register all slot objects under this bridge */ |
321 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge->handle, (u32)1, | 361 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge->handle, (u32)1, |
322 | register_slot, NULL, bridge, NULL); | 362 | register_slot, NULL, bridge, NULL); |
323 | if (ACPI_FAILURE(status)) { | 363 | if (ACPI_FAILURE(status)) { |
364 | mutex_lock(&bridge_mutex); | ||
324 | list_del(&bridge->list); | 365 | list_del(&bridge->list); |
366 | mutex_unlock(&bridge_mutex); | ||
325 | return; | 367 | return; |
326 | } | 368 | } |
327 | 369 | ||
@@ -351,178 +393,46 @@ static struct acpiphp_func *acpiphp_bridge_handle_to_function(acpi_handle handle | |||
351 | { | 393 | { |
352 | struct acpiphp_bridge *bridge; | 394 | struct acpiphp_bridge *bridge; |
353 | struct acpiphp_slot *slot; | 395 | struct acpiphp_slot *slot; |
354 | struct acpiphp_func *func; | 396 | struct acpiphp_func *func = NULL; |
355 | 397 | ||
398 | mutex_lock(&bridge_mutex); | ||
356 | list_for_each_entry(bridge, &bridge_list, list) { | 399 | list_for_each_entry(bridge, &bridge_list, list) { |
357 | for (slot = bridge->slots; slot; slot = slot->next) { | 400 | list_for_each_entry(slot, &bridge->slots, node) { |
358 | list_for_each_entry(func, &slot->funcs, sibling) { | 401 | list_for_each_entry(func, &slot->funcs, sibling) { |
359 | if (func->handle == handle) | 402 | if (func->handle == handle) { |
403 | get_bridge(func->slot->bridge); | ||
404 | mutex_unlock(&bridge_mutex); | ||
360 | return func; | 405 | return func; |
406 | } | ||
361 | } | 407 | } |
362 | } | 408 | } |
363 | } | 409 | } |
410 | mutex_unlock(&bridge_mutex); | ||
364 | 411 | ||
365 | return NULL; | 412 | return NULL; |
366 | } | 413 | } |
367 | 414 | ||
368 | 415 | ||
369 | static inline void config_p2p_bridge_flags(struct acpiphp_bridge *bridge) | ||
370 | { | ||
371 | acpi_handle dummy_handle; | ||
372 | struct acpiphp_func *func; | ||
373 | |||
374 | if (ACPI_SUCCESS(acpi_get_handle(bridge->handle, | ||
375 | "_EJ0", &dummy_handle))) { | ||
376 | bridge->flags |= BRIDGE_HAS_EJ0; | ||
377 | |||
378 | dbg("found ejectable p2p bridge\n"); | ||
379 | |||
380 | /* make link between PCI bridge and PCI function */ | ||
381 | func = acpiphp_bridge_handle_to_function(bridge->handle); | ||
382 | if (!func) | ||
383 | return; | ||
384 | bridge->func = func; | ||
385 | func->bridge = bridge; | ||
386 | } | ||
387 | } | ||
388 | |||
389 | |||
390 | /* allocate and initialize host bridge data structure */ | ||
391 | static void add_host_bridge(struct acpi_pci_root *root) | ||
392 | { | ||
393 | struct acpiphp_bridge *bridge; | ||
394 | acpi_handle handle = root->device->handle; | ||
395 | |||
396 | bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); | ||
397 | if (bridge == NULL) | ||
398 | return; | ||
399 | |||
400 | bridge->handle = handle; | ||
401 | |||
402 | bridge->pci_bus = root->bus; | ||
403 | |||
404 | init_bridge_misc(bridge); | ||
405 | } | ||
406 | |||
407 | |||
408 | /* allocate and initialize PCI-to-PCI bridge data structure */ | ||
409 | static void add_p2p_bridge(acpi_handle *handle) | ||
410 | { | ||
411 | struct acpiphp_bridge *bridge; | ||
412 | |||
413 | bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); | ||
414 | if (bridge == NULL) { | ||
415 | err("out of memory\n"); | ||
416 | return; | ||
417 | } | ||
418 | |||
419 | bridge->handle = handle; | ||
420 | config_p2p_bridge_flags(bridge); | ||
421 | |||
422 | bridge->pci_dev = acpi_get_pci_dev(handle); | ||
423 | bridge->pci_bus = bridge->pci_dev->subordinate; | ||
424 | if (!bridge->pci_bus) { | ||
425 | err("This is not a PCI-to-PCI bridge!\n"); | ||
426 | goto err; | ||
427 | } | ||
428 | |||
429 | /* | ||
430 | * Grab a ref to the subordinate PCI bus in case the bus is | ||
431 | * removed via PCI core logical hotplug. The ref pins the bus | ||
432 | * (which we access during module unload). | ||
433 | */ | ||
434 | get_device(&bridge->pci_bus->dev); | ||
435 | |||
436 | init_bridge_misc(bridge); | ||
437 | return; | ||
438 | err: | ||
439 | pci_dev_put(bridge->pci_dev); | ||
440 | kfree(bridge); | ||
441 | return; | ||
442 | } | ||
443 | |||
444 | |||
445 | /* callback routine to find P2P bridges */ | ||
446 | static acpi_status | ||
447 | find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
448 | { | ||
449 | acpi_status status; | ||
450 | struct pci_dev *dev; | ||
451 | |||
452 | dev = acpi_get_pci_dev(handle); | ||
453 | if (!dev || !dev->subordinate) | ||
454 | goto out; | ||
455 | |||
456 | /* check if this bridge has ejectable slots */ | ||
457 | if ((detect_ejectable_slots(handle) > 0)) { | ||
458 | dbg("found PCI-to-PCI bridge at PCI %s\n", pci_name(dev)); | ||
459 | add_p2p_bridge(handle); | ||
460 | } | ||
461 | |||
462 | /* search P2P bridges under this p2p bridge */ | ||
463 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, | ||
464 | find_p2p_bridge, NULL, NULL, NULL); | ||
465 | if (ACPI_FAILURE(status)) | ||
466 | warn("find_p2p_bridge failed (error code = 0x%x)\n", status); | ||
467 | |||
468 | out: | ||
469 | pci_dev_put(dev); | ||
470 | return AE_OK; | ||
471 | } | ||
472 | |||
473 | |||
474 | /* find hot-pluggable slots, and then find P2P bridge */ | ||
475 | static int add_bridge(struct acpi_pci_root *root) | ||
476 | { | ||
477 | acpi_status status; | ||
478 | unsigned long long tmp; | ||
479 | acpi_handle dummy_handle; | ||
480 | acpi_handle handle = root->device->handle; | ||
481 | |||
482 | /* if the bridge doesn't have _STA, we assume it is always there */ | ||
483 | status = acpi_get_handle(handle, "_STA", &dummy_handle); | ||
484 | if (ACPI_SUCCESS(status)) { | ||
485 | status = acpi_evaluate_integer(handle, "_STA", NULL, &tmp); | ||
486 | if (ACPI_FAILURE(status)) { | ||
487 | dbg("%s: _STA evaluation failure\n", __func__); | ||
488 | return 0; | ||
489 | } | ||
490 | if ((tmp & ACPI_STA_FUNCTIONING) == 0) | ||
491 | /* don't register this object */ | ||
492 | return 0; | ||
493 | } | ||
494 | |||
495 | /* check if this bridge has ejectable slots */ | ||
496 | if (detect_ejectable_slots(handle) > 0) { | ||
497 | dbg("found PCI host-bus bridge with hot-pluggable slots\n"); | ||
498 | add_host_bridge(root); | ||
499 | } | ||
500 | |||
501 | /* search P2P bridges under this host bridge */ | ||
502 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, | ||
503 | find_p2p_bridge, NULL, NULL, NULL); | ||
504 | |||
505 | if (ACPI_FAILURE(status)) | ||
506 | warn("find_p2p_bridge failed (error code = 0x%x)\n", status); | ||
507 | |||
508 | return 0; | ||
509 | } | ||
510 | |||
511 | static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle) | 416 | static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle) |
512 | { | 417 | { |
513 | struct acpiphp_bridge *bridge; | 418 | struct acpiphp_bridge *bridge; |
514 | 419 | ||
420 | mutex_lock(&bridge_mutex); | ||
515 | list_for_each_entry(bridge, &bridge_list, list) | 421 | list_for_each_entry(bridge, &bridge_list, list) |
516 | if (bridge->handle == handle) | 422 | if (bridge->handle == handle) { |
423 | get_bridge(bridge); | ||
424 | mutex_unlock(&bridge_mutex); | ||
517 | return bridge; | 425 | return bridge; |
426 | } | ||
427 | mutex_unlock(&bridge_mutex); | ||
518 | 428 | ||
519 | return NULL; | 429 | return NULL; |
520 | } | 430 | } |
521 | 431 | ||
522 | static void cleanup_bridge(struct acpiphp_bridge *bridge) | 432 | static void cleanup_bridge(struct acpiphp_bridge *bridge) |
523 | { | 433 | { |
524 | struct acpiphp_slot *slot, *next; | 434 | struct acpiphp_slot *slot; |
525 | struct acpiphp_func *func, *tmp; | 435 | struct acpiphp_func *func; |
526 | acpi_status status; | 436 | acpi_status status; |
527 | acpi_handle handle = bridge->handle; | 437 | acpi_handle handle = bridge->handle; |
528 | 438 | ||
@@ -543,10 +453,8 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge) | |||
543 | err("failed to install interrupt notify handler\n"); | 453 | err("failed to install interrupt notify handler\n"); |
544 | } | 454 | } |
545 | 455 | ||
546 | slot = bridge->slots; | 456 | list_for_each_entry(slot, &bridge->slots, node) { |
547 | while (slot) { | 457 | list_for_each_entry(func, &slot->funcs, sibling) { |
548 | next = slot->next; | ||
549 | list_for_each_entry_safe(func, tmp, &slot->funcs, sibling) { | ||
550 | if (is_dock_device(func->handle)) { | 458 | if (is_dock_device(func->handle)) { |
551 | unregister_hotplug_dock_device(func->handle); | 459 | unregister_hotplug_dock_device(func->handle); |
552 | unregister_dock_notifier(&func->nb); | 460 | unregister_dock_notifier(&func->nb); |
@@ -558,63 +466,13 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge) | |||
558 | if (ACPI_FAILURE(status)) | 466 | if (ACPI_FAILURE(status)) |
559 | err("failed to remove notify handler\n"); | 467 | err("failed to remove notify handler\n"); |
560 | } | 468 | } |
561 | list_del(&func->sibling); | ||
562 | kfree(func); | ||
563 | } | 469 | } |
564 | acpiphp_unregister_hotplug_slot(slot); | 470 | acpiphp_unregister_hotplug_slot(slot); |
565 | list_del(&slot->funcs); | ||
566 | kfree(slot); | ||
567 | slot = next; | ||
568 | } | 471 | } |
569 | 472 | ||
570 | /* | 473 | mutex_lock(&bridge_mutex); |
571 | * Only P2P bridges have a pci_dev | ||
572 | */ | ||
573 | if (bridge->pci_dev) | ||
574 | put_device(&bridge->pci_bus->dev); | ||
575 | |||
576 | pci_dev_put(bridge->pci_dev); | ||
577 | list_del(&bridge->list); | 474 | list_del(&bridge->list); |
578 | kfree(bridge); | 475 | mutex_unlock(&bridge_mutex); |
579 | } | ||
580 | |||
581 | static acpi_status | ||
582 | cleanup_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
583 | { | ||
584 | struct acpiphp_bridge *bridge; | ||
585 | |||
586 | /* cleanup p2p bridges under this P2P bridge | ||
587 | in a depth-first manner */ | ||
588 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, | ||
589 | cleanup_p2p_bridge, NULL, NULL, NULL); | ||
590 | |||
591 | bridge = acpiphp_handle_to_bridge(handle); | ||
592 | if (bridge) | ||
593 | cleanup_bridge(bridge); | ||
594 | |||
595 | return AE_OK; | ||
596 | } | ||
597 | |||
598 | static void remove_bridge(struct acpi_pci_root *root) | ||
599 | { | ||
600 | struct acpiphp_bridge *bridge; | ||
601 | acpi_handle handle = root->device->handle; | ||
602 | |||
603 | /* cleanup p2p bridges under this host bridge | ||
604 | in a depth-first manner */ | ||
605 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, | ||
606 | (u32)1, cleanup_p2p_bridge, NULL, NULL, NULL); | ||
607 | |||
608 | /* | ||
609 | * On root bridges with hotplug slots directly underneath (ie, | ||
610 | * no p2p bridge between), we call cleanup_bridge(). | ||
611 | * | ||
612 | * The else clause cleans up root bridges that either had no | ||
613 | * hotplug slots at all, or had a p2p bridge underneath. | ||
614 | */ | ||
615 | bridge = acpiphp_handle_to_bridge(handle); | ||
616 | if (bridge) | ||
617 | cleanup_bridge(bridge); | ||
618 | } | 476 | } |
619 | 477 | ||
620 | static int power_on_slot(struct acpiphp_slot *slot) | 478 | static int power_on_slot(struct acpiphp_slot *slot) |
@@ -798,6 +656,7 @@ static void check_hotplug_bridge(struct acpiphp_slot *slot, struct pci_dev *dev) | |||
798 | } | 656 | } |
799 | } | 657 | } |
800 | } | 658 | } |
659 | |||
801 | /** | 660 | /** |
802 | * enable_device - enable, configure a slot | 661 | * enable_device - enable, configure a slot |
803 | * @slot: slot to be enabled | 662 | * @slot: slot to be enabled |
@@ -810,9 +669,7 @@ static int __ref enable_device(struct acpiphp_slot *slot) | |||
810 | struct pci_dev *dev; | 669 | struct pci_dev *dev; |
811 | struct pci_bus *bus = slot->bridge->pci_bus; | 670 | struct pci_bus *bus = slot->bridge->pci_bus; |
812 | struct acpiphp_func *func; | 671 | struct acpiphp_func *func; |
813 | int retval = 0; | ||
814 | int num, max, pass; | 672 | int num, max, pass; |
815 | acpi_status status; | ||
816 | 673 | ||
817 | if (slot->flags & SLOT_ENABLED) | 674 | if (slot->flags & SLOT_ENABLED) |
818 | goto err_exit; | 675 | goto err_exit; |
@@ -867,23 +724,11 @@ static int __ref enable_device(struct acpiphp_slot *slot) | |||
867 | slot->flags &= (~SLOT_ENABLED); | 724 | slot->flags &= (~SLOT_ENABLED); |
868 | continue; | 725 | continue; |
869 | } | 726 | } |
870 | |||
871 | if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE && | ||
872 | dev->hdr_type != PCI_HEADER_TYPE_CARDBUS) { | ||
873 | pci_dev_put(dev); | ||
874 | continue; | ||
875 | } | ||
876 | |||
877 | status = find_p2p_bridge(func->handle, (u32)1, bus, NULL); | ||
878 | if (ACPI_FAILURE(status)) | ||
879 | warn("find_p2p_bridge failed (error code = 0x%x)\n", | ||
880 | status); | ||
881 | pci_dev_put(dev); | ||
882 | } | 727 | } |
883 | 728 | ||
884 | 729 | ||
885 | err_exit: | 730 | err_exit: |
886 | return retval; | 731 | return 0; |
887 | } | 732 | } |
888 | 733 | ||
889 | /* return first device in slot, acquiring a reference on it */ | 734 | /* return first device in slot, acquiring a reference on it */ |
@@ -912,23 +757,6 @@ static int disable_device(struct acpiphp_slot *slot) | |||
912 | { | 757 | { |
913 | struct acpiphp_func *func; | 758 | struct acpiphp_func *func; |
914 | struct pci_dev *pdev; | 759 | struct pci_dev *pdev; |
915 | struct pci_bus *bus = slot->bridge->pci_bus; | ||
916 | |||
917 | /* The slot will be enabled when func 0 is added, so check | ||
918 | func 0 before disable the slot. */ | ||
919 | pdev = pci_get_slot(bus, PCI_DEVFN(slot->device, 0)); | ||
920 | if (!pdev) | ||
921 | goto err_exit; | ||
922 | pci_dev_put(pdev); | ||
923 | |||
924 | list_for_each_entry(func, &slot->funcs, sibling) { | ||
925 | if (func->bridge) { | ||
926 | /* cleanup p2p bridges under this P2P bridge */ | ||
927 | cleanup_p2p_bridge(func->bridge->handle, | ||
928 | (u32)1, NULL, NULL); | ||
929 | func->bridge = NULL; | ||
930 | } | ||
931 | } | ||
932 | 760 | ||
933 | /* | 761 | /* |
934 | * enable_device() enumerates all functions in this device via | 762 | * enable_device() enumerates all functions in this device via |
@@ -947,7 +775,6 @@ static int disable_device(struct acpiphp_slot *slot) | |||
947 | 775 | ||
948 | slot->flags &= (~SLOT_ENABLED); | 776 | slot->flags &= (~SLOT_ENABLED); |
949 | 777 | ||
950 | err_exit: | ||
951 | return 0; | 778 | return 0; |
952 | } | 779 | } |
953 | 780 | ||
@@ -1037,7 +864,7 @@ static int acpiphp_check_bridge(struct acpiphp_bridge *bridge) | |||
1037 | 864 | ||
1038 | enabled = disabled = 0; | 865 | enabled = disabled = 0; |
1039 | 866 | ||
1040 | for (slot = bridge->slots; slot; slot = slot->next) { | 867 | list_for_each_entry(slot, &bridge->slots, node) { |
1041 | unsigned int status = get_slot_status(slot); | 868 | unsigned int status = get_slot_status(slot); |
1042 | if (slot->flags & SLOT_ENABLED) { | 869 | if (slot->flags & SLOT_ENABLED) { |
1043 | if (status == ACPI_STA_ALL) | 870 | if (status == ACPI_STA_ALL) |
@@ -1082,11 +909,11 @@ static void acpiphp_set_hpp_values(struct pci_bus *bus) | |||
1082 | */ | 909 | */ |
1083 | static void acpiphp_sanitize_bus(struct pci_bus *bus) | 910 | static void acpiphp_sanitize_bus(struct pci_bus *bus) |
1084 | { | 911 | { |
1085 | struct pci_dev *dev; | 912 | struct pci_dev *dev, *tmp; |
1086 | int i; | 913 | int i; |
1087 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM; | 914 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM; |
1088 | 915 | ||
1089 | list_for_each_entry(dev, &bus->devices, bus_list) { | 916 | list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) { |
1090 | for (i=0; i<PCI_BRIDGE_RESOURCES; i++) { | 917 | for (i=0; i<PCI_BRIDGE_RESOURCES; i++) { |
1091 | struct resource *res = &dev->resource[i]; | 918 | struct resource *res = &dev->resource[i]; |
1092 | if ((res->flags & type_mask) && !res->start && | 919 | if ((res->flags & type_mask) && !res->start && |
@@ -1118,6 +945,7 @@ check_sub_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
1118 | dbg("%s: re-enumerating slots under %s\n", | 945 | dbg("%s: re-enumerating slots under %s\n", |
1119 | __func__, objname); | 946 | __func__, objname); |
1120 | acpiphp_check_bridge(bridge); | 947 | acpiphp_check_bridge(bridge); |
948 | put_bridge(bridge); | ||
1121 | } | 949 | } |
1122 | return AE_OK ; | 950 | return AE_OK ; |
1123 | } | 951 | } |
@@ -1195,6 +1023,7 @@ static void _handle_hotplug_event_bridge(struct work_struct *work) | |||
1195 | 1023 | ||
1196 | acpi_scan_lock_release(); | 1024 | acpi_scan_lock_release(); |
1197 | kfree(hp_work); /* allocated in handle_hotplug_event_bridge */ | 1025 | kfree(hp_work); /* allocated in handle_hotplug_event_bridge */ |
1026 | put_bridge(bridge); | ||
1198 | } | 1027 | } |
1199 | 1028 | ||
1200 | /** | 1029 | /** |
@@ -1208,6 +1037,8 @@ static void _handle_hotplug_event_bridge(struct work_struct *work) | |||
1208 | static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, | 1037 | static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, |
1209 | void *context) | 1038 | void *context) |
1210 | { | 1039 | { |
1040 | struct acpiphp_bridge *bridge = context; | ||
1041 | |||
1211 | /* | 1042 | /* |
1212 | * Currently the code adds all hotplug events to the kacpid_wq | 1043 | * Currently the code adds all hotplug events to the kacpid_wq |
1213 | * queue when it should add hotplug events to the kacpi_hotplug_wq. | 1044 | * queue when it should add hotplug events to the kacpi_hotplug_wq. |
@@ -1216,6 +1047,7 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, | |||
1216 | * For now just re-add this work to the kacpi_hotplug_wq so we | 1047 | * For now just re-add this work to the kacpi_hotplug_wq so we |
1217 | * don't deadlock on hotplug actions. | 1048 | * don't deadlock on hotplug actions. |
1218 | */ | 1049 | */ |
1050 | get_bridge(bridge); | ||
1219 | alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_bridge); | 1051 | alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_bridge); |
1220 | } | 1052 | } |
1221 | 1053 | ||
@@ -1270,6 +1102,7 @@ static void _handle_hotplug_event_func(struct work_struct *work) | |||
1270 | 1102 | ||
1271 | acpi_scan_lock_release(); | 1103 | acpi_scan_lock_release(); |
1272 | kfree(hp_work); /* allocated in handle_hotplug_event_func */ | 1104 | kfree(hp_work); /* allocated in handle_hotplug_event_func */ |
1105 | put_bridge(func->slot->bridge); | ||
1273 | } | 1106 | } |
1274 | 1107 | ||
1275 | /** | 1108 | /** |
@@ -1283,6 +1116,8 @@ static void _handle_hotplug_event_func(struct work_struct *work) | |||
1283 | static void handle_hotplug_event_func(acpi_handle handle, u32 type, | 1116 | static void handle_hotplug_event_func(acpi_handle handle, u32 type, |
1284 | void *context) | 1117 | void *context) |
1285 | { | 1118 | { |
1119 | struct acpiphp_func *func = context; | ||
1120 | |||
1286 | /* | 1121 | /* |
1287 | * Currently the code adds all hotplug events to the kacpid_wq | 1122 | * Currently the code adds all hotplug events to the kacpid_wq |
1288 | * queue when it should add hotplug events to the kacpi_hotplug_wq. | 1123 | * queue when it should add hotplug events to the kacpi_hotplug_wq. |
@@ -1291,33 +1126,69 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type, | |||
1291 | * For now just re-add this work to the kacpi_hotplug_wq so we | 1126 | * For now just re-add this work to the kacpi_hotplug_wq so we |
1292 | * don't deadlock on hotplug actions. | 1127 | * don't deadlock on hotplug actions. |
1293 | */ | 1128 | */ |
1129 | get_bridge(func->slot->bridge); | ||
1294 | alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_func); | 1130 | alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_func); |
1295 | } | 1131 | } |
1296 | 1132 | ||
1297 | static struct acpi_pci_driver acpi_pci_hp_driver = { | 1133 | /* |
1298 | .add = add_bridge, | 1134 | * Create hotplug slots for the PCI bus. |
1299 | .remove = remove_bridge, | 1135 | * It should always return 0 to avoid skipping following notifiers. |
1300 | }; | ||
1301 | |||
1302 | /** | ||
1303 | * acpiphp_glue_init - initializes all PCI hotplug - ACPI glue data structures | ||
1304 | */ | 1136 | */ |
1305 | int __init acpiphp_glue_init(void) | 1137 | void acpiphp_enumerate_slots(struct pci_bus *bus, acpi_handle handle) |
1306 | { | 1138 | { |
1307 | acpi_pci_register_driver(&acpi_pci_hp_driver); | 1139 | acpi_handle dummy_handle; |
1140 | struct acpiphp_bridge *bridge; | ||
1308 | 1141 | ||
1309 | return 0; | 1142 | if (acpiphp_disabled) |
1310 | } | 1143 | return; |
1311 | 1144 | ||
1145 | if (detect_ejectable_slots(handle) <= 0) | ||
1146 | return; | ||
1312 | 1147 | ||
1313 | /** | 1148 | bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); |
1314 | * acpiphp_glue_exit - terminates all PCI hotplug - ACPI glue data structures | 1149 | if (bridge == NULL) { |
1315 | * | 1150 | err("out of memory\n"); |
1316 | * This function frees all data allocated in acpiphp_glue_init(). | 1151 | return; |
1317 | */ | 1152 | } |
1318 | void acpiphp_glue_exit(void) | 1153 | |
1154 | INIT_LIST_HEAD(&bridge->slots); | ||
1155 | kref_init(&bridge->ref); | ||
1156 | bridge->handle = handle; | ||
1157 | bridge->pci_dev = pci_dev_get(bus->self); | ||
1158 | bridge->pci_bus = bus; | ||
1159 | |||
1160 | /* | ||
1161 | * Grab a ref to the subordinate PCI bus in case the bus is | ||
1162 | * removed via PCI core logical hotplug. The ref pins the bus | ||
1163 | * (which we access during module unload). | ||
1164 | */ | ||
1165 | get_device(&bus->dev); | ||
1166 | |||
1167 | if (!pci_is_root_bus(bridge->pci_bus) && | ||
1168 | ACPI_SUCCESS(acpi_get_handle(bridge->handle, | ||
1169 | "_EJ0", &dummy_handle))) { | ||
1170 | dbg("found ejectable p2p bridge\n"); | ||
1171 | bridge->flags |= BRIDGE_HAS_EJ0; | ||
1172 | bridge->func = acpiphp_bridge_handle_to_function(handle); | ||
1173 | } | ||
1174 | |||
1175 | init_bridge_misc(bridge); | ||
1176 | } | ||
1177 | |||
1178 | /* Destroy hotplug slots associated with the PCI bus */ | ||
1179 | void acpiphp_remove_slots(struct pci_bus *bus) | ||
1319 | { | 1180 | { |
1320 | acpi_pci_unregister_driver(&acpi_pci_hp_driver); | 1181 | struct acpiphp_bridge *bridge, *tmp; |
1182 | |||
1183 | if (acpiphp_disabled) | ||
1184 | return; | ||
1185 | |||
1186 | list_for_each_entry_safe(bridge, tmp, &bridge_list, list) | ||
1187 | if (bridge->pci_bus == bus) { | ||
1188 | cleanup_bridge(bridge); | ||
1189 | put_bridge(bridge); | ||
1190 | break; | ||
1191 | } | ||
1321 | } | 1192 | } |
1322 | 1193 | ||
1323 | /** | 1194 | /** |
@@ -1396,7 +1267,7 @@ u8 acpiphp_get_latch_status(struct acpiphp_slot *slot) | |||
1396 | 1267 | ||
1397 | sta = get_slot_status(slot); | 1268 | sta = get_slot_status(slot); |
1398 | 1269 | ||
1399 | return (sta & ACPI_STA_SHOW_IN_UI) ? 0 : 1; | 1270 | return (sta & ACPI_STA_DEVICE_UI) ? 0 : 1; |
1400 | } | 1271 | } |
1401 | 1272 | ||
1402 | 1273 | ||
diff --git a/drivers/pci/hotplug/cpci_hotplug.h b/drivers/pci/hotplug/cpci_hotplug.h index 9fff878cf026..1356211431d0 100644 --- a/drivers/pci/hotplug/cpci_hotplug.h +++ b/drivers/pci/hotplug/cpci_hotplug.h | |||
@@ -75,28 +75,36 @@ static inline const char *slot_name(struct slot *slot) | |||
75 | return hotplug_slot_name(slot->hotplug_slot); | 75 | return hotplug_slot_name(slot->hotplug_slot); |
76 | } | 76 | } |
77 | 77 | ||
78 | extern int cpci_hp_register_controller(struct cpci_hp_controller *controller); | 78 | int cpci_hp_register_controller(struct cpci_hp_controller *controller); |
79 | extern int cpci_hp_unregister_controller(struct cpci_hp_controller *controller); | 79 | int cpci_hp_unregister_controller(struct cpci_hp_controller *controller); |
80 | extern int cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last); | 80 | int cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last); |
81 | extern int cpci_hp_unregister_bus(struct pci_bus *bus); | 81 | int cpci_hp_unregister_bus(struct pci_bus *bus); |
82 | extern int cpci_hp_start(void); | 82 | int cpci_hp_start(void); |
83 | extern int cpci_hp_stop(void); | 83 | int cpci_hp_stop(void); |
84 | 84 | ||
85 | /* | 85 | /* |
86 | * Internal function prototypes, these functions should not be used by | 86 | * Internal function prototypes, these functions should not be used by |
87 | * board/chassis drivers. | 87 | * board/chassis drivers. |
88 | */ | 88 | */ |
89 | extern u8 cpci_get_attention_status(struct slot *slot); | 89 | u8 cpci_get_attention_status(struct slot *slot); |
90 | extern u8 cpci_get_latch_status(struct slot *slot); | 90 | u8 cpci_get_latch_status(struct slot *slot); |
91 | extern u8 cpci_get_adapter_status(struct slot *slot); | 91 | u8 cpci_get_adapter_status(struct slot *slot); |
92 | extern u16 cpci_get_hs_csr(struct slot * slot); | 92 | u16 cpci_get_hs_csr(struct slot * slot); |
93 | extern int cpci_set_attention_status(struct slot *slot, int status); | 93 | int cpci_set_attention_status(struct slot *slot, int status); |
94 | extern int cpci_check_and_clear_ins(struct slot * slot); | 94 | int cpci_check_and_clear_ins(struct slot * slot); |
95 | extern int cpci_check_ext(struct slot * slot); | 95 | int cpci_check_ext(struct slot * slot); |
96 | extern int cpci_clear_ext(struct slot * slot); | 96 | int cpci_clear_ext(struct slot * slot); |
97 | extern int cpci_led_on(struct slot * slot); | 97 | int cpci_led_on(struct slot * slot); |
98 | extern int cpci_led_off(struct slot * slot); | 98 | int cpci_led_off(struct slot * slot); |
99 | extern int cpci_configure_slot(struct slot *slot); | 99 | int cpci_configure_slot(struct slot *slot); |
100 | extern int cpci_unconfigure_slot(struct slot *slot); | 100 | int cpci_unconfigure_slot(struct slot *slot); |
101 | |||
102 | #ifdef CONFIG_HOTPLUG_PCI_CPCI | ||
103 | int cpci_hotplug_init(int debug); | ||
104 | void cpci_hotplug_exit(void); | ||
105 | #else | ||
106 | static inline int cpci_hotplug_init(int debug) { return 0; } | ||
107 | static inline void cpci_hotplug_exit(void) { } | ||
108 | #endif | ||
101 | 109 | ||
102 | #endif /* _CPCI_HOTPLUG_H */ | 110 | #endif /* _CPCI_HOTPLUG_H */ |
diff --git a/drivers/pci/hotplug/cpqphp.h b/drivers/pci/hotplug/cpqphp.h index d8ffc7366801..516b87738b6e 100644 --- a/drivers/pci/hotplug/cpqphp.h +++ b/drivers/pci/hotplug/cpqphp.h | |||
@@ -404,50 +404,44 @@ struct resource_lists { | |||
404 | 404 | ||
405 | 405 | ||
406 | /* debugfs functions for the hotplug controller info */ | 406 | /* debugfs functions for the hotplug controller info */ |
407 | extern void cpqhp_initialize_debugfs(void); | 407 | void cpqhp_initialize_debugfs(void); |
408 | extern void cpqhp_shutdown_debugfs(void); | 408 | void cpqhp_shutdown_debugfs(void); |
409 | extern void cpqhp_create_debugfs_files(struct controller *ctrl); | 409 | void cpqhp_create_debugfs_files(struct controller *ctrl); |
410 | extern void cpqhp_remove_debugfs_files(struct controller *ctrl); | 410 | void cpqhp_remove_debugfs_files(struct controller *ctrl); |
411 | 411 | ||
412 | /* controller functions */ | 412 | /* controller functions */ |
413 | extern void cpqhp_pushbutton_thread(unsigned long event_pointer); | 413 | void cpqhp_pushbutton_thread(unsigned long event_pointer); |
414 | extern irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data); | 414 | irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data); |
415 | extern int cpqhp_find_available_resources(struct controller *ctrl, | 415 | int cpqhp_find_available_resources(struct controller *ctrl, |
416 | void __iomem *rom_start); | 416 | void __iomem *rom_start); |
417 | extern int cpqhp_event_start_thread(void); | 417 | int cpqhp_event_start_thread(void); |
418 | extern void cpqhp_event_stop_thread(void); | 418 | void cpqhp_event_stop_thread(void); |
419 | extern struct pci_func *cpqhp_slot_create(unsigned char busnumber); | 419 | struct pci_func *cpqhp_slot_create(unsigned char busnumber); |
420 | extern struct pci_func *cpqhp_slot_find(unsigned char bus, unsigned char device, | 420 | struct pci_func *cpqhp_slot_find(unsigned char bus, unsigned char device, |
421 | unsigned char index); | 421 | unsigned char index); |
422 | extern int cpqhp_process_SI(struct controller *ctrl, struct pci_func *func); | 422 | int cpqhp_process_SI(struct controller *ctrl, struct pci_func *func); |
423 | extern int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func); | 423 | int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func); |
424 | extern int cpqhp_hardware_test(struct controller *ctrl, int test_num); | 424 | int cpqhp_hardware_test(struct controller *ctrl, int test_num); |
425 | 425 | ||
426 | /* resource functions */ | 426 | /* resource functions */ |
427 | extern int cpqhp_resource_sort_and_combine (struct pci_resource **head); | 427 | int cpqhp_resource_sort_and_combine (struct pci_resource **head); |
428 | 428 | ||
429 | /* pci functions */ | 429 | /* pci functions */ |
430 | extern int cpqhp_set_irq(u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num); | 430 | int cpqhp_set_irq(u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num); |
431 | extern int cpqhp_get_bus_dev(struct controller *ctrl, u8 *bus_num, u8 *dev_num, | 431 | int cpqhp_get_bus_dev(struct controller *ctrl, u8 *bus_num, u8 *dev_num, |
432 | u8 slot); | 432 | u8 slot); |
433 | extern int cpqhp_save_config(struct controller *ctrl, int busnumber, | 433 | int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug); |
434 | int is_hot_plug); | 434 | int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func *func); |
435 | extern int cpqhp_save_base_addr_length(struct controller *ctrl, | 435 | int cpqhp_save_used_resources(struct controller *ctrl, struct pci_func *func); |
436 | struct pci_func *func); | 436 | int cpqhp_configure_board(struct controller *ctrl, struct pci_func *func); |
437 | extern int cpqhp_save_used_resources(struct controller *ctrl, | 437 | int cpqhp_save_slot_config(struct controller *ctrl, struct pci_func *new_slot); |
438 | struct pci_func *func); | 438 | int cpqhp_valid_replace(struct controller *ctrl, struct pci_func *func); |
439 | extern int cpqhp_configure_board(struct controller *ctrl, | 439 | void cpqhp_destroy_board_resources(struct pci_func *func); |
440 | struct pci_func *func); | 440 | int cpqhp_return_board_resources(struct pci_func *func, |
441 | extern int cpqhp_save_slot_config(struct controller *ctrl, | 441 | struct resource_lists *resources); |
442 | struct pci_func *new_slot); | 442 | void cpqhp_destroy_resource_list(struct resource_lists *resources); |
443 | extern int cpqhp_valid_replace(struct controller *ctrl, struct pci_func *func); | 443 | int cpqhp_configure_device(struct controller *ctrl, struct pci_func *func); |
444 | extern void cpqhp_destroy_board_resources(struct pci_func *func); | 444 | int cpqhp_unconfigure_device(struct pci_func *func); |
445 | extern int cpqhp_return_board_resources (struct pci_func *func, | ||
446 | struct resource_lists *resources); | ||
447 | extern void cpqhp_destroy_resource_list(struct resource_lists *resources); | ||
448 | extern int cpqhp_configure_device(struct controller *ctrl, | ||
449 | struct pci_func *func); | ||
450 | extern int cpqhp_unconfigure_device(struct pci_func *func); | ||
451 | 445 | ||
452 | /* Global variables */ | 446 | /* Global variables */ |
453 | extern int cpqhp_debug; | 447 | extern int cpqhp_debug; |
diff --git a/drivers/pci/hotplug/cpqphp_nvram.h b/drivers/pci/hotplug/cpqphp_nvram.h index e89c0702119d..34e4e54fcf15 100644 --- a/drivers/pci/hotplug/cpqphp_nvram.h +++ b/drivers/pci/hotplug/cpqphp_nvram.h | |||
@@ -30,26 +30,26 @@ | |||
30 | 30 | ||
31 | #ifndef CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM | 31 | #ifndef CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM |
32 | 32 | ||
33 | static inline void compaq_nvram_init (void __iomem *rom_start) | 33 | static inline void compaq_nvram_init(void __iomem *rom_start) |
34 | { | 34 | { |
35 | return; | 35 | return; |
36 | } | 36 | } |
37 | 37 | ||
38 | static inline int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl) | 38 | static inline int compaq_nvram_load(void __iomem *rom_start, struct controller *ctrl) |
39 | { | 39 | { |
40 | return 0; | 40 | return 0; |
41 | } | 41 | } |
42 | 42 | ||
43 | static inline int compaq_nvram_store (void __iomem *rom_start) | 43 | static inline int compaq_nvram_store(void __iomem *rom_start) |
44 | { | 44 | { |
45 | return 0; | 45 | return 0; |
46 | } | 46 | } |
47 | 47 | ||
48 | #else | 48 | #else |
49 | 49 | ||
50 | extern void compaq_nvram_init (void __iomem *rom_start); | 50 | void compaq_nvram_init(void __iomem *rom_start); |
51 | extern int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl); | 51 | int compaq_nvram_load(void __iomem *rom_start, struct controller *ctrl); |
52 | extern int compaq_nvram_store (void __iomem *rom_start); | 52 | int compaq_nvram_store(void __iomem *rom_start); |
53 | 53 | ||
54 | #endif | 54 | #endif |
55 | 55 | ||
diff --git a/drivers/pci/hotplug/ibmphp.h b/drivers/pci/hotplug/ibmphp.h index a8d391a4957d..8c5b25871d02 100644 --- a/drivers/pci/hotplug/ibmphp.h +++ b/drivers/pci/hotplug/ibmphp.h | |||
@@ -275,17 +275,17 @@ extern struct list_head ibmphp_slot_head; | |||
275 | * FUNCTION PROTOTYPES * | 275 | * FUNCTION PROTOTYPES * |
276 | ***********************************************************/ | 276 | ***********************************************************/ |
277 | 277 | ||
278 | extern void ibmphp_free_ebda_hpc_queue (void); | 278 | void ibmphp_free_ebda_hpc_queue(void); |
279 | extern int ibmphp_access_ebda (void); | 279 | int ibmphp_access_ebda(void); |
280 | extern struct slot *ibmphp_get_slot_from_physical_num (u8); | 280 | struct slot *ibmphp_get_slot_from_physical_num(u8); |
281 | extern int ibmphp_get_total_hp_slots (void); | 281 | int ibmphp_get_total_hp_slots(void); |
282 | extern void ibmphp_free_ibm_slot (struct slot *); | 282 | void ibmphp_free_ibm_slot(struct slot *); |
283 | extern void ibmphp_free_bus_info_queue (void); | 283 | void ibmphp_free_bus_info_queue(void); |
284 | extern void ibmphp_free_ebda_pci_rsrc_queue (void); | 284 | void ibmphp_free_ebda_pci_rsrc_queue(void); |
285 | extern struct bus_info *ibmphp_find_same_bus_num (u32); | 285 | struct bus_info *ibmphp_find_same_bus_num(u32); |
286 | extern int ibmphp_get_bus_index (u8); | 286 | int ibmphp_get_bus_index(u8); |
287 | extern u16 ibmphp_get_total_controllers (void); | 287 | u16 ibmphp_get_total_controllers(void); |
288 | extern int ibmphp_register_pci (void); | 288 | int ibmphp_register_pci(void); |
289 | 289 | ||
290 | /* passed parameters */ | 290 | /* passed parameters */ |
291 | #define MEM 0 | 291 | #define MEM 0 |
@@ -381,24 +381,24 @@ struct res_needed { | |||
381 | 381 | ||
382 | /* functions */ | 382 | /* functions */ |
383 | 383 | ||
384 | extern int ibmphp_rsrc_init (void); | 384 | int ibmphp_rsrc_init(void); |
385 | extern int ibmphp_add_resource (struct resource_node *); | 385 | int ibmphp_add_resource(struct resource_node *); |
386 | extern int ibmphp_remove_resource (struct resource_node *); | 386 | int ibmphp_remove_resource(struct resource_node *); |
387 | extern int ibmphp_find_resource (struct bus_node *, u32, struct resource_node **, int); | 387 | int ibmphp_find_resource(struct bus_node *, u32, struct resource_node **, int); |
388 | extern int ibmphp_check_resource (struct resource_node *, u8); | 388 | int ibmphp_check_resource(struct resource_node *, u8); |
389 | extern int ibmphp_remove_bus (struct bus_node *, u8); | 389 | int ibmphp_remove_bus(struct bus_node *, u8); |
390 | extern void ibmphp_free_resources (void); | 390 | void ibmphp_free_resources(void); |
391 | extern int ibmphp_add_pfmem_from_mem (struct resource_node *); | 391 | int ibmphp_add_pfmem_from_mem(struct resource_node *); |
392 | extern struct bus_node *ibmphp_find_res_bus (u8); | 392 | struct bus_node *ibmphp_find_res_bus(u8); |
393 | extern void ibmphp_print_test (void); /* for debugging purposes */ | 393 | void ibmphp_print_test(void); /* for debugging purposes */ |
394 | 394 | ||
395 | extern void ibmphp_hpc_initvars (void); | 395 | void ibmphp_hpc_initvars(void); |
396 | extern int ibmphp_hpc_readslot (struct slot *, u8, u8 *); | 396 | int ibmphp_hpc_readslot(struct slot *, u8, u8 *); |
397 | extern int ibmphp_hpc_writeslot (struct slot *, u8); | 397 | int ibmphp_hpc_writeslot(struct slot *, u8); |
398 | extern void ibmphp_lock_operations (void); | 398 | void ibmphp_lock_operations(void); |
399 | extern void ibmphp_unlock_operations (void); | 399 | void ibmphp_unlock_operations(void); |
400 | extern int ibmphp_hpc_start_poll_thread (void); | 400 | int ibmphp_hpc_start_poll_thread(void); |
401 | extern void ibmphp_hpc_stop_poll_thread (void); | 401 | void ibmphp_hpc_stop_poll_thread(void); |
402 | 402 | ||
403 | //---------------------------------------------------------------------------- | 403 | //---------------------------------------------------------------------------- |
404 | 404 | ||
@@ -749,11 +749,11 @@ struct controller { | |||
749 | 749 | ||
750 | /* Functions */ | 750 | /* Functions */ |
751 | 751 | ||
752 | extern int ibmphp_init_devno (struct slot **); /* This function is called from EBDA, so we need it not be static */ | 752 | int ibmphp_init_devno(struct slot **); /* This function is called from EBDA, so we need it not be static */ |
753 | extern int ibmphp_do_disable_slot (struct slot *slot_cur); | 753 | int ibmphp_do_disable_slot(struct slot *slot_cur); |
754 | extern int ibmphp_update_slot_info (struct slot *); /* This function is called from HPC, so we need it to not be be static */ | 754 | int ibmphp_update_slot_info(struct slot *); /* This function is called from HPC, so we need it to not be be static */ |
755 | extern int ibmphp_configure_card (struct pci_func *, u8); | 755 | int ibmphp_configure_card(struct pci_func *, u8); |
756 | extern int ibmphp_unconfigure_card (struct slot **, int); | 756 | int ibmphp_unconfigure_card(struct slot **, int); |
757 | extern struct hotplug_slot_ops ibmphp_hotplug_slot_ops; | 757 | extern struct hotplug_slot_ops ibmphp_hotplug_slot_ops; |
758 | 758 | ||
759 | #endif //__IBMPHP_H | 759 | #endif //__IBMPHP_H |
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c index 202f4a969eb5..ec20f74c8981 100644 --- a/drivers/pci/hotplug/pci_hotplug_core.c +++ b/drivers/pci/hotplug/pci_hotplug_core.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/pci_hotplug.h> | 41 | #include <linux/pci_hotplug.h> |
42 | #include <asm/uaccess.h> | 42 | #include <asm/uaccess.h> |
43 | #include "../pci.h" | 43 | #include "../pci.h" |
44 | #include "cpci_hotplug.h" | ||
44 | 45 | ||
45 | #define MY_NAME "pci_hotplug" | 46 | #define MY_NAME "pci_hotplug" |
46 | 47 | ||
@@ -63,14 +64,6 @@ static bool debug; | |||
63 | static LIST_HEAD(pci_hotplug_slot_list); | 64 | static LIST_HEAD(pci_hotplug_slot_list); |
64 | static DEFINE_MUTEX(pci_hp_mutex); | 65 | static DEFINE_MUTEX(pci_hp_mutex); |
65 | 66 | ||
66 | #ifdef CONFIG_HOTPLUG_PCI_CPCI | ||
67 | extern int cpci_hotplug_init(int debug); | ||
68 | extern void cpci_hotplug_exit(void); | ||
69 | #else | ||
70 | static inline int cpci_hotplug_init(int debug) { return 0; } | ||
71 | static inline void cpci_hotplug_exit(void) { } | ||
72 | #endif | ||
73 | |||
74 | /* Weee, fun with macros... */ | 67 | /* Weee, fun with macros... */ |
75 | #define GET_STATUS(name,type) \ | 68 | #define GET_STATUS(name,type) \ |
76 | static int get_##name (struct hotplug_slot *slot, type *value) \ | 69 | static int get_##name (struct hotplug_slot *slot, type *value) \ |
@@ -524,13 +517,11 @@ int pci_hp_deregister(struct hotplug_slot *hotplug) | |||
524 | * | 517 | * |
525 | * Returns 0 if successful, anything else for an error. | 518 | * Returns 0 if successful, anything else for an error. |
526 | */ | 519 | */ |
527 | int __must_check pci_hp_change_slot_info(struct hotplug_slot *hotplug, | 520 | int pci_hp_change_slot_info(struct hotplug_slot *hotplug, |
528 | struct hotplug_slot_info *info) | 521 | struct hotplug_slot_info *info) |
529 | { | 522 | { |
530 | struct pci_slot *slot; | ||
531 | if (!hotplug || !info) | 523 | if (!hotplug || !info) |
532 | return -ENODEV; | 524 | return -ENODEV; |
533 | slot = hotplug->pci_slot; | ||
534 | 525 | ||
535 | memcpy(hotplug->info, info, sizeof(struct hotplug_slot_info)); | 526 | memcpy(hotplug->info, info, sizeof(struct hotplug_slot_info)); |
536 | 527 | ||
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index 2c113de94323..7fb326983ed6 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h | |||
@@ -127,15 +127,15 @@ struct controller { | |||
127 | #define NO_CMD_CMPL(ctrl) ((ctrl)->slot_cap & PCI_EXP_SLTCAP_NCCS) | 127 | #define NO_CMD_CMPL(ctrl) ((ctrl)->slot_cap & PCI_EXP_SLTCAP_NCCS) |
128 | #define PSN(ctrl) ((ctrl)->slot_cap >> 19) | 128 | #define PSN(ctrl) ((ctrl)->slot_cap >> 19) |
129 | 129 | ||
130 | extern int pciehp_sysfs_enable_slot(struct slot *slot); | 130 | int pciehp_sysfs_enable_slot(struct slot *slot); |
131 | extern int pciehp_sysfs_disable_slot(struct slot *slot); | 131 | int pciehp_sysfs_disable_slot(struct slot *slot); |
132 | extern u8 pciehp_handle_attention_button(struct slot *p_slot); | 132 | u8 pciehp_handle_attention_button(struct slot *p_slot); |
133 | extern u8 pciehp_handle_switch_change(struct slot *p_slot); | 133 | u8 pciehp_handle_switch_change(struct slot *p_slot); |
134 | extern u8 pciehp_handle_presence_change(struct slot *p_slot); | 134 | u8 pciehp_handle_presence_change(struct slot *p_slot); |
135 | extern u8 pciehp_handle_power_fault(struct slot *p_slot); | 135 | u8 pciehp_handle_power_fault(struct slot *p_slot); |
136 | extern int pciehp_configure_device(struct slot *p_slot); | 136 | int pciehp_configure_device(struct slot *p_slot); |
137 | extern int pciehp_unconfigure_device(struct slot *p_slot); | 137 | int pciehp_unconfigure_device(struct slot *p_slot); |
138 | extern void pciehp_queue_pushbutton_work(struct work_struct *work); | 138 | void pciehp_queue_pushbutton_work(struct work_struct *work); |
139 | struct controller *pcie_init(struct pcie_device *dev); | 139 | struct controller *pcie_init(struct pcie_device *dev); |
140 | int pcie_init_notification(struct controller *ctrl); | 140 | int pcie_init_notification(struct controller *ctrl); |
141 | int pciehp_enable_slot(struct slot *p_slot); | 141 | int pciehp_enable_slot(struct slot *p_slot); |
@@ -166,8 +166,8 @@ static inline const char *slot_name(struct slot *slot) | |||
166 | #include <acpi/acpi_bus.h> | 166 | #include <acpi/acpi_bus.h> |
167 | #include <linux/pci-acpi.h> | 167 | #include <linux/pci-acpi.h> |
168 | 168 | ||
169 | extern void __init pciehp_acpi_slot_detection_init(void); | 169 | void __init pciehp_acpi_slot_detection_init(void); |
170 | extern int pciehp_acpi_slot_detection_check(struct pci_dev *dev); | 170 | int pciehp_acpi_slot_detection_check(struct pci_dev *dev); |
171 | 171 | ||
172 | static inline void pciehp_firmware_init(void) | 172 | static inline void pciehp_firmware_init(void) |
173 | { | 173 | { |
diff --git a/drivers/pci/hotplug/pciehp_acpi.c b/drivers/pci/hotplug/pciehp_acpi.c index 24d709b7388c..ead7c534095e 100644 --- a/drivers/pci/hotplug/pciehp_acpi.c +++ b/drivers/pci/hotplug/pciehp_acpi.c | |||
@@ -90,7 +90,7 @@ static int __init dummy_probe(struct pcie_device *dev) | |||
90 | slot = kzalloc(sizeof(*slot), GFP_KERNEL); | 90 | slot = kzalloc(sizeof(*slot), GFP_KERNEL); |
91 | if (!slot) | 91 | if (!slot) |
92 | return -ENOMEM; | 92 | return -ENOMEM; |
93 | slot->number = slot_cap >> 19; | 93 | slot->number = (slot_cap & PCI_EXP_SLTCAP_PSN) >> 19; |
94 | list_for_each_entry(tmp, &dummy_slots, list) { | 94 | list_for_each_entry(tmp, &dummy_slots, list) { |
95 | if (tmp->number == slot->number) | 95 | if (tmp->number == slot->number) |
96 | dup_slot_id++; | 96 | dup_slot_id++; |
diff --git a/drivers/pci/hotplug/rpadlpar.h b/drivers/pci/hotplug/rpadlpar.h index 4a0a59b82eae..81df93931ad0 100644 --- a/drivers/pci/hotplug/rpadlpar.h +++ b/drivers/pci/hotplug/rpadlpar.h | |||
@@ -15,10 +15,10 @@ | |||
15 | #ifndef _RPADLPAR_IO_H_ | 15 | #ifndef _RPADLPAR_IO_H_ |
16 | #define _RPADLPAR_IO_H_ | 16 | #define _RPADLPAR_IO_H_ |
17 | 17 | ||
18 | extern int dlpar_sysfs_init(void); | 18 | int dlpar_sysfs_init(void); |
19 | extern void dlpar_sysfs_exit(void); | 19 | void dlpar_sysfs_exit(void); |
20 | 20 | ||
21 | extern int dlpar_add_slot(char *drc_name); | 21 | int dlpar_add_slot(char *drc_name); |
22 | extern int dlpar_remove_slot(char *drc_name); | 22 | int dlpar_remove_slot(char *drc_name); |
23 | 23 | ||
24 | #endif | 24 | #endif |
diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h index df5677440a08..3135856e5e1c 100644 --- a/drivers/pci/hotplug/rpaphp.h +++ b/drivers/pci/hotplug/rpaphp.h | |||
@@ -86,18 +86,18 @@ extern struct list_head rpaphp_slot_head; | |||
86 | /* function prototypes */ | 86 | /* function prototypes */ |
87 | 87 | ||
88 | /* rpaphp_pci.c */ | 88 | /* rpaphp_pci.c */ |
89 | extern int rpaphp_enable_slot(struct slot *slot); | 89 | int rpaphp_enable_slot(struct slot *slot); |
90 | extern int rpaphp_get_sensor_state(struct slot *slot, int *state); | 90 | int rpaphp_get_sensor_state(struct slot *slot, int *state); |
91 | 91 | ||
92 | /* rpaphp_core.c */ | 92 | /* rpaphp_core.c */ |
93 | extern int rpaphp_add_slot(struct device_node *dn); | 93 | int rpaphp_add_slot(struct device_node *dn); |
94 | extern int rpaphp_get_drc_props(struct device_node *dn, int *drc_index, | 94 | int rpaphp_get_drc_props(struct device_node *dn, int *drc_index, |
95 | char **drc_name, char **drc_type, int *drc_power_domain); | 95 | char **drc_name, char **drc_type, int *drc_power_domain); |
96 | 96 | ||
97 | /* rpaphp_slot.c */ | 97 | /* rpaphp_slot.c */ |
98 | extern void dealloc_slot_struct(struct slot *slot); | 98 | void dealloc_slot_struct(struct slot *slot); |
99 | extern struct slot *alloc_slot_struct(struct device_node *dn, int drc_index, char *drc_name, int power_domain); | 99 | struct slot *alloc_slot_struct(struct device_node *dn, int drc_index, char *drc_name, int power_domain); |
100 | extern int rpaphp_register_slot(struct slot *slot); | 100 | int rpaphp_register_slot(struct slot *slot); |
101 | extern int rpaphp_deregister_slot(struct slot *slot); | 101 | int rpaphp_deregister_slot(struct slot *slot); |
102 | 102 | ||
103 | #endif /* _PPC64PHP_H */ | 103 | #endif /* _PPC64PHP_H */ |
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index b849f995075a..e260f207a90e 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h | |||
@@ -168,19 +168,19 @@ struct controller { | |||
168 | #define WRONG_BUS_FREQUENCY 0x0000000D | 168 | #define WRONG_BUS_FREQUENCY 0x0000000D |
169 | #define POWER_FAILURE 0x0000000E | 169 | #define POWER_FAILURE 0x0000000E |
170 | 170 | ||
171 | extern int __must_check shpchp_create_ctrl_files(struct controller *ctrl); | 171 | int __must_check shpchp_create_ctrl_files(struct controller *ctrl); |
172 | extern void shpchp_remove_ctrl_files(struct controller *ctrl); | 172 | void shpchp_remove_ctrl_files(struct controller *ctrl); |
173 | extern int shpchp_sysfs_enable_slot(struct slot *slot); | 173 | int shpchp_sysfs_enable_slot(struct slot *slot); |
174 | extern int shpchp_sysfs_disable_slot(struct slot *slot); | 174 | int shpchp_sysfs_disable_slot(struct slot *slot); |
175 | extern u8 shpchp_handle_attention_button(u8 hp_slot, struct controller *ctrl); | 175 | u8 shpchp_handle_attention_button(u8 hp_slot, struct controller *ctrl); |
176 | extern u8 shpchp_handle_switch_change(u8 hp_slot, struct controller *ctrl); | 176 | u8 shpchp_handle_switch_change(u8 hp_slot, struct controller *ctrl); |
177 | extern u8 shpchp_handle_presence_change(u8 hp_slot, struct controller *ctrl); | 177 | u8 shpchp_handle_presence_change(u8 hp_slot, struct controller *ctrl); |
178 | extern u8 shpchp_handle_power_fault(u8 hp_slot, struct controller *ctrl); | 178 | u8 shpchp_handle_power_fault(u8 hp_slot, struct controller *ctrl); |
179 | extern int shpchp_configure_device(struct slot *p_slot); | 179 | int shpchp_configure_device(struct slot *p_slot); |
180 | extern int shpchp_unconfigure_device(struct slot *p_slot); | 180 | int shpchp_unconfigure_device(struct slot *p_slot); |
181 | extern void cleanup_slots(struct controller *ctrl); | 181 | void cleanup_slots(struct controller *ctrl); |
182 | extern void shpchp_queue_pushbutton_work(struct work_struct *work); | 182 | void shpchp_queue_pushbutton_work(struct work_struct *work); |
183 | extern int shpc_init( struct controller *ctrl, struct pci_dev *pdev); | 183 | int shpc_init( struct controller *ctrl, struct pci_dev *pdev); |
184 | 184 | ||
185 | static inline const char *slot_name(struct slot *slot) | 185 | static inline const char *slot_name(struct slot *slot) |
186 | { | 186 | { |
diff --git a/drivers/pci/hotplug/shpchp_sysfs.c b/drivers/pci/hotplug/shpchp_sysfs.c index eeb23ceae4a8..e8c31fe20566 100644 --- a/drivers/pci/hotplug/shpchp_sysfs.c +++ b/drivers/pci/hotplug/shpchp_sysfs.c | |||
@@ -85,7 +85,7 @@ static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, cha | |||
85 | } | 85 | } |
86 | static DEVICE_ATTR (ctrl, S_IRUGO, show_ctrl, NULL); | 86 | static DEVICE_ATTR (ctrl, S_IRUGO, show_ctrl, NULL); |
87 | 87 | ||
88 | int __must_check shpchp_create_ctrl_files (struct controller *ctrl) | 88 | int shpchp_create_ctrl_files (struct controller *ctrl) |
89 | { | 89 | { |
90 | return device_create_file (&ctrl->pci_dev->dev, &dev_attr_ctrl); | 90 | return device_create_file (&ctrl->pci_dev->dev, &dev_attr_ctrl); |
91 | } | 91 | } |
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 00cc78c7aa04..d40bed726769 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -22,10 +22,12 @@ | |||
22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
23 | 23 | ||
24 | #include "pci.h" | 24 | #include "pci.h" |
25 | #include "msi.h" | ||
26 | 25 | ||
27 | static int pci_msi_enable = 1; | 26 | static int pci_msi_enable = 1; |
28 | 27 | ||
28 | #define msix_table_size(flags) ((flags & PCI_MSIX_FLAGS_QSIZE) + 1) | ||
29 | |||
30 | |||
29 | /* Arch hooks */ | 31 | /* Arch hooks */ |
30 | 32 | ||
31 | #ifndef arch_msi_check_device | 33 | #ifndef arch_msi_check_device |
@@ -111,32 +113,26 @@ void default_restore_msi_irqs(struct pci_dev *dev, int irq) | |||
111 | } | 113 | } |
112 | #endif | 114 | #endif |
113 | 115 | ||
114 | static void msi_set_enable(struct pci_dev *dev, int pos, int enable) | 116 | static void msi_set_enable(struct pci_dev *dev, int enable) |
115 | { | 117 | { |
116 | u16 control; | 118 | u16 control; |
117 | 119 | ||
118 | BUG_ON(!pos); | 120 | pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &control); |
119 | |||
120 | pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control); | ||
121 | control &= ~PCI_MSI_FLAGS_ENABLE; | 121 | control &= ~PCI_MSI_FLAGS_ENABLE; |
122 | if (enable) | 122 | if (enable) |
123 | control |= PCI_MSI_FLAGS_ENABLE; | 123 | control |= PCI_MSI_FLAGS_ENABLE; |
124 | pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control); | 124 | pci_write_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, control); |
125 | } | 125 | } |
126 | 126 | ||
127 | static void msix_set_enable(struct pci_dev *dev, int enable) | 127 | static void msix_set_enable(struct pci_dev *dev, int enable) |
128 | { | 128 | { |
129 | int pos; | ||
130 | u16 control; | 129 | u16 control; |
131 | 130 | ||
132 | pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); | 131 | pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control); |
133 | if (pos) { | 132 | control &= ~PCI_MSIX_FLAGS_ENABLE; |
134 | pci_read_config_word(dev, pos + PCI_MSIX_FLAGS, &control); | 133 | if (enable) |
135 | control &= ~PCI_MSIX_FLAGS_ENABLE; | 134 | control |= PCI_MSIX_FLAGS_ENABLE; |
136 | if (enable) | 135 | pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, control); |
137 | control |= PCI_MSIX_FLAGS_ENABLE; | ||
138 | pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control); | ||
139 | } | ||
140 | } | 136 | } |
141 | 137 | ||
142 | static inline __attribute_const__ u32 msi_mask(unsigned x) | 138 | static inline __attribute_const__ u32 msi_mask(unsigned x) |
@@ -247,18 +243,18 @@ void __read_msi_msg(struct msi_desc *entry, struct msi_msg *msg) | |||
247 | msg->data = readl(base + PCI_MSIX_ENTRY_DATA); | 243 | msg->data = readl(base + PCI_MSIX_ENTRY_DATA); |
248 | } else { | 244 | } else { |
249 | struct pci_dev *dev = entry->dev; | 245 | struct pci_dev *dev = entry->dev; |
250 | int pos = entry->msi_attrib.pos; | 246 | int pos = dev->msi_cap; |
251 | u16 data; | 247 | u16 data; |
252 | 248 | ||
253 | pci_read_config_dword(dev, msi_lower_address_reg(pos), | 249 | pci_read_config_dword(dev, pos + PCI_MSI_ADDRESS_LO, |
254 | &msg->address_lo); | 250 | &msg->address_lo); |
255 | if (entry->msi_attrib.is_64) { | 251 | if (entry->msi_attrib.is_64) { |
256 | pci_read_config_dword(dev, msi_upper_address_reg(pos), | 252 | pci_read_config_dword(dev, pos + PCI_MSI_ADDRESS_HI, |
257 | &msg->address_hi); | 253 | &msg->address_hi); |
258 | pci_read_config_word(dev, msi_data_reg(pos, 1), &data); | 254 | pci_read_config_word(dev, pos + PCI_MSI_DATA_64, &data); |
259 | } else { | 255 | } else { |
260 | msg->address_hi = 0; | 256 | msg->address_hi = 0; |
261 | pci_read_config_word(dev, msi_data_reg(pos, 0), &data); | 257 | pci_read_config_word(dev, pos + PCI_MSI_DATA_32, &data); |
262 | } | 258 | } |
263 | msg->data = data; | 259 | msg->data = data; |
264 | } | 260 | } |
@@ -302,24 +298,24 @@ void __write_msi_msg(struct msi_desc *entry, struct msi_msg *msg) | |||
302 | writel(msg->data, base + PCI_MSIX_ENTRY_DATA); | 298 | writel(msg->data, base + PCI_MSIX_ENTRY_DATA); |
303 | } else { | 299 | } else { |
304 | struct pci_dev *dev = entry->dev; | 300 | struct pci_dev *dev = entry->dev; |
305 | int pos = entry->msi_attrib.pos; | 301 | int pos = dev->msi_cap; |
306 | u16 msgctl; | 302 | u16 msgctl; |
307 | 303 | ||
308 | pci_read_config_word(dev, msi_control_reg(pos), &msgctl); | 304 | pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &msgctl); |
309 | msgctl &= ~PCI_MSI_FLAGS_QSIZE; | 305 | msgctl &= ~PCI_MSI_FLAGS_QSIZE; |
310 | msgctl |= entry->msi_attrib.multiple << 4; | 306 | msgctl |= entry->msi_attrib.multiple << 4; |
311 | pci_write_config_word(dev, msi_control_reg(pos), msgctl); | 307 | pci_write_config_word(dev, pos + PCI_MSI_FLAGS, msgctl); |
312 | 308 | ||
313 | pci_write_config_dword(dev, msi_lower_address_reg(pos), | 309 | pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_LO, |
314 | msg->address_lo); | 310 | msg->address_lo); |
315 | if (entry->msi_attrib.is_64) { | 311 | if (entry->msi_attrib.is_64) { |
316 | pci_write_config_dword(dev, msi_upper_address_reg(pos), | 312 | pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_HI, |
317 | msg->address_hi); | 313 | msg->address_hi); |
318 | pci_write_config_word(dev, msi_data_reg(pos, 1), | 314 | pci_write_config_word(dev, pos + PCI_MSI_DATA_64, |
319 | msg->data); | 315 | msg->data); |
320 | } else { | 316 | } else { |
321 | pci_write_config_word(dev, msi_data_reg(pos, 0), | 317 | pci_write_config_word(dev, pos + PCI_MSI_DATA_32, |
322 | msg->data); | 318 | msg->data); |
323 | } | 319 | } |
324 | } | 320 | } |
325 | entry->msg = *msg; | 321 | entry->msg = *msg; |
@@ -391,7 +387,6 @@ static void pci_intx_for_msi(struct pci_dev *dev, int enable) | |||
391 | 387 | ||
392 | static void __pci_restore_msi_state(struct pci_dev *dev) | 388 | static void __pci_restore_msi_state(struct pci_dev *dev) |
393 | { | 389 | { |
394 | int pos; | ||
395 | u16 control; | 390 | u16 control; |
396 | struct msi_desc *entry; | 391 | struct msi_desc *entry; |
397 | 392 | ||
@@ -399,22 +394,20 @@ static void __pci_restore_msi_state(struct pci_dev *dev) | |||
399 | return; | 394 | return; |
400 | 395 | ||
401 | entry = irq_get_msi_desc(dev->irq); | 396 | entry = irq_get_msi_desc(dev->irq); |
402 | pos = entry->msi_attrib.pos; | ||
403 | 397 | ||
404 | pci_intx_for_msi(dev, 0); | 398 | pci_intx_for_msi(dev, 0); |
405 | msi_set_enable(dev, pos, 0); | 399 | msi_set_enable(dev, 0); |
406 | arch_restore_msi_irqs(dev, dev->irq); | 400 | arch_restore_msi_irqs(dev, dev->irq); |
407 | 401 | ||
408 | pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control); | 402 | pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &control); |
409 | msi_mask_irq(entry, msi_capable_mask(control), entry->masked); | 403 | msi_mask_irq(entry, msi_capable_mask(control), entry->masked); |
410 | control &= ~PCI_MSI_FLAGS_QSIZE; | 404 | control &= ~PCI_MSI_FLAGS_QSIZE; |
411 | control |= (entry->msi_attrib.multiple << 4) | PCI_MSI_FLAGS_ENABLE; | 405 | control |= (entry->msi_attrib.multiple << 4) | PCI_MSI_FLAGS_ENABLE; |
412 | pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control); | 406 | pci_write_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, control); |
413 | } | 407 | } |
414 | 408 | ||
415 | static void __pci_restore_msix_state(struct pci_dev *dev) | 409 | static void __pci_restore_msix_state(struct pci_dev *dev) |
416 | { | 410 | { |
417 | int pos; | ||
418 | struct msi_desc *entry; | 411 | struct msi_desc *entry; |
419 | u16 control; | 412 | u16 control; |
420 | 413 | ||
@@ -422,13 +415,12 @@ static void __pci_restore_msix_state(struct pci_dev *dev) | |||
422 | return; | 415 | return; |
423 | BUG_ON(list_empty(&dev->msi_list)); | 416 | BUG_ON(list_empty(&dev->msi_list)); |
424 | entry = list_first_entry(&dev->msi_list, struct msi_desc, list); | 417 | entry = list_first_entry(&dev->msi_list, struct msi_desc, list); |
425 | pos = entry->msi_attrib.pos; | 418 | pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control); |
426 | pci_read_config_word(dev, pos + PCI_MSIX_FLAGS, &control); | ||
427 | 419 | ||
428 | /* route the table */ | 420 | /* route the table */ |
429 | pci_intx_for_msi(dev, 0); | 421 | pci_intx_for_msi(dev, 0); |
430 | control |= PCI_MSIX_FLAGS_ENABLE | PCI_MSIX_FLAGS_MASKALL; | 422 | control |= PCI_MSIX_FLAGS_ENABLE | PCI_MSIX_FLAGS_MASKALL; |
431 | pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control); | 423 | pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, control); |
432 | 424 | ||
433 | list_for_each_entry(entry, &dev->msi_list, list) { | 425 | list_for_each_entry(entry, &dev->msi_list, list) { |
434 | arch_restore_msi_irqs(dev, entry->irq); | 426 | arch_restore_msi_irqs(dev, entry->irq); |
@@ -436,7 +428,7 @@ static void __pci_restore_msix_state(struct pci_dev *dev) | |||
436 | } | 428 | } |
437 | 429 | ||
438 | control &= ~PCI_MSIX_FLAGS_MASKALL; | 430 | control &= ~PCI_MSIX_FLAGS_MASKALL; |
439 | pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control); | 431 | pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, control); |
440 | } | 432 | } |
441 | 433 | ||
442 | void pci_restore_msi_state(struct pci_dev *dev) | 434 | void pci_restore_msi_state(struct pci_dev *dev) |
@@ -484,12 +476,12 @@ static struct msi_attribute mode_attribute = | |||
484 | __ATTR(mode, S_IRUGO, show_msi_mode, NULL); | 476 | __ATTR(mode, S_IRUGO, show_msi_mode, NULL); |
485 | 477 | ||
486 | 478 | ||
487 | struct attribute *msi_irq_default_attrs[] = { | 479 | static struct attribute *msi_irq_default_attrs[] = { |
488 | &mode_attribute.attr, | 480 | &mode_attribute.attr, |
489 | NULL | 481 | NULL |
490 | }; | 482 | }; |
491 | 483 | ||
492 | void msi_kobj_release(struct kobject *kobj) | 484 | static void msi_kobj_release(struct kobject *kobj) |
493 | { | 485 | { |
494 | struct msi_desc *entry = to_msi_desc(kobj); | 486 | struct msi_desc *entry = to_msi_desc(kobj); |
495 | 487 | ||
@@ -552,27 +544,27 @@ out_unroll: | |||
552 | static int msi_capability_init(struct pci_dev *dev, int nvec) | 544 | static int msi_capability_init(struct pci_dev *dev, int nvec) |
553 | { | 545 | { |
554 | struct msi_desc *entry; | 546 | struct msi_desc *entry; |
555 | int pos, ret; | 547 | int ret; |
556 | u16 control; | 548 | u16 control; |
557 | unsigned mask; | 549 | unsigned mask; |
558 | 550 | ||
559 | pos = pci_find_capability(dev, PCI_CAP_ID_MSI); | 551 | msi_set_enable(dev, 0); /* Disable MSI during set up */ |
560 | msi_set_enable(dev, pos, 0); /* Disable MSI during set up */ | ||
561 | 552 | ||
562 | pci_read_config_word(dev, msi_control_reg(pos), &control); | 553 | pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &control); |
563 | /* MSI Entry Initialization */ | 554 | /* MSI Entry Initialization */ |
564 | entry = alloc_msi_entry(dev); | 555 | entry = alloc_msi_entry(dev); |
565 | if (!entry) | 556 | if (!entry) |
566 | return -ENOMEM; | 557 | return -ENOMEM; |
567 | 558 | ||
568 | entry->msi_attrib.is_msix = 0; | 559 | entry->msi_attrib.is_msix = 0; |
569 | entry->msi_attrib.is_64 = is_64bit_address(control); | 560 | entry->msi_attrib.is_64 = !!(control & PCI_MSI_FLAGS_64BIT); |
570 | entry->msi_attrib.entry_nr = 0; | 561 | entry->msi_attrib.entry_nr = 0; |
571 | entry->msi_attrib.maskbit = is_mask_bit_support(control); | 562 | entry->msi_attrib.maskbit = !!(control & PCI_MSI_FLAGS_MASKBIT); |
572 | entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */ | 563 | entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */ |
573 | entry->msi_attrib.pos = pos; | 564 | entry->msi_attrib.pos = dev->msi_cap; |
574 | 565 | ||
575 | entry->mask_pos = msi_mask_reg(pos, entry->msi_attrib.is_64); | 566 | entry->mask_pos = dev->msi_cap + (control & PCI_MSI_FLAGS_64BIT) ? |
567 | PCI_MSI_MASK_64 : PCI_MSI_MASK_32; | ||
576 | /* All MSIs are unmasked by default, Mask them all */ | 568 | /* All MSIs are unmasked by default, Mask them all */ |
577 | if (entry->msi_attrib.maskbit) | 569 | if (entry->msi_attrib.maskbit) |
578 | pci_read_config_dword(dev, entry->mask_pos, &entry->masked); | 570 | pci_read_config_dword(dev, entry->mask_pos, &entry->masked); |
@@ -598,31 +590,30 @@ static int msi_capability_init(struct pci_dev *dev, int nvec) | |||
598 | 590 | ||
599 | /* Set MSI enabled bits */ | 591 | /* Set MSI enabled bits */ |
600 | pci_intx_for_msi(dev, 0); | 592 | pci_intx_for_msi(dev, 0); |
601 | msi_set_enable(dev, pos, 1); | 593 | msi_set_enable(dev, 1); |
602 | dev->msi_enabled = 1; | 594 | dev->msi_enabled = 1; |
603 | 595 | ||
604 | dev->irq = entry->irq; | 596 | dev->irq = entry->irq; |
605 | return 0; | 597 | return 0; |
606 | } | 598 | } |
607 | 599 | ||
608 | static void __iomem *msix_map_region(struct pci_dev *dev, unsigned pos, | 600 | static void __iomem *msix_map_region(struct pci_dev *dev, unsigned nr_entries) |
609 | unsigned nr_entries) | ||
610 | { | 601 | { |
611 | resource_size_t phys_addr; | 602 | resource_size_t phys_addr; |
612 | u32 table_offset; | 603 | u32 table_offset; |
613 | u8 bir; | 604 | u8 bir; |
614 | 605 | ||
615 | pci_read_config_dword(dev, msix_table_offset_reg(pos), &table_offset); | 606 | pci_read_config_dword(dev, dev->msix_cap + PCI_MSIX_TABLE, |
616 | bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK); | 607 | &table_offset); |
617 | table_offset &= ~PCI_MSIX_FLAGS_BIRMASK; | 608 | bir = (u8)(table_offset & PCI_MSIX_TABLE_BIR); |
609 | table_offset &= PCI_MSIX_TABLE_OFFSET; | ||
618 | phys_addr = pci_resource_start(dev, bir) + table_offset; | 610 | phys_addr = pci_resource_start(dev, bir) + table_offset; |
619 | 611 | ||
620 | return ioremap_nocache(phys_addr, nr_entries * PCI_MSIX_ENTRY_SIZE); | 612 | return ioremap_nocache(phys_addr, nr_entries * PCI_MSIX_ENTRY_SIZE); |
621 | } | 613 | } |
622 | 614 | ||
623 | static int msix_setup_entries(struct pci_dev *dev, unsigned pos, | 615 | static int msix_setup_entries(struct pci_dev *dev, void __iomem *base, |
624 | void __iomem *base, struct msix_entry *entries, | 616 | struct msix_entry *entries, int nvec) |
625 | int nvec) | ||
626 | { | 617 | { |
627 | struct msi_desc *entry; | 618 | struct msi_desc *entry; |
628 | int i; | 619 | int i; |
@@ -642,7 +633,7 @@ static int msix_setup_entries(struct pci_dev *dev, unsigned pos, | |||
642 | entry->msi_attrib.is_64 = 1; | 633 | entry->msi_attrib.is_64 = 1; |
643 | entry->msi_attrib.entry_nr = entries[i].entry; | 634 | entry->msi_attrib.entry_nr = entries[i].entry; |
644 | entry->msi_attrib.default_irq = dev->irq; | 635 | entry->msi_attrib.default_irq = dev->irq; |
645 | entry->msi_attrib.pos = pos; | 636 | entry->msi_attrib.pos = dev->msix_cap; |
646 | entry->mask_base = base; | 637 | entry->mask_base = base; |
647 | 638 | ||
648 | list_add_tail(&entry->list, &dev->msi_list); | 639 | list_add_tail(&entry->list, &dev->msi_list); |
@@ -652,7 +643,7 @@ static int msix_setup_entries(struct pci_dev *dev, unsigned pos, | |||
652 | } | 643 | } |
653 | 644 | ||
654 | static void msix_program_entries(struct pci_dev *dev, | 645 | static void msix_program_entries(struct pci_dev *dev, |
655 | struct msix_entry *entries) | 646 | struct msix_entry *entries) |
656 | { | 647 | { |
657 | struct msi_desc *entry; | 648 | struct msi_desc *entry; |
658 | int i = 0; | 649 | int i = 0; |
@@ -682,23 +673,22 @@ static void msix_program_entries(struct pci_dev *dev, | |||
682 | static int msix_capability_init(struct pci_dev *dev, | 673 | static int msix_capability_init(struct pci_dev *dev, |
683 | struct msix_entry *entries, int nvec) | 674 | struct msix_entry *entries, int nvec) |
684 | { | 675 | { |
685 | int pos, ret; | 676 | int ret; |
686 | u16 control; | 677 | u16 control; |
687 | void __iomem *base; | 678 | void __iomem *base; |
688 | 679 | ||
689 | pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); | 680 | pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control); |
690 | pci_read_config_word(dev, pos + PCI_MSIX_FLAGS, &control); | ||
691 | 681 | ||
692 | /* Ensure MSI-X is disabled while it is set up */ | 682 | /* Ensure MSI-X is disabled while it is set up */ |
693 | control &= ~PCI_MSIX_FLAGS_ENABLE; | 683 | control &= ~PCI_MSIX_FLAGS_ENABLE; |
694 | pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control); | 684 | pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, control); |
695 | 685 | ||
696 | /* Request & Map MSI-X table region */ | 686 | /* Request & Map MSI-X table region */ |
697 | base = msix_map_region(dev, pos, multi_msix_capable(control)); | 687 | base = msix_map_region(dev, msix_table_size(control)); |
698 | if (!base) | 688 | if (!base) |
699 | return -ENOMEM; | 689 | return -ENOMEM; |
700 | 690 | ||
701 | ret = msix_setup_entries(dev, pos, base, entries, nvec); | 691 | ret = msix_setup_entries(dev, base, entries, nvec); |
702 | if (ret) | 692 | if (ret) |
703 | return ret; | 693 | return ret; |
704 | 694 | ||
@@ -712,7 +702,7 @@ static int msix_capability_init(struct pci_dev *dev, | |||
712 | * interrupts coming in before they're fully set up. | 702 | * interrupts coming in before they're fully set up. |
713 | */ | 703 | */ |
714 | control |= PCI_MSIX_FLAGS_MASKALL | PCI_MSIX_FLAGS_ENABLE; | 704 | control |= PCI_MSIX_FLAGS_MASKALL | PCI_MSIX_FLAGS_ENABLE; |
715 | pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control); | 705 | pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, control); |
716 | 706 | ||
717 | msix_program_entries(dev, entries); | 707 | msix_program_entries(dev, entries); |
718 | 708 | ||
@@ -727,7 +717,7 @@ static int msix_capability_init(struct pci_dev *dev, | |||
727 | dev->msix_enabled = 1; | 717 | dev->msix_enabled = 1; |
728 | 718 | ||
729 | control &= ~PCI_MSIX_FLAGS_MASKALL; | 719 | control &= ~PCI_MSIX_FLAGS_MASKALL; |
730 | pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control); | 720 | pci_write_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, control); |
731 | 721 | ||
732 | return 0; | 722 | return 0; |
733 | 723 | ||
@@ -795,9 +785,6 @@ static int pci_msi_check_device(struct pci_dev *dev, int nvec, int type) | |||
795 | if (ret) | 785 | if (ret) |
796 | return ret; | 786 | return ret; |
797 | 787 | ||
798 | if (!pci_find_capability(dev, type)) | ||
799 | return -EINVAL; | ||
800 | |||
801 | return 0; | 788 | return 0; |
802 | } | 789 | } |
803 | 790 | ||
@@ -816,13 +803,13 @@ static int pci_msi_check_device(struct pci_dev *dev, int nvec, int type) | |||
816 | */ | 803 | */ |
817 | int pci_enable_msi_block(struct pci_dev *dev, unsigned int nvec) | 804 | int pci_enable_msi_block(struct pci_dev *dev, unsigned int nvec) |
818 | { | 805 | { |
819 | int status, pos, maxvec; | 806 | int status, maxvec; |
820 | u16 msgctl; | 807 | u16 msgctl; |
821 | 808 | ||
822 | pos = pci_find_capability(dev, PCI_CAP_ID_MSI); | 809 | if (!dev->msi_cap) |
823 | if (!pos) | ||
824 | return -EINVAL; | 810 | return -EINVAL; |
825 | pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &msgctl); | 811 | |
812 | pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &msgctl); | ||
826 | maxvec = 1 << ((msgctl & PCI_MSI_FLAGS_QMASK) >> 1); | 813 | maxvec = 1 << ((msgctl & PCI_MSI_FLAGS_QMASK) >> 1); |
827 | if (nvec > maxvec) | 814 | if (nvec > maxvec) |
828 | return maxvec; | 815 | return maxvec; |
@@ -847,14 +834,13 @@ EXPORT_SYMBOL(pci_enable_msi_block); | |||
847 | 834 | ||
848 | int pci_enable_msi_block_auto(struct pci_dev *dev, unsigned int *maxvec) | 835 | int pci_enable_msi_block_auto(struct pci_dev *dev, unsigned int *maxvec) |
849 | { | 836 | { |
850 | int ret, pos, nvec; | 837 | int ret, nvec; |
851 | u16 msgctl; | 838 | u16 msgctl; |
852 | 839 | ||
853 | pos = pci_find_capability(dev, PCI_CAP_ID_MSI); | 840 | if (!dev->msi_cap) |
854 | if (!pos) | ||
855 | return -EINVAL; | 841 | return -EINVAL; |
856 | 842 | ||
857 | pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &msgctl); | 843 | pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &msgctl); |
858 | ret = 1 << ((msgctl & PCI_MSI_FLAGS_QMASK) >> 1); | 844 | ret = 1 << ((msgctl & PCI_MSI_FLAGS_QMASK) >> 1); |
859 | 845 | ||
860 | if (maxvec) | 846 | if (maxvec) |
@@ -876,21 +862,19 @@ void pci_msi_shutdown(struct pci_dev *dev) | |||
876 | struct msi_desc *desc; | 862 | struct msi_desc *desc; |
877 | u32 mask; | 863 | u32 mask; |
878 | u16 ctrl; | 864 | u16 ctrl; |
879 | unsigned pos; | ||
880 | 865 | ||
881 | if (!pci_msi_enable || !dev || !dev->msi_enabled) | 866 | if (!pci_msi_enable || !dev || !dev->msi_enabled) |
882 | return; | 867 | return; |
883 | 868 | ||
884 | BUG_ON(list_empty(&dev->msi_list)); | 869 | BUG_ON(list_empty(&dev->msi_list)); |
885 | desc = list_first_entry(&dev->msi_list, struct msi_desc, list); | 870 | desc = list_first_entry(&dev->msi_list, struct msi_desc, list); |
886 | pos = desc->msi_attrib.pos; | ||
887 | 871 | ||
888 | msi_set_enable(dev, pos, 0); | 872 | msi_set_enable(dev, 0); |
889 | pci_intx_for_msi(dev, 1); | 873 | pci_intx_for_msi(dev, 1); |
890 | dev->msi_enabled = 0; | 874 | dev->msi_enabled = 0; |
891 | 875 | ||
892 | /* Return the device with MSI unmasked as initial states */ | 876 | /* Return the device with MSI unmasked as initial states */ |
893 | pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &ctrl); | 877 | pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &ctrl); |
894 | mask = msi_capable_mask(ctrl); | 878 | mask = msi_capable_mask(ctrl); |
895 | /* Keep cached state to be restored */ | 879 | /* Keep cached state to be restored */ |
896 | __msi_mask_irq(desc, mask, ~mask); | 880 | __msi_mask_irq(desc, mask, ~mask); |
@@ -917,15 +901,13 @@ EXPORT_SYMBOL(pci_disable_msi); | |||
917 | */ | 901 | */ |
918 | int pci_msix_table_size(struct pci_dev *dev) | 902 | int pci_msix_table_size(struct pci_dev *dev) |
919 | { | 903 | { |
920 | int pos; | ||
921 | u16 control; | 904 | u16 control; |
922 | 905 | ||
923 | pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); | 906 | if (!dev->msix_cap) |
924 | if (!pos) | ||
925 | return 0; | 907 | return 0; |
926 | 908 | ||
927 | pci_read_config_word(dev, msi_control_reg(pos), &control); | 909 | pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control); |
928 | return multi_msix_capable(control); | 910 | return msix_table_size(control); |
929 | } | 911 | } |
930 | 912 | ||
931 | /** | 913 | /** |
@@ -948,7 +930,7 @@ int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec) | |||
948 | int status, nr_entries; | 930 | int status, nr_entries; |
949 | int i, j; | 931 | int i, j; |
950 | 932 | ||
951 | if (!entries) | 933 | if (!entries || !dev->msix_cap) |
952 | return -EINVAL; | 934 | return -EINVAL; |
953 | 935 | ||
954 | status = pci_msi_check_device(dev, nvec, PCI_CAP_ID_MSIX); | 936 | status = pci_msi_check_device(dev, nvec, PCI_CAP_ID_MSIX); |
@@ -1048,15 +1030,17 @@ EXPORT_SYMBOL(pci_msi_enabled); | |||
1048 | 1030 | ||
1049 | void pci_msi_init_pci_dev(struct pci_dev *dev) | 1031 | void pci_msi_init_pci_dev(struct pci_dev *dev) |
1050 | { | 1032 | { |
1051 | int pos; | ||
1052 | INIT_LIST_HEAD(&dev->msi_list); | 1033 | INIT_LIST_HEAD(&dev->msi_list); |
1053 | 1034 | ||
1054 | /* Disable the msi hardware to avoid screaming interrupts | 1035 | /* Disable the msi hardware to avoid screaming interrupts |
1055 | * during boot. This is the power on reset default so | 1036 | * during boot. This is the power on reset default so |
1056 | * usually this should be a noop. | 1037 | * usually this should be a noop. |
1057 | */ | 1038 | */ |
1058 | pos = pci_find_capability(dev, PCI_CAP_ID_MSI); | 1039 | dev->msi_cap = pci_find_capability(dev, PCI_CAP_ID_MSI); |
1059 | if (pos) | 1040 | if (dev->msi_cap) |
1060 | msi_set_enable(dev, pos, 0); | 1041 | msi_set_enable(dev, 0); |
1061 | msix_set_enable(dev, 0); | 1042 | |
1043 | dev->msix_cap = pci_find_capability(dev, PCI_CAP_ID_MSIX); | ||
1044 | if (dev->msix_cap) | ||
1045 | msix_set_enable(dev, 0); | ||
1062 | } | 1046 | } |
diff --git a/drivers/pci/msi.h b/drivers/pci/msi.h deleted file mode 100644 index 65c42f80f23e..000000000000 --- a/drivers/pci/msi.h +++ /dev/null | |||
@@ -1,24 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2003-2004 Intel | ||
3 | * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com) | ||
4 | */ | ||
5 | |||
6 | #ifndef MSI_H | ||
7 | #define MSI_H | ||
8 | |||
9 | #define msi_control_reg(base) (base + PCI_MSI_FLAGS) | ||
10 | #define msi_lower_address_reg(base) (base + PCI_MSI_ADDRESS_LO) | ||
11 | #define msi_upper_address_reg(base) (base + PCI_MSI_ADDRESS_HI) | ||
12 | #define msi_data_reg(base, is64bit) \ | ||
13 | (base + ((is64bit == 1) ? PCI_MSI_DATA_64 : PCI_MSI_DATA_32)) | ||
14 | #define msi_mask_reg(base, is64bit) \ | ||
15 | (base + ((is64bit == 1) ? PCI_MSI_MASK_64 : PCI_MSI_MASK_32)) | ||
16 | #define is_64bit_address(control) (!!(control & PCI_MSI_FLAGS_64BIT)) | ||
17 | #define is_mask_bit_support(control) (!!(control & PCI_MSI_FLAGS_MASKBIT)) | ||
18 | |||
19 | #define msix_table_offset_reg(base) (base + PCI_MSIX_TABLE) | ||
20 | #define msix_pba_offset_reg(base) (base + PCI_MSIX_PBA) | ||
21 | #define msix_table_size(control) ((control & PCI_MSIX_FLAGS_QSIZE)+1) | ||
22 | #define multi_msix_capable(control) msix_table_size((control)) | ||
23 | |||
24 | #endif /* MSI_H */ | ||
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 5147c210df52..e4b1fb2c0f5d 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
@@ -288,6 +288,32 @@ static struct pci_platform_pm_ops acpi_pci_platform_pm = { | |||
288 | .run_wake = acpi_pci_run_wake, | 288 | .run_wake = acpi_pci_run_wake, |
289 | }; | 289 | }; |
290 | 290 | ||
291 | void acpi_pci_add_bus(struct pci_bus *bus) | ||
292 | { | ||
293 | acpi_handle handle = NULL; | ||
294 | |||
295 | if (bus->bridge) | ||
296 | handle = ACPI_HANDLE(bus->bridge); | ||
297 | if (acpi_pci_disabled || handle == NULL) | ||
298 | return; | ||
299 | |||
300 | acpi_pci_slot_enumerate(bus, handle); | ||
301 | acpiphp_enumerate_slots(bus, handle); | ||
302 | } | ||
303 | |||
304 | void acpi_pci_remove_bus(struct pci_bus *bus) | ||
305 | { | ||
306 | /* | ||
307 | * bus->bridge->acpi_node.handle has already been reset to NULL | ||
308 | * when acpi_pci_remove_bus() is called, so don't check ACPI handle. | ||
309 | */ | ||
310 | if (acpi_pci_disabled) | ||
311 | return; | ||
312 | |||
313 | acpiphp_remove_slots(bus); | ||
314 | acpi_pci_slot_remove(bus); | ||
315 | } | ||
316 | |||
291 | /* ACPI bus type */ | 317 | /* ACPI bus type */ |
292 | static int acpi_pci_find_device(struct device *dev, acpi_handle *handle) | 318 | static int acpi_pci_find_device(struct device *dev, acpi_handle *handle) |
293 | { | 319 | { |
@@ -362,7 +388,11 @@ static int __init acpi_pci_init(void) | |||
362 | ret = register_acpi_bus_type(&acpi_pci_bus); | 388 | ret = register_acpi_bus_type(&acpi_pci_bus); |
363 | if (ret) | 389 | if (ret) |
364 | return 0; | 390 | return 0; |
391 | |||
365 | pci_set_platform_pm(&acpi_pci_platform_pm); | 392 | pci_set_platform_pm(&acpi_pci_platform_pm); |
393 | acpi_pci_slot_init(); | ||
394 | acpiphp_init(); | ||
395 | |||
366 | return 0; | 396 | return 0; |
367 | } | 397 | } |
368 | arch_initcall(acpi_pci_init); | 398 | arch_initcall(acpi_pci_init); |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 9c6e9bb674ec..5b4a9d9cd200 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -897,7 +897,7 @@ int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma, | |||
897 | 897 | ||
898 | if (pci_resource_len(pdev, resno) == 0) | 898 | if (pci_resource_len(pdev, resno) == 0) |
899 | return 0; | 899 | return 0; |
900 | nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; | 900 | nr = vma_pages(vma); |
901 | start = vma->vm_pgoff; | 901 | start = vma->vm_pgoff; |
902 | size = ((pci_resource_len(pdev, resno) - 1) >> PAGE_SHIFT) + 1; | 902 | size = ((pci_resource_len(pdev, resno) - 1) >> PAGE_SHIFT) + 1; |
903 | pci_start = (mmap_api == PCI_MMAP_PROCFS) ? | 903 | pci_start = (mmap_api == PCI_MMAP_PROCFS) ? |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index b099e0025d2b..a899d8bb190d 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -646,15 +646,11 @@ static int pci_platform_power_transition(struct pci_dev *dev, pci_power_t state) | |||
646 | error = platform_pci_set_power_state(dev, state); | 646 | error = platform_pci_set_power_state(dev, state); |
647 | if (!error) | 647 | if (!error) |
648 | pci_update_current_state(dev, state); | 648 | pci_update_current_state(dev, state); |
649 | /* Fall back to PCI_D0 if native PM is not supported */ | 649 | } else |
650 | if (!dev->pm_cap) | ||
651 | dev->current_state = PCI_D0; | ||
652 | } else { | ||
653 | error = -ENODEV; | 650 | error = -ENODEV; |
654 | /* Fall back to PCI_D0 if native PM is not supported */ | 651 | |
655 | if (!dev->pm_cap) | 652 | if (error && !dev->pm_cap) /* Fall back to PCI_D0 */ |
656 | dev->current_state = PCI_D0; | 653 | dev->current_state = PCI_D0; |
657 | } | ||
658 | 654 | ||
659 | return error; | 655 | return error; |
660 | } | 656 | } |
@@ -1575,7 +1571,7 @@ void pci_pme_active(struct pci_dev *dev, bool enable) | |||
1575 | { | 1571 | { |
1576 | u16 pmcsr; | 1572 | u16 pmcsr; |
1577 | 1573 | ||
1578 | if (!dev->pm_cap) | 1574 | if (!dev->pme_support) |
1579 | return; | 1575 | return; |
1580 | 1576 | ||
1581 | pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr); | 1577 | pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr); |
@@ -1924,6 +1920,7 @@ void pci_pm_init(struct pci_dev *dev) | |||
1924 | dev->wakeup_prepared = false; | 1920 | dev->wakeup_prepared = false; |
1925 | 1921 | ||
1926 | dev->pm_cap = 0; | 1922 | dev->pm_cap = 0; |
1923 | dev->pme_support = 0; | ||
1927 | 1924 | ||
1928 | /* find PCI PM capability in list */ | 1925 | /* find PCI PM capability in list */ |
1929 | pm = pci_find_capability(dev, PCI_CAP_ID_PM); | 1926 | pm = pci_find_capability(dev, PCI_CAP_ID_PM); |
@@ -1975,8 +1972,6 @@ void pci_pm_init(struct pci_dev *dev) | |||
1975 | device_set_wakeup_capable(&dev->dev, true); | 1972 | device_set_wakeup_capable(&dev->dev, true); |
1976 | /* Disable the PME# generation functionality */ | 1973 | /* Disable the PME# generation functionality */ |
1977 | pci_pme_active(dev, false); | 1974 | pci_pme_active(dev, false); |
1978 | } else { | ||
1979 | dev->pme_support = 0; | ||
1980 | } | 1975 | } |
1981 | } | 1976 | } |
1982 | 1977 | ||
@@ -2619,7 +2614,7 @@ void pci_release_selected_regions(struct pci_dev *pdev, int bars) | |||
2619 | pci_release_region(pdev, i); | 2614 | pci_release_region(pdev, i); |
2620 | } | 2615 | } |
2621 | 2616 | ||
2622 | int __pci_request_selected_regions(struct pci_dev *pdev, int bars, | 2617 | static int __pci_request_selected_regions(struct pci_dev *pdev, int bars, |
2623 | const char *res_name, int excl) | 2618 | const char *res_name, int excl) |
2624 | { | 2619 | { |
2625 | int i; | 2620 | int i; |
@@ -3699,7 +3694,7 @@ static DEFINE_SPINLOCK(resource_alignment_lock); | |||
3699 | * RETURNS: Resource alignment if it is specified. | 3694 | * RETURNS: Resource alignment if it is specified. |
3700 | * Zero if it is not specified. | 3695 | * Zero if it is not specified. |
3701 | */ | 3696 | */ |
3702 | resource_size_t pci_specified_resource_alignment(struct pci_dev *dev) | 3697 | static resource_size_t pci_specified_resource_alignment(struct pci_dev *dev) |
3703 | { | 3698 | { |
3704 | int seg, bus, slot, func, align_order, count; | 3699 | int seg, bus, slot, func, align_order, count; |
3705 | resource_size_t align = 0; | 3700 | resource_size_t align = 0; |
@@ -3812,7 +3807,7 @@ void pci_reassigndev_resource_alignment(struct pci_dev *dev) | |||
3812 | } | 3807 | } |
3813 | } | 3808 | } |
3814 | 3809 | ||
3815 | ssize_t pci_set_resource_alignment_param(const char *buf, size_t count) | 3810 | static ssize_t pci_set_resource_alignment_param(const char *buf, size_t count) |
3816 | { | 3811 | { |
3817 | if (count > RESOURCE_ALIGNMENT_PARAM_SIZE - 1) | 3812 | if (count > RESOURCE_ALIGNMENT_PARAM_SIZE - 1) |
3818 | count = RESOURCE_ALIGNMENT_PARAM_SIZE - 1; | 3813 | count = RESOURCE_ALIGNMENT_PARAM_SIZE - 1; |
@@ -3823,7 +3818,7 @@ ssize_t pci_set_resource_alignment_param(const char *buf, size_t count) | |||
3823 | return count; | 3818 | return count; |
3824 | } | 3819 | } |
3825 | 3820 | ||
3826 | ssize_t pci_get_resource_alignment_param(char *buf, size_t size) | 3821 | static ssize_t pci_get_resource_alignment_param(char *buf, size_t size) |
3827 | { | 3822 | { |
3828 | size_t count; | 3823 | size_t count; |
3829 | spin_lock(&resource_alignment_lock); | 3824 | spin_lock(&resource_alignment_lock); |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 7346ee68f47d..68678ed76b0d 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -8,26 +8,25 @@ | |||
8 | 8 | ||
9 | /* Functions internal to the PCI core code */ | 9 | /* Functions internal to the PCI core code */ |
10 | 10 | ||
11 | extern int pci_create_sysfs_dev_files(struct pci_dev *pdev); | 11 | int pci_create_sysfs_dev_files(struct pci_dev *pdev); |
12 | extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev); | 12 | void pci_remove_sysfs_dev_files(struct pci_dev *pdev); |
13 | #if !defined(CONFIG_DMI) && !defined(CONFIG_ACPI) | 13 | #if !defined(CONFIG_DMI) && !defined(CONFIG_ACPI) |
14 | static inline void pci_create_firmware_label_files(struct pci_dev *pdev) | 14 | static inline void pci_create_firmware_label_files(struct pci_dev *pdev) |
15 | { return; } | 15 | { return; } |
16 | static inline void pci_remove_firmware_label_files(struct pci_dev *pdev) | 16 | static inline void pci_remove_firmware_label_files(struct pci_dev *pdev) |
17 | { return; } | 17 | { return; } |
18 | #else | 18 | #else |
19 | extern void pci_create_firmware_label_files(struct pci_dev *pdev); | 19 | void pci_create_firmware_label_files(struct pci_dev *pdev); |
20 | extern void pci_remove_firmware_label_files(struct pci_dev *pdev); | 20 | void pci_remove_firmware_label_files(struct pci_dev *pdev); |
21 | #endif | 21 | #endif |
22 | extern void pci_cleanup_rom(struct pci_dev *dev); | 22 | void pci_cleanup_rom(struct pci_dev *dev); |
23 | #ifdef HAVE_PCI_MMAP | 23 | #ifdef HAVE_PCI_MMAP |
24 | enum pci_mmap_api { | 24 | enum pci_mmap_api { |
25 | PCI_MMAP_SYSFS, /* mmap on /sys/bus/pci/devices/<BDF>/resource<N> */ | 25 | PCI_MMAP_SYSFS, /* mmap on /sys/bus/pci/devices/<BDF>/resource<N> */ |
26 | PCI_MMAP_PROCFS /* mmap on /proc/bus/pci/<BDF> */ | 26 | PCI_MMAP_PROCFS /* mmap on /proc/bus/pci/<BDF> */ |
27 | }; | 27 | }; |
28 | extern int pci_mmap_fits(struct pci_dev *pdev, int resno, | 28 | int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vmai, |
29 | struct vm_area_struct *vmai, | 29 | enum pci_mmap_api mmap_api); |
30 | enum pci_mmap_api mmap_api); | ||
31 | #endif | 30 | #endif |
32 | int pci_probe_reset_function(struct pci_dev *dev); | 31 | int pci_probe_reset_function(struct pci_dev *dev); |
33 | 32 | ||
@@ -60,17 +59,17 @@ struct pci_platform_pm_ops { | |||
60 | int (*run_wake)(struct pci_dev *dev, bool enable); | 59 | int (*run_wake)(struct pci_dev *dev, bool enable); |
61 | }; | 60 | }; |
62 | 61 | ||
63 | extern int pci_set_platform_pm(struct pci_platform_pm_ops *ops); | 62 | int pci_set_platform_pm(struct pci_platform_pm_ops *ops); |
64 | extern void pci_update_current_state(struct pci_dev *dev, pci_power_t state); | 63 | void pci_update_current_state(struct pci_dev *dev, pci_power_t state); |
65 | extern void pci_power_up(struct pci_dev *dev); | 64 | void pci_power_up(struct pci_dev *dev); |
66 | extern void pci_disable_enabled_device(struct pci_dev *dev); | 65 | void pci_disable_enabled_device(struct pci_dev *dev); |
67 | extern int pci_finish_runtime_suspend(struct pci_dev *dev); | 66 | int pci_finish_runtime_suspend(struct pci_dev *dev); |
68 | extern int __pci_pme_wakeup(struct pci_dev *dev, void *ign); | 67 | int __pci_pme_wakeup(struct pci_dev *dev, void *ign); |
69 | extern void pci_wakeup_bus(struct pci_bus *bus); | 68 | void pci_wakeup_bus(struct pci_bus *bus); |
70 | extern void pci_config_pm_runtime_get(struct pci_dev *dev); | 69 | void pci_config_pm_runtime_get(struct pci_dev *dev); |
71 | extern void pci_config_pm_runtime_put(struct pci_dev *dev); | 70 | void pci_config_pm_runtime_put(struct pci_dev *dev); |
72 | extern void pci_pm_init(struct pci_dev *dev); | 71 | void pci_pm_init(struct pci_dev *dev); |
73 | extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); | 72 | void pci_allocate_cap_save_buffers(struct pci_dev *dev); |
74 | void pci_free_cap_save_buffers(struct pci_dev *dev); | 73 | void pci_free_cap_save_buffers(struct pci_dev *dev); |
75 | 74 | ||
76 | static inline void pci_wakeup_event(struct pci_dev *dev) | 75 | static inline void pci_wakeup_event(struct pci_dev *dev) |
@@ -96,7 +95,7 @@ struct pci_vpd { | |||
96 | struct bin_attribute *attr; /* descriptor for sysfs VPD entry */ | 95 | struct bin_attribute *attr; /* descriptor for sysfs VPD entry */ |
97 | }; | 96 | }; |
98 | 97 | ||
99 | extern int pci_vpd_pci22_init(struct pci_dev *dev); | 98 | int pci_vpd_pci22_init(struct pci_dev *dev); |
100 | static inline void pci_vpd_release(struct pci_dev *dev) | 99 | static inline void pci_vpd_release(struct pci_dev *dev) |
101 | { | 100 | { |
102 | if (dev->vpd) | 101 | if (dev->vpd) |
@@ -105,9 +104,9 @@ static inline void pci_vpd_release(struct pci_dev *dev) | |||
105 | 104 | ||
106 | /* PCI /proc functions */ | 105 | /* PCI /proc functions */ |
107 | #ifdef CONFIG_PROC_FS | 106 | #ifdef CONFIG_PROC_FS |
108 | extern int pci_proc_attach_device(struct pci_dev *dev); | 107 | int pci_proc_attach_device(struct pci_dev *dev); |
109 | extern int pci_proc_detach_device(struct pci_dev *dev); | 108 | int pci_proc_detach_device(struct pci_dev *dev); |
110 | extern int pci_proc_detach_bus(struct pci_bus *bus); | 109 | int pci_proc_detach_bus(struct pci_bus *bus); |
111 | #else | 110 | #else |
112 | static inline int pci_proc_attach_device(struct pci_dev *dev) { return 0; } | 111 | static inline int pci_proc_attach_device(struct pci_dev *dev) { return 0; } |
113 | static inline int pci_proc_detach_device(struct pci_dev *dev) { return 0; } | 112 | static inline int pci_proc_detach_device(struct pci_dev *dev) { return 0; } |
@@ -118,8 +117,8 @@ static inline int pci_proc_detach_bus(struct pci_bus *bus) { return 0; } | |||
118 | int pci_hp_add_bridge(struct pci_dev *dev); | 117 | int pci_hp_add_bridge(struct pci_dev *dev); |
119 | 118 | ||
120 | #ifdef HAVE_PCI_LEGACY | 119 | #ifdef HAVE_PCI_LEGACY |
121 | extern void pci_create_legacy_files(struct pci_bus *bus); | 120 | void pci_create_legacy_files(struct pci_bus *bus); |
122 | extern void pci_remove_legacy_files(struct pci_bus *bus); | 121 | void pci_remove_legacy_files(struct pci_bus *bus); |
123 | #else | 122 | #else |
124 | static inline void pci_create_legacy_files(struct pci_bus *bus) { return; } | 123 | static inline void pci_create_legacy_files(struct pci_bus *bus) { return; } |
125 | static inline void pci_remove_legacy_files(struct pci_bus *bus) { return; } | 124 | static inline void pci_remove_legacy_files(struct pci_bus *bus) { return; } |
@@ -134,7 +133,7 @@ extern unsigned int pci_pm_d3_delay; | |||
134 | 133 | ||
135 | #ifdef CONFIG_PCI_MSI | 134 | #ifdef CONFIG_PCI_MSI |
136 | void pci_no_msi(void); | 135 | void pci_no_msi(void); |
137 | extern void pci_msi_init_pci_dev(struct pci_dev *dev); | 136 | void pci_msi_init_pci_dev(struct pci_dev *dev); |
138 | #else | 137 | #else |
139 | static inline void pci_no_msi(void) { } | 138 | static inline void pci_no_msi(void) { } |
140 | static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { } | 139 | static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { } |
@@ -198,12 +197,11 @@ enum pci_bar_type { | |||
198 | 197 | ||
199 | bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *pl, | 198 | bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *pl, |
200 | int crs_timeout); | 199 | int crs_timeout); |
201 | extern int pci_setup_device(struct pci_dev *dev); | 200 | int pci_setup_device(struct pci_dev *dev); |
202 | extern int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | 201 | int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, |
203 | struct resource *res, unsigned int reg); | 202 | struct resource *res, unsigned int reg); |
204 | extern int pci_resource_bar(struct pci_dev *dev, int resno, | 203 | int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type); |
205 | enum pci_bar_type *type); | 204 | void pci_configure_ari(struct pci_dev *dev); |
206 | extern void pci_configure_ari(struct pci_dev *dev); | ||
207 | 205 | ||
208 | /** | 206 | /** |
209 | * pci_ari_enabled - query ARI forwarding status | 207 | * pci_ari_enabled - query ARI forwarding status |
@@ -217,7 +215,7 @@ static inline int pci_ari_enabled(struct pci_bus *bus) | |||
217 | } | 215 | } |
218 | 216 | ||
219 | void pci_reassigndev_resource_alignment(struct pci_dev *dev); | 217 | void pci_reassigndev_resource_alignment(struct pci_dev *dev); |
220 | extern void pci_disable_bridge_window(struct pci_dev *dev); | 218 | void pci_disable_bridge_window(struct pci_dev *dev); |
221 | 219 | ||
222 | /* Single Root I/O Virtualization */ | 220 | /* Single Root I/O Virtualization */ |
223 | struct pci_sriov { | 221 | struct pci_sriov { |
@@ -241,7 +239,7 @@ struct pci_sriov { | |||
241 | }; | 239 | }; |
242 | 240 | ||
243 | #ifdef CONFIG_PCI_ATS | 241 | #ifdef CONFIG_PCI_ATS |
244 | extern void pci_restore_ats_state(struct pci_dev *dev); | 242 | void pci_restore_ats_state(struct pci_dev *dev); |
245 | #else | 243 | #else |
246 | static inline void pci_restore_ats_state(struct pci_dev *dev) | 244 | static inline void pci_restore_ats_state(struct pci_dev *dev) |
247 | { | 245 | { |
@@ -249,14 +247,13 @@ static inline void pci_restore_ats_state(struct pci_dev *dev) | |||
249 | #endif /* CONFIG_PCI_ATS */ | 247 | #endif /* CONFIG_PCI_ATS */ |
250 | 248 | ||
251 | #ifdef CONFIG_PCI_IOV | 249 | #ifdef CONFIG_PCI_IOV |
252 | extern int pci_iov_init(struct pci_dev *dev); | 250 | int pci_iov_init(struct pci_dev *dev); |
253 | extern void pci_iov_release(struct pci_dev *dev); | 251 | void pci_iov_release(struct pci_dev *dev); |
254 | extern int pci_iov_resource_bar(struct pci_dev *dev, int resno, | 252 | int pci_iov_resource_bar(struct pci_dev *dev, int resno, |
255 | enum pci_bar_type *type); | 253 | enum pci_bar_type *type); |
256 | extern resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, | 254 | resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno); |
257 | int resno); | 255 | void pci_restore_iov_state(struct pci_dev *dev); |
258 | extern void pci_restore_iov_state(struct pci_dev *dev); | 256 | int pci_iov_bus_range(struct pci_bus *bus); |
259 | extern int pci_iov_bus_range(struct pci_bus *bus); | ||
260 | 257 | ||
261 | #else | 258 | #else |
262 | static inline int pci_iov_init(struct pci_dev *dev) | 259 | static inline int pci_iov_init(struct pci_dev *dev) |
@@ -282,10 +279,10 @@ static inline int pci_iov_bus_range(struct pci_bus *bus) | |||
282 | 279 | ||
283 | #endif /* CONFIG_PCI_IOV */ | 280 | #endif /* CONFIG_PCI_IOV */ |
284 | 281 | ||
285 | extern unsigned long pci_cardbus_resource_alignment(struct resource *); | 282 | unsigned long pci_cardbus_resource_alignment(struct resource *); |
286 | 283 | ||
287 | static inline resource_size_t pci_resource_alignment(struct pci_dev *dev, | 284 | static inline resource_size_t pci_resource_alignment(struct pci_dev *dev, |
288 | struct resource *res) | 285 | struct resource *res) |
289 | { | 286 | { |
290 | #ifdef CONFIG_PCI_IOV | 287 | #ifdef CONFIG_PCI_IOV |
291 | int resno = res - dev->resource; | 288 | int resno = res - dev->resource; |
@@ -298,7 +295,7 @@ static inline resource_size_t pci_resource_alignment(struct pci_dev *dev, | |||
298 | return resource_alignment(res); | 295 | return resource_alignment(res); |
299 | } | 296 | } |
300 | 297 | ||
301 | extern void pci_enable_acs(struct pci_dev *dev); | 298 | void pci_enable_acs(struct pci_dev *dev); |
302 | 299 | ||
303 | struct pci_dev_reset_methods { | 300 | struct pci_dev_reset_methods { |
304 | u16 vendor; | 301 | u16 vendor; |
@@ -307,7 +304,7 @@ struct pci_dev_reset_methods { | |||
307 | }; | 304 | }; |
308 | 305 | ||
309 | #ifdef CONFIG_PCI_QUIRKS | 306 | #ifdef CONFIG_PCI_QUIRKS |
310 | extern int pci_dev_specific_reset(struct pci_dev *dev, int probe); | 307 | int pci_dev_specific_reset(struct pci_dev *dev, int probe); |
311 | #else | 308 | #else |
312 | static inline int pci_dev_specific_reset(struct pci_dev *dev, int probe) | 309 | static inline int pci_dev_specific_reset(struct pci_dev *dev, int probe) |
313 | { | 310 | { |
diff --git a/drivers/pci/pcie/Kconfig b/drivers/pci/pcie/Kconfig index fde4a32a0295..569f82fc9e22 100644 --- a/drivers/pci/pcie/Kconfig +++ b/drivers/pci/pcie/Kconfig | |||
@@ -82,4 +82,4 @@ endchoice | |||
82 | 82 | ||
83 | config PCIE_PME | 83 | config PCIE_PME |
84 | def_bool y | 84 | def_bool y |
85 | depends on PCIEPORTBUS && PM_RUNTIME && ACPI | 85 | depends on PCIEPORTBUS && PM_RUNTIME |
diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c index 4e24cb8a94ae..587e7e853107 100644 --- a/drivers/pci/pcie/aer/aer_inject.c +++ b/drivers/pci/pcie/aer/aer_inject.c | |||
@@ -212,8 +212,8 @@ out: | |||
212 | return ops->read(bus, devfn, where, size, val); | 212 | return ops->read(bus, devfn, where, size, val); |
213 | } | 213 | } |
214 | 214 | ||
215 | int pci_write_aer(struct pci_bus *bus, unsigned int devfn, int where, int size, | 215 | static int pci_write_aer(struct pci_bus *bus, unsigned int devfn, int where, |
216 | u32 val) | 216 | int size, u32 val) |
217 | { | 217 | { |
218 | u32 *sim; | 218 | u32 *sim; |
219 | struct aer_error *err; | 219 | struct aer_error *err; |
@@ -334,13 +334,13 @@ static int aer_inject(struct aer_error_inj *einj) | |||
334 | return -ENODEV; | 334 | return -ENODEV; |
335 | rpdev = pcie_find_root_port(dev); | 335 | rpdev = pcie_find_root_port(dev); |
336 | if (!rpdev) { | 336 | if (!rpdev) { |
337 | ret = -ENOTTY; | 337 | ret = -ENODEV; |
338 | goto out_put; | 338 | goto out_put; |
339 | } | 339 | } |
340 | 340 | ||
341 | pos_cap_err = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); | 341 | pos_cap_err = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); |
342 | if (!pos_cap_err) { | 342 | if (!pos_cap_err) { |
343 | ret = -ENOTTY; | 343 | ret = -EPERM; |
344 | goto out_put; | 344 | goto out_put; |
345 | } | 345 | } |
346 | pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_SEVER, &sever); | 346 | pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_SEVER, &sever); |
@@ -350,7 +350,7 @@ static int aer_inject(struct aer_error_inj *einj) | |||
350 | 350 | ||
351 | rp_pos_cap_err = pci_find_ext_capability(rpdev, PCI_EXT_CAP_ID_ERR); | 351 | rp_pos_cap_err = pci_find_ext_capability(rpdev, PCI_EXT_CAP_ID_ERR); |
352 | if (!rp_pos_cap_err) { | 352 | if (!rp_pos_cap_err) { |
353 | ret = -ENOTTY; | 353 | ret = -EPERM; |
354 | goto out_put; | 354 | goto out_put; |
355 | } | 355 | } |
356 | 356 | ||
diff --git a/drivers/pci/pcie/aer/aerdrv.h b/drivers/pci/pcie/aer/aerdrv.h index 22f840f4dda1..d12c77cd6991 100644 --- a/drivers/pci/pcie/aer/aerdrv.h +++ b/drivers/pci/pcie/aer/aerdrv.h | |||
@@ -110,15 +110,15 @@ static inline pci_ers_result_t merge_result(enum pci_ers_result orig, | |||
110 | } | 110 | } |
111 | 111 | ||
112 | extern struct bus_type pcie_port_bus_type; | 112 | extern struct bus_type pcie_port_bus_type; |
113 | extern void aer_do_secondary_bus_reset(struct pci_dev *dev); | 113 | void aer_do_secondary_bus_reset(struct pci_dev *dev); |
114 | extern int aer_init(struct pcie_device *dev); | 114 | int aer_init(struct pcie_device *dev); |
115 | extern void aer_isr(struct work_struct *work); | 115 | void aer_isr(struct work_struct *work); |
116 | extern void aer_print_error(struct pci_dev *dev, struct aer_err_info *info); | 116 | void aer_print_error(struct pci_dev *dev, struct aer_err_info *info); |
117 | extern void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info); | 117 | void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info); |
118 | extern irqreturn_t aer_irq(int irq, void *context); | 118 | irqreturn_t aer_irq(int irq, void *context); |
119 | 119 | ||
120 | #ifdef CONFIG_ACPI_APEI | 120 | #ifdef CONFIG_ACPI_APEI |
121 | extern int pcie_aer_get_firmware_first(struct pci_dev *pci_dev); | 121 | int pcie_aer_get_firmware_first(struct pci_dev *pci_dev); |
122 | #else | 122 | #else |
123 | static inline int pcie_aer_get_firmware_first(struct pci_dev *pci_dev) | 123 | static inline int pcie_aer_get_firmware_first(struct pci_dev *pci_dev) |
124 | { | 124 | { |
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index 564d97f94b6c..8ec8b4f48560 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c | |||
@@ -89,8 +89,6 @@ static int add_error_device(struct aer_err_info *e_info, struct pci_dev *dev) | |||
89 | return -ENOSPC; | 89 | return -ENOSPC; |
90 | } | 90 | } |
91 | 91 | ||
92 | #define PCI_BUS(x) (((x) >> 8) & 0xff) | ||
93 | |||
94 | /** | 92 | /** |
95 | * is_error_source - check whether the device is source of reported error | 93 | * is_error_source - check whether the device is source of reported error |
96 | * @dev: pointer to pci_dev to be checked | 94 | * @dev: pointer to pci_dev to be checked |
@@ -106,7 +104,7 @@ static bool is_error_source(struct pci_dev *dev, struct aer_err_info *e_info) | |||
106 | * When bus id is equal to 0, it might be a bad id | 104 | * When bus id is equal to 0, it might be a bad id |
107 | * reported by root port. | 105 | * reported by root port. |
108 | */ | 106 | */ |
109 | if (!nosourceid && (PCI_BUS(e_info->id) != 0)) { | 107 | if (!nosourceid && (PCI_BUS_NUM(e_info->id) != 0)) { |
110 | /* Device ID match? */ | 108 | /* Device ID match? */ |
111 | if (e_info->id == ((dev->bus->number << 8) | dev->devfn)) | 109 | if (e_info->id == ((dev->bus->number << 8) | dev->devfn)) |
112 | return true; | 110 | return true; |
diff --git a/drivers/pci/pcie/pme.c b/drivers/pci/pcie/pme.c index 9ca0dc9ffd84..795db1f9d50c 100644 --- a/drivers/pci/pcie/pme.c +++ b/drivers/pci/pcie/pme.c | |||
@@ -19,8 +19,6 @@ | |||
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/device.h> | 20 | #include <linux/device.h> |
21 | #include <linux/pcieport_if.h> | 21 | #include <linux/pcieport_if.h> |
22 | #include <linux/acpi.h> | ||
23 | #include <linux/pci-acpi.h> | ||
24 | #include <linux/pm_runtime.h> | 22 | #include <linux/pm_runtime.h> |
25 | 23 | ||
26 | #include "../pci.h" | 24 | #include "../pci.h" |
diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h index eea2ca2375e6..d2eb80aab569 100644 --- a/drivers/pci/pcie/portdrv.h +++ b/drivers/pci/pcie/portdrv.h | |||
@@ -21,18 +21,18 @@ | |||
21 | #define get_descriptor_id(type, service) (((type - 4) << 4) | service) | 21 | #define get_descriptor_id(type, service) (((type - 4) << 4) | service) |
22 | 22 | ||
23 | extern struct bus_type pcie_port_bus_type; | 23 | extern struct bus_type pcie_port_bus_type; |
24 | extern int pcie_port_device_register(struct pci_dev *dev); | 24 | int pcie_port_device_register(struct pci_dev *dev); |
25 | #ifdef CONFIG_PM | 25 | #ifdef CONFIG_PM |
26 | extern int pcie_port_device_suspend(struct device *dev); | 26 | int pcie_port_device_suspend(struct device *dev); |
27 | extern int pcie_port_device_resume(struct device *dev); | 27 | int pcie_port_device_resume(struct device *dev); |
28 | #endif | 28 | #endif |
29 | extern void pcie_port_device_remove(struct pci_dev *dev); | 29 | void pcie_port_device_remove(struct pci_dev *dev); |
30 | extern int __must_check pcie_port_bus_register(void); | 30 | int __must_check pcie_port_bus_register(void); |
31 | extern void pcie_port_bus_unregister(void); | 31 | void pcie_port_bus_unregister(void); |
32 | 32 | ||
33 | struct pci_dev; | 33 | struct pci_dev; |
34 | 34 | ||
35 | extern void pcie_clear_root_pme_status(struct pci_dev *dev); | 35 | void pcie_clear_root_pme_status(struct pci_dev *dev); |
36 | 36 | ||
37 | #ifdef CONFIG_HOTPLUG_PCI_PCIE | 37 | #ifdef CONFIG_HOTPLUG_PCI_PCIE |
38 | extern bool pciehp_msi_disabled; | 38 | extern bool pciehp_msi_disabled; |
@@ -59,7 +59,7 @@ static inline bool pcie_pme_no_msi(void) | |||
59 | return pcie_pme_msi_disabled; | 59 | return pcie_pme_msi_disabled; |
60 | } | 60 | } |
61 | 61 | ||
62 | extern void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable); | 62 | void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable); |
63 | #else /* !CONFIG_PCIE_PME */ | 63 | #else /* !CONFIG_PCIE_PME */ |
64 | static inline void pcie_pme_disable_msi(void) {} | 64 | static inline void pcie_pme_disable_msi(void) {} |
65 | static inline bool pcie_pme_no_msi(void) { return false; } | 65 | static inline bool pcie_pme_no_msi(void) { return false; } |
@@ -67,7 +67,7 @@ static inline void pcie_pme_interrupt_enable(struct pci_dev *dev, bool en) {} | |||
67 | #endif /* !CONFIG_PCIE_PME */ | 67 | #endif /* !CONFIG_PCIE_PME */ |
68 | 68 | ||
69 | #ifdef CONFIG_ACPI | 69 | #ifdef CONFIG_ACPI |
70 | extern int pcie_port_acpi_setup(struct pci_dev *port, int *mask); | 70 | int pcie_port_acpi_setup(struct pci_dev *port, int *mask); |
71 | 71 | ||
72 | static inline int pcie_port_platform_notify(struct pci_dev *port, int *mask) | 72 | static inline int pcie_port_platform_notify(struct pci_dev *port, int *mask) |
73 | { | 73 | { |
diff --git a/drivers/pci/pcie/portdrv_acpi.c b/drivers/pci/pcie/portdrv_acpi.c index a86b56e5f2f2..b4d2894ee3fc 100644 --- a/drivers/pci/pcie/portdrv_acpi.c +++ b/drivers/pci/pcie/portdrv_acpi.c | |||
@@ -17,6 +17,7 @@ | |||
17 | 17 | ||
18 | #include "aer/aerdrv.h" | 18 | #include "aer/aerdrv.h" |
19 | #include "../pci.h" | 19 | #include "../pci.h" |
20 | #include "portdrv.h" | ||
20 | 21 | ||
21 | /** | 22 | /** |
22 | * pcie_port_acpi_setup - Request the BIOS to release control of PCIe services. | 23 | * pcie_port_acpi_setup - Request the BIOS to release control of PCIe services. |
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index ed4d09498337..696caed5fdf5 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c | |||
@@ -259,11 +259,9 @@ static pci_ers_result_t pcie_portdrv_error_detected(struct pci_dev *dev, | |||
259 | enum pci_channel_state error) | 259 | enum pci_channel_state error) |
260 | { | 260 | { |
261 | struct aer_broadcast_data data = {error, PCI_ERS_RESULT_CAN_RECOVER}; | 261 | struct aer_broadcast_data data = {error, PCI_ERS_RESULT_CAN_RECOVER}; |
262 | int ret; | ||
263 | |||
264 | /* can not fail */ | ||
265 | ret = device_for_each_child(&dev->dev, &data, error_detected_iter); | ||
266 | 262 | ||
263 | /* get true return value from &data */ | ||
264 | device_for_each_child(&dev->dev, &data, error_detected_iter); | ||
267 | return data.result; | 265 | return data.result; |
268 | } | 266 | } |
269 | 267 | ||
@@ -295,10 +293,9 @@ static int mmio_enabled_iter(struct device *device, void *data) | |||
295 | static pci_ers_result_t pcie_portdrv_mmio_enabled(struct pci_dev *dev) | 293 | static pci_ers_result_t pcie_portdrv_mmio_enabled(struct pci_dev *dev) |
296 | { | 294 | { |
297 | pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED; | 295 | pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED; |
298 | int retval; | ||
299 | 296 | ||
300 | /* get true return value from &status */ | 297 | /* get true return value from &status */ |
301 | retval = device_for_each_child(&dev->dev, &status, mmio_enabled_iter); | 298 | device_for_each_child(&dev->dev, &status, mmio_enabled_iter); |
302 | return status; | 299 | return status; |
303 | } | 300 | } |
304 | 301 | ||
@@ -330,7 +327,6 @@ static int slot_reset_iter(struct device *device, void *data) | |||
330 | static pci_ers_result_t pcie_portdrv_slot_reset(struct pci_dev *dev) | 327 | static pci_ers_result_t pcie_portdrv_slot_reset(struct pci_dev *dev) |
331 | { | 328 | { |
332 | pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED; | 329 | pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED; |
333 | int retval; | ||
334 | 330 | ||
335 | /* If fatal, restore cfg space for possible link reset at upstream */ | 331 | /* If fatal, restore cfg space for possible link reset at upstream */ |
336 | if (dev->error_state == pci_channel_io_frozen) { | 332 | if (dev->error_state == pci_channel_io_frozen) { |
@@ -341,8 +337,7 @@ static pci_ers_result_t pcie_portdrv_slot_reset(struct pci_dev *dev) | |||
341 | } | 337 | } |
342 | 338 | ||
343 | /* get true return value from &status */ | 339 | /* get true return value from &status */ |
344 | retval = device_for_each_child(&dev->dev, &status, slot_reset_iter); | 340 | device_for_each_child(&dev->dev, &status, slot_reset_iter); |
345 | |||
346 | return status; | 341 | return status; |
347 | } | 342 | } |
348 | 343 | ||
@@ -368,9 +363,7 @@ static int resume_iter(struct device *device, void *data) | |||
368 | 363 | ||
369 | static void pcie_portdrv_err_resume(struct pci_dev *dev) | 364 | static void pcie_portdrv_err_resume(struct pci_dev *dev) |
370 | { | 365 | { |
371 | int retval; | 366 | device_for_each_child(&dev->dev, NULL, resume_iter); |
372 | /* nothing to do with error value, if it ever happens */ | ||
373 | retval = device_for_each_child(&dev->dev, NULL, resume_iter); | ||
374 | } | 367 | } |
375 | 368 | ||
376 | /* | 369 | /* |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index b494066ef32f..43ece5d41d36 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -673,6 +673,8 @@ add_dev: | |||
673 | ret = device_register(&child->dev); | 673 | ret = device_register(&child->dev); |
674 | WARN_ON(ret < 0); | 674 | WARN_ON(ret < 0); |
675 | 675 | ||
676 | pcibios_add_bus(child); | ||
677 | |||
676 | /* Create legacy_io and legacy_mem files for this bus */ | 678 | /* Create legacy_io and legacy_mem files for this bus */ |
677 | pci_create_legacy_files(child); | 679 | pci_create_legacy_files(child); |
678 | 680 | ||
@@ -1627,8 +1629,7 @@ unsigned int pci_scan_child_bus(struct pci_bus *bus) | |||
1627 | if (!bus->is_added) { | 1629 | if (!bus->is_added) { |
1628 | dev_dbg(&bus->dev, "fixups for bus\n"); | 1630 | dev_dbg(&bus->dev, "fixups for bus\n"); |
1629 | pcibios_fixup_bus(bus); | 1631 | pcibios_fixup_bus(bus); |
1630 | if (pci_is_root_bus(bus)) | 1632 | bus->is_added = 1; |
1631 | bus->is_added = 1; | ||
1632 | } | 1633 | } |
1633 | 1634 | ||
1634 | for (pass=0; pass < 2; pass++) | 1635 | for (pass=0; pass < 2; pass++) |
@@ -1661,6 +1662,14 @@ int __weak pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) | |||
1661 | return 0; | 1662 | return 0; |
1662 | } | 1663 | } |
1663 | 1664 | ||
1665 | void __weak pcibios_add_bus(struct pci_bus *bus) | ||
1666 | { | ||
1667 | } | ||
1668 | |||
1669 | void __weak pcibios_remove_bus(struct pci_bus *bus) | ||
1670 | { | ||
1671 | } | ||
1672 | |||
1664 | struct pci_bus *pci_create_root_bus(struct device *parent, int bus, | 1673 | struct pci_bus *pci_create_root_bus(struct device *parent, int bus, |
1665 | struct pci_ops *ops, void *sysdata, struct list_head *resources) | 1674 | struct pci_ops *ops, void *sysdata, struct list_head *resources) |
1666 | { | 1675 | { |
@@ -1715,6 +1724,8 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, | |||
1715 | if (error) | 1724 | if (error) |
1716 | goto class_dev_reg_err; | 1725 | goto class_dev_reg_err; |
1717 | 1726 | ||
1727 | pcibios_add_bus(b); | ||
1728 | |||
1718 | /* Create legacy_io and legacy_mem files for this bus */ | 1729 | /* Create legacy_io and legacy_mem files for this bus */ |
1719 | pci_create_legacy_files(b); | 1730 | pci_create_legacy_files(b); |
1720 | 1731 | ||
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 0369fb6fc1da..7d68aeebf56b 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -324,29 +324,30 @@ static void quirk_cs5536_vsa(struct pci_dev *dev) | |||
324 | } | 324 | } |
325 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA, quirk_cs5536_vsa); | 325 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA, quirk_cs5536_vsa); |
326 | 326 | ||
327 | static void quirk_io_region(struct pci_dev *dev, unsigned region, | 327 | static void quirk_io_region(struct pci_dev *dev, int port, |
328 | unsigned size, int nr, const char *name) | 328 | unsigned size, int nr, const char *name) |
329 | { | 329 | { |
330 | region &= ~(size-1); | 330 | u16 region; |
331 | if (region) { | 331 | struct pci_bus_region bus_region; |
332 | struct pci_bus_region bus_region; | 332 | struct resource *res = dev->resource + nr; |
333 | struct resource *res = dev->resource + nr; | ||
334 | 333 | ||
335 | res->name = pci_name(dev); | 334 | pci_read_config_word(dev, port, ®ion); |
336 | res->start = region; | 335 | region &= ~(size - 1); |
337 | res->end = region + size - 1; | ||
338 | res->flags = IORESOURCE_IO; | ||
339 | 336 | ||
340 | /* Convert from PCI bus to resource space. */ | 337 | if (!region) |
341 | bus_region.start = res->start; | 338 | return; |
342 | bus_region.end = res->end; | ||
343 | pcibios_bus_to_resource(dev, res, &bus_region); | ||
344 | 339 | ||
345 | if (pci_claim_resource(dev, nr) == 0) | 340 | res->name = pci_name(dev); |
346 | dev_info(&dev->dev, "quirk: %pR claimed by %s\n", | 341 | res->flags = IORESOURCE_IO; |
347 | res, name); | 342 | |
348 | } | 343 | /* Convert from PCI bus to resource space */ |
349 | } | 344 | bus_region.start = region; |
345 | bus_region.end = region + size - 1; | ||
346 | pcibios_bus_to_resource(dev, res, &bus_region); | ||
347 | |||
348 | if (!pci_claim_resource(dev, nr)) | ||
349 | dev_info(&dev->dev, "quirk: %pR claimed by %s\n", res, name); | ||
350 | } | ||
350 | 351 | ||
351 | /* | 352 | /* |
352 | * ATI Northbridge setups MCE the processor if you even | 353 | * ATI Northbridge setups MCE the processor if you even |
@@ -374,12 +375,8 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS100, quirk_ati_ | |||
374 | */ | 375 | */ |
375 | static void quirk_ali7101_acpi(struct pci_dev *dev) | 376 | static void quirk_ali7101_acpi(struct pci_dev *dev) |
376 | { | 377 | { |
377 | u16 region; | 378 | quirk_io_region(dev, 0xE0, 64, PCI_BRIDGE_RESOURCES, "ali7101 ACPI"); |
378 | 379 | quirk_io_region(dev, 0xE2, 32, PCI_BRIDGE_RESOURCES+1, "ali7101 SMB"); | |
379 | pci_read_config_word(dev, 0xE0, ®ion); | ||
380 | quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES, "ali7101 ACPI"); | ||
381 | pci_read_config_word(dev, 0xE2, ®ion); | ||
382 | quirk_io_region(dev, region, 32, PCI_BRIDGE_RESOURCES+1, "ali7101 SMB"); | ||
383 | } | 380 | } |
384 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, quirk_ali7101_acpi); | 381 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, quirk_ali7101_acpi); |
385 | 382 | ||
@@ -442,12 +439,10 @@ static void piix4_mem_quirk(struct pci_dev *dev, const char *name, unsigned int | |||
442 | */ | 439 | */ |
443 | static void quirk_piix4_acpi(struct pci_dev *dev) | 440 | static void quirk_piix4_acpi(struct pci_dev *dev) |
444 | { | 441 | { |
445 | u32 region, res_a; | 442 | u32 res_a; |
446 | 443 | ||
447 | pci_read_config_dword(dev, 0x40, ®ion); | 444 | quirk_io_region(dev, 0x40, 64, PCI_BRIDGE_RESOURCES, "PIIX4 ACPI"); |
448 | quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES, "PIIX4 ACPI"); | 445 | quirk_io_region(dev, 0x90, 16, PCI_BRIDGE_RESOURCES+1, "PIIX4 SMB"); |
449 | pci_read_config_dword(dev, 0x90, ®ion); | ||
450 | quirk_io_region(dev, region, 16, PCI_BRIDGE_RESOURCES+1, "PIIX4 SMB"); | ||
451 | 446 | ||
452 | /* Device resource A has enables for some of the other ones */ | 447 | /* Device resource A has enables for some of the other ones */ |
453 | pci_read_config_dword(dev, 0x5c, &res_a); | 448 | pci_read_config_dword(dev, 0x5c, &res_a); |
@@ -491,7 +486,6 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_3, qui | |||
491 | */ | 486 | */ |
492 | static void quirk_ich4_lpc_acpi(struct pci_dev *dev) | 487 | static void quirk_ich4_lpc_acpi(struct pci_dev *dev) |
493 | { | 488 | { |
494 | u32 region; | ||
495 | u8 enable; | 489 | u8 enable; |
496 | 490 | ||
497 | /* | 491 | /* |
@@ -503,22 +497,14 @@ static void quirk_ich4_lpc_acpi(struct pci_dev *dev) | |||
503 | */ | 497 | */ |
504 | 498 | ||
505 | pci_read_config_byte(dev, ICH_ACPI_CNTL, &enable); | 499 | pci_read_config_byte(dev, ICH_ACPI_CNTL, &enable); |
506 | if (enable & ICH4_ACPI_EN) { | 500 | if (enable & ICH4_ACPI_EN) |
507 | pci_read_config_dword(dev, ICH_PMBASE, ®ion); | 501 | quirk_io_region(dev, ICH_PMBASE, 128, PCI_BRIDGE_RESOURCES, |
508 | region &= PCI_BASE_ADDRESS_IO_MASK; | 502 | "ICH4 ACPI/GPIO/TCO"); |
509 | if (region >= PCIBIOS_MIN_IO) | ||
510 | quirk_io_region(dev, region, 128, PCI_BRIDGE_RESOURCES, | ||
511 | "ICH4 ACPI/GPIO/TCO"); | ||
512 | } | ||
513 | 503 | ||
514 | pci_read_config_byte(dev, ICH4_GPIO_CNTL, &enable); | 504 | pci_read_config_byte(dev, ICH4_GPIO_CNTL, &enable); |
515 | if (enable & ICH4_GPIO_EN) { | 505 | if (enable & ICH4_GPIO_EN) |
516 | pci_read_config_dword(dev, ICH4_GPIOBASE, ®ion); | 506 | quirk_io_region(dev, ICH4_GPIOBASE, 64, PCI_BRIDGE_RESOURCES+1, |
517 | region &= PCI_BASE_ADDRESS_IO_MASK; | 507 | "ICH4 GPIO"); |
518 | if (region >= PCIBIOS_MIN_IO) | ||
519 | quirk_io_region(dev, region, 64, | ||
520 | PCI_BRIDGE_RESOURCES + 1, "ICH4 GPIO"); | ||
521 | } | ||
522 | } | 508 | } |
523 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0, quirk_ich4_lpc_acpi); | 509 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0, quirk_ich4_lpc_acpi); |
524 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_0, quirk_ich4_lpc_acpi); | 510 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_0, quirk_ich4_lpc_acpi); |
@@ -533,26 +519,17 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_1, qui | |||
533 | 519 | ||
534 | static void ich6_lpc_acpi_gpio(struct pci_dev *dev) | 520 | static void ich6_lpc_acpi_gpio(struct pci_dev *dev) |
535 | { | 521 | { |
536 | u32 region; | ||
537 | u8 enable; | 522 | u8 enable; |
538 | 523 | ||
539 | pci_read_config_byte(dev, ICH_ACPI_CNTL, &enable); | 524 | pci_read_config_byte(dev, ICH_ACPI_CNTL, &enable); |
540 | if (enable & ICH6_ACPI_EN) { | 525 | if (enable & ICH6_ACPI_EN) |
541 | pci_read_config_dword(dev, ICH_PMBASE, ®ion); | 526 | quirk_io_region(dev, ICH_PMBASE, 128, PCI_BRIDGE_RESOURCES, |
542 | region &= PCI_BASE_ADDRESS_IO_MASK; | 527 | "ICH6 ACPI/GPIO/TCO"); |
543 | if (region >= PCIBIOS_MIN_IO) | ||
544 | quirk_io_region(dev, region, 128, PCI_BRIDGE_RESOURCES, | ||
545 | "ICH6 ACPI/GPIO/TCO"); | ||
546 | } | ||
547 | 528 | ||
548 | pci_read_config_byte(dev, ICH6_GPIO_CNTL, &enable); | 529 | pci_read_config_byte(dev, ICH6_GPIO_CNTL, &enable); |
549 | if (enable & ICH6_GPIO_EN) { | 530 | if (enable & ICH6_GPIO_EN) |
550 | pci_read_config_dword(dev, ICH6_GPIOBASE, ®ion); | 531 | quirk_io_region(dev, ICH6_GPIOBASE, 64, PCI_BRIDGE_RESOURCES+1, |
551 | region &= PCI_BASE_ADDRESS_IO_MASK; | 532 | "ICH6 GPIO"); |
552 | if (region >= PCIBIOS_MIN_IO) | ||
553 | quirk_io_region(dev, region, 64, | ||
554 | PCI_BRIDGE_RESOURCES + 1, "ICH6 GPIO"); | ||
555 | } | ||
556 | } | 533 | } |
557 | 534 | ||
558 | static void ich6_lpc_generic_decode(struct pci_dev *dev, unsigned reg, const char *name, int dynsize) | 535 | static void ich6_lpc_generic_decode(struct pci_dev *dev, unsigned reg, const char *name, int dynsize) |
@@ -650,13 +627,9 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_1, qui | |||
650 | */ | 627 | */ |
651 | static void quirk_vt82c586_acpi(struct pci_dev *dev) | 628 | static void quirk_vt82c586_acpi(struct pci_dev *dev) |
652 | { | 629 | { |
653 | u32 region; | 630 | if (dev->revision & 0x10) |
654 | 631 | quirk_io_region(dev, 0x48, 256, PCI_BRIDGE_RESOURCES, | |
655 | if (dev->revision & 0x10) { | 632 | "vt82c586 ACPI"); |
656 | pci_read_config_dword(dev, 0x48, ®ion); | ||
657 | region &= PCI_BASE_ADDRESS_IO_MASK; | ||
658 | quirk_io_region(dev, region, 256, PCI_BRIDGE_RESOURCES, "vt82c586 ACPI"); | ||
659 | } | ||
660 | } | 633 | } |
661 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_vt82c586_acpi); | 634 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_vt82c586_acpi); |
662 | 635 | ||
@@ -668,18 +641,12 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_vt | |||
668 | */ | 641 | */ |
669 | static void quirk_vt82c686_acpi(struct pci_dev *dev) | 642 | static void quirk_vt82c686_acpi(struct pci_dev *dev) |
670 | { | 643 | { |
671 | u16 hm; | ||
672 | u32 smb; | ||
673 | |||
674 | quirk_vt82c586_acpi(dev); | 644 | quirk_vt82c586_acpi(dev); |
675 | 645 | ||
676 | pci_read_config_word(dev, 0x70, &hm); | 646 | quirk_io_region(dev, 0x70, 128, PCI_BRIDGE_RESOURCES+1, |
677 | hm &= PCI_BASE_ADDRESS_IO_MASK; | 647 | "vt82c686 HW-mon"); |
678 | quirk_io_region(dev, hm, 128, PCI_BRIDGE_RESOURCES + 1, "vt82c686 HW-mon"); | ||
679 | 648 | ||
680 | pci_read_config_dword(dev, 0x90, &smb); | 649 | quirk_io_region(dev, 0x90, 16, PCI_BRIDGE_RESOURCES+2, "vt82c686 SMB"); |
681 | smb &= PCI_BASE_ADDRESS_IO_MASK; | ||
682 | quirk_io_region(dev, smb, 16, PCI_BRIDGE_RESOURCES + 2, "vt82c686 SMB"); | ||
683 | } | 650 | } |
684 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_vt82c686_acpi); | 651 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_vt82c686_acpi); |
685 | 652 | ||
@@ -690,15 +657,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_vt | |||
690 | */ | 657 | */ |
691 | static void quirk_vt8235_acpi(struct pci_dev *dev) | 658 | static void quirk_vt8235_acpi(struct pci_dev *dev) |
692 | { | 659 | { |
693 | u16 pm, smb; | 660 | quirk_io_region(dev, 0x88, 128, PCI_BRIDGE_RESOURCES, "vt8235 PM"); |
694 | 661 | quirk_io_region(dev, 0xd0, 16, PCI_BRIDGE_RESOURCES+1, "vt8235 SMB"); | |
695 | pci_read_config_word(dev, 0x88, &pm); | ||
696 | pm &= PCI_BASE_ADDRESS_IO_MASK; | ||
697 | quirk_io_region(dev, pm, 128, PCI_BRIDGE_RESOURCES, "vt8235 PM"); | ||
698 | |||
699 | pci_read_config_word(dev, 0xd0, &smb); | ||
700 | smb &= PCI_BASE_ADDRESS_IO_MASK; | ||
701 | quirk_io_region(dev, smb, 16, PCI_BRIDGE_RESOURCES + 1, "vt8235 SMB"); | ||
702 | } | 662 | } |
703 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, quirk_vt8235_acpi); | 663 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, quirk_vt8235_acpi); |
704 | 664 | ||
@@ -2594,6 +2554,14 @@ static void quirk_msi_intx_disable_ati_bug(struct pci_dev *dev) | |||
2594 | dev->dev_flags |= PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG; | 2554 | dev->dev_flags |= PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG; |
2595 | pci_dev_put(p); | 2555 | pci_dev_put(p); |
2596 | } | 2556 | } |
2557 | static void quirk_msi_intx_disable_qca_bug(struct pci_dev *dev) | ||
2558 | { | ||
2559 | /* AR816X/AR817X/E210X MSI is fixed at HW level from revision 0x18 */ | ||
2560 | if (dev->revision < 0x18) { | ||
2561 | dev_info(&dev->dev, "set MSI_INTX_DISABLE_BUG flag\n"); | ||
2562 | dev->dev_flags |= PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG; | ||
2563 | } | ||
2564 | } | ||
2597 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM, | 2565 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM, |
2598 | PCI_DEVICE_ID_TIGON3_5780, | 2566 | PCI_DEVICE_ID_TIGON3_5780, |
2599 | quirk_msi_intx_disable_bug); | 2567 | quirk_msi_intx_disable_bug); |
@@ -2643,6 +2611,16 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0x1073, | |||
2643 | quirk_msi_intx_disable_bug); | 2611 | quirk_msi_intx_disable_bug); |
2644 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0x1083, | 2612 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0x1083, |
2645 | quirk_msi_intx_disable_bug); | 2613 | quirk_msi_intx_disable_bug); |
2614 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0x1090, | ||
2615 | quirk_msi_intx_disable_qca_bug); | ||
2616 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0x1091, | ||
2617 | quirk_msi_intx_disable_qca_bug); | ||
2618 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0x10a0, | ||
2619 | quirk_msi_intx_disable_qca_bug); | ||
2620 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0x10a1, | ||
2621 | quirk_msi_intx_disable_qca_bug); | ||
2622 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, 0xe091, | ||
2623 | quirk_msi_intx_disable_qca_bug); | ||
2646 | #endif /* CONFIG_PCI_MSI */ | 2624 | #endif /* CONFIG_PCI_MSI */ |
2647 | 2625 | ||
2648 | /* Allow manual resource allocation for PCI hotplug bridges | 2626 | /* Allow manual resource allocation for PCI hotplug bridges |
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index cc875e6ed159..8fc54b7327bc 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c | |||
@@ -50,10 +50,8 @@ void pci_remove_bus(struct pci_bus *bus) | |||
50 | list_del(&bus->node); | 50 | list_del(&bus->node); |
51 | pci_bus_release_busn_res(bus); | 51 | pci_bus_release_busn_res(bus); |
52 | up_write(&pci_bus_sem); | 52 | up_write(&pci_bus_sem); |
53 | if (!bus->is_added) | ||
54 | return; | ||
55 | |||
56 | pci_remove_legacy_files(bus); | 53 | pci_remove_legacy_files(bus); |
54 | pcibios_remove_bus(bus); | ||
57 | device_unregister(&bus->dev); | 55 | device_unregister(&bus->dev); |
58 | } | 56 | } |
59 | EXPORT_SYMBOL(pci_remove_bus); | 57 | EXPORT_SYMBOL(pci_remove_bus); |
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 7e8739e25b9e..16abaaa1f83c 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
@@ -1044,7 +1044,7 @@ handle_done: | |||
1044 | ; | 1044 | ; |
1045 | } | 1045 | } |
1046 | 1046 | ||
1047 | void __ref __pci_bus_size_bridges(struct pci_bus *bus, | 1047 | static void __ref __pci_bus_size_bridges(struct pci_bus *bus, |
1048 | struct list_head *realloc_head) | 1048 | struct list_head *realloc_head) |
1049 | { | 1049 | { |
1050 | struct pci_dev *dev; | 1050 | struct pci_dev *dev; |
@@ -1545,6 +1545,8 @@ again: | |||
1545 | 1545 | ||
1546 | enable_all: | 1546 | enable_all: |
1547 | retval = pci_reenable_device(bridge); | 1547 | retval = pci_reenable_device(bridge); |
1548 | if (retval) | ||
1549 | dev_err(&bridge->dev, "Error reenabling bridge (%d)\n", retval); | ||
1548 | pci_set_master(bridge); | 1550 | pci_set_master(bridge); |
1549 | pci_enable_bridges(parent); | 1551 | pci_enable_bridges(parent); |
1550 | } | 1552 | } |
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 81b88bda7930..07f2eddc09ce 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c | |||
@@ -261,7 +261,6 @@ int pci_assign_resource(struct pci_dev *dev, int resno) | |||
261 | { | 261 | { |
262 | struct resource *res = dev->resource + resno; | 262 | struct resource *res = dev->resource + resno; |
263 | resource_size_t align, size; | 263 | resource_size_t align, size; |
264 | struct pci_bus *bus; | ||
265 | int ret; | 264 | int ret; |
266 | 265 | ||
267 | align = pci_resource_alignment(dev, res); | 266 | align = pci_resource_alignment(dev, res); |
@@ -271,7 +270,6 @@ int pci_assign_resource(struct pci_dev *dev, int resno) | |||
271 | return -EINVAL; | 270 | return -EINVAL; |
272 | } | 271 | } |
273 | 272 | ||
274 | bus = dev->bus; | ||
275 | size = resource_size(res); | 273 | size = resource_size(res); |
276 | ret = _pci_assign_resource(dev, resno, size, align); | 274 | ret = _pci_assign_resource(dev, resno, size, align); |
277 | 275 | ||
diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c index ac6412fb8d6f..c1e9284a677b 100644 --- a/drivers/pci/slot.c +++ b/drivers/pci/slot.c | |||
@@ -377,14 +377,17 @@ void pci_hp_create_module_link(struct pci_slot *pci_slot) | |||
377 | { | 377 | { |
378 | struct hotplug_slot *slot = pci_slot->hotplug; | 378 | struct hotplug_slot *slot = pci_slot->hotplug; |
379 | struct kobject *kobj = NULL; | 379 | struct kobject *kobj = NULL; |
380 | int no_warn; | 380 | int ret; |
381 | 381 | ||
382 | if (!slot || !slot->ops) | 382 | if (!slot || !slot->ops) |
383 | return; | 383 | return; |
384 | kobj = kset_find_obj(module_kset, slot->ops->mod_name); | 384 | kobj = kset_find_obj(module_kset, slot->ops->mod_name); |
385 | if (!kobj) | 385 | if (!kobj) |
386 | return; | 386 | return; |
387 | no_warn = sysfs_create_link(&pci_slot->kobj, kobj, "module"); | 387 | ret = sysfs_create_link(&pci_slot->kobj, kobj, "module"); |
388 | if (ret) | ||
389 | dev_err(&pci_slot->bus->dev, "Error creating sysfs link (%d)\n", | ||
390 | ret); | ||
388 | kobject_put(kobj); | 391 | kobject_put(kobj); |
389 | } | 392 | } |
390 | EXPORT_SYMBOL_GPL(pci_hp_create_module_link); | 393 | EXPORT_SYMBOL_GPL(pci_hp_create_module_link); |