mmc: mmcblk: Add support for deferred SD bus resume
authorSan Mehat <san@google.com>
Thu, 30 Jul 2009 15:21:19 +0000 (08:21 -0700)
committerArve Hjønnevåg <arve@android.com>
Mon, 1 Jul 2013 20:40:23 +0000 (13:40 -0700)
Signed-off-by: San Mehat <san@google.com>
mmc: card: Add MMC_BLOCK_DEFERRED_RESUME option to Kconfig

Signed-off-by: San Mehat <san@google.com>
drivers/mmc/card/Kconfig
drivers/mmc/card/block.c
drivers/mmc/core/core.c

index 5562308699bc292d5dce1e63fdea2452c38164f5..79d82124413f1c13e6e9d9df8d40a76e5026c5d0 100644 (file)
@@ -50,6 +50,15 @@ config MMC_BLOCK_BOUNCE
 
          If unsure, say Y here.
 
+config MMC_BLOCK_DEFERRED_RESUME
+       bool "Deferr MMC layer resume until I/O is requested"
+       depends on MMC_BLOCK
+       default n
+       help
+         Say Y here to enable deferred MMC resume until I/O
+         is requested. This will reduce overall resume latency and
+         save power when theres an SD card inserted but not being used.
+
 config SDIO_UART
        tristate "SDIO UART/GPS class support"
        depends on TTY
index f201bc47a54bd528b45fd2fd87d4700d8cdfc34f..cfb47e46ba16419f25f049fe152e95508dabaa76 100644 (file)
@@ -1881,6 +1881,9 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc)
        return 0;
 }
 
+static int
+mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card);
+
 static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
 {
        int ret;
@@ -1889,6 +1892,13 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
        struct mmc_host *host = card->host;
        unsigned long flags;
 
+#ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME
+       if (mmc_bus_needs_resume(card->host)) {
+               mmc_resume_bus(card->host);
+               mmc_blk_set_blksize(md, card);
+       }
+#endif
+
        if (req && !mq->mqrq_prev->req)
                /* claim host only for the first request */
                mmc_claim_host(card->host);
@@ -2326,6 +2336,9 @@ static int mmc_blk_probe(struct mmc_card *card)
        mmc_set_drvdata(card, md);
        mmc_fixup_device(card, blk_fixups);
 
+#ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME
+       mmc_set_bus_resume_policy(card->host, 1);
+#endif
        if (mmc_add_disk(md))
                goto out;
 
@@ -2351,6 +2364,9 @@ static void mmc_blk_remove(struct mmc_card *card)
        mmc_release_host(card->host);
        mmc_blk_remove_req(md);
        mmc_set_drvdata(card, NULL);
+#ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME
+       mmc_set_bus_resume_policy(card->host, 0);
+#endif
 }
 
 #ifdef CONFIG_PM
index 265a8c09f7d1b7ff4f75705ad73ac9e45c0a45b9..00abe448f0713de5ce54b622566ea11233b0bbe6 100644 (file)
@@ -2400,6 +2400,12 @@ void mmc_rescan(struct work_struct *work)
 
        host->detect_change = 0;
 
+       /* If the card was removed the bus will be marked
+        * as dead - extend the wakelock so userspace
+        * can respond */
+       if (host->bus_dead)
+               extend_wakelock = 1;
+
        /*
         * Let mmc_bus_put() free the bus/bus_ops if we've found that
         * the card is no longer present.