diff options
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) | |||
| 82 | struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev); | 82 | struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev); |
| 83 | int next_state, entered_state; | 83 | int next_state, entered_state; |
| 84 | unsigned int broadcast; | 84 | unsigned int broadcast; |
| 85 | bool reflect; | ||
| 85 | 86 | ||
| 86 | /* | 87 | /* |
| 87 | * Check if the idle task must be rescheduled. If it is the | 88 | * Check if the idle task must be rescheduled. If it is the |
| @@ -105,6 +106,9 @@ static void cpuidle_idle_call(void) | |||
| 105 | */ | 106 | */ |
| 106 | rcu_idle_enter(); | 107 | rcu_idle_enter(); |
| 107 | 108 | ||
| 109 | if (cpuidle_not_available(drv, dev)) | ||
| 110 | goto use_default; | ||
| 111 | |||
| 108 | /* | 112 | /* |
| 109 | * Suspend-to-idle ("freeze") is a system state in which all user space | 113 | * Suspend-to-idle ("freeze") is a system state in which all user space |
| 110 | * has been frozen, all I/O devices have been suspended and the only | 114 | * has been frozen, all I/O devices have been suspended and the only |
| @@ -115,30 +119,24 @@ static void cpuidle_idle_call(void) | |||
| 115 | * until a proper wakeup interrupt happens. | 119 | * until a proper wakeup interrupt happens. |
| 116 | */ | 120 | */ |
| 117 | if (idle_should_freeze()) { | 121 | if (idle_should_freeze()) { |
| 118 | cpuidle_enter_freeze(); | 122 | entered_state = cpuidle_enter_freeze(drv, dev); |
| 119 | local_irq_enable(); | 123 | if (entered_state >= 0) { |
| 120 | goto exit_idle; | 124 | local_irq_enable(); |
| 121 | } | 125 | goto exit_idle; |
| 126 | } | ||
| 122 | 127 | ||
| 123 | /* | 128 | reflect = false; |
| 124 | * Ask the cpuidle framework to choose a convenient idle state. | 129 | next_state = cpuidle_find_deepest_state(drv, dev); |
| 125 | * Fall back to the default arch idle method on errors. | 130 | } else { |
| 126 | */ | 131 | reflect = true; |
| 127 | next_state = cpuidle_select(drv, dev); | ||
| 128 | if (next_state < 0) { | ||
| 129 | use_default: | ||
| 130 | /* | 132 | /* |
| 131 | * We can't use the cpuidle framework, let's use the default | 133 | * Ask the cpuidle framework to choose a convenient idle state. |
| 132 | * idle routine. | ||
| 133 | */ | 134 | */ |
| 134 | if (current_clr_polling_and_test()) | 135 | next_state = cpuidle_select(drv, dev); |
| 135 | local_irq_enable(); | ||
| 136 | else | ||
| 137 | arch_cpu_idle(); | ||
| 138 | |||
| 139 | goto exit_idle; | ||
| 140 | } | 136 | } |
| 141 | 137 | /* Fall back to the default arch idle method on errors. */ | |
| 138 | if (next_state < 0) | ||
| 139 | goto use_default; | ||
| 142 | 140 | ||
| 143 | /* | 141 | /* |
| 144 | * The idle task must be scheduled, it is pointless to | 142 | * The idle task must be scheduled, it is pointless to |
| @@ -183,7 +181,8 @@ use_default: | |||
| 183 | /* | 181 | /* |
| 184 | * Give the governor an opportunity to reflect on the outcome | 182 | * Give the governor an opportunity to reflect on the outcome |
| 185 | */ | 183 | */ |
| 186 | cpuidle_reflect(dev, entered_state); | 184 | if (reflect) |
| 185 | cpuidle_reflect(dev, entered_state); | ||
| 187 | 186 | ||
| 188 | exit_idle: | 187 | exit_idle: |
| 189 | __current_set_polling(); | 188 | __current_set_polling(); |
| @@ -196,6 +195,19 @@ exit_idle: | |||
| 196 | 195 | ||
| 197 | rcu_idle_exit(); | 196 | rcu_idle_exit(); |
| 198 | start_critical_timings(); | 197 | start_critical_timings(); |
| 198 | return; | ||
| 199 | |||
| 200 | use_default: | ||
| 201 | /* | ||
| 202 | * We can't use the cpuidle framework, let's use the default | ||
| 203 | * idle routine. | ||
| 204 | */ | ||
| 205 | if (current_clr_polling_and_test()) | ||
| 206 | local_irq_enable(); | ||
| 207 | else | ||
| 208 | arch_cpu_idle(); | ||
| 209 | |||
| 210 | goto exit_idle; | ||
| 199 | } | 211 | } |
| 200 | 212 | ||
| 201 | /* | 213 | /* |
