diff options
author | Magnus Damm <damm@opensource.se> | 2011-05-24 06:31:12 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2011-05-24 22:35:23 -0400 |
commit | 26fc02ab5551349b2e593829a76cb44328ee7f61 (patch) | |
tree | 3ad395f8942e2e2ad869f508434e3738ad28bf45 /drivers/dma | |
parent | 66ad12931d523e833516659eafcc29af9a08fff3 (diff) |
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>
Diffstat (limited to 'drivers/dma')
-rw-r--r-- | drivers/dma/shdma.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index dcc1b2139fff..3391b157d057 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c | |||
@@ -213,12 +213,17 @@ static int dmae_set_dmars(struct sh_dmae_chan *sh_chan, u16 val) | |||
213 | struct sh_dmae_device, common); | 213 | struct sh_dmae_device, common); |
214 | struct sh_dmae_pdata *pdata = shdev->pdata; | 214 | struct sh_dmae_pdata *pdata = shdev->pdata; |
215 | const struct sh_dmae_channel *chan_pdata = &pdata->channel[sh_chan->id]; | 215 | const struct sh_dmae_channel *chan_pdata = &pdata->channel[sh_chan->id]; |
216 | u16 __iomem *addr = shdev->dmars + chan_pdata->dmars / sizeof(u16); | 216 | u16 __iomem *addr = shdev->dmars; |
217 | int shift = chan_pdata->dmars_bit; | 217 | int shift = chan_pdata->dmars_bit; |
218 | 218 | ||
219 | if (dmae_is_busy(sh_chan)) | 219 | if (dmae_is_busy(sh_chan)) |
220 | return -EBUSY; | 220 | return -EBUSY; |
221 | 221 | ||
222 | /* in the case of a missing DMARS resource use first memory window */ | ||
223 | if (!addr) | ||
224 | addr = (u16 __iomem *)shdev->chan_reg; | ||
225 | addr += chan_pdata->dmars / sizeof(u16); | ||
226 | |||
222 | __raw_writew((__raw_readw(addr) & (0xff00 >> shift)) | (val << shift), | 227 | __raw_writew((__raw_readw(addr) & (0xff00 >> shift)) | (val << shift), |
223 | addr); | 228 | addr); |
224 | 229 | ||
@@ -1087,7 +1092,7 @@ static int __init sh_dmae_probe(struct platform_device *pdev) | |||
1087 | return -ENODEV; | 1092 | return -ENODEV; |
1088 | 1093 | ||
1089 | chan = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1094 | chan = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1090 | /* DMARS area is optional, if absent, this controller cannot do slave DMA */ | 1095 | /* DMARS area is optional */ |
1091 | dmars = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 1096 | dmars = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
1092 | /* | 1097 | /* |
1093 | * IRQ resources: | 1098 | * IRQ resources: |
@@ -1154,7 +1159,7 @@ static int __init sh_dmae_probe(struct platform_device *pdev) | |||
1154 | INIT_LIST_HEAD(&shdev->common.channels); | 1159 | INIT_LIST_HEAD(&shdev->common.channels); |
1155 | 1160 | ||
1156 | dma_cap_set(DMA_MEMCPY, shdev->common.cap_mask); | 1161 | dma_cap_set(DMA_MEMCPY, shdev->common.cap_mask); |
1157 | if (dmars) | 1162 | if (pdata->slave && pdata->slave_num) |
1158 | dma_cap_set(DMA_SLAVE, shdev->common.cap_mask); | 1163 | dma_cap_set(DMA_SLAVE, shdev->common.cap_mask); |
1159 | 1164 | ||
1160 | shdev->common.device_alloc_chan_resources | 1165 | shdev->common.device_alloc_chan_resources |