diff options
Diffstat (limited to 'arch/arm/plat-s3c24xx/dma.c')
-rw-r--r-- | arch/arm/plat-s3c24xx/dma.c | 47 |
1 files changed, 40 insertions, 7 deletions
diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c index aae1b9cbaf44..ac9ff1666fcc 100644 --- a/arch/arm/plat-s3c24xx/dma.c +++ b/arch/arm/plat-s3c24xx/dma.c | |||
@@ -525,7 +525,8 @@ int s3c2410_dma_enqueue(unsigned int channel, void *id, | |||
525 | } | 525 | } |
526 | } else if (chan->state == S3C2410_DMA_IDLE) { | 526 | } else if (chan->state == S3C2410_DMA_IDLE) { |
527 | if (chan->flags & S3C2410_DMAF_AUTOSTART) { | 527 | if (chan->flags & S3C2410_DMAF_AUTOSTART) { |
528 | s3c2410_dma_ctrl(chan->number, S3C2410_DMAOP_START); | 528 | s3c2410_dma_ctrl(chan->number | DMACH_LOW_LEVEL, |
529 | S3C2410_DMAOP_START); | ||
529 | } | 530 | } |
530 | } | 531 | } |
531 | 532 | ||
@@ -787,7 +788,7 @@ int s3c2410_dma_request(unsigned int channel, | |||
787 | 788 | ||
788 | pr_debug("%s: channel initialised, %p\n", __FUNCTION__, chan); | 789 | pr_debug("%s: channel initialised, %p\n", __FUNCTION__, chan); |
789 | 790 | ||
790 | return 0; | 791 | return chan->number | DMACH_LOW_LEVEL; |
791 | } | 792 | } |
792 | 793 | ||
793 | EXPORT_SYMBOL(s3c2410_dma_request); | 794 | EXPORT_SYMBOL(s3c2410_dma_request); |
@@ -1173,6 +1174,7 @@ int s3c2410_dma_devconfig(int channel, | |||
1173 | 1174 | ||
1174 | chan->source = source; | 1175 | chan->source = source; |
1175 | chan->dev_addr = devaddr; | 1176 | chan->dev_addr = devaddr; |
1177 | chan->hw_cfg = hwcfg; | ||
1176 | 1178 | ||
1177 | switch (source) { | 1179 | switch (source) { |
1178 | case S3C2410_DMASRC_HW: | 1180 | case S3C2410_DMASRC_HW: |
@@ -1184,7 +1186,7 @@ int s3c2410_dma_devconfig(int channel, | |||
1184 | dma_wrreg(chan, S3C2410_DMA_DIDSTC, (0<<1) | (0<<0)); | 1186 | dma_wrreg(chan, S3C2410_DMA_DIDSTC, (0<<1) | (0<<0)); |
1185 | 1187 | ||
1186 | chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DIDST); | 1188 | chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DIDST); |
1187 | return 0; | 1189 | break; |
1188 | 1190 | ||
1189 | case S3C2410_DMASRC_MEM: | 1191 | case S3C2410_DMASRC_MEM: |
1190 | /* source is memory */ | 1192 | /* source is memory */ |
@@ -1195,11 +1197,19 @@ int s3c2410_dma_devconfig(int channel, | |||
1195 | dma_wrreg(chan, S3C2410_DMA_DIDSTC, hwcfg & 3); | 1197 | dma_wrreg(chan, S3C2410_DMA_DIDSTC, hwcfg & 3); |
1196 | 1198 | ||
1197 | chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DISRC); | 1199 | chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DISRC); |
1198 | return 0; | 1200 | break; |
1201 | |||
1202 | default: | ||
1203 | printk(KERN_ERR "dma%d: invalid source type (%d)\n", | ||
1204 | channel, source); | ||
1205 | |||
1206 | return -EINVAL; | ||
1199 | } | 1207 | } |
1200 | 1208 | ||
1201 | printk(KERN_ERR "dma%d: invalid source type (%d)\n", channel, source); | 1209 | if (dma_sel.direction != NULL) |
1202 | return -EINVAL; | 1210 | (dma_sel.direction)(chan, chan->map, source); |
1211 | |||
1212 | return 0; | ||
1203 | } | 1213 | } |
1204 | 1214 | ||
1205 | EXPORT_SYMBOL(s3c2410_dma_devconfig); | 1215 | EXPORT_SYMBOL(s3c2410_dma_devconfig); |
@@ -1227,6 +1237,10 @@ int s3c2410_dma_getposition(dmach_t channel, dma_addr_t *src, dma_addr_t *dst) | |||
1227 | 1237 | ||
1228 | EXPORT_SYMBOL(s3c2410_dma_getposition); | 1238 | EXPORT_SYMBOL(s3c2410_dma_getposition); |
1229 | 1239 | ||
1240 | static struct s3c2410_dma_chan *to_dma_chan(struct sys_device *dev) | ||
1241 | { | ||
1242 | return container_of(dev, struct s3c2410_dma_chan, dev); | ||
1243 | } | ||
1230 | 1244 | ||
1231 | /* system device class */ | 1245 | /* system device class */ |
1232 | 1246 | ||
@@ -1234,7 +1248,7 @@ EXPORT_SYMBOL(s3c2410_dma_getposition); | |||
1234 | 1248 | ||
1235 | static int s3c2410_dma_suspend(struct sys_device *dev, pm_message_t state) | 1249 | static int s3c2410_dma_suspend(struct sys_device *dev, pm_message_t state) |
1236 | { | 1250 | { |
1237 | struct s3c2410_dma_chan *cp = container_of(dev, struct s3c2410_dma_chan, dev); | 1251 | struct s3c2410_dma_chan *cp = to_dma_chan(dev); |
1238 | 1252 | ||
1239 | printk(KERN_DEBUG "suspending dma channel %d\n", cp->number); | 1253 | printk(KERN_DEBUG "suspending dma channel %d\n", cp->number); |
1240 | 1254 | ||
@@ -1256,6 +1270,24 @@ static int s3c2410_dma_suspend(struct sys_device *dev, pm_message_t state) | |||
1256 | 1270 | ||
1257 | static int s3c2410_dma_resume(struct sys_device *dev) | 1271 | static int s3c2410_dma_resume(struct sys_device *dev) |
1258 | { | 1272 | { |
1273 | struct s3c2410_dma_chan *cp = to_dma_chan(dev); | ||
1274 | unsigned int no = cp->number | DMACH_LOW_LEVEL; | ||
1275 | |||
1276 | /* restore channel's hardware configuration */ | ||
1277 | |||
1278 | if (!cp->in_use) | ||
1279 | return 0; | ||
1280 | |||
1281 | printk(KERN_INFO "dma%d: restoring configuration\n", cp->number); | ||
1282 | |||
1283 | s3c2410_dma_config(no, cp->xfer_unit, cp->dcon); | ||
1284 | s3c2410_dma_devconfig(no, cp->source, cp->hw_cfg, cp->dev_addr); | ||
1285 | |||
1286 | /* re-select the dma source for this channel */ | ||
1287 | |||
1288 | if (cp->map != NULL) | ||
1289 | dma_sel.select(cp, cp->map); | ||
1290 | |||
1259 | return 0; | 1291 | return 0; |
1260 | } | 1292 | } |
1261 | 1293 | ||
@@ -1445,6 +1477,7 @@ static struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel) | |||
1445 | 1477 | ||
1446 | found: | 1478 | found: |
1447 | dmach = &s3c2410_chans[ch]; | 1479 | dmach = &s3c2410_chans[ch]; |
1480 | dmach->map = ch_map; | ||
1448 | dma_chan_map[channel] = dmach; | 1481 | dma_chan_map[channel] = dmach; |
1449 | 1482 | ||
1450 | /* select the channel */ | 1483 | /* select the channel */ |