summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorAsutosh Das <asutoshd@codeaurora.org>2014-12-04 23:05:50 +0200
committerSubhash Jadavani <subhashj@codeaurora.org>2016-05-31 15:25:51 -0700
commit3c0c23354a0c200f2f52c4be8de85f8949daa0c4 (patch)
treeea146fdf51dbfc5fdc446c06728e12b49d19d56d /drivers
parent358ac29e04226897063b5f3be85d9eb636b99820 (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.c6
-rw-r--r--drivers/mmc/core/sdio_irq.c18
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, &param);
@@ -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);