aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-09-12 14:22:45 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-09-12 14:22:45 -0400
commit02b9735c12892e04d3e101b06e4c6d64a814f566 (patch)
tree7907deb1cbfd1599d4f34d414873170d3266f164 /drivers/pci
parent75acebf2423ab13ff6198daa6e17ef7a2543bfe4 (diff)
parentf1728fd1599112239ed5cebc7be9810264db6792 (diff)
Merge tag 'pm+acpi-fixes-3.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull ACPI and power management fixes from Rafael Wysocki: "All of these commits are fixes that have emerged recently and some of them fix bugs introduced during this merge window. Specifics: 1) ACPI-based PCI hotplug (ACPIPHP) fixes related to spurious events After the recent ACPIPHP changes we've seen some interesting breakage on a system that triggers device check notifications during boot for non-existing devices. Although those notifications are really spurious, we should be able to deal with them nevertheless and that shouldn't introduce too much overhead. Four commits to make that work properly. 2) Memory hotplug and hibernation mutual exclusion rework This was maent to be a cleanup, but it happens to fix a classical ABBA deadlock between system suspend/hibernation and ACPI memory hotplug which is possible if they are started roughly at the same time. Three commits rework memory hotplug so that it doesn't acquire pm_mutex and make hibernation use device_hotplug_lock which prevents it from racing with memory hotplug. 3) ACPI Intel LPSS (Low-Power Subsystem) driver crash fix The ACPI LPSS driver crashes during boot on Apple Macbook Air with Haswell that has slightly unusual BIOS configuration in which one of the LPSS device's _CRS method doesn't return all of the information expected by the driver. Fix from Mika Westerberg, for stable. 4) ACPICA fix related to Store->ArgX operation AML interpreter fix for obscure breakage that causes AML to be executed incorrectly on some machines (observed in practice). From Bob Moore. 5) ACPI core fix for PCI ACPI device objects lookup There still are cases in which there is more than one ACPI device object matching a given PCI device and we don't choose the one that the BIOS expects us to choose, so this makes the lookup take more criteria into account in those cases. 6) Fix to prevent cpuidle from crashing in some rare cases If the result of cpuidle_get_driver() is NULL, which can happen on some systems, cpuidle_driver_ref() will crash trying to use that pointer and the Daniel Fu's fix prevents that from happening. 7) cpufreq fixes related to CPU hotplug Stephen Boyd reported a number of concurrency problems with cpufreq related to CPU hotplug which are addressed by a series of fixes from Srivatsa S Bhat and Viresh Kumar. 8) cpufreq fix for time conversion in time_in_state attribute Time conversion carried out by cpufreq when user space attempts to read /sys/devices/system/cpu/cpu*/cpufreq/stats/time_in_state won't work correcty if cputime_t doesn't map directly to jiffies. Fix from Andreas Schwab. 9) Revert of a troublesome cpufreq commit Commit 7c30ed5 (cpufreq: make sure frequency transitions are serialized) was intended to address some known concurrency problems in cpufreq related to the ordering of transitions, but unfortunately it introduced several problems of its own, so I decided to revert it now and address the original problems later in a more robust way. 10) Intel Haswell CPU models for intel_pstate from Nell Hardcastle. 11) cpufreq fixes related to system suspend/resume The recent cpufreq changes that made it preserve CPU sysfs attributes over suspend/resume cycles introduced a possible NULL pointer dereference that caused it to crash during the second attempt to suspend. Three commits from Srivatsa S Bhat fix that problem and a couple of related issues. 12) cpufreq locking fix cpufreq_policy_restore() should acquire the lock for reading, but it acquires it for writing. Fix from Lan Tianyu" * tag 'pm+acpi-fixes-3.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (25 commits) cpufreq: Acquire the lock in cpufreq_policy_restore() for reading cpufreq: Prevent problems in update_policy_cpu() if last_cpu == new_cpu cpufreq: Restructure if/else block to avoid unintended behavior cpufreq: Fix crash in cpufreq-stats during suspend/resume intel_pstate: Add Haswell CPU models Revert "cpufreq: make sure frequency transitions are serialized" cpufreq: Use signed type for 'ret' variable, to store negative error values cpufreq: Remove temporary fix for race between CPU hotplug and sysfs-writes cpufreq: Synchronize the cpufreq store_*() routines with CPU hotplug cpufreq: Invoke __cpufreq_remove_dev_finish() after releasing cpu_hotplug.lock cpufreq: Split __cpufreq_remove_dev() into two parts cpufreq: Fix wrong time unit conversion cpufreq: serialize calls to __cpufreq_governor() cpufreq: don't allow governor limits to be changed when it is disabled ACPI / bind: Prefer device objects with _STA to those without it 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 ACPICA: Fix for a Store->ArgX when ArgX contains a reference to a field. ACPI / hotplug / PCI: Don't trim devices before scanning the namespace ...
Diffstat (limited to 'drivers/pci')
-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/*