mmc: jz4740: Support using a bi-directional DMA channel
Since the MMC/SD controller in Ingenic SoCs work in half-duplex, it is possible to use one single DMA channel for both TX and RX operations, instead of using separate channels. As some older Ingenic SoCs offer only a handful of DMA channels, supporting bi-directional channels allow more hardware to use the channels that would otherwise be used for the MMC/SD operation. Signed-off-by: Paul Cercueil <paul@crapouillou.net> Link: https://lore.kernel.org/r/20211220190840.108061-3-paul@crapouillou.net Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
This commit is contained in:
Родитель
34ce293023
Коммит
a474e52c31
|
@ -217,11 +217,23 @@ static void jz4740_mmc_release_dma_channels(struct jz4740_mmc_host *host)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
dma_release_channel(host->dma_tx);
|
dma_release_channel(host->dma_tx);
|
||||||
dma_release_channel(host->dma_rx);
|
if (host->dma_rx)
|
||||||
|
dma_release_channel(host->dma_rx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int jz4740_mmc_acquire_dma_channels(struct jz4740_mmc_host *host)
|
static int jz4740_mmc_acquire_dma_channels(struct jz4740_mmc_host *host)
|
||||||
{
|
{
|
||||||
|
struct device *dev = mmc_dev(host->mmc);
|
||||||
|
|
||||||
|
host->dma_tx = dma_request_chan(dev, "tx-rx");
|
||||||
|
if (!IS_ERR(host->dma_tx))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (PTR_ERR(host->dma_tx) != -ENODEV) {
|
||||||
|
dev_err(dev, "Failed to get dma tx-rx channel\n");
|
||||||
|
return PTR_ERR(host->dma_tx);
|
||||||
|
}
|
||||||
|
|
||||||
host->dma_tx = dma_request_chan(mmc_dev(host->mmc), "tx");
|
host->dma_tx = dma_request_chan(mmc_dev(host->mmc), "tx");
|
||||||
if (IS_ERR(host->dma_tx)) {
|
if (IS_ERR(host->dma_tx)) {
|
||||||
dev_err(mmc_dev(host->mmc), "Failed to get dma_tx channel\n");
|
dev_err(mmc_dev(host->mmc), "Failed to get dma_tx channel\n");
|
||||||
|
@ -241,7 +253,10 @@ static int jz4740_mmc_acquire_dma_channels(struct jz4740_mmc_host *host)
|
||||||
static inline struct dma_chan *jz4740_mmc_get_dma_chan(struct jz4740_mmc_host *host,
|
static inline struct dma_chan *jz4740_mmc_get_dma_chan(struct jz4740_mmc_host *host,
|
||||||
struct mmc_data *data)
|
struct mmc_data *data)
|
||||||
{
|
{
|
||||||
return (data->flags & MMC_DATA_READ) ? host->dma_rx : host->dma_tx;
|
if ((data->flags & MMC_DATA_READ) && host->dma_rx)
|
||||||
|
return host->dma_rx;
|
||||||
|
else
|
||||||
|
return host->dma_tx;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void jz4740_mmc_dma_unmap(struct jz4740_mmc_host *host,
|
static void jz4740_mmc_dma_unmap(struct jz4740_mmc_host *host,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче