diff options
author | Paul Walmsley <paul@pwsan.com> | 2011-09-14 18:01:20 -0400 |
---|---|---|
committer | Paul Walmsley <paul@pwsan.com> | 2011-09-14 18:01:20 -0400 |
commit | 08cb9703e2922db297d8f83ec110bde37823e021 (patch) | |
tree | c76df5dce71b7d8150e7c5c8a98073d5cf9542d2 /arch/arm/mach-omap2/clockdomain.c | |
parent | 057673d8bd4a223c72850d843458cf3d35340bd3 (diff) |
OMAP: clockdomain: split clkdm_init()
In preparation for OMAP_CHIP() removal, split clkdm_init() into four
functions. This allows some of them to be called multiple times: for
example, clkdm_register_clkdms() can be called once to register
clockdomains that are common to a group of SoCs, and once to register
clockdomains that are specific to a single SoC.
The appropriate order to call these functions - which is enforced
by the code - is:
1. clkdm_register_platform_funcs()
2. clkdm_register_clkdms() (can be called multiple times)
3. clkdm_register_autodeps() (optional; deprecated)
4. clkdm_complete_init()
Convert the OMAP2, 3, and 4 clockdomain init code to use these new
functions.
While here, improve documentation, and increase CodingStyle
conformance by shortening some local variable names.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Diffstat (limited to 'arch/arm/mach-omap2/clockdomain.c')
-rw-r--r-- | arch/arm/mach-omap2/clockdomain.c | 130 |
1 files changed, 101 insertions, 29 deletions
diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c index 8f0890685d7b..b73a1dc37dfb 100644 --- a/arch/arm/mach-omap2/clockdomain.c +++ b/arch/arm/mach-omap2/clockdomain.c | |||
@@ -257,43 +257,113 @@ static void _resolve_clkdm_deps(struct clockdomain *clkdm, | |||
257 | /* Public functions */ | 257 | /* Public functions */ |
258 | 258 | ||
259 | /** | 259 | /** |
260 | * clkdm_init - set up the clockdomain layer | 260 | * clkdm_register_platform_funcs - register clockdomain implementation fns |
261 | * @clkdms: optional pointer to an array of clockdomains to register | 261 | * @co: func pointers for arch specific implementations |
262 | * @init_autodeps: optional pointer to an array of autodeps to register | 262 | * |
263 | * @custom_funcs: func pointers for arch specific implementations | 263 | * Register the list of function pointers used to implement the |
264 | * | 264 | * clockdomain functions on different OMAP SoCs. Should be called |
265 | * Set up internal state. If a pointer to an array of clockdomains | 265 | * before any other clkdm_register*() function. Returns -EINVAL if |
266 | * @clkdms was supplied, loop through the list of clockdomains, | 266 | * @co is null, -EEXIST if platform functions have already been |
267 | * register all that are available on the current platform. Similarly, | 267 | * registered, or 0 upon success. |
268 | * if a pointer to an array of clockdomain autodependencies | 268 | */ |
269 | * @init_autodeps was provided, register those. No return value. | 269 | int clkdm_register_platform_funcs(struct clkdm_ops *co) |
270 | { | ||
271 | if (!co) | ||
272 | return -EINVAL; | ||
273 | |||
274 | if (arch_clkdm) | ||
275 | return -EEXIST; | ||
276 | |||
277 | arch_clkdm = co; | ||
278 | |||
279 | return 0; | ||
280 | }; | ||
281 | |||
282 | /** | ||
283 | * clkdm_register_clkdms - register SoC clockdomains | ||
284 | * @cs: pointer to an array of struct clockdomain to register | ||
285 | * | ||
286 | * Register the clockdomains available on a particular OMAP SoC. Must | ||
287 | * be called after clkdm_register_platform_funcs(). May be called | ||
288 | * multiple times. Returns -EACCES if called before | ||
289 | * clkdm_register_platform_funcs(); -EINVAL if the argument @cs is | ||
290 | * null; or 0 upon success. | ||
270 | */ | 291 | */ |
271 | void clkdm_init(struct clockdomain **clkdms, | 292 | int clkdm_register_clkdms(struct clockdomain **cs) |
272 | struct clkdm_autodep *init_autodeps, | ||
273 | struct clkdm_ops *custom_funcs) | ||
274 | { | 293 | { |
275 | struct clockdomain **c = NULL; | 294 | struct clockdomain **c = NULL; |
276 | struct clockdomain *clkdm; | ||
277 | struct clkdm_autodep *autodep = NULL; | ||
278 | 295 | ||
279 | if (!custom_funcs) | 296 | if (!arch_clkdm) |
280 | WARN(1, "No custom clkdm functions registered\n"); | 297 | return -EACCES; |
281 | else | 298 | |
282 | arch_clkdm = custom_funcs; | 299 | if (!cs) |
300 | return -EINVAL; | ||
301 | |||
302 | for (c = cs; *c; c++) | ||
303 | _clkdm_register(*c); | ||
283 | 304 | ||
284 | if (clkdms) | 305 | return 0; |
285 | for (c = clkdms; *c; c++) | 306 | } |
286 | _clkdm_register(*c); | 307 | |
308 | /** | ||
309 | * clkdm_register_autodeps - register autodeps (if required) | ||
310 | * @ia: pointer to a static array of struct clkdm_autodep to register | ||
311 | * | ||
312 | * Register clockdomain "automatic dependencies." These are | ||
313 | * clockdomain wakeup and sleep dependencies that are automatically | ||
314 | * added whenever the first clock inside a clockdomain is enabled, and | ||
315 | * removed whenever the last clock inside a clockdomain is disabled. | ||
316 | * These are currently only used on OMAP3 devices, and are deprecated, | ||
317 | * since they waste energy. However, until the OMAP2/3 IP block | ||
318 | * enable/disable sequence can be converted to match the OMAP4 | ||
319 | * sequence, they are needed. | ||
320 | * | ||
321 | * Must be called only after all of the SoC clockdomains are | ||
322 | * registered, since the function will resolve autodep clockdomain | ||
323 | * names into clockdomain pointers. | ||
324 | * | ||
325 | * The struct clkdm_autodep @ia array must be static, as this function | ||
326 | * does not copy the array elements. | ||
327 | * | ||
328 | * Returns -EACCES if called before any clockdomains have been | ||
329 | * registered, -EINVAL if called with a null @ia argument, -EEXIST if | ||
330 | * autodeps have already been registered, or 0 upon success. | ||
331 | */ | ||
332 | int clkdm_register_autodeps(struct clkdm_autodep *ia) | ||
333 | { | ||
334 | struct clkdm_autodep *a = NULL; | ||
335 | |||
336 | if (list_empty(&clkdm_list)) | ||
337 | return -EACCES; | ||
338 | |||
339 | if (!ia) | ||
340 | return -EINVAL; | ||
287 | 341 | ||
288 | autodeps = init_autodeps; | ||
289 | if (autodeps) | 342 | if (autodeps) |
290 | for (autodep = autodeps; autodep->clkdm.ptr; autodep++) | 343 | return -EEXIST; |
291 | _autodep_lookup(autodep); | 344 | |
345 | autodeps = ia; | ||
346 | for (a = autodeps; a->clkdm.ptr; a++) | ||
347 | _autodep_lookup(a); | ||
348 | |||
349 | return 0; | ||
350 | } | ||
351 | |||
352 | /** | ||
353 | * clkdm_complete_init - set up the clockdomain layer | ||
354 | * | ||
355 | * Put all clockdomains into software-supervised mode; PM code should | ||
356 | * later enable hardware-supervised mode as appropriate. Must be | ||
357 | * called after clkdm_register_clkdms(). Returns -EACCES if called | ||
358 | * before clkdm_register_clkdms(), or 0 upon success. | ||
359 | */ | ||
360 | int clkdm_complete_init(void) | ||
361 | { | ||
362 | struct clockdomain *clkdm; | ||
363 | |||
364 | if (list_empty(&clkdm_list)) | ||
365 | return -EACCES; | ||
292 | 366 | ||
293 | /* | ||
294 | * Put all clockdomains into software-supervised mode; PM code | ||
295 | * should later enable hardware-supervised mode as appropriate | ||
296 | */ | ||
297 | list_for_each_entry(clkdm, &clkdm_list, node) { | 367 | list_for_each_entry(clkdm, &clkdm_list, node) { |
298 | if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) | 368 | if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) |
299 | clkdm_wakeup(clkdm); | 369 | clkdm_wakeup(clkdm); |
@@ -306,6 +376,8 @@ void clkdm_init(struct clockdomain **clkdms, | |||
306 | _resolve_clkdm_deps(clkdm, clkdm->sleepdep_srcs); | 376 | _resolve_clkdm_deps(clkdm, clkdm->sleepdep_srcs); |
307 | clkdm_clear_all_sleepdeps(clkdm); | 377 | clkdm_clear_all_sleepdeps(clkdm); |
308 | } | 378 | } |
379 | |||
380 | return 0; | ||
309 | } | 381 | } |
310 | 382 | ||
311 | /** | 383 | /** |