diff mbox

[v1,3/3] mmc: changes to enable runtime PM of mmc core layer

Message ID 20101128055315.GD3318@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Gao, Yunpeng Nov. 28, 2010, 5:53 a.m. UTC
None
diff mbox

Patch

diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
index af8dc6a..96b6cff 100644
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -160,7 +160,7 @@  static int mmc_runtime_resume(struct device *dev)
 
 static int mmc_runtime_idle(struct device *dev)
 {
-	return pm_runtime_suspend(dev);
+	return pm_schedule_suspend(dev, 100);
 }
 
 static const struct dev_pm_ops mmc_bus_pm_ops = {
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 6286898..2905dac 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -22,6 +22,7 @@ 
 #include <linux/scatterlist.h>
 #include <linux/log2.h>
 #include <linux/regulator/consumer.h>
+#include <linux/pm_runtime.h>
 
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
@@ -1503,6 +1504,7 @@  void mmc_rescan(struct work_struct *work)
 
 	spin_unlock_irqrestore(&host->lock, flags);
 
+	pm_runtime_get_sync(host->parent);
 
 	mmc_bus_get(host);
 
@@ -1598,6 +1600,8 @@  out_fail:
 		mmc_power_off(host);
 	}
 out:
+	pm_runtime_put_sync(host->parent);
+
 	if (host->caps & MMC_CAP_NEEDS_POLL)
 		mmc_schedule_delayed_work(&host->detect, HZ);
 }
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index 92e3370..8268b8e 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -19,6 +19,7 @@ 
 #include <linux/leds.h>
 #include <linux/slab.h>
 #include <linux/suspend.h>
+#include <linux/pm_runtime.h>
 
 #include <linux/mmc/host.h>
 #include <linux/mmc/card.h>
@@ -28,6 +29,33 @@ 
 
 #define cls_dev_to_mmc_host(d)	container_of(d, struct mmc_host, class_dev)
 
+#ifdef CONFIG_PM_RUNTIME
+static int mmc_host_runtime_suspend(struct device *dev)
+{
+	return 0;
+}
+
+static int mmc_host_runtime_resume(struct device *dev)
+{
+	return 0;
+}
+
+static int mmc_host_runtime_idle(struct device *dev)
+{
+	return pm_runtime_suspend(dev);
+}
+#else
+#define mmc_host_runtime_suspend	NULL
+#define mmc_host_runtime_resume		NULL
+#define mmc_host_runtime_idle		NULL
+#endif
+
+const static struct dev_pm_ops host_pm = {
+	.runtime_suspend = mmc_host_runtime_suspend,
+	.runtime_resume = mmc_host_runtime_resume,
+	.runtime_idle = mmc_host_runtime_idle,
+};
+
 static void mmc_host_classdev_release(struct device *dev)
 {
 	struct mmc_host *host = cls_dev_to_mmc_host(dev);
@@ -37,6 +65,7 @@  static void mmc_host_classdev_release(struct device *dev)
 static struct class mmc_host_class = {
 	.name		= "mmc_host",
 	.dev_release	= mmc_host_classdev_release,
+	.pm		= &host_pm,
 };
 
 int mmc_register_host_class(void)
@@ -333,6 +362,12 @@  int mmc_add_host(struct mmc_host *host)
 	if (err)
 		return err;
 
+	/* Enable runtime PM */
+	pm_runtime_get_noresume(&host->class_dev);
+	pm_runtime_set_active(&host->class_dev);
+	pm_runtime_enable(&host->class_dev);
+	pm_runtime_put_sync(&host->class_dev);
+
 #ifdef CONFIG_DEBUG_FS
 	mmc_add_host_debugfs(host);
 #endif