diff options
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/gen_atmel_mci.c | 28 | ||||
-rw-r--r-- | drivers/mmc/rockchip_sdhci.c | 2 | ||||
-rw-r--r-- | drivers/mmc/stm32_sdmmc2.c | 16 |
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 |