From patchwork Wed Sep 1 17:34:18 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Walmsley X-Patchwork-Id: 147291 X-Patchwork-Delegate: khilman@deeprootsystems.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id o81HYKms021221 for ; Wed, 1 Sep 2010 17:34:21 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754770Ab0IAReU (ORCPT ); Wed, 1 Sep 2010 13:34:20 -0400 Received: from utopia.booyaka.com ([72.9.107.138]:45792 "EHLO utopia.booyaka.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751564Ab0IAReT (ORCPT ); Wed, 1 Sep 2010 13:34:19 -0400 Received: (qmail 27944 invoked by uid 1019); 1 Sep 2010 17:34:18 -0000 Date: Wed, 1 Sep 2010 11:34:18 -0600 (MDT) From: Paul Walmsley To: Kevin Hilman cc: linux-omap@vger.kernel.org, b-cousson@ti.com Subject: Re: [PATCH] OMAP: hwmod: separate list locking and hwmod hardware locking In-Reply-To: <1281572685-13964-1-git-send-email-khilman@deeprootsystems.com> Message-ID: References: <1281572685-13964-1-git-send-email-khilman@deeprootsystems.com> User-Agent: Alpine 2.00 (DEB 1167 2008-08-23) MIME-Version: 1.0 Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Wed, 01 Sep 2010 17:34:21 +0000 (UTC) diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 5bb25e3..6676fdd 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) * @data: not used; pass NULL * * Called by omap_hwmod_late_init() (after omap2_clk_init()). - * Resolves all clock names embedded in the hwmod. Must be called - * with omap_hwmod_mutex held. Returns -EINVAL if the omap_hwmod - * has not yet been registered or if the clocks have already been - * initialized, 0 on success, or a non-zero error on failure. + * Resolves all clock names embedded in the hwmod. Returns -EINVAL if + * the omap_hwmod has not yet been registered or if the clocks have + * already been initialized, 0 on success, or a non-zero error on + * failure. */ static int _init_clocks(struct omap_hwmod *oh, void *data) { @@ -838,10 +838,9 @@ static int _wait_target_ready(struct omap_hwmod *oh) * @oh: struct omap_hwmod * * * Resets an omap_hwmod @oh via the OCP_SYSCONFIG bit. hwmod must be - * enabled for this to work. Must be called with omap_hwmod_mutex - * held. 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 -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) { @@ -891,9 +890,8 @@ static int _reset(struct omap_hwmod *oh) * @oh: struct omap_hwmod * * * Enables an omap_hwmod @oh such that the MPU can access the hwmod's - * register target. Must be called with omap_hwmod_mutex held. - * Returns -EINVAL if the hwmod is in the wrong state or passes along - * the return value of _wait_target_ready(). + * register target. Returns -EINVAL if the hwmod is in the wrong + * state or passes along the return value of _wait_target_ready(). */ int _omap_hwmod_enable(struct omap_hwmod *oh) { @@ -1004,11 +1002,10 @@ static int _shutdown(struct omap_hwmod *oh) * @skip_setup_idle_p: do not idle hwmods at the end of the fn if 1 * * Writes the CLOCKACTIVITY bits @clockact to the hwmod @oh - * OCP_SYSCONFIG register. Must be called with omap_hwmod_mutex held. - * @skip_setup_idle is intended to be used on a system that will not - * call omap_hwmod_enable() to enable devices (e.g., a system without - * PM runtime). Returns -EINVAL if the hwmod is in the wrong state or - * returns 0. + * OCP_SYSCONFIG register. @skip_setup_idle is intended to be used on + * a system that will not call omap_hwmod_enable() to enable devices + * (e.g., a system without PM runtime). Returns -EINVAL if the hwmod + * is in the wrong state or returns 0. */ static int _setup(struct omap_hwmod *oh, void *data) { @@ -1038,6 +1035,7 @@ static int _setup(struct omap_hwmod *oh, void *data) } } + mutex_init(&oh->_mutex); oh->_state = _HWMOD_STATE_INITIALIZED; r = _omap_hwmod_enable(oh); @@ -1323,9 +1321,9 @@ int omap_hwmod_enable(struct omap_hwmod *oh) if (!oh) return -EINVAL; - mutex_lock(&omap_hwmod_mutex); + mutex_lock(&oh->_mutex); r = _omap_hwmod_enable(oh); - mutex_unlock(&omap_hwmod_mutex); + mutex_unlock(&oh->_mutex); return r; } @@ -1343,9 +1341,9 @@ int omap_hwmod_idle(struct omap_hwmod *oh) if (!oh) return -EINVAL; - mutex_lock(&omap_hwmod_mutex); + mutex_lock(&oh->_mutex); _omap_hwmod_idle(oh); - mutex_unlock(&omap_hwmod_mutex); + mutex_unlock(&oh->_mutex); return 0; } @@ -1363,9 +1361,9 @@ int omap_hwmod_shutdown(struct omap_hwmod *oh) if (!oh) return -EINVAL; - mutex_lock(&omap_hwmod_mutex); + mutex_lock(&oh->_mutex); _shutdown(oh); - mutex_unlock(&omap_hwmod_mutex); + mutex_unlock(&oh->_mutex); return 0; } @@ -1378,9 +1376,9 @@ int omap_hwmod_shutdown(struct omap_hwmod *oh) */ int omap_hwmod_enable_clocks(struct omap_hwmod *oh) { - mutex_lock(&omap_hwmod_mutex); + mutex_lock(&oh->_mutex); _enable_clocks(oh); - mutex_unlock(&omap_hwmod_mutex); + mutex_unlock(&oh->_mutex); return 0; } @@ -1393,9 +1391,9 @@ int omap_hwmod_enable_clocks(struct omap_hwmod *oh) */ int omap_hwmod_disable_clocks(struct omap_hwmod *oh) { - mutex_lock(&omap_hwmod_mutex); + mutex_lock(&oh->_mutex); _disable_clocks(oh); - mutex_unlock(&omap_hwmod_mutex); + mutex_unlock(&oh->_mutex); return 0; } @@ -1443,11 +1441,11 @@ int omap_hwmod_reset(struct omap_hwmod *oh) if (!oh || !(oh->_state & _HWMOD_STATE_ENABLED)) return -EINVAL; - mutex_lock(&omap_hwmod_mutex); + mutex_lock(&oh->_mutex); r = _reset(oh); if (!r) r = _omap_hwmod_enable(oh); - mutex_unlock(&omap_hwmod_mutex); + mutex_unlock(&oh->_mutex); return r; } @@ -1648,9 +1646,9 @@ int omap_hwmod_enable_wakeup(struct omap_hwmod *oh) !(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) return -EINVAL; - mutex_lock(&omap_hwmod_mutex); + mutex_lock(&oh->_mutex); _enable_wakeup(oh); - mutex_unlock(&omap_hwmod_mutex); + mutex_unlock(&oh->_mutex); return 0; } @@ -1673,9 +1671,9 @@ int omap_hwmod_disable_wakeup(struct omap_hwmod *oh) !(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) return -EINVAL; - mutex_lock(&omap_hwmod_mutex); + mutex_lock(&oh->_mutex); _disable_wakeup(oh); - mutex_unlock(&omap_hwmod_mutex); + mutex_unlock(&oh->_mutex); return 0; } diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h index 5506d80..03350ba 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 @@ #include #include #include +#include #include struct omap_device; @@ -433,6 +434,7 @@ struct omap_hwmod_class { * @_state: internal-use hwmod state * @flags: hwmod flags (documented below) * @omap_chip: OMAP chips this hwmod is present on + * @_mutex: mutex serializing operations on this hwmod * @node: list node for hwmod list (internal use) * * @main_clk refers to this module's "main clock," which for our @@ -461,6 +463,7 @@ struct omap_hwmod { void *dev_attr; u32 _sysc_cache; void __iomem *_mpu_rt_va; + struct mutex _mutex; struct list_head node; u16 flags; u8 _mpu_port_index;