From patchwork Mon Aug 9 15:31:25 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Hilman X-Patchwork-Id: 118416 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.4/8.14.3) with ESMTP id o79FVWJ2019865 for ; Mon, 9 Aug 2010 15:31:32 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751691Ab0HIPba (ORCPT ); Mon, 9 Aug 2010 11:31:30 -0400 Received: from mail-pv0-f174.google.com ([74.125.83.174]:43103 "EHLO mail-pv0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756835Ab0HIPb3 (ORCPT ); Mon, 9 Aug 2010 11:31:29 -0400 Received: by pvg2 with SMTP id 2so766334pvg.19 for ; Mon, 09 Aug 2010 08:31:28 -0700 (PDT) Received: by 10.114.131.6 with SMTP id e6mr17941604wad.114.1281367888154; Mon, 09 Aug 2010 08:31:28 -0700 (PDT) Received: from localhost (c-24-18-179-55.hsd1.wa.comcast.net [24.18.179.55]) by mx.google.com with ESMTPS id d39sm10616782wam.16.2010.08.09.08.31.26 (version=TLSv1/SSLv3 cipher=RC4-MD5); Mon, 09 Aug 2010 08:31:26 -0700 (PDT) From: Kevin Hilman To: "Basak\, Partha" Cc: Paul Walmsley , "linux-omap\@vger.kernel.org" , "Kalliguddi\, Hema" , "Raja\, Govindraj" , "Varadarajan\, Charulatha" Subject: Re: Issues with calling pm_runtime functions in platform_pm_suspend_noirq/IRQ disabled context. Organization: Deep Root Systems, LLC References: Date: Mon, 09 Aug 2010 08:31:25 -0700 In-Reply-To: (Partha Basak's message of "Mon, 9 Aug 2010 16:01:41 +0530") Message-ID: <871va7n6pe.fsf@deeprootsystems.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1.50 (gnu/linux) 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 (demeter.kernel.org [140.211.167.41]); Mon, 09 Aug 2010 15:31:32 +0000 (UTC) diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index b0ec0e9..b02ef35 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -80,24 +80,24 @@ static int __pm_runtime_idle(struct device *dev) dev->power.idle_notification = true; if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_idle) { - spin_unlock_irq(&dev->power.lock); + spin_unlock_irqrestore(&dev->power.lock, dev->power.lock_flags); dev->bus->pm->runtime_idle(dev); - spin_lock_irq(&dev->power.lock); + spin_lock_irqsave(&dev->power.lock, dev->power.lock_flags); } else if (dev->type && dev->type->pm && dev->type->pm->runtime_idle) { - spin_unlock_irq(&dev->power.lock); + spin_unlock_irqrestore(&dev->power.lock, dev->power.lock_flags); dev->type->pm->runtime_idle(dev); - spin_lock_irq(&dev->power.lock); + spin_lock_irqsave(&dev->power.lock, dev->power.lock_flags); } else if (dev->class && dev->class->pm && dev->class->pm->runtime_idle) { - spin_unlock_irq(&dev->power.lock); + spin_unlock_irqrestore(&dev->power.lock, dev->power.lock_flags); dev->class->pm->runtime_idle(dev); - spin_lock_irq(&dev->power.lock); + spin_lock_irqsave(&dev->power.lock, dev->power.lock_flags); } dev->power.idle_notification = false; @@ -115,9 +115,9 @@ int pm_runtime_idle(struct device *dev) { int retval; - spin_lock_irq(&dev->power.lock); + spin_lock_irqsave(&dev->power.lock, dev->power.lock_flags); retval = __pm_runtime_idle(dev); - spin_unlock_irq(&dev->power.lock); + spin_unlock_irqrestore(&dev->power.lock, dev->power.lock_flags); return retval; } @@ -187,11 +187,13 @@ int __pm_runtime_suspend(struct device *dev, bool from_wq) if (dev->power.runtime_status != RPM_SUSPENDING) break; - spin_unlock_irq(&dev->power.lock); + spin_unlock_irqrestore(&dev->power.lock, + dev->power.lock_flags); schedule(); - spin_lock_irq(&dev->power.lock); + spin_lock_irqsave(&dev->power.lock, + dev->power.lock_flags); } finish_wait(&dev->power.wait_queue, &wait); goto repeat; @@ -201,27 +203,27 @@ int __pm_runtime_suspend(struct device *dev, bool from_wq) dev->power.deferred_resume = false; if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_suspend) { - spin_unlock_irq(&dev->power.lock); + spin_unlock_irqrestore(&dev->power.lock, dev->power.lock_flags); retval = dev->bus->pm->runtime_suspend(dev); - spin_lock_irq(&dev->power.lock); + spin_lock_irqsave(&dev->power.lock, dev->power.lock_flags); dev->power.runtime_error = retval; } else if (dev->type && dev->type->pm && dev->type->pm->runtime_suspend) { - spin_unlock_irq(&dev->power.lock); + spin_unlock_irqrestore(&dev->power.lock, dev->power.lock_flags); retval = dev->type->pm->runtime_suspend(dev); - spin_lock_irq(&dev->power.lock); + spin_lock_irqsave(&dev->power.lock, dev->power.lock_flags); dev->power.runtime_error = retval; } else if (dev->class && dev->class->pm && dev->class->pm->runtime_suspend) { - spin_unlock_irq(&dev->power.lock); + spin_unlock_irqrestore(&dev->power.lock, dev->power.lock_flags); retval = dev->class->pm->runtime_suspend(dev); - spin_lock_irq(&dev->power.lock); + spin_lock_irqsave(&dev->power.lock, dev->power.lock_flags); dev->power.runtime_error = retval; } else { retval = -ENOSYS; @@ -257,11 +259,11 @@ int __pm_runtime_suspend(struct device *dev, bool from_wq) __pm_runtime_idle(dev); if (parent && !parent->power.ignore_children) { - spin_unlock_irq(&dev->power.lock); + spin_unlock_irqrestore(&dev->power.lock, dev->power.lock_flags); pm_request_idle(parent); - spin_lock_irq(&dev->power.lock); + spin_lock_irqsave(&dev->power.lock, dev->power.lock_flags); } out: @@ -278,9 +280,9 @@ int pm_runtime_suspend(struct device *dev) { int retval; - spin_lock_irq(&dev->power.lock); + spin_lock_irqsave(&dev->power.lock, dev->power.lock_flags); retval = __pm_runtime_suspend(dev, false); - spin_unlock_irq(&dev->power.lock); + spin_unlock_irqrestore(&dev->power.lock, dev->power.lock_flags); return retval; } @@ -342,11 +344,13 @@ int __pm_runtime_resume(struct device *dev, bool from_wq) && dev->power.runtime_status != RPM_SUSPENDING) break; - spin_unlock_irq(&dev->power.lock); + spin_unlock_irqrestore(&dev->power.lock, + dev->power.lock_flags); schedule(); - spin_lock_irq(&dev->power.lock); + spin_lock_irqsave(&dev->power.lock, + dev->power.lock_flags); } finish_wait(&dev->power.wait_queue, &wait); goto repeat; @@ -384,27 +388,27 @@ int __pm_runtime_resume(struct device *dev, bool from_wq) dev->power.runtime_status = RPM_RESUMING; if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_resume) { - spin_unlock_irq(&dev->power.lock); + spin_unlock_irqrestore(&dev->power.lock, dev->power.lock_flags); retval = dev->bus->pm->runtime_resume(dev); - spin_lock_irq(&dev->power.lock); + spin_lock_irqsave(&dev->power.lock, dev->power.lock_flags); dev->power.runtime_error = retval; } else if (dev->type && dev->type->pm && dev->type->pm->runtime_resume) { - spin_unlock_irq(&dev->power.lock); + spin_unlock_irqrestore(&dev->power.lock, dev->power.lock_flags); retval = dev->type->pm->runtime_resume(dev); - spin_lock_irq(&dev->power.lock); + spin_lock_irqsave(&dev->power.lock, dev->power.lock_flags); dev->power.runtime_error = retval; } else if (dev->class && dev->class->pm && dev->class->pm->runtime_resume) { - spin_unlock_irq(&dev->power.lock); + spin_unlock_irqrestore(&dev->power.lock, dev->power.lock_flags); retval = dev->class->pm->runtime_resume(dev); - spin_lock_irq(&dev->power.lock); + spin_lock_irqsave(&dev->power.lock, dev->power.lock_flags); dev->power.runtime_error = retval; } else { retval = -ENOSYS; @@ -425,11 +429,11 @@ int __pm_runtime_resume(struct device *dev, bool from_wq) out: if (parent) { - spin_unlock_irq(&dev->power.lock); + spin_unlock_irqrestore(&dev->power.lock, dev->power.lock_flags); pm_runtime_put(parent); - spin_lock_irq(&dev->power.lock); + spin_lock_irqsave(&dev->power.lock, dev->power.lock_flags); } dev_dbg(dev, "__pm_runtime_resume() returns %d!\n", retval); @@ -445,9 +449,9 @@ int pm_runtime_resume(struct device *dev) { int retval; - spin_lock_irq(&dev->power.lock); + spin_lock_irqsave(&dev->power.lock, dev->power.lock_flags); retval = __pm_runtime_resume(dev, false); - spin_unlock_irq(&dev->power.lock); + spin_unlock_irqrestore(&dev->power.lock, dev->power.lock_flags); return retval; } diff --git a/include/linux/pm.h b/include/linux/pm.h index 8e258c7..1a3d514 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -464,6 +464,7 @@ struct dev_pm_info { struct work_struct work; wait_queue_head_t wait_queue; spinlock_t lock; + unsigned long lock_flags; atomic_t usage_count; atomic_t child_count; unsigned int disable_depth:3;