aboutsummaryrefslogtreecommitdiff
path: root/drivers/mmc/core/sdio.c
diff options
context:
space:
mode:
authorOhad Ben-Cohen <ohad@wizery.com>2010-11-19 09:29:09 +0200
committerChris Ball <cjb@laptop.org>2010-11-19 17:07:01 -0500
commited919b0125b26dcc052e44836f66e7e1f5c49c7e (patch)
tree10abd2b197488ee2c75e693e9422668481e5e4ce /drivers/mmc/core/sdio.c
parent4d0812c37f2f6cf6fc7ca086b5a5e572cbbe7f6d (diff)
mmc: sdio: fix runtime PM anomalies by introducing MMC_CAP_POWER_OFF_CARD
Some board/card/host configurations are not capable of powering off the card after boot. To support such configurations, and to allow smoother transition to runtime PM behavior, MMC_CAP_POWER_OFF_CARD is added, so hosts need to explicitly indicate whether it's OK to power off their cards after boot. SDIO core will enable runtime PM for a card only if that cap is set. As a result, the card will be powered down after boot, and will only be powered up again when a driver is loaded (and then it's up to the driver to decide whether power will be kept or not). This will prevent sdio_bus_probe() failures with setups that do not support powering off the card. Reported-and-tested-by: Daniel Drake <dsd@laptop.org> Reported-and-tested-by: Arnd Hannemann <arnd@arndnet.de> Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc/core/sdio.c')
-rw-r--r--drivers/mmc/core/sdio.c37
1 files changed, 23 insertions, 14 deletions
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index 42a949b723b..efef5f94ac4 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -547,9 +547,11 @@ static void mmc_sdio_detect(struct mmc_host *host)
BUG_ON(!host->card);
/* Make sure card is powered before detecting it */
- err = pm_runtime_get_sync(&host->card->dev);
- if (err < 0)
- goto out;
+ if (host->caps & MMC_CAP_POWER_OFF_CARD) {
+ err = pm_runtime_get_sync(&host->card->dev);
+ if (err < 0)
+ goto out;
+ }
mmc_claim_host(host);
@@ -571,7 +573,8 @@ static void mmc_sdio_detect(struct mmc_host *host)
* is about to show up at this point, the _sync variant is
* desirable anyway.
*/
- pm_runtime_put_sync(&host->card->dev);
+ if (host->caps & MMC_CAP_POWER_OFF_CARD)
+ pm_runtime_put_sync(&host->card->dev);
out:
if (err) {
@@ -728,16 +731,21 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr)
card = host->card;
/*
- * Let runtime PM core know our card is active
+ * Enable runtime PM only if supported by host+card+board
*/
- err = pm_runtime_set_active(&card->dev);
- if (err)
- goto remove;
+ if (host->caps & MMC_CAP_POWER_OFF_CARD) {
+ /*
+ * Let runtime PM core know our card is active
+ */
+ err = pm_runtime_set_active(&card->dev);
+ if (err)
+ goto remove;
- /*
- * Enable runtime PM for this card
- */
- pm_runtime_enable(&card->dev);
+ /*
+ * Enable runtime PM for this card
+ */
+ pm_runtime_enable(&card->dev);
+ }
/*
* The number of functions on the card is encoded inside
@@ -755,9 +763,10 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr)
goto remove;
/*
- * Enable Runtime PM for this func
+ * Enable Runtime PM for this func (if supported)
*/
- pm_runtime_enable(&card->sdio_func[i]->dev);
+ if (host->caps & MMC_CAP_POWER_OFF_CARD)
+ pm_runtime_enable(&card->sdio_func[i]->dev);
}
mmc_release_host(host);