Commit 381d033a authored by Paul Walmsley's avatar Paul Walmsley

ARM: OMAP2+: hwmod: reorganize and document the initialization process

Reorganize the code involved in initializing the internal data for
each hwmod to make it easier to read and maintain.  This involves
improving documentation and removing some duplicated and unnecessary
code.
Signed-off-by: default avatarPaul Walmsley <paul@pwsan.com>
Cc: Benoît Cousson <b-cousson@ti.com>
parent 30e105c0
...@@ -1768,6 +1768,56 @@ static int _shutdown(struct omap_hwmod *oh) ...@@ -1768,6 +1768,56 @@ static int _shutdown(struct omap_hwmod *oh)
return 0; return 0;
} }
/**
* _init_mpu_rt_base - populate the virtual address for a hwmod
* @oh: struct omap_hwmod * to locate the virtual address
*
* Cache the virtual address used by the MPU to access this IP block's
* registers. This address is needed early so the OCP registers that
* are part of the device's address space can be ioremapped properly.
* No return value.
*/
static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data)
{
if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
return;
oh->_mpu_rt_va = _find_mpu_rt_base(oh, oh->_mpu_port_index);
}
/**
* _init - initialize internal data for the hwmod @oh
* @oh: struct omap_hwmod *
* @n: (unused)
*
* Look up the clocks and the address space used by the MPU to access
* registers belonging to the hwmod @oh. @oh must already be
* registered at this point. This is the first of two phases for
* hwmod initialization. Code called here does not touch any hardware
* registers, it simply prepares internal data structures. Returns 0
* upon success or if the hwmod isn't registered, or -EINVAL upon
* failure.
*/
static int __init _init(struct omap_hwmod *oh, void *data)
{
int r;
if (oh->_state != _HWMOD_STATE_REGISTERED)
return 0;
_init_mpu_rt_base(oh, NULL);
r = _init_clocks(oh, NULL);
if (IS_ERR_VALUE(r)) {
WARN(1, "omap_hwmod: %s: couldn't init clocks\n", oh->name);
return -EINVAL;
}
oh->_state = _HWMOD_STATE_INITIALIZED;
return 0;
}
/** /**
* _setup - do initial configuration of omap_hwmod * _setup - do initial configuration of omap_hwmod
* @oh: struct omap_hwmod * * @oh: struct omap_hwmod *
...@@ -1780,7 +1830,7 @@ static int _setup(struct omap_hwmod *oh, void *data) ...@@ -1780,7 +1830,7 @@ static int _setup(struct omap_hwmod *oh, void *data)
int i, r; int i, r;
u8 postsetup_state; u8 postsetup_state;
if (oh->_state != _HWMOD_STATE_CLKS_INITED) if (oh->_state != _HWMOD_STATE_INITIALIZED)
return 0; return 0;
/* Set iclk autoidle mode */ /* Set iclk autoidle mode */
...@@ -2052,96 +2102,69 @@ int __init omap_hwmod_register(struct omap_hwmod **ohs) ...@@ -2052,96 +2102,69 @@ int __init omap_hwmod_register(struct omap_hwmod **ohs)
return 0; return 0;
} }
/* /**
* _populate_mpu_rt_base - populate the virtual address for a hwmod * _ensure_mpu_hwmod_is_setup - ensure the MPU SS hwmod is init'ed and set up
* @oh: pointer to the hwmod currently being set up (usually not the MPU)
* *
* Must be called only from omap_hwmod_setup_*() so ioremap works properly. * If the hwmod data corresponding to the MPU subsystem IP block
* Assumes the caller takes care of locking if needed. * hasn't been initialized and set up yet, do so now. This must be
* done first since sleep dependencies may be added from other hwmods
* to the MPU. Intended to be called only by omap_hwmod_setup*(). No
* return value.
*/ */
static int __init _populate_mpu_rt_base(struct omap_hwmod *oh, void *data) static void __init _ensure_mpu_hwmod_is_setup(struct omap_hwmod *oh)
{ {
if (oh->_state != _HWMOD_STATE_REGISTERED) if (!mpu_oh || mpu_oh->_state == _HWMOD_STATE_UNKNOWN)
return 0; pr_err("omap_hwmod: %s: MPU initiator hwmod %s not yet registered\n",
__func__, MPU_INITIATOR_NAME);
if (oh->_int_flags & _HWMOD_NO_MPU_PORT) else if (mpu_oh->_state == _HWMOD_STATE_REGISTERED && oh != mpu_oh)
return 0; omap_hwmod_setup_one(MPU_INITIATOR_NAME);
oh->_mpu_rt_va = _find_mpu_rt_base(oh, oh->_mpu_port_index);
return 0;
} }
/** /**
* omap_hwmod_setup_one - set up a single hwmod * omap_hwmod_setup_one - set up a single hwmod
* @oh_name: const char * name of the already-registered hwmod to set up * @oh_name: const char * name of the already-registered hwmod to set up
* *
* Must be called after omap2_clk_init(). Resolves the struct clk * Initialize and set up a single hwmod. Intended to be used for a
* names to struct clk pointers for each registered omap_hwmod. Also * small number of early devices, such as the timer IP blocks used for
* calls _setup() on each hwmod. Returns -EINVAL upon error or 0 upon * the scheduler clock. Must be called after omap2_clk_init().
* success. * Resolves the struct clk names to struct clk pointers for each
* registered omap_hwmod. Also calls _setup() on each hwmod. Returns
* -EINVAL upon error or 0 upon success.
*/ */
int __init omap_hwmod_setup_one(const char *oh_name) int __init omap_hwmod_setup_one(const char *oh_name)
{ {
struct omap_hwmod *oh; struct omap_hwmod *oh;
int r;
pr_debug("omap_hwmod: %s: %s\n", oh_name, __func__); pr_debug("omap_hwmod: %s: %s\n", oh_name, __func__);
if (!mpu_oh) {
pr_err("omap_hwmod: %s: cannot setup_one: MPU initiator hwmod %s not yet registered\n",
oh_name, MPU_INITIATOR_NAME);
return -EINVAL;
}
oh = _lookup(oh_name); oh = _lookup(oh_name);
if (!oh) { if (!oh) {
WARN(1, "omap_hwmod: %s: hwmod not yet registered\n", oh_name); WARN(1, "omap_hwmod: %s: hwmod not yet registered\n", oh_name);
return -EINVAL; return -EINVAL;
} }
if (mpu_oh->_state == _HWMOD_STATE_REGISTERED && oh != mpu_oh) _ensure_mpu_hwmod_is_setup(oh);
omap_hwmod_setup_one(MPU_INITIATOR_NAME);
r = _populate_mpu_rt_base(oh, NULL);
if (IS_ERR_VALUE(r)) {
WARN(1, "omap_hwmod: %s: couldn't set mpu_rt_base\n", oh_name);
return -EINVAL;
}
r = _init_clocks(oh, NULL);
if (IS_ERR_VALUE(r)) {
WARN(1, "omap_hwmod: %s: couldn't init clocks\n", oh_name);
return -EINVAL;
}
_init(oh, NULL);
_setup(oh, NULL); _setup(oh, NULL);
return 0; return 0;
} }
/** /**
* omap_hwmod_setup - do some post-clock framework initialization * omap_hwmod_setup_all - set up all registered IP blocks
* *
* Must be called after omap2_clk_init(). Resolves the struct clk names * Initialize and set up all IP blocks registered with the hwmod code.
* to struct clk pointers for each registered omap_hwmod. Also calls * Must be called after omap2_clk_init(). Resolves the struct clk
* _setup() on each hwmod. Returns 0 upon success. * names to struct clk pointers for each registered omap_hwmod. Also
* calls _setup() on each hwmod. Returns 0 upon success.
*/ */
static int __init omap_hwmod_setup_all(void) static int __init omap_hwmod_setup_all(void)
{ {
int r; _ensure_mpu_hwmod_is_setup(NULL);
if (!mpu_oh) {
pr_err("omap_hwmod: %s: MPU initiator hwmod %s not yet registered\n",
__func__, MPU_INITIATOR_NAME);
return -EINVAL;
}
r = omap_hwmod_for_each(_populate_mpu_rt_base, NULL);
r = omap_hwmod_for_each(_init_clocks, NULL);
WARN(IS_ERR_VALUE(r),
"omap_hwmod: %s: _init_clocks failed\n", __func__);
omap_hwmod_for_each(_init, NULL);
omap_hwmod_for_each(_setup, NULL); omap_hwmod_for_each(_setup, NULL);
return 0; return 0;
......
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