aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-09-10 17:15:02 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-09-10 17:15:02 -0400
commit08e97ff2779ffd3e6eb05d28bafdbc1fbb531d20 (patch)
treeccb6de2eb69a1f6260cc9b7d442be2c394a80dda
parent85fb0a1c35d86ed9a4de8d6cba79ba0801f7a1f7 (diff)
parenta47d8c8e72a5fa2e69117674c4b0b6cc79c5bc53 (diff)
Merge branch 'acpi-pci-hotplug'
* acpi-pci-hotplug: ACPI / hotplug / PCI: Avoid parent bus rescans on spurious device checks ACPI / hotplug / PCI: Use _OST to notify firmware about notify status ACPI / hotplug / PCI: Avoid doing too much for spurious notifies ACPI / hotplug / PCI: Don't trim devices before scanning the namespace
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c61
1 files changed, 47 insertions, 14 deletions
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index f6488adf3af1..0b7d23b4ad95 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -487,7 +487,6 @@ static void acpiphp_bus_add(acpi_handle handle)
487{ 487{
488 struct acpi_device *adev = NULL; 488 struct acpi_device *adev = NULL;
489 489
490 acpiphp_bus_trim(handle);
491 acpi_bus_scan(handle); 490 acpi_bus_scan(handle);
492 acpi_bus_get_device(handle, &adev); 491 acpi_bus_get_device(handle, &adev);
493 if (adev) 492 if (adev)
@@ -529,6 +528,16 @@ static void check_hotplug_bridge(struct acpiphp_slot *slot, struct pci_dev *dev)
529 } 528 }
530} 529}
531 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
532/** 541/**
533 * enable_slot - enable, configure a slot 542 * enable_slot - enable, configure a slot
534 * @slot: slot to be enabled 543 * @slot: slot to be enabled
@@ -543,12 +552,9 @@ static void __ref enable_slot(struct acpiphp_slot *slot)
543 struct acpiphp_func *func; 552 struct acpiphp_func *func;
544 int max, pass; 553 int max, pass;
545 LIST_HEAD(add_list); 554 LIST_HEAD(add_list);
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 pci_scan_slot(bus, PCI_DEVFN(slot->device, 0));
551
552 max = acpiphp_max_busnr(bus); 558 max = acpiphp_max_busnr(bus);
553 for (pass = 0; pass < 2; pass++) { 559 for (pass = 0; pass < 2; pass++) {
554 list_for_each_entry(dev, &bus->devices, bus_list) { 560 list_for_each_entry(dev, &bus->devices, bus_list) {
@@ -567,8 +573,11 @@ static void __ref enable_slot(struct acpiphp_slot *slot)
567 } 573 }
568 } 574 }
569 } 575 }
570
571 __pci_bus_assign_resources(bus, &add_list, NULL); 576 __pci_bus_assign_resources(bus, &add_list, NULL);
577 /* Nothing more to do here if there are no new devices on this bus. */
578 if (!nr_found && (slot->flags & SLOT_ENABLED))
579 return;
580
572 acpiphp_sanitize_bus(bus); 581 acpiphp_sanitize_bus(bus);
573 acpiphp_set_hpp_values(bus); 582 acpiphp_set_hpp_values(bus);
574 acpiphp_set_acpi_region(slot); 583 acpiphp_set_acpi_region(slot);
@@ -837,11 +846,22 @@ static void hotplug_event(acpi_handle handle, u32 type, void *data)
837 case ACPI_NOTIFY_DEVICE_CHECK: 846 case ACPI_NOTIFY_DEVICE_CHECK:
838 /* device check */ 847 /* device check */
839 dbg("%s: Device check notify on %s\n", __func__, objname); 848 dbg("%s: Device check notify on %s\n", __func__, objname);
840 if (bridge) 849 if (bridge) {
841 acpiphp_check_bridge(bridge); 850 acpiphp_check_bridge(bridge);
842 else 851 } else {
843 acpiphp_check_bridge(func->parent); 852 struct acpiphp_slot *slot = func->slot;
853 int ret;
844 854
855 /*
856 * Check if anything has changed in the slot and rescan
857 * from the parent if that's the case.
858 */
859 mutex_lock(&slot->crit_sect);
860 ret = acpiphp_rescan_slot(slot);
861 mutex_unlock(&slot->crit_sect);
862 if (ret)
863 acpiphp_check_bridge(func->parent);
864 }
845 break; 865 break;
846 866
847 case ACPI_NOTIFY_EJECT_REQUEST: 867 case ACPI_NOTIFY_EJECT_REQUEST:
@@ -867,6 +887,8 @@ static void hotplug_event_work(struct work_struct *work)
867 hotplug_event(hp_work->handle, hp_work->type, context); 887 hotplug_event(hp_work->handle, hp_work->type, context);
868 888
869 acpi_scan_lock_release(); 889 acpi_scan_lock_release();
890 acpi_evaluate_hotplug_ost(hp_work->handle, hp_work->type,
891 ACPI_OST_SC_SUCCESS, NULL);
870 kfree(hp_work); /* allocated in handle_hotplug_event() */ 892 kfree(hp_work); /* allocated in handle_hotplug_event() */
871 put_bridge(context->func.parent); 893 put_bridge(context->func.parent);
872} 894}
@@ -882,11 +904,15 @@ static void hotplug_event_work(struct work_struct *work)
882static void handle_hotplug_event(acpi_handle handle, u32 type, void *data) 904static void handle_hotplug_event(acpi_handle handle, u32 type, void *data)
883{ 905{
884 struct acpiphp_context *context; 906 struct acpiphp_context *context;
907 u32 ost_code = ACPI_OST_SC_SUCCESS;
885 908
886 switch (type) { 909 switch (type) {
887 case ACPI_NOTIFY_BUS_CHECK: 910 case ACPI_NOTIFY_BUS_CHECK:
888 case ACPI_NOTIFY_DEVICE_CHECK: 911 case ACPI_NOTIFY_DEVICE_CHECK:
912 break;
889 case ACPI_NOTIFY_EJECT_REQUEST: 913 case ACPI_NOTIFY_EJECT_REQUEST:
914 ost_code = ACPI_OST_SC_EJECT_IN_PROGRESS;
915 acpi_evaluate_hotplug_ost(handle, type, ost_code, NULL);
890 break; 916 break;
891 917
892 case ACPI_NOTIFY_DEVICE_WAKE: 918 case ACPI_NOTIFY_DEVICE_WAKE:
@@ -895,20 +921,21 @@ static void handle_hotplug_event(acpi_handle handle, u32 type, void *data)
895 case ACPI_NOTIFY_FREQUENCY_MISMATCH: 921 case ACPI_NOTIFY_FREQUENCY_MISMATCH:
896 acpi_handle_err(handle, "Device cannot be configured due " 922 acpi_handle_err(handle, "Device cannot be configured due "
897 "to a frequency mismatch\n"); 923 "to a frequency mismatch\n");
898 return; 924 goto out;
899 925
900 case ACPI_NOTIFY_BUS_MODE_MISMATCH: 926 case ACPI_NOTIFY_BUS_MODE_MISMATCH:
901 acpi_handle_err(handle, "Device cannot be configured due " 927 acpi_handle_err(handle, "Device cannot be configured due "
902 "to a bus mode mismatch\n"); 928 "to a bus mode mismatch\n");
903 return; 929 goto out;
904 930
905 case ACPI_NOTIFY_POWER_FAULT: 931 case ACPI_NOTIFY_POWER_FAULT:
906 acpi_handle_err(handle, "Device has suffered a power fault\n"); 932 acpi_handle_err(handle, "Device has suffered a power fault\n");
907 return; 933 goto out;
908 934
909 default: 935 default:
910 acpi_handle_warn(handle, "Unsupported event type 0x%x\n", type); 936 acpi_handle_warn(handle, "Unsupported event type 0x%x\n", type);
911 return; 937 ost_code = ACPI_OST_SC_UNRECOGNIZED_NOTIFY;
938 goto out;
912 } 939 }
913 940
914 mutex_lock(&acpiphp_context_lock); 941 mutex_lock(&acpiphp_context_lock);
@@ -917,8 +944,14 @@ static void handle_hotplug_event(acpi_handle handle, u32 type, void *data)
917 get_bridge(context->func.parent); 944 get_bridge(context->func.parent);
918 acpiphp_put_context(context); 945 acpiphp_put_context(context);
919 alloc_acpi_hp_work(handle, type, context, hotplug_event_work); 946 alloc_acpi_hp_work(handle, type, context, hotplug_event_work);
947 mutex_unlock(&acpiphp_context_lock);
948 return;
920 } 949 }
921 mutex_unlock(&acpiphp_context_lock); 950 mutex_unlock(&acpiphp_context_lock);
951 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE;
952
953 out:
954 acpi_evaluate_hotplug_ost(handle, type, ost_code, NULL);
922} 955}
923 956
924/* 957/*