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

Commit 113a7413 authored by Benoit Cousson's avatar Benoit Cousson Committed by Paul Walmsley
Browse files

OMAP2+: clockdomain: Add 2 APIs to control clockdomain from hwmod framework



Duplicate the existing API for clockdomain enable from clock to enable
a clock domain from hwmod framework.
This will be needed when the hwmod framework will move from the current
clock centric approach to the module based approach.

These APIs are returning 0 for the moment for OMAP2 and OMAP3 until
their hwmods are updated with the clksm attribute.

Signed-off-by: default avatarBenoit Cousson <b-cousson@ti.com>
Cc: Kevin Hilman <khilman@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Rajendra Nayak <rnayak@ti.com>
Signed-off-by: default avatarPaul Walmsley <paul@pwsan.com>
parent a5122ff8
Loading
Loading
Loading
Loading
+106 −36
Original line number Diff line number Diff line
@@ -796,7 +796,50 @@ void clkdm_deny_idle(struct clockdomain *clkdm)
}


/* Clockdomain-to-clock framework interface code */
/* Clockdomain-to-clock/hwmod framework interface code */

static int _clkdm_clk_hwmod_enable(struct clockdomain *clkdm)
{
	if (!clkdm || !arch_clkdm || !arch_clkdm->clkdm_clk_enable)
		return -EINVAL;

	/*
	 * For arch's with no autodeps, clkcm_clk_enable
	 * should be called for every clock instance or hwmod that is
	 * enabled, so the clkdm can be force woken up.
	 */
	if ((atomic_inc_return(&clkdm->usecount) > 1) && autodeps)
		return 0;

	arch_clkdm->clkdm_clk_enable(clkdm);
	pwrdm_wait_transition(clkdm->pwrdm.ptr);
	pwrdm_clkdm_state_switch(clkdm);

	pr_debug("clockdomain: clkdm %s: enabled\n", clkdm->name);

	return 0;
}

static int _clkdm_clk_hwmod_disable(struct clockdomain *clkdm)
{
	if (!clkdm || !arch_clkdm || !arch_clkdm->clkdm_clk_disable)
		return -EINVAL;

	if (atomic_read(&clkdm->usecount) == 0) {
		WARN_ON(1); /* underflow */
		return -ERANGE;
	}

	if (atomic_dec_return(&clkdm->usecount) > 0)
		return 0;

	arch_clkdm->clkdm_clk_disable(clkdm);
	pwrdm_clkdm_state_switch(clkdm);

	pr_debug("clockdomain: clkdm %s: disabled\n", clkdm->name);

	return 0;
}

/**
 * clkdm_clk_enable - add an enabled downstream clock to this clkdm
@@ -819,24 +862,10 @@ int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
	 * downstream clocks for debugging purposes?
	 */

	if (!clkdm || !clk)
		return -EINVAL;

	if (!arch_clkdm || !arch_clkdm->clkdm_clk_enable)
	if (!clk)
		return -EINVAL;

	if (atomic_inc_return(&clkdm->usecount) > 1)
		return 0;

	/* Clockdomain now has one enabled downstream clock */

	pr_debug("clockdomain: clkdm %s: clk %s now enabled\n", clkdm->name,
		 clk->name);

	arch_clkdm->clkdm_clk_enable(clkdm);
	pwrdm_clkdm_state_switch(clkdm);

	return 0;
	return _clkdm_clk_hwmod_enable(clkdm);
}

/**
@@ -849,9 +878,8 @@ int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
 * clockdomain usecount goes to 0, put the clockdomain to sleep
 * (software-supervised mode) or remove the clkdm autodependencies
 * (hardware-supervised mode).  Returns -EINVAL if passed null
 * pointers; -ERANGE if the @clkdm usecount underflows and debugging
 * is enabled; or returns 0 upon success or if the clockdomain is in
 * hwsup idle mode.
 * pointers; -ERANGE if the @clkdm usecount underflows; or returns 0
 * upon success or if the clockdomain is in hwsup idle mode.
 */
int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
{
@@ -860,30 +888,72 @@ int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
	 * downstream clocks for debugging purposes?
	 */

	if (!clkdm || !clk)
		return -EINVAL;

	if (!arch_clkdm || !arch_clkdm->clkdm_clk_disable)
	if (!clk)
		return -EINVAL;

#ifdef DEBUG
	if (atomic_read(&clkdm->usecount) == 0) {
		WARN_ON(1); /* underflow */
		return -ERANGE;
	return _clkdm_clk_hwmod_disable(clkdm);
}
#endif

	if (atomic_dec_return(&clkdm->usecount) > 0)
/**
 * clkdm_hwmod_enable - add an enabled downstream hwmod to this clkdm
 * @clkdm: struct clockdomain *
 * @oh: struct omap_hwmod * of the enabled downstream hwmod
 *
 * Increment the usecount of the clockdomain @clkdm and ensure that it
 * is awake before @oh is enabled. Intended to be called by
 * module_enable() code.
 * If the clockdomain is in software-supervised idle mode, force the
 * clockdomain to wake.  If the clockdomain is in hardware-supervised idle
 * mode, add clkdm-pwrdm autodependencies, to ensure that devices in the
 * clockdomain can be read from/written to by on-chip processors.
 * Returns -EINVAL if passed null pointers;
 * returns 0 upon success or if the clockdomain is in hwsup idle mode.
 */
int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh)
{
	/* The clkdm attribute does not exist yet prior OMAP4 */
	if (cpu_is_omap24xx() || cpu_is_omap34xx())
		return 0;

	/* All downstream clocks of this clockdomain are now disabled */
	/*
	 * XXX Rewrite this code to maintain a list of enabled
	 * downstream hwmods for debugging purposes?
	 */

	pr_debug("clockdomain: clkdm %s: clk %s now disabled\n", clkdm->name,
		 clk->name);
	if (!oh)
		return -EINVAL;

	arch_clkdm->clkdm_clk_disable(clkdm);
	pwrdm_clkdm_state_switch(clkdm);
	return _clkdm_clk_hwmod_enable(clkdm);
}

/**
 * clkdm_hwmod_disable - remove an enabled downstream hwmod from this clkdm
 * @clkdm: struct clockdomain *
 * @oh: struct omap_hwmod * of the disabled downstream hwmod
 *
 * Decrement the usecount of this clockdomain @clkdm when @oh is
 * disabled. Intended to be called by module_disable() code.
 * If the clockdomain usecount goes to 0, put the clockdomain to sleep
 * (software-supervised mode) or remove the clkdm autodependencies
 * (hardware-supervised mode).
 * Returns -EINVAL if passed null pointers; -ERANGE if the @clkdm usecount
 * underflows; or returns 0 upon success or if the clockdomain is in hwsup
 * idle mode.
 */
int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh)
{
	/* The clkdm attribute does not exist yet prior OMAP4 */
	if (cpu_is_omap24xx() || cpu_is_omap34xx())
		return 0;

	/*
	 * XXX Rewrite this code to maintain a list of enabled
	 * downstream hwmods for debugging purposes?
	 */

	if (!oh)
		return -EINVAL;

	return _clkdm_clk_hwmod_disable(clkdm);
}
+3 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@

#include "powerdomain.h"
#include <plat/clock.h>
#include <plat/omap_hwmod.h>
#include <plat/cpu.h>

/*
@@ -183,6 +184,8 @@ int clkdm_sleep(struct clockdomain *clkdm);

int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk);
int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk);
int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh);
int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh);

extern void __init omap2xxx_clockdomains_init(void);
extern void __init omap3xxx_clockdomains_init(void);