|
@@ -546,6 +546,36 @@ static int _disable_clocks(struct omap_hwmod *oh)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static void _enable_optional_clocks(struct omap_hwmod *oh)
|
|
|
+{
|
|
|
+ struct omap_hwmod_opt_clk *oc;
|
|
|
+ int i;
|
|
|
+
|
|
|
+ pr_debug("omap_hwmod: %s: enabling optional clocks\n", oh->name);
|
|
|
+
|
|
|
+ for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++)
|
|
|
+ if (oc->_clk) {
|
|
|
+ pr_debug("omap_hwmod: enable %s:%s\n", oc->role,
|
|
|
+ oc->_clk->name);
|
|
|
+ clk_enable(oc->_clk);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void _disable_optional_clocks(struct omap_hwmod *oh)
|
|
|
+{
|
|
|
+ struct omap_hwmod_opt_clk *oc;
|
|
|
+ int i;
|
|
|
+
|
|
|
+ pr_debug("omap_hwmod: %s: disabling optional clocks\n", oh->name);
|
|
|
+
|
|
|
+ for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++)
|
|
|
+ if (oc->_clk) {
|
|
|
+ pr_debug("omap_hwmod: disable %s:%s\n", oc->role,
|
|
|
+ oc->_clk->name);
|
|
|
+ clk_disable(oc->_clk);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* _find_mpu_port_index - find hwmod OCP slave port ID intended for MPU use
|
|
|
* @oh: struct omap_hwmod *
|
|
@@ -976,8 +1006,9 @@ static int _read_hardreset(struct omap_hwmod *oh, const char *name)
|
|
|
*/
|
|
|
static int _reset(struct omap_hwmod *oh)
|
|
|
{
|
|
|
- u32 r, v;
|
|
|
+ u32 v;
|
|
|
int c = 0;
|
|
|
+ int ret = 0;
|
|
|
|
|
|
if (!oh->class->sysc ||
|
|
|
!(oh->class->sysc->sysc_flags & SYSC_HAS_SOFTRESET))
|
|
@@ -990,12 +1021,16 @@ static int _reset(struct omap_hwmod *oh)
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
+ /* For some modules, all optionnal clocks need to be enabled as well */
|
|
|
+ if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET)
|
|
|
+ _enable_optional_clocks(oh);
|
|
|
+
|
|
|
pr_debug("omap_hwmod: %s: resetting\n", oh->name);
|
|
|
|
|
|
v = oh->_sysc_cache;
|
|
|
- r = _set_softreset(oh, &v);
|
|
|
- if (r)
|
|
|
- return r;
|
|
|
+ ret = _set_softreset(oh, &v);
|
|
|
+ if (ret)
|
|
|
+ goto dis_opt_clks;
|
|
|
_write_sysconfig(v, oh);
|
|
|
|
|
|
if (oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS)
|
|
@@ -1020,7 +1055,13 @@ static int _reset(struct omap_hwmod *oh)
|
|
|
* _wait_target_ready() or _reset()
|
|
|
*/
|
|
|
|
|
|
- return (c == MAX_MODULE_SOFTRESET_WAIT) ? -ETIMEDOUT : 0;
|
|
|
+ ret = (c == MAX_MODULE_SOFTRESET_WAIT) ? -ETIMEDOUT : 0;
|
|
|
+
|
|
|
+dis_opt_clks:
|
|
|
+ if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET)
|
|
|
+ _disable_optional_clocks(oh);
|
|
|
+
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
/**
|