diff options
author | Guennadi Liakhovetski <g.liakhovetski@gmx.de> | 2013-07-10 12:09:47 +0200 |
---|---|---|
committer | Vinod Koul <vinod.koul@intel.com> | 2013-08-27 14:24:07 +0530 |
commit | ca8b387803072a16baf6d8090591b10bfdf4e253 (patch) | |
tree | 369a7e9cc93d4ff6d7e9445d57ef933a107eb75f /drivers | |
parent | 115357e9774ff8d70a84d3c31f271209913637b0 (diff) | |
download | op-kernel-dev-ca8b387803072a16baf6d8090591b10bfdf4e253.zip op-kernel-dev-ca8b387803072a16baf6d8090591b10bfdf4e253.tar.gz |
DMA: shdma: support the new CHCLR register layout
On newer r-car SoCs the CHCLR register only contains one bit per channel,
to which a 1 has to be written to reset the channel. Older SoC versions had
one CHCLR register per channel, to which a 0 must be written to reset the
channel and clear its buffers. This patch adds support for the newer
layout.
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/dma/sh/shdma.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/drivers/dma/sh/shdma.c b/drivers/dma/sh/shdma.c index 9ee1272..53bd630 100644 --- a/drivers/dma/sh/shdma.c +++ b/drivers/dma/sh/shdma.c @@ -49,12 +49,22 @@ static DEFINE_SPINLOCK(sh_dmae_lock); static LIST_HEAD(sh_dmae_devices); +/* + * Different DMAC implementations provide different ways to clear DMA channels: + * (1) none - no CHCLR registers are available + * (2) one CHCLR register per channel - 0 has to be written to it to clear + * channel buffers + * (3) one CHCLR per several channels - 1 has to be written to the bit, + * corresponding to the specific channel to reset it + */ static void channel_clear(struct sh_dmae_chan *sh_dc) { struct sh_dmae_device *shdev = to_sh_dev(sh_dc); + const struct sh_dmae_channel *chan_pdata = shdev->pdata->channel + + sh_dc->shdma_chan.id; + u32 val = shdev->pdata->chclr_bitwise ? 1 << chan_pdata->chclr_bit : 0; - __raw_writel(0, shdev->chan_reg + - shdev->pdata->channel[sh_dc->shdma_chan.id].chclr_offset); + __raw_writel(val, shdev->chan_reg + chan_pdata->chclr_offset); } static void sh_dmae_writel(struct sh_dmae_chan *sh_dc, u32 data, u32 reg) |