diff options
author | Ulf Hansson <ulf.hansson@stericsson.com> | 2011-12-13 17:01:11 +0100 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2012-01-20 01:00:58 +0100 |
commit | 2cd976c46472e34460349ed43a217e34f90bad55 (patch) | |
tree | b3dc1b537ee5c99f565ea1b5ba4fc571f3f7525e | |
parent | ARM: 7221/1: mmc: mmci: Change from using legacy suspend (diff) | |
download | linux-2cd976c46472e34460349ed43a217e34f90bad55.tar.xz linux-2cd976c46472e34460349ed43a217e34f90bad55.zip |
ARM: 7223/1: mmc: mmci: Fixup use of runtime PM and use autosuspend
Added use of runtime PM autosuspend feature, with a fixed
timeout of 50 ms. This will prevent adding a latency,
although very minor, for _every_ request.
Moreover the runtime_get_sync is now also used in set_ios and
suspend since the runtime resourses are needed here as well.
Tested-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Ulf Hansson <ulf.hansson@stericsson.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r-- | drivers/mmc/host/mmci.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 544995b3cb95..6a21fc0bf3d8 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -178,8 +178,10 @@ mmci_request_end(struct mmci_host *host, struct mmc_request *mrq) host->mrq = NULL; host->cmd = NULL; - pm_runtime_put(mmc_dev(host->mmc)); mmc_request_done(host->mmc, mrq); + + pm_runtime_mark_last_busy(mmc_dev(host->mmc)); + pm_runtime_put_autosuspend(mmc_dev(host->mmc)); } static void mmci_set_mask1(struct mmci_host *host, unsigned int mask) @@ -1026,6 +1028,8 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) unsigned long flags; int ret; + pm_runtime_get_sync(mmc_dev(mmc)); + if (host->plat->ios_handler && host->plat->ios_handler(mmc_dev(mmc), ios)) dev_err(mmc_dev(mmc), "platform ios_handler failed\n"); @@ -1046,7 +1050,7 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) * power should be rare so we print an error * and return here. */ - return; + goto out; } } /* @@ -1100,6 +1104,10 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) } spin_unlock_irqrestore(&host->lock, flags); + + out: + pm_runtime_mark_last_busy(mmc_dev(mmc)); + pm_runtime_put_autosuspend(mmc_dev(mmc)); } static int mmci_get_ro(struct mmc_host *mmc) @@ -1372,6 +1380,8 @@ static int __devinit mmci_probe(struct amba_device *dev, mmci_dma_setup(host); + pm_runtime_set_autosuspend_delay(&dev->dev, 50); + pm_runtime_use_autosuspend(&dev->dev); pm_runtime_put(&dev->dev); mmc_add_host(mmc); @@ -1467,8 +1477,10 @@ static int mmci_suspend(struct device *dev) struct mmci_host *host = mmc_priv(mmc); ret = mmc_suspend_host(mmc); - if (ret == 0) + if (ret == 0) { + pm_runtime_get_sync(dev); writel(0, host->base + MMCIMASK0); + } } return ret; @@ -1484,6 +1496,7 @@ static int mmci_resume(struct device *dev) struct mmci_host *host = mmc_priv(mmc); writel(MCI_IRQENABLE, host->base + MMCIMASK0); + pm_runtime_put(dev); ret = mmc_resume_host(mmc); } |