diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-26 00:18:18 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-26 00:18:18 -0500 |
commit | 556f12f602ac0a18a82ca83e9f8e8547688fc633 (patch) | |
tree | d4051f6dd57968c8e8e660ad117c5bedc2aa7e8e /drivers | |
parent | fffddfd6c8e0c10c42c6e2cc54ba880fcc36ebbb (diff) | |
parent | 018ba0a6efada61b9bc17500101d81c3d35807c2 (diff) |
Merge tag 'pci-v3.9-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI changes from Bjorn Helgaas:
"Host bridge hotplug
- Major overhaul of ACPI host bridge add/start (Rafael Wysocki, Yinghai Lu)
- Major overhaul of PCI/ACPI binding (Rafael Wysocki, Yinghai Lu)
- Split out ACPI host bridge and ACPI PCI device hotplug (Yinghai Lu)
- Stop caching _PRT and make independent of bus numbers (Yinghai Lu)
PCI device hotplug
- Clean up cpqphp dead code (Sasha Levin)
- Disable ARI unless device and upstream bridge support it (Yijing Wang)
- Initialize all hot-added devices (not functions 0-7) (Yijing Wang)
Power management
- Don't touch ASPM if disabled (Joe Lawrence)
- Fix ASPM link state management (Myron Stowe)
Miscellaneous
- Fix PCI_EXP_FLAGS accessor (Alex Williamson)
- Disable Bus Master in pci_device_shutdown (Konstantin Khlebnikov)
- Document hotplug resource and MPS parameters (Yijing Wang)
- Add accessor for PCIe capabilities (Myron Stowe)
- Drop pciehp suspend/resume messages (Paul Bolle)
- Make pci_slot built-in only (not a module) (Jiang Liu)
- Remove unused PCI/ACPI bind ops (Jiang Liu)
- Removed used pci_root_bus (Bjorn Helgaas)"
* tag 'pci-v3.9-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (51 commits)
PCI/ACPI: Don't cache _PRT, and don't associate them with bus numbers
PCI: Fix PCI Express Capability accessors for PCI_EXP_FLAGS
ACPI / PCI: Make pci_slot built-in only, not a module
PCI/PM: Clear state_saved during suspend
PCI: Use atomic_inc_return() rather than atomic_add_return()
PCI: Catch attempts to disable already-disabled devices
PCI: Disable Bus Master unconditionally in pci_device_shutdown()
PCI: acpiphp: Remove dead code for PCI host bridge hotplug
PCI: acpiphp: Create companion ACPI devices before creating PCI devices
PCI: Remove unused "rc" in virtfn_add_bus()
PCI: pciehp: Drop suspend/resume ENTRY messages
PCI/ASPM: Don't touch ASPM if forcibly disabled
PCI/ASPM: Deallocate upstream link state even if device is not PCIe
PCI: Document MPS parameters pci=pcie_bus_safe, pci=pcie_bus_perf, etc
PCI: Document hpiosize= and hpmemsize= resource reservation parameters
PCI: Use PCI Express Capability accessor
PCI: Introduce accessor to retrieve PCIe Capabilities Register
PCI: Put pci_dev in device tree as early as possible
PCI: Skip attaching driver in device_add()
PCI: acpiphp: Keep driver loaded even if no slots found
...
Diffstat (limited to 'drivers')
29 files changed, 490 insertions, 706 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 1a4ed64586a7..320006019e68 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -306,7 +306,7 @@ config ACPI_DEBUG_FUNC_TRACE | |||
306 | is about half of the penalty and is rarely useful. | 306 | is about half of the penalty and is rarely useful. |
307 | 307 | ||
308 | config ACPI_PCI_SLOT | 308 | config ACPI_PCI_SLOT |
309 | tristate "PCI slot detection driver" | 309 | bool "PCI slot detection driver" |
310 | depends on SYSFS | 310 | depends on SYSFS |
311 | default n | 311 | default n |
312 | help | 312 | help |
@@ -315,9 +315,6 @@ config ACPI_PCI_SLOT | |||
315 | i.e., segment/bus/device/function tuples, with physical slots in | 315 | i.e., segment/bus/device/function tuples, with physical slots in |
316 | the system. If you are unsure, say N. | 316 | the system. If you are unsure, say N. |
317 | 317 | ||
318 | To compile this driver as a module, choose M here: | ||
319 | the module will be called pci_slot. | ||
320 | |||
321 | config X86_PM_TIMER | 318 | config X86_PM_TIMER |
322 | bool "Power Management Timer Support" if EXPERT | 319 | bool "Power Management Timer Support" if EXPERT |
323 | depends on X86 | 320 | depends on X86 |
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 79092328cf06..c8b70b5b2814 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h | |||
@@ -25,8 +25,14 @@ | |||
25 | 25 | ||
26 | int init_acpi_device_notify(void); | 26 | int init_acpi_device_notify(void); |
27 | int acpi_scan_init(void); | 27 | int acpi_scan_init(void); |
28 | #ifdef CONFIG_ACPI_PCI_SLOT | ||
29 | void acpi_pci_slot_init(void); | ||
30 | #else | ||
31 | static inline void acpi_pci_slot_init(void) { } | ||
32 | #endif | ||
28 | void acpi_pci_root_init(void); | 33 | void acpi_pci_root_init(void); |
29 | void acpi_pci_link_init(void); | 34 | void acpi_pci_link_init(void); |
35 | void acpi_pci_root_hp_init(void); | ||
30 | void acpi_platform_init(void); | 36 | void acpi_platform_init(void); |
31 | int acpi_sysfs_init(void); | 37 | int acpi_sysfs_init(void); |
32 | void acpi_csrt_init(void); | 38 | void acpi_csrt_init(void); |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 8080588f88cb..586e7e993d3d 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -84,8 +84,7 @@ static acpi_osd_handler acpi_irq_handler; | |||
84 | static void *acpi_irq_context; | 84 | static void *acpi_irq_context; |
85 | static struct workqueue_struct *kacpid_wq; | 85 | static struct workqueue_struct *kacpid_wq; |
86 | static struct workqueue_struct *kacpi_notify_wq; | 86 | static struct workqueue_struct *kacpi_notify_wq; |
87 | struct workqueue_struct *kacpi_hotplug_wq; | 87 | static struct workqueue_struct *kacpi_hotplug_wq; |
88 | EXPORT_SYMBOL(kacpi_hotplug_wq); | ||
89 | 88 | ||
90 | /* | 89 | /* |
91 | * This list of permanent mappings is for memory that may be accessed from | 90 | * This list of permanent mappings is for memory that may be accessed from |
@@ -1778,3 +1777,24 @@ void acpi_os_set_prepare_sleep(int (*func)(u8 sleep_state, | |||
1778 | { | 1777 | { |
1779 | __acpi_os_prepare_sleep = func; | 1778 | __acpi_os_prepare_sleep = func; |
1780 | } | 1779 | } |
1780 | |||
1781 | void alloc_acpi_hp_work(acpi_handle handle, u32 type, void *context, | ||
1782 | void (*func)(struct work_struct *work)) | ||
1783 | { | ||
1784 | struct acpi_hp_work *hp_work; | ||
1785 | int ret; | ||
1786 | |||
1787 | hp_work = kmalloc(sizeof(*hp_work), GFP_KERNEL); | ||
1788 | if (!hp_work) | ||
1789 | return; | ||
1790 | |||
1791 | hp_work->handle = handle; | ||
1792 | hp_work->type = type; | ||
1793 | hp_work->context = context; | ||
1794 | |||
1795 | INIT_WORK(&hp_work->work, func); | ||
1796 | ret = queue_work(kacpi_hotplug_wq, &hp_work->work); | ||
1797 | if (!ret) | ||
1798 | kfree(hp_work); | ||
1799 | } | ||
1800 | EXPORT_SYMBOL_GPL(alloc_acpi_hp_work); | ||
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index 68a921d03247..41c5e1b799ef 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c | |||
@@ -53,9 +53,6 @@ struct acpi_prt_entry { | |||
53 | u32 index; /* GSI, or link _CRS index */ | 53 | u32 index; /* GSI, or link _CRS index */ |
54 | }; | 54 | }; |
55 | 55 | ||
56 | static LIST_HEAD(acpi_prt_list); | ||
57 | static DEFINE_SPINLOCK(acpi_prt_lock); | ||
58 | |||
59 | static inline char pin_name(int pin) | 56 | static inline char pin_name(int pin) |
60 | { | 57 | { |
61 | return 'A' + pin - 1; | 58 | return 'A' + pin - 1; |
@@ -65,28 +62,6 @@ static inline char pin_name(int pin) | |||
65 | PCI IRQ Routing Table (PRT) Support | 62 | PCI IRQ Routing Table (PRT) Support |
66 | -------------------------------------------------------------------------- */ | 63 | -------------------------------------------------------------------------- */ |
67 | 64 | ||
68 | static struct acpi_prt_entry *acpi_pci_irq_find_prt_entry(struct pci_dev *dev, | ||
69 | int pin) | ||
70 | { | ||
71 | struct acpi_prt_entry *entry; | ||
72 | int segment = pci_domain_nr(dev->bus); | ||
73 | int bus = dev->bus->number; | ||
74 | int device = PCI_SLOT(dev->devfn); | ||
75 | |||
76 | spin_lock(&acpi_prt_lock); | ||
77 | list_for_each_entry(entry, &acpi_prt_list, list) { | ||
78 | if ((segment == entry->id.segment) | ||
79 | && (bus == entry->id.bus) | ||
80 | && (device == entry->id.device) | ||
81 | && (pin == entry->pin)) { | ||
82 | spin_unlock(&acpi_prt_lock); | ||
83 | return entry; | ||
84 | } | ||
85 | } | ||
86 | spin_unlock(&acpi_prt_lock); | ||
87 | return NULL; | ||
88 | } | ||
89 | |||
90 | /* http://bugzilla.kernel.org/show_bug.cgi?id=4773 */ | 65 | /* http://bugzilla.kernel.org/show_bug.cgi?id=4773 */ |
91 | static const struct dmi_system_id medion_md9580[] = { | 66 | static const struct dmi_system_id medion_md9580[] = { |
92 | { | 67 | { |
@@ -184,11 +159,19 @@ static void do_prt_fixups(struct acpi_prt_entry *entry, | |||
184 | } | 159 | } |
185 | } | 160 | } |
186 | 161 | ||
187 | static int acpi_pci_irq_add_entry(acpi_handle handle, int segment, int bus, | 162 | static int acpi_pci_irq_check_entry(acpi_handle handle, struct pci_dev *dev, |
188 | struct acpi_pci_routing_table *prt) | 163 | int pin, struct acpi_pci_routing_table *prt, |
164 | struct acpi_prt_entry **entry_ptr) | ||
189 | { | 165 | { |
166 | int segment = pci_domain_nr(dev->bus); | ||
167 | int bus = dev->bus->number; | ||
168 | int device = PCI_SLOT(dev->devfn); | ||
190 | struct acpi_prt_entry *entry; | 169 | struct acpi_prt_entry *entry; |
191 | 170 | ||
171 | if (((prt->address >> 16) & 0xffff) != device || | ||
172 | prt->pin + 1 != pin) | ||
173 | return -ENODEV; | ||
174 | |||
192 | entry = kzalloc(sizeof(struct acpi_prt_entry), GFP_KERNEL); | 175 | entry = kzalloc(sizeof(struct acpi_prt_entry), GFP_KERNEL); |
193 | if (!entry) | 176 | if (!entry) |
194 | return -ENOMEM; | 177 | return -ENOMEM; |
@@ -237,43 +220,37 @@ static int acpi_pci_irq_add_entry(acpi_handle handle, int segment, int bus, | |||
237 | entry->id.device, pin_name(entry->pin), | 220 | entry->id.device, pin_name(entry->pin), |
238 | prt->source, entry->index)); | 221 | prt->source, entry->index)); |
239 | 222 | ||
240 | spin_lock(&acpi_prt_lock); | 223 | *entry_ptr = entry; |
241 | list_add_tail(&entry->list, &acpi_prt_list); | ||
242 | spin_unlock(&acpi_prt_lock); | ||
243 | 224 | ||
244 | return 0; | 225 | return 0; |
245 | } | 226 | } |
246 | 227 | ||
247 | int acpi_pci_irq_add_prt(acpi_handle handle, int segment, int bus) | 228 | static int acpi_pci_irq_find_prt_entry(struct pci_dev *dev, |
229 | int pin, struct acpi_prt_entry **entry_ptr) | ||
248 | { | 230 | { |
249 | acpi_status status; | 231 | acpi_status status; |
250 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 232 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
251 | struct acpi_pci_routing_table *entry; | 233 | struct acpi_pci_routing_table *entry; |
234 | acpi_handle handle = NULL; | ||
252 | 235 | ||
253 | /* 'handle' is the _PRT's parent (root bridge or PCI-PCI bridge) */ | 236 | if (dev->bus->bridge) |
254 | status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); | 237 | handle = ACPI_HANDLE(dev->bus->bridge); |
255 | if (ACPI_FAILURE(status)) | ||
256 | return -ENODEV; | ||
257 | |||
258 | printk(KERN_DEBUG "ACPI: PCI Interrupt Routing Table [%s._PRT]\n", | ||
259 | (char *) buffer.pointer); | ||
260 | |||
261 | kfree(buffer.pointer); | ||
262 | 238 | ||
263 | buffer.length = ACPI_ALLOCATE_BUFFER; | 239 | if (!handle) |
264 | buffer.pointer = NULL; | 240 | return -ENODEV; |
265 | 241 | ||
242 | /* 'handle' is the _PRT's parent (root bridge or PCI-PCI bridge) */ | ||
266 | status = acpi_get_irq_routing_table(handle, &buffer); | 243 | status = acpi_get_irq_routing_table(handle, &buffer); |
267 | if (ACPI_FAILURE(status)) { | 244 | if (ACPI_FAILURE(status)) { |
268 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PRT [%s]", | ||
269 | acpi_format_exception(status))); | ||
270 | kfree(buffer.pointer); | 245 | kfree(buffer.pointer); |
271 | return -ENODEV; | 246 | return -ENODEV; |
272 | } | 247 | } |
273 | 248 | ||
274 | entry = buffer.pointer; | 249 | entry = buffer.pointer; |
275 | while (entry && (entry->length > 0)) { | 250 | while (entry && (entry->length > 0)) { |
276 | acpi_pci_irq_add_entry(handle, segment, bus, entry); | 251 | if (!acpi_pci_irq_check_entry(handle, dev, pin, |
252 | entry, entry_ptr)) | ||
253 | break; | ||
277 | entry = (struct acpi_pci_routing_table *) | 254 | entry = (struct acpi_pci_routing_table *) |
278 | ((unsigned long)entry + entry->length); | 255 | ((unsigned long)entry + entry->length); |
279 | } | 256 | } |
@@ -282,23 +259,6 @@ int acpi_pci_irq_add_prt(acpi_handle handle, int segment, int bus) | |||
282 | return 0; | 259 | return 0; |
283 | } | 260 | } |
284 | 261 | ||
285 | void acpi_pci_irq_del_prt(int segment, int bus) | ||
286 | { | ||
287 | struct acpi_prt_entry *entry, *tmp; | ||
288 | |||
289 | printk(KERN_DEBUG | ||
290 | "ACPI: Delete PCI Interrupt Routing Table for %04x:%02x\n", | ||
291 | segment, bus); | ||
292 | spin_lock(&acpi_prt_lock); | ||
293 | list_for_each_entry_safe(entry, tmp, &acpi_prt_list, list) { | ||
294 | if (segment == entry->id.segment && bus == entry->id.bus) { | ||
295 | list_del(&entry->list); | ||
296 | kfree(entry); | ||
297 | } | ||
298 | } | ||
299 | spin_unlock(&acpi_prt_lock); | ||
300 | } | ||
301 | |||
302 | /* -------------------------------------------------------------------------- | 262 | /* -------------------------------------------------------------------------- |
303 | PCI Interrupt Routing Support | 263 | PCI Interrupt Routing Support |
304 | -------------------------------------------------------------------------- */ | 264 | -------------------------------------------------------------------------- */ |
@@ -359,12 +319,13 @@ static int acpi_reroute_boot_interrupt(struct pci_dev *dev, | |||
359 | 319 | ||
360 | static struct acpi_prt_entry *acpi_pci_irq_lookup(struct pci_dev *dev, int pin) | 320 | static struct acpi_prt_entry *acpi_pci_irq_lookup(struct pci_dev *dev, int pin) |
361 | { | 321 | { |
362 | struct acpi_prt_entry *entry; | 322 | struct acpi_prt_entry *entry = NULL; |
363 | struct pci_dev *bridge; | 323 | struct pci_dev *bridge; |
364 | u8 bridge_pin, orig_pin = pin; | 324 | u8 bridge_pin, orig_pin = pin; |
325 | int ret; | ||
365 | 326 | ||
366 | entry = acpi_pci_irq_find_prt_entry(dev, pin); | 327 | ret = acpi_pci_irq_find_prt_entry(dev, pin, &entry); |
367 | if (entry) { | 328 | if (!ret && entry) { |
368 | #ifdef CONFIG_X86_IO_APIC | 329 | #ifdef CONFIG_X86_IO_APIC |
369 | acpi_reroute_boot_interrupt(dev, entry); | 330 | acpi_reroute_boot_interrupt(dev, entry); |
370 | #endif /* CONFIG_X86_IO_APIC */ | 331 | #endif /* CONFIG_X86_IO_APIC */ |
@@ -373,7 +334,7 @@ static struct acpi_prt_entry *acpi_pci_irq_lookup(struct pci_dev *dev, int pin) | |||
373 | return entry; | 334 | return entry; |
374 | } | 335 | } |
375 | 336 | ||
376 | /* | 337 | /* |
377 | * Attempt to derive an IRQ for this device from a parent bridge's | 338 | * Attempt to derive an IRQ for this device from a parent bridge's |
378 | * PCI interrupt routing entry (eg. yenta bridge and add-in card bridge). | 339 | * PCI interrupt routing entry (eg. yenta bridge and add-in card bridge). |
379 | */ | 340 | */ |
@@ -393,8 +354,8 @@ static struct acpi_prt_entry *acpi_pci_irq_lookup(struct pci_dev *dev, int pin) | |||
393 | pin = bridge_pin; | 354 | pin = bridge_pin; |
394 | } | 355 | } |
395 | 356 | ||
396 | entry = acpi_pci_irq_find_prt_entry(bridge, pin); | 357 | ret = acpi_pci_irq_find_prt_entry(bridge, pin, &entry); |
397 | if (entry) { | 358 | if (!ret && entry) { |
398 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 359 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
399 | "Derived GSI for %s INT %c from %s\n", | 360 | "Derived GSI for %s INT %c from %s\n", |
400 | pci_name(dev), pin_name(orig_pin), | 361 | pci_name(dev), pin_name(orig_pin), |
@@ -470,6 +431,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev) | |||
470 | dev_warn(&dev->dev, "PCI INT %c: no GSI\n", | 431 | dev_warn(&dev->dev, "PCI INT %c: no GSI\n", |
471 | pin_name(pin)); | 432 | pin_name(pin)); |
472 | } | 433 | } |
434 | |||
473 | return 0; | 435 | return 0; |
474 | } | 436 | } |
475 | 437 | ||
@@ -477,6 +439,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev) | |||
477 | if (rc < 0) { | 439 | if (rc < 0) { |
478 | dev_warn(&dev->dev, "PCI INT %c: failed to register GSI\n", | 440 | dev_warn(&dev->dev, "PCI INT %c: failed to register GSI\n", |
479 | pin_name(pin)); | 441 | pin_name(pin)); |
442 | kfree(entry); | ||
480 | return rc; | 443 | return rc; |
481 | } | 444 | } |
482 | dev->irq = rc; | 445 | dev->irq = rc; |
@@ -491,6 +454,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev) | |||
491 | (triggering == ACPI_LEVEL_SENSITIVE) ? "level" : "edge", | 454 | (triggering == ACPI_LEVEL_SENSITIVE) ? "level" : "edge", |
492 | (polarity == ACPI_ACTIVE_LOW) ? "low" : "high", dev->irq); | 455 | (polarity == ACPI_ACTIVE_LOW) ? "low" : "high", dev->irq); |
493 | 456 | ||
457 | kfree(entry); | ||
494 | return 0; | 458 | return 0; |
495 | } | 459 | } |
496 | 460 | ||
@@ -513,6 +477,8 @@ void acpi_pci_irq_disable(struct pci_dev *dev) | |||
513 | else | 477 | else |
514 | gsi = entry->index; | 478 | gsi = entry->index; |
515 | 479 | ||
480 | kfree(entry); | ||
481 | |||
516 | /* | 482 | /* |
517 | * TBD: It might be worth clearing dev->irq by magic constant | 483 | * TBD: It might be worth clearing dev->irq by magic constant |
518 | * (e.g. PCI_UNDEFINED_IRQ). | 484 | * (e.g. PCI_UNDEFINED_IRQ). |
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index b3cc69c5caf1..0ac546d5e53f 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
@@ -103,24 +103,6 @@ void acpi_pci_unregister_driver(struct acpi_pci_driver *driver) | |||
103 | } | 103 | } |
104 | EXPORT_SYMBOL(acpi_pci_unregister_driver); | 104 | EXPORT_SYMBOL(acpi_pci_unregister_driver); |
105 | 105 | ||
106 | acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus) | ||
107 | { | ||
108 | struct acpi_pci_root *root; | ||
109 | acpi_handle handle = NULL; | ||
110 | |||
111 | mutex_lock(&acpi_pci_root_lock); | ||
112 | list_for_each_entry(root, &acpi_pci_roots, node) | ||
113 | if ((root->segment == (u16) seg) && | ||
114 | (root->secondary.start == (u16) bus)) { | ||
115 | handle = root->device->handle; | ||
116 | break; | ||
117 | } | ||
118 | mutex_unlock(&acpi_pci_root_lock); | ||
119 | return handle; | ||
120 | } | ||
121 | |||
122 | EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle); | ||
123 | |||
124 | /** | 106 | /** |
125 | * acpi_is_root_bridge - determine whether an ACPI CA node is a PCI root bridge | 107 | * acpi_is_root_bridge - determine whether an ACPI CA node is a PCI root bridge |
126 | * @handle - the ACPI CA node in question. | 108 | * @handle - the ACPI CA node in question. |
@@ -431,7 +413,6 @@ static int acpi_pci_root_add(struct acpi_device *device, | |||
431 | acpi_status status; | 413 | acpi_status status; |
432 | int result; | 414 | int result; |
433 | struct acpi_pci_root *root; | 415 | struct acpi_pci_root *root; |
434 | acpi_handle handle; | ||
435 | struct acpi_pci_driver *driver; | 416 | struct acpi_pci_driver *driver; |
436 | u32 flags, base_flags; | 417 | u32 flags, base_flags; |
437 | bool is_osc_granted = false; | 418 | bool is_osc_granted = false; |
@@ -486,16 +467,6 @@ static int acpi_pci_root_add(struct acpi_device *device, | |||
486 | acpi_device_name(device), acpi_device_bid(device), | 467 | acpi_device_name(device), acpi_device_bid(device), |
487 | root->segment, &root->secondary); | 468 | root->segment, &root->secondary); |
488 | 469 | ||
489 | /* | ||
490 | * PCI Routing Table | ||
491 | * ----------------- | ||
492 | * Evaluate and parse _PRT, if exists. | ||
493 | */ | ||
494 | status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle); | ||
495 | if (ACPI_SUCCESS(status)) | ||
496 | result = acpi_pci_irq_add_prt(device->handle, root->segment, | ||
497 | root->secondary.start); | ||
498 | |||
499 | root->mcfg_addr = acpi_pci_root_get_mcfg_addr(device->handle); | 470 | root->mcfg_addr = acpi_pci_root_get_mcfg_addr(device->handle); |
500 | 471 | ||
501 | /* | 472 | /* |
@@ -597,8 +568,10 @@ static int acpi_pci_root_add(struct acpi_device *device, | |||
597 | if (device->wakeup.flags.run_wake) | 568 | if (device->wakeup.flags.run_wake) |
598 | device_set_run_wake(root->bus->bridge, true); | 569 | device_set_run_wake(root->bus->bridge, true); |
599 | 570 | ||
600 | if (system_state != SYSTEM_BOOTING) | 571 | if (system_state != SYSTEM_BOOTING) { |
572 | pcibios_resource_survey_bus(root->bus); | ||
601 | pci_assign_unassigned_bus_resources(root->bus); | 573 | pci_assign_unassigned_bus_resources(root->bus); |
574 | } | ||
602 | 575 | ||
603 | mutex_lock(&acpi_pci_root_lock); | 576 | mutex_lock(&acpi_pci_root_lock); |
604 | list_for_each_entry(driver, &acpi_pci_drivers, node) | 577 | list_for_each_entry(driver, &acpi_pci_drivers, node) |
@@ -618,7 +591,6 @@ out_del_root: | |||
618 | list_del(&root->node); | 591 | list_del(&root->node); |
619 | mutex_unlock(&acpi_pci_root_lock); | 592 | mutex_unlock(&acpi_pci_root_lock); |
620 | 593 | ||
621 | acpi_pci_irq_del_prt(root->segment, root->secondary.start); | ||
622 | end: | 594 | end: |
623 | kfree(root); | 595 | kfree(root); |
624 | return result; | 596 | return result; |
@@ -626,8 +598,6 @@ end: | |||
626 | 598 | ||
627 | static void acpi_pci_root_remove(struct acpi_device *device) | 599 | static void acpi_pci_root_remove(struct acpi_device *device) |
628 | { | 600 | { |
629 | acpi_status status; | ||
630 | acpi_handle handle; | ||
631 | struct acpi_pci_root *root = acpi_driver_data(device); | 601 | struct acpi_pci_root *root = acpi_driver_data(device); |
632 | struct acpi_pci_driver *driver; | 602 | struct acpi_pci_driver *driver; |
633 | 603 | ||
@@ -642,10 +612,6 @@ static void acpi_pci_root_remove(struct acpi_device *device) | |||
642 | device_set_run_wake(root->bus->bridge, false); | 612 | device_set_run_wake(root->bus->bridge, false); |
643 | pci_acpi_remove_bus_pm_notifier(device); | 613 | pci_acpi_remove_bus_pm_notifier(device); |
644 | 614 | ||
645 | status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle); | ||
646 | if (ACPI_SUCCESS(status)) | ||
647 | acpi_pci_irq_del_prt(root->segment, root->secondary.start); | ||
648 | |||
649 | pci_remove_root_bus(root->bus); | 615 | pci_remove_root_bus(root->bus); |
650 | 616 | ||
651 | mutex_lock(&acpi_pci_root_lock); | 617 | mutex_lock(&acpi_pci_root_lock); |
@@ -663,3 +629,133 @@ void __init acpi_pci_root_init(void) | |||
663 | acpi_scan_add_handler(&pci_root_handler); | 629 | acpi_scan_add_handler(&pci_root_handler); |
664 | } | 630 | } |
665 | } | 631 | } |
632 | /* Support root bridge hotplug */ | ||
633 | |||
634 | static void handle_root_bridge_insertion(acpi_handle handle) | ||
635 | { | ||
636 | struct acpi_device *device; | ||
637 | |||
638 | if (!acpi_bus_get_device(handle, &device)) { | ||
639 | printk(KERN_DEBUG "acpi device exists...\n"); | ||
640 | return; | ||
641 | } | ||
642 | |||
643 | if (acpi_bus_scan(handle)) | ||
644 | printk(KERN_ERR "cannot add bridge to acpi list\n"); | ||
645 | } | ||
646 | |||
647 | static void handle_root_bridge_removal(struct acpi_device *device) | ||
648 | { | ||
649 | struct acpi_eject_event *ej_event; | ||
650 | |||
651 | ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL); | ||
652 | if (!ej_event) { | ||
653 | /* Inform firmware the hot-remove operation has error */ | ||
654 | (void) acpi_evaluate_hotplug_ost(device->handle, | ||
655 | ACPI_NOTIFY_EJECT_REQUEST, | ||
656 | ACPI_OST_SC_NON_SPECIFIC_FAILURE, | ||
657 | NULL); | ||
658 | return; | ||
659 | } | ||
660 | |||
661 | ej_event->device = device; | ||
662 | ej_event->event = ACPI_NOTIFY_EJECT_REQUEST; | ||
663 | |||
664 | acpi_bus_hot_remove_device(ej_event); | ||
665 | } | ||
666 | |||
667 | static void _handle_hotplug_event_root(struct work_struct *work) | ||
668 | { | ||
669 | struct acpi_pci_root *root; | ||
670 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER }; | ||
671 | struct acpi_hp_work *hp_work; | ||
672 | acpi_handle handle; | ||
673 | u32 type; | ||
674 | |||
675 | hp_work = container_of(work, struct acpi_hp_work, work); | ||
676 | handle = hp_work->handle; | ||
677 | type = hp_work->type; | ||
678 | |||
679 | root = acpi_pci_find_root(handle); | ||
680 | |||
681 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); | ||
682 | |||
683 | switch (type) { | ||
684 | case ACPI_NOTIFY_BUS_CHECK: | ||
685 | /* bus enumerate */ | ||
686 | printk(KERN_DEBUG "%s: Bus check notify on %s\n", __func__, | ||
687 | (char *)buffer.pointer); | ||
688 | if (!root) | ||
689 | handle_root_bridge_insertion(handle); | ||
690 | |||
691 | break; | ||
692 | |||
693 | case ACPI_NOTIFY_DEVICE_CHECK: | ||
694 | /* device check */ | ||
695 | printk(KERN_DEBUG "%s: Device check notify on %s\n", __func__, | ||
696 | (char *)buffer.pointer); | ||
697 | if (!root) | ||
698 | handle_root_bridge_insertion(handle); | ||
699 | break; | ||
700 | |||
701 | case ACPI_NOTIFY_EJECT_REQUEST: | ||
702 | /* request device eject */ | ||
703 | printk(KERN_DEBUG "%s: Device eject notify on %s\n", __func__, | ||
704 | (char *)buffer.pointer); | ||
705 | if (root) | ||
706 | handle_root_bridge_removal(root->device); | ||
707 | break; | ||
708 | default: | ||
709 | printk(KERN_WARNING "notify_handler: unknown event type 0x%x for %s\n", | ||
710 | type, (char *)buffer.pointer); | ||
711 | break; | ||
712 | } | ||
713 | |||
714 | kfree(hp_work); /* allocated in handle_hotplug_event_bridge */ | ||
715 | kfree(buffer.pointer); | ||
716 | } | ||
717 | |||
718 | static void handle_hotplug_event_root(acpi_handle handle, u32 type, | ||
719 | void *context) | ||
720 | { | ||
721 | alloc_acpi_hp_work(handle, type, context, | ||
722 | _handle_hotplug_event_root); | ||
723 | } | ||
724 | |||
725 | static acpi_status __init | ||
726 | find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
727 | { | ||
728 | acpi_status status; | ||
729 | char objname[64]; | ||
730 | struct acpi_buffer buffer = { .length = sizeof(objname), | ||
731 | .pointer = objname }; | ||
732 | int *count = (int *)context; | ||
733 | |||
734 | if (!acpi_is_root_bridge(handle)) | ||
735 | return AE_OK; | ||
736 | |||
737 | (*count)++; | ||
738 | |||
739 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); | ||
740 | |||
741 | status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, | ||
742 | handle_hotplug_event_root, NULL); | ||
743 | if (ACPI_FAILURE(status)) | ||
744 | printk(KERN_DEBUG "acpi root: %s notify handler is not installed, exit status: %u\n", | ||
745 | objname, (unsigned int)status); | ||
746 | else | ||
747 | printk(KERN_DEBUG "acpi root: %s notify handler is installed\n", | ||
748 | objname); | ||
749 | |||
750 | return AE_OK; | ||
751 | } | ||
752 | |||
753 | void __init acpi_pci_root_hp_init(void) | ||
754 | { | ||
755 | int num = 0; | ||
756 | |||
757 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | ||
758 | ACPI_UINT32_MAX, find_root_bridges, NULL, &num, NULL); | ||
759 | |||
760 | printk(KERN_DEBUG "Found %d acpi root devices\n", num); | ||
761 | } | ||
diff --git a/drivers/acpi/pci_slot.c b/drivers/acpi/pci_slot.c index 2c630c006c2f..cd1434eb1de8 100644 --- a/drivers/acpi/pci_slot.c +++ b/drivers/acpi/pci_slot.c | |||
@@ -329,19 +329,8 @@ static struct dmi_system_id acpi_pci_slot_dmi_table[] __initdata = { | |||
329 | {} | 329 | {} |
330 | }; | 330 | }; |
331 | 331 | ||
332 | static int __init | 332 | void __init acpi_pci_slot_init(void) |
333 | acpi_pci_slot_init(void) | ||
334 | { | 333 | { |
335 | dmi_check_system(acpi_pci_slot_dmi_table); | 334 | dmi_check_system(acpi_pci_slot_dmi_table); |
336 | acpi_pci_register_driver(&acpi_pci_slot_driver); | 335 | acpi_pci_register_driver(&acpi_pci_slot_driver); |
337 | return 0; | ||
338 | } | 336 | } |
339 | |||
340 | static void __exit | ||
341 | acpi_pci_slot_exit(void) | ||
342 | { | ||
343 | acpi_pci_unregister_driver(&acpi_pci_slot_driver); | ||
344 | } | ||
345 | |||
346 | module_init(acpi_pci_slot_init); | ||
347 | module_exit(acpi_pci_slot_exit); | ||
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index daee7497efd3..4be408756adc 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -1783,6 +1783,7 @@ int __init acpi_scan_init(void) | |||
1783 | acpi_platform_init(); | 1783 | acpi_platform_init(); |
1784 | acpi_csrt_init(); | 1784 | acpi_csrt_init(); |
1785 | acpi_container_init(); | 1785 | acpi_container_init(); |
1786 | acpi_pci_slot_init(); | ||
1786 | 1787 | ||
1787 | mutex_lock(&acpi_scan_lock); | 1788 | mutex_lock(&acpi_scan_lock); |
1788 | /* | 1789 | /* |
@@ -1804,6 +1805,8 @@ int __init acpi_scan_init(void) | |||
1804 | 1805 | ||
1805 | acpi_update_all_gpes(); | 1806 | acpi_update_all_gpes(); |
1806 | 1807 | ||
1808 | acpi_pci_root_hp_init(); | ||
1809 | |||
1807 | out: | 1810 | out: |
1808 | mutex_unlock(&acpi_scan_lock); | 1811 | mutex_unlock(&acpi_scan_lock); |
1809 | return result; | 1812 | return result; |
diff --git a/drivers/pci/access.c b/drivers/pci/access.c index 3af0478c057b..1cc23661f79b 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c | |||
@@ -472,7 +472,7 @@ EXPORT_SYMBOL_GPL(pci_cfg_access_unlock); | |||
472 | 472 | ||
473 | static inline int pcie_cap_version(const struct pci_dev *dev) | 473 | static inline int pcie_cap_version(const struct pci_dev *dev) |
474 | { | 474 | { |
475 | return dev->pcie_flags_reg & PCI_EXP_FLAGS_VERS; | 475 | return pcie_caps_reg(dev) & PCI_EXP_FLAGS_VERS; |
476 | } | 476 | } |
477 | 477 | ||
478 | static inline bool pcie_cap_has_devctl(const struct pci_dev *dev) | 478 | static inline bool pcie_cap_has_devctl(const struct pci_dev *dev) |
@@ -497,7 +497,7 @@ static inline bool pcie_cap_has_sltctl(const struct pci_dev *dev) | |||
497 | return pcie_cap_version(dev) > 1 || | 497 | return pcie_cap_version(dev) > 1 || |
498 | type == PCI_EXP_TYPE_ROOT_PORT || | 498 | type == PCI_EXP_TYPE_ROOT_PORT || |
499 | (type == PCI_EXP_TYPE_DOWNSTREAM && | 499 | (type == PCI_EXP_TYPE_DOWNSTREAM && |
500 | dev->pcie_flags_reg & PCI_EXP_FLAGS_SLOT); | 500 | pcie_caps_reg(dev) & PCI_EXP_FLAGS_SLOT); |
501 | } | 501 | } |
502 | 502 | ||
503 | static inline bool pcie_cap_has_rtctl(const struct pci_dev *dev) | 503 | static inline bool pcie_cap_has_rtctl(const struct pci_dev *dev) |
@@ -515,7 +515,7 @@ static bool pcie_capability_reg_implemented(struct pci_dev *dev, int pos) | |||
515 | return false; | 515 | return false; |
516 | 516 | ||
517 | switch (pos) { | 517 | switch (pos) { |
518 | case PCI_EXP_FLAGS_TYPE: | 518 | case PCI_EXP_FLAGS: |
519 | return true; | 519 | return true; |
520 | case PCI_EXP_DEVCAP: | 520 | case PCI_EXP_DEVCAP: |
521 | case PCI_EXP_DEVCTL: | 521 | case PCI_EXP_DEVCTL: |
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index ad6a8b635692..8647dc6f52d0 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c | |||
@@ -158,69 +158,38 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, | |||
158 | return ret; | 158 | return ret; |
159 | } | 159 | } |
160 | 160 | ||
161 | void __weak pcibios_resource_survey_bus(struct pci_bus *bus) { } | ||
162 | |||
161 | /** | 163 | /** |
162 | * pci_bus_add_device - add a single device | 164 | * pci_bus_add_device - start driver for a single device |
163 | * @dev: device to add | 165 | * @dev: device to add |
164 | * | 166 | * |
165 | * This adds a single pci device to the global | 167 | * This adds add sysfs entries and start device drivers |
166 | * device list and adds sysfs and procfs entries | ||
167 | */ | 168 | */ |
168 | int pci_bus_add_device(struct pci_dev *dev) | 169 | int pci_bus_add_device(struct pci_dev *dev) |
169 | { | 170 | { |
170 | int retval; | 171 | int retval; |
171 | 172 | ||
172 | pci_fixup_device(pci_fixup_final, dev); | 173 | /* |
173 | 174 | * Can not put in pci_device_add yet because resources | |
174 | retval = pcibios_add_device(dev); | 175 | * are not assigned yet for some devices. |
175 | if (retval) | 176 | */ |
176 | return retval; | ||
177 | |||
178 | retval = device_add(&dev->dev); | ||
179 | if (retval) | ||
180 | return retval; | ||
181 | |||
182 | dev->is_added = 1; | ||
183 | pci_proc_attach_device(dev); | ||
184 | pci_create_sysfs_dev_files(dev); | 177 | pci_create_sysfs_dev_files(dev); |
185 | return 0; | ||
186 | } | ||
187 | |||
188 | /** | ||
189 | * pci_bus_add_child - add a child bus | ||
190 | * @bus: bus to add | ||
191 | * | ||
192 | * This adds sysfs entries for a single bus | ||
193 | */ | ||
194 | int pci_bus_add_child(struct pci_bus *bus) | ||
195 | { | ||
196 | int retval; | ||
197 | |||
198 | if (bus->bridge) | ||
199 | bus->dev.parent = bus->bridge; | ||
200 | 178 | ||
201 | retval = device_register(&bus->dev); | 179 | dev->match_driver = true; |
202 | if (retval) | 180 | retval = device_attach(&dev->dev); |
203 | return retval; | 181 | WARN_ON(retval < 0); |
204 | 182 | ||
205 | bus->is_added = 1; | 183 | dev->is_added = 1; |
206 | |||
207 | /* Create legacy_io and legacy_mem files for this bus */ | ||
208 | pci_create_legacy_files(bus); | ||
209 | 184 | ||
210 | return retval; | 185 | return 0; |
211 | } | 186 | } |
212 | 187 | ||
213 | /** | 188 | /** |
214 | * pci_bus_add_devices - insert newly discovered PCI devices | 189 | * pci_bus_add_devices - start driver for PCI devices |
215 | * @bus: bus to check for new devices | 190 | * @bus: bus to check for new devices |
216 | * | 191 | * |
217 | * Add newly discovered PCI devices (which are on the bus->devices | 192 | * Start driver for PCI devices and add some sysfs entries. |
218 | * list) to the global PCI device list, add the sysfs and procfs | ||
219 | * entries. Where a bridge is found, add the discovered bus to | ||
220 | * the parents list of child buses, and recurse (breadth-first | ||
221 | * to be compatible with 2.4) | ||
222 | * | ||
223 | * Call hotplug for each new devices. | ||
224 | */ | 193 | */ |
225 | void pci_bus_add_devices(const struct pci_bus *bus) | 194 | void pci_bus_add_devices(const struct pci_bus *bus) |
226 | { | 195 | { |
@@ -233,36 +202,20 @@ void pci_bus_add_devices(const struct pci_bus *bus) | |||
233 | if (dev->is_added) | 202 | if (dev->is_added) |
234 | continue; | 203 | continue; |
235 | retval = pci_bus_add_device(dev); | 204 | retval = pci_bus_add_device(dev); |
236 | if (retval) | ||
237 | dev_err(&dev->dev, "Error adding device, continuing\n"); | ||
238 | } | 205 | } |
239 | 206 | ||
240 | list_for_each_entry(dev, &bus->devices, bus_list) { | 207 | list_for_each_entry(dev, &bus->devices, bus_list) { |
241 | BUG_ON(!dev->is_added); | 208 | BUG_ON(!dev->is_added); |
242 | 209 | ||
243 | child = dev->subordinate; | 210 | child = dev->subordinate; |
244 | /* | 211 | |
245 | * If there is an unattached subordinate bus, attach | ||
246 | * it and then scan for unattached PCI devices. | ||
247 | */ | ||
248 | if (!child) | 212 | if (!child) |
249 | continue; | 213 | continue; |
250 | if (list_empty(&child->node)) { | ||
251 | down_write(&pci_bus_sem); | ||
252 | list_add_tail(&child->node, &dev->bus->children); | ||
253 | up_write(&pci_bus_sem); | ||
254 | } | ||
255 | pci_bus_add_devices(child); | 214 | pci_bus_add_devices(child); |
256 | 215 | ||
257 | /* | ||
258 | * register the bus with sysfs as the parent is now | ||
259 | * properly registered. | ||
260 | */ | ||
261 | if (child->is_added) | 216 | if (child->is_added) |
262 | continue; | 217 | continue; |
263 | retval = pci_bus_add_child(child); | 218 | child->is_added = 1; |
264 | if (retval) | ||
265 | dev_err(&dev->dev, "Error adding bus, continuing\n"); | ||
266 | } | 219 | } |
267 | } | 220 | } |
268 | 221 | ||
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h index a1afb5b39ad4..b70ac00a117e 100644 --- a/drivers/pci/hotplug/acpiphp.h +++ b/drivers/pci/hotplug/acpiphp.h | |||
@@ -79,7 +79,6 @@ struct acpiphp_bridge { | |||
79 | /* Ejectable PCI-to-PCI bridge (PCI bridge and PCI function) */ | 79 | /* Ejectable PCI-to-PCI bridge (PCI bridge and PCI function) */ |
80 | struct acpiphp_func *func; | 80 | struct acpiphp_func *func; |
81 | 81 | ||
82 | int type; | ||
83 | int nr_slots; | 82 | int nr_slots; |
84 | 83 | ||
85 | u32 flags; | 84 | u32 flags; |
@@ -146,10 +145,6 @@ struct acpiphp_attention_info | |||
146 | /* PCI bus bridge HID */ | 145 | /* PCI bus bridge HID */ |
147 | #define ACPI_PCI_HOST_HID "PNP0A03" | 146 | #define ACPI_PCI_HOST_HID "PNP0A03" |
148 | 147 | ||
149 | /* PCI BRIDGE type */ | ||
150 | #define BRIDGE_TYPE_HOST 0 | ||
151 | #define BRIDGE_TYPE_P2P 1 | ||
152 | |||
153 | /* ACPI _STA method value (ignore bit 4; battery present) */ | 148 | /* ACPI _STA method value (ignore bit 4; battery present) */ |
154 | #define ACPI_STA_PRESENT (0x00000001) | 149 | #define ACPI_STA_PRESENT (0x00000001) |
155 | #define ACPI_STA_ENABLED (0x00000002) | 150 | #define ACPI_STA_ENABLED (0x00000002) |
@@ -158,13 +153,7 @@ struct acpiphp_attention_info | |||
158 | #define ACPI_STA_ALL (0x0000000f) | 153 | #define ACPI_STA_ALL (0x0000000f) |
159 | 154 | ||
160 | /* bridge flags */ | 155 | /* bridge flags */ |
161 | #define BRIDGE_HAS_STA (0x00000001) | 156 | #define BRIDGE_HAS_EJ0 (0x00000001) |
162 | #define BRIDGE_HAS_EJ0 (0x00000002) | ||
163 | #define BRIDGE_HAS_HPP (0x00000004) | ||
164 | #define BRIDGE_HAS_PS0 (0x00000010) | ||
165 | #define BRIDGE_HAS_PS1 (0x00000020) | ||
166 | #define BRIDGE_HAS_PS2 (0x00000040) | ||
167 | #define BRIDGE_HAS_PS3 (0x00000080) | ||
168 | 157 | ||
169 | /* slot flags */ | 158 | /* slot flags */ |
170 | 159 | ||
@@ -193,7 +182,6 @@ extern void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *slot); | |||
193 | /* acpiphp_glue.c */ | 182 | /* acpiphp_glue.c */ |
194 | extern int acpiphp_glue_init (void); | 183 | extern int acpiphp_glue_init (void); |
195 | extern void acpiphp_glue_exit (void); | 184 | extern void acpiphp_glue_exit (void); |
196 | extern int acpiphp_get_num_slots (void); | ||
197 | typedef int (*acpiphp_callback)(struct acpiphp_slot *slot, void *data); | 185 | typedef int (*acpiphp_callback)(struct acpiphp_slot *slot, void *data); |
198 | 186 | ||
199 | extern int acpiphp_enable_slot (struct acpiphp_slot *slot); | 187 | extern int acpiphp_enable_slot (struct acpiphp_slot *slot); |
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c index 96316b74969f..c2fd3095701f 100644 --- a/drivers/pci/hotplug/acpiphp_core.c +++ b/drivers/pci/hotplug/acpiphp_core.c | |||
@@ -50,7 +50,6 @@ | |||
50 | bool acpiphp_debug; | 50 | bool acpiphp_debug; |
51 | 51 | ||
52 | /* local variables */ | 52 | /* local variables */ |
53 | static int num_slots; | ||
54 | static struct acpiphp_attention_info *attention_info; | 53 | static struct acpiphp_attention_info *attention_info; |
55 | 54 | ||
56 | #define DRIVER_VERSION "0.5" | 55 | #define DRIVER_VERSION "0.5" |
@@ -272,25 +271,6 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) | |||
272 | return 0; | 271 | return 0; |
273 | } | 272 | } |
274 | 273 | ||
275 | static int __init init_acpi(void) | ||
276 | { | ||
277 | int retval; | ||
278 | |||
279 | /* initialize internal data structure etc. */ | ||
280 | retval = acpiphp_glue_init(); | ||
281 | |||
282 | /* read initial number of slots */ | ||
283 | if (!retval) { | ||
284 | num_slots = acpiphp_get_num_slots(); | ||
285 | if (num_slots == 0) { | ||
286 | acpiphp_glue_exit(); | ||
287 | retval = -ENODEV; | ||
288 | } | ||
289 | } | ||
290 | |||
291 | return retval; | ||
292 | } | ||
293 | |||
294 | /** | 274 | /** |
295 | * release_slot - free up the memory used by a slot | 275 | * release_slot - free up the memory used by a slot |
296 | * @hotplug_slot: slot to free | 276 | * @hotplug_slot: slot to free |
@@ -379,7 +359,8 @@ static int __init acpiphp_init(void) | |||
379 | return 0; | 359 | return 0; |
380 | 360 | ||
381 | /* read all the ACPI info from the system */ | 361 | /* read all the ACPI info from the system */ |
382 | return init_acpi(); | 362 | /* initialize internal data structure etc. */ |
363 | return acpiphp_glue_init(); | ||
383 | } | 364 | } |
384 | 365 | ||
385 | 366 | ||
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index a951c22921d1..270fdbadc19c 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -325,8 +325,8 @@ static void init_bridge_misc(struct acpiphp_bridge *bridge) | |||
325 | return; | 325 | return; |
326 | } | 326 | } |
327 | 327 | ||
328 | /* install notify handler */ | 328 | /* install notify handler for P2P bridges */ |
329 | if (bridge->type != BRIDGE_TYPE_HOST) { | 329 | if (!pci_is_root_bus(bridge->pci_bus)) { |
330 | if ((bridge->flags & BRIDGE_HAS_EJ0) && bridge->func) { | 330 | if ((bridge->flags & BRIDGE_HAS_EJ0) && bridge->func) { |
331 | status = acpi_remove_notify_handler(bridge->func->handle, | 331 | status = acpi_remove_notify_handler(bridge->func->handle, |
332 | ACPI_SYSTEM_NOTIFY, | 332 | ACPI_SYSTEM_NOTIFY, |
@@ -369,27 +369,12 @@ static struct acpiphp_func *acpiphp_bridge_handle_to_function(acpi_handle handle | |||
369 | static inline void config_p2p_bridge_flags(struct acpiphp_bridge *bridge) | 369 | static inline void config_p2p_bridge_flags(struct acpiphp_bridge *bridge) |
370 | { | 370 | { |
371 | acpi_handle dummy_handle; | 371 | acpi_handle dummy_handle; |
372 | struct acpiphp_func *func; | ||
372 | 373 | ||
373 | if (ACPI_SUCCESS(acpi_get_handle(bridge->handle, | 374 | if (ACPI_SUCCESS(acpi_get_handle(bridge->handle, |
374 | "_STA", &dummy_handle))) | 375 | "_EJ0", &dummy_handle))) { |
375 | bridge->flags |= BRIDGE_HAS_STA; | ||
376 | |||
377 | if (ACPI_SUCCESS(acpi_get_handle(bridge->handle, | ||
378 | "_EJ0", &dummy_handle))) | ||
379 | bridge->flags |= BRIDGE_HAS_EJ0; | 376 | bridge->flags |= BRIDGE_HAS_EJ0; |
380 | 377 | ||
381 | if (ACPI_SUCCESS(acpi_get_handle(bridge->handle, | ||
382 | "_PS0", &dummy_handle))) | ||
383 | bridge->flags |= BRIDGE_HAS_PS0; | ||
384 | |||
385 | if (ACPI_SUCCESS(acpi_get_handle(bridge->handle, | ||
386 | "_PS3", &dummy_handle))) | ||
387 | bridge->flags |= BRIDGE_HAS_PS3; | ||
388 | |||
389 | /* is this ejectable p2p bridge? */ | ||
390 | if (bridge->flags & BRIDGE_HAS_EJ0) { | ||
391 | struct acpiphp_func *func; | ||
392 | |||
393 | dbg("found ejectable p2p bridge\n"); | 378 | dbg("found ejectable p2p bridge\n"); |
394 | 379 | ||
395 | /* make link between PCI bridge and PCI function */ | 380 | /* make link between PCI bridge and PCI function */ |
@@ -412,7 +397,6 @@ static void add_host_bridge(struct acpi_pci_root *root) | |||
412 | if (bridge == NULL) | 397 | if (bridge == NULL) |
413 | return; | 398 | return; |
414 | 399 | ||
415 | bridge->type = BRIDGE_TYPE_HOST; | ||
416 | bridge->handle = handle; | 400 | bridge->handle = handle; |
417 | 401 | ||
418 | bridge->pci_bus = root->bus; | 402 | bridge->pci_bus = root->bus; |
@@ -432,7 +416,6 @@ static void add_p2p_bridge(acpi_handle *handle) | |||
432 | return; | 416 | return; |
433 | } | 417 | } |
434 | 418 | ||
435 | bridge->type = BRIDGE_TYPE_P2P; | ||
436 | bridge->handle = handle; | 419 | bridge->handle = handle; |
437 | config_p2p_bridge_flags(bridge); | 420 | config_p2p_bridge_flags(bridge); |
438 | 421 | ||
@@ -543,13 +526,15 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge) | |||
543 | acpi_status status; | 526 | acpi_status status; |
544 | acpi_handle handle = bridge->handle; | 527 | acpi_handle handle = bridge->handle; |
545 | 528 | ||
546 | status = acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY, | 529 | if (!pci_is_root_bus(bridge->pci_bus)) { |
530 | status = acpi_remove_notify_handler(handle, | ||
531 | ACPI_SYSTEM_NOTIFY, | ||
547 | handle_hotplug_event_bridge); | 532 | handle_hotplug_event_bridge); |
548 | if (ACPI_FAILURE(status)) | 533 | if (ACPI_FAILURE(status)) |
549 | err("failed to remove notify handler\n"); | 534 | err("failed to remove notify handler\n"); |
535 | } | ||
550 | 536 | ||
551 | if ((bridge->type != BRIDGE_TYPE_HOST) && | 537 | if ((bridge->flags & BRIDGE_HAS_EJ0) && bridge->func) { |
552 | ((bridge->flags & BRIDGE_HAS_EJ0) && bridge->func)) { | ||
553 | status = acpi_install_notify_handler(bridge->func->handle, | 538 | status = acpi_install_notify_handler(bridge->func->handle, |
554 | ACPI_SYSTEM_NOTIFY, | 539 | ACPI_SYSTEM_NOTIFY, |
555 | handle_hotplug_event_func, | 540 | handle_hotplug_event_func, |
@@ -630,9 +615,6 @@ static void remove_bridge(struct acpi_pci_root *root) | |||
630 | bridge = acpiphp_handle_to_bridge(handle); | 615 | bridge = acpiphp_handle_to_bridge(handle); |
631 | if (bridge) | 616 | if (bridge) |
632 | cleanup_bridge(bridge); | 617 | cleanup_bridge(bridge); |
633 | else | ||
634 | acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY, | ||
635 | handle_hotplug_event_bridge); | ||
636 | } | 618 | } |
637 | 619 | ||
638 | static int power_on_slot(struct acpiphp_slot *slot) | 620 | static int power_on_slot(struct acpiphp_slot *slot) |
@@ -793,6 +775,29 @@ static void acpiphp_set_acpi_region(struct acpiphp_slot *slot) | |||
793 | } | 775 | } |
794 | } | 776 | } |
795 | 777 | ||
778 | static void check_hotplug_bridge(struct acpiphp_slot *slot, struct pci_dev *dev) | ||
779 | { | ||
780 | struct acpiphp_func *func; | ||
781 | |||
782 | if (!dev->subordinate) | ||
783 | return; | ||
784 | |||
785 | /* quirk, or pcie could set it already */ | ||
786 | if (dev->is_hotplug_bridge) | ||
787 | return; | ||
788 | |||
789 | if (PCI_SLOT(dev->devfn) != slot->device) | ||
790 | return; | ||
791 | |||
792 | list_for_each_entry(func, &slot->funcs, sibling) { | ||
793 | if (PCI_FUNC(dev->devfn) == func->function) { | ||
794 | /* check if this bridge has ejectable slots */ | ||
795 | if ((detect_ejectable_slots(func->handle) > 0)) | ||
796 | dev->is_hotplug_bridge = 1; | ||
797 | break; | ||
798 | } | ||
799 | } | ||
800 | } | ||
796 | /** | 801 | /** |
797 | * enable_device - enable, configure a slot | 802 | * enable_device - enable, configure a slot |
798 | * @slot: slot to be enabled | 803 | * @slot: slot to be enabled |
@@ -812,6 +817,9 @@ static int __ref enable_device(struct acpiphp_slot *slot) | |||
812 | if (slot->flags & SLOT_ENABLED) | 817 | if (slot->flags & SLOT_ENABLED) |
813 | goto err_exit; | 818 | goto err_exit; |
814 | 819 | ||
820 | list_for_each_entry(func, &slot->funcs, sibling) | ||
821 | acpiphp_bus_add(func); | ||
822 | |||
815 | num = pci_scan_slot(bus, PCI_DEVFN(slot->device, 0)); | 823 | num = pci_scan_slot(bus, PCI_DEVFN(slot->device, 0)); |
816 | if (num == 0) { | 824 | if (num == 0) { |
817 | /* Maybe only part of funcs are added. */ | 825 | /* Maybe only part of funcs are added. */ |
@@ -827,15 +835,14 @@ static int __ref enable_device(struct acpiphp_slot *slot) | |||
827 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || | 835 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || |
828 | dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) { | 836 | dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) { |
829 | max = pci_scan_bridge(bus, dev, max, pass); | 837 | max = pci_scan_bridge(bus, dev, max, pass); |
830 | if (pass && dev->subordinate) | 838 | if (pass && dev->subordinate) { |
839 | check_hotplug_bridge(slot, dev); | ||
831 | pci_bus_size_bridges(dev->subordinate); | 840 | pci_bus_size_bridges(dev->subordinate); |
841 | } | ||
832 | } | 842 | } |
833 | } | 843 | } |
834 | } | 844 | } |
835 | 845 | ||
836 | list_for_each_entry(func, &slot->funcs, sibling) | ||
837 | acpiphp_bus_add(func); | ||
838 | |||
839 | pci_bus_assign_resources(bus); | 846 | pci_bus_assign_resources(bus); |
840 | acpiphp_sanitize_bus(bus); | 847 | acpiphp_sanitize_bus(bus); |
841 | acpiphp_set_hpp_values(bus); | 848 | acpiphp_set_hpp_values(bus); |
@@ -1093,70 +1100,11 @@ static void acpiphp_sanitize_bus(struct pci_bus *bus) | |||
1093 | } | 1100 | } |
1094 | } | 1101 | } |
1095 | 1102 | ||
1096 | /* Program resources in newly inserted bridge */ | ||
1097 | static int acpiphp_configure_bridge (acpi_handle handle) | ||
1098 | { | ||
1099 | struct pci_bus *bus; | ||
1100 | |||
1101 | if (acpi_is_root_bridge(handle)) { | ||
1102 | struct acpi_pci_root *root = acpi_pci_find_root(handle); | ||
1103 | bus = root->bus; | ||
1104 | } else { | ||
1105 | struct pci_dev *pdev = acpi_get_pci_dev(handle); | ||
1106 | bus = pdev->subordinate; | ||
1107 | pci_dev_put(pdev); | ||
1108 | } | ||
1109 | |||
1110 | pci_bus_size_bridges(bus); | ||
1111 | pci_bus_assign_resources(bus); | ||
1112 | acpiphp_sanitize_bus(bus); | ||
1113 | acpiphp_set_hpp_values(bus); | ||
1114 | pci_enable_bridges(bus); | ||
1115 | return 0; | ||
1116 | } | ||
1117 | |||
1118 | static void handle_bridge_insertion(acpi_handle handle, u32 type) | ||
1119 | { | ||
1120 | struct acpi_device *device; | ||
1121 | |||
1122 | if ((type != ACPI_NOTIFY_BUS_CHECK) && | ||
1123 | (type != ACPI_NOTIFY_DEVICE_CHECK)) { | ||
1124 | err("unexpected notification type %d\n", type); | ||
1125 | return; | ||
1126 | } | ||
1127 | |||
1128 | if (acpi_bus_scan(handle)) { | ||
1129 | err("cannot add bridge to acpi list\n"); | ||
1130 | return; | ||
1131 | } | ||
1132 | if (acpi_bus_get_device(handle, &device)) { | ||
1133 | err("ACPI device object missing\n"); | ||
1134 | return; | ||
1135 | } | ||
1136 | if (!acpiphp_configure_bridge(handle)) | ||
1137 | add_bridge(handle); | ||
1138 | else | ||
1139 | err("cannot configure and start bridge\n"); | ||
1140 | |||
1141 | } | ||
1142 | |||
1143 | /* | 1103 | /* |
1144 | * ACPI event handlers | 1104 | * ACPI event handlers |
1145 | */ | 1105 | */ |
1146 | 1106 | ||
1147 | static acpi_status | 1107 | static acpi_status |
1148 | count_sub_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
1149 | { | ||
1150 | int *count = (int *)context; | ||
1151 | struct acpiphp_bridge *bridge; | ||
1152 | |||
1153 | bridge = acpiphp_handle_to_bridge(handle); | ||
1154 | if (bridge) | ||
1155 | (*count)++; | ||
1156 | return AE_OK ; | ||
1157 | } | ||
1158 | |||
1159 | static acpi_status | ||
1160 | check_sub_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) | 1108 | check_sub_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) |
1161 | { | 1109 | { |
1162 | struct acpiphp_bridge *bridge; | 1110 | struct acpiphp_bridge *bridge; |
@@ -1174,83 +1122,33 @@ check_sub_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
1174 | return AE_OK ; | 1122 | return AE_OK ; |
1175 | } | 1123 | } |
1176 | 1124 | ||
1177 | struct acpiphp_hp_work { | ||
1178 | struct work_struct work; | ||
1179 | acpi_handle handle; | ||
1180 | u32 type; | ||
1181 | void *context; | ||
1182 | }; | ||
1183 | |||
1184 | static void alloc_acpiphp_hp_work(acpi_handle handle, u32 type, | ||
1185 | void *context, | ||
1186 | void (*func)(struct work_struct *work)) | ||
1187 | { | ||
1188 | struct acpiphp_hp_work *hp_work; | ||
1189 | int ret; | ||
1190 | |||
1191 | hp_work = kmalloc(sizeof(*hp_work), GFP_KERNEL); | ||
1192 | if (!hp_work) | ||
1193 | return; | ||
1194 | |||
1195 | hp_work->handle = handle; | ||
1196 | hp_work->type = type; | ||
1197 | hp_work->context = context; | ||
1198 | |||
1199 | INIT_WORK(&hp_work->work, func); | ||
1200 | ret = queue_work(kacpi_hotplug_wq, &hp_work->work); | ||
1201 | if (!ret) | ||
1202 | kfree(hp_work); | ||
1203 | } | ||
1204 | |||
1205 | static void _handle_hotplug_event_bridge(struct work_struct *work) | 1125 | static void _handle_hotplug_event_bridge(struct work_struct *work) |
1206 | { | 1126 | { |
1207 | struct acpiphp_bridge *bridge; | 1127 | struct acpiphp_bridge *bridge; |
1208 | char objname[64]; | 1128 | char objname[64]; |
1209 | struct acpi_buffer buffer = { .length = sizeof(objname), | 1129 | struct acpi_buffer buffer = { .length = sizeof(objname), |
1210 | .pointer = objname }; | 1130 | .pointer = objname }; |
1211 | struct acpi_device *device; | 1131 | struct acpi_hp_work *hp_work; |
1212 | int num_sub_bridges = 0; | ||
1213 | struct acpiphp_hp_work *hp_work; | ||
1214 | acpi_handle handle; | 1132 | acpi_handle handle; |
1215 | u32 type; | 1133 | u32 type; |
1216 | 1134 | ||
1217 | hp_work = container_of(work, struct acpiphp_hp_work, work); | 1135 | hp_work = container_of(work, struct acpi_hp_work, work); |
1218 | handle = hp_work->handle; | 1136 | handle = hp_work->handle; |
1219 | type = hp_work->type; | 1137 | type = hp_work->type; |
1138 | bridge = (struct acpiphp_bridge *)hp_work->context; | ||
1220 | 1139 | ||
1221 | acpi_scan_lock_acquire(); | 1140 | acpi_scan_lock_acquire(); |
1222 | 1141 | ||
1223 | if (acpi_bus_get_device(handle, &device)) { | ||
1224 | /* This bridge must have just been physically inserted */ | ||
1225 | handle_bridge_insertion(handle, type); | ||
1226 | goto out; | ||
1227 | } | ||
1228 | |||
1229 | bridge = acpiphp_handle_to_bridge(handle); | ||
1230 | if (type == ACPI_NOTIFY_BUS_CHECK) { | ||
1231 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, ACPI_UINT32_MAX, | ||
1232 | count_sub_bridges, NULL, &num_sub_bridges, NULL); | ||
1233 | } | ||
1234 | |||
1235 | if (!bridge && !num_sub_bridges) { | ||
1236 | err("cannot get bridge info\n"); | ||
1237 | goto out; | ||
1238 | } | ||
1239 | |||
1240 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); | 1142 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); |
1241 | 1143 | ||
1242 | switch (type) { | 1144 | switch (type) { |
1243 | case ACPI_NOTIFY_BUS_CHECK: | 1145 | case ACPI_NOTIFY_BUS_CHECK: |
1244 | /* bus re-enumerate */ | 1146 | /* bus re-enumerate */ |
1245 | dbg("%s: Bus check notify on %s\n", __func__, objname); | 1147 | dbg("%s: Bus check notify on %s\n", __func__, objname); |
1246 | if (bridge) { | 1148 | dbg("%s: re-enumerating slots under %s\n", __func__, objname); |
1247 | dbg("%s: re-enumerating slots under %s\n", | 1149 | acpiphp_check_bridge(bridge); |
1248 | __func__, objname); | 1150 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, |
1249 | acpiphp_check_bridge(bridge); | 1151 | ACPI_UINT32_MAX, check_sub_bridges, NULL, NULL, NULL); |
1250 | } | ||
1251 | if (num_sub_bridges) | ||
1252 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, | ||
1253 | ACPI_UINT32_MAX, check_sub_bridges, NULL, NULL, NULL); | ||
1254 | break; | 1152 | break; |
1255 | 1153 | ||
1256 | case ACPI_NOTIFY_DEVICE_CHECK: | 1154 | case ACPI_NOTIFY_DEVICE_CHECK: |
@@ -1267,8 +1165,7 @@ static void _handle_hotplug_event_bridge(struct work_struct *work) | |||
1267 | case ACPI_NOTIFY_EJECT_REQUEST: | 1165 | case ACPI_NOTIFY_EJECT_REQUEST: |
1268 | /* request device eject */ | 1166 | /* request device eject */ |
1269 | dbg("%s: Device eject notify on %s\n", __func__, objname); | 1167 | dbg("%s: Device eject notify on %s\n", __func__, objname); |
1270 | if ((bridge->type != BRIDGE_TYPE_HOST) && | 1168 | if ((bridge->flags & BRIDGE_HAS_EJ0) && bridge->func) { |
1271 | (bridge->flags & BRIDGE_HAS_EJ0)) { | ||
1272 | struct acpiphp_slot *slot; | 1169 | struct acpiphp_slot *slot; |
1273 | slot = bridge->func->slot; | 1170 | slot = bridge->func->slot; |
1274 | if (!acpiphp_disable_slot(slot)) | 1171 | if (!acpiphp_disable_slot(slot)) |
@@ -1296,7 +1193,6 @@ static void _handle_hotplug_event_bridge(struct work_struct *work) | |||
1296 | break; | 1193 | break; |
1297 | } | 1194 | } |
1298 | 1195 | ||
1299 | out: | ||
1300 | acpi_scan_lock_release(); | 1196 | acpi_scan_lock_release(); |
1301 | kfree(hp_work); /* allocated in handle_hotplug_event_bridge */ | 1197 | kfree(hp_work); /* allocated in handle_hotplug_event_bridge */ |
1302 | } | 1198 | } |
@@ -1320,8 +1216,7 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, | |||
1320 | * For now just re-add this work to the kacpi_hotplug_wq so we | 1216 | * For now just re-add this work to the kacpi_hotplug_wq so we |
1321 | * don't deadlock on hotplug actions. | 1217 | * don't deadlock on hotplug actions. |
1322 | */ | 1218 | */ |
1323 | alloc_acpiphp_hp_work(handle, type, context, | 1219 | alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_bridge); |
1324 | _handle_hotplug_event_bridge); | ||
1325 | } | 1220 | } |
1326 | 1221 | ||
1327 | static void _handle_hotplug_event_func(struct work_struct *work) | 1222 | static void _handle_hotplug_event_func(struct work_struct *work) |
@@ -1330,22 +1225,19 @@ static void _handle_hotplug_event_func(struct work_struct *work) | |||
1330 | char objname[64]; | 1225 | char objname[64]; |
1331 | struct acpi_buffer buffer = { .length = sizeof(objname), | 1226 | struct acpi_buffer buffer = { .length = sizeof(objname), |
1332 | .pointer = objname }; | 1227 | .pointer = objname }; |
1333 | struct acpiphp_hp_work *hp_work; | 1228 | struct acpi_hp_work *hp_work; |
1334 | acpi_handle handle; | 1229 | acpi_handle handle; |
1335 | u32 type; | 1230 | u32 type; |
1336 | void *context; | ||
1337 | 1231 | ||
1338 | hp_work = container_of(work, struct acpiphp_hp_work, work); | 1232 | hp_work = container_of(work, struct acpi_hp_work, work); |
1339 | handle = hp_work->handle; | 1233 | handle = hp_work->handle; |
1340 | type = hp_work->type; | 1234 | type = hp_work->type; |
1341 | context = hp_work->context; | 1235 | func = (struct acpiphp_func *)hp_work->context; |
1342 | |||
1343 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); | ||
1344 | |||
1345 | func = (struct acpiphp_func *)context; | ||
1346 | 1236 | ||
1347 | acpi_scan_lock_acquire(); | 1237 | acpi_scan_lock_acquire(); |
1348 | 1238 | ||
1239 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); | ||
1240 | |||
1349 | switch (type) { | 1241 | switch (type) { |
1350 | case ACPI_NOTIFY_BUS_CHECK: | 1242 | case ACPI_NOTIFY_BUS_CHECK: |
1351 | /* bus re-enumerate */ | 1243 | /* bus re-enumerate */ |
@@ -1399,23 +1291,7 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type, | |||
1399 | * For now just re-add this work to the kacpi_hotplug_wq so we | 1291 | * For now just re-add this work to the kacpi_hotplug_wq so we |
1400 | * don't deadlock on hotplug actions. | 1292 | * don't deadlock on hotplug actions. |
1401 | */ | 1293 | */ |
1402 | alloc_acpiphp_hp_work(handle, type, context, | 1294 | alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_func); |
1403 | _handle_hotplug_event_func); | ||
1404 | } | ||
1405 | |||
1406 | static acpi_status | ||
1407 | find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
1408 | { | ||
1409 | int *count = (int *)context; | ||
1410 | |||
1411 | if (!acpi_is_root_bridge(handle)) | ||
1412 | return AE_OK; | ||
1413 | |||
1414 | (*count)++; | ||
1415 | acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, | ||
1416 | handle_hotplug_event_bridge, NULL); | ||
1417 | |||
1418 | return AE_OK ; | ||
1419 | } | 1295 | } |
1420 | 1296 | ||
1421 | static struct acpi_pci_driver acpi_pci_hp_driver = { | 1297 | static struct acpi_pci_driver acpi_pci_hp_driver = { |
@@ -1428,15 +1304,7 @@ static struct acpi_pci_driver acpi_pci_hp_driver = { | |||
1428 | */ | 1304 | */ |
1429 | int __init acpiphp_glue_init(void) | 1305 | int __init acpiphp_glue_init(void) |
1430 | { | 1306 | { |
1431 | int num = 0; | 1307 | acpi_pci_register_driver(&acpi_pci_hp_driver); |
1432 | |||
1433 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | ||
1434 | ACPI_UINT32_MAX, find_root_bridges, NULL, &num, NULL); | ||
1435 | |||
1436 | if (num <= 0) | ||
1437 | return -1; | ||
1438 | else | ||
1439 | acpi_pci_register_driver(&acpi_pci_hp_driver); | ||
1440 | 1308 | ||
1441 | return 0; | 1309 | return 0; |
1442 | } | 1310 | } |
@@ -1452,28 +1320,6 @@ void acpiphp_glue_exit(void) | |||
1452 | acpi_pci_unregister_driver(&acpi_pci_hp_driver); | 1320 | acpi_pci_unregister_driver(&acpi_pci_hp_driver); |
1453 | } | 1321 | } |
1454 | 1322 | ||
1455 | |||
1456 | /** | ||
1457 | * acpiphp_get_num_slots - count number of slots in a system | ||
1458 | */ | ||
1459 | int __init acpiphp_get_num_slots(void) | ||
1460 | { | ||
1461 | struct acpiphp_bridge *bridge; | ||
1462 | int num_slots = 0; | ||
1463 | |||
1464 | list_for_each_entry(bridge, &bridge_list, list) { | ||
1465 | dbg("Bus %04x:%02x has %d slot%s\n", | ||
1466 | pci_domain_nr(bridge->pci_bus), | ||
1467 | bridge->pci_bus->number, bridge->nr_slots, | ||
1468 | bridge->nr_slots == 1 ? "" : "s"); | ||
1469 | num_slots += bridge->nr_slots; | ||
1470 | } | ||
1471 | |||
1472 | dbg("Total %d slots\n", num_slots); | ||
1473 | return num_slots; | ||
1474 | } | ||
1475 | |||
1476 | |||
1477 | /** | 1323 | /** |
1478 | * acpiphp_enable_slot - power on slot | 1324 | * acpiphp_enable_slot - power on slot |
1479 | * @slot: ACPI PHP slot | 1325 | * @slot: ACPI PHP slot |
diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c index dcc75c785443..d8add34177f2 100644 --- a/drivers/pci/hotplug/cpci_hotplug_pci.c +++ b/drivers/pci/hotplug/cpci_hotplug_pci.c | |||
@@ -252,8 +252,8 @@ int cpci_led_off(struct slot* slot) | |||
252 | 252 | ||
253 | int __ref cpci_configure_slot(struct slot *slot) | 253 | int __ref cpci_configure_slot(struct slot *slot) |
254 | { | 254 | { |
255 | struct pci_dev *dev; | ||
255 | struct pci_bus *parent; | 256 | struct pci_bus *parent; |
256 | int fn; | ||
257 | 257 | ||
258 | dbg("%s - enter", __func__); | 258 | dbg("%s - enter", __func__); |
259 | 259 | ||
@@ -282,18 +282,13 @@ int __ref cpci_configure_slot(struct slot *slot) | |||
282 | } | 282 | } |
283 | parent = slot->dev->bus; | 283 | parent = slot->dev->bus; |
284 | 284 | ||
285 | for (fn = 0; fn < 8; fn++) { | 285 | list_for_each_entry(dev, &parent->devices, bus_list) |
286 | struct pci_dev *dev; | 286 | if (PCI_SLOT(dev->devfn) != PCI_SLOT(slot->devfn)) |
287 | |||
288 | dev = pci_get_slot(parent, | ||
289 | PCI_DEVFN(PCI_SLOT(slot->devfn), fn)); | ||
290 | if (!dev) | ||
291 | continue; | 287 | continue; |
292 | if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || | 288 | if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || |
293 | (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) | 289 | (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) |
294 | pci_hp_add_bridge(dev); | 290 | pci_hp_add_bridge(dev); |
295 | pci_dev_put(dev); | 291 | |
296 | } | ||
297 | 292 | ||
298 | pci_assign_unassigned_bridge_resources(parent->self); | 293 | pci_assign_unassigned_bridge_resources(parent->self); |
299 | 294 | ||
@@ -305,8 +300,7 @@ int __ref cpci_configure_slot(struct slot *slot) | |||
305 | 300 | ||
306 | int cpci_unconfigure_slot(struct slot* slot) | 301 | int cpci_unconfigure_slot(struct slot* slot) |
307 | { | 302 | { |
308 | int i; | 303 | struct pci_dev *dev, *temp; |
309 | struct pci_dev *dev; | ||
310 | 304 | ||
311 | dbg("%s - enter", __func__); | 305 | dbg("%s - enter", __func__); |
312 | if (!slot->dev) { | 306 | if (!slot->dev) { |
@@ -314,13 +308,12 @@ int cpci_unconfigure_slot(struct slot* slot) | |||
314 | return -ENODEV; | 308 | return -ENODEV; |
315 | } | 309 | } |
316 | 310 | ||
317 | for (i = 0; i < 8; i++) { | 311 | list_for_each_entry_safe(dev, temp, &slot->bus->devices, bus_list) { |
318 | dev = pci_get_slot(slot->bus, | 312 | if (PCI_SLOT(dev->devfn) != PCI_SLOT(slot->devfn)) |
319 | PCI_DEVFN(PCI_SLOT(slot->devfn), i)); | 313 | continue; |
320 | if (dev) { | 314 | pci_dev_get(dev); |
321 | pci_stop_and_remove_bus_device(dev); | 315 | pci_stop_and_remove_bus_device(dev); |
322 | pci_dev_put(dev); | 316 | pci_dev_put(dev); |
323 | } | ||
324 | } | 317 | } |
325 | pci_dev_put(slot->dev); | 318 | pci_dev_put(slot->dev); |
326 | slot->dev = NULL; | 319 | slot->dev = NULL; |
diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c index 36112fe212d3..d282019cda5f 100644 --- a/drivers/pci/hotplug/cpqphp_ctrl.c +++ b/drivers/pci/hotplug/cpqphp_ctrl.c | |||
@@ -1900,8 +1900,7 @@ static void interrupt_event_handler(struct controller *ctrl) | |||
1900 | dbg("power fault\n"); | 1900 | dbg("power fault\n"); |
1901 | } else { | 1901 | } else { |
1902 | /* refresh notification */ | 1902 | /* refresh notification */ |
1903 | if (p_slot) | 1903 | update_slot_info(ctrl, p_slot); |
1904 | update_slot_info(ctrl, p_slot); | ||
1905 | } | 1904 | } |
1906 | 1905 | ||
1907 | ctrl->event_queue[loop].event_type = 0; | 1906 | ctrl->event_queue[loop].event_type = 0; |
@@ -2520,44 +2519,28 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func | |||
2520 | 2519 | ||
2521 | /* If we have IO resources copy them and fill in the bridge's | 2520 | /* If we have IO resources copy them and fill in the bridge's |
2522 | * IO range registers */ | 2521 | * IO range registers */ |
2523 | if (io_node) { | 2522 | memcpy(hold_IO_node, io_node, sizeof(struct pci_resource)); |
2524 | memcpy(hold_IO_node, io_node, sizeof(struct pci_resource)); | 2523 | io_node->next = NULL; |
2525 | io_node->next = NULL; | ||
2526 | 2524 | ||
2527 | /* set IO base and Limit registers */ | 2525 | /* set IO base and Limit registers */ |
2528 | temp_byte = io_node->base >> 8; | 2526 | temp_byte = io_node->base >> 8; |
2529 | rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_BASE, temp_byte); | 2527 | rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_BASE, temp_byte); |
2530 | 2528 | ||
2531 | temp_byte = (io_node->base + io_node->length - 1) >> 8; | 2529 | temp_byte = (io_node->base + io_node->length - 1) >> 8; |
2532 | rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_LIMIT, temp_byte); | 2530 | rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_LIMIT, temp_byte); |
2533 | } else { | ||
2534 | kfree(hold_IO_node); | ||
2535 | hold_IO_node = NULL; | ||
2536 | } | ||
2537 | |||
2538 | /* If we have memory resources copy them and fill in the | ||
2539 | * bridge's memory range registers. Otherwise, fill in the | ||
2540 | * range registers with values that disable them. */ | ||
2541 | if (mem_node) { | ||
2542 | memcpy(hold_mem_node, mem_node, sizeof(struct pci_resource)); | ||
2543 | mem_node->next = NULL; | ||
2544 | |||
2545 | /* set Mem base and Limit registers */ | ||
2546 | temp_word = mem_node->base >> 16; | ||
2547 | rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_BASE, temp_word); | ||
2548 | 2531 | ||
2549 | temp_word = (mem_node->base + mem_node->length - 1) >> 16; | 2532 | /* Copy the memory resources and fill in the bridge's memory |
2550 | rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word); | 2533 | * range registers. |
2551 | } else { | 2534 | */ |
2552 | temp_word = 0xFFFF; | 2535 | memcpy(hold_mem_node, mem_node, sizeof(struct pci_resource)); |
2553 | rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_BASE, temp_word); | 2536 | mem_node->next = NULL; |
2554 | 2537 | ||
2555 | temp_word = 0x0000; | 2538 | /* set Mem base and Limit registers */ |
2556 | rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word); | 2539 | temp_word = mem_node->base >> 16; |
2540 | rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_BASE, temp_word); | ||
2557 | 2541 | ||
2558 | kfree(hold_mem_node); | 2542 | temp_word = (mem_node->base + mem_node->length - 1) >> 16; |
2559 | hold_mem_node = NULL; | 2543 | rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word); |
2560 | } | ||
2561 | 2544 | ||
2562 | memcpy(hold_p_mem_node, p_mem_node, sizeof(struct pci_resource)); | 2545 | memcpy(hold_p_mem_node, p_mem_node, sizeof(struct pci_resource)); |
2563 | p_mem_node->next = NULL; | 2546 | p_mem_node->next = NULL; |
@@ -2627,7 +2610,7 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func | |||
2627 | /* Return unused bus resources | 2610 | /* Return unused bus resources |
2628 | * First use the temporary node to store information for | 2611 | * First use the temporary node to store information for |
2629 | * the board */ | 2612 | * the board */ |
2630 | if (hold_bus_node && bus_node && temp_resources.bus_head) { | 2613 | if (bus_node && temp_resources.bus_head) { |
2631 | hold_bus_node->length = bus_node->base - hold_bus_node->base; | 2614 | hold_bus_node->length = bus_node->base - hold_bus_node->base; |
2632 | 2615 | ||
2633 | hold_bus_node->next = func->bus_head; | 2616 | hold_bus_node->next = func->bus_head; |
@@ -2751,7 +2734,7 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func | |||
2751 | } | 2734 | } |
2752 | /* If we have prefetchable memory space available and there | 2735 | /* If we have prefetchable memory space available and there |
2753 | * is some left at the end, return the unused portion */ | 2736 | * is some left at the end, return the unused portion */ |
2754 | if (hold_p_mem_node && temp_resources.p_mem_head) { | 2737 | if (temp_resources.p_mem_head) { |
2755 | p_mem_node = do_pre_bridge_resource_split(&(temp_resources.p_mem_head), | 2738 | p_mem_node = do_pre_bridge_resource_split(&(temp_resources.p_mem_head), |
2756 | &hold_p_mem_node, 0x100000); | 2739 | &hold_p_mem_node, 0x100000); |
2757 | 2740 | ||
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index 939bd1d4b5b1..7d72c5e2eba9 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c | |||
@@ -293,7 +293,6 @@ static void pciehp_remove(struct pcie_device *dev) | |||
293 | #ifdef CONFIG_PM | 293 | #ifdef CONFIG_PM |
294 | static int pciehp_suspend (struct pcie_device *dev) | 294 | static int pciehp_suspend (struct pcie_device *dev) |
295 | { | 295 | { |
296 | dev_info(&dev->device, "%s ENTRY\n", __func__); | ||
297 | return 0; | 296 | return 0; |
298 | } | 297 | } |
299 | 298 | ||
@@ -303,7 +302,6 @@ static int pciehp_resume (struct pcie_device *dev) | |||
303 | struct slot *slot; | 302 | struct slot *slot; |
304 | u8 status; | 303 | u8 status; |
305 | 304 | ||
306 | dev_info(&dev->device, "%s ENTRY\n", __func__); | ||
307 | ctrl = get_service_data(dev); | 305 | ctrl = get_service_data(dev); |
308 | 306 | ||
309 | /* reinitialize the chipset's event detection logic */ | 307 | /* reinitialize the chipset's event detection logic */ |
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c index 09cecaf450c5..aac7a40e4a4a 100644 --- a/drivers/pci/hotplug/pciehp_pci.c +++ b/drivers/pci/hotplug/pciehp_pci.c | |||
@@ -39,7 +39,7 @@ int pciehp_configure_device(struct slot *p_slot) | |||
39 | struct pci_dev *dev; | 39 | struct pci_dev *dev; |
40 | struct pci_dev *bridge = p_slot->ctrl->pcie->port; | 40 | struct pci_dev *bridge = p_slot->ctrl->pcie->port; |
41 | struct pci_bus *parent = bridge->subordinate; | 41 | struct pci_bus *parent = bridge->subordinate; |
42 | int num, fn; | 42 | int num; |
43 | struct controller *ctrl = p_slot->ctrl; | 43 | struct controller *ctrl = p_slot->ctrl; |
44 | 44 | ||
45 | dev = pci_get_slot(parent, PCI_DEVFN(0, 0)); | 45 | dev = pci_get_slot(parent, PCI_DEVFN(0, 0)); |
@@ -57,28 +57,18 @@ int pciehp_configure_device(struct slot *p_slot) | |||
57 | return -ENODEV; | 57 | return -ENODEV; |
58 | } | 58 | } |
59 | 59 | ||
60 | for (fn = 0; fn < 8; fn++) { | 60 | list_for_each_entry(dev, &parent->devices, bus_list) |
61 | dev = pci_get_slot(parent, PCI_DEVFN(0, fn)); | ||
62 | if (!dev) | ||
63 | continue; | ||
64 | if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || | 61 | if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || |
65 | (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) | 62 | (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) |
66 | pci_hp_add_bridge(dev); | 63 | pci_hp_add_bridge(dev); |
67 | pci_dev_put(dev); | ||
68 | } | ||
69 | 64 | ||
70 | pci_assign_unassigned_bridge_resources(bridge); | 65 | pci_assign_unassigned_bridge_resources(bridge); |
71 | 66 | ||
72 | for (fn = 0; fn < 8; fn++) { | 67 | list_for_each_entry(dev, &parent->devices, bus_list) { |
73 | dev = pci_get_slot(parent, PCI_DEVFN(0, fn)); | 68 | if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) |
74 | if (!dev) | ||
75 | continue; | 69 | continue; |
76 | if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) { | 70 | |
77 | pci_dev_put(dev); | ||
78 | continue; | ||
79 | } | ||
80 | pci_configure_slot(dev); | 71 | pci_configure_slot(dev); |
81 | pci_dev_put(dev); | ||
82 | } | 72 | } |
83 | 73 | ||
84 | pci_bus_add_devices(parent); | 74 | pci_bus_add_devices(parent); |
@@ -89,9 +79,9 @@ int pciehp_configure_device(struct slot *p_slot) | |||
89 | int pciehp_unconfigure_device(struct slot *p_slot) | 79 | int pciehp_unconfigure_device(struct slot *p_slot) |
90 | { | 80 | { |
91 | int ret, rc = 0; | 81 | int ret, rc = 0; |
92 | int j; | ||
93 | u8 bctl = 0; | 82 | u8 bctl = 0; |
94 | u8 presence = 0; | 83 | u8 presence = 0; |
84 | struct pci_dev *dev, *temp; | ||
95 | struct pci_bus *parent = p_slot->ctrl->pcie->port->subordinate; | 85 | struct pci_bus *parent = p_slot->ctrl->pcie->port->subordinate; |
96 | u16 command; | 86 | u16 command; |
97 | struct controller *ctrl = p_slot->ctrl; | 87 | struct controller *ctrl = p_slot->ctrl; |
@@ -102,33 +92,31 @@ int pciehp_unconfigure_device(struct slot *p_slot) | |||
102 | if (ret) | 92 | if (ret) |
103 | presence = 0; | 93 | presence = 0; |
104 | 94 | ||
105 | for (j = 0; j < 8; j++) { | 95 | list_for_each_entry_safe(dev, temp, &parent->devices, bus_list) { |
106 | struct pci_dev *temp = pci_get_slot(parent, PCI_DEVFN(0, j)); | 96 | pci_dev_get(dev); |
107 | if (!temp) | 97 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) { |
108 | continue; | 98 | pci_read_config_byte(dev, PCI_BRIDGE_CONTROL, &bctl); |
109 | if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) { | ||
110 | pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, &bctl); | ||
111 | if (bctl & PCI_BRIDGE_CTL_VGA) { | 99 | if (bctl & PCI_BRIDGE_CTL_VGA) { |
112 | ctrl_err(ctrl, | 100 | ctrl_err(ctrl, |
113 | "Cannot remove display device %s\n", | 101 | "Cannot remove display device %s\n", |
114 | pci_name(temp)); | 102 | pci_name(dev)); |
115 | pci_dev_put(temp); | 103 | pci_dev_put(dev); |
116 | rc = -EINVAL; | 104 | rc = -EINVAL; |
117 | break; | 105 | break; |
118 | } | 106 | } |
119 | } | 107 | } |
120 | pci_stop_and_remove_bus_device(temp); | 108 | pci_stop_and_remove_bus_device(dev); |
121 | /* | 109 | /* |
122 | * Ensure that no new Requests will be generated from | 110 | * Ensure that no new Requests will be generated from |
123 | * the device. | 111 | * the device. |
124 | */ | 112 | */ |
125 | if (presence) { | 113 | if (presence) { |
126 | pci_read_config_word(temp, PCI_COMMAND, &command); | 114 | pci_read_config_word(dev, PCI_COMMAND, &command); |
127 | command &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_SERR); | 115 | command &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_SERR); |
128 | command |= PCI_COMMAND_INTX_DISABLE; | 116 | command |= PCI_COMMAND_INTX_DISABLE; |
129 | pci_write_config_word(temp, PCI_COMMAND, command); | 117 | pci_write_config_word(dev, PCI_COMMAND, command); |
130 | } | 118 | } |
131 | pci_dev_put(temp); | 119 | pci_dev_put(dev); |
132 | } | 120 | } |
133 | 121 | ||
134 | return rc; | 122 | return rc; |
diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c index 574421bc2fa6..b2781dfe60e9 100644 --- a/drivers/pci/hotplug/sgi_hotplug.c +++ b/drivers/pci/hotplug/sgi_hotplug.c | |||
@@ -334,7 +334,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) | |||
334 | struct slot *slot = bss_hotplug_slot->private; | 334 | struct slot *slot = bss_hotplug_slot->private; |
335 | struct pci_bus *new_bus = NULL; | 335 | struct pci_bus *new_bus = NULL; |
336 | struct pci_dev *dev; | 336 | struct pci_dev *dev; |
337 | int func, num_funcs; | 337 | int num_funcs; |
338 | int new_ppb = 0; | 338 | int new_ppb = 0; |
339 | int rc; | 339 | int rc; |
340 | char *ssdt = NULL; | 340 | char *ssdt = NULL; |
@@ -381,29 +381,26 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) | |||
381 | * to the Linux PCI interface and tell the drivers | 381 | * to the Linux PCI interface and tell the drivers |
382 | * about them. | 382 | * about them. |
383 | */ | 383 | */ |
384 | for (func = 0; func < num_funcs; func++) { | 384 | list_for_each_entry(dev, &slot->pci_bus->devices, bus_list) { |
385 | dev = pci_get_slot(slot->pci_bus, | 385 | if (PCI_SLOT(dev->devfn) != slot->device_num + 1) |
386 | PCI_DEVFN(slot->device_num + 1, | 386 | continue; |
387 | PCI_FUNC(func))); | 387 | |
388 | if (dev) { | 388 | /* Need to do slot fixup on PPB before fixup of children |
389 | /* Need to do slot fixup on PPB before fixup of children | 389 | * (PPB's pcidev_info needs to be in pcidev_info list |
390 | * (PPB's pcidev_info needs to be in pcidev_info list | 390 | * before child's SN_PCIDEV_INFO() call to setup |
391 | * before child's SN_PCIDEV_INFO() call to setup | 391 | * pdi_host_pcidev_info). |
392 | * pdi_host_pcidev_info). | 392 | */ |
393 | */ | 393 | pcibios_fixup_device_resources(dev); |
394 | pcibios_fixup_device_resources(dev); | 394 | if (SN_ACPI_BASE_SUPPORT()) |
395 | if (SN_ACPI_BASE_SUPPORT()) | 395 | sn_acpi_slot_fixup(dev); |
396 | sn_acpi_slot_fixup(dev); | 396 | else |
397 | else | 397 | sn_io_slot_fixup(dev); |
398 | sn_io_slot_fixup(dev); | 398 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { |
399 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { | 399 | pci_hp_add_bridge(dev); |
400 | pci_hp_add_bridge(dev); | 400 | if (dev->subordinate) { |
401 | if (dev->subordinate) { | 401 | new_bus = dev->subordinate; |
402 | new_bus = dev->subordinate; | 402 | new_ppb = 1; |
403 | new_ppb = 1; | ||
404 | } | ||
405 | } | 403 | } |
406 | pci_dev_put(dev); | ||
407 | } | 404 | } |
408 | } | 405 | } |
409 | 406 | ||
@@ -483,8 +480,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) | |||
483 | static int disable_slot(struct hotplug_slot *bss_hotplug_slot) | 480 | static int disable_slot(struct hotplug_slot *bss_hotplug_slot) |
484 | { | 481 | { |
485 | struct slot *slot = bss_hotplug_slot->private; | 482 | struct slot *slot = bss_hotplug_slot->private; |
486 | struct pci_dev *dev; | 483 | struct pci_dev *dev, *temp; |
487 | int func; | ||
488 | int rc; | 484 | int rc; |
489 | acpi_owner_id ssdt_id = 0; | 485 | acpi_owner_id ssdt_id = 0; |
490 | 486 | ||
@@ -545,15 +541,14 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot) | |||
545 | } | 541 | } |
546 | 542 | ||
547 | /* Free the SN resources assigned to the Linux device.*/ | 543 | /* Free the SN resources assigned to the Linux device.*/ |
548 | for (func = 0; func < 8; func++) { | 544 | list_for_each_entry_safe(dev, temp, &slot->pci_bus->devices, bus_list) { |
549 | dev = pci_get_slot(slot->pci_bus, | 545 | if (PCI_SLOT(dev->devfn) != slot->device_num + 1) |
550 | PCI_DEVFN(slot->device_num + 1, | 546 | continue; |
551 | PCI_FUNC(func))); | 547 | |
552 | if (dev) { | 548 | pci_dev_get(dev); |
553 | sn_bus_free_data(dev); | 549 | sn_bus_free_data(dev); |
554 | pci_stop_and_remove_bus_device(dev); | 550 | pci_stop_and_remove_bus_device(dev); |
555 | pci_dev_put(dev); | 551 | pci_dev_put(dev); |
556 | } | ||
557 | } | 552 | } |
558 | 553 | ||
559 | /* Remove the SSDT for the slot from the ACPI namespace */ | 554 | /* Remove the SSDT for the slot from the ACPI namespace */ |
diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c index c627ed9957d1..b0e83132542e 100644 --- a/drivers/pci/hotplug/shpchp_pci.c +++ b/drivers/pci/hotplug/shpchp_pci.c | |||
@@ -40,7 +40,7 @@ int __ref shpchp_configure_device(struct slot *p_slot) | |||
40 | struct controller *ctrl = p_slot->ctrl; | 40 | struct controller *ctrl = p_slot->ctrl; |
41 | struct pci_dev *bridge = ctrl->pci_dev; | 41 | struct pci_dev *bridge = ctrl->pci_dev; |
42 | struct pci_bus *parent = bridge->subordinate; | 42 | struct pci_bus *parent = bridge->subordinate; |
43 | int num, fn; | 43 | int num; |
44 | 44 | ||
45 | dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, 0)); | 45 | dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, 0)); |
46 | if (dev) { | 46 | if (dev) { |
@@ -57,24 +57,20 @@ int __ref shpchp_configure_device(struct slot *p_slot) | |||
57 | return -ENODEV; | 57 | return -ENODEV; |
58 | } | 58 | } |
59 | 59 | ||
60 | for (fn = 0; fn < 8; fn++) { | 60 | list_for_each_entry(dev, &parent->devices, bus_list) { |
61 | dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, fn)); | 61 | if (PCI_SLOT(dev->devfn) != p_slot->device) |
62 | if (!dev) | ||
63 | continue; | 62 | continue; |
64 | if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || | 63 | if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || |
65 | (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) | 64 | (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) |
66 | pci_hp_add_bridge(dev); | 65 | pci_hp_add_bridge(dev); |
67 | pci_dev_put(dev); | ||
68 | } | 66 | } |
69 | 67 | ||
70 | pci_assign_unassigned_bridge_resources(bridge); | 68 | pci_assign_unassigned_bridge_resources(bridge); |
71 | 69 | ||
72 | for (fn = 0; fn < 8; fn++) { | 70 | list_for_each_entry(dev, &parent->devices, bus_list) { |
73 | dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, fn)); | 71 | if (PCI_SLOT(dev->devfn) != p_slot->device) |
74 | if (!dev) | ||
75 | continue; | 72 | continue; |
76 | pci_configure_slot(dev); | 73 | pci_configure_slot(dev); |
77 | pci_dev_put(dev); | ||
78 | } | 74 | } |
79 | 75 | ||
80 | pci_bus_add_devices(parent); | 76 | pci_bus_add_devices(parent); |
@@ -85,32 +81,32 @@ int __ref shpchp_configure_device(struct slot *p_slot) | |||
85 | int shpchp_unconfigure_device(struct slot *p_slot) | 81 | int shpchp_unconfigure_device(struct slot *p_slot) |
86 | { | 82 | { |
87 | int rc = 0; | 83 | int rc = 0; |
88 | int j; | ||
89 | u8 bctl = 0; | 84 | u8 bctl = 0; |
90 | struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate; | 85 | struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate; |
86 | struct pci_dev *dev, *temp; | ||
91 | struct controller *ctrl = p_slot->ctrl; | 87 | struct controller *ctrl = p_slot->ctrl; |
92 | 88 | ||
93 | ctrl_dbg(ctrl, "%s: domain:bus:dev = %04x:%02x:%02x\n", | 89 | ctrl_dbg(ctrl, "%s: domain:bus:dev = %04x:%02x:%02x\n", |
94 | __func__, pci_domain_nr(parent), p_slot->bus, p_slot->device); | 90 | __func__, pci_domain_nr(parent), p_slot->bus, p_slot->device); |
95 | 91 | ||
96 | for (j = 0; j < 8 ; j++) { | 92 | list_for_each_entry_safe(dev, temp, &parent->devices, bus_list) { |
97 | struct pci_dev *temp = pci_get_slot(parent, | 93 | if (PCI_SLOT(dev->devfn) != p_slot->device) |
98 | (p_slot->device << 3) | j); | ||
99 | if (!temp) | ||
100 | continue; | 94 | continue; |
101 | if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE) { | 95 | |
102 | pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, &bctl); | 96 | pci_dev_get(dev); |
97 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { | ||
98 | pci_read_config_byte(dev, PCI_BRIDGE_CONTROL, &bctl); | ||
103 | if (bctl & PCI_BRIDGE_CTL_VGA) { | 99 | if (bctl & PCI_BRIDGE_CTL_VGA) { |
104 | ctrl_err(ctrl, | 100 | ctrl_err(ctrl, |
105 | "Cannot remove display device %s\n", | 101 | "Cannot remove display device %s\n", |
106 | pci_name(temp)); | 102 | pci_name(dev)); |
107 | pci_dev_put(temp); | 103 | pci_dev_put(dev); |
108 | rc = -EINVAL; | 104 | rc = -EINVAL; |
109 | break; | 105 | break; |
110 | } | 106 | } |
111 | } | 107 | } |
112 | pci_stop_and_remove_bus_device(temp); | 108 | pci_stop_and_remove_bus_device(dev); |
113 | pci_dev_put(temp); | 109 | pci_dev_put(dev); |
114 | } | 110 | } |
115 | return rc; | 111 | return rc; |
116 | } | 112 | } |
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index c18e5bf444fa..ee599f274f05 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c | |||
@@ -33,7 +33,6 @@ static inline u8 virtfn_devfn(struct pci_dev *dev, int id) | |||
33 | 33 | ||
34 | static struct pci_bus *virtfn_add_bus(struct pci_bus *bus, int busnr) | 34 | static struct pci_bus *virtfn_add_bus(struct pci_bus *bus, int busnr) |
35 | { | 35 | { |
36 | int rc; | ||
37 | struct pci_bus *child; | 36 | struct pci_bus *child; |
38 | 37 | ||
39 | if (bus->number == busnr) | 38 | if (bus->number == busnr) |
@@ -48,12 +47,7 @@ static struct pci_bus *virtfn_add_bus(struct pci_bus *bus, int busnr) | |||
48 | return NULL; | 47 | return NULL; |
49 | 48 | ||
50 | pci_bus_insert_busn_res(child, busnr, busnr); | 49 | pci_bus_insert_busn_res(child, busnr, busnr); |
51 | child->dev.parent = bus->bridge; | 50 | bus->is_added = 1; |
52 | rc = pci_bus_add_child(child); | ||
53 | if (rc) { | ||
54 | pci_remove_bus(child); | ||
55 | return NULL; | ||
56 | } | ||
57 | 51 | ||
58 | return child; | 52 | return child; |
59 | } | 53 | } |
@@ -123,8 +117,6 @@ static int virtfn_add(struct pci_dev *dev, int id, int reset) | |||
123 | virtfn->is_virtfn = 1; | 117 | virtfn->is_virtfn = 1; |
124 | 118 | ||
125 | rc = pci_bus_add_device(virtfn); | 119 | rc = pci_bus_add_device(virtfn); |
126 | if (rc) | ||
127 | goto failed1; | ||
128 | sprintf(buf, "virtfn%u", id); | 120 | sprintf(buf, "virtfn%u", id); |
129 | rc = sysfs_create_link(&dev->dev.kobj, &virtfn->dev.kobj, buf); | 121 | rc = sysfs_create_link(&dev->dev.kobj, &virtfn->dev.kobj, buf); |
130 | if (rc) | 122 | if (rc) |
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index e407c61559ca..39c937f9b426 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
@@ -302,48 +302,11 @@ static int acpi_pci_find_device(struct device *dev, acpi_handle *handle) | |||
302 | return 0; | 302 | return 0; |
303 | } | 303 | } |
304 | 304 | ||
305 | static int acpi_pci_find_root_bridge(struct device *dev, acpi_handle *handle) | ||
306 | { | ||
307 | int num; | ||
308 | unsigned int seg, bus; | ||
309 | |||
310 | /* | ||
311 | * The string should be the same as root bridge's name | ||
312 | * Please look at 'pci_scan_bus_parented' | ||
313 | */ | ||
314 | num = sscanf(dev_name(dev), "pci%04x:%02x", &seg, &bus); | ||
315 | if (num != 2) | ||
316 | return -ENODEV; | ||
317 | *handle = acpi_get_pci_rootbridge_handle(seg, bus); | ||
318 | if (!*handle) | ||
319 | return -ENODEV; | ||
320 | return 0; | ||
321 | } | ||
322 | |||
323 | static void pci_acpi_setup(struct device *dev) | 305 | static void pci_acpi_setup(struct device *dev) |
324 | { | 306 | { |
325 | struct pci_dev *pci_dev = to_pci_dev(dev); | 307 | struct pci_dev *pci_dev = to_pci_dev(dev); |
326 | acpi_handle handle = ACPI_HANDLE(dev); | 308 | acpi_handle handle = ACPI_HANDLE(dev); |
327 | struct acpi_device *adev; | 309 | struct acpi_device *adev; |
328 | acpi_status status; | ||
329 | acpi_handle dummy; | ||
330 | |||
331 | /* | ||
332 | * Evaluate and parse _PRT, if exists. This code allows parsing of | ||
333 | * _PRT objects within the scope of non-bridge devices. Note that | ||
334 | * _PRTs within the scope of a PCI bridge assume the bridge's | ||
335 | * subordinate bus number. | ||
336 | * | ||
337 | * TBD: Can _PRTs exist within the scope of non-bridge PCI devices? | ||
338 | */ | ||
339 | status = acpi_get_handle(handle, METHOD_NAME__PRT, &dummy); | ||
340 | if (ACPI_SUCCESS(status)) { | ||
341 | unsigned char bus; | ||
342 | |||
343 | bus = pci_dev->subordinate ? | ||
344 | pci_dev->subordinate->number : pci_dev->bus->number; | ||
345 | acpi_pci_irq_add_prt(handle, pci_domain_nr(pci_dev->bus), bus); | ||
346 | } | ||
347 | 310 | ||
348 | if (acpi_bus_get_device(handle, &adev) || !adev->wakeup.flags.valid) | 311 | if (acpi_bus_get_device(handle, &adev) || !adev->wakeup.flags.valid) |
349 | return; | 312 | return; |
@@ -358,7 +321,6 @@ static void pci_acpi_setup(struct device *dev) | |||
358 | 321 | ||
359 | static void pci_acpi_cleanup(struct device *dev) | 322 | static void pci_acpi_cleanup(struct device *dev) |
360 | { | 323 | { |
361 | struct pci_dev *pci_dev = to_pci_dev(dev); | ||
362 | acpi_handle handle = ACPI_HANDLE(dev); | 324 | acpi_handle handle = ACPI_HANDLE(dev); |
363 | struct acpi_device *adev; | 325 | struct acpi_device *adev; |
364 | 326 | ||
@@ -367,16 +329,11 @@ static void pci_acpi_cleanup(struct device *dev) | |||
367 | device_set_run_wake(dev, false); | 329 | device_set_run_wake(dev, false); |
368 | pci_acpi_remove_pm_notifier(adev); | 330 | pci_acpi_remove_pm_notifier(adev); |
369 | } | 331 | } |
370 | |||
371 | if (pci_dev->subordinate) | ||
372 | acpi_pci_irq_del_prt(pci_domain_nr(pci_dev->bus), | ||
373 | pci_dev->subordinate->number); | ||
374 | } | 332 | } |
375 | 333 | ||
376 | static struct acpi_bus_type acpi_pci_bus = { | 334 | static struct acpi_bus_type acpi_pci_bus = { |
377 | .bus = &pci_bus_type, | 335 | .bus = &pci_bus_type, |
378 | .find_device = acpi_pci_find_device, | 336 | .find_device = acpi_pci_find_device, |
379 | .find_bridge = acpi_pci_find_root_bridge, | ||
380 | .setup = pci_acpi_setup, | 337 | .setup = pci_acpi_setup, |
381 | .cleanup = pci_acpi_cleanup, | 338 | .cleanup = pci_acpi_cleanup, |
382 | }; | 339 | }; |
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index f79cbcd3944b..1fa1e482a999 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
@@ -392,7 +392,7 @@ static void pci_device_shutdown(struct device *dev) | |||
392 | * Turn off Bus Master bit on the device to tell it to not | 392 | * Turn off Bus Master bit on the device to tell it to not |
393 | * continue to do DMA | 393 | * continue to do DMA |
394 | */ | 394 | */ |
395 | pci_disable_device(pci_dev); | 395 | pci_clear_master(pci_dev); |
396 | } | 396 | } |
397 | 397 | ||
398 | #ifdef CONFIG_PM | 398 | #ifdef CONFIG_PM |
@@ -628,6 +628,7 @@ static int pci_pm_suspend(struct device *dev) | |||
628 | goto Fixup; | 628 | goto Fixup; |
629 | } | 629 | } |
630 | 630 | ||
631 | pci_dev->state_saved = false; | ||
631 | if (pm->suspend) { | 632 | if (pm->suspend) { |
632 | pci_power_t prev = pci_dev->current_state; | 633 | pci_power_t prev = pci_dev->current_state; |
633 | int error; | 634 | int error; |
@@ -774,6 +775,7 @@ static int pci_pm_freeze(struct device *dev) | |||
774 | return 0; | 775 | return 0; |
775 | } | 776 | } |
776 | 777 | ||
778 | pci_dev->state_saved = false; | ||
777 | if (pm->freeze) { | 779 | if (pm->freeze) { |
778 | int error; | 780 | int error; |
779 | 781 | ||
@@ -862,6 +864,7 @@ static int pci_pm_poweroff(struct device *dev) | |||
862 | goto Fixup; | 864 | goto Fixup; |
863 | } | 865 | } |
864 | 866 | ||
867 | pci_dev->state_saved = false; | ||
865 | if (pm->poweroff) { | 868 | if (pm->poweroff) { |
866 | int error; | 869 | int error; |
867 | 870 | ||
@@ -987,6 +990,7 @@ static int pci_pm_runtime_suspend(struct device *dev) | |||
987 | if (!pm || !pm->runtime_suspend) | 990 | if (!pm || !pm->runtime_suspend) |
988 | return -ENOSYS; | 991 | return -ENOSYS; |
989 | 992 | ||
993 | pci_dev->state_saved = false; | ||
990 | pci_dev->no_d3cold = false; | 994 | pci_dev->no_d3cold = false; |
991 | error = pm->runtime_suspend(dev); | 995 | error = pm->runtime_suspend(dev); |
992 | suspend_report_result(pm->runtime_suspend, error); | 996 | suspend_report_result(pm->runtime_suspend, error); |
@@ -1186,9 +1190,13 @@ pci_dev_driver(const struct pci_dev *dev) | |||
1186 | static int pci_bus_match(struct device *dev, struct device_driver *drv) | 1190 | static int pci_bus_match(struct device *dev, struct device_driver *drv) |
1187 | { | 1191 | { |
1188 | struct pci_dev *pci_dev = to_pci_dev(dev); | 1192 | struct pci_dev *pci_dev = to_pci_dev(dev); |
1189 | struct pci_driver *pci_drv = to_pci_driver(drv); | 1193 | struct pci_driver *pci_drv; |
1190 | const struct pci_device_id *found_id; | 1194 | const struct pci_device_id *found_id; |
1191 | 1195 | ||
1196 | if (!pci_dev->match_driver) | ||
1197 | return 0; | ||
1198 | |||
1199 | pci_drv = to_pci_driver(drv); | ||
1192 | found_id = pci_match_device(pci_drv, pci_dev); | 1200 | found_id = pci_match_device(pci_drv, pci_dev); |
1193 | if (found_id) | 1201 | if (found_id) |
1194 | return 1; | 1202 | return 1; |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 0c4f641b7be1..924e4665bd57 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -1151,8 +1151,7 @@ int pci_reenable_device(struct pci_dev *dev) | |||
1151 | return 0; | 1151 | return 0; |
1152 | } | 1152 | } |
1153 | 1153 | ||
1154 | static int __pci_enable_device_flags(struct pci_dev *dev, | 1154 | static int pci_enable_device_flags(struct pci_dev *dev, unsigned long flags) |
1155 | resource_size_t flags) | ||
1156 | { | 1155 | { |
1157 | int err; | 1156 | int err; |
1158 | int i, bars = 0; | 1157 | int i, bars = 0; |
@@ -1169,7 +1168,7 @@ static int __pci_enable_device_flags(struct pci_dev *dev, | |||
1169 | dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK); | 1168 | dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK); |
1170 | } | 1169 | } |
1171 | 1170 | ||
1172 | if (atomic_add_return(1, &dev->enable_cnt) > 1) | 1171 | if (atomic_inc_return(&dev->enable_cnt) > 1) |
1173 | return 0; /* already enabled */ | 1172 | return 0; /* already enabled */ |
1174 | 1173 | ||
1175 | /* only skip sriov related */ | 1174 | /* only skip sriov related */ |
@@ -1196,7 +1195,7 @@ static int __pci_enable_device_flags(struct pci_dev *dev, | |||
1196 | */ | 1195 | */ |
1197 | int pci_enable_device_io(struct pci_dev *dev) | 1196 | int pci_enable_device_io(struct pci_dev *dev) |
1198 | { | 1197 | { |
1199 | return __pci_enable_device_flags(dev, IORESOURCE_IO); | 1198 | return pci_enable_device_flags(dev, IORESOURCE_IO); |
1200 | } | 1199 | } |
1201 | 1200 | ||
1202 | /** | 1201 | /** |
@@ -1209,7 +1208,7 @@ int pci_enable_device_io(struct pci_dev *dev) | |||
1209 | */ | 1208 | */ |
1210 | int pci_enable_device_mem(struct pci_dev *dev) | 1209 | int pci_enable_device_mem(struct pci_dev *dev) |
1211 | { | 1210 | { |
1212 | return __pci_enable_device_flags(dev, IORESOURCE_MEM); | 1211 | return pci_enable_device_flags(dev, IORESOURCE_MEM); |
1213 | } | 1212 | } |
1214 | 1213 | ||
1215 | /** | 1214 | /** |
@@ -1225,7 +1224,7 @@ int pci_enable_device_mem(struct pci_dev *dev) | |||
1225 | */ | 1224 | */ |
1226 | int pci_enable_device(struct pci_dev *dev) | 1225 | int pci_enable_device(struct pci_dev *dev) |
1227 | { | 1226 | { |
1228 | return __pci_enable_device_flags(dev, IORESOURCE_MEM | IORESOURCE_IO); | 1227 | return pci_enable_device_flags(dev, IORESOURCE_MEM | IORESOURCE_IO); |
1229 | } | 1228 | } |
1230 | 1229 | ||
1231 | /* | 1230 | /* |
@@ -1396,7 +1395,10 @@ pci_disable_device(struct pci_dev *dev) | |||
1396 | if (dr) | 1395 | if (dr) |
1397 | dr->enabled = 0; | 1396 | dr->enabled = 0; |
1398 | 1397 | ||
1399 | if (atomic_sub_return(1, &dev->enable_cnt) != 0) | 1398 | dev_WARN_ONCE(&dev->dev, atomic_read(&dev->enable_cnt) <= 0, |
1399 | "disabling already-disabled device"); | ||
1400 | |||
1401 | if (atomic_dec_return(&dev->enable_cnt) != 0) | ||
1400 | return; | 1402 | return; |
1401 | 1403 | ||
1402 | do_pci_disable_device(dev); | 1404 | do_pci_disable_device(dev); |
@@ -2043,10 +2045,13 @@ void pci_free_cap_save_buffers(struct pci_dev *dev) | |||
2043 | } | 2045 | } |
2044 | 2046 | ||
2045 | /** | 2047 | /** |
2046 | * pci_enable_ari - enable ARI forwarding if hardware support it | 2048 | * pci_configure_ari - enable or disable ARI forwarding |
2047 | * @dev: the PCI device | 2049 | * @dev: the PCI device |
2050 | * | ||
2051 | * If @dev and its upstream bridge both support ARI, enable ARI in the | ||
2052 | * bridge. Otherwise, disable ARI in the bridge. | ||
2048 | */ | 2053 | */ |
2049 | void pci_enable_ari(struct pci_dev *dev) | 2054 | void pci_configure_ari(struct pci_dev *dev) |
2050 | { | 2055 | { |
2051 | u32 cap; | 2056 | u32 cap; |
2052 | struct pci_dev *bridge; | 2057 | struct pci_dev *bridge; |
@@ -2054,9 +2059,6 @@ void pci_enable_ari(struct pci_dev *dev) | |||
2054 | if (pcie_ari_disabled || !pci_is_pcie(dev) || dev->devfn) | 2059 | if (pcie_ari_disabled || !pci_is_pcie(dev) || dev->devfn) |
2055 | return; | 2060 | return; |
2056 | 2061 | ||
2057 | if (!pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI)) | ||
2058 | return; | ||
2059 | |||
2060 | bridge = dev->bus->self; | 2062 | bridge = dev->bus->self; |
2061 | if (!bridge) | 2063 | if (!bridge) |
2062 | return; | 2064 | return; |
@@ -2065,8 +2067,15 @@ void pci_enable_ari(struct pci_dev *dev) | |||
2065 | if (!(cap & PCI_EXP_DEVCAP2_ARI)) | 2067 | if (!(cap & PCI_EXP_DEVCAP2_ARI)) |
2066 | return; | 2068 | return; |
2067 | 2069 | ||
2068 | pcie_capability_set_word(bridge, PCI_EXP_DEVCTL2, PCI_EXP_DEVCTL2_ARI); | 2070 | if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI)) { |
2069 | bridge->ari_enabled = 1; | 2071 | pcie_capability_set_word(bridge, PCI_EXP_DEVCTL2, |
2072 | PCI_EXP_DEVCTL2_ARI); | ||
2073 | bridge->ari_enabled = 1; | ||
2074 | } else { | ||
2075 | pcie_capability_clear_word(bridge, PCI_EXP_DEVCTL2, | ||
2076 | PCI_EXP_DEVCTL2_ARI); | ||
2077 | bridge->ari_enabled = 0; | ||
2078 | } | ||
2070 | } | 2079 | } |
2071 | 2080 | ||
2072 | /** | 2081 | /** |
@@ -3742,18 +3751,6 @@ resource_size_t pci_specified_resource_alignment(struct pci_dev *dev) | |||
3742 | return align; | 3751 | return align; |
3743 | } | 3752 | } |
3744 | 3753 | ||
3745 | /** | ||
3746 | * pci_is_reassigndev - check if specified PCI is target device to reassign | ||
3747 | * @dev: the PCI device to check | ||
3748 | * | ||
3749 | * RETURNS: non-zero for PCI device is a target device to reassign, | ||
3750 | * or zero is not. | ||
3751 | */ | ||
3752 | int pci_is_reassigndev(struct pci_dev *dev) | ||
3753 | { | ||
3754 | return (pci_specified_resource_alignment(dev) != 0); | ||
3755 | } | ||
3756 | |||
3757 | /* | 3754 | /* |
3758 | * This function disables memory decoding and releases memory resources | 3755 | * This function disables memory decoding and releases memory resources |
3759 | * of the device specified by kernel's boot parameter 'pci=resource_alignment='. | 3756 | * of the device specified by kernel's boot parameter 'pci=resource_alignment='. |
@@ -3768,7 +3765,9 @@ void pci_reassigndev_resource_alignment(struct pci_dev *dev) | |||
3768 | resource_size_t align, size; | 3765 | resource_size_t align, size; |
3769 | u16 command; | 3766 | u16 command; |
3770 | 3767 | ||
3771 | if (!pci_is_reassigndev(dev)) | 3768 | /* check if specified PCI is target device to reassign */ |
3769 | align = pci_specified_resource_alignment(dev); | ||
3770 | if (!align) | ||
3772 | return; | 3771 | return; |
3773 | 3772 | ||
3774 | if (dev->hdr_type == PCI_HEADER_TYPE_NORMAL && | 3773 | if (dev->hdr_type == PCI_HEADER_TYPE_NORMAL && |
@@ -3784,7 +3783,6 @@ void pci_reassigndev_resource_alignment(struct pci_dev *dev) | |||
3784 | command &= ~PCI_COMMAND_MEMORY; | 3783 | command &= ~PCI_COMMAND_MEMORY; |
3785 | pci_write_config_word(dev, PCI_COMMAND, command); | 3784 | pci_write_config_word(dev, PCI_COMMAND, command); |
3786 | 3785 | ||
3787 | align = pci_specified_resource_alignment(dev); | ||
3788 | for (i = 0; i < PCI_BRIDGE_RESOURCES; i++) { | 3786 | for (i = 0; i < PCI_BRIDGE_RESOURCES; i++) { |
3789 | r = &dev->resource[i]; | 3787 | r = &dev->resource[i]; |
3790 | if (!(r->flags & IORESOURCE_MEM)) | 3788 | if (!(r->flags & IORESOURCE_MEM)) |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index adfd172c5b9b..7346ee68f47d 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -203,8 +203,8 @@ extern int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
203 | struct resource *res, unsigned int reg); | 203 | struct resource *res, unsigned int reg); |
204 | extern int pci_resource_bar(struct pci_dev *dev, int resno, | 204 | extern int pci_resource_bar(struct pci_dev *dev, int resno, |
205 | enum pci_bar_type *type); | 205 | enum pci_bar_type *type); |
206 | extern int pci_bus_add_child(struct pci_bus *bus); | 206 | extern void pci_configure_ari(struct pci_dev *dev); |
207 | extern void pci_enable_ari(struct pci_dev *dev); | 207 | |
208 | /** | 208 | /** |
209 | * pci_ari_enabled - query ARI forwarding status | 209 | * pci_ari_enabled - query ARI forwarding status |
210 | * @bus: the PCI bus | 210 | * @bus: the PCI bus |
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 8474b6a4fc9b..d320df6375a2 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c | |||
@@ -556,6 +556,9 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev) | |||
556 | struct pcie_link_state *link; | 556 | struct pcie_link_state *link; |
557 | int blacklist = !!pcie_aspm_sanity_check(pdev); | 557 | int blacklist = !!pcie_aspm_sanity_check(pdev); |
558 | 558 | ||
559 | if (!aspm_support_enabled) | ||
560 | return; | ||
561 | |||
559 | if (!pci_is_pcie(pdev) || pdev->link_state) | 562 | if (!pci_is_pcie(pdev) || pdev->link_state) |
560 | return; | 563 | return; |
561 | if (pci_pcie_type(pdev) != PCI_EXP_TYPE_ROOT_PORT && | 564 | if (pci_pcie_type(pdev) != PCI_EXP_TYPE_ROOT_PORT && |
@@ -634,10 +637,7 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev) | |||
634 | struct pci_dev *parent = pdev->bus->self; | 637 | struct pci_dev *parent = pdev->bus->self; |
635 | struct pcie_link_state *link, *root, *parent_link; | 638 | struct pcie_link_state *link, *root, *parent_link; |
636 | 639 | ||
637 | if (!pci_is_pcie(pdev) || !parent || !parent->link_state) | 640 | if (!parent || !parent->link_state) |
638 | return; | ||
639 | if ((pci_pcie_type(parent) != PCI_EXP_TYPE_ROOT_PORT) && | ||
640 | (pci_pcie_type(parent) != PCI_EXP_TYPE_DOWNSTREAM)) | ||
641 | return; | 641 | return; |
642 | 642 | ||
643 | down_read(&pci_bus_sem); | 643 | down_read(&pci_bus_sem); |
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index b42133afca98..31063ac30992 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c | |||
@@ -272,7 +272,7 @@ static int get_port_device_capability(struct pci_dev *dev) | |||
272 | 272 | ||
273 | /* Hot-Plug Capable */ | 273 | /* Hot-Plug Capable */ |
274 | if ((cap_mask & PCIE_PORT_SERVICE_HP) && | 274 | if ((cap_mask & PCIE_PORT_SERVICE_HP) && |
275 | dev->pcie_flags_reg & PCI_EXP_FLAGS_SLOT) { | 275 | pcie_caps_reg(dev) & PCI_EXP_FLAGS_SLOT) { |
276 | pcie_capability_read_dword(dev, PCI_EXP_SLTCAP, ®32); | 276 | pcie_capability_read_dword(dev, PCI_EXP_SLTCAP, ®32); |
277 | if (reg32 & PCI_EXP_SLTCAP_HPC) { | 277 | if (reg32 & PCI_EXP_SLTCAP_HPC) { |
278 | services |= PCIE_PORT_SERVICE_HP; | 278 | services |= PCIE_PORT_SERVICE_HP; |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 2dcd22d9c816..b494066ef32f 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -623,6 +623,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, | |||
623 | { | 623 | { |
624 | struct pci_bus *child; | 624 | struct pci_bus *child; |
625 | int i; | 625 | int i; |
626 | int ret; | ||
626 | 627 | ||
627 | /* | 628 | /* |
628 | * Allocate a new bus, and inherit stuff from the parent.. | 629 | * Allocate a new bus, and inherit stuff from the parent.. |
@@ -637,8 +638,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, | |||
637 | child->bus_flags = parent->bus_flags; | 638 | child->bus_flags = parent->bus_flags; |
638 | 639 | ||
639 | /* initialize some portions of the bus device, but don't register it | 640 | /* initialize some portions of the bus device, but don't register it |
640 | * now as the parent is not properly set up yet. This device will get | 641 | * now as the parent is not properly set up yet. |
641 | * registered later in pci_bus_add_devices() | ||
642 | */ | 642 | */ |
643 | child->dev.class = &pcibus_class; | 643 | child->dev.class = &pcibus_class; |
644 | dev_set_name(&child->dev, "%04x:%02x", pci_domain_nr(child), busnr); | 644 | dev_set_name(&child->dev, "%04x:%02x", pci_domain_nr(child), busnr); |
@@ -651,11 +651,14 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, | |||
651 | child->primary = parent->busn_res.start; | 651 | child->primary = parent->busn_res.start; |
652 | child->busn_res.end = 0xff; | 652 | child->busn_res.end = 0xff; |
653 | 653 | ||
654 | if (!bridge) | 654 | if (!bridge) { |
655 | return child; | 655 | child->dev.parent = parent->bridge; |
656 | goto add_dev; | ||
657 | } | ||
656 | 658 | ||
657 | child->self = bridge; | 659 | child->self = bridge; |
658 | child->bridge = get_device(&bridge->dev); | 660 | child->bridge = get_device(&bridge->dev); |
661 | child->dev.parent = child->bridge; | ||
659 | pci_set_bus_of_node(child); | 662 | pci_set_bus_of_node(child); |
660 | pci_set_bus_speed(child); | 663 | pci_set_bus_speed(child); |
661 | 664 | ||
@@ -666,6 +669,13 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, | |||
666 | } | 669 | } |
667 | bridge->subordinate = child; | 670 | bridge->subordinate = child; |
668 | 671 | ||
672 | add_dev: | ||
673 | ret = device_register(&child->dev); | ||
674 | WARN_ON(ret < 0); | ||
675 | |||
676 | /* Create legacy_io and legacy_mem files for this bus */ | ||
677 | pci_create_legacy_files(child); | ||
678 | |||
669 | return child; | 679 | return child; |
670 | } | 680 | } |
671 | 681 | ||
@@ -1285,7 +1295,7 @@ static void pci_init_capabilities(struct pci_dev *dev) | |||
1285 | pci_vpd_pci22_init(dev); | 1295 | pci_vpd_pci22_init(dev); |
1286 | 1296 | ||
1287 | /* Alternative Routing-ID Forwarding */ | 1297 | /* Alternative Routing-ID Forwarding */ |
1288 | pci_enable_ari(dev); | 1298 | pci_configure_ari(dev); |
1289 | 1299 | ||
1290 | /* Single Root I/O Virtualization */ | 1300 | /* Single Root I/O Virtualization */ |
1291 | pci_iov_init(dev); | 1301 | pci_iov_init(dev); |
@@ -1296,10 +1306,12 @@ static void pci_init_capabilities(struct pci_dev *dev) | |||
1296 | 1306 | ||
1297 | void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) | 1307 | void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) |
1298 | { | 1308 | { |
1309 | int ret; | ||
1310 | |||
1299 | device_initialize(&dev->dev); | 1311 | device_initialize(&dev->dev); |
1300 | dev->dev.release = pci_release_dev; | 1312 | dev->dev.release = pci_release_dev; |
1301 | pci_dev_get(dev); | ||
1302 | 1313 | ||
1314 | set_dev_node(&dev->dev, pcibus_to_node(bus)); | ||
1303 | dev->dev.dma_mask = &dev->dma_mask; | 1315 | dev->dev.dma_mask = &dev->dma_mask; |
1304 | dev->dev.dma_parms = &dev->dma_parms; | 1316 | dev->dev.dma_parms = &dev->dma_parms; |
1305 | dev->dev.coherent_dma_mask = 0xffffffffull; | 1317 | dev->dev.coherent_dma_mask = 0xffffffffull; |
@@ -1326,6 +1338,17 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) | |||
1326 | down_write(&pci_bus_sem); | 1338 | down_write(&pci_bus_sem); |
1327 | list_add_tail(&dev->bus_list, &bus->devices); | 1339 | list_add_tail(&dev->bus_list, &bus->devices); |
1328 | up_write(&pci_bus_sem); | 1340 | up_write(&pci_bus_sem); |
1341 | |||
1342 | pci_fixup_device(pci_fixup_final, dev); | ||
1343 | ret = pcibios_add_device(dev); | ||
1344 | WARN_ON(ret < 0); | ||
1345 | |||
1346 | /* Notifier could use PCI capabilities */ | ||
1347 | dev->match_driver = false; | ||
1348 | ret = device_add(&dev->dev); | ||
1349 | WARN_ON(ret < 0); | ||
1350 | |||
1351 | pci_proc_attach_device(dev); | ||
1329 | } | 1352 | } |
1330 | 1353 | ||
1331 | struct pci_dev *__ref pci_scan_single_device(struct pci_bus *bus, int devfn) | 1354 | struct pci_dev *__ref pci_scan_single_device(struct pci_bus *bus, int devfn) |
@@ -1348,31 +1371,31 @@ struct pci_dev *__ref pci_scan_single_device(struct pci_bus *bus, int devfn) | |||
1348 | } | 1371 | } |
1349 | EXPORT_SYMBOL(pci_scan_single_device); | 1372 | EXPORT_SYMBOL(pci_scan_single_device); |
1350 | 1373 | ||
1351 | static unsigned next_ari_fn(struct pci_dev *dev, unsigned fn) | 1374 | static unsigned next_fn(struct pci_bus *bus, struct pci_dev *dev, unsigned fn) |
1352 | { | 1375 | { |
1353 | u16 cap; | 1376 | int pos; |
1354 | unsigned pos, next_fn; | 1377 | u16 cap = 0; |
1378 | unsigned next_fn; | ||
1355 | 1379 | ||
1356 | if (!dev) | 1380 | if (pci_ari_enabled(bus)) { |
1357 | return 0; | 1381 | if (!dev) |
1382 | return 0; | ||
1383 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI); | ||
1384 | if (!pos) | ||
1385 | return 0; | ||
1358 | 1386 | ||
1359 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI); | 1387 | pci_read_config_word(dev, pos + PCI_ARI_CAP, &cap); |
1360 | if (!pos) | 1388 | next_fn = PCI_ARI_CAP_NFN(cap); |
1361 | return 0; | 1389 | if (next_fn <= fn) |
1362 | pci_read_config_word(dev, pos + 4, &cap); | 1390 | return 0; /* protect against malformed list */ |
1363 | next_fn = cap >> 8; | ||
1364 | if (next_fn <= fn) | ||
1365 | return 0; | ||
1366 | return next_fn; | ||
1367 | } | ||
1368 | 1391 | ||
1369 | static unsigned next_trad_fn(struct pci_dev *dev, unsigned fn) | 1392 | return next_fn; |
1370 | { | 1393 | } |
1371 | return (fn + 1) % 8; | 1394 | |
1372 | } | 1395 | /* dev may be NULL for non-contiguous multifunction devices */ |
1396 | if (!dev || dev->multifunction) | ||
1397 | return (fn + 1) % 8; | ||
1373 | 1398 | ||
1374 | static unsigned no_next_fn(struct pci_dev *dev, unsigned fn) | ||
1375 | { | ||
1376 | return 0; | 1399 | return 0; |
1377 | } | 1400 | } |
1378 | 1401 | ||
@@ -1405,7 +1428,6 @@ int pci_scan_slot(struct pci_bus *bus, int devfn) | |||
1405 | { | 1428 | { |
1406 | unsigned fn, nr = 0; | 1429 | unsigned fn, nr = 0; |
1407 | struct pci_dev *dev; | 1430 | struct pci_dev *dev; |
1408 | unsigned (*next_fn)(struct pci_dev *, unsigned) = no_next_fn; | ||
1409 | 1431 | ||
1410 | if (only_one_child(bus) && (devfn > 0)) | 1432 | if (only_one_child(bus) && (devfn > 0)) |
1411 | return 0; /* Already scanned the entire slot */ | 1433 | return 0; /* Already scanned the entire slot */ |
@@ -1416,12 +1438,7 @@ int pci_scan_slot(struct pci_bus *bus, int devfn) | |||
1416 | if (!dev->is_added) | 1438 | if (!dev->is_added) |
1417 | nr++; | 1439 | nr++; |
1418 | 1440 | ||
1419 | if (pci_ari_enabled(bus)) | 1441 | for (fn = next_fn(bus, dev, 0); fn > 0; fn = next_fn(bus, dev, fn)) { |
1420 | next_fn = next_ari_fn; | ||
1421 | else if (dev->multifunction) | ||
1422 | next_fn = next_trad_fn; | ||
1423 | |||
1424 | for (fn = next_fn(dev, 0); fn > 0; fn = next_fn(dev, fn)) { | ||
1425 | dev = pci_scan_single_device(bus, devfn + fn); | 1442 | dev = pci_scan_single_device(bus, devfn + fn); |
1426 | if (dev) { | 1443 | if (dev) { |
1427 | if (!dev->is_added) | 1444 | if (!dev->is_added) |
@@ -1632,6 +1649,18 @@ unsigned int pci_scan_child_bus(struct pci_bus *bus) | |||
1632 | return max; | 1649 | return max; |
1633 | } | 1650 | } |
1634 | 1651 | ||
1652 | /** | ||
1653 | * pcibios_root_bridge_prepare - Platform-specific host bridge setup. | ||
1654 | * @bridge: Host bridge to set up. | ||
1655 | * | ||
1656 | * Default empty implementation. Replace with an architecture-specific setup | ||
1657 | * routine, if necessary. | ||
1658 | */ | ||
1659 | int __weak pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) | ||
1660 | { | ||
1661 | return 0; | ||
1662 | } | ||
1663 | |||
1635 | struct pci_bus *pci_create_root_bus(struct device *parent, int bus, | 1664 | struct pci_bus *pci_create_root_bus(struct device *parent, int bus, |
1636 | struct pci_ops *ops, void *sysdata, struct list_head *resources) | 1665 | struct pci_ops *ops, void *sysdata, struct list_head *resources) |
1637 | { | 1666 | { |
@@ -1644,13 +1673,13 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, | |||
1644 | char bus_addr[64]; | 1673 | char bus_addr[64]; |
1645 | char *fmt; | 1674 | char *fmt; |
1646 | 1675 | ||
1647 | |||
1648 | b = pci_alloc_bus(); | 1676 | b = pci_alloc_bus(); |
1649 | if (!b) | 1677 | if (!b) |
1650 | return NULL; | 1678 | return NULL; |
1651 | 1679 | ||
1652 | b->sysdata = sysdata; | 1680 | b->sysdata = sysdata; |
1653 | b->ops = ops; | 1681 | b->ops = ops; |
1682 | b->number = b->busn_res.start = bus; | ||
1654 | b2 = pci_find_bus(pci_domain_nr(b), bus); | 1683 | b2 = pci_find_bus(pci_domain_nr(b), bus); |
1655 | if (b2) { | 1684 | if (b2) { |
1656 | /* If we already got to this bus through a different bridge, ignore it */ | 1685 | /* If we already got to this bus through a different bridge, ignore it */ |
@@ -1665,6 +1694,10 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, | |||
1665 | bridge->dev.parent = parent; | 1694 | bridge->dev.parent = parent; |
1666 | bridge->dev.release = pci_release_bus_bridge_dev; | 1695 | bridge->dev.release = pci_release_bus_bridge_dev; |
1667 | dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus); | 1696 | dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus); |
1697 | error = pcibios_root_bridge_prepare(bridge); | ||
1698 | if (error) | ||
1699 | goto bridge_dev_reg_err; | ||
1700 | |||
1668 | error = device_register(&bridge->dev); | 1701 | error = device_register(&bridge->dev); |
1669 | if (error) | 1702 | if (error) |
1670 | goto bridge_dev_reg_err; | 1703 | goto bridge_dev_reg_err; |
@@ -1685,8 +1718,6 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, | |||
1685 | /* Create legacy_io and legacy_mem files for this bus */ | 1718 | /* Create legacy_io and legacy_mem files for this bus */ |
1686 | pci_create_legacy_files(b); | 1719 | pci_create_legacy_files(b); |
1687 | 1720 | ||
1688 | b->number = b->busn_res.start = bus; | ||
1689 | |||
1690 | if (parent) | 1721 | if (parent) |
1691 | dev_info(parent, "PCI host bridge to bus %s\n", dev_name(&b->dev)); | 1722 | dev_info(parent, "PCI host bridge to bus %s\n", dev_name(&b->dev)); |
1692 | else | 1723 | else |
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index 84954a726a94..cc875e6ed159 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c | |||
@@ -24,7 +24,7 @@ static void pci_stop_dev(struct pci_dev *dev) | |||
24 | if (dev->is_added) { | 24 | if (dev->is_added) { |
25 | pci_proc_detach_device(dev); | 25 | pci_proc_detach_device(dev); |
26 | pci_remove_sysfs_dev_files(dev); | 26 | pci_remove_sysfs_dev_files(dev); |
27 | device_unregister(&dev->dev); | 27 | device_del(&dev->dev); |
28 | dev->is_added = 0; | 28 | dev->is_added = 0; |
29 | } | 29 | } |
30 | 30 | ||
@@ -39,7 +39,7 @@ static void pci_destroy_dev(struct pci_dev *dev) | |||
39 | up_write(&pci_bus_sem); | 39 | up_write(&pci_bus_sem); |
40 | 40 | ||
41 | pci_free_resources(dev); | 41 | pci_free_resources(dev); |
42 | pci_dev_put(dev); | 42 | put_device(&dev->dev); |
43 | } | 43 | } |
44 | 44 | ||
45 | void pci_remove_bus(struct pci_bus *bus) | 45 | void pci_remove_bus(struct pci_bus *bus) |
diff --git a/drivers/pci/search.c b/drivers/pci/search.c index bf969ba58e59..d0627fa9f368 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c | |||
@@ -319,13 +319,13 @@ int pci_dev_present(const struct pci_device_id *ids) | |||
319 | WARN_ON(in_interrupt()); | 319 | WARN_ON(in_interrupt()); |
320 | while (ids->vendor || ids->subvendor || ids->class_mask) { | 320 | while (ids->vendor || ids->subvendor || ids->class_mask) { |
321 | found = pci_get_dev_by_id(ids, NULL); | 321 | found = pci_get_dev_by_id(ids, NULL); |
322 | if (found) | 322 | if (found) { |
323 | goto exit; | 323 | pci_dev_put(found); |
324 | return 1; | ||
325 | } | ||
324 | ids++; | 326 | ids++; |
325 | } | 327 | } |
326 | exit: | 328 | |
327 | if (found) | ||
328 | return 1; | ||
329 | return 0; | 329 | return 0; |
330 | } | 330 | } |
331 | EXPORT_SYMBOL(pci_dev_present); | 331 | EXPORT_SYMBOL(pci_dev_present); |
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 6d3591d57ea0..7e8739e25b9e 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
@@ -283,7 +283,7 @@ static void assign_requested_resources_sorted(struct list_head *head, | |||
283 | idx = res - &dev_res->dev->resource[0]; | 283 | idx = res - &dev_res->dev->resource[0]; |
284 | if (resource_size(res) && | 284 | if (resource_size(res) && |
285 | pci_assign_resource(dev_res->dev, idx)) { | 285 | pci_assign_resource(dev_res->dev, idx)) { |
286 | if (fail_head && !pci_is_root_bus(dev_res->dev->bus)) { | 286 | if (fail_head) { |
287 | /* | 287 | /* |
288 | * if the failed res is for ROM BAR, and it will | 288 | * if the failed res is for ROM BAR, and it will |
289 | * be enabled later, don't add it to the list | 289 | * be enabled later, don't add it to the list |