|
@@ -2334,3 +2334,103 @@ static int _shutdown(struct omap_hwmod *oh)
|
|
|
*/
|
|
|
static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data)
|
|
|
{
|
|
|
+ struct omap_hwmod_addr_space *mem;
|
|
|
+ void __iomem *va_start;
|
|
|
+
|
|
|
+ if (!oh)
|
|
|
+ return;
|
|
|
+
|
|
|
+ _save_mpu_port_index(oh);
|
|
|
+
|
|
|
+ if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
|
|
|
+ return;
|
|
|
+
|
|
|
+ mem = _find_mpu_rt_addr_space(oh);
|
|
|
+ if (!mem) {
|
|
|
+ pr_debug("omap_hwmod: %s: no MPU register target found\n",
|
|
|
+ oh->name);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ va_start = ioremap(mem->pa_start, mem->pa_end - mem->pa_start);
|
|
|
+ if (!va_start) {
|
|
|
+ pr_err("omap_hwmod: %s: Could not ioremap\n", oh->name);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ pr_debug("omap_hwmod: %s: MPU register target at va %p\n",
|
|
|
+ oh->name, va_start);
|
|
|
+
|
|
|
+ oh->_mpu_rt_va = va_start;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * _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_iclk_autoidle - configure an IP block's interface clocks
|
|
|
+ * @oh: struct omap_hwmod *
|
|
|
+ *
|
|
|
+ * Set up the module's interface clocks. XXX This function is still mostly
|
|
|
+ * a stub; implementing this properly requires iclk autoidle usecounting in
|
|
|
+ * the clock code. No return value.
|
|
|
+ */
|
|
|
+static void __init _setup_iclk_autoidle(struct omap_hwmod *oh)
|
|
|
+{
|
|
|
+ struct omap_hwmod_ocp_if *os;
|
|
|
+ struct list_head *p;
|
|
|
+ int i = 0;
|
|
|
+ if (oh->_state != _HWMOD_STATE_INITIALIZED)
|
|
|
+ return;
|
|
|
+
|
|
|
+ p = oh->slave_ports.next;
|
|
|
+
|
|
|
+ while (i < oh->slaves_cnt) {
|
|
|
+ os = _fetch_next_ocp_if(&p, &i);
|
|
|
+ if (!os->_clk)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ if (os->flags & OCPIF_SWSUP_IDLE) {
|
|
|
+ /* XXX omap_iclk_deny_idle(c); */
|
|
|
+ } else {
|
|
|
+ /* XXX omap_iclk_allow_idle(c); */
|
|
|
+ clk_enable(os->_clk);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * _setup_reset - reset an IP block during the setup process
|
|
|
+ * @oh: struct omap_hwmod *
|