aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-s3c2410
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-09-28 17:40:39 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-09-28 17:40:39 -0400
commitebdea46fecae40c4d7effcd33f40918a37a1df4b (patch)
treee4312bf7f1f3d184738963a0ec300aa9fdfd55c1 /arch/arm/mach-s3c2410
parentfecf3404f4aba6d0edeba31eeb018cbb6326dff2 (diff)
parent250d375d1da45a5e08ab8baf5eaa7eb258afd82b (diff)
Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm: (130 commits) [ARM] 3856/1: Add clocksource for Intel IXP4xx platforms [ARM] 3855/1: Add generic time support [ARM] 3873/1: S3C24XX: Add irq_chip names [ARM] 3872/1: S3C24XX: Apply consistant tabbing to irq_chips [ARM] 3871/1: S3C24XX: Fix ordering of EINT4..23 [ARM] nommu: confirms the CR_V bit in nommu mode [ARM] nommu: abort handler fixup for !CPU_CP15_MMU cores. [ARM] 3870/1: AT91: Start removing static memory mappings [ARM] 3869/1: AT91: NAND support for DK and KB9202 boards [ARM] 3868/1: AT91 hardware header update [ARM] 3867/1: AT91 GPIO update [ARM] 3866/1: AT91 clock update [ARM] 3865/1: AT91RM9200 header updates [ARM] 3862/2: S3C2410 - add basic power management support for AML M5900 series [ARM] kthread: switch arch/arm/kernel/apm.c [ARM] Off-by-one in arch/arm/common/icst* [ARM] 3864/1: Refactore sharpsl_pm [ARM] 3863/1: Add Locomo SPI Device [ARM] 3847/2: Convert LOMOMO to use struct device for GPIOs [ARM] Use CPU_CACHE_* where possible in asm/cacheflush.h ...
Diffstat (limited to 'arch/arm/mach-s3c2410')
-rw-r--r--arch/arm/mach-s3c2410/Kconfig38
-rw-r--r--arch/arm/mach-s3c2410/Makefile16
-rw-r--r--arch/arm/mach-s3c2410/bast-irq.c4
-rw-r--r--arch/arm/mach-s3c2410/cpu.c9
-rw-r--r--arch/arm/mach-s3c2410/devs.h5
-rw-r--r--arch/arm/mach-s3c2410/dma.c241
-rw-r--r--arch/arm/mach-s3c2410/dma.h45
-rw-r--r--arch/arm/mach-s3c2410/gpio.c16
-rw-r--r--arch/arm/mach-s3c2410/irq.c165
-rw-r--r--arch/arm/mach-s3c2410/mach-amlm5900.c266
-rw-r--r--arch/arm/mach-s3c2410/mach-anubis.c6
-rw-r--r--arch/arm/mach-s3c2410/mach-smdk2440.c9
-rw-r--r--arch/arm/mach-s3c2410/mach-vstms.c168
-rw-r--r--arch/arm/mach-s3c2410/pm-simtec.c3
-rw-r--r--arch/arm/mach-s3c2410/pm.c72
-rw-r--r--arch/arm/mach-s3c2410/pm.h16
-rw-r--r--arch/arm/mach-s3c2410/s3c2410-dma.c158
-rw-r--r--arch/arm/mach-s3c2410/s3c2410-irq.c48
-rw-r--r--arch/arm/mach-s3c2410/s3c2410-pm.c120
-rw-r--r--arch/arm/mach-s3c2410/s3c2410-sleep.S68
-rw-r--r--arch/arm/mach-s3c2410/s3c2410.c11
-rw-r--r--arch/arm/mach-s3c2410/s3c2412-dma.c160
-rw-r--r--arch/arm/mach-s3c2410/s3c2412-irq.c3
-rw-r--r--arch/arm/mach-s3c2410/s3c2412-pm.c128
-rw-r--r--arch/arm/mach-s3c2410/s3c2412.c61
-rw-r--r--arch/arm/mach-s3c2410/s3c2440-dma.c164
-rw-r--r--arch/arm/mach-s3c2410/s3c2440-dsc.c5
-rw-r--r--arch/arm/mach-s3c2410/s3c2440-irq.c2
-rw-r--r--arch/arm/mach-s3c2410/s3c244x-irq.c9
-rw-r--r--arch/arm/mach-s3c2410/sleep.S54
-rw-r--r--arch/arm/mach-s3c2410/usb-simtec.c6
31 files changed, 1768 insertions, 308 deletions
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig
index bbd138be6a70..df37594c30f8 100644
--- a/arch/arm/mach-s3c2410/Kconfig
+++ b/arch/arm/mach-s3c2410/Kconfig
@@ -2,6 +2,13 @@ if ARCH_S3C2410
2 2
3menu "S3C24XX Implementations" 3menu "S3C24XX Implementations"
4 4
5config MACH_AML_M5900
6 bool "AML M5900 Series"
7 select CPU_S3C2410
8 help
9 Say Y here if you are using the American Microsystems M5900 Series
10 <http://www.amltd.com>
11
5config MACH_ANUBIS 12config MACH_ANUBIS
6 bool "Simtec Electronics ANUBIS" 13 bool "Simtec Electronics ANUBIS"
7 select CPU_S3C2440 14 select CPU_S3C2440
@@ -126,6 +133,12 @@ config MACH_NEXCODER_2440
126 help 133 help
127 Say Y here if you are using the Nex Vision NEXCODER 2440 Light Board 134 Say Y here if you are using the Nex Vision NEXCODER 2440 Light Board
128 135
136config MACH_VSTMS
137 bool "VMSTMS"
138 select CPU_S3C2412
139 help
140 Say Y here if you are using an VSTMS board
141
129endmenu 142endmenu
130 143
131config S3C2410_CLOCK 144config S3C2410_CLOCK
@@ -133,10 +146,24 @@ config S3C2410_CLOCK
133 help 146 help
134 Clock code for the S3C2410, and similar processors 147 Clock code for the S3C2410, and similar processors
135 148
149config S3C2410_PM
150 bool
151 depends on CONFIG_PM
152 help
153 Power Management code common to S3C2410 and better
154
155config CPU_S3C2410_DMA
156 bool
157 depends on S3C2410_DMA && (CPU_S3C2410 || CPU_S3C2442)
158 default y if CPU_S3C2410 || CPU_S3C2442
159 help
160 DMA device selection for S3C2410 and compatible CPUs
161
136config CPU_S3C2410 162config CPU_S3C2410
137 bool 163 bool
138 depends on ARCH_S3C2410 164 depends on ARCH_S3C2410
139 select S3C2410_CLOCK 165 select S3C2410_CLOCK
166 select S3C2410_PM
140 help 167 help
141 Support for S3C2410 and S3C2410A family from the S3C24XX line 168 Support for S3C2410 and S3C2410A family from the S3C24XX line
142 of Samsung Mobile CPUs. 169 of Samsung Mobile CPUs.
@@ -149,6 +176,13 @@ config CPU_S3C2412_ONLY
149 !CPU_S3C2440 && !CPU_S3C2442 && CPU_S3C2412 176 !CPU_S3C2440 && !CPU_S3C2442 && CPU_S3C2412
150 default y if CPU_S3C2412 177 default y if CPU_S3C2412
151 178
179config S3C2412_PM
180 bool
181 default y if PM
182 depends on CPU_S3C2412
183 help
184 Internal config node to apply S3C2412 power management
185
152config CPU_S3C2412 186config CPU_S3C2412
153 bool 187 bool
154 depends on ARCH_S3C2410 188 depends on ARCH_S3C2410
@@ -165,6 +199,7 @@ config CPU_S3C2440
165 bool 199 bool
166 depends on ARCH_S3C2410 200 depends on ARCH_S3C2410
167 select S3C2410_CLOCK 201 select S3C2410_CLOCK
202 select S3C2410_PM
168 select CPU_S3C244X 203 select CPU_S3C244X
169 help 204 help
170 Support for S3C2440 Samsung Mobile CPU based systems. 205 Support for S3C2440 Samsung Mobile CPU based systems.
@@ -173,6 +208,7 @@ config CPU_S3C2442
173 bool 208 bool
174 depends on ARCH_S3C2420 209 depends on ARCH_S3C2420
175 select S3C2410_CLOCK 210 select S3C2410_CLOCK
211 select S3C2410_PM
176 select CPU_S3C244X 212 select CPU_S3C244X
177 help 213 help
178 Support for S3C2442 Samsung Mobile CPU based systems. 214 Support for S3C2442 Samsung Mobile CPU based systems.
@@ -256,7 +292,7 @@ config S3C2410_PM_CHECK_CHUNKSIZE
256 292
257config PM_SIMTEC 293config PM_SIMTEC
258 bool 294 bool
259 depends on PM && (ARCH_BAST || MACH_VR1000) 295 depends on PM && (ARCH_BAST || MACH_VR1000 || MACH_AML_M5900)
260 default y 296 default y
261 297
262config S3C2410_LOWLEVEL_UART_PORT 298config S3C2410_LOWLEVEL_UART_PORT
diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile
index 0eadec916214..d66013365b6b 100644
--- a/arch/arm/mach-s3c2410/Makefile
+++ b/arch/arm/mach-s3c2410/Makefile
@@ -9,6 +9,8 @@ obj-y := cpu.o irq.o time.o gpio.o clock.o devs.o
9obj-m := 9obj-m :=
10obj-n := 10obj-n :=
11obj- := 11obj- :=
12obj-dma-y :=
13obj-dma-n :=
12 14
13# DMA 15# DMA
14obj-$(CONFIG_S3C2410_DMA) += dma.o 16obj-$(CONFIG_S3C2410_DMA) += dma.o
@@ -20,6 +22,10 @@ obj-$(CONFIG_CPU_S3C2400) += s3c2400-gpio.o
20 22
21obj-$(CONFIG_CPU_S3C2410) += s3c2410.o 23obj-$(CONFIG_CPU_S3C2410) += s3c2410.o
22obj-$(CONFIG_CPU_S3C2410) += s3c2410-gpio.o 24obj-$(CONFIG_CPU_S3C2410) += s3c2410-gpio.o
25obj-$(CONFIG_CPU_S3C2410) += s3c2410-irq.o
26
27obj-$(CONFIG_S3C2410_PM) += s3c2410-pm.o s3c2410-sleep.o
28obj-$(CONFIG_CPU_S3C2410_DMA) += s3c2410-dma.o
23 29
24# Power Management support 30# Power Management support
25 31
@@ -30,6 +36,9 @@ obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o
30obj-$(CONFIG_CPU_S3C2412) += s3c2412.o 36obj-$(CONFIG_CPU_S3C2412) += s3c2412.o
31obj-$(CONFIG_CPU_S3C2412) += s3c2412-irq.o 37obj-$(CONFIG_CPU_S3C2412) += s3c2412-irq.o
32obj-$(CONFIG_CPU_S3C2412) += s3c2412-clock.o 38obj-$(CONFIG_CPU_S3C2412) += s3c2412-clock.o
39obj-dma-$(CONFIG_CPU_S3C2412) += s3c2412-dma.o
40
41obj-$(CONFIG_S3C2412_PM) += s3c2412-pm.o
33 42
34# 43#
35# S3C244X support 44# S3C244X support
@@ -47,6 +56,7 @@ obj-$(CONFIG_CPU_S3C2440) += s3c2440.o s3c2440-dsc.o
47obj-$(CONFIG_CPU_S3C2440) += s3c2440-irq.o 56obj-$(CONFIG_CPU_S3C2440) += s3c2440-irq.o
48obj-$(CONFIG_CPU_S3C2440) += s3c2440-clock.o 57obj-$(CONFIG_CPU_S3C2440) += s3c2440-clock.o
49obj-$(CONFIG_CPU_S3C2440) += s3c2410-gpio.o 58obj-$(CONFIG_CPU_S3C2440) += s3c2410-gpio.o
59obj-dma-$(CONFIG_CPU_S3C2440) += s3c2440-dma.o
50 60
51# S3C2442 support 61# S3C2442 support
52 62
@@ -57,8 +67,13 @@ obj-$(CONFIG_CPU_S3C2442) += s3c2442-clock.o
57 67
58obj-$(CONFIG_BAST_PC104_IRQ) += bast-irq.o 68obj-$(CONFIG_BAST_PC104_IRQ) += bast-irq.o
59 69
70# merge in dma objects
71
72obj-y += $(obj-dma-y)
73
60# machine specific support 74# machine specific support
61 75
76obj-$(CONFIG_MACH_AML_M5900) += mach-amlm5900.o
62obj-$(CONFIG_MACH_ANUBIS) += mach-anubis.o 77obj-$(CONFIG_MACH_ANUBIS) += mach-anubis.o
63obj-$(CONFIG_MACH_OSIRIS) += mach-osiris.o 78obj-$(CONFIG_MACH_OSIRIS) += mach-osiris.o
64obj-$(CONFIG_ARCH_BAST) += mach-bast.o usb-simtec.o 79obj-$(CONFIG_ARCH_BAST) += mach-bast.o usb-simtec.o
@@ -71,5 +86,6 @@ obj-$(CONFIG_MACH_VR1000) += mach-vr1000.o usb-simtec.o
71obj-$(CONFIG_MACH_RX3715) += mach-rx3715.o 86obj-$(CONFIG_MACH_RX3715) += mach-rx3715.o
72obj-$(CONFIG_MACH_OTOM) += mach-otom.o 87obj-$(CONFIG_MACH_OTOM) += mach-otom.o
73obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o 88obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o
89obj-$(CONFIG_MACH_VSTMS) += mach-vstms.o
74 90
75obj-$(CONFIG_MACH_SMDK) += common-smdk.o \ No newline at end of file 91obj-$(CONFIG_MACH_SMDK) += common-smdk.o \ No newline at end of file
diff --git a/arch/arm/mach-s3c2410/bast-irq.c b/arch/arm/mach-s3c2410/bast-irq.c
index def4441d2442..440e9aa0211a 100644
--- a/arch/arm/mach-s3c2410/bast-irq.c
+++ b/arch/arm/mach-s3c2410/bast-irq.c
@@ -18,10 +18,6 @@
18 * You should have received a copy of the GNU General Public License 18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software 19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 * Modifications:
23 * 08-Jan-2003 BJD Moved from central IRQ code
24 * 21-Aug-2005 BJD Fixed missing code and compile errors
25*/ 21*/
26 22
27 23
diff --git a/arch/arm/mach-s3c2410/cpu.c b/arch/arm/mach-s3c2410/cpu.c
index 1c3c6adae6c4..9d4899eddf1f 100644
--- a/arch/arm/mach-s3c2410/cpu.c
+++ b/arch/arm/mach-s3c2410/cpu.c
@@ -124,6 +124,15 @@ static struct cpu_table cpu_ids[] __initdata = {
124 .init = s3c2412_init, 124 .init = s3c2412_init,
125 .name = name_s3c2412, 125 .name = name_s3c2412,
126 }, 126 },
127 { /* a newer version of the s3c2412 */
128 .idcode = 0x32412003,
129 .idmask = 0xffffffff,
130 .map_io = s3c2412_map_io,
131 .init_clocks = s3c2412_init_clocks,
132 .init_uarts = s3c2412_init_uarts,
133 .init = s3c2412_init,
134 .name = name_s3c2412,
135 },
127 { 136 {
128 .idcode = 0x0, /* S3C2400 doesn't have an idcode */ 137 .idcode = 0x0, /* S3C2400 doesn't have an idcode */
129 .idmask = 0xffffffff, 138 .idmask = 0xffffffff,
diff --git a/arch/arm/mach-s3c2410/devs.h b/arch/arm/mach-s3c2410/devs.h
index 726e2eaf8797..14fb0bade716 100644
--- a/arch/arm/mach-s3c2410/devs.h
+++ b/arch/arm/mach-s3c2410/devs.h
@@ -8,11 +8,6 @@
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 *
12 * Modifications:
13 * 18-Aug-2004 BJD Created initial version
14 * 27-Aug-2004 BJD Added timers 0 through 3
15 * 10-Feb-2005 BJD Added camera from guillaume.gourat@nexvision.tv
16*/ 11*/
17#include <linux/platform_device.h> 12#include <linux/platform_device.h>
18 13
diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c
index cc92a7b2db88..d264bbbd8bef 100644
--- a/arch/arm/mach-s3c2410/dma.c
+++ b/arch/arm/mach-s3c2410/dma.c
@@ -1,35 +1,16 @@
1/* linux/arch/arm/mach-bast/dma.c 1/* linux/arch/arm/mach-s3c2410/dma.c
2 * 2 *
3 * (c) 2003-2005 Simtec Electronics 3 * (c) 2003-2005,2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
5 * 5 *
6 * S3C2410 DMA core 6 * S3C2410 DMA core
7 * 7 *
8 * http://www.simtec.co.uk/products/EB2410ITX/ 8 * http://armlinux.simtec.co.uk/
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 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 11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
13 * 13*/
14 * Changelog:
15 * 27-Feb-2005 BJD Added kmem cache for dma descriptors
16 * 18-Nov-2004 BJD Removed error for loading onto stopped channel
17 * 10-Nov-2004 BJD Ensure all external symbols exported for modules
18 * 10-Nov-2004 BJD Use sys_device and sysdev_class for power management
19 * 08-Aug-2004 BJD Apply rmk's suggestions
20 * 21-Jul-2004 BJD Ported to linux 2.6
21 * 12-Jul-2004 BJD Finished re-write and change of API
22 * 06-Jul-2004 BJD Rewrote dma code to try and cope with various problems
23 * 23-May-2003 BJD Created file
24 * 19-Aug-2003 BJD Cleanup, header fix, added URL
25 *
26 * This file is based on the Sangwook Lee/Samsung patches, re-written due
27 * to various ommisions from the code (such as flexible dma configuration)
28 * for use with the BAST system board.
29 *
30 * The re-write is pretty much complete, and should be good enough for any
31 * possible DMA function
32 */
33 14
34 15
35#ifdef CONFIG_S3C2410_DMA_DEBUG 16#ifdef CONFIG_S3C2410_DMA_DEBUG
@@ -55,10 +36,14 @@
55#include <asm/mach/dma.h> 36#include <asm/mach/dma.h>
56#include <asm/arch/map.h> 37#include <asm/arch/map.h>
57 38
39#include "dma.h"
40
58/* io map for dma */ 41/* io map for dma */
59static void __iomem *dma_base; 42static void __iomem *dma_base;
60static kmem_cache_t *dma_kmem; 43static kmem_cache_t *dma_kmem;
61 44
45struct s3c24xx_dma_selection dma_sel;
46
62/* dma channel state information */ 47/* dma channel state information */
63struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS]; 48struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS];
64 49
@@ -79,7 +64,6 @@ dma_wrreg(struct s3c2410_dma_chan *chan, int reg, unsigned long val)
79 pr_debug("writing %08x to register %08x\n",(unsigned int)val,reg); 64 pr_debug("writing %08x to register %08x\n",(unsigned int)val,reg);
80 writel(val, dma_regaddr(chan, reg)); 65 writel(val, dma_regaddr(chan, reg));
81} 66}
82
83#endif 67#endif
84 68
85#define dma_rdreg(chan, reg) readl((chan)->regs + (reg)) 69#define dma_rdreg(chan, reg) readl((chan)->regs + (reg))
@@ -151,12 +135,20 @@ dmadbg_showregs(const char *fname, int line, struct s3c2410_dma_chan *chan)
151#define dbg_showchan(chan) do { } while(0) 135#define dbg_showchan(chan) do { } while(0)
152#endif /* CONFIG_S3C2410_DMA_DEBUG */ 136#endif /* CONFIG_S3C2410_DMA_DEBUG */
153 137
154#define check_channel(chan) \ 138static struct s3c2410_dma_chan *dma_chan_map[DMACH_MAX];
155 do { if ((chan) >= S3C2410_DMA_CHANNELS) { \
156 printk(KERN_ERR "%s: invalid channel %d\n", __FUNCTION__, (chan)); \
157 return -EINVAL; \
158 } } while(0)
159 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}
160 152
161/* s3c2410_dma_stats_timeout 153/* s3c2410_dma_stats_timeout
162 * 154 *
@@ -321,8 +313,10 @@ static inline void
321s3c2410_dma_buffdone(struct s3c2410_dma_chan *chan, struct s3c2410_dma_buf *buf, 313s3c2410_dma_buffdone(struct s3c2410_dma_chan *chan, struct s3c2410_dma_buf *buf,
322 enum s3c2410_dma_buffresult result) 314 enum s3c2410_dma_buffresult result)
323{ 315{
316#if 0
324 pr_debug("callback_fn=%p, buf=%p, id=%p, size=%d, result=%d\n", 317 pr_debug("callback_fn=%p, buf=%p, id=%p, size=%d, result=%d\n",
325 chan->callback_fn, buf, buf->id, buf->size, result); 318 chan->callback_fn, buf, buf->id, buf->size, result);
319#endif
326 320
327 if (chan->callback_fn != NULL) { 321 if (chan->callback_fn != NULL) {
328 (chan->callback_fn)(chan, buf->id, buf->size, result); 322 (chan->callback_fn)(chan, buf->id, buf->size, result);
@@ -439,7 +433,6 @@ s3c2410_dma_canload(struct s3c2410_dma_chan *chan)
439 return 0; 433 return 0;
440} 434}
441 435
442
443/* s3c2410_dma_enqueue 436/* s3c2410_dma_enqueue
444 * 437 *
445 * queue an given buffer for dma transfer. 438 * queue an given buffer for dma transfer.
@@ -460,11 +453,12 @@ s3c2410_dma_canload(struct s3c2410_dma_chan *chan)
460int s3c2410_dma_enqueue(unsigned int channel, void *id, 453int s3c2410_dma_enqueue(unsigned int channel, void *id,
461 dma_addr_t data, int size) 454 dma_addr_t data, int size)
462{ 455{
463 struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; 456 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
464 struct s3c2410_dma_buf *buf; 457 struct s3c2410_dma_buf *buf;
465 unsigned long flags; 458 unsigned long flags;
466 459
467 check_channel(channel); 460 if (chan == NULL)
461 return -EINVAL;
468 462
469 pr_debug("%s: id=%p, data=%08x, size=%d\n", 463 pr_debug("%s: id=%p, data=%08x, size=%d\n",
470 __FUNCTION__, id, (unsigned int)data, size); 464 __FUNCTION__, id, (unsigned int)data, size);
@@ -562,8 +556,10 @@ s3c2410_dma_freebuf(struct s3c2410_dma_buf *buf)
562static inline void 556static inline void
563s3c2410_dma_lastxfer(struct s3c2410_dma_chan *chan) 557s3c2410_dma_lastxfer(struct s3c2410_dma_chan *chan)
564{ 558{
559#if 0
565 pr_debug("dma%d: s3c2410_dma_lastxfer: load_state %d\n", 560 pr_debug("dma%d: s3c2410_dma_lastxfer: load_state %d\n",
566 chan->number, chan->load_state); 561 chan->number, chan->load_state);
562#endif
567 563
568 switch (chan->load_state) { 564 switch (chan->load_state) {
569 case S3C2410_DMALOAD_NONE: 565 case S3C2410_DMALOAD_NONE:
@@ -718,7 +714,8 @@ s3c2410_dma_irq(int irq, void *devpw, struct pt_regs *regs)
718 if (chan->load_state == S3C2410_DMALOAD_NONE) { 714 if (chan->load_state == S3C2410_DMALOAD_NONE) {
719 pr_debug("dma%d: end of transfer, stopping channel (%ld)\n", 715 pr_debug("dma%d: end of transfer, stopping channel (%ld)\n",
720 chan->number, jiffies); 716 chan->number, jiffies);
721 s3c2410_dma_ctrl(chan->number, S3C2410_DMAOP_STOP); 717 s3c2410_dma_ctrl(chan->number | DMACH_LOW_LEVEL,
718 S3C2410_DMAOP_STOP);
722 } 719 }
723 } 720 }
724 721
@@ -726,37 +723,34 @@ s3c2410_dma_irq(int irq, void *devpw, struct pt_regs *regs)
726 return IRQ_HANDLED; 723 return IRQ_HANDLED;
727} 724}
728 725
726static struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel);
727
729/* s3c2410_request_dma 728/* s3c2410_request_dma
730 * 729 *
731 * get control of an dma channel 730 * get control of an dma channel
732*/ 731*/
733 732
734int s3c2410_dma_request(unsigned int channel, struct s3c2410_dma_client *client, 733int s3c2410_dma_request(unsigned int channel,
734 struct s3c2410_dma_client *client,
735 void *dev) 735 void *dev)
736{ 736{
737 struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; 737 struct s3c2410_dma_chan *chan;
738 unsigned long flags; 738 unsigned long flags;
739 int err; 739 int err;
740 740
741 pr_debug("dma%d: s3c2410_request_dma: client=%s, dev=%p\n", 741 pr_debug("dma%d: s3c2410_request_dma: client=%s, dev=%p\n",
742 channel, client->name, dev); 742 channel, client->name, dev);
743 743
744 check_channel(channel);
745
746 local_irq_save(flags); 744 local_irq_save(flags);
747 745
748 dbg_showchan(chan); 746 chan = s3c2410_dma_map_channel(channel);
749 747 if (chan == NULL) {
750 if (chan->in_use) { 748 local_irq_restore(flags);
751 if (client != chan->client) { 749 return -EBUSY;
752 printk(KERN_ERR "dma%d: already in use\n", channel);
753 local_irq_restore(flags);
754 return -EBUSY;
755 } else {
756 printk(KERN_ERR "dma%d: client already has channel\n", channel);
757 }
758 } 750 }
759 751
752 dbg_showchan(chan);
753
760 chan->client = client; 754 chan->client = client;
761 chan->in_use = 1; 755 chan->in_use = 1;
762 756
@@ -809,14 +803,14 @@ EXPORT_SYMBOL(s3c2410_dma_request);
809 803
810int s3c2410_dma_free(dmach_t channel, struct s3c2410_dma_client *client) 804int s3c2410_dma_free(dmach_t channel, struct s3c2410_dma_client *client)
811{ 805{
812 struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; 806 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
813 unsigned long flags; 807 unsigned long flags;
814 808
815 check_channel(channel); 809 if (chan == NULL)
810 return -EINVAL;
816 811
817 local_irq_save(flags); 812 local_irq_save(flags);
818 813
819
820 if (chan->client != client) { 814 if (chan->client != client) {
821 printk(KERN_WARNING "dma%d: possible free from different client (channel %p, passed %p)\n", 815 printk(KERN_WARNING "dma%d: possible free from different client (channel %p, passed %p)\n",
822 channel, chan->client, client); 816 channel, chan->client, client);
@@ -837,8 +831,12 @@ int s3c2410_dma_free(dmach_t channel, struct s3c2410_dma_client *client)
837 831
838 if (chan->irq_claimed) 832 if (chan->irq_claimed)
839 free_irq(chan->irq, (void *)chan); 833 free_irq(chan->irq, (void *)chan);
834
840 chan->irq_claimed = 0; 835 chan->irq_claimed = 0;
841 836
837 if (!(channel & DMACH_LOW_LEVEL))
838 dma_chan_map[channel] = NULL;
839
842 local_irq_restore(flags); 840 local_irq_restore(flags);
843 841
844 return 0; 842 return 0;
@@ -848,8 +846,8 @@ EXPORT_SYMBOL(s3c2410_dma_free);
848 846
849static int s3c2410_dma_dostop(struct s3c2410_dma_chan *chan) 847static int s3c2410_dma_dostop(struct s3c2410_dma_chan *chan)
850{ 848{
851 unsigned long tmp;
852 unsigned long flags; 849 unsigned long flags;
850 unsigned long tmp;
853 851
854 pr_debug("%s:\n", __FUNCTION__); 852 pr_debug("%s:\n", __FUNCTION__);
855 853
@@ -997,9 +995,10 @@ s3c2410_dma_started(struct s3c2410_dma_chan *chan)
997int 995int
998s3c2410_dma_ctrl(dmach_t channel, enum s3c2410_chan_op op) 996s3c2410_dma_ctrl(dmach_t channel, enum s3c2410_chan_op op)
999{ 997{
1000 struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; 998 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
1001 999
1002 check_channel(channel); 1000 if (chan == NULL)
1001 return -EINVAL;
1003 1002
1004 switch (op) { 1003 switch (op) {
1005 case S3C2410_DMAOP_START: 1004 case S3C2410_DMAOP_START:
@@ -1046,12 +1045,19 @@ int s3c2410_dma_config(dmach_t channel,
1046 int xferunit, 1045 int xferunit,
1047 int dcon) 1046 int dcon)
1048{ 1047{
1049 struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; 1048 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
1050 1049
1051 pr_debug("%s: chan=%d, xfer_unit=%d, dcon=%08x\n", 1050 pr_debug("%s: chan=%d, xfer_unit=%d, dcon=%08x\n",
1052 __FUNCTION__, channel, xferunit, dcon); 1051 __FUNCTION__, channel, xferunit, dcon);
1053 1052
1054 check_channel(channel); 1053 if (chan == NULL)
1054 return -EINVAL;
1055
1056 printk("Initial dcon is %08x\n", dcon);
1057
1058 dcon |= chan->dcon & dma_sel.dcon_mask;
1059
1060 printk("New dcon is %08x\n", dcon);
1055 1061
1056 switch (xferunit) { 1062 switch (xferunit) {
1057 case 1: 1063 case 1:
@@ -1086,9 +1092,10 @@ EXPORT_SYMBOL(s3c2410_dma_config);
1086 1092
1087int s3c2410_dma_setflags(dmach_t channel, unsigned int flags) 1093int s3c2410_dma_setflags(dmach_t channel, unsigned int flags)
1088{ 1094{
1089 struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; 1095 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
1090 1096
1091 check_channel(channel); 1097 if (chan == NULL)
1098 return -EINVAL;
1092 1099
1093 pr_debug("%s: chan=%p, flags=%08x\n", __FUNCTION__, chan, flags); 1100 pr_debug("%s: chan=%p, flags=%08x\n", __FUNCTION__, chan, flags);
1094 1101
@@ -1106,9 +1113,10 @@ EXPORT_SYMBOL(s3c2410_dma_setflags);
1106 1113
1107int s3c2410_dma_set_opfn(dmach_t channel, s3c2410_dma_opfn_t rtn) 1114int s3c2410_dma_set_opfn(dmach_t channel, s3c2410_dma_opfn_t rtn)
1108{ 1115{
1109 struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; 1116 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
1110 1117
1111 check_channel(channel); 1118 if (chan == NULL)
1119 return -EINVAL;
1112 1120
1113 pr_debug("%s: chan=%p, op rtn=%p\n", __FUNCTION__, chan, rtn); 1121 pr_debug("%s: chan=%p, op rtn=%p\n", __FUNCTION__, chan, rtn);
1114 1122
@@ -1121,9 +1129,10 @@ EXPORT_SYMBOL(s3c2410_dma_set_opfn);
1121 1129
1122int s3c2410_dma_set_buffdone_fn(dmach_t channel, s3c2410_dma_cbfn_t rtn) 1130int s3c2410_dma_set_buffdone_fn(dmach_t channel, s3c2410_dma_cbfn_t rtn)
1123{ 1131{
1124 struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; 1132 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
1125 1133
1126 check_channel(channel); 1134 if (chan == NULL)
1135 return -EINVAL;
1127 1136
1128 pr_debug("%s: chan=%p, callback rtn=%p\n", __FUNCTION__, chan, rtn); 1137 pr_debug("%s: chan=%p, callback rtn=%p\n", __FUNCTION__, chan, rtn);
1129 1138
@@ -1153,9 +1162,10 @@ int s3c2410_dma_devconfig(int channel,
1153 int hwcfg, 1162 int hwcfg,
1154 unsigned long devaddr) 1163 unsigned long devaddr)
1155{ 1164{
1156 struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; 1165 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
1157 1166
1158 check_channel(channel); 1167 if (chan == NULL)
1168 return -EINVAL;
1159 1169
1160 pr_debug("%s: source=%d, hwcfg=%08x, devaddr=%08lx\n", 1170 pr_debug("%s: source=%d, hwcfg=%08x, devaddr=%08lx\n",
1161 __FUNCTION__, (int)source, hwcfg, devaddr); 1171 __FUNCTION__, (int)source, hwcfg, devaddr);
@@ -1200,9 +1210,10 @@ EXPORT_SYMBOL(s3c2410_dma_devconfig);
1200 1210
1201int s3c2410_dma_getposition(dmach_t channel, dma_addr_t *src, dma_addr_t *dst) 1211int s3c2410_dma_getposition(dmach_t channel, dma_addr_t *src, dma_addr_t *dst)
1202{ 1212{
1203 struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; 1213 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
1204 1214
1205 check_channel(channel); 1215 if (chan == NULL)
1216 return -EINVAL;
1206 1217
1207 if (src != NULL) 1218 if (src != NULL)
1208 *src = dma_rdreg(chan, S3C2410_DMA_DCSRC); 1219 *src = dma_rdreg(chan, S3C2410_DMA_DCSRC);
@@ -1252,7 +1263,7 @@ static int s3c2410_dma_resume(struct sys_device *dev)
1252#define s3c2410_dma_resume NULL 1263#define s3c2410_dma_resume NULL
1253#endif /* CONFIG_PM */ 1264#endif /* CONFIG_PM */
1254 1265
1255static struct sysdev_class dma_sysclass = { 1266struct sysdev_class dma_sysclass = {
1256 set_kset_name("s3c24xx-dma"), 1267 set_kset_name("s3c24xx-dma"),
1257 .suspend = s3c2410_dma_suspend, 1268 .suspend = s3c2410_dma_suspend,
1258 .resume = s3c2410_dma_resume, 1269 .resume = s3c2410_dma_resume,
@@ -1265,7 +1276,6 @@ static void s3c2410_dma_cache_ctor(void *p, kmem_cache_t *c, unsigned long f)
1265 memset(p, 0, sizeof(struct s3c2410_dma_buf)); 1276 memset(p, 0, sizeof(struct s3c2410_dma_buf));
1266} 1277}
1267 1278
1268
1269/* initialisation code */ 1279/* initialisation code */
1270 1280
1271static int __init s3c2410_init_dma(void) 1281static int __init s3c2410_init_dma(void)
@@ -1274,7 +1284,7 @@ static int __init s3c2410_init_dma(void)
1274 int channel; 1284 int channel;
1275 int ret; 1285 int ret;
1276 1286
1277 printk("S3C2410 DMA Driver, (c) 2003-2004 Simtec Electronics\n"); 1287 printk("S3C24XX DMA Driver, (c) 2003-2004,2006 Simtec Electronics\n");
1278 1288
1279 dma_base = ioremap(S3C24XX_PA_DMA, 0x200); 1289 dma_base = ioremap(S3C24XX_PA_DMA, 0x200);
1280 if (dma_base == NULL) { 1290 if (dma_base == NULL) {
@@ -1282,6 +1292,8 @@ static int __init s3c2410_init_dma(void)
1282 return -ENOMEM; 1292 return -ENOMEM;
1283 } 1293 }
1284 1294
1295 printk("Registering sysclass\n");
1296
1285 ret = sysdev_class_register(&dma_sysclass); 1297 ret = sysdev_class_register(&dma_sysclass);
1286 if (ret != 0) { 1298 if (ret != 0) {
1287 printk(KERN_ERR "dma sysclass registration failed\n"); 1299 printk(KERN_ERR "dma sysclass registration failed\n");
@@ -1335,4 +1347,95 @@ static int __init s3c2410_init_dma(void)
1335 return ret; 1347 return ret;
1336} 1348}
1337 1349
1338__initcall(s3c2410_init_dma); 1350core_initcall(s3c2410_init_dma);
1351
1352static inline int is_channel_valid(unsigned int channel)
1353{
1354 return (channel & DMA_CH_VALID);
1355}
1356
1357/* s3c2410_dma_map_channel()
1358 *
1359 * turn the virtual channel number into a real, and un-used hardware
1360 * channel.
1361 *
1362 * currently this code uses first-free channel from the specified harware
1363 * map, not taking into account anything that the board setup code may
1364 * have to say about the likely peripheral set to be in use.
1365*/
1366
1367struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel)
1368{
1369 struct s3c24xx_dma_map *ch_map;
1370 struct s3c2410_dma_chan *dmach;
1371 int ch;
1372
1373 if (dma_sel.map == NULL || channel > dma_sel.map_size)
1374 return NULL;
1375
1376 ch_map = dma_sel.map + channel;
1377
1378 for (ch = 0; ch < S3C2410_DMA_CHANNELS; ch++) {
1379 if (!is_channel_valid(ch_map->channels[ch]))
1380 continue;
1381
1382 if (s3c2410_chans[ch].in_use == 0) {
1383 printk("mapped channel %d to %d\n", channel, ch);
1384 break;
1385 }
1386 }
1387
1388 if (ch >= S3C2410_DMA_CHANNELS)
1389 return NULL;
1390
1391 /* update our channel mapping */
1392
1393 dmach = &s3c2410_chans[ch];
1394 dma_chan_map[channel] = dmach;
1395
1396 /* select the channel */
1397
1398 (dma_sel.select)(dmach, ch_map);
1399
1400 return dmach;
1401}
1402
1403static void s3c24xx_dma_show_ch(struct s3c24xx_dma_map *map, int ch)
1404{
1405 /* show the channel configuration */
1406
1407 printk("%2d: %20s, channels %c%c%c%c\n", ch, map->name,
1408 (is_channel_valid(map->channels[0]) ? '0' : '-'),
1409 (is_channel_valid(map->channels[1]) ? '1' : '-'),
1410 (is_channel_valid(map->channels[2]) ? '2' : '-'),
1411 (is_channel_valid(map->channels[3]) ? '3' : '-'));
1412}
1413
1414static int s3c24xx_dma_check_entry(struct s3c24xx_dma_map *map, int ch)
1415{
1416 if (1)
1417 s3c24xx_dma_show_ch(map, ch);
1418
1419 return 0;
1420}
1421
1422int __init s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel)
1423{
1424 struct s3c24xx_dma_map *nmap;
1425 size_t map_sz = sizeof(*nmap) * sel->map_size;
1426 int ptr;
1427
1428 nmap = kmalloc(map_sz, GFP_KERNEL);
1429 if (nmap == NULL)
1430 return -ENOMEM;
1431
1432 memcpy(nmap, sel->map, map_sz);
1433 memcpy(&dma_sel, sel, sizeof(*sel));
1434
1435 dma_sel.map = nmap;
1436
1437 for (ptr = 0; ptr < sel->map_size; ptr++)
1438 s3c24xx_dma_check_entry(nmap+ptr, ptr);
1439
1440 return 0;
1441}
diff --git a/arch/arm/mach-s3c2410/dma.h b/arch/arm/mach-s3c2410/dma.h
new file mode 100644
index 000000000000..0ebfe0aab80b
--- /dev/null
+++ b/arch/arm/mach-s3c2410/dma.h
@@ -0,0 +1,45 @@
1/* arch/arm/mach-s3c2410/dma.h
2 *
3 * Copyright (C) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * Samsung S3C24XX DMA support
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13extern struct sysdev_class dma_sysclass;
14extern struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS];
15
16#define DMA_CH_VALID (1<<31)
17
18struct s3c24xx_dma_addr {
19 unsigned long from;
20 unsigned long to;
21};
22
23/* struct s3c24xx_dma_map
24 *
25 * this holds the mapping information for the channel selected
26 * to be connected to the specified device
27*/
28
29struct s3c24xx_dma_map {
30 const char *name;
31 struct s3c24xx_dma_addr hw_addr;
32
33 unsigned long channels[S3C2410_DMA_CHANNELS];
34};
35
36struct s3c24xx_dma_selection {
37 struct s3c24xx_dma_map *map;
38 unsigned long map_size;
39 unsigned long dcon_mask;
40
41 void (*select)(struct s3c2410_dma_chan *chan,
42 struct s3c24xx_dma_map *map);
43};
44
45extern int s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel);
diff --git a/arch/arm/mach-s3c2410/gpio.c b/arch/arm/mach-s3c2410/gpio.c
index cd39e8684584..db6393c99860 100644
--- a/arch/arm/mach-s3c2410/gpio.c
+++ b/arch/arm/mach-s3c2410/gpio.c
@@ -18,21 +18,7 @@
18 * You should have received a copy of the GNU General Public License 18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software 19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 * 21*/
22 * Changelog
23 * 13-Sep-2004 BJD Implemented change of MISCCR
24 * 14-Sep-2004 BJD Added getpin call
25 * 14-Sep-2004 BJD Fixed bug in setpin() call
26 * 30-Sep-2004 BJD Fixed cfgpin() mask bug
27 * 01-Oct-2004 BJD Added getcfg() to get pin configuration
28 * 01-Oct-2004 BJD Fixed mask bug in pullup() call
29 * 01-Oct-2004 BJD Added getirq() to turn pin into irqno
30 * 04-Oct-2004 BJD Added irq filter controls for GPIO
31 * 05-Nov-2004 BJD EXPORT_SYMBOL() added for all code
32 * 13-Mar-2005 BJD Updates for __iomem
33 * 26-Oct-2005 BJD Added generic configuration types
34 * 15-Jan-2006 LCVR Added support for the S3C2400
35 */
36 22
37 23
38#include <linux/kernel.h> 24#include <linux/kernel.h>
diff --git a/arch/arm/mach-s3c2410/irq.c b/arch/arm/mach-s3c2410/irq.c
index cd6139b35999..3e9f3462c61b 100644
--- a/arch/arm/mach-s3c2410/irq.c
+++ b/arch/arm/mach-s3c2410/irq.c
@@ -181,17 +181,19 @@ s3c_irq_unmask(unsigned int irqno)
181} 181}
182 182
183struct irqchip s3c_irq_level_chip = { 183struct irqchip s3c_irq_level_chip = {
184 .ack = s3c_irq_maskack, 184 .name = "s3c-level",
185 .mask = s3c_irq_mask, 185 .ack = s3c_irq_maskack,
186 .unmask = s3c_irq_unmask, 186 .mask = s3c_irq_mask,
187 .set_wake = s3c_irq_wake 187 .unmask = s3c_irq_unmask,
188 .set_wake = s3c_irq_wake
188}; 189};
189 190
190static struct irqchip s3c_irq_chip = { 191static struct irqchip s3c_irq_chip = {
191 .ack = s3c_irq_ack, 192 .name = "s3c",
192 .mask = s3c_irq_mask, 193 .ack = s3c_irq_ack,
193 .unmask = s3c_irq_unmask, 194 .mask = s3c_irq_mask,
194 .set_wake = s3c_irq_wake 195 .unmask = s3c_irq_unmask,
196 .set_wake = s3c_irq_wake
195}; 197};
196 198
197static void 199static void
@@ -343,19 +345,21 @@ s3c_irqext_type(unsigned int irq, unsigned int type)
343} 345}
344 346
345static struct irqchip s3c_irqext_chip = { 347static struct irqchip s3c_irqext_chip = {
346 .mask = s3c_irqext_mask, 348 .name = "s3c-ext",
347 .unmask = s3c_irqext_unmask, 349 .mask = s3c_irqext_mask,
348 .ack = s3c_irqext_ack, 350 .unmask = s3c_irqext_unmask,
349 .set_type = s3c_irqext_type, 351 .ack = s3c_irqext_ack,
350 .set_wake = s3c_irqext_wake 352 .set_type = s3c_irqext_type,
353 .set_wake = s3c_irqext_wake
351}; 354};
352 355
353static struct irqchip s3c_irq_eint0t4 = { 356static struct irqchip s3c_irq_eint0t4 = {
354 .ack = s3c_irq_ack, 357 .name = "s3c-ext0",
355 .mask = s3c_irq_mask, 358 .ack = s3c_irq_ack,
356 .unmask = s3c_irq_unmask, 359 .mask = s3c_irq_mask,
357 .set_wake = s3c_irq_wake, 360 .unmask = s3c_irq_unmask,
358 .set_type = s3c_irqext_type, 361 .set_wake = s3c_irq_wake,
362 .set_type = s3c_irqext_type,
359}; 363};
360 364
361/* mask values for the parent registers for each of the interrupt types */ 365/* mask values for the parent registers for each of the interrupt types */
@@ -387,9 +391,10 @@ s3c_irq_uart0_ack(unsigned int irqno)
387} 391}
388 392
389static struct irqchip s3c_irq_uart0 = { 393static struct irqchip s3c_irq_uart0 = {
390 .mask = s3c_irq_uart0_mask, 394 .name = "s3c-uart0",
391 .unmask = s3c_irq_uart0_unmask, 395 .mask = s3c_irq_uart0_mask,
392 .ack = s3c_irq_uart0_ack, 396 .unmask = s3c_irq_uart0_unmask,
397 .ack = s3c_irq_uart0_ack,
393}; 398};
394 399
395/* UART1 */ 400/* UART1 */
@@ -413,9 +418,10 @@ s3c_irq_uart1_ack(unsigned int irqno)
413} 418}
414 419
415static struct irqchip s3c_irq_uart1 = { 420static struct irqchip s3c_irq_uart1 = {
416 .mask = s3c_irq_uart1_mask, 421 .name = "s3c-uart1",
417 .unmask = s3c_irq_uart1_unmask, 422 .mask = s3c_irq_uart1_mask,
418 .ack = s3c_irq_uart1_ack, 423 .unmask = s3c_irq_uart1_unmask,
424 .ack = s3c_irq_uart1_ack,
419}; 425};
420 426
421/* UART2 */ 427/* UART2 */
@@ -439,9 +445,10 @@ s3c_irq_uart2_ack(unsigned int irqno)
439} 445}
440 446
441static struct irqchip s3c_irq_uart2 = { 447static struct irqchip s3c_irq_uart2 = {
442 .mask = s3c_irq_uart2_mask, 448 .name = "s3c-uart2",
443 .unmask = s3c_irq_uart2_unmask, 449 .mask = s3c_irq_uart2_mask,
444 .ack = s3c_irq_uart2_ack, 450 .unmask = s3c_irq_uart2_unmask,
451 .ack = s3c_irq_uart2_ack,
445}; 452};
446 453
447/* ADC and Touchscreen */ 454/* ADC and Touchscreen */
@@ -465,9 +472,10 @@ s3c_irq_adc_ack(unsigned int irqno)
465} 472}
466 473
467static struct irqchip s3c_irq_adc = { 474static struct irqchip s3c_irq_adc = {
468 .mask = s3c_irq_adc_mask, 475 .name = "s3c-adc",
469 .unmask = s3c_irq_adc_unmask, 476 .mask = s3c_irq_adc_mask,
470 .ack = s3c_irq_adc_ack, 477 .unmask = s3c_irq_adc_unmask,
478 .ack = s3c_irq_adc_ack,
471}; 479};
472 480
473/* irq demux for adc */ 481/* irq demux for adc */
@@ -569,23 +577,104 @@ s3c_irq_demux_uart2(unsigned int irq,
569} 577}
570 578
571static void 579static void
572s3c_irq_demux_extint(unsigned int irq, 580s3c_irq_demux_extint8(unsigned int irq,
573 struct irqdesc *desc, 581 struct irqdesc *desc,
574 struct pt_regs *regs) 582 struct pt_regs *regs)
575{ 583{
576 unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND); 584 unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND);
577 unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK); 585 unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK);
578 586
579 eintpnd &= ~eintmsk; 587 eintpnd &= ~eintmsk;
588 eintpnd &= ~0xff; /* ignore lower irqs */
580 589
581 if (eintpnd) { 590 /* we may as well handle all the pending IRQs here */
582 irq = fls(eintpnd);
583 irq += (IRQ_EINT4 - (4 + 1));
584 591
592 while (eintpnd) {
593 irq = __ffs(eintpnd);
594 eintpnd &= ~(1<<irq);
595
596 irq += (IRQ_EINT4 - 4);
585 desc_handle_irq(irq, irq_desc + irq, regs); 597 desc_handle_irq(irq, irq_desc + irq, regs);
586 } 598 }
599
600}
601
602static void
603s3c_irq_demux_extint4t7(unsigned int irq,
604 struct irqdesc *desc,
605 struct pt_regs *regs)
606{
607 unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND);
608 unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK);
609
610 eintpnd &= ~eintmsk;
611 eintpnd &= 0xff; /* only lower irqs */
612
613 /* we may as well handle all the pending IRQs here */
614
615 while (eintpnd) {
616 irq = __ffs(eintpnd);
617 eintpnd &= ~(1<<irq);
618
619 irq += (IRQ_EINT4 - 4);
620
621 desc_handle_irq(irq, irq_desc + irq, regs);
622 }
623}
624
625#ifdef CONFIG_PM
626
627static struct sleep_save irq_save[] = {
628 SAVE_ITEM(S3C2410_INTMSK),
629 SAVE_ITEM(S3C2410_INTSUBMSK),
630};
631
632/* the extint values move between the s3c2410/s3c2440 and the s3c2412
633 * so we use an array to hold them, and to calculate the address of
634 * the register at run-time
635*/
636
637static unsigned long save_extint[3];
638static unsigned long save_eintflt[4];
639static unsigned long save_eintmask;
640
641int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state)
642{
643 unsigned int i;
644
645 for (i = 0; i < ARRAY_SIZE(save_extint); i++)
646 save_extint[i] = __raw_readl(S3C24XX_EXTINT0 + (i*4));
647
648 for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
649 save_eintflt[i] = __raw_readl(S3C24XX_EINFLT0 + (i*4));
650
651 s3c2410_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
652 save_eintmask = __raw_readl(S3C24XX_EINTMASK);
653
654 return 0;
587} 655}
588 656
657int s3c24xx_irq_resume(struct sys_device *dev)
658{
659 unsigned int i;
660
661 for (i = 0; i < ARRAY_SIZE(save_extint); i++)
662 __raw_writel(save_extint[i], S3C24XX_EXTINT0 + (i*4));
663
664 for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
665 __raw_writel(save_eintflt[i], S3C24XX_EINFLT0 + (i*4));
666
667 s3c2410_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
668 __raw_writel(save_eintmask, S3C24XX_EINTMASK);
669
670 return 0;
671}
672
673#else
674#define s3c24xx_irq_suspend NULL
675#define s3c24xx_irq_resume NULL
676#endif
677
589/* s3c24xx_init_irq 678/* s3c24xx_init_irq
590 * 679 *
591 * Initialise S3C2410 IRQ system 680 * Initialise S3C2410 IRQ system
@@ -674,8 +763,8 @@ void __init s3c24xx_init_irq(void)
674 763
675 /* setup the cascade irq handlers */ 764 /* setup the cascade irq handlers */
676 765
677 set_irq_chained_handler(IRQ_EINT4t7, s3c_irq_demux_extint); 766 set_irq_chained_handler(IRQ_EINT4t7, s3c_irq_demux_extint4t7);
678 set_irq_chained_handler(IRQ_EINT8t23, s3c_irq_demux_extint); 767 set_irq_chained_handler(IRQ_EINT8t23, s3c_irq_demux_extint8);
679 768
680 set_irq_chained_handler(IRQ_UART0, s3c_irq_demux_uart0); 769 set_irq_chained_handler(IRQ_UART0, s3c_irq_demux_uart0);
681 set_irq_chained_handler(IRQ_UART1, s3c_irq_demux_uart1); 770 set_irq_chained_handler(IRQ_UART1, s3c_irq_demux_uart1);
diff --git a/arch/arm/mach-s3c2410/mach-amlm5900.c b/arch/arm/mach-s3c2410/mach-amlm5900.c
new file mode 100644
index 000000000000..ba5109af40b4
--- /dev/null
+++ b/arch/arm/mach-s3c2410/mach-amlm5900.c
@@ -0,0 +1,266 @@
1/***********************************************************************
2 *
3 * linux/arch/arm/mach-s3c2410/mach-amlm5900.c
4 *
5 * Copyright (c) 2006 American Microsystems Limited
6 * David Anders <danders@amltd.com>
7
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
22 *
23 * @History:
24 * derived from linux/arch/arm/mach-s3c2410/mach-bast.c, written by
25 * Ben Dooks <ben@simtec.co.uk>
26 *
27 ***********************************************************************/
28
29#include <linux/kernel.h>
30#include <linux/types.h>
31#include <linux/interrupt.h>
32#include <linux/list.h>
33#include <linux/timer.h>
34#include <linux/init.h>
35#include <linux/device.h>
36#include <linux/platform_device.h>
37#include <linux/proc_fs.h>
38
39
40#include <asm/mach/arch.h>
41#include <asm/mach/map.h>
42#include <asm/mach/irq.h>
43#include <asm/mach/flash.h>
44
45#include <asm/hardware.h>
46#include <asm/io.h>
47#include <asm/irq.h>
48#include <asm/mach-types.h>
49#include <asm/arch/fb.h>
50
51#include <asm/arch/regs-serial.h>
52#include <asm/arch/regs-lcd.h>
53#include <asm/arch/regs-gpio.h>
54
55#include "devs.h"
56#include "cpu.h"
57
58#ifdef CONFIG_MTD_PARTITIONS
59
60#include <linux/mtd/mtd.h>
61#include <linux/mtd/partitions.h>
62#include <linux/mtd/map.h>
63#include <linux/mtd/physmap.h>
64
65static struct resource amlm5900_nor_resource = {
66 .start = 0x00000000,
67 .end = 0x01000000 - 1,
68 .flags = IORESOURCE_MEM,
69};
70
71
72
73static struct mtd_partition amlm5900_mtd_partitions[] = {
74 {
75 .name = "System",
76 .size = 0x240000,
77 .offset = 0,
78 .mask_flags = MTD_WRITEABLE, /* force read-only */
79 }, {
80 .name = "Kernel",
81 .size = 0x100000,
82 .offset = MTDPART_OFS_APPEND,
83 }, {
84 .name = "Ramdisk",
85 .size = 0x300000,
86 .offset = MTDPART_OFS_APPEND,
87 }, {
88 .name = "JFFS2",
89 .size = 0x9A0000,
90 .offset = MTDPART_OFS_APPEND,
91 }, {
92 .name = "Settings",
93 .size = MTDPART_SIZ_FULL,
94 .offset = MTDPART_OFS_APPEND,
95 }
96};
97
98static struct physmap_flash_data amlm5900_flash_data = {
99 .width = 2,
100 .parts = amlm5900_mtd_partitions,
101 .nr_parts = ARRAY_SIZE(amlm5900_mtd_partitions),
102};
103
104static struct platform_device amlm5900_device_nor = {
105 .name = "physmap-flash",
106 .id = 0,
107 .dev = {
108 .platform_data = &amlm5900_flash_data,
109 },
110 .num_resources = 1,
111 .resource = &amlm5900_nor_resource,
112};
113#endif
114
115static struct map_desc amlm5900_iodesc[] __initdata = {
116 {
117 .virtual = (u32)S3C24XX_VA_SPI,
118 .pfn = __phys_to_pfn(S3C2410_PA_SPI),
119 .length = SZ_1M,
120 .type = MT_DEVICE
121 }
122};
123
124#define UCON S3C2410_UCON_DEFAULT
125#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
126#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
127
128static struct s3c2410_uartcfg amlm5900_uartcfgs[] = {
129 [0] = {
130 .hwport = 0,
131 .flags = 0,
132 .ucon = UCON,
133 .ulcon = ULCON,
134 .ufcon = UFCON,
135 },
136 [1] = {
137 .hwport = 1,
138 .flags = 0,
139 .ucon = UCON,
140 .ulcon = ULCON,
141 .ufcon = UFCON,
142 },
143 [2] = {
144 .hwport = 2,
145 .flags = 0,
146 .ucon = UCON,
147 .ulcon = ULCON,
148 .ufcon = UFCON,
149 }
150};
151
152
153static struct platform_device *amlm5900_devices[] __initdata = {
154#ifdef CONFIG_FB_S3C2410
155 &s3c_device_lcd,
156#endif
157 &s3c_device_adc,
158 &s3c_device_wdt,
159 &s3c_device_i2c,
160 &s3c_device_usb,
161 &s3c_device_rtc,
162 &s3c_device_usbgadget,
163 &s3c_device_sdi,
164#ifdef CONFIG_MTD_PARTITIONS
165 &amlm5900_device_nor,
166#endif
167};
168
169static struct s3c24xx_board amlm5900_board __initdata = {
170 .devices = amlm5900_devices,
171 .devices_count = ARRAY_SIZE(amlm5900_devices)
172};
173
174void __init amlm5900_map_io(void)
175{
176 s3c24xx_init_io(amlm5900_iodesc, ARRAY_SIZE(amlm5900_iodesc));
177 s3c24xx_init_clocks(0);
178 s3c24xx_init_uarts(amlm5900_uartcfgs, ARRAY_SIZE(amlm5900_uartcfgs));
179 s3c24xx_set_board(&amlm5900_board);
180}
181
182#ifdef CONFIG_FB_S3C2410
183static struct s3c2410fb_mach_info __initdata amlm5900_lcd_info = {
184 .width = 160,
185 .height = 160,
186
187/* commented out until stn patch is submitted
188* .type = S3C2410_LCDCON1_STN4,
189*/
190 .gpccon = 0xaaaaaaaa,
191 .gpccon_mask = 0xffffffff,
192 .gpcup = 0x0000ffff,
193 .gpcup_mask = 0xffffffff,
194
195 .gpdcon = 0xaaaaaaaa,
196 .gpdcon_mask = 0xffffffff,
197 .gpdup = 0x0000ffff,
198 .gpdup_mask = 0xffffffff,
199
200 .xres = {
201 .min = 160,
202 .max = 160,
203 .defval = 160,
204 },
205
206 .yres = {
207 .min = 160,
208 .max = 160,
209 .defval = 160,
210 },
211
212 .bpp = {
213 .min = 4,
214 .max = 4,
215 .defval = 4,
216 },
217
218 .regs = {
219 .lcdcon1 = 0x00008225,
220 .lcdcon2 = 0x0027c000,
221 .lcdcon3 = 0x00182708,
222 .lcdcon4 = 0x00000002,
223 .lcdcon5 = 0x00000001,
224 }
225};
226#endif
227
228static irqreturn_t
229amlm5900_wake_interrupt(int irq, void *ignored, struct pt_regs *regs)
230{
231 return IRQ_HANDLED;
232}
233
234static void amlm5900_init_pm(void)
235{
236 int ret = 0;
237
238 ret = request_irq(IRQ_EINT9, &amlm5900_wake_interrupt,
239 IRQF_TRIGGER_RISING | IRQF_SHARED,
240 "amlm5900_wakeup", &amlm5900_wake_interrupt);
241 if (ret != 0) {
242 printk(KERN_ERR "AML-M5900: no wakeup irq, %d?\n", ret);
243 } else {
244 enable_irq_wake(IRQ_EINT9);
245 /* configure the suspend/resume status pin */
246 s3c2410_gpio_cfgpin(S3C2410_GPF2, S3C2410_GPF2_OUTP);
247 s3c2410_gpio_pullup(S3C2410_GPF2, 0);
248 }
249}
250static void __init amlm5900_init(void)
251{
252 amlm5900_init_pm();
253#ifdef CONFIG_FB_S3C2410
254 s3c24xx_fb_set_platdata(&amlm5900_lcd_info);
255#endif
256}
257
258MACHINE_START(AML_M5900, "AML_M5900")
259 .phys_io = S3C2410_PA_UART,
260 .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
261 .boot_params = S3C2410_SDRAM_PA + 0x100,
262 .map_io = amlm5900_map_io,
263 .init_irq = s3c24xx_init_irq,
264 .init_machine = amlm5900_init,
265 .timer = &s3c24xx_timer,
266MACHINE_END
diff --git a/arch/arm/mach-s3c2410/mach-anubis.c b/arch/arm/mach-s3c2410/mach-anubis.c
index 60641d452db3..e94cdcd96591 100644
--- a/arch/arm/mach-s3c2410/mach-anubis.c
+++ b/arch/arm/mach-s3c2410/mach-anubis.c
@@ -4,15 +4,9 @@
4 * http://armlinux.simtec.co.uk/ 4 * http://armlinux.simtec.co.uk/
5 * Ben Dooks <ben@simtec.co.uk> 5 * Ben Dooks <ben@simtec.co.uk>
6 * 6 *
7 *
8 *
9 * This program is free software; you can redistribute it and/or modify 7 * 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 8 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation. 9 * published by the Free Software Foundation.
12 *
13 * Modifications:
14 * 02-May-2005 BJD Copied from mach-bast.c
15 * 20-Sep-2005 BJD Added static to non-exported items
16*/ 10*/
17 11
18#include <linux/kernel.h> 12#include <linux/kernel.h>
diff --git a/arch/arm/mach-s3c2410/mach-smdk2440.c b/arch/arm/mach-s3c2410/mach-smdk2440.c
index d661c6b7ff56..e2205ff1b0ee 100644
--- a/arch/arm/mach-s3c2410/mach-smdk2440.c
+++ b/arch/arm/mach-s3c2410/mach-smdk2440.c
@@ -11,15 +11,6 @@
11 * it under the terms of the GNU General Public License version 2 as 11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
13 * 13 *
14 * Modifications:
15 * 01-Nov-2004 BJD Initial version
16 * 12-Nov-2004 BJD Updated for release
17 * 04-Jan-2005 BJD Fixes for pre-release
18 * 22-Feb-2005 BJD Updated for 2.6.11-rc5 relesa
19 * 10-Mar-2005 LCVR Replaced S3C2410_VA by S3C24XX_VA
20 * 14-Mar-2005 BJD void __iomem fixes
21 * 20-Sep-2005 BJD Added static to non-exported items
22 * 26-Oct-2005 BJD Added framebuffer data
23*/ 14*/
24 15
25#include <linux/kernel.h> 16#include <linux/kernel.h>
diff --git a/arch/arm/mach-s3c2410/mach-vstms.c b/arch/arm/mach-s3c2410/mach-vstms.c
new file mode 100644
index 000000000000..ea554e7c006e
--- /dev/null
+++ b/arch/arm/mach-s3c2410/mach-vstms.c
@@ -0,0 +1,168 @@
1/* linux/arch/arm/mach-s3c2410/mach-vstms.c
2 *
3 * (C) 2006 Thomas Gleixner <tglx@linutronix.de>
4 *
5 * Derived from mach-smdk2413.c - (C) 2006 Simtec Electronics
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/kernel.h>
13#include <linux/types.h>
14#include <linux/interrupt.h>
15#include <linux/list.h>
16#include <linux/timer.h>
17#include <linux/init.h>
18#include <linux/platform_device.h>
19
20#include <linux/mtd/mtd.h>
21#include <linux/mtd/nand.h>
22#include <linux/mtd/nand_ecc.h>
23#include <linux/mtd/partitions.h>
24
25#include <asm/mach/arch.h>
26#include <asm/mach/map.h>
27#include <asm/mach/irq.h>
28
29#include <asm/hardware.h>
30#include <asm/hardware/iomd.h>
31#include <asm/setup.h>
32#include <asm/io.h>
33#include <asm/irq.h>
34#include <asm/mach-types.h>
35
36#include <asm/arch/regs-serial.h>
37#include <asm/arch/regs-gpio.h>
38#include <asm/arch/regs-lcd.h>
39
40#include <asm/arch/idle.h>
41#include <asm/arch/fb.h>
42
43#include <asm/arch/nand.h>
44
45#include "s3c2410.h"
46#include "s3c2412.h"
47#include "clock.h"
48#include "devs.h"
49#include "cpu.h"
50
51
52static struct map_desc vstms_iodesc[] __initdata = {
53};
54
55static struct s3c2410_uartcfg vstms_uartcfgs[] __initdata = {
56 [0] = {
57 .hwport = 0,
58 .flags = 0,
59 .ucon = 0x3c5,
60 .ulcon = 0x03,
61 .ufcon = 0x51,
62 },
63 [1] = {
64 .hwport = 1,
65 .flags = 0,
66 .ucon = 0x3c5,
67 .ulcon = 0x03,
68 .ufcon = 0x51,
69 },
70 [2] = {
71 .hwport = 2,
72 .flags = 0,
73 .ucon = 0x3c5,
74 .ulcon = 0x03,
75 .ufcon = 0x51,
76 }
77};
78
79static struct mtd_partition vstms_nand_part[] = {
80 [0] = {
81 .name = "Boot Agent",
82 .size = 0x7C000,
83 .offset = 0,
84 },
85 [1] = {
86 .name = "UBoot Config",
87 .offset = 0x7C000,
88 .size = 0x4000,
89 },
90 [2] = {
91 .name = "Kernel",
92 .offset = 0x80000,
93 .size = 0x200000,
94 },
95 [3] = {
96 .name = "RFS",
97 .offset = 0x280000,
98 .size = 0x3d80000,
99 },
100};
101
102static struct s3c2410_nand_set vstms_nand_sets[] = {
103 [0] = {
104 .name = "NAND",
105 .nr_chips = 1,
106 .nr_partitions = ARRAY_SIZE(vstms_nand_part),
107 .partitions = vstms_nand_part,
108 },
109};
110
111/* choose a set of timings which should suit most 512Mbit
112 * chips and beyond.
113*/
114
115static struct s3c2410_platform_nand vstms_nand_info = {
116 .tacls = 20,
117 .twrph0 = 60,
118 .twrph1 = 20,
119 .nr_sets = ARRAY_SIZE(vstms_nand_sets),
120 .sets = vstms_nand_sets,
121};
122
123static struct platform_device *vstms_devices[] __initdata = {
124 &s3c_device_usb,
125 &s3c_device_wdt,
126 &s3c_device_i2c,
127 &s3c_device_iis,
128 &s3c_device_rtc,
129 &s3c_device_nand,
130};
131
132static struct s3c24xx_board vstms_board __initdata = {
133 .devices = vstms_devices,
134 .devices_count = ARRAY_SIZE(vstms_devices)
135};
136
137static void __init vstms_fixup(struct machine_desc *desc,
138 struct tag *tags, char **cmdline,
139 struct meminfo *mi)
140{
141 if (tags != phys_to_virt(S3C2410_SDRAM_PA + 0x100)) {
142 mi->nr_banks=1;
143 mi->bank[0].start = 0x30000000;
144 mi->bank[0].size = SZ_64M;
145 mi->bank[0].node = 0;
146 }
147}
148
149static void __init vstms_map_io(void)
150{
151 s3c_device_nand.dev.platform_data = &vstms_nand_info;
152
153 s3c24xx_init_io(vstms_iodesc, ARRAY_SIZE(vstms_iodesc));
154 s3c24xx_init_clocks(12000000);
155 s3c24xx_init_uarts(vstms_uartcfgs, ARRAY_SIZE(vstms_uartcfgs));
156 s3c24xx_set_board(&vstms_board);
157}
158
159MACHINE_START(VSTMS, "VSTMS")
160 .phys_io = S3C2410_PA_UART,
161 .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
162 .boot_params = S3C2410_SDRAM_PA + 0x100,
163
164 .fixup = vstms_fixup,
165 .init_irq = s3c24xx_init_irq,
166 .map_io = vstms_map_io,
167 .timer = &s3c24xx_timer,
168MACHINE_END
diff --git a/arch/arm/mach-s3c2410/pm-simtec.c b/arch/arm/mach-s3c2410/pm-simtec.c
index 7b244566a436..42cd05e298f8 100644
--- a/arch/arm/mach-s3c2410/pm-simtec.c
+++ b/arch/arm/mach-s3c2410/pm-simtec.c
@@ -49,7 +49,8 @@ static __init int pm_simtec_init(void)
49 /* check which machine we are running on */ 49 /* check which machine we are running on */
50 50
51 if (!machine_is_bast() && !machine_is_vr1000() && 51 if (!machine_is_bast() && !machine_is_vr1000() &&
52 !machine_is_anubis() && !machine_is_osiris()) 52 !machine_is_anubis() && !machine_is_osiris() &&
53 !machine_is_aml_m5900())
53 return 0; 54 return 0;
54 55
55 printk(KERN_INFO "Simtec Board Power Manangement" COPYRIGHT "\n"); 56 printk(KERN_INFO "Simtec Board Power Manangement" COPYRIGHT "\n");
diff --git a/arch/arm/mach-s3c2410/pm.c b/arch/arm/mach-s3c2410/pm.c
index a589fe76d915..b49a0b3b72b3 100644
--- a/arch/arm/mach-s3c2410/pm.c
+++ b/arch/arm/mach-s3c2410/pm.c
@@ -1,9 +1,9 @@
1/* linux/arch/arm/mach-s3c2410/pm.c 1/* linux/arch/arm/mach-s3c2410/pm.c
2 * 2 *
3 * Copyright (c) 2004 Simtec Electronics 3 * Copyright (c) 2004,2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
5 * 5 *
6 * S3C2410 Power Manager (Suspend-To-RAM) support 6 * S3C24XX Power Manager (Suspend-To-RAM) support
7 * 7 *
8 * See Documentation/arm/Samsung-S3C24XX/Suspend.txt for more information 8 * See Documentation/arm/Samsung-S3C24XX/Suspend.txt for more information
9 * 9 *
@@ -24,9 +24,6 @@
24 * Parts based on arch/arm/mach-pxa/pm.c 24 * Parts based on arch/arm/mach-pxa/pm.c
25 * 25 *
26 * Thanks to Dimitry Andric for debugging 26 * Thanks to Dimitry Andric for debugging
27 *
28 * Modifications:
29 * 10-Mar-2005 LCVR Changed S3C2410_VA_UART to S3C24XX_VA_UART
30*/ 27*/
31 28
32#include <linux/init.h> 29#include <linux/init.h>
@@ -38,6 +35,7 @@
38#include <linux/ioport.h> 35#include <linux/ioport.h>
39#include <linux/delay.h> 36#include <linux/delay.h>
40 37
38#include <asm/cacheflush.h>
41#include <asm/hardware.h> 39#include <asm/hardware.h>
42#include <asm/io.h> 40#include <asm/io.h>
43 41
@@ -55,14 +53,6 @@
55 53
56unsigned long s3c_pm_flags; 54unsigned long s3c_pm_flags;
57 55
58/* cache functions from arch/arm/mm/proc-arm920.S */
59
60#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
61extern void arm920_flush_kern_cache_all(void);
62#else
63static void arm920_flush_kern_cache_all(void) { }
64#endif
65
66#define PFX "s3c24xx-pm: " 56#define PFX "s3c24xx-pm: "
67 57
68static struct sleep_save core_save[] = { 58static struct sleep_save core_save[] = {
@@ -92,19 +82,6 @@ static struct sleep_save core_save[] = {
92 SAVE_ITEM(S3C2410_REFRESH), 82 SAVE_ITEM(S3C2410_REFRESH),
93}; 83};
94 84
95/* this lot should be really saved by the IRQ code */
96static struct sleep_save irq_save[] = {
97 SAVE_ITEM(S3C2410_EXTINT0),
98 SAVE_ITEM(S3C2410_EXTINT1),
99 SAVE_ITEM(S3C2410_EXTINT2),
100 SAVE_ITEM(S3C2410_EINFLT0),
101 SAVE_ITEM(S3C2410_EINFLT1),
102 SAVE_ITEM(S3C2410_EINFLT2),
103 SAVE_ITEM(S3C2410_EINFLT3),
104 SAVE_ITEM(S3C2410_EINTMASK),
105 SAVE_ITEM(S3C2410_INTMSK)
106};
107
108static struct sleep_save gpio_save[] = { 85static struct sleep_save gpio_save[] = {
109 SAVE_ITEM(S3C2410_GPACON), 86 SAVE_ITEM(S3C2410_GPACON),
110 SAVE_ITEM(S3C2410_GPADAT), 87 SAVE_ITEM(S3C2410_GPADAT),
@@ -165,7 +142,7 @@ static struct sleep_save uart_save[] = {
165 142
166extern void printascii(const char *); 143extern void printascii(const char *);
167 144
168static void pm_dbg(const char *fmt, ...) 145void pm_dbg(const char *fmt, ...)
169{ 146{
170 va_list va; 147 va_list va;
171 char buff[256]; 148 char buff[256];
@@ -509,6 +486,9 @@ static void s3c2410_pm_configure_extint(void)
509 } 486 }
510} 487}
511 488
489void (*pm_cpu_prep)(void);
490void (*pm_cpu_sleep)(void);
491
512#define any_allowed(mask, allow) (((mask) & (allow)) != (allow)) 492#define any_allowed(mask, allow) (((mask) & (allow)) != (allow))
513 493
514/* s3c2410_pm_enter 494/* s3c2410_pm_enter
@@ -519,7 +499,6 @@ static void s3c2410_pm_configure_extint(void)
519static int s3c2410_pm_enter(suspend_state_t state) 499static int s3c2410_pm_enter(suspend_state_t state)
520{ 500{
521 unsigned long regs_save[16]; 501 unsigned long regs_save[16];
522 unsigned long tmp;
523 502
524 /* ensure the debug is initialised (if enabled) */ 503 /* ensure the debug is initialised (if enabled) */
525 504
@@ -527,6 +506,11 @@ static int s3c2410_pm_enter(suspend_state_t state)
527 506
528 DBG("s3c2410_pm_enter(%d)\n", state); 507 DBG("s3c2410_pm_enter(%d)\n", state);
529 508
509 if (pm_cpu_prep == NULL || pm_cpu_sleep == NULL) {
510 printk(KERN_ERR PFX "error: no cpu sleep functions set\n");
511 return -EINVAL;
512 }
513
530 if (state != PM_SUSPEND_MEM) { 514 if (state != PM_SUSPEND_MEM) {
531 printk(KERN_ERR PFX "error: only PM_SUSPEND_MEM supported\n"); 515 printk(KERN_ERR PFX "error: only PM_SUSPEND_MEM supported\n");
532 return -EINVAL; 516 return -EINVAL;
@@ -554,17 +538,9 @@ static int s3c2410_pm_enter(suspend_state_t state)
554 538
555 DBG("s3c2410_sleep_save_phys=0x%08lx\n", s3c2410_sleep_save_phys); 539 DBG("s3c2410_sleep_save_phys=0x%08lx\n", s3c2410_sleep_save_phys);
556 540
557 /* ensure at least GESTATUS3 has the resume address */
558
559 __raw_writel(virt_to_phys(s3c2410_cpu_resume), S3C2410_GSTATUS3);
560
561 DBG("GSTATUS3 0x%08x\n", __raw_readl(S3C2410_GSTATUS3));
562 DBG("GSTATUS4 0x%08x\n", __raw_readl(S3C2410_GSTATUS4));
563
564 /* save all necessary core registers not covered by the drivers */ 541 /* save all necessary core registers not covered by the drivers */
565 542
566 s3c2410_pm_do_save(gpio_save, ARRAY_SIZE(gpio_save)); 543 s3c2410_pm_do_save(gpio_save, ARRAY_SIZE(gpio_save));
567 s3c2410_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
568 s3c2410_pm_do_save(core_save, ARRAY_SIZE(core_save)); 544 s3c2410_pm_do_save(core_save, ARRAY_SIZE(core_save));
569 s3c2410_pm_do_save(uart_save, ARRAY_SIZE(uart_save)); 545 s3c2410_pm_do_save(uart_save, ARRAY_SIZE(uart_save));
570 546
@@ -581,10 +557,16 @@ static int s3c2410_pm_enter(suspend_state_t state)
581 /* ack any outstanding external interrupts before we go to sleep */ 557 /* ack any outstanding external interrupts before we go to sleep */
582 558
583 __raw_writel(__raw_readl(S3C2410_EINTPEND), S3C2410_EINTPEND); 559 __raw_writel(__raw_readl(S3C2410_EINTPEND), S3C2410_EINTPEND);
560 __raw_writel(__raw_readl(S3C2410_INTPND), S3C2410_INTPND);
561 __raw_writel(__raw_readl(S3C2410_SRCPND), S3C2410_SRCPND);
562
563 /* call cpu specific preperation */
564
565 pm_cpu_prep();
584 566
585 /* flush cache back to ram */ 567 /* flush cache back to ram */
586 568
587 arm920_flush_kern_cache_all(); 569 flush_cache_all();
588 570
589 s3c2410_pm_check_store(); 571 s3c2410_pm_check_store();
590 572
@@ -592,23 +574,23 @@ static int s3c2410_pm_enter(suspend_state_t state)
592 574
593 __raw_writel(0x00, S3C2410_CLKCON); /* turn off clocks over sleep */ 575 __raw_writel(0x00, S3C2410_CLKCON); /* turn off clocks over sleep */
594 576
595 s3c2410_cpu_suspend(regs_save); 577 /* s3c2410_cpu_save will also act as our return point from when
578 * we resume as it saves its own register state, so use the return
579 * code to differentiate return from save and return from sleep */
580
581 if (s3c2410_cpu_save(regs_save) == 0) {
582 flush_cache_all();
583 pm_cpu_sleep();
584 }
596 585
597 /* restore the cpu state */ 586 /* restore the cpu state */
598 587
599 cpu_init(); 588 cpu_init();
600 589
601 /* unset the return-from-sleep flag, to ensure reset */
602
603 tmp = __raw_readl(S3C2410_GSTATUS2);
604 tmp &= S3C2410_GSTATUS2_OFFRESET;
605 __raw_writel(tmp, S3C2410_GSTATUS2);
606
607 /* restore the system state */ 590 /* restore the system state */
608 591
609 s3c2410_pm_do_restore_core(core_save, ARRAY_SIZE(core_save)); 592 s3c2410_pm_do_restore_core(core_save, ARRAY_SIZE(core_save));
610 s3c2410_pm_do_restore(gpio_save, ARRAY_SIZE(gpio_save)); 593 s3c2410_pm_do_restore(gpio_save, ARRAY_SIZE(gpio_save));
611 s3c2410_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
612 s3c2410_pm_do_restore(uart_save, ARRAY_SIZE(uart_save)); 594 s3c2410_pm_do_restore(uart_save, ARRAY_SIZE(uart_save));
613 595
614 s3c2410_pm_debug_init(); 596 s3c2410_pm_debug_init();
diff --git a/arch/arm/mach-s3c2410/pm.h b/arch/arm/mach-s3c2410/pm.h
index 7a5e714c7386..ffe197a119fb 100644
--- a/arch/arm/mach-s3c2410/pm.h
+++ b/arch/arm/mach-s3c2410/pm.h
@@ -34,13 +34,19 @@ extern unsigned long s3c_irqwake_eintmask;
34extern unsigned long s3c_irqwake_intallow; 34extern unsigned long s3c_irqwake_intallow;
35extern unsigned long s3c_irqwake_eintallow; 35extern unsigned long s3c_irqwake_eintallow;
36 36
37/* per-cpu sleep functions */
38
39extern void (*pm_cpu_prep)(void);
40extern void (*pm_cpu_sleep)(void);
41
37/* Flags for PM Control */ 42/* Flags for PM Control */
38 43
39extern unsigned long s3c_pm_flags; 44extern unsigned long s3c_pm_flags;
40 45
41/* from sleep.S */ 46/* from sleep.S */
42 47
43extern void s3c2410_cpu_suspend(unsigned long *saveblk); 48extern int s3c2410_cpu_save(unsigned long *saveblk);
49extern void s3c2410_cpu_suspend(void);
44extern void s3c2410_cpu_resume(void); 50extern void s3c2410_cpu_resume(void);
45 51
46extern unsigned long s3c2410_sleep_save_phys; 52extern unsigned long s3c2410_sleep_save_phys;
@@ -57,3 +63,11 @@ struct sleep_save {
57 63
58extern void s3c2410_pm_do_save(struct sleep_save *ptr, int count); 64extern void s3c2410_pm_do_save(struct sleep_save *ptr, int count);
59extern void s3c2410_pm_do_restore(struct sleep_save *ptr, int count); 65extern void s3c2410_pm_do_restore(struct sleep_save *ptr, int count);
66
67#ifdef CONFIG_PM
68extern int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state);
69extern int s3c24xx_irq_resume(struct sys_device *dev);
70#else
71#define s3c24xx_irq_suspend NULL
72#define s3c24xx_irq_resume NULL
73#endif
diff --git a/arch/arm/mach-s3c2410/s3c2410-dma.c b/arch/arm/mach-s3c2410/s3c2410-dma.c
new file mode 100644
index 000000000000..51e5098b32e8
--- /dev/null
+++ b/arch/arm/mach-s3c2410/s3c2410-dma.c
@@ -0,0 +1,158 @@
1/* linux/arch/arm/mach-s3c2410/s3c2410-dma.c
2 *
3 * (c) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C2410 DMA selection
7 *
8 * http://armlinux.simtec.co.uk/
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
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/sysdev.h>
18
19#include <asm/dma.h>
20#include <asm/arch/dma.h>
21#include "dma.h"
22
23#include "cpu.h"
24
25#include <asm/arch/regs-serial.h>
26#include <asm/arch/regs-gpio.h>
27#include <asm/arch/regs-ac97.h>
28#include <asm/arch/regs-mem.h>
29#include <asm/arch/regs-lcd.h>
30#include <asm/arch/regs-sdi.h>
31#include <asm/arch/regs-iis.h>
32#include <asm/arch/regs-spi.h>
33
34static struct s3c24xx_dma_map __initdata s3c2410_dma_mappings[] = {
35 [DMACH_XD0] = {
36 .name = "xdreq0",
37 .channels[0] = S3C2410_DCON_CH0_XDREQ0 | DMA_CH_VALID,
38 },
39 [DMACH_XD1] = {
40 .name = "xdreq1",
41 .channels[1] = S3C2410_DCON_CH1_XDREQ1 | DMA_CH_VALID,
42 },
43 [DMACH_SDI] = {
44 .name = "sdi",
45 .channels[0] = S3C2410_DCON_CH0_SDI | DMA_CH_VALID,
46 .channels[2] = S3C2410_DCON_CH2_SDI | DMA_CH_VALID,
47 .channels[3] = S3C2410_DCON_CH3_SDI | DMA_CH_VALID,
48 .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO,
49 .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO,
50 },
51 [DMACH_SPI0] = {
52 .name = "spi0",
53 .channels[1] = S3C2410_DCON_CH1_SPI | DMA_CH_VALID,
54 .hw_addr.to = S3C2410_PA_SPI + S3C2410_SPTDAT,
55 .hw_addr.from = S3C2410_PA_SPI + S3C2410_SPRDAT,
56 },
57 [DMACH_SPI1] = {
58 .name = "spi1",
59 .channels[3] = S3C2410_DCON_CH3_SPI | DMA_CH_VALID,
60 .hw_addr.to = S3C2410_PA_SPI + 0x20 + S3C2410_SPTDAT,
61 .hw_addr.from = S3C2410_PA_SPI + 0x20 + S3C2410_SPRDAT,
62 },
63 [DMACH_UART0] = {
64 .name = "uart0",
65 .channels[0] = S3C2410_DCON_CH0_UART0 | DMA_CH_VALID,
66 .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH,
67 .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH,
68 },
69 [DMACH_UART1] = {
70 .name = "uart1",
71 .channels[1] = S3C2410_DCON_CH1_UART1 | DMA_CH_VALID,
72 .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH,
73 .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH,
74 },
75 [DMACH_UART2] = {
76 .name = "uart2",
77 .channels[3] = S3C2410_DCON_CH3_UART2 | DMA_CH_VALID,
78 .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH,
79 .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH,
80 },
81 [DMACH_TIMER] = {
82 .name = "timer",
83 .channels[0] = S3C2410_DCON_CH0_TIMER | DMA_CH_VALID,
84 .channels[2] = S3C2410_DCON_CH2_TIMER | DMA_CH_VALID,
85 .channels[3] = S3C2410_DCON_CH3_TIMER | DMA_CH_VALID,
86 },
87 [DMACH_I2S_IN] = {
88 .name = "i2s-sdi",
89 .channels[1] = S3C2410_DCON_CH1_I2SSDI | DMA_CH_VALID,
90 .channels[2] = S3C2410_DCON_CH2_I2SSDI | DMA_CH_VALID,
91 .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO,
92 },
93 [DMACH_I2S_OUT] = {
94 .name = "i2s-sdo",
95 .channels[2] = S3C2410_DCON_CH2_I2SSDO | DMA_CH_VALID,
96 .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO,
97 },
98 [DMACH_USB_EP1] = {
99 .name = "usb-ep1",
100 .channels[0] = S3C2410_DCON_CH0_USBEP1 | DMA_CH_VALID,
101 },
102 [DMACH_USB_EP2] = {
103 .name = "usb-ep2",
104 .channels[1] = S3C2410_DCON_CH1_USBEP2 | DMA_CH_VALID,
105 },
106 [DMACH_USB_EP3] = {
107 .name = "usb-ep3",
108 .channels[2] = S3C2410_DCON_CH2_USBEP3 | DMA_CH_VALID,
109 },
110 [DMACH_USB_EP4] = {
111 .name = "usb-ep4",
112 .channels[3] =S3C2410_DCON_CH3_USBEP4 | DMA_CH_VALID,
113 },
114};
115
116static void s3c2410_dma_select(struct s3c2410_dma_chan *chan,
117 struct s3c24xx_dma_map *map)
118{
119 chan->dcon = map->channels[chan->number] & ~DMA_CH_VALID;
120}
121
122static struct s3c24xx_dma_selection __initdata s3c2410_dma_sel = {
123 .select = s3c2410_dma_select,
124 .dcon_mask = 7 << 24,
125 .map = s3c2410_dma_mappings,
126 .map_size = ARRAY_SIZE(s3c2410_dma_mappings),
127};
128
129static int s3c2410_dma_add(struct sys_device *sysdev)
130{
131 return s3c24xx_dma_init_map(&s3c2410_dma_sel);
132}
133
134static struct sysdev_driver s3c2410_dma_driver = {
135 .add = s3c2410_dma_add,
136};
137
138static int __init s3c2410_dma_init(void)
139{
140 return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_dma_driver);
141}
142
143arch_initcall(s3c2410_dma_init);
144
145/* S3C2442 DMA contains the same selection table as the S3C2410 */
146
147static struct sysdev_driver s3c2442_dma_driver = {
148 .add = s3c2410_dma_add,
149};
150
151static int __init s3c2442_dma_init(void)
152{
153 return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_dma_driver);
154}
155
156arch_initcall(s3c2442_dma_init);
157
158
diff --git a/arch/arm/mach-s3c2410/s3c2410-irq.c b/arch/arm/mach-s3c2410/s3c2410-irq.c
new file mode 100644
index 000000000000..c796c9c76e78
--- /dev/null
+++ b/arch/arm/mach-s3c2410/s3c2410-irq.c
@@ -0,0 +1,48 @@
1/* linux/arch/arm/mach-s3c2410/s3c2410-irq.c
2 *
3 * Copyright (c) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20*/
21
22#include <linux/init.h>
23#include <linux/module.h>
24#include <linux/interrupt.h>
25#include <linux/ioport.h>
26#include <linux/ptrace.h>
27#include <linux/sysdev.h>
28
29#include "cpu.h"
30#include "pm.h"
31
32static int s3c2410_irq_add(struct sys_device *sysdev)
33{
34 return 0;
35}
36
37static struct sysdev_driver s3c2410_irq_driver = {
38 .add = s3c2410_irq_add,
39 .suspend = s3c24xx_irq_suspend,
40 .resume = s3c24xx_irq_resume,
41};
42
43static int s3c2410_irq_init(void)
44{
45 return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_irq_driver);
46}
47
48arch_initcall(s3c2410_irq_init);
diff --git a/arch/arm/mach-s3c2410/s3c2410-pm.c b/arch/arm/mach-s3c2410/s3c2410-pm.c
new file mode 100644
index 000000000000..e51d76669512
--- /dev/null
+++ b/arch/arm/mach-s3c2410/s3c2410-pm.c
@@ -0,0 +1,120 @@
1/* linux/arch/arm/mach-s3c2410/s3c2410-pm.c
2 *
3 * Copyright (c) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C2410 (and compatible) Power Manager (Suspend-To-RAM) support
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21*/
22
23#include <linux/init.h>
24#include <linux/suspend.h>
25#include <linux/errno.h>
26#include <linux/time.h>
27#include <linux/sysdev.h>
28
29#include <asm/hardware.h>
30#include <asm/io.h>
31
32#include <asm/mach-types.h>
33
34#include <asm/arch/regs-gpio.h>
35
36#include "cpu.h"
37#include "pm.h"
38
39#ifdef CONFIG_S3C2410_PM_DEBUG
40extern void pm_dbg(const char *fmt, ...);
41#define DBG(fmt...) pm_dbg(fmt)
42#else
43#define DBG(fmt...) printk(KERN_DEBUG fmt)
44#endif
45
46static void s3c2410_pm_prepare(void)
47{
48 /* ensure at least GSTATUS3 has the resume address */
49
50 __raw_writel(virt_to_phys(s3c2410_cpu_resume), S3C2410_GSTATUS3);
51
52 DBG("GSTATUS3 0x%08x\n", __raw_readl(S3C2410_GSTATUS3));
53 DBG("GSTATUS4 0x%08x\n", __raw_readl(S3C2410_GSTATUS4));
54
55 if ( machine_is_aml_m5900() )
56 s3c2410_gpio_setpin(S3C2410_GPF2, 1);
57
58}
59
60int s3c2410_pm_resume(struct sys_device *dev)
61{
62 unsigned long tmp;
63
64 /* unset the return-from-sleep flag, to ensure reset */
65
66 tmp = __raw_readl(S3C2410_GSTATUS2);
67 tmp &= S3C2410_GSTATUS2_OFFRESET;
68 __raw_writel(tmp, S3C2410_GSTATUS2);
69
70 if ( machine_is_aml_m5900() )
71 s3c2410_gpio_setpin(S3C2410_GPF2, 0);
72
73 return 0;
74}
75
76static int s3c2410_pm_add(struct sys_device *dev)
77{
78 pm_cpu_prep = s3c2410_pm_prepare;
79 pm_cpu_sleep = s3c2410_cpu_suspend;
80
81 return 0;
82}
83
84static struct sysdev_driver s3c2410_pm_driver = {
85 .add = s3c2410_pm_add,
86 .resume = s3c2410_pm_resume,
87};
88
89/* register ourselves */
90
91static int __init s3c2410_pm_drvinit(void)
92{
93 return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_pm_driver);
94}
95
96arch_initcall(s3c2410_pm_drvinit);
97
98static struct sysdev_driver s3c2440_pm_driver = {
99 .add = s3c2410_pm_add,
100 .resume = s3c2410_pm_resume,
101};
102
103static int __init s3c2440_pm_drvinit(void)
104{
105 return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_pm_driver);
106}
107
108arch_initcall(s3c2440_pm_drvinit);
109
110static struct sysdev_driver s3c2442_pm_driver = {
111 .add = s3c2410_pm_add,
112 .resume = s3c2410_pm_resume,
113};
114
115static int __init s3c2442_pm_drvinit(void)
116{
117 return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_pm_driver);
118}
119
120arch_initcall(s3c2442_pm_drvinit);
diff --git a/arch/arm/mach-s3c2410/s3c2410-sleep.S b/arch/arm/mach-s3c2410/s3c2410-sleep.S
new file mode 100644
index 000000000000..9179a1024588
--- /dev/null
+++ b/arch/arm/mach-s3c2410/s3c2410-sleep.S
@@ -0,0 +1,68 @@
1/* linux/arch/arm/mach-s3c2410/s3c2410-sleep.S
2 *
3 * Copyright (c) 2004 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C2410 Power Manager (Suspend-To-RAM) support
7 *
8 * Based on PXA/SA1100 sleep code by:
9 * Nicolas Pitre, (c) 2002 Monta Vista Software Inc
10 * Cliff Brake, (c) 2001
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25*/
26
27#include <linux/linkage.h>
28#include <asm/assembler.h>
29#include <asm/hardware.h>
30#include <asm/arch/map.h>
31
32#include <asm/arch/regs-gpio.h>
33#include <asm/arch/regs-clock.h>
34#include <asm/arch/regs-mem.h>
35#include <asm/arch/regs-serial.h>
36
37 /* s3c2410_cpu_suspend
38 *
39 * put the cpu into sleep mode
40 */
41
42ENTRY(s3c2410_cpu_suspend)
43 @@ prepare cpu to sleep
44
45 ldr r4, =S3C2410_REFRESH
46 ldr r5, =S3C24XX_MISCCR
47 ldr r6, =S3C2410_CLKCON
48 ldr r7, [ r4 ] @ get REFRESH (and ensure in TLB)
49 ldr r8, [ r5 ] @ get MISCCR (and ensure in TLB)
50 ldr r9, [ r6 ] @ get CLKCON (and ensure in TLB)
51
52 orr r7, r7, #S3C2410_REFRESH_SELF @ SDRAM sleep command
53 orr r8, r8, #S3C2410_MISCCR_SDSLEEP @ SDRAM power-down signals
54 orr r9, r9, #S3C2410_CLKCON_POWER @ power down command
55
56 teq pc, #0 @ first as a trial-run to load cache
57 bl s3c2410_do_sleep
58 teq r0, r0 @ now do it for real
59 b s3c2410_do_sleep @
60
61 @@ align next bit of code to cache line
62 .align 8
63s3c2410_do_sleep:
64 streq r7, [ r4 ] @ SDRAM sleep command
65 streq r8, [ r5 ] @ SDRAM power-down config
66 streq r9, [ r6 ] @ CPU sleep
671: beq 1b
68 mov pc, r14
diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c
index a110cff9cf6b..183e4033ce61 100644
--- a/arch/arm/mach-s3c2410/s3c2410.c
+++ b/arch/arm/mach-s3c2410/s3c2410.c
@@ -8,17 +8,6 @@
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 *
12 * Modifications:
13 * 16-May-2003 BJD Created initial version
14 * 16-Aug-2003 BJD Fixed header files and copyright, added URL
15 * 05-Sep-2003 BJD Moved to kernel v2.6
16 * 18-Jan-2004 BJD Added serial port configuration
17 * 21-Aug-2004 BJD Added new struct s3c2410_board handler
18 * 28-Sep-2004 BJD Updates for new serial port bits
19 * 04-Nov-2004 BJD Updated UART configuration process
20 * 10-Jan-2005 BJD Removed s3c2410_clock_tick_rate
21 * 13-Aug-2005 DA Removed UART from initial I/O mappings
22*/ 11*/
23 12
24#include <linux/kernel.h> 13#include <linux/kernel.h>
diff --git a/arch/arm/mach-s3c2410/s3c2412-dma.c b/arch/arm/mach-s3c2410/s3c2412-dma.c
new file mode 100644
index 000000000000..171f3706d36d
--- /dev/null
+++ b/arch/arm/mach-s3c2410/s3c2412-dma.c
@@ -0,0 +1,160 @@
1/* linux/arch/arm/mach-s3c2410/s3c2412-dma.c
2 *
3 * (c) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C2412 DMA selection
7 *
8 * http://armlinux.simtec.co.uk/
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
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/sysdev.h>
18
19#include <asm/dma.h>
20#include <asm/arch/dma.h>
21#include <asm/io.h>
22
23#include "dma.h"
24#include "cpu.h"
25
26#include <asm/arch/regs-serial.h>
27#include <asm/arch/regs-gpio.h>
28#include <asm/arch/regs-ac97.h>
29#include <asm/arch/regs-mem.h>
30#include <asm/arch/regs-lcd.h>
31#include <asm/arch/regs-sdi.h>
32#include <asm/arch/regs-iis.h>
33#include <asm/arch/regs-spi.h>
34
35#define MAP(x) { (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID }
36
37static struct s3c24xx_dma_map __initdata s3c2412_dma_mappings[] = {
38 [DMACH_XD0] = {
39 .name = "xdreq0",
40 .channels = MAP(S3C2412_DMAREQSEL_XDREQ0),
41 },
42 [DMACH_XD1] = {
43 .name = "xdreq1",
44 .channels = MAP(S3C2412_DMAREQSEL_XDREQ1),
45 },
46 [DMACH_SDI] = {
47 .name = "sdi",
48 .channels = MAP(S3C2412_DMAREQSEL_SDI),
49 .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO,
50 .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO,
51 },
52 [DMACH_SPI0] = {
53 .name = "spi0",
54 .channels = MAP(S3C2412_DMAREQSEL_SPI0TX),
55 .hw_addr.to = S3C2410_PA_SPI + S3C2410_SPTDAT,
56 .hw_addr.from = S3C2410_PA_SPI + S3C2410_SPRDAT,
57 },
58 [DMACH_SPI1] = {
59 .name = "spi1",
60 .channels = MAP(S3C2412_DMAREQSEL_SPI1TX),
61 .hw_addr.to = S3C2410_PA_SPI + 0x20 + S3C2410_SPTDAT,
62 .hw_addr.from = S3C2410_PA_SPI + 0x20 + S3C2410_SPRDAT,
63 },
64 [DMACH_UART0] = {
65 .name = "uart0",
66 .channels = MAP(S3C2412_DMAREQSEL_UART0_0),
67 .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH,
68 .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH,
69 },
70 [DMACH_UART1] = {
71 .name = "uart1",
72 .channels = MAP(S3C2412_DMAREQSEL_UART1_0),
73 .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH,
74 .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH,
75 },
76 [DMACH_UART2] = {
77 .name = "uart2",
78 .channels = MAP(S3C2412_DMAREQSEL_UART2_0),
79 .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH,
80 .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH,
81 },
82 [DMACH_UART0_SRC2] = {
83 .name = "uart0",
84 .channels = MAP(S3C2412_DMAREQSEL_UART0_1),
85 .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH,
86 .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH,
87 },
88 [DMACH_UART1_SRC2] = {
89 .name = "uart1",
90 .channels = MAP(S3C2412_DMAREQSEL_UART1_1),
91 .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH,
92 .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH,
93 },
94 [DMACH_UART2_SRC2] = {
95 .name = "uart2",
96 .channels = MAP(S3C2412_DMAREQSEL_UART2_1),
97 .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH,
98 .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH,
99 },
100 [DMACH_TIMER] = {
101 .name = "timer",
102 .channels = MAP(S3C2412_DMAREQSEL_TIMER),
103 },
104 [DMACH_I2S_IN] = {
105 .name = "i2s-sdi",
106 .channels = MAP(S3C2412_DMAREQSEL_I2SRX),
107 .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO,
108 },
109 [DMACH_I2S_OUT] = {
110 .name = "i2s-sdo",
111 .channels = MAP(S3C2412_DMAREQSEL_I2STX),
112 .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO,
113 },
114 [DMACH_USB_EP1] = {
115 .name = "usb-ep1",
116 .channels = MAP(S3C2412_DMAREQSEL_USBEP1),
117 },
118 [DMACH_USB_EP2] = {
119 .name = "usb-ep2",
120 .channels = MAP(S3C2412_DMAREQSEL_USBEP2),
121 },
122 [DMACH_USB_EP3] = {
123 .name = "usb-ep3",
124 .channels = MAP(S3C2412_DMAREQSEL_USBEP3),
125 },
126 [DMACH_USB_EP4] = {
127 .name = "usb-ep4",
128 .channels = MAP(S3C2412_DMAREQSEL_USBEP4),
129 },
130};
131
132static void s3c2412_dma_select(struct s3c2410_dma_chan *chan,
133 struct s3c24xx_dma_map *map)
134{
135 writel(chan->regs + S3C2412_DMA_DMAREQSEL,
136 map->channels[0] | S3C2412_DMAREQSEL_HW);
137}
138
139static struct s3c24xx_dma_selection __initdata s3c2412_dma_sel = {
140 .select = s3c2412_dma_select,
141 .dcon_mask = 0,
142 .map = s3c2412_dma_mappings,
143 .map_size = ARRAY_SIZE(s3c2412_dma_mappings),
144};
145
146static int s3c2412_dma_add(struct sys_device *sysdev)
147{
148 return s3c24xx_dma_init_map(&s3c2412_dma_sel);
149}
150
151static struct sysdev_driver s3c2412_dma_driver = {
152 .add = s3c2412_dma_add,
153};
154
155static int __init s3c2412_dma_init(void)
156{
157 return sysdev_driver_register(&s3c2412_sysclass, &s3c2412_dma_driver);
158}
159
160arch_initcall(s3c2412_dma_init);
diff --git a/arch/arm/mach-s3c2410/s3c2412-irq.c b/arch/arm/mach-s3c2410/s3c2412-irq.c
index c80ec93dfea9..7f741547658f 100644
--- a/arch/arm/mach-s3c2410/s3c2412-irq.c
+++ b/arch/arm/mach-s3c2410/s3c2412-irq.c
@@ -37,6 +37,7 @@
37 37
38#include "cpu.h" 38#include "cpu.h"
39#include "irq.h" 39#include "irq.h"
40#include "pm.h"
40 41
41/* the s3c2412 changes the behaviour of IRQ_EINT0 through IRQ_EINT3 by 42/* the s3c2412 changes the behaviour of IRQ_EINT0 through IRQ_EINT3 by
42 * having them turn up in both the INT* and the EINT* registers. Whilst 43 * having them turn up in both the INT* and the EINT* registers. Whilst
@@ -120,6 +121,8 @@ static int s3c2412_irq_add(struct sys_device *sysdev)
120 121
121static struct sysdev_driver s3c2412_irq_driver = { 122static struct sysdev_driver s3c2412_irq_driver = {
122 .add = s3c2412_irq_add, 123 .add = s3c2412_irq_add,
124 .suspend = s3c24xx_irq_suspend,
125 .resume = s3c24xx_irq_resume,
123}; 126};
124 127
125static int s3c2412_irq_init(void) 128static int s3c2412_irq_init(void)
diff --git a/arch/arm/mach-s3c2410/s3c2412-pm.c b/arch/arm/mach-s3c2410/s3c2412-pm.c
new file mode 100644
index 000000000000..19b63322d259
--- /dev/null
+++ b/arch/arm/mach-s3c2410/s3c2412-pm.c
@@ -0,0 +1,128 @@
1/* linux/arch/arm/mach-s3c2410/s3c2412-pm.c
2 *
3 * Copyright (c) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * http://armlinux.simtec.co.uk/.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/kernel.h>
14#include <linux/types.h>
15#include <linux/interrupt.h>
16#include <linux/list.h>
17#include <linux/timer.h>
18#include <linux/init.h>
19#include <linux/sysdev.h>
20#include <linux/platform_device.h>
21
22#include <asm/hardware.h>
23#include <asm/io.h>
24#include <asm/irq.h>
25
26#include <asm/arch/regs-power.h>
27#include <asm/arch/regs-gpioj.h>
28#include <asm/arch/regs-gpio.h>
29#include <asm/arch/regs-dsc.h>
30
31#include "cpu.h"
32#include "pm.h"
33
34#include "s3c2412.h"
35
36static void s3c2412_cpu_suspend(void)
37{
38 unsigned long tmp;
39
40 /* set our standby method to sleep */
41
42 tmp = __raw_readl(S3C2412_PWRCFG);
43 tmp |= S3C2412_PWRCFG_STANDBYWFI_SLEEP;
44 __raw_writel(tmp, S3C2412_PWRCFG);
45
46 /* issue the standby signal into the pm unit. Note, we
47 * issue a write-buffer drain just in case */
48
49 tmp = 0;
50
51 asm("b 1f\n\t"
52 ".align 5\n\t"
53 "1:\n\t"
54 "mcr p15, 0, %0, c7, c10, 4\n\t"
55 "mcr p15, 0, %0, c7, c0, 4" :: "r" (tmp));
56
57 /* we should never get past here */
58
59 panic("sleep resumed to originator?");
60}
61
62static void s3c2412_pm_prepare(void)
63{
64}
65
66static int s3c2412_pm_add(struct sys_device *sysdev)
67{
68 pm_cpu_prep = s3c2412_pm_prepare;
69 pm_cpu_sleep = s3c2412_cpu_suspend;
70
71 return 0;
72}
73
74static struct sleep_save s3c2412_sleep[] = {
75 SAVE_ITEM(S3C2412_DSC0),
76 SAVE_ITEM(S3C2412_DSC1),
77 SAVE_ITEM(S3C2413_GPJDAT),
78 SAVE_ITEM(S3C2413_GPJCON),
79 SAVE_ITEM(S3C2413_GPJUP),
80
81 /* save the PWRCFG to get back to original sleep method */
82
83 SAVE_ITEM(S3C2412_PWRCFG),
84
85 /* save the sleep configuration anyway, just in case these
86 * get damaged during wakeup */
87
88 SAVE_ITEM(S3C2412_GPBSLPCON),
89 SAVE_ITEM(S3C2412_GPCSLPCON),
90 SAVE_ITEM(S3C2412_GPDSLPCON),
91 SAVE_ITEM(S3C2412_GPESLPCON),
92 SAVE_ITEM(S3C2412_GPFSLPCON),
93 SAVE_ITEM(S3C2412_GPGSLPCON),
94 SAVE_ITEM(S3C2412_GPHSLPCON),
95 SAVE_ITEM(S3C2413_GPJSLPCON),
96};
97
98static int s3c2412_pm_suspend(struct sys_device *dev, pm_message_t state)
99{
100 s3c2410_pm_do_save(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
101 return 0;
102}
103
104static int s3c2412_pm_resume(struct sys_device *dev)
105{
106 unsigned long tmp;
107
108 tmp = __raw_readl(S3C2412_PWRCFG);
109 tmp &= ~S3C2412_PWRCFG_STANDBYWFI_MASK;
110 tmp |= S3C2412_PWRCFG_STANDBYWFI_IDLE;
111 __raw_writel(tmp, S3C2412_PWRCFG);
112
113 s3c2410_pm_do_restore(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
114 return 0;
115}
116
117static struct sysdev_driver s3c2412_pm_driver = {
118 .add = s3c2412_pm_add,
119 .suspend = s3c2412_pm_suspend,
120 .resume = s3c2412_pm_resume,
121};
122
123static __init int s3c2412_pm_init(void)
124{
125 return sysdev_driver_register(&s3c2412_sysclass, &s3c2412_pm_driver);
126}
127
128arch_initcall(s3c2412_pm_init);
diff --git a/arch/arm/mach-s3c2410/s3c2412.c b/arch/arm/mach-s3c2410/s3c2412.c
index 2d163f7600be..e76431c41461 100644
--- a/arch/arm/mach-s3c2410/s3c2412.c
+++ b/arch/arm/mach-s3c2410/s3c2412.c
@@ -8,17 +8,6 @@
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 *
12 * Modifications:
13 * 16-May-2003 BJD Created initial version
14 * 16-Aug-2003 BJD Fixed header files and copyright, added URL
15 * 05-Sep-2003 BJD Moved to kernel v2.6
16 * 18-Jan-2004 BJD Added serial port configuration
17 * 21-Aug-2004 BJD Added new struct s3c2410_board handler
18 * 28-Sep-2004 BJD Updates for new serial port bits
19 * 04-Nov-2004 BJD Updated UART configuration process
20 * 10-Jan-2005 BJD Removed s3c2410_clock_tick_rate
21 * 13-Aug-2005 DA Removed UART from initial I/O mappings
22*/ 11*/
23 12
24#include <linux/kernel.h> 13#include <linux/kernel.h>
@@ -56,6 +45,13 @@
56 45
57#ifndef CONFIG_CPU_S3C2412_ONLY 46#ifndef CONFIG_CPU_S3C2412_ONLY
58void __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO; 47void __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO;
48
49static inline void s3c2412_init_gpio2(void)
50{
51 s3c24xx_va_gpio2 = S3C24XX_VA_GPIO + 0x10;
52}
53#else
54#define s3c2412_init_gpio2() do { } while(0)
59#endif 55#endif
60 56
61/* Initial IO mappings */ 57/* Initial IO mappings */
@@ -76,6 +72,7 @@ void __init s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no)
76 72
77 /* rename devices that are s3c2412/s3c2413 specific */ 73 /* rename devices that are s3c2412/s3c2413 specific */
78 s3c_device_sdi.name = "s3c2412-sdi"; 74 s3c_device_sdi.name = "s3c2412-sdi";
75 s3c_device_lcd.name = "s3c2412-lcd";
79 s3c_device_nand.name = "s3c2412-nand"; 76 s3c_device_nand.name = "s3c2412-nand";
80} 77}
81 78
@@ -110,7 +107,7 @@ void __init s3c2412_map_io(struct map_desc *mach_desc, int mach_size)
110{ 107{
111 /* move base of IO */ 108 /* move base of IO */
112 109
113 s3c24xx_va_gpio2 = S3C24XX_VA_GPIO + 0x10; 110 s3c2412_init_gpio2();
114 111
115 /* set our idle function */ 112 /* set our idle function */
116 113
@@ -161,48 +158,8 @@ void __init s3c2412_init_clocks(int xtal)
161 * as a driver which may support both 2410 and 2440 may try and use it. 158 * as a driver which may support both 2410 and 2440 may try and use it.
162*/ 159*/
163 160
164#ifdef CONFIG_PM
165static struct sleep_save s3c2412_sleep[] = {
166 SAVE_ITEM(S3C2412_DSC0),
167 SAVE_ITEM(S3C2412_DSC1),
168 SAVE_ITEM(S3C2413_GPJDAT),
169 SAVE_ITEM(S3C2413_GPJCON),
170 SAVE_ITEM(S3C2413_GPJUP),
171
172 /* save the sleep configuration anyway, just in case these
173 * get damaged during wakeup */
174
175 SAVE_ITEM(S3C2412_GPBSLPCON),
176 SAVE_ITEM(S3C2412_GPCSLPCON),
177 SAVE_ITEM(S3C2412_GPDSLPCON),
178 SAVE_ITEM(S3C2412_GPESLPCON),
179 SAVE_ITEM(S3C2412_GPFSLPCON),
180 SAVE_ITEM(S3C2412_GPGSLPCON),
181 SAVE_ITEM(S3C2412_GPHSLPCON),
182 SAVE_ITEM(S3C2413_GPJSLPCON),
183};
184
185static int s3c2412_suspend(struct sys_device *dev, pm_message_t state)
186{
187 s3c2410_pm_do_save(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
188 return 0;
189}
190
191static int s3c2412_resume(struct sys_device *dev)
192{
193 s3c2410_pm_do_restore(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
194 return 0;
195}
196
197#else
198#define s3c2412_suspend NULL
199#define s3c2412_resume NULL
200#endif
201
202struct sysdev_class s3c2412_sysclass = { 161struct sysdev_class s3c2412_sysclass = {
203 set_kset_name("s3c2412-core"), 162 set_kset_name("s3c2412-core"),
204 .suspend = s3c2412_suspend,
205 .resume = s3c2412_resume
206}; 163};
207 164
208static int __init s3c2412_core_init(void) 165static int __init s3c2412_core_init(void)
diff --git a/arch/arm/mach-s3c2410/s3c2440-dma.c b/arch/arm/mach-s3c2410/s3c2440-dma.c
new file mode 100644
index 000000000000..11e109c84a15
--- /dev/null
+++ b/arch/arm/mach-s3c2410/s3c2440-dma.c
@@ -0,0 +1,164 @@
1/* linux/arch/arm/mach-s3c2410/s3c2440-dma.c
2 *
3 * (c) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C2440 DMA selection
7 *
8 * http://armlinux.simtec.co.uk/
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
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/sysdev.h>
18
19#include <asm/dma.h>
20#include <asm/arch/dma.h>
21#include "dma.h"
22
23#include "cpu.h"
24
25#include <asm/arch/regs-serial.h>
26#include <asm/arch/regs-gpio.h>
27#include <asm/arch/regs-ac97.h>
28#include <asm/arch/regs-mem.h>
29#include <asm/arch/regs-lcd.h>
30#include <asm/arch/regs-sdi.h>
31#include <asm/arch/regs-iis.h>
32#include <asm/arch/regs-spi.h>
33
34static struct s3c24xx_dma_map __initdata s3c2440_dma_mappings[] = {
35 [DMACH_XD0] = {
36 .name = "xdreq0",
37 .channels[0] = S3C2410_DCON_CH0_XDREQ0 | DMA_CH_VALID,
38 },
39 [DMACH_XD1] = {
40 .name = "xdreq1",
41 .channels[1] = S3C2410_DCON_CH1_XDREQ1 | DMA_CH_VALID,
42 },
43 [DMACH_SDI] = {
44 .name = "sdi",
45 .channels[0] = S3C2410_DCON_CH0_SDI | DMA_CH_VALID,
46 .channels[1] = S3C2440_DCON_CH1_SDI | DMA_CH_VALID,
47 .channels[2] = S3C2410_DCON_CH2_SDI | DMA_CH_VALID,
48 .channels[3] = S3C2410_DCON_CH3_SDI | DMA_CH_VALID,
49 .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO,
50 .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO,
51 },
52 [DMACH_SPI0] = {
53 .name = "spi0",
54 .channels[1] = S3C2410_DCON_CH1_SPI | DMA_CH_VALID,
55 .hw_addr.to = S3C2410_PA_SPI + S3C2410_SPTDAT,
56 .hw_addr.from = S3C2410_PA_SPI + S3C2410_SPRDAT,
57 },
58 [DMACH_SPI1] = {
59 .name = "spi1",
60 .channels[3] = S3C2410_DCON_CH3_SPI | DMA_CH_VALID,
61 .hw_addr.to = S3C2410_PA_SPI + 0x20 + S3C2410_SPTDAT,
62 .hw_addr.from = S3C2410_PA_SPI + 0x20 + S3C2410_SPRDAT,
63 },
64 [DMACH_UART0] = {
65 .name = "uart0",
66 .channels[0] = S3C2410_DCON_CH0_UART0 | DMA_CH_VALID,
67 .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH,
68 .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH,
69 },
70 [DMACH_UART1] = {
71 .name = "uart1",
72 .channels[1] = S3C2410_DCON_CH1_UART1 | DMA_CH_VALID,
73 .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH,
74 .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH,
75 },
76 [DMACH_UART2] = {
77 .name = "uart2",
78 .channels[3] = S3C2410_DCON_CH3_UART2 | DMA_CH_VALID,
79 .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH,
80 .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH,
81 },
82 [DMACH_TIMER] = {
83 .name = "timer",
84 .channels[0] = S3C2410_DCON_CH0_TIMER | DMA_CH_VALID,
85 .channels[2] = S3C2410_DCON_CH2_TIMER | DMA_CH_VALID,
86 .channels[3] = S3C2410_DCON_CH3_TIMER | DMA_CH_VALID,
87 },
88 [DMACH_I2S_IN] = {
89 .name = "i2s-sdi",
90 .channels[1] = S3C2410_DCON_CH1_I2SSDI | DMA_CH_VALID,
91 .channels[2] = S3C2410_DCON_CH2_I2SSDI | DMA_CH_VALID,
92 .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO,
93 },
94 [DMACH_I2S_OUT] = {
95 .name = "i2s-sdo",
96 .channels[0] = S3C2440_DCON_CH0_I2SSDO | DMA_CH_VALID,
97 .channels[2] = S3C2410_DCON_CH2_I2SSDO | DMA_CH_VALID,
98 .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO,
99 },
100 [DMACH_PCM_IN] = {
101 .name = "pcm-in",
102 .channels[0] = S3C2440_DCON_CH0_PCMIN | DMA_CH_VALID,
103 .channels[2] = S3C2440_DCON_CH2_PCMIN | DMA_CH_VALID,
104 .hw_addr.from = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA,
105 },
106 [DMACH_PCM_OUT] = {
107 .name = "pcm-out",
108 .channels[1] = S3C2440_DCON_CH1_PCMOUT | DMA_CH_VALID,
109 .channels[3] = S3C2440_DCON_CH3_PCMOUT | DMA_CH_VALID,
110 .hw_addr.to = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA,
111 },
112 [DMACH_MIC_IN] = {
113 .name = "mic-in",
114 .channels[2] = S3C2440_DCON_CH2_MICIN | DMA_CH_VALID,
115 .channels[3] = S3C2440_DCON_CH3_MICIN | DMA_CH_VALID,
116 .hw_addr.from = S3C2440_PA_AC97 + S3C_AC97_MIC_DATA,
117 },
118 [DMACH_USB_EP1] = {
119 .name = "usb-ep1",
120 .channels[0] = S3C2410_DCON_CH0_USBEP1 | DMA_CH_VALID,
121 },
122 [DMACH_USB_EP2] = {
123 .name = "usb-ep2",
124 .channels[1] = S3C2410_DCON_CH1_USBEP2 | DMA_CH_VALID,
125 },
126 [DMACH_USB_EP3] = {
127 .name = "usb-ep3",
128 .channels[2] = S3C2410_DCON_CH2_USBEP3 | DMA_CH_VALID,
129 },
130 [DMACH_USB_EP4] = {
131 .name = "usb-ep4",
132 .channels[3] = S3C2410_DCON_CH3_USBEP4 | DMA_CH_VALID,
133 },
134};
135
136static void s3c2440_dma_select(struct s3c2410_dma_chan *chan,
137 struct s3c24xx_dma_map *map)
138{
139 chan->dcon = map->channels[chan->number] & ~DMA_CH_VALID;
140}
141
142static struct s3c24xx_dma_selection __initdata s3c2440_dma_sel = {
143 .select = s3c2440_dma_select,
144 .dcon_mask = 7 << 24,
145 .map = s3c2440_dma_mappings,
146 .map_size = ARRAY_SIZE(s3c2440_dma_mappings),
147};
148
149static int s3c2440_dma_add(struct sys_device *sysdev)
150{
151 return s3c24xx_dma_init_map(&s3c2440_dma_sel);
152}
153
154static struct sysdev_driver s3c2440_dma_driver = {
155 .add = s3c2440_dma_add,
156};
157
158static int __init s3c2440_dma_init(void)
159{
160 return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_dma_driver);
161}
162
163arch_initcall(s3c2440_dma_init);
164
diff --git a/arch/arm/mach-s3c2410/s3c2440-dsc.c b/arch/arm/mach-s3c2410/s3c2440-dsc.c
index 16fa2a3b38fa..c92ea66ba45e 100644
--- a/arch/arm/mach-s3c2410/s3c2440-dsc.c
+++ b/arch/arm/mach-s3c2410/s3c2440-dsc.c
@@ -8,11 +8,6 @@
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 *
12 * Modifications:
13 * 29-Aug-2004 BJD Start of drive-strength control
14 * 09-Nov-2004 BJD Added symbol export
15 * 11-Jan-2005 BJD Include fix
16*/ 11*/
17 12
18#include <linux/kernel.h> 13#include <linux/kernel.h>
diff --git a/arch/arm/mach-s3c2410/s3c2440-irq.c b/arch/arm/mach-s3c2410/s3c2440-irq.c
index 1667ba1fa43d..fc08febe2e54 100644
--- a/arch/arm/mach-s3c2410/s3c2440-irq.c
+++ b/arch/arm/mach-s3c2410/s3c2440-irq.c
@@ -119,7 +119,7 @@ static int s3c2440_irq_add(struct sys_device *sysdev)
119} 119}
120 120
121static struct sysdev_driver s3c2440_irq_driver = { 121static struct sysdev_driver s3c2440_irq_driver = {
122 .add = s3c2440_irq_add, 122 .add = s3c2440_irq_add,
123}; 123};
124 124
125static int s3c2440_irq_init(void) 125static int s3c2440_irq_init(void)
diff --git a/arch/arm/mach-s3c2410/s3c244x-irq.c b/arch/arm/mach-s3c2410/s3c244x-irq.c
index 44c5affa9b89..0d13546c3500 100644
--- a/arch/arm/mach-s3c2410/s3c244x-irq.c
+++ b/arch/arm/mach-s3c2410/s3c244x-irq.c
@@ -120,7 +120,9 @@ static int s3c244x_irq_add(struct sys_device *sysdev)
120} 120}
121 121
122static struct sysdev_driver s3c2440_irq_driver = { 122static struct sysdev_driver s3c2440_irq_driver = {
123 .add = s3c244x_irq_add, 123 .add = s3c244x_irq_add,
124 .suspend = s3c24xx_irq_suspend,
125 .resume = s3c24xx_irq_resume,
124}; 126};
125 127
126static int s3c2440_irq_init(void) 128static int s3c2440_irq_init(void)
@@ -131,9 +133,12 @@ static int s3c2440_irq_init(void)
131arch_initcall(s3c2440_irq_init); 133arch_initcall(s3c2440_irq_init);
132 134
133static struct sysdev_driver s3c2442_irq_driver = { 135static struct sysdev_driver s3c2442_irq_driver = {
134 .add = s3c244x_irq_add, 136 .add = s3c244x_irq_add,
137 .suspend = s3c24xx_irq_suspend,
138 .resume = s3c24xx_irq_resume,
135}; 139};
136 140
141
137static int s3c2442_irq_init(void) 142static int s3c2442_irq_init(void)
138{ 143{
139 return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_irq_driver); 144 return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_irq_driver);
diff --git a/arch/arm/mach-s3c2410/sleep.S b/arch/arm/mach-s3c2410/sleep.S
index a7561a79fc82..2018c2e1dcc5 100644
--- a/arch/arm/mach-s3c2410/sleep.S
+++ b/arch/arm/mach-s3c2410/sleep.S
@@ -41,15 +41,25 @@
41 41
42 .text 42 .text
43 43
44 /* s3c2410_cpu_suspend 44 /* s3c2410_cpu_save
45 * 45 *
46 * put the cpu into sleep mode 46 * save enough of the CPU state to allow us to re-start
47 * pm.c code. as we store items like the sp/lr, we will
48 * end up returning from this function when the cpu resumes
49 * so the return value is set to mark this.
50 *
51 * This arangement means we avoid having to flush the cache
52 * from this code.
47 * 53 *
48 * entry: 54 * entry:
49 * r0 = sleep save block 55 * r0 = pointer to save block
56 *
57 * exit:
58 * r0 = 0 => we stored everything
59 * 1 => resumed from sleep
50 */ 60 */
51 61
52ENTRY(s3c2410_cpu_suspend) 62ENTRY(s3c2410_cpu_save)
53 stmfd sp!, { r4 - r12, lr } 63 stmfd sp!, { r4 - r12, lr }
54 64
55 @@ store co-processor registers 65 @@ store co-processor registers
@@ -62,44 +72,14 @@ ENTRY(s3c2410_cpu_suspend)
62 72
63 stmia r0, { r4 - r13 } 73 stmia r0, { r4 - r13 }
64 74
65 @@ flush the caches to ensure everything is back out to 75 mov r0, #0
66 @@ SDRAM before the core powers down 76 ldmfd sp, { r4 - r12, pc }
67
68#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
69 bl arm920_flush_kern_cache_all
70#endif
71
72 @@ prepare cpu to sleep
73
74 ldr r4, =S3C2410_REFRESH
75 ldr r5, =S3C24XX_MISCCR
76 ldr r6, =S3C2410_CLKCON
77 ldr r7, [ r4 ] @ get REFRESH (and ensure in TLB)
78 ldr r8, [ r5 ] @ get MISCCR (and ensure in TLB)
79 ldr r9, [ r6 ] @ get CLKCON (and ensure in TLB)
80
81 orr r7, r7, #S3C2410_REFRESH_SELF @ SDRAM sleep command
82 orr r8, r8, #S3C2410_MISCCR_SDSLEEP @ SDRAM power-down signals
83 orr r9, r9, #S3C2410_CLKCON_POWER @ power down command
84
85 teq pc, #0 @ first as a trial-run to load cache
86 bl s3c2410_do_sleep
87 teq r0, r0 @ now do it for real
88 b s3c2410_do_sleep @
89
90 @@ align next bit of code to cache line
91 .align 8
92s3c2410_do_sleep:
93 streq r7, [ r4 ] @ SDRAM sleep command
94 streq r8, [ r5 ] @ SDRAM power-down config
95 streq r9, [ r6 ] @ CPU sleep
961: beq 1b
97 mov pc, r14
98 77
99 @@ return to the caller, after having the MMU 78 @@ return to the caller, after having the MMU
100 @@ turned on, this restores the last bits from the 79 @@ turned on, this restores the last bits from the
101 @@ stack 80 @@ stack
102resume_with_mmu: 81resume_with_mmu:
82 mov r0, #1
103 ldmfd sp!, { r4 - r12, pc } 83 ldmfd sp!, { r4 - r12, pc }
104 84
105 .ltorg 85 .ltorg
diff --git a/arch/arm/mach-s3c2410/usb-simtec.c b/arch/arm/mach-s3c2410/usb-simtec.c
index 6b22d8f0a00d..c635efa7cd31 100644
--- a/arch/arm/mach-s3c2410/usb-simtec.c
+++ b/arch/arm/mach-s3c2410/usb-simtec.c
@@ -10,12 +10,6 @@
10 * This program is free software; you can redistribute it and/or modify 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 11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
13 *
14 * Modifications:
15 * 14-Sep-2004 BJD Created
16 * 18-Oct-2004 BJD Cleanups, and added code to report OC cleared
17 * 09-Aug-2005 BJD Renamed s3c2410_report_oc to s3c2410_usb_report_oc
18 * 09-Aug-2005 BJD Ports powered only if both are enabled
19*/ 13*/
20 14
21#define DEBUG 15#define DEBUG