diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-12 16:14:19 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-12 16:14:19 -0400 |
commit | 19c1940feab777bb037c665a09f495d08a6c4e6c (patch) | |
tree | 68d4de31f30c9d69a1f1ea080b8a69ce61e1ead5 /drivers/pci | |
parent | 7c574cf6aeb75920ba4d3af937bb1b3c42785ac4 (diff) | |
parent | d715a226b0b3dae48865d05e8c36175a8f75a809 (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.h | 10 | ||||
-rw-r--r-- | drivers/pci/hotplug/acpiphp_glue.c | 60 |
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 | ||
145 | struct acpiphp_root_context { | ||
146 | struct acpi_hotplug_context hp; | ||
147 | struct acpiphp_bridge *root_bridge; | ||
148 | }; | ||
149 | |||
150 | static 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 | ||
374 | static struct acpiphp_bridge *acpiphp_dev_to_bridge(struct acpi_device *adev) | 374 | static 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 | |||
932 | void 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 | ||