aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-06-12 16:14:19 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-06-12 16:14:19 -0400
commit19c1940feab777bb037c665a09f495d08a6c4e6c (patch)
tree68d4de31f30c9d69a1f1ea080b8a69ce61e1ead5 /drivers/pci
parent7c574cf6aeb75920ba4d3af937bb1b3c42785ac4 (diff)
parentd715a226b0b3dae48865d05e8c36175a8f75a809 (diff)
Merge tag 'pm+acpi-3.16-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull more ACPI and power management updates from Rafael Wysocki: "These are fixups on top of the previous PM+ACPI pull request, regression fixes (ACPI hotplug, cpufreq ppc-corenet), other bug fixes (ACPI reset, cpufreq), new PM trace points for system suspend profiling and a copyright notice update. Specifics: - I didn't remember correctly that the Hans de Goede's ACPI video patches actually didn't flip the video.use_native_backlight default, although we had discussed that and decided to do that. Since I said we would do that in the previous PM+ACPI pull request, make that change for real now. - ACPI bus check notifications for PCI host bridges don't cause the bus below the host bridge to be checked for changes as they should because of a mistake in the ACPI-based PCI hotplug (ACPIPHP) subsystem that forgets to add hotplug contexts to PCI host bridge ACPI device objects. Create hotplug contexts for PCI host bridges too as appropriate. - Revert recent cpufreq commit related to the big.LITTLE cpufreq driver that breaks arm64 builds. - Fix for a regression in the ppc-corenet cpufreq driver introduced during the 3.15 cycle and causing the driver to use the remainder from do_div instead of the quotient. From Ed Swarthout. - Resets triggered by panic activate a BUG_ON() in vmalloc.c on systems where the ACPI reset register is located in memory address space. Fix from Randy Wright. - Fix for a problem with cpufreq governors that decisions made by them may be suboptimal due to the fact that deferrable timers are used by them for CPU load sampling. From Srivatsa S Bhat. - Fix for a problem with the Tegra cpufreq driver where the CPU frequency is temporarily switched to a "stable" level that is different from both the initial and target frequencies during transitions which causes udelay() to expire earlier than it should sometimes. From Viresh Kumar. - New trace points and rework of some existing trace points for system suspend/resume profiling from Todd Brandt. - Assorted cpufreq fixes and cleanups from Stratos Karafotis and Viresh Kumar. - Copyright notice update for suspend-and-cpuhotplug.txt from Srivatsa S Bhat" * tag 'pm+acpi-3.16-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: ACPI / hotplug / PCI: Add hotplug contexts to PCI host bridges PM / sleep: trace events for device PM callbacks cpufreq: cpufreq-cpu0: remove dependency on THERMAL and REGULATOR cpufreq: tegra: update comment for clarity cpufreq: intel_pstate: Remove duplicate CPU ID check cpufreq: Mark CPU0 driver with CPUFREQ_NEED_INITIAL_FREQ_CHECK flag PM / Documentation: Update copyright in suspend-and-cpuhotplug.txt cpufreq: governor: remove copy_prev_load from 'struct cpu_dbs_common_info' cpufreq: governor: Be friendly towards latency-sensitive bursty workloads PM / sleep: trace events for suspend/resume cpufreq: ppc-corenet-cpu-freq: do_div use quotient Revert "cpufreq: Enable big.LITTLE cpufreq driver on arm64" cpufreq: Tegra: implement intermediate frequency callbacks cpufreq: add support for intermediate (stable) frequencies ACPI / video: Change the default for video.use_native_backlight to 1 ACPI: Fix bug when ACPI reset register is implemented in system memory
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/hotplug/acpiphp.h10
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c60
2 files changed, 52 insertions, 18 deletions
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h
index 2b859249303b..b0e61bf261a7 100644
--- a/drivers/pci/hotplug/acpiphp.h
+++ b/drivers/pci/hotplug/acpiphp.h
@@ -142,6 +142,16 @@ static inline acpi_handle func_to_handle(struct acpiphp_func *func)
142 return func_to_acpi_device(func)->handle; 142 return func_to_acpi_device(func)->handle;
143} 143}
144 144
145struct acpiphp_root_context {
146 struct acpi_hotplug_context hp;
147 struct acpiphp_bridge *root_bridge;
148};
149
150static inline struct acpiphp_root_context *to_acpiphp_root_context(struct acpi_hotplug_context *hp)
151{
152 return container_of(hp, struct acpiphp_root_context, hp);
153}
154
145/* 155/*
146 * struct acpiphp_attention_info - device specific attention registration 156 * struct acpiphp_attention_info - device specific attention registration
147 * 157 *
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 75e178330215..91aa3d780138 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -373,17 +373,13 @@ static acpi_status acpiphp_add_context(acpi_handle handle, u32 lvl, void *data,
373 373
374static struct acpiphp_bridge *acpiphp_dev_to_bridge(struct acpi_device *adev) 374static struct acpiphp_bridge *acpiphp_dev_to_bridge(struct acpi_device *adev)
375{ 375{
376 struct acpiphp_context *context;
377 struct acpiphp_bridge *bridge = NULL; 376 struct acpiphp_bridge *bridge = NULL;
378 377
379 acpi_lock_hp_context(); 378 acpi_lock_hp_context();
380 context = acpiphp_get_context(adev); 379 if (adev->hp) {
381 if (context) { 380 bridge = to_acpiphp_root_context(adev->hp)->root_bridge;
382 bridge = context->bridge;
383 if (bridge) 381 if (bridge)
384 get_bridge(bridge); 382 get_bridge(bridge);
385
386 acpiphp_put_context(context);
387 } 383 }
388 acpi_unlock_hp_context(); 384 acpi_unlock_hp_context();
389 return bridge; 385 return bridge;
@@ -881,7 +877,17 @@ void acpiphp_enumerate_slots(struct pci_bus *bus)
881 */ 877 */
882 get_device(&bus->dev); 878 get_device(&bus->dev);
883 879
884 if (!pci_is_root_bus(bridge->pci_bus)) { 880 acpi_lock_hp_context();
881 if (pci_is_root_bus(bridge->pci_bus)) {
882 struct acpiphp_root_context *root_context;
883
884 root_context = kzalloc(sizeof(*root_context), GFP_KERNEL);
885 if (!root_context)
886 goto err;
887
888 root_context->root_bridge = bridge;
889 acpi_set_hp_context(adev, &root_context->hp, NULL, NULL, NULL);
890 } else {
885 struct acpiphp_context *context; 891 struct acpiphp_context *context;
886 892
887 /* 893 /*
@@ -890,21 +896,16 @@ void acpiphp_enumerate_slots(struct pci_bus *bus)
890 * parent is going to be handled by pciehp, in which case this 896 * parent is going to be handled by pciehp, in which case this
891 * bridge is not interesting to us either. 897 * bridge is not interesting to us either.
892 */ 898 */
893 acpi_lock_hp_context();
894 context = acpiphp_get_context(adev); 899 context = acpiphp_get_context(adev);
895 if (!context) { 900 if (!context)
896 acpi_unlock_hp_context(); 901 goto err;
897 put_device(&bus->dev); 902
898 pci_dev_put(bridge->pci_dev);
899 kfree(bridge);
900 return;
901 }
902 bridge->context = context; 903 bridge->context = context;
903 context->bridge = bridge; 904 context->bridge = bridge;
904 /* Get a reference to the parent bridge. */ 905 /* Get a reference to the parent bridge. */
905 get_bridge(context->func.parent); 906 get_bridge(context->func.parent);
906 acpi_unlock_hp_context();
907 } 907 }
908 acpi_unlock_hp_context();
908 909
909 /* Must be added to the list prior to calling acpiphp_add_context(). */ 910 /* Must be added to the list prior to calling acpiphp_add_context(). */
910 mutex_lock(&bridge_mutex); 911 mutex_lock(&bridge_mutex);
@@ -919,6 +920,30 @@ void acpiphp_enumerate_slots(struct pci_bus *bus)
919 cleanup_bridge(bridge); 920 cleanup_bridge(bridge);
920 put_bridge(bridge); 921 put_bridge(bridge);
921 } 922 }
923 return;
924
925 err:
926 acpi_unlock_hp_context();
927 put_device(&bus->dev);
928 pci_dev_put(bridge->pci_dev);
929 kfree(bridge);
930}
931
932void acpiphp_drop_bridge(struct acpiphp_bridge *bridge)
933{
934 if (pci_is_root_bus(bridge->pci_bus)) {
935 struct acpiphp_root_context *root_context;
936 struct acpi_device *adev;
937
938 acpi_lock_hp_context();
939 adev = ACPI_COMPANION(bridge->pci_bus->bridge);
940 root_context = to_acpiphp_root_context(adev->hp);
941 adev->hp = NULL;
942 acpi_unlock_hp_context();
943 kfree(root_context);
944 }
945 cleanup_bridge(bridge);
946 put_bridge(bridge);
922} 947}
923 948
924/** 949/**
@@ -936,8 +961,7 @@ void acpiphp_remove_slots(struct pci_bus *bus)
936 list_for_each_entry(bridge, &bridge_list, list) 961 list_for_each_entry(bridge, &bridge_list, list)
937 if (bridge->pci_bus == bus) { 962 if (bridge->pci_bus == bus) {
938 mutex_unlock(&bridge_mutex); 963 mutex_unlock(&bridge_mutex);
939 cleanup_bridge(bridge); 964 acpiphp_drop_bridge(bridge);
940 put_bridge(bridge);
941 return; 965 return;
942 } 966 }
943 967