diff options
-rw-r--r-- | arch/arm/mach-s3c2410/dma.c | 11 | ||||
-rw-r--r-- | arch/arm/mach-s3c2412/dma.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-s3c2440/dma.c | 3 | ||||
-rw-r--r-- | arch/arm/plat-s3c24xx/dma.c | 77 | ||||
-rw-r--r-- | include/asm-arm/plat-s3c24xx/dma.h | 7 |
5 files changed, 69 insertions, 30 deletions
diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c index 6b3452680755..67d1ad363973 100644 --- a/arch/arm/mach-s3c2410/dma.c +++ b/arch/arm/mach-s3c2410/dma.c | |||
@@ -19,9 +19,9 @@ | |||
19 | 19 | ||
20 | #include <asm/dma.h> | 20 | #include <asm/dma.h> |
21 | #include <asm/arch/dma.h> | 21 | #include <asm/arch/dma.h> |
22 | #include <asm/plat-s3c24xx/dma.h> | ||
23 | 22 | ||
24 | #include <asm/plat-s3c24xx/cpu.h> | 23 | #include <asm/plat-s3c24xx/cpu.h> |
24 | #include <asm/plat-s3c24xx/dma.h> | ||
25 | 25 | ||
26 | #include <asm/arch/regs-serial.h> | 26 | #include <asm/arch/regs-serial.h> |
27 | #include <asm/arch/regs-gpio.h> | 27 | #include <asm/arch/regs-gpio.h> |
@@ -147,6 +147,7 @@ static struct s3c24xx_dma_order __initdata s3c2410_dma_order = { | |||
147 | 147 | ||
148 | static int s3c2410_dma_add(struct sys_device *sysdev) | 148 | static int s3c2410_dma_add(struct sys_device *sysdev) |
149 | { | 149 | { |
150 | s3c2410_dma_init(); | ||
150 | s3c24xx_dma_order_set(&s3c2410_dma_order); | 151 | s3c24xx_dma_order_set(&s3c2410_dma_order); |
151 | return s3c24xx_dma_init_map(&s3c2410_dma_sel); | 152 | return s3c24xx_dma_init_map(&s3c2410_dma_sel); |
152 | } | 153 | } |
@@ -156,12 +157,12 @@ static struct sysdev_driver s3c2410_dma_driver = { | |||
156 | .add = s3c2410_dma_add, | 157 | .add = s3c2410_dma_add, |
157 | }; | 158 | }; |
158 | 159 | ||
159 | static int __init s3c2410_dma_init(void) | 160 | static int __init s3c2410_dma_drvinit(void) |
160 | { | 161 | { |
161 | return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_dma_driver); | 162 | return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_dma_driver); |
162 | } | 163 | } |
163 | 164 | ||
164 | arch_initcall(s3c2410_dma_init); | 165 | arch_initcall(s3c2410_dma_drvinit); |
165 | #endif | 166 | #endif |
166 | 167 | ||
167 | #if defined(CONFIG_CPU_S3C2442) | 168 | #if defined(CONFIG_CPU_S3C2442) |
@@ -170,11 +171,11 @@ static struct sysdev_driver s3c2442_dma_driver = { | |||
170 | .add = s3c2410_dma_add, | 171 | .add = s3c2410_dma_add, |
171 | }; | 172 | }; |
172 | 173 | ||
173 | static int __init s3c2442_dma_init(void) | 174 | static int __init s3c2442_dma_drvinit(void) |
174 | { | 175 | { |
175 | return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_dma_driver); | 176 | return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_dma_driver); |
176 | } | 177 | } |
177 | 178 | ||
178 | arch_initcall(s3c2442_dma_init); | 179 | arch_initcall(s3c2442_dma_drvinit); |
179 | #endif | 180 | #endif |
180 | 181 | ||
diff --git a/arch/arm/mach-s3c2412/dma.c b/arch/arm/mach-s3c2412/dma.c index 28b598287fae..d0f4695c09d9 100644 --- a/arch/arm/mach-s3c2412/dma.c +++ b/arch/arm/mach-s3c2412/dma.c | |||
@@ -146,6 +146,7 @@ static struct s3c24xx_dma_selection __initdata s3c2412_dma_sel = { | |||
146 | 146 | ||
147 | static int s3c2412_dma_add(struct sys_device *sysdev) | 147 | static int s3c2412_dma_add(struct sys_device *sysdev) |
148 | { | 148 | { |
149 | s3c2410_dma_init(); | ||
149 | return s3c24xx_dma_init_map(&s3c2412_dma_sel); | 150 | return s3c24xx_dma_init_map(&s3c2412_dma_sel); |
150 | } | 151 | } |
151 | 152 | ||
diff --git a/arch/arm/mach-s3c2440/dma.c b/arch/arm/mach-s3c2440/dma.c index 2bb2926554c8..cd035a3ec878 100644 --- a/arch/arm/mach-s3c2440/dma.c +++ b/arch/arm/mach-s3c2440/dma.c | |||
@@ -19,8 +19,8 @@ | |||
19 | 19 | ||
20 | #include <asm/dma.h> | 20 | #include <asm/dma.h> |
21 | #include <asm/arch/dma.h> | 21 | #include <asm/arch/dma.h> |
22 | #include <asm/plat-s3c24xx/dma.h> | ||
23 | 22 | ||
23 | #include <asm/plat-s3c24xx/dma.h> | ||
24 | #include <asm/plat-s3c24xx/cpu.h> | 24 | #include <asm/plat-s3c24xx/cpu.h> |
25 | 25 | ||
26 | #include <asm/arch/regs-serial.h> | 26 | #include <asm/arch/regs-serial.h> |
@@ -192,6 +192,7 @@ static struct s3c24xx_dma_order __initdata s3c2440_dma_order = { | |||
192 | 192 | ||
193 | static int s3c2440_dma_add(struct sys_device *sysdev) | 193 | static int s3c2440_dma_add(struct sys_device *sysdev) |
194 | { | 194 | { |
195 | s3c2410_dma_init(); | ||
195 | s3c24xx_dma_order_set(&s3c2440_dma_order); | 196 | s3c24xx_dma_order_set(&s3c2440_dma_order); |
196 | return s3c24xx_dma_init_map(&s3c2440_dma_sel); | 197 | return s3c24xx_dma_init_map(&s3c2440_dma_sel); |
197 | } | 198 | } |
diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c index 929265aab7dd..4540a806f522 100644 --- a/arch/arm/plat-s3c24xx/dma.c +++ b/arch/arm/plat-s3c24xx/dma.c | |||
@@ -42,6 +42,8 @@ | |||
42 | static void __iomem *dma_base; | 42 | static void __iomem *dma_base; |
43 | static struct kmem_cache *dma_kmem; | 43 | static struct kmem_cache *dma_kmem; |
44 | 44 | ||
45 | static int dma_channels; | ||
46 | |||
45 | struct s3c24xx_dma_selection dma_sel; | 47 | struct s3c24xx_dma_selection dma_sel; |
46 | 48 | ||
47 | /* dma channel state information */ | 49 | /* dma channel state information */ |
@@ -1278,7 +1280,42 @@ static void s3c2410_dma_cache_ctor(void *p, struct kmem_cache *c, unsigned long | |||
1278 | 1280 | ||
1279 | /* initialisation code */ | 1281 | /* initialisation code */ |
1280 | 1282 | ||
1281 | static int __init s3c2410_init_dma(void) | 1283 | int __init s3c24xx_dma_sysclass_init(void) |
1284 | { | ||
1285 | int ret = sysdev_class_register(&dma_sysclass); | ||
1286 | |||
1287 | if (ret != 0) | ||
1288 | printk(KERN_ERR "dma sysclass registration failed\n"); | ||
1289 | |||
1290 | return ret; | ||
1291 | } | ||
1292 | |||
1293 | core_initcall(s3c24xx_dma_sysclass_init); | ||
1294 | |||
1295 | int __init s3c24xx_dma_sysdev_register(void) | ||
1296 | { | ||
1297 | struct s3c2410_dma_chan *cp = s3c2410_chans; | ||
1298 | int channel, ret; | ||
1299 | |||
1300 | for (channel = 0; channel < dma_channels; cp++, channel++) { | ||
1301 | cp->dev.cls = &dma_sysclass; | ||
1302 | cp->dev.id = channel; | ||
1303 | ret = sysdev_register(&cp->dev); | ||
1304 | |||
1305 | if (ret) { | ||
1306 | printk(KERN_ERR "error registering dev for dma %d\n", | ||
1307 | channel); | ||
1308 | return ret; | ||
1309 | } | ||
1310 | } | ||
1311 | |||
1312 | return 0; | ||
1313 | } | ||
1314 | |||
1315 | late_initcall(s3c24xx_dma_sysdev_register); | ||
1316 | |||
1317 | int __init s3c24xx_dma_init(unsigned int channels, unsigned int irq, | ||
1318 | unsigned int stride) | ||
1282 | { | 1319 | { |
1283 | struct s3c2410_dma_chan *cp; | 1320 | struct s3c2410_dma_chan *cp; |
1284 | int channel; | 1321 | int channel; |
@@ -1286,21 +1323,16 @@ static int __init s3c2410_init_dma(void) | |||
1286 | 1323 | ||
1287 | printk("S3C24XX DMA Driver, (c) 2003-2004,2006 Simtec Electronics\n"); | 1324 | printk("S3C24XX DMA Driver, (c) 2003-2004,2006 Simtec Electronics\n"); |
1288 | 1325 | ||
1289 | dma_base = ioremap(S3C24XX_PA_DMA, 0x200); | 1326 | dma_channels = channels; |
1327 | |||
1328 | dma_base = ioremap(S3C24XX_PA_DMA, stride * channels); | ||
1290 | if (dma_base == NULL) { | 1329 | if (dma_base == NULL) { |
1291 | printk(KERN_ERR "dma failed to remap register block\n"); | 1330 | printk(KERN_ERR "dma failed to remap register block\n"); |
1292 | return -ENOMEM; | 1331 | return -ENOMEM; |
1293 | } | 1332 | } |
1294 | 1333 | ||
1295 | printk("Registering sysclass\n"); | 1334 | dma_kmem = kmem_cache_create("dma_desc", |
1296 | 1335 | sizeof(struct s3c2410_dma_buf), 0, | |
1297 | ret = sysdev_class_register(&dma_sysclass); | ||
1298 | if (ret != 0) { | ||
1299 | printk(KERN_ERR "dma sysclass registration failed\n"); | ||
1300 | goto err; | ||
1301 | } | ||
1302 | |||
1303 | dma_kmem = kmem_cache_create("dma_desc", sizeof(struct s3c2410_dma_buf), 0, | ||
1304 | SLAB_HWCACHE_ALIGN, | 1336 | SLAB_HWCACHE_ALIGN, |
1305 | s3c2410_dma_cache_ctor, NULL); | 1337 | s3c2410_dma_cache_ctor, NULL); |
1306 | 1338 | ||
@@ -1310,15 +1342,15 @@ static int __init s3c2410_init_dma(void) | |||
1310 | goto err; | 1342 | goto err; |
1311 | } | 1343 | } |
1312 | 1344 | ||
1313 | for (channel = 0; channel < S3C2410_DMA_CHANNELS; channel++) { | 1345 | for (channel = 0; channel < channels; channel++) { |
1314 | cp = &s3c2410_chans[channel]; | 1346 | cp = &s3c2410_chans[channel]; |
1315 | 1347 | ||
1316 | memset(cp, 0, sizeof(struct s3c2410_dma_chan)); | 1348 | memset(cp, 0, sizeof(struct s3c2410_dma_chan)); |
1317 | 1349 | ||
1318 | /* dma channel irqs are in order.. */ | 1350 | /* dma channel irqs are in order.. */ |
1319 | cp->number = channel; | 1351 | cp->number = channel; |
1320 | cp->irq = channel + IRQ_DMA0; | 1352 | cp->irq = channel + irq; |
1321 | cp->regs = dma_base + (channel*0x40); | 1353 | cp->regs = dma_base + (channel * stride); |
1322 | 1354 | ||
1323 | /* point current stats somewhere */ | 1355 | /* point current stats somewhere */ |
1324 | cp->stats = &cp->stats_store; | 1356 | cp->stats = &cp->stats_store; |
@@ -1328,12 +1360,6 @@ static int __init s3c2410_init_dma(void) | |||
1328 | 1360 | ||
1329 | cp->load_timeout = 1<<18; | 1361 | cp->load_timeout = 1<<18; |
1330 | 1362 | ||
1331 | /* register system device */ | ||
1332 | |||
1333 | cp->dev.cls = &dma_sysclass; | ||
1334 | cp->dev.id = channel; | ||
1335 | ret = sysdev_register(&cp->dev); | ||
1336 | |||
1337 | printk("DMA channel %d at %p, irq %d\n", | 1363 | printk("DMA channel %d at %p, irq %d\n", |
1338 | cp->number, cp->regs, cp->irq); | 1364 | cp->number, cp->regs, cp->irq); |
1339 | } | 1365 | } |
@@ -1347,7 +1373,10 @@ static int __init s3c2410_init_dma(void) | |||
1347 | return ret; | 1373 | return ret; |
1348 | } | 1374 | } |
1349 | 1375 | ||
1350 | core_initcall(s3c2410_init_dma); | 1376 | int s3c2410_dma_init(void) |
1377 | { | ||
1378 | return s3c24xx_dma_init(4, IRQ_DMA0, 0x40); | ||
1379 | } | ||
1351 | 1380 | ||
1352 | static inline int is_channel_valid(unsigned int channel) | 1381 | static inline int is_channel_valid(unsigned int channel) |
1353 | { | 1382 | { |
@@ -1384,7 +1413,7 @@ struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel) | |||
1384 | if (dma_order) { | 1413 | if (dma_order) { |
1385 | ord = &dma_order->channels[channel]; | 1414 | ord = &dma_order->channels[channel]; |
1386 | 1415 | ||
1387 | for (ch = 0; ch < S3C2410_DMA_CHANNELS; ch++) { | 1416 | for (ch = 0; ch < dma_channels; ch++) { |
1388 | if (!is_channel_valid(ord->list[ch])) | 1417 | if (!is_channel_valid(ord->list[ch])) |
1389 | continue; | 1418 | continue; |
1390 | 1419 | ||
@@ -1400,7 +1429,7 @@ struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel) | |||
1400 | 1429 | ||
1401 | /* second, search the channel map for first free */ | 1430 | /* second, search the channel map for first free */ |
1402 | 1431 | ||
1403 | for (ch = 0; ch < S3C2410_DMA_CHANNELS; ch++) { | 1432 | for (ch = 0; ch < dma_channels; ch++) { |
1404 | if (!is_channel_valid(ch_map->channels[ch])) | 1433 | if (!is_channel_valid(ch_map->channels[ch])) |
1405 | continue; | 1434 | continue; |
1406 | 1435 | ||
@@ -1410,7 +1439,7 @@ struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel) | |||
1410 | } | 1439 | } |
1411 | } | 1440 | } |
1412 | 1441 | ||
1413 | if (ch >= S3C2410_DMA_CHANNELS) | 1442 | if (ch >= dma_channels) |
1414 | return NULL; | 1443 | return NULL; |
1415 | 1444 | ||
1416 | /* update our channel mapping */ | 1445 | /* update our channel mapping */ |
diff --git a/include/asm-arm/plat-s3c24xx/dma.h b/include/asm-arm/plat-s3c24xx/dma.h index 15e140c2d4fc..2c59406435e5 100644 --- a/include/asm-arm/plat-s3c24xx/dma.h +++ b/include/asm-arm/plat-s3c24xx/dma.h | |||
@@ -68,3 +68,10 @@ struct s3c24xx_dma_order { | |||
68 | }; | 68 | }; |
69 | 69 | ||
70 | extern int s3c24xx_dma_order_set(struct s3c24xx_dma_order *map); | 70 | extern int s3c24xx_dma_order_set(struct s3c24xx_dma_order *map); |
71 | |||
72 | /* DMA init code, called from the cpu support code */ | ||
73 | |||
74 | extern int s3c2410_dma_init(void); | ||
75 | |||
76 | extern int s3c24xx_dma_init(unsigned int channels, unsigned int irq, | ||
77 | unsigned int stride); | ||