From patchwork Sun Aug 21 19:10:45 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rafael Wysocki X-Patchwork-Id: 1083672 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.4) with ESMTP id p7LJBM02018748 for ; Sun, 21 Aug 2011 19:11:22 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755854Ab1HUTLB (ORCPT ); Sun, 21 Aug 2011 15:11:01 -0400 Received: from ogre.sisk.pl ([217.79.144.158]:55718 "EHLO ogre.sisk.pl" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755713Ab1HUTKq (ORCPT ); Sun, 21 Aug 2011 15:10:46 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by ogre.sisk.pl (Postfix) with ESMTP id BC4E01B7A58; Sun, 21 Aug 2011 20:30:35 +0200 (CEST) Received: from ogre.sisk.pl ([127.0.0.1]) by localhost (ogre.sisk.pl [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 30541-10; Sun, 21 Aug 2011 20:30:21 +0200 (CEST) Received: from ferrari.rjw.lan (220-bem-13.acn.waw.pl [82.210.184.220]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ogre.sisk.pl (Postfix) with ESMTP id C474F1B831F; Sun, 21 Aug 2011 20:30:21 +0200 (CEST) From: "Rafael J. Wysocki" To: linux-sh@vger.kernel.org Subject: [PATCH 1/2 v2] PM: Change PM subsys_data lock type into spinlock Date: Sun, 21 Aug 2011 21:10:45 +0200 User-Agent: KMail/1.13.6 (Linux/3.1.0-rc2+; KDE/4.6.0; x86_64; ; ) Cc: Linux PM mailing list , LKML , Magnus Damm , Alan Stern References: <201108202131.19479.rjw@sisk.pl> <201108212109.30399.rjw@sisk.pl> In-Reply-To: <201108212109.30399.rjw@sisk.pl> MIME-Version: 1.0 Message-Id: <201108212110.45316.rjw@sisk.pl> X-Virus-Scanned: amavisd-new at ogre.sisk.pl using MkS_Vir for Linux Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Sun, 21 Aug 2011 19:11:22 +0000 (UTC) From: Rafael J. Wysocki The lock member of struct pm_subsys_data is of type struct mutex, which is a problem, because the suspend and resume routines defined in drivers/base/power/clock_ops.c cannot be executed with interrupts disabled for this reason. Modify struct pm_subsys_data so that its lock member is a spinlock. Signed-off-by: Rafael J. Wysocki --- drivers/base/power/clock_ops.c | 35 +++++++++++++++++++++-------------- drivers/base/power/common.c | 2 +- include/linux/pm.h | 2 +- 3 files changed, 23 insertions(+), 16 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-sh" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Index: linux/include/linux/pm.h =================================================================== --- linux.orig/include/linux/pm.h +++ linux/include/linux/pm.h @@ -438,7 +438,7 @@ struct pm_domain_data { }; struct pm_subsys_data { - struct mutex lock; + spinlock_t lock; unsigned int refcount; #ifdef CONFIG_PM_CLK struct list_head clock_list; Index: linux/drivers/base/power/clock_ops.c =================================================================== --- linux.orig/drivers/base/power/clock_ops.c +++ linux/drivers/base/power/clock_ops.c @@ -43,6 +43,7 @@ int pm_clk_add(struct device *dev, const { struct pm_subsys_data *psd = dev_to_psd(dev); struct pm_clock_entry *ce; + unsigned long flags; if (!psd) return -EINVAL; @@ -63,9 +64,9 @@ int pm_clk_add(struct device *dev, const } } - mutex_lock(&psd->lock); + spin_lock_irqsave(&psd->lock, flags); list_add_tail(&ce->node, &psd->clock_list); - mutex_unlock(&psd->lock); + spin_unlock_irqrestore(&psd->lock, flags); return 0; } @@ -109,11 +110,12 @@ void pm_clk_remove(struct device *dev, c { struct pm_subsys_data *psd = dev_to_psd(dev); struct pm_clock_entry *ce; + unsigned long flags; if (!psd) return; - mutex_lock(&psd->lock); + spin_lock_irqsave(&psd->lock, flags); list_for_each_entry(ce, &psd->clock_list, node) { if (!con_id && !ce->con_id) { @@ -127,7 +129,7 @@ void pm_clk_remove(struct device *dev, c } } - mutex_unlock(&psd->lock); + spin_unlock_irqrestore(&psd->lock, flags); } /** @@ -169,16 +171,17 @@ void pm_clk_destroy(struct device *dev) { struct pm_subsys_data *psd = dev_to_psd(dev); struct pm_clock_entry *ce, *c; + unsigned long flags; if (!psd) return; - mutex_lock(&psd->lock); + spin_lock_irqsave(&psd->lock, flags); list_for_each_entry_safe_reverse(ce, c, &psd->clock_list, node) __pm_clk_remove(ce); - mutex_unlock(&psd->lock); + spin_unlock_irqrestore(&psd->lock, flags); dev_pm_put_subsys_data(dev); } @@ -212,13 +215,14 @@ int pm_clk_suspend(struct device *dev) { struct pm_subsys_data *psd = dev_to_psd(dev); struct pm_clock_entry *ce; + unsigned long flags; dev_dbg(dev, "%s()\n", __func__); if (!psd) return 0; - mutex_lock(&psd->lock); + spin_lock_irqsave(&psd->lock, flags); list_for_each_entry_reverse(ce, &psd->clock_list, node) { if (ce->status == PCE_STATUS_NONE) @@ -230,7 +234,7 @@ int pm_clk_suspend(struct device *dev) } } - mutex_unlock(&psd->lock); + spin_unlock_irqrestore(&psd->lock, flags); return 0; } @@ -243,13 +247,14 @@ int pm_clk_resume(struct device *dev) { struct pm_subsys_data *psd = dev_to_psd(dev); struct pm_clock_entry *ce; + unsigned long flags; dev_dbg(dev, "%s()\n", __func__); if (!psd) return 0; - mutex_lock(&psd->lock); + spin_lock_irqsave(&psd->lock, flags); list_for_each_entry(ce, &psd->clock_list, node) { if (ce->status == PCE_STATUS_NONE) @@ -261,7 +266,7 @@ int pm_clk_resume(struct device *dev) } } - mutex_unlock(&psd->lock); + spin_unlock_irqrestore(&psd->lock, flags); return 0; } @@ -336,6 +341,7 @@ int pm_clk_suspend(struct device *dev) { struct pm_subsys_data *psd = dev_to_psd(dev); struct pm_clock_entry *ce; + unsigned long flags; dev_dbg(dev, "%s()\n", __func__); @@ -343,12 +349,12 @@ int pm_clk_suspend(struct device *dev) if (!psd || !dev->driver) return 0; - mutex_lock(&psd->lock); + spin_lock_irqsave(&psd->lock, flags); list_for_each_entry_reverse(ce, &psd->clock_list, node) clk_disable(ce->clk); - mutex_unlock(&psd->lock); + spin_unlock_irqrestore(&psd->lock, flags); return 0; } @@ -361,6 +367,7 @@ int pm_clk_resume(struct device *dev) { struct pm_subsys_data *psd = dev_to_psd(dev); struct pm_clock_entry *ce; + unsigned long flags; dev_dbg(dev, "%s()\n", __func__); @@ -368,12 +375,12 @@ int pm_clk_resume(struct device *dev) if (!psd || !dev->driver) return 0; - mutex_lock(&psd->lock); + spin_lock_irqsave(&psd->lock, flags); list_for_each_entry(ce, &psd->clock_list, node) clk_enable(ce->clk); - mutex_unlock(&psd->lock); + spin_unlock_irqrestore(&psd->lock, flags); return 0; } Index: linux/drivers/base/power/common.c =================================================================== --- linux.orig/drivers/base/power/common.c +++ linux/drivers/base/power/common.c @@ -34,7 +34,7 @@ int dev_pm_get_subsys_data(struct device if (dev->power.subsys_data) { dev->power.subsys_data->refcount++; } else { - mutex_init(&psd->lock); + spin_lock_init(&psd->lock); psd->refcount = 1; dev->power.subsys_data = psd; pm_clk_init(dev);