diff options
| -rw-r--r-- | include/linux/cpuidle.h | 2 | ||||
| -rw-r--r-- | kernel/sched/idle.c | 33 |
2 files changed, 17 insertions, 18 deletions
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h index 8d97962d6d64..b0238cba440b 100644 --- a/include/linux/cpuidle.h +++ b/include/linux/cpuidle.h | |||
| @@ -180,6 +180,8 @@ static inline int cpuidle_enable_device(struct cpuidle_device *dev) | |||
| 180 | {return -ENODEV; } | 180 | {return -ENODEV; } |
| 181 | static inline void cpuidle_disable_device(struct cpuidle_device *dev) { } | 181 | static inline void cpuidle_disable_device(struct cpuidle_device *dev) { } |
| 182 | static inline int cpuidle_play_dead(void) {return -ENODEV; } | 182 | static inline int cpuidle_play_dead(void) {return -ENODEV; } |
| 183 | static inline struct cpuidle_driver *cpuidle_get_cpu_driver( | ||
| 184 | struct cpuidle_device *dev) {return NULL; } | ||
| 183 | #endif | 185 | #endif |
| 184 | 186 | ||
| 185 | #ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED | 187 | #ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED |
diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c index d5aaf5eb4531..dc8a2466418f 100644 --- a/kernel/sched/idle.c +++ b/kernel/sched/idle.c | |||
| @@ -63,7 +63,6 @@ void __weak arch_cpu_idle(void) | |||
| 63 | local_irq_enable(); | 63 | local_irq_enable(); |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | #ifdef CONFIG_CPU_IDLE | ||
| 67 | /** | 66 | /** |
| 68 | * cpuidle_idle_call - the main idle function | 67 | * cpuidle_idle_call - the main idle function |
| 69 | * | 68 | * |
| @@ -77,9 +76,14 @@ static int cpuidle_idle_call(void) | |||
| 77 | int next_state, entered_state, ret; | 76 | int next_state, entered_state, ret; |
| 78 | bool broadcast; | 77 | bool broadcast; |
| 79 | 78 | ||
| 79 | stop_critical_timings(); | ||
| 80 | rcu_idle_enter(); | ||
| 81 | |||
| 80 | ret = cpuidle_enabled(drv, dev); | 82 | ret = cpuidle_enabled(drv, dev); |
| 81 | if (ret < 0) | 83 | if (ret < 0) { |
| 82 | return ret; | 84 | arch_cpu_idle(); |
| 85 | goto out; | ||
| 86 | } | ||
| 83 | 87 | ||
| 84 | /* ask the governor for the next state */ | 88 | /* ask the governor for the next state */ |
| 85 | next_state = cpuidle_select(drv, dev); | 89 | next_state = cpuidle_select(drv, dev); |
| @@ -89,7 +93,7 @@ static int cpuidle_idle_call(void) | |||
| 89 | /* give the governor an opportunity to reflect on the outcome */ | 93 | /* give the governor an opportunity to reflect on the outcome */ |
| 90 | cpuidle_reflect(dev, next_state); | 94 | cpuidle_reflect(dev, next_state); |
| 91 | local_irq_enable(); | 95 | local_irq_enable(); |
| 92 | return 0; | 96 | goto out; |
| 93 | } | 97 | } |
| 94 | 98 | ||
| 95 | broadcast = !!(drv->states[next_state].flags & CPUIDLE_FLAG_TIMER_STOP); | 99 | broadcast = !!(drv->states[next_state].flags & CPUIDLE_FLAG_TIMER_STOP); |
| @@ -109,15 +113,15 @@ static int cpuidle_idle_call(void) | |||
| 109 | 113 | ||
| 110 | /* give the governor an opportunity to reflect on the outcome */ | 114 | /* give the governor an opportunity to reflect on the outcome */ |
| 111 | cpuidle_reflect(dev, entered_state); | 115 | cpuidle_reflect(dev, entered_state); |
| 116 | out: | ||
| 117 | if (WARN_ON_ONCE(irqs_disabled())) | ||
| 118 | local_irq_enable(); | ||
| 119 | |||
| 120 | rcu_idle_exit(); | ||
| 121 | start_critical_timings(); | ||
| 112 | 122 | ||
| 113 | return 0; | 123 | return 0; |
| 114 | } | 124 | } |
| 115 | #else | ||
| 116 | static inline int cpuidle_idle_call(void) | ||
| 117 | { | ||
| 118 | return -ENODEV; | ||
| 119 | } | ||
| 120 | #endif | ||
| 121 | 125 | ||
| 122 | /* | 126 | /* |
| 123 | * Generic idle loop implementation | 127 | * Generic idle loop implementation |
| @@ -150,14 +154,7 @@ static void cpu_idle_loop(void) | |||
| 150 | cpu_idle_poll(); | 154 | cpu_idle_poll(); |
| 151 | } else { | 155 | } else { |
| 152 | if (!current_clr_polling_and_test()) { | 156 | if (!current_clr_polling_and_test()) { |
| 153 | stop_critical_timings(); | 157 | cpuidle_idle_call(); |
| 154 | rcu_idle_enter(); | ||
| 155 | if (cpuidle_idle_call()) | ||
| 156 | arch_cpu_idle(); | ||
| 157 | if (WARN_ON_ONCE(irqs_disabled())) | ||
| 158 | local_irq_enable(); | ||
| 159 | rcu_idle_exit(); | ||
| 160 | start_critical_timings(); | ||
| 161 | } else { | 158 | } else { |
| 162 | local_irq_enable(); | 159 | local_irq_enable(); |
| 163 | } | 160 | } |
