mmc: sdhci: add power management capability.

Current mmc stack doesn't use the framework provided by power
management subsystem. It doesn't let each device suspend itself
and the pm operations are solely handled by the platform driver.
This may lead to races, since the concurrency of pm framework is
not used. The pm core does its best to reduce the probability of
a race between system suspend/resume and runtime PM by
decrementing/incrementing the usage counters of respective
devices during system-pm operations.
Moreover, it disables runtime PM altogether after suspending the
device and re-enables the same on resume.

To avoid this, the parent child relationship between the platform,
mmc_host and mmc_card devices is used. In this case, the relation
is defined as,
mmc_card -> (child of) -> mmc_host -> (child of) -> platform_dev

Each device is now responsible for its power management.
 * mmc_card
	-> schedules the runtime-suspend
 * mmc_host
	-> actually suspends/resume the host & card i.e. invokes
		mmc_[suspend/resume]_host
 * pltform_dev
	-> disables irqs

Typically, the card device serves as a trigger for scheduling the
runtime-suspend and invoking runtime-resume.

Two new runtime-pm functions have been introduced:
 * mmc_rpm_hold
	-> resumes the device passed as a parameter
 * mmc_rpm_release
	-> suspends the device passed as a parameter

The above two functions are invoked from the below contexts:
 * mmc_rescan
 * bkops
 * mmc-queue

Change-Id: Icf9dd34a445abfaf8dbb974ab1255feeda2581c9
Signed-off-by: Asutosh Das <asutoshd@codeaurora.org>
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index e4aab43..9a4e61d 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -385,6 +385,9 @@
 	struct mmc_wr_pack_stats wr_pack_stats; /* packed commands stats*/
 
 	struct mmc_bkops_info	bkops_info;
+
+	struct device_attribute rpm_attrib;
+	unsigned int		idle_timeout;
 };
 
 /*
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h
index 5f1e2d9..f951c2a 100644
--- a/include/linux/mmc/core.h
+++ b/include/linux/mmc/core.h
@@ -206,6 +206,8 @@
 extern int mmc_detect_card_removed(struct mmc_host *host);
 
 extern void mmc_blk_init_bkops_statistics(struct mmc_card *card);
+extern void mmc_rpm_hold(struct mmc_host *host, struct device *dev);
+extern void mmc_rpm_release(struct mmc_host *host, struct device *dev);
 
 /**
  *	mmc_claim_host - exclusively claim a host
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 2bfd9a2..99df79e 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -283,6 +283,8 @@
 #define MMC_CAP2_INIT_BKOPS	    (1 << 16)	/* Need to set BKOPS_EN */
 #define MMC_CAP2_CLK_SCALE	(1 << 17)	/* Allow dynamic clk scaling */
 #define MMC_CAP2_STOP_REQUEST	(1 << 18)	/* Allow stop ongoing request */
+/* Use runtime PM framework provided by MMC core */
+#define MMC_CAP2_CORE_RUNTIME_PM (1 << 19)
 	mmc_pm_flag_t		pm_caps;	/* supported pm features */
 
 	int			clk_requests;	/* internal reference counter */
@@ -543,4 +545,10 @@
 	return host->ios.clock;
 }
 #endif
+
+static inline int mmc_use_core_runtime_pm(struct mmc_host *host)
+{
+	return host->caps2 & MMC_CAP2_CORE_RUNTIME_PM;
+}
+
 #endif /* LINUX_MMC_HOST_H */