aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/processor_idle.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/processor_idle.c')
-rw-r--r--drivers/acpi/processor_idle.c44
1 files changed, 36 insertions, 8 deletions
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index f3decb30223f..9837c9c4f009 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -224,6 +224,7 @@ static void lapic_timer_state_broadcast(struct acpi_processor *pr,
224/* 224/*
225 * Suspend / resume control 225 * Suspend / resume control
226 */ 226 */
227static int acpi_idle_suspend;
227static u32 saved_bm_rld; 228static u32 saved_bm_rld;
228 229
229static void acpi_idle_bm_rld_save(void) 230static void acpi_idle_bm_rld_save(void)
@@ -242,13 +243,21 @@ static void acpi_idle_bm_rld_restore(void)
242 243
243int acpi_processor_suspend(struct acpi_device * device, pm_message_t state) 244int acpi_processor_suspend(struct acpi_device * device, pm_message_t state)
244{ 245{
246 if (acpi_idle_suspend == 1)
247 return 0;
248
245 acpi_idle_bm_rld_save(); 249 acpi_idle_bm_rld_save();
250 acpi_idle_suspend = 1;
246 return 0; 251 return 0;
247} 252}
248 253
249int acpi_processor_resume(struct acpi_device * device) 254int acpi_processor_resume(struct acpi_device * device)
250{ 255{
256 if (acpi_idle_suspend == 0)
257 return 0;
258
251 acpi_idle_bm_rld_restore(); 259 acpi_idle_bm_rld_restore();
260 acpi_idle_suspend = 0;
252 return 0; 261 return 0;
253} 262}
254 263
@@ -304,16 +313,16 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
304 pr->power.states[ACPI_STATE_C3].address = pr->pblk + 5; 313 pr->power.states[ACPI_STATE_C3].address = pr->pblk + 5;
305 314
306 /* determine latencies from FADT */ 315 /* determine latencies from FADT */
307 pr->power.states[ACPI_STATE_C2].latency = acpi_gbl_FADT.C2latency; 316 pr->power.states[ACPI_STATE_C2].latency = acpi_gbl_FADT.c2_latency;
308 pr->power.states[ACPI_STATE_C3].latency = acpi_gbl_FADT.C3latency; 317 pr->power.states[ACPI_STATE_C3].latency = acpi_gbl_FADT.c3_latency;
309 318
310 /* 319 /*
311 * FADT specified C2 latency must be less than or equal to 320 * FADT specified C2 latency must be less than or equal to
312 * 100 microseconds. 321 * 100 microseconds.
313 */ 322 */
314 if (acpi_gbl_FADT.C2latency > ACPI_PROCESSOR_MAX_C2_LATENCY) { 323 if (acpi_gbl_FADT.c2_latency > ACPI_PROCESSOR_MAX_C2_LATENCY) {
315 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 324 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
316 "C2 latency too large [%d]\n", acpi_gbl_FADT.C2latency)); 325 "C2 latency too large [%d]\n", acpi_gbl_FADT.c2_latency));
317 /* invalidate C2 */ 326 /* invalidate C2 */
318 pr->power.states[ACPI_STATE_C2].address = 0; 327 pr->power.states[ACPI_STATE_C2].address = 0;
319 } 328 }
@@ -322,9 +331,9 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
322 * FADT supplied C3 latency must be less than or equal to 331 * FADT supplied C3 latency must be less than or equal to
323 * 1000 microseconds. 332 * 1000 microseconds.
324 */ 333 */
325 if (acpi_gbl_FADT.C3latency > ACPI_PROCESSOR_MAX_C3_LATENCY) { 334 if (acpi_gbl_FADT.c3_latency > ACPI_PROCESSOR_MAX_C3_LATENCY) {
326 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 335 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
327 "C3 latency too large [%d]\n", acpi_gbl_FADT.C3latency)); 336 "C3 latency too large [%d]\n", acpi_gbl_FADT.c3_latency));
328 /* invalidate C3 */ 337 /* invalidate C3 */
329 pr->power.states[ACPI_STATE_C3].address = 0; 338 pr->power.states[ACPI_STATE_C3].address = 0;
330 } 339 }
@@ -754,6 +763,12 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
754 763
755 local_irq_disable(); 764 local_irq_disable();
756 765
766 if (acpi_idle_suspend) {
767 local_irq_enable();
768 cpu_relax();
769 return -EBUSY;
770 }
771
757 lapic_timer_state_broadcast(pr, cx, 1); 772 lapic_timer_state_broadcast(pr, cx, 1);
758 kt1 = ktime_get_real(); 773 kt1 = ktime_get_real();
759 acpi_idle_do_entry(cx); 774 acpi_idle_do_entry(cx);
@@ -823,6 +838,12 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
823 838
824 local_irq_disable(); 839 local_irq_disable();
825 840
841 if (acpi_idle_suspend) {
842 local_irq_enable();
843 cpu_relax();
844 return -EBUSY;
845 }
846
826 if (cx->entry_method != ACPI_CSTATE_FFH) { 847 if (cx->entry_method != ACPI_CSTATE_FFH) {
827 current_thread_info()->status &= ~TS_POLLING; 848 current_thread_info()->status &= ~TS_POLLING;
828 /* 849 /*
@@ -907,14 +928,21 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
907 drv, drv->safe_state_index); 928 drv, drv->safe_state_index);
908 } else { 929 } else {
909 local_irq_disable(); 930 local_irq_disable();
910 acpi_safe_halt(); 931 if (!acpi_idle_suspend)
932 acpi_safe_halt();
911 local_irq_enable(); 933 local_irq_enable();
912 return -EINVAL; 934 return -EBUSY;
913 } 935 }
914 } 936 }
915 937
916 local_irq_disable(); 938 local_irq_disable();
917 939
940 if (acpi_idle_suspend) {
941 local_irq_enable();
942 cpu_relax();
943 return -EBUSY;
944 }
945
918 if (cx->entry_method != ACPI_CSTATE_FFH) { 946 if (cx->entry_method != ACPI_CSTATE_FFH) {
919 current_thread_info()->status &= ~TS_POLLING; 947 current_thread_info()->status &= ~TS_POLLING;
920 /* 948 /*