From: Kuninori Morimoto <kuninori.morimoto...@renesas.com>

In some controllers, when performing a multiple block read of
one or two blocks, depending on the timing with which the
response register is read, the response value may not
be read properly.
Use single block read for this HW bug

Signed-off-by: Kuninori Morimoto <kuninori.morimoto...@renesas.com>
---
 drivers/mmc/card/block.c |   19 +++++++++++++++++--
 include/linux/mmc/host.h |    3 +++
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 452782b..f3cbe37 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -1400,8 +1400,23 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req 
*mqrq,
 
                /* Some controllers can't do multiblock reads due to hw bugs */
                if (card->host->caps2 & MMC_CAP2_NO_MULTI_READ &&
-                   rq_data_dir(req) == READ)
-                       brq->data.blocks = 1;
+                   rq_data_dir(req) == READ) {
+
+                       if (card->host->caps2 & MMC_CAP2_2BLKS_LIMIT) {
+                               /*
+                                * In some controllers, when performing a
+                                * multiple block read of one or two blocks,
+                                * depending on the timing with which the
+                                * response register is read, the response
+                                * value may not be read properly.
+                                * Use single block read for this HW bug
+                                */
+                               if (brq->data.blocks == 2)
+                                       brq->data.blocks = 1;
+                       } else {
+                               brq->data.blocks = 1;
+                       }
+               }
        }
 
        if (brq->data.blocks > 1 || do_rel_wr) {
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index cb61ea4..5429cd7 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -266,6 +266,9 @@ struct mmc_host {
 #define MMC_CAP2_BOOTPART_NOACC        (1 << 0)        /* Boot partition no 
access */
 #define MMC_CAP2_FULL_PWR_CYCLE        (1 << 2)        /* Can do full power 
cycle */
 #define MMC_CAP2_NO_MULTI_READ (1 << 3)        /* Multiblock reads don't work 
*/
+#define MMC_CAP2_2BLKS_LIMIT   (1 << 4)        /* 2 blocks limit for multi 
read */
+#define MMC_CAP2_NO_2BLKS_READ (MMC_CAP2_NO_MULTI_READ | \
+                                MMC_CAP2_2BLKS_LIMIT)
 #define MMC_CAP2_HS200_1_8V_SDR        (1 << 5)        /* can support */
 #define MMC_CAP2_HS200_1_2V_SDR        (1 << 6)        /* can support */
 #define MMC_CAP2_HS200         (MMC_CAP2_HS200_1_8V_SDR | \
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to