Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+101 −29
Original line number Diff line number Diff line
@@ -257,43 +257,113 @@ static void _resolve_clkdm_deps(struct clockdomain *clkdm,
/* Public functions */

/**
 * clkdm_init - set up the clockdomain layer
 * @clkdms: optional pointer to an array of clockdomains to register
 * @init_autodeps: optional pointer to an array of autodeps to register
 * @custom_funcs: func pointers for arch specific implementations
 * clkdm_register_platform_funcs - register clockdomain implementation fns
 * @co: func pointers for arch specific implementations
 *
 * Set up internal state.  If a pointer to an array of clockdomains
 * @clkdms was supplied, loop through the list of clockdomains,
 * register all that are available on the current platform. Similarly,
 * if a pointer to an array of clockdomain autodependencies
 * @init_autodeps was provided, register those.  No return value.
 * Register the list of function pointers used to implement the
 * clockdomain functions on different OMAP SoCs.  Should be called
 * before any other clkdm_register*() function.  Returns -EINVAL if
 * @co is null, -EEXIST if platform functions have already been
 * registered, or 0 upon success.
 */
void clkdm_init(struct clockdomain **clkdms,
		struct clkdm_autodep *init_autodeps,
		struct clkdm_ops *custom_funcs)
int clkdm_register_platform_funcs(struct clkdm_ops *co)
{
	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 *clkdm;
	struct clkdm_autodep *autodep = NULL;

	if (!custom_funcs)
		WARN(1, "No custom clkdm functions registered\n");
	else
		arch_clkdm = custom_funcs;
	if (!arch_clkdm)
		return -EACCES;

	if (!cs)
		return -EINVAL;

	if (clkdms)
		for (c = clkdms; *c; c++)
	for (c = cs; *c; 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)
		for (autodep = autodeps; autodep->clkdm.ptr; autodep++)
			_autodep_lookup(autodep);
		return -EEXIST;

	/*
	 * Put all clockdomains into software-supervised mode; PM code
	 * should later enable hardware-supervised mode as appropriate
	autodeps = ia;
	for (a = autodeps; a->clkdm.ptr; a++)
		_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) {
		if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
			clkdm_wakeup(clkdm);
@@ -306,6 +376,8 @@ void clkdm_init(struct clockdomain **clkdms,
		_resolve_clkdm_deps(clkdm, clkdm->sleepdep_srcs);
		clkdm_clear_all_sleepdeps(clkdm);
	}

	return 0;
}

/**
+5 −2
Original line number Diff line number Diff line
@@ -166,8 +166,11 @@ struct clkdm_ops {
	int	(*clkdm_clk_disable)(struct clockdomain *clkdm);
};

void clkdm_init(struct clockdomain **clkdms, struct clkdm_autodep *autodeps,
			struct clkdm_ops *custom_funcs);
int clkdm_register_platform_funcs(struct clkdm_ops *co);
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);

int clkdm_for_each(int (*fn)(struct clockdomain *clkdm, void *user),
+11 −2
Original line number Diff line number Diff line
@@ -857,12 +857,21 @@ static struct clockdomain *clockdomains_omap2[] __initdata = {
	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)
{
	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)
{
	clkdm_init(clockdomains_omap2, clkdm_autodeps, &omap3_clkdm_operations);
	clkdm_register_platform_funcs(&omap3_clkdm_operations);
	omap2_3_clockdomains_init();
}
+4 −1
Original line number Diff line number Diff line
@@ -685,7 +685,10 @@ static struct clockdomain *clockdomains_omap44xx[] __initdata = {
	NULL
};


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();
}