Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 303011
b: refs/heads/master
c: 747834a
h: refs/heads/master
i:
  303009: f6f2d2d
  303007: 0b2906a
v: v3
  • Loading branch information
Paul Walmsley committed Apr 19, 2012
1 parent 3376651 commit 234f712
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 57 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 64813c3fa68fc3e93e99187d313126710d7c4b0d
refs/heads/master: 747834ab83475f47878c68954d913e27124e4391
139 changes: 83 additions & 56 deletions trunk/arch/arm/mach-omap2/omap_hwmod.c
Original file line number Diff line number Diff line change
Expand Up @@ -780,39 +780,6 @@ static int _omap4_wait_target_disable(struct omap_hwmod *oh)
oh->prcm.omap4.clkctrl_offs);
}

/**
* _omap4_disable_module - enable CLKCTRL modulemode on OMAP4
* @oh: struct omap_hwmod *
*
* Disable the PRCM module mode related to the hwmod @oh.
* Return EINVAL if the modulemode is not supported and 0 in case of success.
*/
static int _omap4_disable_module(struct omap_hwmod *oh)
{
int v;

/* The module mode does not exist prior OMAP4 */
if (!cpu_is_omap44xx())
return -EINVAL;

if (!oh->clkdm || !oh->prcm.omap4.modulemode)
return -EINVAL;

pr_debug("omap_hwmod: %s: %s\n", oh->name, __func__);

omap4_cminst_module_disable(oh->clkdm->prcm_partition,
oh->clkdm->cm_inst,
oh->clkdm->clkdm_offs,
oh->prcm.omap4.clkctrl_offs);

v = _omap4_wait_target_disable(oh);
if (v)
pr_warn("omap_hwmod: %s: _wait_target_disable failed\n",
oh->name);

return 0;
}

/**
* _count_mpu_irqs - count the number of MPU IRQ lines associated with @oh
* @oh: struct omap_hwmod *oh
Expand Down Expand Up @@ -1377,6 +1344,66 @@ static int _read_hardreset(struct omap_hwmod *oh, const char *name)
}
}

/**
* _are_any_hardreset_lines_asserted - return true if part of @oh is hard-reset
* @oh: struct omap_hwmod *
*
* If any hardreset line associated with @oh is asserted, then return true.
* Otherwise, if @oh has no hardreset lines associated with it, or if
* no hardreset lines associated with @oh are asserted, then return false.
* This function is used to avoid executing some parts of the IP block
* enable/disable sequence if a hardreset line is set.
*/
static bool _are_any_hardreset_lines_asserted(struct omap_hwmod *oh)
{
int i;

if (oh->rst_lines_cnt == 0)
return false;

for (i = 0; i < oh->rst_lines_cnt; i++)
if (_read_hardreset(oh, oh->rst_lines[i].name) > 0)
return true;

return false;
}

/**
* _omap4_disable_module - enable CLKCTRL modulemode on OMAP4
* @oh: struct omap_hwmod *
*
* Disable the PRCM module mode related to the hwmod @oh.
* Return EINVAL if the modulemode is not supported and 0 in case of success.
*/
static int _omap4_disable_module(struct omap_hwmod *oh)
{
int v;

/* The module mode does not exist prior OMAP4 */
if (!cpu_is_omap44xx())
return -EINVAL;

if (!oh->clkdm || !oh->prcm.omap4.modulemode)
return -EINVAL;

pr_debug("omap_hwmod: %s: %s\n", oh->name, __func__);

omap4_cminst_module_disable(oh->clkdm->prcm_partition,
oh->clkdm->cm_inst,
oh->clkdm->clkdm_offs,
oh->prcm.omap4.clkctrl_offs);

if (_are_any_hardreset_lines_asserted(oh))
return 0;

v = _omap4_wait_target_disable(oh);
if (v)
pr_warn("omap_hwmod: %s: _wait_target_disable failed\n",
oh->name);

return 0;
}

/**
* _ocp_softreset - reset an omap_hwmod via the OCP_SYSCONFIG bit
* @oh: struct omap_hwmod *
Expand Down Expand Up @@ -1528,7 +1555,7 @@ static int _reset(struct omap_hwmod *oh)
*/
static int _enable(struct omap_hwmod *oh)
{
int r, i;
int r;
int hwsup = 0;

pr_debug("omap_hwmod: %s: enabling\n", oh->name);
Expand Down Expand Up @@ -1560,14 +1587,16 @@ static int _enable(struct omap_hwmod *oh)
}

/*
* If an IP contains HW reset lines, then de-assert them in order
* to allow the module state transition. Otherwise the PRCM will return
* Intransition status, and the init will failed.
* If an IP block contains HW reset lines and any of them are
* asserted, we let integration code associated with that
* block handle the enable. We've received very little
* information on what those driver authors need, and until
* detailed information is provided and the driver code is
* posted to the public lists, this is probably the best we
* can do.
*/
if (oh->_state == _HWMOD_STATE_INITIALIZED ||
oh->_state == _HWMOD_STATE_DISABLED)
for (i = 0; i < oh->rst_lines_cnt; i++)
_deassert_hardreset(oh, oh->rst_lines[i].name);
if (_are_any_hardreset_lines_asserted(oh))
return 0;

/* Mux pins for device runtime if populated */
if (oh->mux && (!oh->mux->enabled ||
Expand Down Expand Up @@ -1642,6 +1671,9 @@ static int _idle(struct omap_hwmod *oh)
return -EINVAL;
}

if (_are_any_hardreset_lines_asserted(oh))
return 0;

if (oh->class->sysc)
_idle_sysc(oh);
_del_initiator_dep(oh, mpu_oh);
Expand Down Expand Up @@ -1724,6 +1756,9 @@ static int _shutdown(struct omap_hwmod *oh)
return -EINVAL;
}

if (_are_any_hardreset_lines_asserted(oh))
return 0;

pr_debug("omap_hwmod: %s: disabling\n", oh->name);

if (oh->class->pre_shutdown) {
Expand Down Expand Up @@ -1866,21 +1901,13 @@ static int __init _setup_reset(struct omap_hwmod *oh)
if (oh->_state != _HWMOD_STATE_INITIALIZED)
return -EINVAL;

/*
* In the case of hwmod with hardreset that should not be
* de-assert at boot time, we have to keep the module
* initialized, because we cannot enable it properly with the
* reset asserted. Exit without warning because that behavior
* is expected.
*/
if ((oh->flags & HWMOD_INIT_NO_RESET) && oh->rst_lines_cnt > 0)
return 0;

r = _enable(oh);
if (r) {
pr_warning("omap_hwmod: %s: cannot be enabled (%d)\n",
oh->name, oh->_state);
return 0;
if (oh->rst_lines_cnt == 0) {
r = _enable(oh);
if (r) {
pr_warning("omap_hwmod: %s: cannot be enabled for reset (%d)\n",
oh->name, oh->_state);
return -EINVAL;
}
}

if (!(oh->flags & HWMOD_INIT_NO_RESET))
Expand Down

0 comments on commit 234f712

Please sign in to comment.