aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorUlf Hansson <ulf.hansson@linaro.org>2015-03-27 07:15:15 -0400
committerUlf Hansson <ulf.hansson@linaro.org>2015-03-31 10:50:14 -0400
commit9250aea76bfcbf4c2a7868e5566281bf2bb7af27 (patch)
tree19a576d68b20889ebb7816f04c4669462afefd73 /drivers
parentb7a5646fa5d5d319b2b1a3db07f615e40b184205 (diff)
mmc: core: Enable runtime PM management of host devices
Currently those host drivers which have deployed runtime PM, deals with the runtime PM reference counting entirely by themselves. Since host drivers don't know when the core will send the next request through some of the host_ops callbacks, they need to handle runtime PM get/put between each an every request. In quite many cases this has some negative effects, since it leads to a high frequency of scheduled runtime PM suspend operations. That due to the runtime PM reference count will normally reach zero in-between every request. We can decrease that frequency, by enabling the core to deal with runtime PM reference counting of the host device. Since the core often knows that it will send a seqeunce of requests, it makes sense for it to keep a runtime PM reference count during these periods. More exactly, let's increase the runtime PM reference count by invoking pm_runtime_get_sync() from __mmc_claim_host(). Restore that action by invoking pm_runtime_mark_last_busy() and pm_runtime_put_autosuspend() in mmc_release_host(). In this way a runtime PM reference count will be kept during the complete cycle of a claim -> release host. Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Acked-by: Adrian Hunter <adrian.hunter@intel.com> Acked-by: Konstantin Dorfman <kdorfman@codeaurora.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/core/core.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 709ada9f26b5..c296bc098fe2 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -897,6 +897,7 @@ int __mmc_claim_host(struct mmc_host *host, atomic_t *abort)
897 DECLARE_WAITQUEUE(wait, current); 897 DECLARE_WAITQUEUE(wait, current);
898 unsigned long flags; 898 unsigned long flags;
899 int stop; 899 int stop;
900 bool pm = false;
900 901
901 might_sleep(); 902 might_sleep();
902 903
@@ -916,13 +917,18 @@ int __mmc_claim_host(struct mmc_host *host, atomic_t *abort)
916 host->claimed = 1; 917 host->claimed = 1;
917 host->claimer = current; 918 host->claimer = current;
918 host->claim_cnt += 1; 919 host->claim_cnt += 1;
920 if (host->claim_cnt == 1)
921 pm = true;
919 } else 922 } else
920 wake_up(&host->wq); 923 wake_up(&host->wq);
921 spin_unlock_irqrestore(&host->lock, flags); 924 spin_unlock_irqrestore(&host->lock, flags);
922 remove_wait_queue(&host->wq, &wait); 925 remove_wait_queue(&host->wq, &wait);
926
927 if (pm)
928 pm_runtime_get_sync(mmc_dev(host));
929
923 return stop; 930 return stop;
924} 931}
925
926EXPORT_SYMBOL(__mmc_claim_host); 932EXPORT_SYMBOL(__mmc_claim_host);
927 933
928/** 934/**
@@ -947,6 +953,8 @@ void mmc_release_host(struct mmc_host *host)
947 host->claimer = NULL; 953 host->claimer = NULL;
948 spin_unlock_irqrestore(&host->lock, flags); 954 spin_unlock_irqrestore(&host->lock, flags);
949 wake_up(&host->wq); 955 wake_up(&host->wq);
956 pm_runtime_mark_last_busy(mmc_dev(host));
957 pm_runtime_put_autosuspend(mmc_dev(host));
950 } 958 }
951} 959}
952EXPORT_SYMBOL(mmc_release_host); 960EXPORT_SYMBOL(mmc_release_host);