dmaengine: shdma: Make second memory window optional
This patch makes the shdma.c driver allow slave operation on DMA hardware mapped with a single I/O-memory window. The dmae_set_dmars() function is adjusted to use the first memory window in case of a missing DMARS window. At probe() time the code is updated to enable DMA_SLAVE only if slave information is passed with the platform data. Signed-off-by: Magnus Damm <damm@opensource.se> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
This commit is contained in:
parent
66ad12931d
commit
26fc02ab55
|
@ -213,12 +213,17 @@ static int dmae_set_dmars(struct sh_dmae_chan *sh_chan, u16 val)
|
||||||
struct sh_dmae_device, common);
|
struct sh_dmae_device, common);
|
||||||
struct sh_dmae_pdata *pdata = shdev->pdata;
|
struct sh_dmae_pdata *pdata = shdev->pdata;
|
||||||
const struct sh_dmae_channel *chan_pdata = &pdata->channel[sh_chan->id];
|
const struct sh_dmae_channel *chan_pdata = &pdata->channel[sh_chan->id];
|
||||||
u16 __iomem *addr = shdev->dmars + chan_pdata->dmars / sizeof(u16);
|
u16 __iomem *addr = shdev->dmars;
|
||||||
int shift = chan_pdata->dmars_bit;
|
int shift = chan_pdata->dmars_bit;
|
||||||
|
|
||||||
if (dmae_is_busy(sh_chan))
|
if (dmae_is_busy(sh_chan))
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
|
/* in the case of a missing DMARS resource use first memory window */
|
||||||
|
if (!addr)
|
||||||
|
addr = (u16 __iomem *)shdev->chan_reg;
|
||||||
|
addr += chan_pdata->dmars / sizeof(u16);
|
||||||
|
|
||||||
__raw_writew((__raw_readw(addr) & (0xff00 >> shift)) | (val << shift),
|
__raw_writew((__raw_readw(addr) & (0xff00 >> shift)) | (val << shift),
|
||||||
addr);
|
addr);
|
||||||
|
|
||||||
|
@ -1087,7 +1092,7 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
chan = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
chan = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
/* DMARS area is optional, if absent, this controller cannot do slave DMA */
|
/* DMARS area is optional */
|
||||||
dmars = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
dmars = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||||
/*
|
/*
|
||||||
* IRQ resources:
|
* IRQ resources:
|
||||||
|
@ -1154,7 +1159,7 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
|
||||||
INIT_LIST_HEAD(&shdev->common.channels);
|
INIT_LIST_HEAD(&shdev->common.channels);
|
||||||
|
|
||||||
dma_cap_set(DMA_MEMCPY, shdev->common.cap_mask);
|
dma_cap_set(DMA_MEMCPY, shdev->common.cap_mask);
|
||||||
if (dmars)
|
if (pdata->slave && pdata->slave_num)
|
||||||
dma_cap_set(DMA_SLAVE, shdev->common.cap_mask);
|
dma_cap_set(DMA_SLAVE, shdev->common.cap_mask);
|
||||||
|
|
||||||
shdev->common.device_alloc_chan_resources
|
shdev->common.device_alloc_chan_resources
|
||||||
|
|
Loading…
Reference in New Issue