diff --git a/drivers/mci/imx-esdhc.c b/drivers/mci/imx-esdhc.c index b91f94b..8929901 100644 --- a/drivers/mci/imx-esdhc.c +++ b/drivers/mci/imx-esdhc.c @@ -211,18 +211,14 @@ return 0; } -static int esdhc_setup_data(struct mci_host *mci, struct mci_data *data) +static int esdhc_setup_data(struct mci_host *mci, struct mci_data *data, + dma_addr_t dma) { struct fsl_esdhc_host *host = to_fsl_esdhc(mci); void __iomem *regs = host->regs; u32 wml_value; - if (IS_ENABLED(CONFIG_MCI_IMX_ESDHC_PIO)) { - if (!(data->flags & MMC_DATA_READ)) - esdhc_write32(regs + SDHCI_DMA_ADDRESS, (u32)data->src); - else - esdhc_write32(regs + SDHCI_DMA_ADDRESS, (u32)data->dest); - } else { + if (!IS_ENABLED(CONFIG_MCI_IMX_ESDHC_PIO)) { wml_value = data->blocksize/4; if (data->flags & MMC_DATA_READ) { @@ -230,15 +226,14 @@ wml_value = 0x10; esdhc_clrsetbits32(regs + IMX_SDHCI_WML, WML_RD_WML_MASK, wml_value); - esdhc_write32(regs + SDHCI_DMA_ADDRESS, (u32)data->dest); } else { if (wml_value > 0x80) wml_value = 0x80; esdhc_clrsetbits32(regs + IMX_SDHCI_WML, WML_WR_WML_MASK, wml_value << 16); - esdhc_write32(regs + SDHCI_DMA_ADDRESS, (u32)data->src); } + esdhc_write32(regs + SDHCI_DMA_ADDRESS, dma); } esdhc_write32(regs + SDHCI_BLOCK_SIZE__BLOCK_COUNT, data->blocks << 16 | data->blocksize); @@ -250,7 +245,6 @@ { struct fsl_esdhc_host *host = to_fsl_esdhc(mci); void __iomem *regs = host->regs; - unsigned int num_bytes = data->blocks * data->blocksize; u32 irqstat; if (IS_ENABLED(CONFIG_MCI_IMX_ESDHC_PIO)) @@ -267,13 +261,6 @@ } while (!(irqstat & IRQSTAT_TC) && (esdhc_read32(regs + SDHCI_PRESENT_STATE) & PRSSTAT_DLA)); - if (data->flags & MMC_DATA_WRITE) - dma_sync_single_for_cpu((unsigned long)data->src, - num_bytes, DMA_TO_DEVICE); - else - dma_sync_single_for_cpu((unsigned long)data->dest, - num_bytes, DMA_FROM_DEVICE); - return 0; } @@ -290,6 +277,9 @@ void __iomem *regs = host->regs; unsigned int num_bytes = 0; int ret; + void *ptr; + enum dma_data_direction dir = 0; + dma_addr_t dma = 0; esdhc_write32(regs + SDHCI_INT_STATUS, -1); @@ -300,19 +290,25 @@ if (data) { int err; - err = esdhc_setup_data(mci, data); + if (!IS_ENABLED(CONFIG_MCI_IMX_ESDHC_PIO)) { + num_bytes = data->blocks * data->blocksize; + + if (data->flags & MMC_DATA_WRITE) { + ptr = (void *)data->src; + dir = DMA_TO_DEVICE; + } else { + ptr = data->dest; + dir = DMA_FROM_DEVICE; + } + + dma = dma_map_single(host->dev, ptr, num_bytes, dir); + if (dma_mapping_error(host->dev, dma)) + return -EIO; + } + + err = esdhc_setup_data(mci, data, dma); if(err) return err; - - num_bytes = data->blocks * data->blocksize; - - if (data->flags & MMC_DATA_WRITE) - dma_sync_single_for_device((unsigned long)data->src, - num_bytes, DMA_TO_DEVICE); - else - dma_sync_single_for_device((unsigned long)data->dest, - num_bytes, DMA_FROM_DEVICE); - } /* Figure out the transfer arguments */ @@ -383,6 +379,9 @@ ret = esdhc_do_data(mci, data); if (ret) return ret; + + if (!IS_ENABLED(CONFIG_MCI_IMX_ESDHC_PIO)) + dma_unmap_single(host->dev, dma, num_bytes, dir); } esdhc_write32(regs + SDHCI_INT_STATUS, -1);