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 | } |