aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorKevin Hilman <khilman@ti.com>2010-09-21 12:34:09 -0400
committerPaul Walmsley <paul@pwsan.com>2010-09-21 17:11:30 -0400
commit12b1fdb45c2594070bb36e39cd89a33547aad8fb (patch)
tree01af153ff32c155ca5a5392badf82ffcaca6bbaa /arch/arm
parentff4d3e186b7b92c74a4f64360f723c603193f344 (diff)
OMAP: hwmod: separate list locking and hwmod hardware locking
Currently omap_hwmod_mutex is being used to protect both the list access/modification and concurrent access to hwmod functions. This patch separates these two types of locking. First, omap_hwmod_mutex is used only to protect access and modification of omap_hwmod_list. Also cleaned up some comments referring to this mutex that are no longer needed. Then, for protecting concurrent access to hwmod functions, use a per-hwmod mutex. This protects concurrent access to a single hwmod, but would allow concurrent access to different hwmods. Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com> [paul@pwsan.com: added structure documentation; changed mutex variable name] Signed-off-by: Paul Walmsley <paul@pwsan.com>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c62
-rw-r--r--arch/arm/plat-omap/include/plat/omap_hwmod.h3
2 files changed, 33 insertions, 32 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 100115ff1d96..3084409ad1dc 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -767,10 +767,10 @@ static struct omap_hwmod *_lookup(const char *name)
767 * @data: not used; pass NULL 767 * @data: not used; pass NULL
768 * 768 *
769 * Called by omap_hwmod_late_init() (after omap2_clk_init()). 769 * Called by omap_hwmod_late_init() (after omap2_clk_init()).
770 * Resolves all clock names embedded in the hwmod. Must be called 770 * Resolves all clock names embedded in the hwmod. Returns -EINVAL if
771 * with omap_hwmod_mutex held. Returns -EINVAL if the omap_hwmod 771 * the omap_hwmod has not yet been registered or if the clocks have
772 * has not yet been registered or if the clocks have already been 772 * already been initialized, 0 on success, or a non-zero error on
773 * initialized, 0 on success, or a non-zero error on failure. 773 * failure.
774 */ 774 */
775static int _init_clocks(struct omap_hwmod *oh, void *data) 775static int _init_clocks(struct omap_hwmod *oh, void *data)
776{ 776{
@@ -838,10 +838,9 @@ static int _wait_target_ready(struct omap_hwmod *oh)
838 * @oh: struct omap_hwmod * 838 * @oh: struct omap_hwmod *
839 * 839 *
840 * Resets an omap_hwmod @oh via the OCP_SYSCONFIG bit. hwmod must be 840 * Resets an omap_hwmod @oh via the OCP_SYSCONFIG bit. hwmod must be
841 * enabled for this to work. Must be called with omap_hwmod_mutex 841 * enabled for this to work. Returns -EINVAL if the hwmod cannot be
842 * held. Returns -EINVAL if the hwmod cannot be reset this way or if 842 * reset this way or if the hwmod is in the wrong state, -ETIMEDOUT if
843 * the hwmod is in the wrong state, -ETIMEDOUT if the module did not 843 * the module did not reset in time, or 0 upon success.
844 * reset in time, or 0 upon success.
845 */ 844 */
846static int _reset(struct omap_hwmod *oh) 845static int _reset(struct omap_hwmod *oh)
847{ 846{
@@ -891,9 +890,8 @@ static int _reset(struct omap_hwmod *oh)
891 * @oh: struct omap_hwmod * 890 * @oh: struct omap_hwmod *
892 * 891 *
893 * 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 * register target. Must be called with omap_hwmod_mutex held. 893 * register target. Returns -EINVAL if the hwmod is in the wrong
895 * Returns -EINVAL if the hwmod is in the wrong state or passes along 894 * state or passes along the return value of _wait_target_ready().
896 * the return value of _wait_target_ready().
897 */ 895 */
898int _omap_hwmod_enable(struct omap_hwmod *oh) 896int _omap_hwmod_enable(struct omap_hwmod *oh)
899{ 897{
@@ -1004,11 +1002,10 @@ static int _shutdown(struct omap_hwmod *oh)
1004 * @skip_setup_idle_p: do not idle hwmods at the end of the fn if 1 1002 * @skip_setup_idle_p: do not idle hwmods at the end of the fn if 1
1005 * 1003 *
1006 * Writes the CLOCKACTIVITY bits @clockact to the hwmod @oh 1004 * Writes the CLOCKACTIVITY bits @clockact to the hwmod @oh
1007 * OCP_SYSCONFIG register. Must be called with omap_hwmod_mutex held. 1005 * OCP_SYSCONFIG register. @skip_setup_idle is intended to be used on
1008 * @skip_setup_idle is intended to be used on a system that will not 1006 * a system that will not call omap_hwmod_enable() to enable devices
1009 * call omap_hwmod_enable() to enable devices (e.g., a system without 1007 * (e.g., a system without PM runtime). Returns -EINVAL if the hwmod
1010 * PM runtime). Returns -EINVAL if the hwmod is in the wrong state or 1008 * is in the wrong state or returns 0.
1011 * returns 0.
1012 */ 1009 */
1013static int _setup(struct omap_hwmod *oh, void *data) 1010static int _setup(struct omap_hwmod *oh, void *data)
1014{ 1011{
@@ -1038,6 +1035,7 @@ static int _setup(struct omap_hwmod *oh, void *data)
1038 } 1035 }
1039 } 1036 }
1040 1037
1038 mutex_init(&oh->_mutex);
1041 oh->_state = _HWMOD_STATE_INITIALIZED; 1039 oh->_state = _HWMOD_STATE_INITIALIZED;
1042 1040
1043 r = _omap_hwmod_enable(oh); 1041 r = _omap_hwmod_enable(oh);
@@ -1323,9 +1321,9 @@ int omap_hwmod_enable(struct omap_hwmod *oh)
1323 if (!oh) 1321 if (!oh)
1324 return -EINVAL; 1322 return -EINVAL;
1325 1323
1326 mutex_lock(&omap_hwmod_mutex); 1324 mutex_lock(&oh->_mutex);
1327 r = _omap_hwmod_enable(oh); 1325 r = _omap_hwmod_enable(oh);
1328 mutex_unlock(&omap_hwmod_mutex); 1326 mutex_unlock(&oh->_mutex);
1329 1327
1330 return r; 1328 return r;
1331} 1329}
@@ -1343,9 +1341,9 @@ int omap_hwmod_idle(struct omap_hwmod *oh)
1343 if (!oh) 1341 if (!oh)
1344 return -EINVAL; 1342 return -EINVAL;
1345 1343
1346 mutex_lock(&omap_hwmod_mutex); 1344 mutex_lock(&oh->_mutex);
1347 _omap_hwmod_idle(oh); 1345 _omap_hwmod_idle(oh);
1348 mutex_unlock(&omap_hwmod_mutex); 1346 mutex_unlock(&oh->_mutex);
1349 1347
1350 return 0; 1348 return 0;
1351} 1349}
@@ -1363,9 +1361,9 @@ int omap_hwmod_shutdown(struct omap_hwmod *oh)
1363 if (!oh) 1361 if (!oh)
1364 return -EINVAL; 1362 return -EINVAL;
1365 1363
1366 mutex_lock(&omap_hwmod_mutex); 1364 mutex_lock(&oh->_mutex);
1367 _shutdown(oh); 1365 _shutdown(oh);
1368 mutex_unlock(&omap_hwmod_mutex); 1366 mutex_unlock(&oh->_mutex);
1369 1367
1370 return 0; 1368 return 0;
1371} 1369}
@@ -1378,9 +1376,9 @@ int omap_hwmod_shutdown(struct omap_hwmod *oh)
1378 */ 1376 */
1379int omap_hwmod_enable_clocks(struct omap_hwmod *oh) 1377int omap_hwmod_enable_clocks(struct omap_hwmod *oh)
1380{ 1378{
1381 mutex_lock(&omap_hwmod_mutex); 1379 mutex_lock(&oh->_mutex);
1382 _enable_clocks(oh); 1380 _enable_clocks(oh);
1383 mutex_unlock(&omap_hwmod_mutex); 1381 mutex_unlock(&oh->_mutex);
1384 1382
1385 return 0; 1383 return 0;
1386} 1384}
@@ -1393,9 +1391,9 @@ int omap_hwmod_enable_clocks(struct omap_hwmod *oh)
1393 */ 1391 */
1394int omap_hwmod_disable_clocks(struct omap_hwmod *oh) 1392int omap_hwmod_disable_clocks(struct omap_hwmod *oh)
1395{ 1393{
1396 mutex_lock(&omap_hwmod_mutex); 1394 mutex_lock(&oh->_mutex);
1397 _disable_clocks(oh); 1395 _disable_clocks(oh);
1398 mutex_unlock(&omap_hwmod_mutex); 1396 mutex_unlock(&oh->_mutex);
1399 1397
1400 return 0; 1398 return 0;
1401} 1399}
@@ -1443,9 +1441,9 @@ int omap_hwmod_reset(struct omap_hwmod *oh)
1443 if (!oh) 1441 if (!oh)
1444 return -EINVAL; 1442 return -EINVAL;
1445 1443
1446 mutex_lock(&omap_hwmod_mutex); 1444 mutex_lock(&oh->_mutex);
1447 r = _reset(oh); 1445 r = _reset(oh);
1448 mutex_unlock(&omap_hwmod_mutex); 1446 mutex_unlock(&oh->_mutex);
1449 1447
1450 return r; 1448 return r;
1451} 1449}
@@ -1646,9 +1644,9 @@ int omap_hwmod_enable_wakeup(struct omap_hwmod *oh)
1646 !(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) 1644 !(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP))
1647 return -EINVAL; 1645 return -EINVAL;
1648 1646
1649 mutex_lock(&omap_hwmod_mutex); 1647 mutex_lock(&oh->_mutex);
1650 _enable_wakeup(oh); 1648 _enable_wakeup(oh);
1651 mutex_unlock(&omap_hwmod_mutex); 1649 mutex_unlock(&oh->_mutex);
1652 1650
1653 return 0; 1651 return 0;
1654} 1652}
@@ -1671,9 +1669,9 @@ int omap_hwmod_disable_wakeup(struct omap_hwmod *oh)
1671 !(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) 1669 !(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP))
1672 return -EINVAL; 1670 return -EINVAL;
1673 1671
1674 mutex_lock(&omap_hwmod_mutex); 1672 mutex_lock(&oh->_mutex);
1675 _disable_wakeup(oh); 1673 _disable_wakeup(oh);
1676 mutex_unlock(&omap_hwmod_mutex); 1674 mutex_unlock(&oh->_mutex);
1677 1675
1678 return 0; 1676 return 0;
1679} 1677}
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index 5506d80d94b9..03350bac01d8 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -35,6 +35,7 @@
35#include <linux/kernel.h> 35#include <linux/kernel.h>
36#include <linux/list.h> 36#include <linux/list.h>
37#include <linux/ioport.h> 37#include <linux/ioport.h>
38#include <linux/mutex.h>
38#include <plat/cpu.h> 39#include <plat/cpu.h>
39 40
40struct omap_device; 41struct omap_device;
@@ -433,6 +434,7 @@ struct omap_hwmod_class {
433 * @_state: internal-use hwmod state 434 * @_state: internal-use hwmod state
434 * @flags: hwmod flags (documented below) 435 * @flags: hwmod flags (documented below)
435 * @omap_chip: OMAP chips this hwmod is present on 436 * @omap_chip: OMAP chips this hwmod is present on
437 * @_mutex: mutex serializing operations on this hwmod
436 * @node: list node for hwmod list (internal use) 438 * @node: list node for hwmod list (internal use)
437 * 439 *
438 * @main_clk refers to this module's "main clock," which for our 440 * @main_clk refers to this module's "main clock," which for our
@@ -461,6 +463,7 @@ struct omap_hwmod {
461 void *dev_attr; 463 void *dev_attr;
462 u32 _sysc_cache; 464 u32 _sysc_cache;
463 void __iomem *_mpu_rt_va; 465 void __iomem *_mpu_rt_va;
466 struct mutex _mutex;
464 struct list_head node; 467 struct list_head node;
465 u16 flags; 468 u16 flags;
466 u8 _mpu_port_index; 469 u8 _mpu_port_index;