mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 20:32:04 +09:00
mmc: mmcblk: Add support for deferred SD bus resume
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>
This commit is contained in:
committed by
Arve Hjønnevåg
parent
40594a0045
commit
a31e8fffe8
@@ -32,6 +32,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"
|
||||
help
|
||||
|
||||
@@ -234,6 +234,33 @@ static u32 get_card_status(struct mmc_card *card, struct request *req)
|
||||
return cmd.resp[0];
|
||||
}
|
||||
|
||||
static int
|
||||
mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card)
|
||||
{
|
||||
struct mmc_command cmd;
|
||||
int err;
|
||||
|
||||
/* Block-addressed cards ignore MMC_SET_BLOCKLEN. */
|
||||
if (mmc_card_blockaddr(card))
|
||||
return 0;
|
||||
|
||||
mmc_claim_host(card->host);
|
||||
cmd.opcode = MMC_SET_BLOCKLEN;
|
||||
cmd.arg = 512;
|
||||
cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
|
||||
err = mmc_wait_for_cmd(card->host, &cmd, 5);
|
||||
mmc_release_host(card->host);
|
||||
|
||||
if (err) {
|
||||
printk(KERN_ERR "%s: unable to set block size to %d: %d\n",
|
||||
md->disk->disk_name, cmd.arg, err);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
|
||||
{
|
||||
struct mmc_blk_data *md = mq->data;
|
||||
@@ -241,6 +268,13 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
|
||||
struct mmc_blk_request brq;
|
||||
int ret = 1, disable_multi = 0;
|
||||
|
||||
#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
|
||||
|
||||
mmc_claim_host(card->host);
|
||||
|
||||
do {
|
||||
@@ -555,32 +589,6 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card)
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
static int
|
||||
mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card)
|
||||
{
|
||||
struct mmc_command cmd;
|
||||
int err;
|
||||
|
||||
/* Block-addressed cards ignore MMC_SET_BLOCKLEN. */
|
||||
if (mmc_card_blockaddr(card))
|
||||
return 0;
|
||||
|
||||
mmc_claim_host(card->host);
|
||||
cmd.opcode = MMC_SET_BLOCKLEN;
|
||||
cmd.arg = 512;
|
||||
cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
|
||||
err = mmc_wait_for_cmd(card->host, &cmd, 5);
|
||||
mmc_release_host(card->host);
|
||||
|
||||
if (err) {
|
||||
printk(KERN_ERR "%s: unable to set block size to %d: %d\n",
|
||||
md->disk->disk_name, cmd.arg, err);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mmc_blk_probe(struct mmc_card *card)
|
||||
{
|
||||
struct mmc_blk_data *md;
|
||||
@@ -609,6 +617,9 @@ static int mmc_blk_probe(struct mmc_card *card)
|
||||
cap_str, md->read_only ? "(ro)" : "");
|
||||
|
||||
mmc_set_drvdata(card, md);
|
||||
#ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME
|
||||
mmc_set_bus_resume_policy(card->host, 1);
|
||||
#endif
|
||||
add_disk(md->disk);
|
||||
return 0;
|
||||
|
||||
@@ -632,6 +643,9 @@ static void mmc_blk_remove(struct mmc_card *card)
|
||||
mmc_blk_put(md);
|
||||
}
|
||||
mmc_set_drvdata(card, NULL);
|
||||
#ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME
|
||||
mmc_set_bus_resume_policy(card->host, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
@@ -650,7 +664,9 @@ static int mmc_blk_resume(struct mmc_card *card)
|
||||
struct mmc_blk_data *md = mmc_get_drvdata(card);
|
||||
|
||||
if (md) {
|
||||
#ifndef CONFIG_MMC_BLOCK_DEFERRED_RESUME
|
||||
mmc_blk_set_blksize(md, card);
|
||||
#endif
|
||||
mmc_queue_resume(&md->queue);
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -1076,6 +1076,12 @@ void mmc_rescan(struct work_struct *work)
|
||||
if ((host->bus_ops != NULL) && host->bus_ops->detect && !host->bus_dead)
|
||||
host->bus_ops->detect(host);
|
||||
|
||||
/* 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;
|
||||
|
||||
mmc_bus_put(host);
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user