diff options
author | Asutosh Das <asutoshd@codeaurora.org> | 2014-12-04 23:05:50 +0200 |
---|---|---|
committer | Subhash Jadavani <subhashj@codeaurora.org> | 2016-05-31 15:25:51 -0700 |
commit | 3c0c23354a0c200f2f52c4be8de85f8949daa0c4 (patch) | |
tree | ea146fdf51dbfc5fdc446c06728e12b49d19d56d /drivers | |
parent | 358ac29e04226897063b5f3be85d9eb636b99820 (diff) |
mmc: core: add wakeup functionality to sdio cards
This patch initializes wakeup source if the detected card
is a sdio card and enables the wakeup capability.
Platform drivers would have to invoke:
* pm_wakeup_event on this card device to signal a wakeup
* corresponding pm_relax have to be invoked
Change-Id: Ic8d5c98073e8ed3f676eb42fc0ce1f13a11cb40f
Signed-off-by: Asutosh Das <asutoshd@codeaurora.org>
[merez@codeaurora.org: fix conflicts due to different PM in 3.14]
Signed-off-by: Maya Erez <merez@codeaurora.org>
[subhashj@codeaurora.org: fixed trivial merge conflicts]
Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mmc/core/bus.c | 6 | ||||
-rw-r--r-- | drivers/mmc/core/sdio_irq.c | 18 |
2 files changed, 24 insertions, 0 deletions
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index 15e94c25b06e..4a542d6bf509 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c @@ -361,6 +361,12 @@ int mmc_add_card(struct mmc_card *card) card->dev.of_node = mmc_of_find_child_device(card->host, 0); + if (mmc_card_sdio(card)) { + ret = device_init_wakeup(&card->dev, true); + if (ret) + pr_err("%s: %s: failed to init wakeup: %d\n", + mmc_hostname(card->host), __func__, ret); + } ret = device_add(&card->dev); if (ret) return ret; diff --git a/drivers/mmc/core/sdio_irq.c b/drivers/mmc/core/sdio_irq.c index 09cc67d028f0..b95f942aea0e 100644 --- a/drivers/mmc/core/sdio_irq.c +++ b/drivers/mmc/core/sdio_irq.c @@ -104,6 +104,7 @@ static int sdio_irq_thread(void *_host) struct sched_param param = { .sched_priority = 1 }; unsigned long period, idle_period; int ret; + bool ws; sched_setscheduler(current, SCHED_FIFO, ¶m); @@ -137,6 +138,17 @@ static int sdio_irq_thread(void *_host) ret = __mmc_claim_host(host, &host->sdio_irq_thread_abort); if (ret) break; + ws = false; + /* + * prevent suspend if it has started when scheduled; + * 100 msec (approx. value) should be enough for the system to + * resume and attend to the card's request + */ + if ((host->dev_status == DEV_SUSPENDING) || + (host->dev_status == DEV_SUSPENDED)) { + pm_wakeup_event(&host->card->dev, 100); + ws = true; + } ret = process_sdio_pending_irqs(host); host->sdio_irq_pending = false; mmc_release_host(host); @@ -173,6 +185,12 @@ static int sdio_irq_thread(void *_host) host->ops->enable_sdio_irq(host, 1); mmc_host_clk_release(host); } + /* + * function drivers would have processed the event from card + * unless suspended, hence release wake source + */ + if (ws && (host->dev_status == DEV_RESUMED)) + pm_relax(&host->card->dev); if (!kthread_should_stop()) schedule_timeout(period); set_current_state(TASK_RUNNING); |