diff options
| author | Rob Herring <robh@kernel.org> | 2015-03-10 09:03:04 -0500 |
|---|---|---|
| committer | Rob Herring <robh@kernel.org> | 2015-03-10 09:03:04 -0500 |
| commit | 2c192699a7050ef5bdf1e2cc95fdddfbcf524509 (patch) | |
| tree | 945d4553691ecb24151a2fa83b7d489665dd3248 /kernel/sched | |
| parent | 25e8f336e535d10c30216e1ba330fbea98dfccc5 (diff) | |
| parent | 9eccca0843205f87c00404b663188b88eb248051 (diff) | |
Merge tag 'v4.0-rc3' into HEAD
Linux 4.0-rc3
Merging in v4.0-rc3 because commit 30a22c215a00 (console: Fix
console name size mismatch) is a dependency.
Diffstat (limited to 'kernel/sched')
| -rw-r--r-- | kernel/sched/idle.c | 54 |
1 files changed, 33 insertions, 21 deletions
diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c index 94b2d7b88a27..80014a178342 100644 --- a/kernel/sched/idle.c +++ b/kernel/sched/idle.c @@ -82,6 +82,7 @@ static void cpuidle_idle_call(void) struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev); int next_state, entered_state; unsigned int broadcast; + bool reflect; /* * Check if the idle task must be rescheduled. If it is the @@ -105,6 +106,9 @@ static void cpuidle_idle_call(void) */ rcu_idle_enter(); + if (cpuidle_not_available(drv, dev)) + goto use_default; + /* * Suspend-to-idle ("freeze") is a system state in which all user space * has been frozen, all I/O devices have been suspended and the only @@ -115,30 +119,24 @@ static void cpuidle_idle_call(void) * until a proper wakeup interrupt happens. */ if (idle_should_freeze()) { - cpuidle_enter_freeze(); - local_irq_enable(); - goto exit_idle; - } + entered_state = cpuidle_enter_freeze(drv, dev); + if (entered_state >= 0) { + local_irq_enable(); + goto exit_idle; + } - /* - * Ask the cpuidle framework to choose a convenient idle state. - * Fall back to the default arch idle method on errors. - */ - next_state = cpuidle_select(drv, dev); - if (next_state < 0) { -use_default: + reflect = false; + next_state = cpuidle_find_deepest_state(drv, dev); + } else { + reflect = true; /* - * We can't use the cpuidle framework, let's use the default - * idle routine. + * Ask the cpuidle framework to choose a convenient idle state. */ - if (current_clr_polling_and_test()) - local_irq_enable(); - else - arch_cpu_idle(); - - goto exit_idle; + next_state = cpuidle_select(drv, dev); } - + /* Fall back to the default arch idle method on errors. */ + if (next_state < 0) + goto use_default; /* * The idle task must be scheduled, it is pointless to @@ -183,7 +181,8 @@ use_default: /* * Give the governor an opportunity to reflect on the outcome */ - cpuidle_reflect(dev, entered_state); + if (reflect) + cpuidle_reflect(dev, entered_state); exit_idle: __current_set_polling(); @@ -196,6 +195,19 @@ exit_idle: rcu_idle_exit(); start_critical_timings(); + return; + +use_default: + /* + * We can't use the cpuidle framework, let's use the default + * idle routine. + */ + if (current_clr_polling_and_test()) + local_irq_enable(); + else + arch_cpu_idle(); + + goto exit_idle; } /* |
