mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-26 11:28:28 +00:00
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: Benoit 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: Paul Walmsley <paul@pwsan.com>
This commit is contained in:
parent
a5122ff8ce
commit
113a74137f
@ -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
|
* 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?
|
* downstream clocks for debugging purposes?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!clkdm || !clk)
|
if (!clk)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (!arch_clkdm || !arch_clkdm->clkdm_clk_enable)
|
return _clkdm_clk_hwmod_enable(clkdm);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -849,9 +878,8 @@ int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
|
|||||||
* clockdomain usecount goes to 0, put the clockdomain to sleep
|
* clockdomain usecount goes to 0, put the clockdomain to sleep
|
||||||
* (software-supervised mode) or remove the clkdm autodependencies
|
* (software-supervised mode) or remove the clkdm autodependencies
|
||||||
* (hardware-supervised mode). Returns -EINVAL if passed null
|
* (hardware-supervised mode). Returns -EINVAL if passed null
|
||||||
* pointers; -ERANGE if the @clkdm usecount underflows and debugging
|
* pointers; -ERANGE if the @clkdm usecount underflows; or returns 0
|
||||||
* is enabled; or returns 0 upon success or if the clockdomain is in
|
* upon success or if the clockdomain is in hwsup idle mode.
|
||||||
* hwsup idle mode.
|
|
||||||
*/
|
*/
|
||||||
int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
|
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?
|
* downstream clocks for debugging purposes?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!clkdm || !clk)
|
if (!clk)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (!arch_clkdm || !arch_clkdm->clkdm_clk_disable)
|
return _clkdm_clk_hwmod_disable(clkdm);
|
||||||
return -EINVAL;
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
/**
|
||||||
if (atomic_read(&clkdm->usecount) == 0) {
|
* clkdm_hwmod_enable - add an enabled downstream hwmod to this clkdm
|
||||||
WARN_ON(1); /* underflow */
|
* @clkdm: struct clockdomain *
|
||||||
return -ERANGE;
|
* @oh: struct omap_hwmod * of the enabled downstream hwmod
|
||||||
}
|
*
|
||||||
#endif
|
* Increment the usecount of the clockdomain @clkdm and ensure that it
|
||||||
|
* is awake before @oh is enabled. Intended to be called by
|
||||||
if (atomic_dec_return(&clkdm->usecount) > 0)
|
* module_enable() code.
|
||||||
return 0;
|
* If the clockdomain is in software-supervised idle mode, force the
|
||||||
|
* clockdomain to wake. If the clockdomain is in hardware-supervised idle
|
||||||
/* All downstream clocks of this clockdomain are now disabled */
|
* mode, add clkdm-pwrdm autodependencies, to ensure that devices in the
|
||||||
|
* clockdomain can be read from/written to by on-chip processors.
|
||||||
pr_debug("clockdomain: clkdm %s: clk %s now disabled\n", clkdm->name,
|
* Returns -EINVAL if passed null pointers;
|
||||||
clk->name);
|
* returns 0 upon success or if the clockdomain is in hwsup idle mode.
|
||||||
|
*/
|
||||||
arch_clkdm->clkdm_clk_disable(clkdm);
|
int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh)
|
||||||
pwrdm_clkdm_state_switch(clkdm);
|
{
|
||||||
|
/* The clkdm attribute does not exist yet prior OMAP4 */
|
||||||
return 0;
|
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_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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#include "powerdomain.h"
|
#include "powerdomain.h"
|
||||||
#include <plat/clock.h>
|
#include <plat/clock.h>
|
||||||
|
#include <plat/omap_hwmod.h>
|
||||||
#include <plat/cpu.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_enable(struct clockdomain *clkdm, struct clk *clk);
|
||||||
int clkdm_clk_disable(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 omap2xxx_clockdomains_init(void);
|
||||||
extern void __init omap3xxx_clockdomains_init(void);
|
extern void __init omap3xxx_clockdomains_init(void);
|
||||||
|
Loading…
Reference in New Issue
Block a user