Commit 37be4e78 authored by Russell King's avatar Russell King Committed by Russell King

[MMC] extend data timeout for writes

The CSD contains a "read2write factor" which determines the multiplier to
be applied to the read timeout to obtain the write timeout.  We were
ignoring this parameter, resulting in the possibility for writes being
timed out too early.
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 81d38428
...@@ -549,6 +549,7 @@ static void mmc_decode_csd(struct mmc_card *card) ...@@ -549,6 +549,7 @@ static void mmc_decode_csd(struct mmc_card *card)
csd->read_partial = UNSTUFF_BITS(resp, 79, 1); csd->read_partial = UNSTUFF_BITS(resp, 79, 1);
csd->write_misalign = UNSTUFF_BITS(resp, 78, 1); csd->write_misalign = UNSTUFF_BITS(resp, 78, 1);
csd->read_misalign = UNSTUFF_BITS(resp, 77, 1); csd->read_misalign = UNSTUFF_BITS(resp, 77, 1);
csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3);
csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4); csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4);
csd->write_partial = UNSTUFF_BITS(resp, 21, 1); csd->write_partial = UNSTUFF_BITS(resp, 21, 1);
} else { } else {
...@@ -583,6 +584,7 @@ static void mmc_decode_csd(struct mmc_card *card) ...@@ -583,6 +584,7 @@ static void mmc_decode_csd(struct mmc_card *card)
csd->read_partial = UNSTUFF_BITS(resp, 79, 1); csd->read_partial = UNSTUFF_BITS(resp, 79, 1);
csd->write_misalign = UNSTUFF_BITS(resp, 78, 1); csd->write_misalign = UNSTUFF_BITS(resp, 78, 1);
csd->read_misalign = UNSTUFF_BITS(resp, 77, 1); csd->read_misalign = UNSTUFF_BITS(resp, 77, 1);
csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3);
csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4); csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4);
csd->write_partial = UNSTUFF_BITS(resp, 21, 1); csd->write_partial = UNSTUFF_BITS(resp, 21, 1);
} }
......
...@@ -187,6 +187,12 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) ...@@ -187,6 +187,12 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
brq.cmd.opcode = MMC_WRITE_BLOCK; brq.cmd.opcode = MMC_WRITE_BLOCK;
brq.data.flags |= MMC_DATA_WRITE; brq.data.flags |= MMC_DATA_WRITE;
brq.data.blocks = 1; brq.data.blocks = 1;
/*
* Scale up the timeout by the r2w factor
*/
brq.data.timeout_ns <<= card->csd.r2w_factor;
brq.data.timeout_clks <<= card->csd.r2w_factor;
} }
if (brq.data.blocks > 1) { if (brq.data.blocks > 1) {
......
...@@ -28,6 +28,7 @@ struct mmc_csd { ...@@ -28,6 +28,7 @@ struct mmc_csd {
unsigned short cmdclass; unsigned short cmdclass;
unsigned short tacc_clks; unsigned short tacc_clks;
unsigned int tacc_ns; unsigned int tacc_ns;
unsigned int r2w_factor;
unsigned int max_dtr; unsigned int max_dtr;
unsigned int read_blkbits; unsigned int read_blkbits;
unsigned int write_blkbits; unsigned int write_blkbits;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment