summaryrefslogtreecommitdiff
path: root/drivers/mmc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/gen_atmel_mci.c28
-rw-r--r--drivers/mmc/rockchip_sdhci.c2
-rw-r--r--drivers/mmc/stm32_sdmmc2.c16
3 files changed, 30 insertions, 16 deletions
diff --git a/drivers/mmc/gen_atmel_mci.c b/drivers/mmc/gen_atmel_mci.c
index 6a531fa0961..838b4f4a65a 100644
--- a/drivers/mmc/gen_atmel_mci.c
+++ b/drivers/mmc/gen_atmel_mci.c
@@ -206,10 +206,9 @@ static u32 mci_data_read(atmel_mci_t *mci, u32* data, u32 error_flags)
goto io_fail;
} while (!(status & MMCI_BIT(RXRDY)));
- if (status & MMCI_BIT(RXRDY)) {
- *data = readl(&mci->rdr);
- status = 0;
- }
+ *data = readl(&mci->rdr);
+ status = 0;
+
io_fail:
return status;
}
@@ -225,10 +224,9 @@ static u32 mci_data_write(atmel_mci_t *mci, u32* data, u32 error_flags)
goto io_fail;
} while (!(status & MMCI_BIT(TXRDY)));
- if (status & MMCI_BIT(TXRDY)) {
- writel(*data, &mci->tdr);
- status = 0;
- }
+ writel(*data, &mci->tdr);
+ status = 0;
+
io_fail:
return status;
}
@@ -265,13 +263,15 @@ mci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
/* Figure out the transfer arguments */
cmdr = mci_encode_cmd(cmd, data, &error_flags);
- mci_set_blklen(mci, data->blocksize);
+ if (data) {
+ mci_set_blklen(mci, data->blocksize);
- /* For multi blocks read/write, set the block register */
- if ((cmd->cmdidx == MMC_CMD_READ_MULTIPLE_BLOCK)
- || (cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK))
- writel(data->blocks | MMCI_BF(BLKLEN, data->blocksize),
- &mci->blkr);
+ /* For multi blocks read/write, set the block register */
+ if (cmd->cmdidx == MMC_CMD_READ_MULTIPLE_BLOCK ||
+ cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK)
+ writel(data->blocks | MMCI_BF(BLKLEN, data->blocksize),
+ &mci->blkr);
+ }
/* Send the command */
writel(cmd->cmdarg, &mci->argr);
diff --git a/drivers/mmc/rockchip_sdhci.c b/drivers/mmc/rockchip_sdhci.c
index 761e3619329..5e025d76a82 100644
--- a/drivers/mmc/rockchip_sdhci.c
+++ b/drivers/mmc/rockchip_sdhci.c
@@ -500,7 +500,7 @@ static int rockchip_sdhci_execute_tuning(struct mmc *mmc, u8 opcode)
{
struct rockchip_sdhc *priv = dev_get_priv(mmc->dev);
struct sdhci_host *host = &priv->host;
- char tuning_loop_counter = SDHCI_TUNING_LOOP_COUNT;
+ s8 tuning_loop_counter = SDHCI_TUNING_LOOP_COUNT;
struct mmc_cmd cmd;
u32 ctrl, blk_size;
int ret;
diff --git a/drivers/mmc/stm32_sdmmc2.c b/drivers/mmc/stm32_sdmmc2.c
index 9483fb57daf..122690aef3e 100644
--- a/drivers/mmc/stm32_sdmmc2.c
+++ b/drivers/mmc/stm32_sdmmc2.c
@@ -385,15 +385,29 @@ static int stm32_sdmmc2_end_data(struct udevice *dev,
u32 mask = SDMMC_STA_DCRCFAIL | SDMMC_STA_DTIMEOUT |
SDMMC_STA_IDMATE | SDMMC_STA_DATAEND;
u32 status;
+ unsigned long timeout_msecs = ctx->data_length >> 8;
+ unsigned long start_timeout;
+
+ /* At least, a timeout of 2 seconds is set */
+ if (timeout_msecs < 2000)
+ timeout_msecs = 2000;
if (data->flags & MMC_DATA_READ)
mask |= SDMMC_STA_RXOVERR;
else
mask |= SDMMC_STA_TXUNDERR;
+ start_timeout = get_timer(0);
status = readl(plat->base + SDMMC_STA);
- while (!(status & mask))
+ while (!(status & mask)) {
+ if (get_timer(start_timeout) > timeout_msecs) {
+ ctx->dpsm_abort = true;
+ return -ETIMEDOUT;
+ }
+
+ schedule();
status = readl(plat->base + SDMMC_STA);
+ }
/*
* Need invalidate the dcache again to avoid any