diff options
Diffstat (limited to 'drivers/mmc/card')
-rw-r--r-- | drivers/mmc/card/Kconfig | 9 | ||||
-rw-r--r-- | drivers/mmc/card/block.c | 28 |
2 files changed, 29 insertions, 8 deletions
diff --git a/drivers/mmc/card/Kconfig b/drivers/mmc/card/Kconfig index 5562308699b..79d82124413 100644 --- a/drivers/mmc/card/Kconfig +++ b/drivers/mmc/card/Kconfig @@ -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 diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 41b1aff5334..806d37cb1d9 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -163,11 +163,7 @@ static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk) static inline int mmc_get_devidx(struct gendisk *disk) { - int devmaj = MAJOR(disk_devt(disk)); - int devidx = MINOR(disk_devt(disk)) / perdev_minors; - - if (!devmaj) - devidx = disk->first_minor / perdev_minors; + int devidx = disk->first_minor / perdev_minors; return devidx; } @@ -729,18 +725,22 @@ static int mmc_blk_cmd_error(struct request *req, const char *name, int error, req->rq_disk->disk_name, "timed out", name, status); /* If the status cmd initially failed, retry the r/w cmd */ - if (!status_valid) + if (!status_valid) { + pr_err("%s: status not valid, retrying timeout\n", req->rq_disk->disk_name); return ERR_RETRY; - + } /* * If it was a r/w cmd crc error, or illegal command * (eg, issued in wrong state) then retry - we should * have corrected the state problem above. */ - if (status & (R1_COM_CRC_ERROR | R1_ILLEGAL_COMMAND)) + if (status & (R1_COM_CRC_ERROR | R1_ILLEGAL_COMMAND)) { + pr_err("%s: command error, retrying timeout\n", req->rq_disk->disk_name); return ERR_RETRY; + } /* Otherwise abort the command */ + pr_err("%s: not retrying timeout\n", req->rq_disk->disk_name); return ERR_ABORT; default: @@ -1898,6 +1898,11 @@ 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); +#endif + if (req && !mq->mqrq_prev->req) /* claim host only for the first request */ mmc_claim_host(card->host); @@ -2014,6 +2019,7 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, md->disk->queue = md->queue.queue; md->disk->driverfs_dev = parent; set_disk_ro(md->disk, md->read_only || default_ro); + md->disk->flags = GENHD_FL_EXT_DEVT; if (area_type & MMC_BLK_DATA_AREA_RPMB) md->disk->flags |= GENHD_FL_NO_PART_SCAN; @@ -2328,6 +2334,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; @@ -2353,6 +2362,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 |