From 91cf54feecf815bec0b6a8d6d9dbd0e219f2f2cc Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 13 Mar 2013 17:11:59 +0100 Subject: mmc: at91/avr32/atmel-mci: fix DMA-channel leak on module unload Fix regression introduced by commit 796211b7953 ("mmc: atmel-mci: add pdc support and runtime capabilities detection") which removed the need for CONFIG_MMC_ATMELMCI_DMA but kept the Kconfig-entry as well as the compile guards around dma_release_channel() in remove(). Consequently, DMA is always enabled (if supported), but the DMA-channel is not released on module unload unless the DMA-config option is selected. Remove the no longer used CONFIG_MMC_ATMELMCI_DMA option completely. Signed-off-by: Johan Hovold Acked-by: Ludovic Desroches Cc: stable Signed-off-by: Chris Ball --- arch/arm/configs/at91sam9g45_defconfig | 1 - arch/avr32/configs/favr-32_defconfig | 1 - arch/avr32/configs/merisc_defconfig | 1 - 3 files changed, 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/configs/at91sam9g45_defconfig b/arch/arm/configs/at91sam9g45_defconfig index 606d48f3b8f8..8aab786863df 100644 --- a/arch/arm/configs/at91sam9g45_defconfig +++ b/arch/arm/configs/at91sam9g45_defconfig @@ -173,7 +173,6 @@ CONFIG_MMC=y # CONFIG_MMC_BLOCK_BOUNCE is not set CONFIG_SDIO_UART=m CONFIG_MMC_ATMELMCI=y -CONFIG_MMC_ATMELMCI_DMA=y CONFIG_LEDS_ATMEL_PWM=y CONFIG_LEDS_GPIO=y CONFIG_LEDS_TRIGGER_TIMER=y diff --git a/arch/avr32/configs/favr-32_defconfig b/arch/avr32/configs/favr-32_defconfig index 0421498d666b..97918204f795 100644 --- a/arch/avr32/configs/favr-32_defconfig +++ b/arch/avr32/configs/favr-32_defconfig @@ -122,7 +122,6 @@ CONFIG_USB_G_SERIAL=m CONFIG_USB_CDC_COMPOSITE=m CONFIG_MMC=y CONFIG_MMC_ATMELMCI=y -CONFIG_MMC_ATMELMCI_DMA=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y CONFIG_LEDS_ATMEL_PWM=m diff --git a/arch/avr32/configs/merisc_defconfig b/arch/avr32/configs/merisc_defconfig index 3befab966827..65de4431108c 100644 --- a/arch/avr32/configs/merisc_defconfig +++ b/arch/avr32/configs/merisc_defconfig @@ -102,7 +102,6 @@ CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y CONFIG_MMC=y CONFIG_MMC_ATMELMCI=y -CONFIG_MMC_ATMELMCI_DMA=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y CONFIG_LEDS_ATMEL_PWM=y -- cgit v1.2.3 From e48fc15aa205f380b2fc6d565724a55b1efd8083 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Mon, 8 Apr 2013 23:28:09 +0200 Subject: mmc: mxcmmc: enable DMA support on mpc512x Add SDHC DMA channel description to the mpc512x device tree to enable slave channel requesting in the mxcmmc driver. mpc512x DMA engine doesn't support endianness conversion when reading/writing data from peripheral's FIFO, so we have to swap data buffers before each DMA write and after each DMA read transfer manually. Since chained SDHC DMA transfers are not supported on mpc512x, limit 'max_segs' tunable parameter to one and initialise it to 64 only when running on i.MX platforms. Signed-off-by: Anatolij Gustschin Acked-by: Sascha Hauer Signed-off-by: Chris Ball --- arch/powerpc/boot/dts/mpc5121.dtsi | 2 ++ drivers/mmc/host/mxcmmc.c | 35 +++++++++++++++++++++++++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/boot/dts/mpc5121.dtsi b/arch/powerpc/boot/dts/mpc5121.dtsi index 723e292b6b4e..710aae6ecb40 100644 --- a/arch/powerpc/boot/dts/mpc5121.dtsi +++ b/arch/powerpc/boot/dts/mpc5121.dtsi @@ -152,6 +152,8 @@ compatible = "fsl,mpc5121-sdhc"; reg = <0x1500 0x100>; interrupts = <8 0x8>; + dmas = <&dma0 30>; + dma-names = "rx-tx"; }; i2c@1700 { diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index 5d528269587f..d5036353bddc 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c @@ -301,6 +301,29 @@ static void mxcmci_softreset(struct mxcmci_host *host) } static int mxcmci_setup_dma(struct mmc_host *mmc); +#if IS_ENABLED(CONFIG_PPC_MPC512x) +static inline void buffer_swap32(u32 *buf, int len) +{ + int i; + + for (i = 0; i < ((len + 3) / 4); i++) { + st_le32(buf, *buf); + buf++; + } +} + +static void mxcmci_swap_buffers(struct mmc_data *data) +{ + struct scatterlist *sg; + int i; + + for_each_sg(data->sg, sg, data->sg_len, i) + buffer_swap32(sg_virt(sg), sg->length); +} +#else +static inline void mxcmci_swap_buffers(struct mmc_data *data) {} +#endif + static int mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data) { unsigned int nob = data->blocks; @@ -336,6 +359,8 @@ static int mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data) } else { host->dma_dir = DMA_TO_DEVICE; slave_dirn = DMA_MEM_TO_DEV; + + mxcmci_swap_buffers(data); } nents = dma_map_sg(host->dma->device->dev, data->sg, @@ -461,9 +486,11 @@ static int mxcmci_finish_data(struct mxcmci_host *host, unsigned int stat) struct mmc_data *data = host->data; int data_error; - if (mxcmci_use_dma(host)) + if (mxcmci_use_dma(host)) { dma_unmap_sg(host->dma->device->dev, data->sg, data->sg_len, host->dma_dir); + mxcmci_swap_buffers(data); + } if (stat & STATUS_ERR_MASK) { dev_dbg(mmc_dev(host->mmc), "request failed. status: 0x%08x\n", @@ -1050,7 +1077,6 @@ static int mxcmci_probe(struct platform_device *pdev) mmc->caps |= MMC_CAP_SDIO_IRQ; /* MMC core transfer sizes tunable parameters */ - mmc->max_segs = 64; mmc->max_blk_size = 2048; mmc->max_blk_count = 65535; mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; @@ -1069,6 +1095,11 @@ static int mxcmci_probe(struct platform_device *pdev) } else { host->devtype = pdev->id_entry->driver_data; } + + /* adjust max_segs after devtype detection */ + if (!is_mpc512x_mmc(host)) + mmc->max_segs = 64; + host->mmc = mmc; host->pdata = pdata; spin_lock_init(&host->lock); -- cgit v1.2.3