aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/powerdomain.c
diff options
context:
space:
mode:
authorPaul Walmsley <paul@pwsan.com>2010-01-26 22:13:00 -0500
committerPaul Walmsley <paul@pwsan.com>2010-01-26 22:13:00 -0500
commite909d62a8afda7a224a7e322cf2f387d69ca771f (patch)
tree7d082ca294ac927fc3599900f291d7ccdc80e713 /arch/arm/mach-omap2/powerdomain.c
parent3d309cdef37e238c108cade95a8192d5688bd56a (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.c178
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 */
81static LIST_HEAD(pwrdm_list); 81static 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 */
87static DEFINE_RWLOCK(pwrdm_rwlock);
88
89
90/* Private functions */ 83/* Private functions */
91 84
92static struct powerdomain *_pwrdm_lookup(const char *name) 85static 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 */
109static 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
108static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag) 137static 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
155static __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 */
210int 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
232pr_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 */
245int 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)
268struct powerdomain *pwrdm_lookup(const char *name) 223struct 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 */
293int pwrdm_for_each_nolock(int (*fn)(struct powerdomain *pwrdm, void *user), 245int 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 */
320int 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 */
343int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm) 273int 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
380pac_exit: 307pac_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 */
396int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm) 321int 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
425pdc_exit: 347pdc_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 */
446int pwrdm_for_each_clkdm(struct powerdomain *pwrdm, 363int 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