diff options
Diffstat (limited to 'drivers/acpi/processor_idle.c')
-rw-r--r-- | drivers/acpi/processor_idle.c | 23 |
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, .. */ |
273 | static void acpi_cstate_enter(struct acpi_processor_cx *cstate) | 272 | static 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 | */ |
1419 | static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx) | 1427 | static 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 |