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.c50
1 files changed, 40 insertions, 10 deletions
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index f7ca8c55956..10a2d913635 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -148,6 +148,9 @@ static void acpi_timer_check_state(int state, struct acpi_processor *pr,
148 if (cpu_has(&cpu_data(pr->id), X86_FEATURE_ARAT)) 148 if (cpu_has(&cpu_data(pr->id), X86_FEATURE_ARAT))
149 return; 149 return;
150 150
151 if (boot_cpu_has(X86_FEATURE_AMDC1E))
152 type = ACPI_STATE_C1;
153
151 /* 154 /*
152 * Check, if one of the previous states already marked the lapic 155 * Check, if one of the previous states already marked the lapic
153 * unstable 156 * unstable
@@ -202,21 +205,44 @@ static void acpi_state_timer_broadcast(struct acpi_processor *pr,
202 * Suspend / resume control 205 * Suspend / resume control
203 */ 206 */
204static int acpi_idle_suspend; 207static int acpi_idle_suspend;
208static u32 saved_bm_rld;
209
210static void acpi_idle_bm_rld_save(void)
211{
212 acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &saved_bm_rld);
213}
214static void acpi_idle_bm_rld_restore(void)
215{
216 u32 resumed_bm_rld;
217
218 acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &resumed_bm_rld);
219
220 if (resumed_bm_rld != saved_bm_rld)
221 acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, saved_bm_rld);
222}
205 223
206int acpi_processor_suspend(struct acpi_device * device, pm_message_t state) 224int acpi_processor_suspend(struct acpi_device * device, pm_message_t state)
207{ 225{
226 if (acpi_idle_suspend == 1)
227 return 0;
228
229 acpi_idle_bm_rld_save();
208 acpi_idle_suspend = 1; 230 acpi_idle_suspend = 1;
209 return 0; 231 return 0;
210} 232}
211 233
212int acpi_processor_resume(struct acpi_device * device) 234int acpi_processor_resume(struct acpi_device * device)
213{ 235{
236 if (acpi_idle_suspend == 0)
237 return 0;
238
239 acpi_idle_bm_rld_restore();
214 acpi_idle_suspend = 0; 240 acpi_idle_suspend = 0;
215 return 0; 241 return 0;
216} 242}
217 243
218#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86) 244#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
219static int tsc_halts_in_c(int state) 245static void tsc_check_state(int state)
220{ 246{
221 switch (boot_cpu_data.x86_vendor) { 247 switch (boot_cpu_data.x86_vendor) {
222 case X86_VENDOR_AMD: 248 case X86_VENDOR_AMD:
@@ -226,13 +252,17 @@ static int tsc_halts_in_c(int state)
226 * C/P/S0/S1 states when this bit is set. 252 * C/P/S0/S1 states when this bit is set.
227 */ 253 */
228 if (boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) 254 if (boot_cpu_has(X86_FEATURE_NONSTOP_TSC))
229 return 0; 255 return;
230 256
231 /*FALL THROUGH*/ 257 /*FALL THROUGH*/
232 default: 258 default:
233 return state > ACPI_STATE_C1; 259 /* TSC could halt in idle, so notify users */
260 if (state > ACPI_STATE_C1)
261 mark_tsc_unstable("TSC halts in idle");
234 } 262 }
235} 263}
264#else
265static void tsc_check_state(int state) { return; }
236#endif 266#endif
237 267
238static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr) 268static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
@@ -578,17 +608,13 @@ static int acpi_processor_power_verify(struct acpi_processor *pr)
578 608
579 pr->power.timer_broadcast_on_state = INT_MAX; 609 pr->power.timer_broadcast_on_state = INT_MAX;
580 610
581 for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) { 611 for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) {
582 struct acpi_processor_cx *cx = &pr->power.states[i]; 612 struct acpi_processor_cx *cx = &pr->power.states[i];
583 613
584#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
585 /* TSC could halt in idle, so notify users */
586 if (tsc_halts_in_c(cx->type))
587 mark_tsc_unstable("TSC halts in idle");;
588#endif
589 switch (cx->type) { 614 switch (cx->type) {
590 case ACPI_STATE_C1: 615 case ACPI_STATE_C1:
591 cx->valid = 1; 616 cx->valid = 1;
617 acpi_timer_check_state(i, pr, cx);
592 break; 618 break;
593 619
594 case ACPI_STATE_C2: 620 case ACPI_STATE_C2:
@@ -603,6 +629,8 @@ static int acpi_processor_power_verify(struct acpi_processor *pr)
603 acpi_timer_check_state(i, pr, cx); 629 acpi_timer_check_state(i, pr, cx);
604 break; 630 break;
605 } 631 }
632 if (cx->valid)
633 tsc_check_state(cx->type);
606 634
607 if (cx->valid) 635 if (cx->valid)
608 working++; 636 working++;
@@ -806,11 +834,12 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
806 834
807 /* Do not access any ACPI IO ports in suspend path */ 835 /* Do not access any ACPI IO ports in suspend path */
808 if (acpi_idle_suspend) { 836 if (acpi_idle_suspend) {
809 acpi_safe_halt();
810 local_irq_enable(); 837 local_irq_enable();
838 cpu_relax();
811 return 0; 839 return 0;
812 } 840 }
813 841
842 acpi_state_timer_broadcast(pr, cx, 1);
814 kt1 = ktime_get_real(); 843 kt1 = ktime_get_real();
815 acpi_idle_do_entry(cx); 844 acpi_idle_do_entry(cx);
816 kt2 = ktime_get_real(); 845 kt2 = ktime_get_real();
@@ -818,6 +847,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
818 847
819 local_irq_enable(); 848 local_irq_enable();
820 cx->usage++; 849 cx->usage++;
850 acpi_state_timer_broadcast(pr, cx, 0);
821 851
822 return idle_time; 852 return idle_time;
823} 853}