aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Walmsley <paul@pwsan.com>2010-12-14 14:42:34 -0500
committerPaul Walmsley <paul@pwsan.com>2010-12-21 21:55:11 -0500
commite4dc8f507c3066d6fcece988d99b6d766c46af85 (patch)
tree5548478340c53a1ee79756d9c3c97118bf9abb13
parent4805734bcc5a6b28b527a13a5c1603a2912c9f48 (diff)
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: Paul Walmsley <paul@pwsan.com> Cc: BenoƮt Cousson <b-cousson@ti.com>
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c15
-rw-r--r--arch/arm/plat-omap/include/plat/omap_hwmod.h10
2 files changed, 25 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 5a30658444d0..c051fa493594 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -1261,6 +1261,9 @@ int _omap_hwmod_idle(struct omap_hwmod *oh)
1261 */ 1261 */
1262static int _shutdown(struct omap_hwmod *oh) 1262static int _shutdown(struct omap_hwmod *oh)
1263{ 1263{
1264 int ret;
1265 u8 prev_state;
1266
1264 if (oh->_state != _HWMOD_STATE_IDLE && 1267 if (oh->_state != _HWMOD_STATE_IDLE &&
1265 oh->_state != _HWMOD_STATE_ENABLED) { 1268 oh->_state != _HWMOD_STATE_ENABLED) {
1266 WARN(1, "omap_hwmod: %s: disabled state can only be entered " 1269 WARN(1, "omap_hwmod: %s: disabled state can only be entered "
@@ -1270,6 +1273,18 @@ static int _shutdown(struct omap_hwmod *oh)
1270 1273
1271 pr_debug("omap_hwmod: %s: disabling\n", oh->name); 1274 pr_debug("omap_hwmod: %s: disabling\n", oh->name);
1272 1275
1276 if (oh->class->pre_shutdown) {
1277 prev_state = oh->_state;
1278 if (oh->_state == _HWMOD_STATE_IDLE)
1279 _omap_hwmod_enable(oh);
1280 ret = oh->class->pre_shutdown(oh);
1281 if (ret) {
1282 if (prev_state == _HWMOD_STATE_IDLE)
1283 _omap_hwmod_idle(oh);
1284 return ret;
1285 }
1286 }
1287
1273 if (oh->class->sysc) 1288 if (oh->class->sysc)
1274 _shutdown_sysc(oh); 1289 _shutdown_sysc(oh);
1275 1290
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index 7eaa8edf3b14..d1f1265fc4a6 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -415,14 +415,24 @@ struct omap_hwmod_omap4_prcm {
415 * @name: name of the hwmod_class 415 * @name: name of the hwmod_class
416 * @sysc: device SYSCONFIG/SYSSTATUS register data 416 * @sysc: device SYSCONFIG/SYSSTATUS register data
417 * @rev: revision of the IP class 417 * @rev: revision of the IP class
418 * @pre_shutdown: ptr to fn to be executed immediately prior to device shutdown
418 * 419 *
419 * Represent the class of a OMAP hardware "modules" (e.g. timer, 420 * Represent the class of a OMAP hardware "modules" (e.g. timer,
420 * smartreflex, gpio, uart...) 421 * smartreflex, gpio, uart...)
422 *
423 * @pre_shutdown is a function that will be run immediately before
424 * hwmod clocks are disabled, etc. It is intended for use for hwmods
425 * like the MPU watchdog, which cannot be disabled with the standard
426 * omap_hwmod_shutdown(). The function should return 0 upon success,
427 * or some negative error upon failure. Returning an error will cause
428 * omap_hwmod_shutdown() to abort the device shutdown and return an
429 * error.
421 */ 430 */
422struct omap_hwmod_class { 431struct omap_hwmod_class {
423 const char *name; 432 const char *name;
424 struct omap_hwmod_class_sysconfig *sysc; 433 struct omap_hwmod_class_sysconfig *sysc;
425 u32 rev; 434 u32 rev;
435 int (*pre_shutdown)(struct omap_hwmod *oh);
426}; 436};
427 437
428/** 438/**