aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma
diff options
context:
space:
mode:
authorMagnus Damm <damm@opensource.se>2011-05-24 06:31:12 -0400
committerPaul Mundt <lethal@linux-sh.org>2011-05-24 22:35:23 -0400
commit26fc02ab5551349b2e593829a76cb44328ee7f61 (patch)
tree3ad395f8942e2e2ad869f508434e3738ad28bf45 /drivers/dma
parent66ad12931d523e833516659eafcc29af9a08fff3 (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.c11
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