summaryrefslogtreecommitdiff
path: root/drivers/mmc/card/block.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-06-23 13:38:04 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2015-06-23 13:38:04 -0700
commita57f14bac07f63118d947f53976d7f15c04b062a (patch)
tree36a253602d5a4d121fed8cd2dd6a4002d8c31e73 /drivers/mmc/card/block.c
parent10b4b096d0c7e9f1b5f84c2a0658b2963e1e6ed0 (diff)
parenta8c27c0bea45c6531fbc1e3be79ddd5a9bc1ba3e (diff)
Merge tag 'mmc-v4.2' of git://git.linaro.org/people/ulf.hansson/mmc
Pull MMC updates from Ulf Hansson: "Here are the changes for MMC for v4.2. MMC core: - Fix an error path in the mmc block layer - Fix PM domain attachment for the SDIO bus - Add support for driver strength selection - Increase a delay to let voltage stabilize - Add support for disabling write-protect detection - Add facility to support re-tuning - Re-tune and retry in the recovery path - Add reset option for SDIO - Consolidations and clean-ups MMC host: - Add Mediatek MMC driver - Constify platform_device_id for a couple of hosts - Fix modalias to make module auto-loading work for a couple of hosts - sdhci: Add support for sdhci-arasan4.9a - sdhci: Fix low memory corruption - sdhci: Restore behavior while creating OCR mask - sdhci: Add a callback to select drive strength - sdhci: Fix driver type B and D handling - sdhci: Add support for drive strength selection for SPT - sdhci: Enable HS400 for some Intel host controllers - sdhci: Convert to use the new re-tuning facility - sdhci: Various minor fixes and clean-ups - dw_mmc: Add support for hi6220 - dw_mmc: Use core to handle absent write protect line - dw_mmc: Add support to switch voltage - tmio: Some fixes and modernizations - sh_mmcif: Improve clock rate calculation" * tag 'mmc-v4.2' of git://git.linaro.org/people/ulf.hansson/mmc: (98 commits) mmc: queue: prevent soft lockups on PREEMPT=n mmc: mediatek: Add PM support for MMC driver mmc: mediatek: Add Mediatek MMC driver mmc: dt-bindings: add Mediatek MMC bindings mmc: card: Fixup request missing in mmc_blk_issue_rw_rq mmc: sdhci: fix low memory corruption mmc: sdhci-pci: Change AMD SDHCI quirk application scope i2c-piix4: Use Macro for AMD CZ SMBus device ID pci_ids: Add AMD KERNCZ device ID support mmc: queue: use swap() in mmc_queue_thread() mmc: dw_mmc: insmod followed by rmmod will hung for eMMC mmc: sdhci: Restore behavior while creating OCR mask mmc: sdhci-pxav3: fix device wakeup initialization mmc: core: Attach PM domain prior probing of SDIO func driver mmc: core: Remove redundant ->power_restore() callback for SD mmc: core: Remove redundant ->power_restore() callback for MMC mmc: sdhci-bcm2835: Actually enable the clock mmc: sdhci-bcm2835: Clean up platform allocations if sdhci init fails. mmc: sdhci-of-esdhc: enable interrupt mode to detect card mmc: sdhci-esdhc-imx: add quirk SDHCI_QUIRK2_BROKEN_HS200 for imx6qdl ...
Diffstat (limited to 'drivers/mmc/card/block.c')
-rw-r--r--drivers/mmc/card/block.c25
1 files changed, 20 insertions, 5 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 60f7141a6b02..c9c3d20b784b 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -913,6 +913,9 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req,
if (!err)
break;
+ /* Re-tune if needed */
+ mmc_retune_recheck(card->host);
+
prev_cmd_status_valid = false;
pr_err("%s: error %d sending status command, %sing\n",
req->rq_disk->disk_name, err, retry ? "retry" : "abort");
@@ -1204,6 +1207,7 @@ static int mmc_blk_err_check(struct mmc_card *card,
mmc_active);
struct mmc_blk_request *brq = &mq_mrq->brq;
struct request *req = mq_mrq->req;
+ int need_retune = card->host->need_retune;
int ecc_err = 0, gen_err = 0;
/*
@@ -1271,6 +1275,12 @@ static int mmc_blk_err_check(struct mmc_card *card,
}
if (brq->data.error) {
+ if (need_retune && !brq->retune_retry_done) {
+ pr_info("%s: retrying because a re-tune was needed\n",
+ req->rq_disk->disk_name);
+ brq->retune_retry_done = 1;
+ return MMC_BLK_RETRY;
+ }
pr_err("%s: error %d transferring data, sector %u, nr %u, cmd response %#x, card status %#x\n",
req->rq_disk->disk_name, brq->data.error,
(unsigned)blk_rq_pos(req),
@@ -1830,7 +1840,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc)
struct mmc_blk_data *md = mq->data;
struct mmc_card *card = md->queue.card;
struct mmc_blk_request *brq = &mq->mqrq_cur->brq;
- int ret = 1, disable_multi = 0, retry = 0, type;
+ int ret = 1, disable_multi = 0, retry = 0, type, retune_retry_done = 0;
enum mmc_blk_status status;
struct mmc_queue_req *mq_rq;
struct request *req = rqc;
@@ -1910,10 +1920,13 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc)
break;
case MMC_BLK_CMD_ERR:
ret = mmc_blk_cmd_err(md, card, brq, req, ret);
- if (!mmc_blk_reset(md, card->host, type))
- break;
- goto cmd_abort;
+ if (mmc_blk_reset(md, card->host, type))
+ goto cmd_abort;
+ if (!ret)
+ goto start_new_req;
+ break;
case MMC_BLK_RETRY:
+ retune_retry_done = brq->retune_retry_done;
if (retry++ < 5)
break;
/* Fall through */
@@ -1976,6 +1989,7 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc)
mmc_start_req(card->host,
&mq_rq->mmc_active, NULL);
}
+ mq_rq->brq.retune_retry_done = retune_retry_done;
}
} while (ret);
@@ -2217,7 +2231,8 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card)
* The CSD capacity field is in units of read_blkbits.
* set_capacity takes units of 512 bytes.
*/
- size = card->csd.capacity << (card->csd.read_blkbits - 9);
+ size = (typeof(sector_t))card->csd.capacity
+ << (card->csd.read_blkbits - 9);
}
return mmc_blk_alloc_req(card, &card->dev, size, false, NULL,