Skip to content

Commit 89bcd9a

Browse files
Mengqi Zhangstorulf
authored andcommitted
mmc: mediatek: wait dma stop bit reset to 0
MediaTek IP requires that after dma stop, it need to wait this dma stop bit auto-reset to 0. When bus is in high loading state, it will take a while for the dma stop complete. If there is no waiting operation here, when program runs to clear fifo and reset, bus will hang. In addition, there should be no return in msdc_data_xfer_next() if there is data need be transferred, because no matter what error occurs here, it should continue to excute to the following mmc_request_done. Otherwise the core layer may wait complete forever. Signed-off-by: Mengqi Zhang <[email protected]> Cc: [email protected] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Ulf Hansson <[email protected]>
1 parent e591fcf commit 89bcd9a

File tree

1 file changed

+12
-8
lines changed

1 file changed

+12
-8
lines changed

drivers/mmc/host/mtk-sd.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1356,7 +1356,7 @@ static void msdc_data_xfer_next(struct msdc_host *host, struct mmc_request *mrq)
13561356
msdc_request_done(host, mrq);
13571357
}
13581358

1359-
static bool msdc_data_xfer_done(struct msdc_host *host, u32 events,
1359+
static void msdc_data_xfer_done(struct msdc_host *host, u32 events,
13601360
struct mmc_request *mrq, struct mmc_data *data)
13611361
{
13621362
struct mmc_command *stop;
@@ -1376,7 +1376,7 @@ static bool msdc_data_xfer_done(struct msdc_host *host, u32 events,
13761376
spin_unlock_irqrestore(&host->lock, flags);
13771377

13781378
if (done)
1379-
return true;
1379+
return;
13801380
stop = data->stop;
13811381

13821382
if (check_data || (stop && stop->error)) {
@@ -1385,12 +1385,15 @@ static bool msdc_data_xfer_done(struct msdc_host *host, u32 events,
13851385
sdr_set_field(host->base + MSDC_DMA_CTRL, MSDC_DMA_CTRL_STOP,
13861386
1);
13871387

1388+
ret = readl_poll_timeout_atomic(host->base + MSDC_DMA_CTRL, val,
1389+
!(val & MSDC_DMA_CTRL_STOP), 1, 20000);
1390+
if (ret)
1391+
dev_dbg(host->dev, "DMA stop timed out\n");
1392+
13881393
ret = readl_poll_timeout_atomic(host->base + MSDC_DMA_CFG, val,
13891394
!(val & MSDC_DMA_CFG_STS), 1, 20000);
1390-
if (ret) {
1391-
dev_dbg(host->dev, "DMA stop timed out\n");
1392-
return false;
1393-
}
1395+
if (ret)
1396+
dev_dbg(host->dev, "DMA inactive timed out\n");
13941397

13951398
sdr_clr_bits(host->base + MSDC_INTEN, data_ints_mask);
13961399
dev_dbg(host->dev, "DMA stop\n");
@@ -1415,9 +1418,7 @@ static bool msdc_data_xfer_done(struct msdc_host *host, u32 events,
14151418
}
14161419

14171420
msdc_data_xfer_next(host, mrq);
1418-
done = true;
14191421
}
1420-
return done;
14211422
}
14221423

14231424
static void msdc_set_buswidth(struct msdc_host *host, u32 width)
@@ -2416,6 +2417,9 @@ static void msdc_cqe_disable(struct mmc_host *mmc, bool recovery)
24162417
if (recovery) {
24172418
sdr_set_field(host->base + MSDC_DMA_CTRL,
24182419
MSDC_DMA_CTRL_STOP, 1);
2420+
if (WARN_ON(readl_poll_timeout(host->base + MSDC_DMA_CTRL, val,
2421+
!(val & MSDC_DMA_CTRL_STOP), 1, 3000)))
2422+
return;
24192423
if (WARN_ON(readl_poll_timeout(host->base + MSDC_DMA_CFG, val,
24202424
!(val & MSDC_DMA_CFG_STS), 1, 3000)))
24212425
return;

0 commit comments

Comments
 (0)