From d380443cd0271903bf9516bc04cead81676be034 Mon Sep 17 00:00:00 2001 From: Subhash Jadavani Date: Wed, 13 Jun 2012 17:10:43 +0530 Subject: [PATCH 1/2] mmc: block: fix the data timeout issue with ACMD22 If multi block write operation fails for SD card, during error handling we send the SD_APP_SEND_NUM_WR_BLKS (ACMD22) to know how many blocks were already programmed by card. But mmc_sd_num_wr_blocks() function which sends the ACMD22 calculates the data timeout value from csd.tacc_ns and csd.tacc_clks parameters which will be 0 for block addressed (>2GB cards) SD card. This would result in timeout_ns and timeout_clks being 0 in the mmc_request passed to host driver. This means host controller would program its data timeout timer value with 0 which could result in DATA TIMEOUT errors from controller. To fix this issue, mmc_sd_num_wr_blocks() should instead just call the mmc_set_data_timeout() to calculate the data timeout value. mmc_set_data_timeout() function ensures that non zero timeout value is set even for block addressed SD cards. Signed-off-by: Subhash Jadavani Reviewed-by: Venkatraman S Signed-off-by: Chris Ball --- drivers/mmc/card/block.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index dd2d374dcc7a..276d21ce6bc1 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -554,7 +554,6 @@ static u32 mmc_sd_num_wr_blocks(struct mmc_card *card) struct mmc_request mrq = {NULL}; struct mmc_command cmd = {0}; struct mmc_data data = {0}; - unsigned int timeout_us; struct scatterlist sg; @@ -574,23 +573,12 @@ static u32 mmc_sd_num_wr_blocks(struct mmc_card *card) cmd.arg = 0; cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; - data.timeout_ns = card->csd.tacc_ns * 100; - data.timeout_clks = card->csd.tacc_clks * 100; - - timeout_us = data.timeout_ns / 1000; - timeout_us += data.timeout_clks * 1000 / - (card->host->ios.clock / 1000); - - if (timeout_us > 100000) { - data.timeout_ns = 100000000; - data.timeout_clks = 0; - } - data.blksz = 4; data.blocks = 1; data.flags = MMC_DATA_READ; data.sg = &sg; data.sg_len = 1; + mmc_set_data_timeout(&data, card); mrq.cmd = &cmd; mrq.data = &data; From fe85227347738eb9b871bc163e7fb0db8b6cd2a0 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Fri, 22 Jun 2012 18:49:35 +0800 Subject: [PATCH 2/2] Revert "mmc: omap_hsmmc: Enable Auto CMD12" This patch reverts the commit dba3c29ea4a1d5d544. After bisecting, this commit dba3c29 is found to ruin micro-SD card data (writing incorrect file, or fs is corrupt after several times mount) on the beagle-xm revB, and reverting the commit will fix the problem. Also from TRM of OMAP3/OMAP4/DM37x, the below is mentioned about the Auto CMD12 Enable bit. - SDIO does not support this feature. - SD card only. Looks it is not suitable to always enable Auto CMD12 in host controller driver. Considered that the commit is not mature enough, so ask to revert it first. Cc: Balaji T K Cc: Venkatraman S Buglink: https://lkml.org/lkml/2012/6/10/225 Reported-by: Paolo Pisati Reported-bisected-and-tested-by: Ming Lei Signed-off-by: Ming Lei Acked-by: Venkatraman S Signed-off-by: Chris Ball --- drivers/mmc/host/omap_hsmmc.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 9a7a60aeb19e..389a3eedfc24 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -85,7 +85,6 @@ #define BRR_ENABLE (1 << 5) #define DTO_ENABLE (1 << 20) #define INIT_STREAM (1 << 1) -#define ACEN_ACMD12 (1 << 2) #define DP_SELECT (1 << 21) #define DDIR (1 << 4) #define DMA_EN 0x1 @@ -117,7 +116,6 @@ #define OMAP_MMC_MAX_CLOCK 52000000 #define DRIVER_NAME "omap_hsmmc" -#define AUTO_CMD12 (1 << 0) /* Auto CMD12 support */ /* * One controller can have multiple slots, like on some omap boards using * omap.c controller driver. Luckily this is not currently done on any known @@ -177,7 +175,6 @@ struct omap_hsmmc_host { int reqs_blocked; int use_reg; int req_in_progress; - unsigned int flags; struct omap_hsmmc_next next_data; struct omap_mmc_platform_data *pdata; @@ -773,8 +770,6 @@ omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd, cmdtype = 0x3; cmdreg = (cmd->opcode << 24) | (resptype << 16) | (cmdtype << 22); - if ((host->flags & AUTO_CMD12) && mmc_op_multi(cmd->opcode)) - cmdreg |= ACEN_ACMD12; if (data) { cmdreg |= DP_SELECT | MSBS | BCE; @@ -847,14 +842,11 @@ omap_hsmmc_xfer_done(struct omap_hsmmc_host *host, struct mmc_data *data) else data->bytes_xfered = 0; - if (data->stop && ((!(host->flags & AUTO_CMD12)) || data->error)) { - omap_hsmmc_start_command(host, data->stop, NULL); - } else { - if (data->stop) - data->stop->resp[0] = OMAP_HSMMC_READ(host->base, - RSP76); + if (!data->stop) { omap_hsmmc_request_done(host, data->mrq); + return; } + omap_hsmmc_start_command(host, data->stop, NULL); } /* @@ -1859,7 +1851,6 @@ static int __devinit omap_hsmmc_probe(struct platform_device *pdev) host->mapbase = res->start + pdata->reg_offset; host->base = ioremap(host->mapbase, SZ_4K); host->power_mode = MMC_POWER_OFF; - host->flags = AUTO_CMD12; host->next_data.cookie = 1; platform_set_drvdata(pdev, host);