Commit 08cb9703 authored by Paul Walmsley's avatar Paul Walmsley

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: default avatarPaul Walmsley <paul@pwsan.com>
parent 057673d8
...@@ -257,43 +257,113 @@ static void _resolve_clkdm_deps(struct clockdomain *clkdm, ...@@ -257,43 +257,113 @@ static void _resolve_clkdm_deps(struct clockdomain *clkdm,
/* Public functions */ /* Public functions */
/** /**
* clkdm_init - set up the clockdomain layer * clkdm_register_platform_funcs - register clockdomain implementation fns
* @clkdms: optional pointer to an array of clockdomains to register * @co: func pointers for arch specific implementations
* @init_autodeps: optional pointer to an array of autodeps to register
* @custom_funcs: func pointers for arch specific implementations
* *
* Set up internal state. If a pointer to an array of clockdomains * Register the list of function pointers used to implement the
* @clkdms was supplied, loop through the list of clockdomains, * clockdomain functions on different OMAP SoCs. Should be called
* register all that are available on the current platform. Similarly, * before any other clkdm_register*() function. Returns -EINVAL if
* if a pointer to an array of clockdomain autodependencies * @co is null, -EEXIST if platform functions have already been
* @init_autodeps was provided, register those. No return value. * registered, or 0 upon success.
*/ */
void clkdm_init(struct clockdomain **clkdms, int clkdm_register_platform_funcs(struct clkdm_ops *co)
struct clkdm_autodep *init_autodeps, {
struct clkdm_ops *custom_funcs) if (!co)
return -EINVAL;
if (arch_clkdm)
return -EEXIST;
arch_clkdm = co;
return 0;
};
/**
* clkdm_register_clkdms - register SoC clockdomains
* @cs: pointer to an array of struct clockdomain to register
*
* Register the clockdomains available on a particular OMAP SoC. Must
* be called after clkdm_register_platform_funcs(). May be called
* multiple times. Returns -EACCES if called before
* clkdm_register_platform_funcs(); -EINVAL if the argument @cs is
* null; or 0 upon success.
*/
int clkdm_register_clkdms(struct clockdomain **cs)
{ {
struct clockdomain **c = NULL; struct clockdomain **c = NULL;
struct clockdomain *clkdm;
struct clkdm_autodep *autodep = NULL;
if (!custom_funcs) if (!arch_clkdm)
WARN(1, "No custom clkdm functions registered\n"); return -EACCES;
else
arch_clkdm = custom_funcs; if (!cs)
return -EINVAL;
if (clkdms) for (c = cs; *c; c++)
for (c = clkdms; *c; c++)
_clkdm_register(*c); _clkdm_register(*c);
autodeps = init_autodeps; return 0;
}
/**
* clkdm_register_autodeps - register autodeps (if required)
* @ia: pointer to a static array of struct clkdm_autodep to register
*
* Register clockdomain "automatic dependencies." These are
* clockdomain wakeup and sleep dependencies that are automatically
* added whenever the first clock inside a clockdomain is enabled, and
* removed whenever the last clock inside a clockdomain is disabled.
* These are currently only used on OMAP3 devices, and are deprecated,
* since they waste energy. However, until the OMAP2/3 IP block
* enable/disable sequence can be converted to match the OMAP4
* sequence, they are needed.
*
* Must be called only after all of the SoC clockdomains are
* registered, since the function will resolve autodep clockdomain
* names into clockdomain pointers.
*
* The struct clkdm_autodep @ia array must be static, as this function
* does not copy the array elements.
*
* Returns -EACCES if called before any clockdomains have been
* registered, -EINVAL if called with a null @ia argument, -EEXIST if
* autodeps have already been registered, or 0 upon success.
*/
int clkdm_register_autodeps(struct clkdm_autodep *ia)
{
struct clkdm_autodep *a = NULL;
if (list_empty(&clkdm_list))
return -EACCES;
if (!ia)
return -EINVAL;
if (autodeps) if (autodeps)
for (autodep = autodeps; autodep->clkdm.ptr; autodep++) return -EEXIST;
_autodep_lookup(autodep);
/* autodeps = ia;
* Put all clockdomains into software-supervised mode; PM code for (a = autodeps; a->clkdm.ptr; a++)
* should later enable hardware-supervised mode as appropriate _autodep_lookup(a);
return 0;
}
/**
* clkdm_complete_init - set up the clockdomain layer
*
* Put all clockdomains into software-supervised mode; PM code should
* later enable hardware-supervised mode as appropriate. Must be
* called after clkdm_register_clkdms(). Returns -EACCES if called
* before clkdm_register_clkdms(), or 0 upon success.
*/ */
int clkdm_complete_init(void)
{
struct clockdomain *clkdm;
if (list_empty(&clkdm_list))
return -EACCES;
list_for_each_entry(clkdm, &clkdm_list, node) { list_for_each_entry(clkdm, &clkdm_list, node) {
if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
clkdm_wakeup(clkdm); clkdm_wakeup(clkdm);
...@@ -306,6 +376,8 @@ void clkdm_init(struct clockdomain **clkdms, ...@@ -306,6 +376,8 @@ void clkdm_init(struct clockdomain **clkdms,
_resolve_clkdm_deps(clkdm, clkdm->sleepdep_srcs); _resolve_clkdm_deps(clkdm, clkdm->sleepdep_srcs);
clkdm_clear_all_sleepdeps(clkdm); clkdm_clear_all_sleepdeps(clkdm);
} }
return 0;
} }
/** /**
......
...@@ -166,8 +166,11 @@ struct clkdm_ops { ...@@ -166,8 +166,11 @@ struct clkdm_ops {
int (*clkdm_clk_disable)(struct clockdomain *clkdm); int (*clkdm_clk_disable)(struct clockdomain *clkdm);
}; };
void clkdm_init(struct clockdomain **clkdms, struct clkdm_autodep *autodeps, int clkdm_register_platform_funcs(struct clkdm_ops *co);
struct clkdm_ops *custom_funcs); int clkdm_register_autodeps(struct clkdm_autodep *ia);
int clkdm_register_clkdms(struct clockdomain **c);
int clkdm_complete_init(void);
struct clockdomain *clkdm_lookup(const char *name); struct clockdomain *clkdm_lookup(const char *name);
int clkdm_for_each(int (*fn)(struct clockdomain *clkdm, void *user), int clkdm_for_each(int (*fn)(struct clockdomain *clkdm, void *user),
......
...@@ -857,12 +857,21 @@ static struct clockdomain *clockdomains_omap2[] __initdata = { ...@@ -857,12 +857,21 @@ static struct clockdomain *clockdomains_omap2[] __initdata = {
NULL, NULL,
}; };
static void __init omap2_3_clockdomains_init(void)
{
clkdm_register_clkdms(clockdomains_omap2);
clkdm_register_autodeps(clkdm_autodeps);
clkdm_complete_init();
}
void __init omap2xxx_clockdomains_init(void) void __init omap2xxx_clockdomains_init(void)
{ {
clkdm_init(clockdomains_omap2, clkdm_autodeps, &omap2_clkdm_operations); clkdm_register_platform_funcs(&omap2_clkdm_operations);
omap2_3_clockdomains_init();
} }
void __init omap3xxx_clockdomains_init(void) void __init omap3xxx_clockdomains_init(void)
{ {
clkdm_init(clockdomains_omap2, clkdm_autodeps, &omap3_clkdm_operations); clkdm_register_platform_funcs(&omap3_clkdm_operations);
omap2_3_clockdomains_init();
} }
...@@ -685,7 +685,10 @@ static struct clockdomain *clockdomains_omap44xx[] __initdata = { ...@@ -685,7 +685,10 @@ static struct clockdomain *clockdomains_omap44xx[] __initdata = {
NULL NULL
}; };
void __init omap44xx_clockdomains_init(void) void __init omap44xx_clockdomains_init(void)
{ {
clkdm_init(clockdomains_omap44xx, NULL, &omap4_clkdm_operations); clkdm_register_platform_funcs(&omap4_clkdm_operations);
clkdm_register_clkdms(clockdomains_omap44xx);
clkdm_complete_init();
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment