aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-03-14 21:02:02 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-03-14 21:02:02 -0400
commitcee152ff8a3c8aedf7b97417889f9319a7002141 (patch)
treee9e2bbc3a88c5b8947438db1e50273ca1b1b18b7
parent0c01b45257168bc21af88618c75e6aed5b0e6b6d (diff)
parentd5af40d6b34d9d1ba39a27f657948cbce4e0b0e7 (diff)
Merge tag 'pm+acpi-3.14-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull ACPI and power management fixes from Rafael Wysocki: "Three of these are regression fixes, for two recent regressions and one introduced during the 3.13 cycle, and the fourth one is a working version of the fix that had to be reverted last time. Specifics: - A recent ACPI resources handling fix overlooked the fact that it had to update the ACPI PNP subsystem's resources parsing too and caused confusing warning messages to be printed during system intialization on some systems (with arguably buggy ACPI tables). Fix from Zhang Rui. - Moving the early ACPI initialization before timekeeping_init() earlier in this cycle broke fast TSC calibration on at least one system, so it needs to be done later, but still before efi_enter_virtual_mode() to allow the EFI initialization to refer to ACPI. - A change related to code duplication reduction in the cpufreq core inadvertently caused cpufreq intialization to fail for some CPUs handled by intel_pstate by adding checks that may fail for that driver, but aren't even necessary when it is used. The issue is addressed by preventing those checks from run in the configurations in which they aren't needed. - If the Hardware Reduced ACPI flag is set in the ACPI tables, system suspend, hibernation and ACPI power off will only work when special sleep control and sleep status registeres are provided (their addresses in the ACPI tables are not zero). If those registers are not available, the features in question have no chances to work, so they shouldn't even be regarded as supported. That helps with power off in particular, because alternative power off methods may be used then and they may actually work" * tag 'pm+acpi-3.14-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: ACPI / sleep: Add extra checks for HW Reduced ACPI mode sleep states ACPI / init: Invoke early ACPI initialization later cpufreq: Skip current frequency initialization for ->setpolicy drivers PNP / ACPI: proper handling of ACPI IO/Memory resource parsing failures
-rw-r--r--drivers/acpi/sleep.c32
-rw-r--r--drivers/cpufreq/cpufreq.c4
-rw-r--r--drivers/pnp/pnpacpi/rsparser.c15
-rw-r--r--init/main.c2
4 files changed, 30 insertions, 23 deletions
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index b718806657cd..c40fb2e81bbc 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -71,6 +71,17 @@ static int acpi_sleep_prepare(u32 acpi_state)
71 return 0; 71 return 0;
72} 72}
73 73
74static bool acpi_sleep_state_supported(u8 sleep_state)
75{
76 acpi_status status;
77 u8 type_a, type_b;
78
79 status = acpi_get_sleep_type_data(sleep_state, &type_a, &type_b);
80 return ACPI_SUCCESS(status) && (!acpi_gbl_reduced_hardware
81 || (acpi_gbl_FADT.sleep_control.address
82 && acpi_gbl_FADT.sleep_status.address));
83}
84
74#ifdef CONFIG_ACPI_SLEEP 85#ifdef CONFIG_ACPI_SLEEP
75static u32 acpi_target_sleep_state = ACPI_STATE_S0; 86static u32 acpi_target_sleep_state = ACPI_STATE_S0;
76 87
@@ -604,15 +615,9 @@ static void acpi_sleep_suspend_setup(void)
604{ 615{
605 int i; 616 int i;
606 617
607 for (i = ACPI_STATE_S1; i < ACPI_STATE_S4; i++) { 618 for (i = ACPI_STATE_S1; i < ACPI_STATE_S4; i++)
608 acpi_status status; 619 if (acpi_sleep_state_supported(i))
609 u8 type_a, type_b;
610
611 status = acpi_get_sleep_type_data(i, &type_a, &type_b);
612 if (ACPI_SUCCESS(status)) {
613 sleep_states[i] = 1; 620 sleep_states[i] = 1;
614 }
615 }
616 621
617 suspend_set_ops(old_suspend_ordering ? 622 suspend_set_ops(old_suspend_ordering ?
618 &acpi_suspend_ops_old : &acpi_suspend_ops); 623 &acpi_suspend_ops_old : &acpi_suspend_ops);
@@ -740,11 +745,7 @@ static const struct platform_hibernation_ops acpi_hibernation_ops_old = {
740 745
741static void acpi_sleep_hibernate_setup(void) 746static void acpi_sleep_hibernate_setup(void)
742{ 747{
743 acpi_status status; 748 if (!acpi_sleep_state_supported(ACPI_STATE_S4))
744 u8 type_a, type_b;
745
746 status = acpi_get_sleep_type_data(ACPI_STATE_S4, &type_a, &type_b);
747 if (ACPI_FAILURE(status))
748 return; 749 return;
749 750
750 hibernation_set_ops(old_suspend_ordering ? 751 hibernation_set_ops(old_suspend_ordering ?
@@ -793,8 +794,6 @@ static void acpi_power_off(void)
793 794
794int __init acpi_sleep_init(void) 795int __init acpi_sleep_init(void)
795{ 796{
796 acpi_status status;
797 u8 type_a, type_b;
798 char supported[ACPI_S_STATE_COUNT * 3 + 1]; 797 char supported[ACPI_S_STATE_COUNT * 3 + 1];
799 char *pos = supported; 798 char *pos = supported;
800 int i; 799 int i;
@@ -806,8 +805,7 @@ int __init acpi_sleep_init(void)
806 acpi_sleep_suspend_setup(); 805 acpi_sleep_suspend_setup();
807 acpi_sleep_hibernate_setup(); 806 acpi_sleep_hibernate_setup();
808 807
809 status = acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b); 808 if (acpi_sleep_state_supported(ACPI_STATE_S5)) {
810 if (ACPI_SUCCESS(status)) {
811 sleep_states[ACPI_STATE_S5] = 1; 809 sleep_states[ACPI_STATE_S5] = 1;
812 pm_power_off_prepare = acpi_power_off_prepare; 810 pm_power_off_prepare = acpi_power_off_prepare;
813 pm_power_off = acpi_power_off; 811 pm_power_off = acpi_power_off;
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index cf485d928903..199b52b7c3e1 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1129,7 +1129,7 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif,
1129 per_cpu(cpufreq_cpu_data, j) = policy; 1129 per_cpu(cpufreq_cpu_data, j) = policy;
1130 write_unlock_irqrestore(&cpufreq_driver_lock, flags); 1130 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
1131 1131
1132 if (cpufreq_driver->get) { 1132 if (cpufreq_driver->get && !cpufreq_driver->setpolicy) {
1133 policy->cur = cpufreq_driver->get(policy->cpu); 1133 policy->cur = cpufreq_driver->get(policy->cpu);
1134 if (!policy->cur) { 1134 if (!policy->cur) {
1135 pr_err("%s: ->get() failed\n", __func__); 1135 pr_err("%s: ->get() failed\n", __func__);
@@ -2143,7 +2143,7 @@ int cpufreq_update_policy(unsigned int cpu)
2143 * BIOS might change freq behind our back 2143 * BIOS might change freq behind our back
2144 * -> ask driver for current freq and notify governors about a change 2144 * -> ask driver for current freq and notify governors about a change
2145 */ 2145 */
2146 if (cpufreq_driver->get) { 2146 if (cpufreq_driver->get && !cpufreq_driver->setpolicy) {
2147 new_policy.cur = cpufreq_driver->get(cpu); 2147 new_policy.cur = cpufreq_driver->get(cpu);
2148 if (!policy->cur) { 2148 if (!policy->cur) {
2149 pr_debug("Driver did not initialize current freq"); 2149 pr_debug("Driver did not initialize current freq");
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c
index 167f3d00c916..66977ebf13b3 100644
--- a/drivers/pnp/pnpacpi/rsparser.c
+++ b/drivers/pnp/pnpacpi/rsparser.c
@@ -183,9 +183,7 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
183 struct resource r = {0}; 183 struct resource r = {0};
184 int i, flags; 184 int i, flags;
185 185
186 if (acpi_dev_resource_memory(res, &r) 186 if (acpi_dev_resource_address_space(res, &r)
187 || acpi_dev_resource_io(res, &r)
188 || acpi_dev_resource_address_space(res, &r)
189 || acpi_dev_resource_ext_address_space(res, &r)) { 187 || acpi_dev_resource_ext_address_space(res, &r)) {
190 pnp_add_resource(dev, &r); 188 pnp_add_resource(dev, &r);
191 return AE_OK; 189 return AE_OK;
@@ -217,6 +215,17 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
217 } 215 }
218 216
219 switch (res->type) { 217 switch (res->type) {
218 case ACPI_RESOURCE_TYPE_MEMORY24:
219 case ACPI_RESOURCE_TYPE_MEMORY32:
220 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
221 if (acpi_dev_resource_memory(res, &r))
222 pnp_add_resource(dev, &r);
223 break;
224 case ACPI_RESOURCE_TYPE_IO:
225 case ACPI_RESOURCE_TYPE_FIXED_IO:
226 if (acpi_dev_resource_io(res, &r))
227 pnp_add_resource(dev, &r);
228 break;
220 case ACPI_RESOURCE_TYPE_DMA: 229 case ACPI_RESOURCE_TYPE_DMA:
221 dma = &res->data.dma; 230 dma = &res->data.dma;
222 if (dma->channel_count > 0 && dma->channels[0] != (u8) -1) 231 if (dma->channel_count > 0 && dma->channels[0] != (u8) -1)
diff --git a/init/main.c b/init/main.c
index eb03090cdced..9c7fd4c9249f 100644
--- a/init/main.c
+++ b/init/main.c
@@ -561,7 +561,6 @@ asmlinkage void __init start_kernel(void)
561 init_timers(); 561 init_timers();
562 hrtimers_init(); 562 hrtimers_init();
563 softirq_init(); 563 softirq_init();
564 acpi_early_init();
565 timekeeping_init(); 564 timekeeping_init();
566 time_init(); 565 time_init();
567 sched_clock_postinit(); 566 sched_clock_postinit();
@@ -613,6 +612,7 @@ asmlinkage void __init start_kernel(void)
613 calibrate_delay(); 612 calibrate_delay();
614 pidmap_init(); 613 pidmap_init();
615 anon_vma_init(); 614 anon_vma_init();
615 acpi_early_init();
616#ifdef CONFIG_X86 616#ifdef CONFIG_X86
617 if (efi_enabled(EFI_RUNTIME_SERVICES)) 617 if (efi_enabled(EFI_RUNTIME_SERVICES))
618 efi_enter_virtual_mode(); 618 efi_enter_virtual_mode();