@@ -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 = {
@@ -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);
}
@@ -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