aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c32
1 files changed, 25 insertions, 7 deletions
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 1971d2943de4..9d6e535e74a1 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -528,6 +528,16 @@ static void check_hotplug_bridge(struct acpiphp_slot *slot, struct pci_dev *dev)
528 } 528 }
529} 529}
530 530
531static int acpiphp_rescan_slot(struct acpiphp_slot *slot)
532{
533 struct acpiphp_func *func;
534
535 list_for_each_entry(func, &slot->funcs, sibling)
536 acpiphp_bus_add(func_to_handle(func));
537
538 return pci_scan_slot(slot->bus, PCI_DEVFN(slot->device, 0));
539}
540
531/** 541/**
532 * enable_slot - enable, configure a slot 542 * enable_slot - enable, configure a slot
533 * @slot: slot to be enabled 543 * @slot: slot to be enabled
@@ -544,10 +554,7 @@ static void __ref enable_slot(struct acpiphp_slot *slot)
544 LIST_HEAD(add_list); 554 LIST_HEAD(add_list);
545 int nr_found; 555 int nr_found;
546 556
547 list_for_each_entry(func, &slot->funcs, sibling) 557 nr_found = acpiphp_rescan_slot(slot);
548 acpiphp_bus_add(func_to_handle(func));
549
550 nr_found = pci_scan_slot(bus, PCI_DEVFN(slot->device, 0));
551 max = acpiphp_max_busnr(bus); 558 max = acpiphp_max_busnr(bus);
552 for (pass = 0; pass < 2; pass++) { 559 for (pass = 0; pass < 2; pass++) {
553 list_for_each_entry(dev, &bus->devices, bus_list) { 560 list_for_each_entry(dev, &bus->devices, bus_list) {
@@ -840,11 +847,22 @@ static void hotplug_event(acpi_handle handle, u32 type, void *data)
840 case ACPI_NOTIFY_DEVICE_CHECK: 847 case ACPI_NOTIFY_DEVICE_CHECK:
841 /* device check */ 848 /* device check */
842 dbg("%s: Device check notify on %s\n", __func__, objname); 849 dbg("%s: Device check notify on %s\n", __func__, objname);
843 if (bridge) 850 if (bridge) {
844 acpiphp_check_bridge(bridge); 851 acpiphp_check_bridge(bridge);
845 else 852 } else {
846 acpiphp_check_bridge(func->parent); 853 struct acpiphp_slot *slot = func->slot;
854 int ret;
847 855
856 /*
857 * Check if anything has changed in the slot and rescan
858 * from the parent if that's the case.
859 */
860 mutex_lock(&slot->crit_sect);
861 ret = acpiphp_rescan_slot(slot);
862 mutex_unlock(&slot->crit_sect);
863 if (ret)
864 acpiphp_check_bridge(func->parent);
865 }
848 break; 866 break;
849 867
850 case ACPI_NOTIFY_EJECT_REQUEST: 868 case ACPI_NOTIFY_EJECT_REQUEST: