diff options
Diffstat (limited to 'drivers/dma/sh')
-rw-r--r-- | drivers/dma/sh/Kconfig | 12 | ||||
-rw-r--r-- | drivers/dma/sh/Makefile | 1 | ||||
-rw-r--r-- | drivers/dma/sh/rcar-dmac.c | 32 | ||||
-rw-r--r-- | drivers/dma/sh/shdma-r8a73a4.c | 74 | ||||
-rw-r--r-- | drivers/dma/sh/shdma.h | 7 | ||||
-rw-r--r-- | drivers/dma/sh/shdmac.c | 7 | ||||
-rw-r--r-- | drivers/dma/sh/usb-dmac.c | 2 |
7 files changed, 31 insertions, 104 deletions
diff --git a/drivers/dma/sh/Kconfig b/drivers/dma/sh/Kconfig index 6e0685f1a838..4d6b02b3b1f1 100644 --- a/drivers/dma/sh/Kconfig +++ b/drivers/dma/sh/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # DMA engine configuration for sh # @@ -12,7 +13,7 @@ config RENESAS_DMA config SH_DMAE_BASE bool "Renesas SuperH DMA Engine support" - depends on SUPERH || ARCH_RENESAS || COMPILE_TEST + depends on SUPERH || COMPILE_TEST depends on !SUPERH || SH_DMA depends on !SH_DMA_API default y @@ -30,15 +31,6 @@ config SH_DMAE help Enable support for the Renesas SuperH DMA controllers. -if SH_DMAE - -config SH_DMAE_R8A73A4 - def_bool y - depends on ARCH_R8A73A4 - depends on OF - -endif - config RCAR_DMAC tristate "Renesas R-Car Gen2 DMA Controller" depends on ARCH_RENESAS || COMPILE_TEST diff --git a/drivers/dma/sh/Makefile b/drivers/dma/sh/Makefile index 7d7c9491ade1..42110dd57a56 100644 --- a/drivers/dma/sh/Makefile +++ b/drivers/dma/sh/Makefile @@ -10,7 +10,6 @@ obj-$(CONFIG_SH_DMAE_BASE) += shdma-base.o shdma-of.o # shdma-y := shdmac.o -shdma-$(CONFIG_SH_DMAE_R8A73A4) += shdma-r8a73a4.o shdma-objs := $(shdma-y) obj-$(CONFIG_SH_DMAE) += shdma.o diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c index 74fa2b1a6a86..e2a5398f89b5 100644 --- a/drivers/dma/sh/rcar-dmac.c +++ b/drivers/dma/sh/rcar-dmac.c @@ -1282,6 +1282,9 @@ static unsigned int rcar_dmac_chan_get_residue(struct rcar_dmac_chan *chan, enum dma_status status; unsigned int residue = 0; unsigned int dptr = 0; + unsigned int chcrb; + unsigned int tcrb; + unsigned int i; if (!desc) return 0; @@ -1330,14 +1333,31 @@ static unsigned int rcar_dmac_chan_get_residue(struct rcar_dmac_chan *chan, } /* + * We need to read two registers. + * Make sure the control register does not skip to next chunk + * while reading the counter. + * Trying it 3 times should be enough: Initial read, retry, retry + * for the paranoid. + */ + for (i = 0; i < 3; i++) { + chcrb = rcar_dmac_chan_read(chan, RCAR_DMACHCRB) & + RCAR_DMACHCRB_DPTR_MASK; + tcrb = rcar_dmac_chan_read(chan, RCAR_DMATCRB); + /* Still the same? */ + if (chcrb == (rcar_dmac_chan_read(chan, RCAR_DMACHCRB) & + RCAR_DMACHCRB_DPTR_MASK)) + break; + } + WARN_ONCE(i >= 3, "residue might be not continuous!"); + + /* * In descriptor mode the descriptor running pointer is not maintained * by the interrupt handler, find the running descriptor from the * descriptor pointer field in the CHCRB register. In non-descriptor * mode just use the running descriptor pointer. */ if (desc->hwdescs.use) { - dptr = (rcar_dmac_chan_read(chan, RCAR_DMACHCRB) & - RCAR_DMACHCRB_DPTR_MASK) >> RCAR_DMACHCRB_DPTR_SHIFT; + dptr = chcrb >> RCAR_DMACHCRB_DPTR_SHIFT; if (dptr == 0) dptr = desc->nchunks; dptr--; @@ -1355,7 +1375,7 @@ static unsigned int rcar_dmac_chan_get_residue(struct rcar_dmac_chan *chan, } /* Add the residue for the current chunk. */ - residue += rcar_dmac_chan_read(chan, RCAR_DMATCRB) << desc->xfer_shift; + residue += tcrb << desc->xfer_shift; return residue; } @@ -1368,6 +1388,7 @@ static enum dma_status rcar_dmac_tx_status(struct dma_chan *chan, enum dma_status status; unsigned long flags; unsigned int residue; + bool cyclic; status = dma_cookie_status(chan, cookie, txstate); if (status == DMA_COMPLETE || !txstate) @@ -1375,10 +1396,11 @@ static enum dma_status rcar_dmac_tx_status(struct dma_chan *chan, spin_lock_irqsave(&rchan->lock, flags); residue = rcar_dmac_chan_get_residue(rchan, cookie); + cyclic = rchan->desc.running ? rchan->desc.running->cyclic : false; spin_unlock_irqrestore(&rchan->lock, flags); /* if there's no residue, the cookie is complete */ - if (!residue) + if (!residue && !cyclic) return DMA_COMPLETE; dma_set_residue(txstate, residue); @@ -1809,7 +1831,7 @@ static int rcar_dmac_probe(struct platform_device *pdev) * level we can't disable it selectively, so ignore channel 0 for now if * the device is part of an IOMMU group. */ - if (pdev->dev.iommu_group) { + if (device_iommu_mapped(&pdev->dev)) { dmac->n_channels--; channels_offset = 1; } diff --git a/drivers/dma/sh/shdma-r8a73a4.c b/drivers/dma/sh/shdma-r8a73a4.c deleted file mode 100644 index ddc9a3578353..000000000000 --- a/drivers/dma/sh/shdma-r8a73a4.c +++ /dev/null @@ -1,74 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Renesas SuperH DMA Engine support for r8a73a4 (APE6) SoCs - * - * Copyright (C) 2013 Renesas Electronics, Inc. - */ -#include <linux/sh_dma.h> - -#include "shdma-arm.h" - -static const unsigned int dma_ts_shift[] = SH_DMAE_TS_SHIFT; - -static const struct sh_dmae_slave_config dma_slaves[] = { - { - .chcr = CHCR_TX(XMIT_SZ_32BIT), - .mid_rid = 0xd1, /* MMC0 Tx */ - }, { - .chcr = CHCR_RX(XMIT_SZ_32BIT), - .mid_rid = 0xd2, /* MMC0 Rx */ - }, { - .chcr = CHCR_TX(XMIT_SZ_32BIT), - .mid_rid = 0xe1, /* MMC1 Tx */ - }, { - .chcr = CHCR_RX(XMIT_SZ_32BIT), - .mid_rid = 0xe2, /* MMC1 Rx */ - }, -}; - -#define DMAE_CHANNEL(a, b) \ - { \ - .offset = (a) - 0x20, \ - .dmars = (a) - 0x20 + 0x40, \ - .chclr_bit = (b), \ - .chclr_offset = 0x80 - 0x20, \ - } - -static const struct sh_dmae_channel dma_channels[] = { - DMAE_CHANNEL(0x8000, 0), - DMAE_CHANNEL(0x8080, 1), - DMAE_CHANNEL(0x8100, 2), - DMAE_CHANNEL(0x8180, 3), - DMAE_CHANNEL(0x8200, 4), - DMAE_CHANNEL(0x8280, 5), - DMAE_CHANNEL(0x8300, 6), - DMAE_CHANNEL(0x8380, 7), - DMAE_CHANNEL(0x8400, 8), - DMAE_CHANNEL(0x8480, 9), - DMAE_CHANNEL(0x8500, 10), - DMAE_CHANNEL(0x8580, 11), - DMAE_CHANNEL(0x8600, 12), - DMAE_CHANNEL(0x8680, 13), - DMAE_CHANNEL(0x8700, 14), - DMAE_CHANNEL(0x8780, 15), - DMAE_CHANNEL(0x8800, 16), - DMAE_CHANNEL(0x8880, 17), - DMAE_CHANNEL(0x8900, 18), - DMAE_CHANNEL(0x8980, 19), -}; - -const struct sh_dmae_pdata r8a73a4_dma_pdata = { - .slave = dma_slaves, - .slave_num = ARRAY_SIZE(dma_slaves), - .channel = dma_channels, - .channel_num = ARRAY_SIZE(dma_channels), - .ts_low_shift = TS_LOW_SHIFT, - .ts_low_mask = TS_LOW_BIT << TS_LOW_SHIFT, - .ts_high_shift = TS_HI_SHIFT, - .ts_high_mask = TS_HI_BIT << TS_HI_SHIFT, - .ts_shift = dma_ts_shift, - .ts_shift_num = ARRAY_SIZE(dma_ts_shift), - .dmaor_init = DMAOR_DME, - .chclr_present = 1, - .chclr_bitwise = 1, -}; diff --git a/drivers/dma/sh/shdma.h b/drivers/dma/sh/shdma.h index bfb69909bd19..9c121a4b33ad 100644 --- a/drivers/dma/sh/shdma.h +++ b/drivers/dma/sh/shdma.h @@ -58,11 +58,4 @@ struct sh_dmae_desc { #define to_sh_dev(chan) container_of(chan->shdma_chan.dma_chan.device,\ struct sh_dmae_device, shdma_dev.dma_dev) -#ifdef CONFIG_SH_DMAE_R8A73A4 -extern const struct sh_dmae_pdata r8a73a4_dma_pdata; -#define r8a73a4_shdma_devid (&r8a73a4_dma_pdata) -#else -#define r8a73a4_shdma_devid NULL -#endif - #endif /* __DMA_SHDMA_H */ diff --git a/drivers/dma/sh/shdmac.c b/drivers/dma/sh/shdmac.c index 7971ea275387..5aafe548ca5f 100644 --- a/drivers/dma/sh/shdmac.c +++ b/drivers/dma/sh/shdmac.c @@ -665,12 +665,6 @@ static const struct shdma_ops sh_dmae_shdma_ops = { .get_partial = sh_dmae_get_partial, }; -static const struct of_device_id sh_dmae_of_match[] = { - {.compatible = "renesas,shdma-r8a73a4", .data = r8a73a4_shdma_devid,}, - {} -}; -MODULE_DEVICE_TABLE(of, sh_dmae_of_match); - static int sh_dmae_probe(struct platform_device *pdev) { const enum dma_slave_buswidth widths = @@ -915,7 +909,6 @@ static struct platform_driver sh_dmae_driver = { .driver = { .pm = &sh_dmae_pm, .name = SH_DMAE_DRV_NAME, - .of_match_table = sh_dmae_of_match, }, .remove = sh_dmae_remove, }; diff --git a/drivers/dma/sh/usb-dmac.c b/drivers/dma/sh/usb-dmac.c index 7f7184c3cf95..59403f6d008a 100644 --- a/drivers/dma/sh/usb-dmac.c +++ b/drivers/dma/sh/usb-dmac.c @@ -694,6 +694,8 @@ static int usb_dmac_runtime_resume(struct device *dev) #endif /* CONFIG_PM */ static const struct dev_pm_ops usb_dmac_pm = { + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, + pm_runtime_force_resume) SET_RUNTIME_PM_OPS(usb_dmac_runtime_suspend, usb_dmac_runtime_resume, NULL) }; |