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.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index d592dbb1d12a..81b40ed5379e 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -41,7 +41,6 @@
41#include <linux/pm_qos_params.h> 41#include <linux/pm_qos_params.h>
42#include <linux/clockchips.h> 42#include <linux/clockchips.h>
43#include <linux/cpuidle.h> 43#include <linux/cpuidle.h>
44#include <linux/cpuidle.h>
45 44
46/* 45/*
47 * Include the apic definitions for x86 to have the APIC timer related defines 46 * Include the apic definitions for x86 to have the APIC timer related defines
@@ -272,6 +271,8 @@ static atomic_t c3_cpu_count;
272/* Common C-state entry for C2, C3, .. */ 271/* Common C-state entry for C2, C3, .. */
273static void acpi_cstate_enter(struct acpi_processor_cx *cstate) 272static void acpi_cstate_enter(struct acpi_processor_cx *cstate)
274{ 273{
274 /* Don't trace irqs off for idle */
275 stop_critical_timings();
275 if (cstate->entry_method == ACPI_CSTATE_FFH) { 276 if (cstate->entry_method == ACPI_CSTATE_FFH) {
276 /* Call into architectural FFH based C-state */ 277 /* Call into architectural FFH based C-state */
277 acpi_processor_ffh_cstate_enter(cstate); 278 acpi_processor_ffh_cstate_enter(cstate);
@@ -284,6 +285,7 @@ static void acpi_cstate_enter(struct acpi_processor_cx *cstate)
284 gets asserted in time to freeze execution properly. */ 285 gets asserted in time to freeze execution properly. */
285 unused = inl(acpi_gbl_FADT.xpm_timer_block.address); 286 unused = inl(acpi_gbl_FADT.xpm_timer_block.address);
286 } 287 }
288 start_critical_timings();
287} 289}
288#endif /* !CONFIG_CPU_IDLE */ 290#endif /* !CONFIG_CPU_IDLE */
289 291
@@ -1329,9 +1331,15 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr)
1329 if (!pr->flags.power_setup_done) 1331 if (!pr->flags.power_setup_done)
1330 return -ENODEV; 1332 return -ENODEV;
1331 1333
1332 /* Fall back to the default idle loop */ 1334 /*
1333 pm_idle = pm_idle_save; 1335 * Fall back to the default idle loop, when pm_idle_save had
1334 synchronize_sched(); /* Relies on interrupts forcing exit from idle. */ 1336 * been initialized.
1337 */
1338 if (pm_idle_save) {
1339 pm_idle = pm_idle_save;
1340 /* Relies on interrupts forcing exit from idle. */
1341 synchronize_sched();
1342 }
1335 1343
1336 pr->flags.power = 0; 1344 pr->flags.power = 0;
1337 result = acpi_processor_get_power_info(pr); 1345 result = acpi_processor_get_power_info(pr);
@@ -1418,6 +1426,8 @@ static inline void acpi_idle_update_bm_rld(struct acpi_processor *pr,
1418 */ 1426 */
1419static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx) 1427static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx)
1420{ 1428{
1429 /* Don't trace irqs off for idle */
1430 stop_critical_timings();
1421 if (cx->entry_method == ACPI_CSTATE_FFH) { 1431 if (cx->entry_method == ACPI_CSTATE_FFH) {
1422 /* Call into architectural FFH based C-state */ 1432 /* Call into architectural FFH based C-state */
1423 acpi_processor_ffh_cstate_enter(cx); 1433 acpi_processor_ffh_cstate_enter(cx);
@@ -1432,6 +1442,7 @@ static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx)
1432 gets asserted in time to freeze execution properly. */ 1442 gets asserted in time to freeze execution properly. */
1433 unused = inl(acpi_gbl_FADT.xpm_timer_block.address); 1443 unused = inl(acpi_gbl_FADT.xpm_timer_block.address);
1434 } 1444 }
1445 start_critical_timings();
1435} 1446}
1436 1447
1437/** 1448/**
@@ -1576,6 +1587,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
1576 1587
1577 if (acpi_idle_bm_check()) { 1588 if (acpi_idle_bm_check()) {
1578 if (dev->safe_state) { 1589 if (dev->safe_state) {
1590 dev->last_state = dev->safe_state;
1579 return dev->safe_state->enter(dev, dev->safe_state); 1591 return dev->safe_state->enter(dev, dev->safe_state);
1580 } else { 1592 } else {
1581 local_irq_disable(); 1593 local_irq_disable();
@@ -1890,7 +1902,8 @@ int acpi_processor_power_exit(struct acpi_processor *pr,
1890 1902
1891 /* Unregister the idle handler when processor #0 is removed. */ 1903 /* Unregister the idle handler when processor #0 is removed. */
1892 if (pr->id == 0) { 1904 if (pr->id == 0) {
1893 pm_idle = pm_idle_save; 1905 if (pm_idle_save)
1906 pm_idle = pm_idle_save;
1894 1907
1895 /* 1908 /*
1896 * We are about to unload the current idle thread pm callback 1909 * We are about to unload the current idle thread pm callback