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/pci/hotplug | |
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/pci/hotplug')
-rw-r--r-- | drivers/pci/hotplug/acpiphp.h | 14 | ||||
-rw-r--r-- | drivers/pci/hotplug/acpiphp_core.c | 23 | ||||
-rw-r--r-- | drivers/pci/hotplug/acpiphp_glue.c | 266 | ||||
-rw-r--r-- | drivers/pci/hotplug/cpci_hotplug_pci.c | 29 | ||||
-rw-r--r-- | drivers/pci/hotplug/cpqphp_ctrl.c | 57 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_core.c | 2 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_pci.c | 44 | ||||
-rw-r--r-- | drivers/pci/hotplug/sgi_hotplug.c | 63 | ||||
-rw-r--r-- | drivers/pci/hotplug/shpchp_pci.c | 36 |
9 files changed, 151 insertions, 383 deletions
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 | } |