diff options
Diffstat (limited to 'drivers/cpuidle')
-rw-r--r-- | drivers/cpuidle/cpuidle.c | 82 |
1 files changed, 41 insertions, 41 deletions
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 386888f10df0..a2d5b95a6d64 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c | |||
@@ -155,6 +155,45 @@ void cpuidle_resume_and_unlock(void) | |||
155 | 155 | ||
156 | EXPORT_SYMBOL_GPL(cpuidle_resume_and_unlock); | 156 | EXPORT_SYMBOL_GPL(cpuidle_resume_and_unlock); |
157 | 157 | ||
158 | #ifdef CONFIG_ARCH_HAS_CPU_RELAX | ||
159 | static int poll_idle(struct cpuidle_device *dev, struct cpuidle_state *st) | ||
160 | { | ||
161 | ktime_t t1, t2; | ||
162 | s64 diff; | ||
163 | int ret; | ||
164 | |||
165 | t1 = ktime_get(); | ||
166 | local_irq_enable(); | ||
167 | while (!need_resched()) | ||
168 | cpu_relax(); | ||
169 | |||
170 | t2 = ktime_get(); | ||
171 | diff = ktime_to_us(ktime_sub(t2, t1)); | ||
172 | if (diff > INT_MAX) | ||
173 | diff = INT_MAX; | ||
174 | |||
175 | ret = (int) diff; | ||
176 | return ret; | ||
177 | } | ||
178 | |||
179 | static void poll_idle_init(struct cpuidle_device *dev) | ||
180 | { | ||
181 | struct cpuidle_state *state = &dev->states[0]; | ||
182 | |||
183 | cpuidle_set_statedata(state, NULL); | ||
184 | |||
185 | snprintf(state->name, CPUIDLE_NAME_LEN, "POLL"); | ||
186 | snprintf(state->desc, CPUIDLE_DESC_LEN, "CPUIDLE CORE POLL IDLE"); | ||
187 | state->exit_latency = 0; | ||
188 | state->target_residency = 0; | ||
189 | state->power_usage = -1; | ||
190 | state->flags = 0; | ||
191 | state->enter = poll_idle; | ||
192 | } | ||
193 | #else | ||
194 | static void poll_idle_init(struct cpuidle_device *dev) {} | ||
195 | #endif /* CONFIG_ARCH_HAS_CPU_RELAX */ | ||
196 | |||
158 | /** | 197 | /** |
159 | * cpuidle_enable_device - enables idle PM for a CPU | 198 | * cpuidle_enable_device - enables idle PM for a CPU |
160 | * @dev: the CPU | 199 | * @dev: the CPU |
@@ -179,6 +218,8 @@ int cpuidle_enable_device(struct cpuidle_device *dev) | |||
179 | return ret; | 218 | return ret; |
180 | } | 219 | } |
181 | 220 | ||
221 | poll_idle_init(dev); | ||
222 | |||
182 | if ((ret = cpuidle_add_state_sysfs(dev))) | 223 | if ((ret = cpuidle_add_state_sysfs(dev))) |
183 | return ret; | 224 | return ret; |
184 | 225 | ||
@@ -233,45 +274,6 @@ void cpuidle_disable_device(struct cpuidle_device *dev) | |||
233 | 274 | ||
234 | EXPORT_SYMBOL_GPL(cpuidle_disable_device); | 275 | EXPORT_SYMBOL_GPL(cpuidle_disable_device); |
235 | 276 | ||
236 | #ifdef CONFIG_ARCH_HAS_CPU_RELAX | ||
237 | static int poll_idle(struct cpuidle_device *dev, struct cpuidle_state *st) | ||
238 | { | ||
239 | ktime_t t1, t2; | ||
240 | s64 diff; | ||
241 | int ret; | ||
242 | |||
243 | t1 = ktime_get(); | ||
244 | local_irq_enable(); | ||
245 | while (!need_resched()) | ||
246 | cpu_relax(); | ||
247 | |||
248 | t2 = ktime_get(); | ||
249 | diff = ktime_to_us(ktime_sub(t2, t1)); | ||
250 | if (diff > INT_MAX) | ||
251 | diff = INT_MAX; | ||
252 | |||
253 | ret = (int) diff; | ||
254 | return ret; | ||
255 | } | ||
256 | |||
257 | static void poll_idle_init(struct cpuidle_device *dev) | ||
258 | { | ||
259 | struct cpuidle_state *state = &dev->states[0]; | ||
260 | |||
261 | cpuidle_set_statedata(state, NULL); | ||
262 | |||
263 | snprintf(state->name, CPUIDLE_NAME_LEN, "C0"); | ||
264 | snprintf(state->desc, CPUIDLE_DESC_LEN, "CPUIDLE CORE POLL IDLE"); | ||
265 | state->exit_latency = 0; | ||
266 | state->target_residency = 0; | ||
267 | state->power_usage = -1; | ||
268 | state->flags = CPUIDLE_FLAG_POLL; | ||
269 | state->enter = poll_idle; | ||
270 | } | ||
271 | #else | ||
272 | static void poll_idle_init(struct cpuidle_device *dev) {} | ||
273 | #endif /* CONFIG_ARCH_HAS_CPU_RELAX */ | ||
274 | |||
275 | /** | 277 | /** |
276 | * __cpuidle_register_device - internal register function called before register | 278 | * __cpuidle_register_device - internal register function called before register |
277 | * and enable routines | 279 | * and enable routines |
@@ -292,8 +294,6 @@ static int __cpuidle_register_device(struct cpuidle_device *dev) | |||
292 | 294 | ||
293 | init_completion(&dev->kobj_unregister); | 295 | init_completion(&dev->kobj_unregister); |
294 | 296 | ||
295 | poll_idle_init(dev); | ||
296 | |||
297 | /* | 297 | /* |
298 | * cpuidle driver should set the dev->power_specified bit | 298 | * cpuidle driver should set the dev->power_specified bit |
299 | * before registering the device if the driver provides | 299 | * before registering the device if the driver provides |