aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorKevin Hilman <khilman@deeprootsystems.com>2010-07-26 18:34:29 -0400
committerPaul Walmsley <paul@pwsan.com>2010-07-26 18:34:29 -0400
commit848240223c35fcc71c424ad51a8e8aef42d3879c (patch)
tree6c11872b61e0aa4eed0db43e362cdbac8c7c9284 /arch
parentfa98347ebf1c516e49694e1584cd96a63428676a (diff)
OMAP: hwmod: add non-locking versions of enable and idle functions
Some hwmods may need to be idled/enabled in atomic context, so non-locking versions of these functions are required. Most users should not need these and usage of theses should be controlled to understand why access is being done in atomic context. For this reason, the non-locking functions are only exposed at the hwmod level and not at the omap-device level. The use-case that led to the need for the non-locking versions is hwmods that are enabled/idled from within the core idle/suspend path. Since interrupts are already disabled here, the mutex-based locking in hwmod can sleep and will cause potential deadlocks. Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com> Signed-off-by: Paul Walmsley <paul@pwsan.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c19
-rw-r--r--arch/arm/plat-omap/include/plat/omap_hwmod.h2
2 files changed, 12 insertions, 9 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index b7a4133267d8..a23a60ad4059 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -886,7 +886,7 @@ static int _reset(struct omap_hwmod *oh)
886} 886}
887 887
888/** 888/**
889 * _enable - enable an omap_hwmod 889 * _omap_hwmod_enable - enable an omap_hwmod
890 * @oh: struct omap_hwmod * 890 * @oh: struct omap_hwmod *
891 * 891 *
892 * Enables an omap_hwmod @oh such that the MPU can access the hwmod's 892 * Enables an omap_hwmod @oh such that the MPU can access the hwmod's
@@ -894,7 +894,7 @@ static int _reset(struct omap_hwmod *oh)
894 * Returns -EINVAL if the hwmod is in the wrong state or passes along 894 * Returns -EINVAL if the hwmod is in the wrong state or passes along
895 * the return value of _wait_target_ready(). 895 * the return value of _wait_target_ready().
896 */ 896 */
897static int _enable(struct omap_hwmod *oh) 897int _omap_hwmod_enable(struct omap_hwmod *oh)
898{ 898{
899 int r; 899 int r;
900 900
@@ -939,7 +939,7 @@ static int _enable(struct omap_hwmod *oh)
939 * no further work. Returns -EINVAL if the hwmod is in the wrong 939 * no further work. Returns -EINVAL if the hwmod is in the wrong
940 * state or returns 0. 940 * state or returns 0.
941 */ 941 */
942static int _idle(struct omap_hwmod *oh) 942int _omap_hwmod_idle(struct omap_hwmod *oh)
943{ 943{
944 if (oh->_state != _HWMOD_STATE_ENABLED) { 944 if (oh->_state != _HWMOD_STATE_ENABLED) {
945 WARN(1, "omap_hwmod: %s: idle state can only be entered from " 945 WARN(1, "omap_hwmod: %s: idle state can only be entered from "
@@ -1029,7 +1029,7 @@ static int _setup(struct omap_hwmod *oh)
1029 1029
1030 oh->_state = _HWMOD_STATE_INITIALIZED; 1030 oh->_state = _HWMOD_STATE_INITIALIZED;
1031 1031
1032 r = _enable(oh); 1032 r = _omap_hwmod_enable(oh);
1033 if (r) { 1033 if (r) {
1034 pr_warning("omap_hwmod: %s: cannot be enabled (%d)\n", 1034 pr_warning("omap_hwmod: %s: cannot be enabled (%d)\n",
1035 oh->name, oh->_state); 1035 oh->name, oh->_state);
@@ -1041,7 +1041,7 @@ static int _setup(struct omap_hwmod *oh)
1041 * XXX Do the OCP_SYSCONFIG bits need to be 1041 * XXX Do the OCP_SYSCONFIG bits need to be
1042 * reprogrammed after a reset? If not, then this can 1042 * reprogrammed after a reset? If not, then this can
1043 * be removed. If they do, then probably the 1043 * be removed. If they do, then probably the
1044 * _enable() function should be split to avoid the 1044 * _omap_hwmod_enable() function should be split to avoid the
1045 * rewrite of the OCP_SYSCONFIG register. 1045 * rewrite of the OCP_SYSCONFIG register.
1046 */ 1046 */
1047 if (oh->class->sysc) { 1047 if (oh->class->sysc) {
@@ -1051,7 +1051,7 @@ static int _setup(struct omap_hwmod *oh)
1051 } 1051 }
1052 1052
1053 if (!(oh->flags & HWMOD_INIT_NO_IDLE)) 1053 if (!(oh->flags & HWMOD_INIT_NO_IDLE))
1054 _idle(oh); 1054 _omap_hwmod_idle(oh);
1055 1055
1056 return 0; 1056 return 0;
1057} 1057}
@@ -1292,12 +1292,13 @@ int omap_hwmod_enable(struct omap_hwmod *oh)
1292 return -EINVAL; 1292 return -EINVAL;
1293 1293
1294 mutex_lock(&omap_hwmod_mutex); 1294 mutex_lock(&omap_hwmod_mutex);
1295 r = _enable(oh); 1295 r = _omap_hwmod_enable(oh);
1296 mutex_unlock(&omap_hwmod_mutex); 1296 mutex_unlock(&omap_hwmod_mutex);
1297 1297
1298 return r; 1298 return r;
1299} 1299}
1300 1300
1301
1301/** 1302/**
1302 * omap_hwmod_idle - idle an omap_hwmod 1303 * omap_hwmod_idle - idle an omap_hwmod
1303 * @oh: struct omap_hwmod * 1304 * @oh: struct omap_hwmod *
@@ -1311,7 +1312,7 @@ int omap_hwmod_idle(struct omap_hwmod *oh)
1311 return -EINVAL; 1312 return -EINVAL;
1312 1313
1313 mutex_lock(&omap_hwmod_mutex); 1314 mutex_lock(&omap_hwmod_mutex);
1314 _idle(oh); 1315 _omap_hwmod_idle(oh);
1315 mutex_unlock(&omap_hwmod_mutex); 1316 mutex_unlock(&omap_hwmod_mutex);
1316 1317
1317 return 0; 1318 return 0;
@@ -1413,7 +1414,7 @@ int omap_hwmod_reset(struct omap_hwmod *oh)
1413 mutex_lock(&omap_hwmod_mutex); 1414 mutex_lock(&omap_hwmod_mutex);
1414 r = _reset(oh); 1415 r = _reset(oh);
1415 if (!r) 1416 if (!r)
1416 r = _enable(oh); 1417 r = _omap_hwmod_enable(oh);
1417 mutex_unlock(&omap_hwmod_mutex); 1418 mutex_unlock(&omap_hwmod_mutex);
1418 1419
1419 return r; 1420 return r;
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index 0eccc09ac4a9..253f6e55638c 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -486,7 +486,9 @@ int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh));
486int omap_hwmod_late_init(void); 486int omap_hwmod_late_init(void);
487 487
488int omap_hwmod_enable(struct omap_hwmod *oh); 488int omap_hwmod_enable(struct omap_hwmod *oh);
489int _omap_hwmod_enable(struct omap_hwmod *oh);
489int omap_hwmod_idle(struct omap_hwmod *oh); 490int omap_hwmod_idle(struct omap_hwmod *oh);
491int _omap_hwmod_idle(struct omap_hwmod *oh);
490int omap_hwmod_shutdown(struct omap_hwmod *oh); 492int omap_hwmod_shutdown(struct omap_hwmod *oh);
491 493
492int omap_hwmod_enable_clocks(struct omap_hwmod *oh); 494int omap_hwmod_enable_clocks(struct omap_hwmod *oh);