aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Dooks <ben@simtec.co.uk>2009-03-19 11:02:39 -0400
committerBen Dooks <ben-linux@fluff.org>2009-05-01 06:39:07 -0400
commit97c1b145231730e62dd71921ec653315a1da3aad (patch)
tree8bfc9e4d781f5ad1e17aae3e058372e53c24574a
parent20934cdbaae9c26a31d7f593c6a747c687ae79a1 (diff)
[ARM] S3C: Move DMA channel management code to plat-s3c
Change the name of S3C2410_DMA_CHANNELS to S3C_DMA_CHANNELS in the process. Signed-off-by: Ben Dooks <ben@simtec.co.uk> Signed-off-by: Ben Dooks <ben-linux@fluff.org>
-rw-r--r--arch/arm/mach-s3c2410/include/mach/dma.h8
-rw-r--r--arch/arm/plat-s3c/Kconfig7
-rw-r--r--arch/arm/plat-s3c/Makefile4
-rw-r--r--arch/arm/plat-s3c/dma.c86
-rw-r--r--arch/arm/plat-s3c/include/plat/dma-core.h22
-rw-r--r--arch/arm/plat-s3c24xx/Kconfig1
-rw-r--r--arch/arm/plat-s3c24xx/dma.c87
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/dma-plat.h10
8 files changed, 136 insertions, 89 deletions
diff --git a/arch/arm/mach-s3c2410/include/mach/dma.h b/arch/arm/mach-s3c2410/include/mach/dma.h
index 1648311c7b47..c3a2629e0ded 100644
--- a/arch/arm/mach-s3c2410/include/mach/dma.h
+++ b/arch/arm/mach-s3c2410/include/mach/dma.h
@@ -55,9 +55,9 @@ enum dma_ch {
55 55
56/* we have 4 dma channels */ 56/* we have 4 dma channels */
57#ifndef CONFIG_CPU_S3C2443 57#ifndef CONFIG_CPU_S3C2443
58#define S3C2410_DMA_CHANNELS (4) 58#define S3C_DMA_CHANNELS (4)
59#else 59#else
60#define S3C2410_DMA_CHANNELS (6) 60#define S3C_DMA_CHANNELS (6)
61#endif 61#endif
62 62
63/* types */ 63/* types */
@@ -192,10 +192,6 @@ struct s3c2410_dma_chan {
192 struct sys_device dev; 192 struct sys_device dev;
193}; 193};
194 194
195/* the currently allocated channel information */
196extern struct s3c2410_dma_chan s3c2410_chans[];
197
198/* note, we don't really use dma_device_t at the moment */
199typedef unsigned long dma_device_t; 195typedef unsigned long dma_device_t;
200 196
201#endif /* __ASM_ARCH_DMA_H */ 197#endif /* __ASM_ARCH_DMA_H */
diff --git a/arch/arm/plat-s3c/Kconfig b/arch/arm/plat-s3c/Kconfig
index de9383814e5e..d4fc89fc5f45 100644
--- a/arch/arm/plat-s3c/Kconfig
+++ b/arch/arm/plat-s3c/Kconfig
@@ -150,6 +150,13 @@ config S3C_GPIO_CFG_S3C64XX
150 Internal configuration to enable S3C64XX style GPIO configuration 150 Internal configuration to enable S3C64XX style GPIO configuration
151 functions. 151 functions.
152 152
153# DMA
154
155config S3C_DMA
156 bool
157 help
158 Internal configuration for S3C DMA core
159
153# device definitions to compile in 160# device definitions to compile in
154 161
155config S3C_DEV_HSMMC 162config S3C_DEV_HSMMC
diff --git a/arch/arm/plat-s3c/Makefile b/arch/arm/plat-s3c/Makefile
index 8d7815d25a51..e8b23fc8fba2 100644
--- a/arch/arm/plat-s3c/Makefile
+++ b/arch/arm/plat-s3c/Makefile
@@ -18,6 +18,10 @@ obj-y += pwm-clock.o
18obj-y += gpio.o 18obj-y += gpio.o
19obj-y += gpio-config.o 19obj-y += gpio-config.o
20 20
21# DMA support
22
23obj-$(CONFIG_S3C_DMA) += dma.o
24
21# PM support 25# PM support
22 26
23obj-$(CONFIG_PM) += pm.o 27obj-$(CONFIG_PM) += pm.o
diff --git a/arch/arm/plat-s3c/dma.c b/arch/arm/plat-s3c/dma.c
new file mode 100644
index 000000000000..c9db75c06af5
--- /dev/null
+++ b/arch/arm/plat-s3c/dma.c
@@ -0,0 +1,86 @@
1/* linux/arch/arm/plat-s3c/dma.c
2 *
3 * Copyright (c) 2003-2005,2006,2009 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 * http://armlinux.simtec.co.uk/
6 *
7 * S3C DMA core
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14struct s3c2410_dma_buf;
15
16#include <linux/kernel.h>
17#include <linux/module.h>
18#include <linux/errno.h>
19
20#include <mach/dma.h>
21#include <mach/irqs.h>
22
23#include <plat/dma-plat.h>
24
25/* dma channel state information */
26struct s3c2410_dma_chan s3c2410_chans[S3C_DMA_CHANNELS];
27struct s3c2410_dma_chan *s3c_dma_chan_map[DMACH_MAX];
28
29/* s3c_dma_lookup_channel
30 *
31 * change the dma channel number given into a real dma channel id
32*/
33
34struct s3c2410_dma_chan *s3c_dma_lookup_channel(unsigned int channel)
35{
36 if (channel & DMACH_LOW_LEVEL)
37 return &s3c2410_chans[channel & ~DMACH_LOW_LEVEL];
38 else
39 return s3c_dma_chan_map[channel];
40}
41
42/* do we need to protect the settings of the fields from
43 * irq?
44*/
45
46int s3c2410_dma_set_opfn(unsigned int channel, s3c2410_dma_opfn_t rtn)
47{
48 struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
49
50 if (chan == NULL)
51 return -EINVAL;
52
53 pr_debug("%s: chan=%p, op rtn=%p\n", __func__, chan, rtn);
54
55 chan->op_fn = rtn;
56
57 return 0;
58}
59EXPORT_SYMBOL(s3c2410_dma_set_opfn);
60
61int s3c2410_dma_set_buffdone_fn(unsigned int channel, s3c2410_dma_cbfn_t rtn)
62{
63 struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
64
65 if (chan == NULL)
66 return -EINVAL;
67
68 pr_debug("%s: chan=%p, callback rtn=%p\n", __func__, chan, rtn);
69
70 chan->callback_fn = rtn;
71
72 return 0;
73}
74EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn);
75
76int s3c2410_dma_setflags(unsigned int channel, unsigned int flags)
77{
78 struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
79
80 if (chan == NULL)
81 return -EINVAL;
82
83 chan->flags = flags;
84 return 0;
85}
86EXPORT_SYMBOL(s3c2410_dma_setflags);
diff --git a/arch/arm/plat-s3c/include/plat/dma-core.h b/arch/arm/plat-s3c/include/plat/dma-core.h
new file mode 100644
index 000000000000..32ff2a92cb3c
--- /dev/null
+++ b/arch/arm/plat-s3c/include/plat/dma-core.h
@@ -0,0 +1,22 @@
1/* arch/arm/plat-s3c/include/plat/dma.h
2 *
3 * Copyright 2008 Openmoko, Inc.
4 * Copyright 2008 Simtec Electronics
5 * Ben Dooks <ben@simtec.co.uk>
6 * http://armlinux.simtec.co.uk/
7 *
8 * Samsung S3C DMA core support
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15extern struct s3c2410_dma_chan *s3c_dma_lookup_channel(unsigned int channel);
16
17extern struct s3c2410_dma_chan *s3c_dma_chan_map[];
18
19/* the currently allocated channel information */
20extern struct s3c2410_dma_chan s3c2410_chans[];
21
22
diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig
index 2c8a2f5d75ff..5b0bc914f58e 100644
--- a/arch/arm/plat-s3c24xx/Kconfig
+++ b/arch/arm/plat-s3c24xx/Kconfig
@@ -71,6 +71,7 @@ config PM_SIMTEC
71config S3C2410_DMA 71config S3C2410_DMA
72 bool "S3C2410 DMA support" 72 bool "S3C2410 DMA support"
73 depends on ARCH_S3C2410 73 depends on ARCH_S3C2410
74 select S3C_DMA
74 help 75 help
75 S3C2410 DMA support. This is needed for drivers like sound which 76 S3C2410 DMA support. This is needed for drivers like sound which
76 use the S3C2410's DMA system to move data to and from the 77 use the S3C2410's DMA system to move data to and from the
diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c
index 7c37c9a75323..b07fec01ab47 100644
--- a/arch/arm/plat-s3c24xx/dma.c
+++ b/arch/arm/plat-s3c24xx/dma.c
@@ -44,8 +44,6 @@ static int dma_channels;
44 44
45static struct s3c24xx_dma_selection dma_sel; 45static struct s3c24xx_dma_selection dma_sel;
46 46
47/* dma channel state information */
48struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS];
49 47
50/* debugging functions */ 48/* debugging functions */
51 49
@@ -135,21 +133,6 @@ dmadbg_showregs(const char *fname, int line, struct s3c2410_dma_chan *chan)
135#define dbg_showchan(chan) do { } while(0) 133#define dbg_showchan(chan) do { } while(0)
136#endif /* CONFIG_S3C2410_DMA_DEBUG */ 134#endif /* CONFIG_S3C2410_DMA_DEBUG */
137 135
138static struct s3c2410_dma_chan *dma_chan_map[DMACH_MAX];
139
140/* lookup_dma_channel
141 *
142 * change the dma channel number given into a real dma channel id
143*/
144
145static struct s3c2410_dma_chan *lookup_dma_channel(unsigned int channel)
146{
147 if (channel & DMACH_LOW_LEVEL)
148 return &s3c2410_chans[channel & ~DMACH_LOW_LEVEL];
149 else
150 return dma_chan_map[channel];
151}
152
153/* s3c2410_dma_stats_timeout 136/* s3c2410_dma_stats_timeout
154 * 137 *
155 * Update DMA stats from timeout info 138 * Update DMA stats from timeout info
@@ -214,8 +197,6 @@ s3c2410_dma_waitforload(struct s3c2410_dma_chan *chan, int line)
214 return 0; 197 return 0;
215} 198}
216 199
217
218
219/* s3c2410_dma_loadbuffer 200/* s3c2410_dma_loadbuffer
220 * 201 *
221 * load a buffer, and update the channel state 202 * load a buffer, and update the channel state
@@ -453,7 +434,7 @@ s3c2410_dma_canload(struct s3c2410_dma_chan *chan)
453int s3c2410_dma_enqueue(unsigned int channel, void *id, 434int s3c2410_dma_enqueue(unsigned int channel, void *id,
454 dma_addr_t data, int size) 435 dma_addr_t data, int size)
455{ 436{
456 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); 437 struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
457 struct s3c2410_dma_buf *buf; 438 struct s3c2410_dma_buf *buf;
458 unsigned long flags; 439 unsigned long flags;
459 440
@@ -804,7 +785,7 @@ EXPORT_SYMBOL(s3c2410_dma_request);
804 785
805int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *client) 786int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *client)
806{ 787{
807 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); 788 struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
808 unsigned long flags; 789 unsigned long flags;
809 790
810 if (chan == NULL) 791 if (chan == NULL)
@@ -836,7 +817,7 @@ int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *client)
836 chan->irq_claimed = 0; 817 chan->irq_claimed = 0;
837 818
838 if (!(channel & DMACH_LOW_LEVEL)) 819 if (!(channel & DMACH_LOW_LEVEL))
839 dma_chan_map[channel] = NULL; 820 s3c_dma_chan_map[channel] = NULL;
840 821
841 local_irq_restore(flags); 822 local_irq_restore(flags);
842 823
@@ -995,7 +976,7 @@ static int s3c2410_dma_started(struct s3c2410_dma_chan *chan)
995int 976int
996s3c2410_dma_ctrl(unsigned int channel, enum s3c2410_chan_op op) 977s3c2410_dma_ctrl(unsigned int channel, enum s3c2410_chan_op op)
997{ 978{
998 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); 979 struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
999 980
1000 if (chan == NULL) 981 if (chan == NULL)
1001 return -EINVAL; 982 return -EINVAL;
@@ -1043,7 +1024,7 @@ EXPORT_SYMBOL(s3c2410_dma_ctrl);
1043int s3c2410_dma_config(unsigned int channel, 1024int s3c2410_dma_config(unsigned int channel,
1044 int xferunit) 1025 int xferunit)
1045{ 1026{
1046 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); 1027 struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
1047 unsigned int dcon; 1028 unsigned int dcon;
1048 1029
1049 pr_debug("%s: chan=%d, xfer_unit=%d, dcon=%08x\n", 1030 pr_debug("%s: chan=%d, xfer_unit=%d, dcon=%08x\n",
@@ -1112,58 +1093,6 @@ int s3c2410_dma_config(unsigned int channel,
1112 1093
1113EXPORT_SYMBOL(s3c2410_dma_config); 1094EXPORT_SYMBOL(s3c2410_dma_config);
1114 1095
1115int s3c2410_dma_setflags(unsigned int channel, unsigned int flags)
1116{
1117 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
1118
1119 if (chan == NULL)
1120 return -EINVAL;
1121
1122 pr_debug("%s: chan=%p, flags=%08x\n", __func__, chan, flags);
1123
1124 chan->flags = flags;
1125
1126 return 0;
1127}
1128
1129EXPORT_SYMBOL(s3c2410_dma_setflags);
1130
1131
1132/* do we need to protect the settings of the fields from
1133 * irq?
1134*/
1135
1136int s3c2410_dma_set_opfn(unsigned int channel, s3c2410_dma_opfn_t rtn)
1137{
1138 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
1139
1140 if (chan == NULL)
1141 return -EINVAL;
1142
1143 pr_debug("%s: chan=%p, op rtn=%p\n", __func__, chan, rtn);
1144
1145 chan->op_fn = rtn;
1146
1147 return 0;
1148}
1149
1150EXPORT_SYMBOL(s3c2410_dma_set_opfn);
1151
1152int s3c2410_dma_set_buffdone_fn(unsigned int channel, s3c2410_dma_cbfn_t rtn)
1153{
1154 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
1155
1156 if (chan == NULL)
1157 return -EINVAL;
1158
1159 pr_debug("%s: chan=%p, callback rtn=%p\n", __func__, chan, rtn);
1160
1161 chan->callback_fn = rtn;
1162
1163 return 0;
1164}
1165
1166EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn);
1167 1096
1168/* s3c2410_dma_devconfig 1097/* s3c2410_dma_devconfig
1169 * 1098 *
@@ -1179,7 +1108,7 @@ int s3c2410_dma_devconfig(int channel,
1179 enum s3c2410_dmasrc source, 1108 enum s3c2410_dmasrc source,
1180 unsigned long devaddr) 1109 unsigned long devaddr)
1181{ 1110{
1182 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); 1111 struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
1183 unsigned int hwcfg; 1112 unsigned int hwcfg;
1184 1113
1185 if (chan == NULL) 1114 if (chan == NULL)
@@ -1250,7 +1179,7 @@ EXPORT_SYMBOL(s3c2410_dma_devconfig);
1250 1179
1251int s3c2410_dma_getposition(unsigned int channel, dma_addr_t *src, dma_addr_t *dst) 1180int s3c2410_dma_getposition(unsigned int channel, dma_addr_t *src, dma_addr_t *dst)
1252{ 1181{
1253 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); 1182 struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
1254 1183
1255 if (chan == NULL) 1184 if (chan == NULL)
1256 return -EINVAL; 1185 return -EINVAL;
@@ -1508,7 +1437,7 @@ static struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel)
1508 dmach = &s3c2410_chans[ch]; 1437 dmach = &s3c2410_chans[ch];
1509 dmach->map = ch_map; 1438 dmach->map = ch_map;
1510 dmach->req_ch = channel; 1439 dmach->req_ch = channel;
1511 dma_chan_map[channel] = dmach; 1440 s3c_dma_chan_map[channel] = dmach;
1512 1441
1513 /* select the channel */ 1442 /* select the channel */
1514 1443
diff --git a/arch/arm/plat-s3c24xx/include/plat/dma-plat.h b/arch/arm/plat-s3c24xx/include/plat/dma-plat.h
index fbe84afe2d90..9565ead1bc9b 100644
--- a/arch/arm/plat-s3c24xx/include/plat/dma-plat.h
+++ b/arch/arm/plat-s3c24xx/include/plat/dma-plat.h
@@ -10,8 +10,10 @@
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11*/ 11*/
12 12
13#include <plat/dma-core.h>
14
13extern struct sysdev_class dma_sysclass; 15extern struct sysdev_class dma_sysclass;
14extern struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS]; 16extern struct s3c2410_dma_chan s3c2410_chans[S3C_DMA_CHANNELS];
15 17
16#define DMA_CH_VALID (1<<31) 18#define DMA_CH_VALID (1<<31)
17#define DMA_CH_NEVER (1<<30) 19#define DMA_CH_NEVER (1<<30)
@@ -31,8 +33,8 @@ struct s3c24xx_dma_map {
31 const char *name; 33 const char *name;
32 struct s3c24xx_dma_addr hw_addr; 34 struct s3c24xx_dma_addr hw_addr;
33 35
34 unsigned long channels[S3C2410_DMA_CHANNELS]; 36 unsigned long channels[S3C_DMA_CHANNELS];
35 unsigned long channels_rx[S3C2410_DMA_CHANNELS]; 37 unsigned long channels_rx[S3C_DMA_CHANNELS];
36}; 38};
37 39
38struct s3c24xx_dma_selection { 40struct s3c24xx_dma_selection {
@@ -58,7 +60,7 @@ extern int s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel);
58*/ 60*/
59 61
60struct s3c24xx_dma_order_ch { 62struct s3c24xx_dma_order_ch {
61 unsigned int list[S3C2410_DMA_CHANNELS]; /* list of channels */ 63 unsigned int list[S3C_DMA_CHANNELS]; /* list of channels */
62 unsigned int flags; /* flags */ 64 unsigned int flags; /* flags */
63}; 65};
64 66