From d5e1670afe0c886d6dd92afb7a1f085f88294dc8 Mon Sep 17 00:00:00 2001
From: Shuah Khan <shuah.kh@samsung.com>
Date: Wed, 8 May 2013 01:14:32 +0200
Subject: [PATCH] PM: Avoid calling kfree() under spinlock in
 dev_pm_put_subsys_data()

Fix dev_pm_put_subsys_data() so that it doesn't call kfree() under
a spinlock and make it return 1 whenever it leaves NULL
power.subsys_data (regardless of the reason).

Signed-off-by: Shuah Khan <shuah.kh@samsung.com>
Reviewed-by: Pavel Machek <pavel@ucw.cz>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/base/power/common.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/base/power/common.c b/drivers/base/power/common.c
index 39c32529b833..5da914041305 100644
--- a/drivers/base/power/common.c
+++ b/drivers/base/power/common.c
@@ -61,24 +61,24 @@ EXPORT_SYMBOL_GPL(dev_pm_get_subsys_data);
 int dev_pm_put_subsys_data(struct device *dev)
 {
 	struct pm_subsys_data *psd;
-	int ret = 0;
+	int ret = 1;
 
 	spin_lock_irq(&dev->power.lock);
 
 	psd = dev_to_psd(dev);
-	if (!psd) {
-		ret = -EINVAL;
+	if (!psd)
 		goto out;
-	}
 
 	if (--psd->refcount == 0) {
 		dev->power.subsys_data = NULL;
-		kfree(psd);
-		ret = 1;
+	} else {
+		psd = NULL;
+		ret = 0;
 	}
 
  out:
 	spin_unlock_irq(&dev->power.lock);
+	kfree(psd);
 
 	return ret;
 }
-- 
GitLab