diff options
author | Paul Walmsley <paul@pwsan.com> | 2010-01-26 22:13:00 -0500 |
---|---|---|
committer | Paul Walmsley <paul@pwsan.com> | 2010-01-26 22:13:00 -0500 |
commit | e909d62a8afda7a224a7e322cf2f387d69ca771f (patch) | |
tree | 7d082ca294ac927fc3599900f291d7ccdc80e713 /arch/arm/mach-omap2/powerdomain.c | |
parent | 3d309cdef37e238c108cade95a8192d5688bd56a (diff) |
OMAP clockdomain/powerdomain: remove runtime register/unregister
OMAP clockdomains and powerdomains are currently defined statically,
only registered at boot, and never unregistered, so we can remove the
unregister function and the locking. A variant of this was originally
suggested a while ago by Dmitry Baryshkov <dbaryshkov@gmail.com>.
This version of this patch contains an additional fix from Kevin Hilman
<khilman@deeprootsystems.com> to address one of the pwrdm_for_each_nolock()
users in mach-omap2/pm-debug.c. Thanks Kevin.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Dmitry Baryshkov <dbaryshkov@gmail.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Diffstat (limited to 'arch/arm/mach-omap2/powerdomain.c')
-rw-r--r-- | arch/arm/mach-omap2/powerdomain.c | 178 |
1 files changed, 45 insertions, 133 deletions
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c index e8e8d8872a0e..411361f97eda 100644 --- a/arch/arm/mach-omap2/powerdomain.c +++ b/arch/arm/mach-omap2/powerdomain.c | |||
@@ -80,13 +80,6 @@ static u16 pwrstst_reg_offs; | |||
80 | /* pwrdm_list contains all registered struct powerdomains */ | 80 | /* pwrdm_list contains all registered struct powerdomains */ |
81 | static LIST_HEAD(pwrdm_list); | 81 | static LIST_HEAD(pwrdm_list); |
82 | 82 | ||
83 | /* | ||
84 | * pwrdm_rwlock protects pwrdm_list add and del ops - also reused to | ||
85 | * protect pwrdm_clkdms[] during clkdm add/del ops | ||
86 | */ | ||
87 | static DEFINE_RWLOCK(pwrdm_rwlock); | ||
88 | |||
89 | |||
90 | /* Private functions */ | 83 | /* Private functions */ |
91 | 84 | ||
92 | static struct powerdomain *_pwrdm_lookup(const char *name) | 85 | static struct powerdomain *_pwrdm_lookup(const char *name) |
@@ -105,6 +98,42 @@ static struct powerdomain *_pwrdm_lookup(const char *name) | |||
105 | return pwrdm; | 98 | return pwrdm; |
106 | } | 99 | } |
107 | 100 | ||
101 | /** | ||
102 | * _pwrdm_register - register a powerdomain | ||
103 | * @pwrdm: struct powerdomain * to register | ||
104 | * | ||
105 | * Adds a powerdomain to the internal powerdomain list. Returns | ||
106 | * -EINVAL if given a null pointer, -EEXIST if a powerdomain is | ||
107 | * already registered by the provided name, or 0 upon success. | ||
108 | */ | ||
109 | static int _pwrdm_register(struct powerdomain *pwrdm) | ||
110 | { | ||
111 | int i; | ||
112 | |||
113 | if (!pwrdm) | ||
114 | return -EINVAL; | ||
115 | |||
116 | if (!omap_chip_is(pwrdm->omap_chip)) | ||
117 | return -EINVAL; | ||
118 | |||
119 | if (_pwrdm_lookup(pwrdm->name)) | ||
120 | return -EEXIST; | ||
121 | |||
122 | list_add(&pwrdm->node, &pwrdm_list); | ||
123 | |||
124 | /* Initialize the powerdomain's state counter */ | ||
125 | for (i = 0; i < 4; i++) | ||
126 | pwrdm->state_counter[i] = 0; | ||
127 | |||
128 | pwrdm_wait_transition(pwrdm); | ||
129 | pwrdm->state = pwrdm_read_pwrst(pwrdm); | ||
130 | pwrdm->state_counter[pwrdm->state] = 1; | ||
131 | |||
132 | pr_debug("powerdomain: registered %s\n", pwrdm->name); | ||
133 | |||
134 | return 0; | ||
135 | } | ||
136 | |||
108 | static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag) | 137 | static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag) |
109 | { | 138 | { |
110 | 139 | ||
@@ -152,19 +181,6 @@ static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused) | |||
152 | return 0; | 181 | return 0; |
153 | } | 182 | } |
154 | 183 | ||
155 | static __init void _pwrdm_setup(struct powerdomain *pwrdm) | ||
156 | { | ||
157 | int i; | ||
158 | |||
159 | for (i = 0; i < PWRDM_MAX_PWRSTS; i++) | ||
160 | pwrdm->state_counter[i] = 0; | ||
161 | |||
162 | pwrdm_wait_transition(pwrdm); | ||
163 | pwrdm->state = pwrdm_read_pwrst(pwrdm); | ||
164 | pwrdm->state_counter[pwrdm->state] = 1; | ||
165 | |||
166 | } | ||
167 | |||
168 | /* Public functions */ | 184 | /* Public functions */ |
169 | 185 | ||
170 | /** | 186 | /** |
@@ -192,73 +208,12 @@ void pwrdm_init(struct powerdomain **pwrdm_list) | |||
192 | } | 208 | } |
193 | 209 | ||
194 | if (pwrdm_list) { | 210 | if (pwrdm_list) { |
195 | for (p = pwrdm_list; *p; p++) { | 211 | for (p = pwrdm_list; *p; p++) |
196 | pwrdm_register(*p); | 212 | _pwrdm_register(*p); |
197 | _pwrdm_setup(*p); | ||
198 | } | ||
199 | } | 213 | } |
200 | } | 214 | } |
201 | 215 | ||
202 | /** | 216 | /** |
203 | * pwrdm_register - register a powerdomain | ||
204 | * @pwrdm: struct powerdomain * to register | ||
205 | * | ||
206 | * Adds a powerdomain to the internal powerdomain list. Returns | ||
207 | * -EINVAL if given a null pointer, -EEXIST if a powerdomain is | ||
208 | * already registered by the provided name, or 0 upon success. | ||
209 | */ | ||
210 | int pwrdm_register(struct powerdomain *pwrdm) | ||
211 | { | ||
212 | unsigned long flags; | ||
213 | int ret = -EINVAL; | ||
214 | |||
215 | if (!pwrdm) | ||
216 | return -EINVAL; | ||
217 | |||
218 | if (!omap_chip_is(pwrdm->omap_chip)) | ||
219 | return -EINVAL; | ||
220 | |||
221 | write_lock_irqsave(&pwrdm_rwlock, flags); | ||
222 | if (_pwrdm_lookup(pwrdm->name)) { | ||
223 | ret = -EEXIST; | ||
224 | goto pr_unlock; | ||
225 | } | ||
226 | |||
227 | list_add(&pwrdm->node, &pwrdm_list); | ||
228 | |||
229 | pr_debug("powerdomain: registered %s\n", pwrdm->name); | ||
230 | ret = 0; | ||
231 | |||
232 | pr_unlock: | ||
233 | write_unlock_irqrestore(&pwrdm_rwlock, flags); | ||
234 | |||
235 | return ret; | ||
236 | } | ||
237 | |||
238 | /** | ||
239 | * pwrdm_unregister - unregister a powerdomain | ||
240 | * @pwrdm: struct powerdomain * to unregister | ||
241 | * | ||
242 | * Removes a powerdomain from the internal powerdomain list. Returns | ||
243 | * -EINVAL if pwrdm argument is NULL. | ||
244 | */ | ||
245 | int pwrdm_unregister(struct powerdomain *pwrdm) | ||
246 | { | ||
247 | unsigned long flags; | ||
248 | |||
249 | if (!pwrdm) | ||
250 | return -EINVAL; | ||
251 | |||
252 | write_lock_irqsave(&pwrdm_rwlock, flags); | ||
253 | list_del(&pwrdm->node); | ||
254 | write_unlock_irqrestore(&pwrdm_rwlock, flags); | ||
255 | |||
256 | pr_debug("powerdomain: unregistered %s\n", pwrdm->name); | ||
257 | |||
258 | return 0; | ||
259 | } | ||
260 | |||
261 | /** | ||
262 | * pwrdm_lookup - look up a powerdomain by name, return a pointer | 217 | * pwrdm_lookup - look up a powerdomain by name, return a pointer |
263 | * @name: name of powerdomain | 218 | * @name: name of powerdomain |
264 | * | 219 | * |
@@ -268,20 +223,17 @@ int pwrdm_unregister(struct powerdomain *pwrdm) | |||
268 | struct powerdomain *pwrdm_lookup(const char *name) | 223 | struct powerdomain *pwrdm_lookup(const char *name) |
269 | { | 224 | { |
270 | struct powerdomain *pwrdm; | 225 | struct powerdomain *pwrdm; |
271 | unsigned long flags; | ||
272 | 226 | ||
273 | if (!name) | 227 | if (!name) |
274 | return NULL; | 228 | return NULL; |
275 | 229 | ||
276 | read_lock_irqsave(&pwrdm_rwlock, flags); | ||
277 | pwrdm = _pwrdm_lookup(name); | 230 | pwrdm = _pwrdm_lookup(name); |
278 | read_unlock_irqrestore(&pwrdm_rwlock, flags); | ||
279 | 231 | ||
280 | return pwrdm; | 232 | return pwrdm; |
281 | } | 233 | } |
282 | 234 | ||
283 | /** | 235 | /** |
284 | * pwrdm_for_each_nolock - call function on each registered clockdomain | 236 | * pwrdm_for_each - call function on each registered clockdomain |
285 | * @fn: callback function * | 237 | * @fn: callback function * |
286 | * | 238 | * |
287 | * Call the supplied function for each registered powerdomain. The | 239 | * Call the supplied function for each registered powerdomain. The |
@@ -290,8 +242,8 @@ struct powerdomain *pwrdm_lookup(const char *name) | |||
290 | * should be 0 for success or anything else to indicate failure; or -EINVAL if | 242 | * should be 0 for success or anything else to indicate failure; or -EINVAL if |
291 | * the function pointer is null. | 243 | * the function pointer is null. |
292 | */ | 244 | */ |
293 | int pwrdm_for_each_nolock(int (*fn)(struct powerdomain *pwrdm, void *user), | 245 | int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user), |
294 | void *user) | 246 | void *user) |
295 | { | 247 | { |
296 | struct powerdomain *temp_pwrdm; | 248 | struct powerdomain *temp_pwrdm; |
297 | int ret = 0; | 249 | int ret = 0; |
@@ -309,28 +261,6 @@ int pwrdm_for_each_nolock(int (*fn)(struct powerdomain *pwrdm, void *user), | |||
309 | } | 261 | } |
310 | 262 | ||
311 | /** | 263 | /** |
312 | * pwrdm_for_each - call function on each registered clockdomain | ||
313 | * @fn: callback function * | ||
314 | * | ||
315 | * This function is the same as 'pwrdm_for_each_nolock()', but keeps the | ||
316 | * &pwrdm_rwlock locked for reading, so no powerdomain structure manipulation | ||
317 | * functions should be called from the callback, although hardware powerdomain | ||
318 | * control functions are fine. | ||
319 | */ | ||
320 | int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user), | ||
321 | void *user) | ||
322 | { | ||
323 | unsigned long flags; | ||
324 | int ret; | ||
325 | |||
326 | read_lock_irqsave(&pwrdm_rwlock, flags); | ||
327 | ret = pwrdm_for_each_nolock(fn, user); | ||
328 | read_unlock_irqrestore(&pwrdm_rwlock, flags); | ||
329 | |||
330 | return ret; | ||
331 | } | ||
332 | |||
333 | /** | ||
334 | * pwrdm_add_clkdm - add a clockdomain to a powerdomain | 264 | * pwrdm_add_clkdm - add a clockdomain to a powerdomain |
335 | * @pwrdm: struct powerdomain * to add the clockdomain to | 265 | * @pwrdm: struct powerdomain * to add the clockdomain to |
336 | * @clkdm: struct clockdomain * to associate with a powerdomain | 266 | * @clkdm: struct clockdomain * to associate with a powerdomain |
@@ -342,7 +272,6 @@ int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user), | |||
342 | */ | 272 | */ |
343 | int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm) | 273 | int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm) |
344 | { | 274 | { |
345 | unsigned long flags; | ||
346 | int i; | 275 | int i; |
347 | int ret = -EINVAL; | 276 | int ret = -EINVAL; |
348 | 277 | ||
@@ -352,8 +281,6 @@ int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm) | |||
352 | pr_debug("powerdomain: associating clockdomain %s with powerdomain " | 281 | pr_debug("powerdomain: associating clockdomain %s with powerdomain " |
353 | "%s\n", clkdm->name, pwrdm->name); | 282 | "%s\n", clkdm->name, pwrdm->name); |
354 | 283 | ||
355 | write_lock_irqsave(&pwrdm_rwlock, flags); | ||
356 | |||
357 | for (i = 0; i < PWRDM_MAX_CLKDMS; i++) { | 284 | for (i = 0; i < PWRDM_MAX_CLKDMS; i++) { |
358 | if (!pwrdm->pwrdm_clkdms[i]) | 285 | if (!pwrdm->pwrdm_clkdms[i]) |
359 | break; | 286 | break; |
@@ -378,8 +305,6 @@ int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm) | |||
378 | ret = 0; | 305 | ret = 0; |
379 | 306 | ||
380 | pac_exit: | 307 | pac_exit: |
381 | write_unlock_irqrestore(&pwrdm_rwlock, flags); | ||
382 | |||
383 | return ret; | 308 | return ret; |
384 | } | 309 | } |
385 | 310 | ||
@@ -395,7 +320,6 @@ pac_exit: | |||
395 | */ | 320 | */ |
396 | int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm) | 321 | int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm) |
397 | { | 322 | { |
398 | unsigned long flags; | ||
399 | int ret = -EINVAL; | 323 | int ret = -EINVAL; |
400 | int i; | 324 | int i; |
401 | 325 | ||
@@ -405,8 +329,6 @@ int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm) | |||
405 | pr_debug("powerdomain: dissociating clockdomain %s from powerdomain " | 329 | pr_debug("powerdomain: dissociating clockdomain %s from powerdomain " |
406 | "%s\n", clkdm->name, pwrdm->name); | 330 | "%s\n", clkdm->name, pwrdm->name); |
407 | 331 | ||
408 | write_lock_irqsave(&pwrdm_rwlock, flags); | ||
409 | |||
410 | for (i = 0; i < PWRDM_MAX_CLKDMS; i++) | 332 | for (i = 0; i < PWRDM_MAX_CLKDMS; i++) |
411 | if (pwrdm->pwrdm_clkdms[i] == clkdm) | 333 | if (pwrdm->pwrdm_clkdms[i] == clkdm) |
412 | break; | 334 | break; |
@@ -423,8 +345,6 @@ int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm) | |||
423 | ret = 0; | 345 | ret = 0; |
424 | 346 | ||
425 | pdc_exit: | 347 | pdc_exit: |
426 | write_unlock_irqrestore(&pwrdm_rwlock, flags); | ||
427 | |||
428 | return ret; | 348 | return ret; |
429 | } | 349 | } |
430 | 350 | ||
@@ -435,32 +355,24 @@ pdc_exit: | |||
435 | * | 355 | * |
436 | * Call the supplied function for each clockdomain in the powerdomain | 356 | * Call the supplied function for each clockdomain in the powerdomain |
437 | * 'pwrdm'. The callback function can return anything but 0 to bail | 357 | * 'pwrdm'. The callback function can return anything but 0 to bail |
438 | * out early from the iterator. The callback function is called with | 358 | * out early from the iterator. Returns -EINVAL if presented with |
439 | * the pwrdm_rwlock held for reading, so no powerdomain structure | 359 | * invalid pointers; or passes along the last return value of the |
440 | * manipulation functions should be called from the callback, although | 360 | * callback function, which should be 0 for success or anything else |
441 | * hardware powerdomain control functions are fine. Returns -EINVAL | 361 | * to indicate failure. |
442 | * if presented with invalid pointers; or passes along the last return | ||
443 | * value of the callback function, which should be 0 for success or | ||
444 | * anything else to indicate failure. | ||
445 | */ | 362 | */ |
446 | int pwrdm_for_each_clkdm(struct powerdomain *pwrdm, | 363 | int pwrdm_for_each_clkdm(struct powerdomain *pwrdm, |
447 | int (*fn)(struct powerdomain *pwrdm, | 364 | int (*fn)(struct powerdomain *pwrdm, |
448 | struct clockdomain *clkdm)) | 365 | struct clockdomain *clkdm)) |
449 | { | 366 | { |
450 | unsigned long flags; | ||
451 | int ret = 0; | 367 | int ret = 0; |
452 | int i; | 368 | int i; |
453 | 369 | ||
454 | if (!fn) | 370 | if (!fn) |
455 | return -EINVAL; | 371 | return -EINVAL; |
456 | 372 | ||
457 | read_lock_irqsave(&pwrdm_rwlock, flags); | ||
458 | |||
459 | for (i = 0; i < PWRDM_MAX_CLKDMS && !ret; i++) | 373 | for (i = 0; i < PWRDM_MAX_CLKDMS && !ret; i++) |
460 | ret = (*fn)(pwrdm, pwrdm->pwrdm_clkdms[i]); | 374 | ret = (*fn)(pwrdm, pwrdm->pwrdm_clkdms[i]); |
461 | 375 | ||
462 | read_unlock_irqrestore(&pwrdm_rwlock, flags); | ||
463 | |||
464 | return ret; | 376 | return ret; |
465 | } | 377 | } |
466 | 378 | ||