|
@@ -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)
|
|
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)
|
|
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.
|
|
|
|
- * Assumes the caller takes care of locking if needed.
|
|
|
|
|
|
+ * If the hwmod data corresponding to the MPU subsystem IP block
|
|
|
|
+ * 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)
|
|
|
|
- return 0;
|
|
|
|
-
|
|
|
|
- if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
|
|
|
|
- return 0;
|
|
|
|
-
|
|
|
|
- oh->_mpu_rt_va = _find_mpu_rt_base(oh, oh->_mpu_port_index);
|
|
|
|
-
|
|
|
|
- return 0;
|
|
|
|
|
|
+ if (!mpu_oh || mpu_oh->_state == _HWMOD_STATE_UNKNOWN)
|
|
|
|
+ pr_err("omap_hwmod: %s: MPU initiator hwmod %s not yet registered\n",
|
|
|
|
+ __func__, MPU_INITIATOR_NAME);
|
|
|
|
+ else if (mpu_oh->_state == _HWMOD_STATE_REGISTERED && oh != mpu_oh)
|
|
|
|
+ omap_hwmod_setup_one(MPU_INITIATOR_NAME);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
* 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
|
|
|
|
- * names to struct clk pointers for each registered omap_hwmod. Also
|
|
|
|
- * calls _setup() on each hwmod. Returns -EINVAL upon error or 0 upon
|
|
|
|
- * success.
|
|
|
|
|
|
+ * Initialize and set up a single hwmod. Intended to be used for a
|
|
|
|
+ * small number of early devices, such as the timer IP blocks used for
|
|
|
|
+ * the scheduler clock. Must be called after omap2_clk_init().
|
|
|
|
+ * 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)
|
|
|
|
- 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;
|
|
|
|
- }
|
|
|
|
|
|
+ _ensure_mpu_hwmod_is_setup(oh);
|
|
|
|
|
|
|
|
+ _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
|
|
|
|
- * to struct clk pointers for each registered omap_hwmod. Also calls
|
|
|
|
- * _setup() on each hwmod. Returns 0 upon success.
|
|
|
|
|
|
+ * Initialize and set up all IP blocks registered with the hwmod code.
|
|
|
|
+ * Must be called after omap2_clk_init(). Resolves the struct clk
|
|
|
|
+ * 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;
|
|
|
|
-
|
|
|
|
- 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__);
|
|
|
|
|
|
+ _ensure_mpu_hwmod_is_setup(NULL);
|
|
|
|
|
|
|
|
+ omap_hwmod_for_each(_init, NULL);
|
|
omap_hwmod_for_each(_setup, NULL);
|
|
omap_hwmod_for_each(_setup, NULL);
|
|
|
|
|
|
return 0;
|
|
return 0;
|