Commit d3dd5db0 authored by Masahiro Yamada's avatar Masahiro Yamada Committed by Ulf Hansson
Browse files

mmc: tmio: simplify the DMA mode test

host->chan_{rx,tx} represents the DMA capability of the platform.
Even if DMA is supported, there are cases where we want to use PIO,
for example, data length is short enough as commit 5f52c355


("mmc: tmio: use PIO for short transfers") mentioned.

Regarding the hardware control flow, we are interested in whether DMA
is currently enabled or not, instead of whether the platform has the
DMA capability.

Hence, the several conditionals in tmio_mmc_core.c end up with
checking host->chan_{rx,tx} and !host->force_pio. This is not nice.

Let's flip the flag host->force_pio into host->dma_on.

host->dma_on represents whether the DMA is currently enabled or not.
This flag is set false in the beginning of each command, then should
be set true by tmio_mmc_start_dma() when the DMA is turned on.

Signed-off-by: default avatarMasahiro Yamada <yamada.masahiro@socionext.com>
Reviewed-by: default avatarWolfram Sang <wsa+renesas@sang-engineering.com>
Tested-by: default avatarWolfram Sang <wsa+renesas@sang-engineering.com>
Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
parent 722fb61e
......@@ -199,13 +199,14 @@ renesas_sdhi_internal_dmac_start_dma(struct tmio_mmc_host *host,
renesas_sdhi_internal_dmac_dm_write(host, DM_DTRAN_ADDR,
sg_dma_address(sg));
host->dma_on = true;
return;
force_pio_with_unmap:
dma_unmap_sg(&host->pdev->dev, sg, host->sg_len, mmc_get_dma_dir(data));
force_pio:
host->force_pio = true;
renesas_sdhi_internal_dmac_enable_dma(host, false);
}
......
......@@ -210,10 +210,8 @@ static void renesas_sdhi_sys_dmac_start_dma_rx(struct tmio_mmc_host *host)
goto pio;
}
if (sg->length < TMIO_MMC_MIN_DMA_LEN) {
host->force_pio = true;
if (sg->length < TMIO_MMC_MIN_DMA_LEN)
return;
}
/* The only sg element can be unaligned, use our bounce buffer then */
if (!aligned) {
......@@ -237,6 +235,7 @@ static void renesas_sdhi_sys_dmac_start_dma_rx(struct tmio_mmc_host *host)
desc = NULL;
ret = cookie;
}
host->dma_on = true;
}
pio:
if (!desc) {
......@@ -283,10 +282,8 @@ static void renesas_sdhi_sys_dmac_start_dma_tx(struct tmio_mmc_host *host)
goto pio;
}
if (sg->length < TMIO_MMC_MIN_DMA_LEN) {
host->force_pio = true;
if (sg->length < TMIO_MMC_MIN_DMA_LEN)
return;
}
/* The only sg element can be unaligned, use our bounce buffer then */
if (!aligned) {
......@@ -315,6 +312,7 @@ static void renesas_sdhi_sys_dmac_start_dma_tx(struct tmio_mmc_host *host)
desc = NULL;
ret = cookie;
}
host->dma_on = true;
}
pio:
if (!desc) {
......
......@@ -138,7 +138,7 @@ struct tmio_mmc_host {
struct tmio_mmc_data *pdata;
/* DMA support */
bool force_pio;
bool dma_on;
struct dma_chan *chan_rx;
struct dma_chan *chan_tx;
struct tasklet_struct dma_issue;
......
......@@ -361,7 +361,7 @@ static void tmio_mmc_pio_irq(struct tmio_mmc_host *host)
unsigned int count;
unsigned long flags;
if ((host->chan_tx || host->chan_rx) && !host->force_pio) {
if (host->dma_on) {
pr_err("PIO IRQ in DMA mode!\n");
return;
} else if (!data) {
......@@ -433,7 +433,7 @@ void tmio_mmc_do_data_irq(struct tmio_mmc_host *host)
*/
if (data->flags & MMC_DATA_READ) {
if (host->chan_rx && !host->force_pio)
if (host->dma_on)
tmio_mmc_check_bounce_buffer(host);
dev_dbg(&host->pdev->dev, "Complete Rx request %p\n",
host->mrq);
......@@ -470,7 +470,7 @@ static void tmio_mmc_data_irq(struct tmio_mmc_host *host, unsigned int stat)
if (stat & TMIO_STAT_CRCFAIL || stat & TMIO_STAT_STOPBIT_ERR ||
stat & TMIO_STAT_TXUNDERRUN)
data->error = -EILSEQ;
if (host->chan_tx && (data->flags & MMC_DATA_WRITE) && !host->force_pio) {
if (host->dma_on && (data->flags & MMC_DATA_WRITE)) {
u32 status = sd_ctrl_read16_and_16_as_32(host, CTL_STATUS);
bool done = false;
......@@ -494,7 +494,7 @@ static void tmio_mmc_data_irq(struct tmio_mmc_host *host, unsigned int stat)
tmio_mmc_disable_mmc_irqs(host, TMIO_STAT_DATAEND);
tmio_mmc_dataend_dma(host);
}
} else if (host->chan_rx && (data->flags & MMC_DATA_READ) && !host->force_pio) {
} else if (host->dma_on && (data->flags & MMC_DATA_READ)) {
tmio_mmc_disable_mmc_irqs(host, TMIO_STAT_DATAEND);
tmio_mmc_dataend_dma(host);
} else {
......@@ -547,7 +547,7 @@ static void tmio_mmc_cmd_irq(struct tmio_mmc_host *host, unsigned int stat)
*/
if (host->data && (!cmd->error || cmd->error == -EILSEQ)) {
if (host->data->flags & MMC_DATA_READ) {
if (host->force_pio || !host->chan_rx) {
if (!host->dma_on) {
tmio_mmc_enable_mmc_irqs(host, TMIO_MASK_READOP);
} else {
tmio_mmc_disable_mmc_irqs(host,
......@@ -555,7 +555,7 @@ static void tmio_mmc_cmd_irq(struct tmio_mmc_host *host, unsigned int stat)
tasklet_schedule(&host->dma_issue);
}
} else {
if (host->force_pio || !host->chan_tx) {
if (!host->dma_on) {
tmio_mmc_enable_mmc_irqs(host, TMIO_MASK_WRITEOP);
} else {
tmio_mmc_disable_mmc_irqs(host,
......@@ -685,7 +685,7 @@ static int tmio_mmc_start_data(struct tmio_mmc_host *host,
tmio_mmc_init_sg(host, data);
host->data = data;
host->force_pio = false;
host->dma_on = false;
/* Set transfer length / blocksize */
sd_ctrl_write16(host, CTL_SD_XFER_LEN, data->blksz);
......
......@@ -157,13 +157,14 @@ static void uniphier_sd_external_dma_start(struct tmio_mmc_host *host,
if (cookie < 0)
goto unmap_sg;
host->dma_on = true;
return;
unmap_sg:
dma_unmap_sg(mmc_dev(host->mmc), host->sg_ptr, host->sg_len,
priv->dma_dir);
force_pio:
host->force_pio = true;
uniphier_sd_dma_endisable(host, 0);
}
......@@ -280,9 +281,10 @@ static void uniphier_sd_internal_dma_start(struct tmio_mmc_host *host,
writel(lower_32_bits(dma_addr), host->ctl + UNIPHIER_SD_DMA_ADDR_L);
writel(upper_32_bits(dma_addr), host->ctl + UNIPHIER_SD_DMA_ADDR_H);
host->dma_on = true;
return;
force_pio:
host->force_pio = true;
uniphier_sd_dma_endisable(host, 0);
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment