Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 303008
b: refs/heads/master
c: 30e105c
h: refs/heads/master
v: v3
  • Loading branch information
Paul Walmsley committed Apr 19, 2012
1 parent 0b2906a commit de5f1f3
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 24 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: f2f5736cf83fff7e95991390b2a4b481818e29b5
refs/heads/master: 30e105c000abbac55602b37f4831437bca5487b0
69 changes: 46 additions & 23 deletions trunk/arch/arm/mach-omap2/omap_hwmod.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* omap_hwmod implementation for OMAP2/3/4
*
* Copyright (C) 2009-2011 Nokia Corporation
* Copyright (C) 2011 Texas Instruments, Inc.
* Copyright (C) 2011-2012 Texas Instruments, Inc.
*
* Paul Walmsley, Benoît Cousson, Kevin Hilman
*
Expand Down Expand Up @@ -1382,9 +1382,9 @@ static int _read_hardreset(struct omap_hwmod *oh, const char *name)
* @oh: struct omap_hwmod *
*
* Resets an omap_hwmod @oh via the OCP_SYSCONFIG bit. hwmod must be
* enabled for this to work. Returns -EINVAL if the hwmod cannot be
* reset this way or if the hwmod is in the wrong state, -ETIMEDOUT if
* the module did not reset in time, or 0 upon success.
* enabled for this to work. Returns -ENOENT if the hwmod cannot be
* reset this way, -EINVAL if the hwmod is in the wrong state,
* -ETIMEDOUT if the module did not reset in time, or 0 upon success.
*
* In OMAP3 a specific SYSSTATUS register is used to get the reset status.
* Starting in OMAP4, some IPs do not have SYSSTATUS registers and instead
Expand All @@ -1401,7 +1401,7 @@ static int _ocp_softreset(struct omap_hwmod *oh)

if (!oh->class->sysc ||
!(oh->class->sysc->sysc_flags & SYSC_HAS_SOFTRESET))
return -EINVAL;
return -ENOENT;

/* clocks must be on for this operation */
if (oh->_state != _HWMOD_STATE_ENABLED) {
Expand Down Expand Up @@ -1462,37 +1462,60 @@ static int _ocp_softreset(struct omap_hwmod *oh)
* _reset - reset an omap_hwmod
* @oh: struct omap_hwmod *
*
* Resets an omap_hwmod @oh. The default software reset mechanism for
* most OMAP IP blocks is triggered via the OCP_SYSCONFIG.SOFTRESET
* bit. However, some hwmods cannot be reset via this method: some
* are not targets and therefore have no OCP header registers to
* access; others (like the IVA) have idiosyncratic reset sequences.
* So for these relatively rare cases, custom reset code can be
* supplied in the struct omap_hwmod_class .reset function pointer.
* Passes along the return value from either _reset() or the custom
* reset function - these must return -EINVAL if the hwmod cannot be
* reset this way or if the hwmod is in the wrong state, -ETIMEDOUT if
* the module did not reset in time, or 0 upon success.
* Resets an omap_hwmod @oh. If the module has a custom reset
* function pointer defined, then call it to reset the IP block, and
* pass along its return value to the caller. Otherwise, if the IP
* block has an OCP_SYSCONFIG register with a SOFTRESET bitfield
* associated with it, call a function to reset the IP block via that
* method, and pass along the return value to the caller. Finally, if
* the IP block has some hardreset lines associated with it, assert
* all of those, but do _not_ deassert them. (This is because driver
* authors have expressed an apparent requirement to control the
* deassertion of the hardreset lines themselves.)
*
* The default software reset mechanism for most OMAP IP blocks is
* triggered via the OCP_SYSCONFIG.SOFTRESET bit. However, some
* hwmods cannot be reset via this method. Some are not targets and
* therefore have no OCP header registers to access. Others (like the
* IVA) have idiosyncratic reset sequences. So for these relatively
* rare cases, custom reset code can be supplied in the struct
* omap_hwmod_class .reset function pointer. Passes along the return
* value from either _ocp_softreset() or the custom reset function -
* these must return -EINVAL if the hwmod cannot be reset this way or
* if the hwmod is in the wrong state, -ETIMEDOUT if the module did
* not reset in time, or 0 upon success.
*/
static int _reset(struct omap_hwmod *oh)
{
int ret;
int i, r;

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

if (oh->class->reset) {
r = oh->class->reset(oh);
} else {
if (oh->rst_lines_cnt > 0) {
for (i = 0; i < oh->rst_lines_cnt; i++)
_assert_hardreset(oh, oh->rst_lines[i].name);
return 0;
} else {
r = _ocp_softreset(oh);
if (r == -ENOENT)
r = 0;
}
}

/*
* XXX We're not resetting modules with hardreset lines
* automatically here. Should we do this also, or just expect
* those modules to define custom reset functions?
* OCP_SYSCONFIG bits need to be reprogrammed after a
* softreset. The _enable() function should be split to avoid
* the rewrite of the OCP_SYSCONFIG register.
*/
ret = (oh->class->reset) ? oh->class->reset(oh) : _ocp_softreset(oh);

if (oh->class->sysc) {
_update_sysc_cache(oh);
_enable_sysc(oh);
}

return ret;
return r;
}

/**
Expand Down

0 comments on commit de5f1f3

Please sign in to comment.