Commit e4dc8f50 authored by Paul Walmsley's avatar Paul Walmsley

OMAP2+: hwmod: allow custom pre-shutdown functions

Some OMAP IP blocks, such as the watchdog timers, cannot be completely
shut down via the standard hwmod shutdown mechanism.  This patch
enables the hwmod data files to supply a pointer to a custom
pre-shutdown function via the struct omap_hwmod_class.pre_shutdown
function pointer.  If the struct omap_hwmod_class.pre_shutdown
function pointer is non-null, the function will be executed before the
existing hwmod shutdown code runs.
Signed-off-by: default avatarPaul Walmsley <paul@pwsan.com>
Cc: Benoît Cousson <b-cousson@ti.com>
parent 4805734b
...@@ -1261,6 +1261,9 @@ int _omap_hwmod_idle(struct omap_hwmod *oh) ...@@ -1261,6 +1261,9 @@ int _omap_hwmod_idle(struct omap_hwmod *oh)
*/ */
static int _shutdown(struct omap_hwmod *oh) static int _shutdown(struct omap_hwmod *oh)
{ {
int ret;
u8 prev_state;
if (oh->_state != _HWMOD_STATE_IDLE && if (oh->_state != _HWMOD_STATE_IDLE &&
oh->_state != _HWMOD_STATE_ENABLED) { oh->_state != _HWMOD_STATE_ENABLED) {
WARN(1, "omap_hwmod: %s: disabled state can only be entered " WARN(1, "omap_hwmod: %s: disabled state can only be entered "
...@@ -1270,6 +1273,18 @@ static int _shutdown(struct omap_hwmod *oh) ...@@ -1270,6 +1273,18 @@ static int _shutdown(struct omap_hwmod *oh)
pr_debug("omap_hwmod: %s: disabling\n", oh->name); pr_debug("omap_hwmod: %s: disabling\n", oh->name);
if (oh->class->pre_shutdown) {
prev_state = oh->_state;
if (oh->_state == _HWMOD_STATE_IDLE)
_omap_hwmod_enable(oh);
ret = oh->class->pre_shutdown(oh);
if (ret) {
if (prev_state == _HWMOD_STATE_IDLE)
_omap_hwmod_idle(oh);
return ret;
}
}
if (oh->class->sysc) if (oh->class->sysc)
_shutdown_sysc(oh); _shutdown_sysc(oh);
......
...@@ -415,14 +415,24 @@ struct omap_hwmod_omap4_prcm { ...@@ -415,14 +415,24 @@ struct omap_hwmod_omap4_prcm {
* @name: name of the hwmod_class * @name: name of the hwmod_class
* @sysc: device SYSCONFIG/SYSSTATUS register data * @sysc: device SYSCONFIG/SYSSTATUS register data
* @rev: revision of the IP class * @rev: revision of the IP class
* @pre_shutdown: ptr to fn to be executed immediately prior to device shutdown
* *
* Represent the class of a OMAP hardware "modules" (e.g. timer, * Represent the class of a OMAP hardware "modules" (e.g. timer,
* smartreflex, gpio, uart...) * smartreflex, gpio, uart...)
*
* @pre_shutdown is a function that will be run immediately before
* hwmod clocks are disabled, etc. It is intended for use for hwmods
* like the MPU watchdog, which cannot be disabled with the standard
* omap_hwmod_shutdown(). The function should return 0 upon success,
* or some negative error upon failure. Returning an error will cause
* omap_hwmod_shutdown() to abort the device shutdown and return an
* error.
*/ */
struct omap_hwmod_class { struct omap_hwmod_class {
const char *name; const char *name;
struct omap_hwmod_class_sysconfig *sysc; struct omap_hwmod_class_sysconfig *sysc;
u32 rev; u32 rev;
int (*pre_shutdown)(struct omap_hwmod *oh);
}; };
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment