diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-28 17:40:39 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-28 17:40:39 -0400 |
commit | ebdea46fecae40c4d7effcd33f40918a37a1df4b (patch) | |
tree | e4312bf7f1f3d184738963a0ec300aa9fdfd55c1 /arch/arm/mach-s3c2410 | |
parent | fecf3404f4aba6d0edeba31eeb018cbb6326dff2 (diff) | |
parent | 250d375d1da45a5e08ab8baf5eaa7eb258afd82b (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')
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 | ||
3 | menu "S3C24XX Implementations" | 3 | menu "S3C24XX Implementations" |
4 | 4 | ||
5 | config 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 | |||
5 | config MACH_ANUBIS | 12 | config 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 | ||
136 | config MACH_VSTMS | ||
137 | bool "VMSTMS" | ||
138 | select CPU_S3C2412 | ||
139 | help | ||
140 | Say Y here if you are using an VSTMS board | ||
141 | |||
129 | endmenu | 142 | endmenu |
130 | 143 | ||
131 | config S3C2410_CLOCK | 144 | config 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 | ||
149 | config S3C2410_PM | ||
150 | bool | ||
151 | depends on CONFIG_PM | ||
152 | help | ||
153 | Power Management code common to S3C2410 and better | ||
154 | |||
155 | config 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 | |||
136 | config CPU_S3C2410 | 162 | config 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 | ||
179 | config 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 | |||
152 | config CPU_S3C2412 | 186 | config 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 | ||
257 | config PM_SIMTEC | 293 | config 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 | ||
262 | config S3C2410_LOWLEVEL_UART_PORT | 298 | config 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 | |||
9 | obj-m := | 9 | obj-m := |
10 | obj-n := | 10 | obj-n := |
11 | obj- := | 11 | obj- := |
12 | obj-dma-y := | ||
13 | obj-dma-n := | ||
12 | 14 | ||
13 | # DMA | 15 | # DMA |
14 | obj-$(CONFIG_S3C2410_DMA) += dma.o | 16 | obj-$(CONFIG_S3C2410_DMA) += dma.o |
@@ -20,6 +22,10 @@ obj-$(CONFIG_CPU_S3C2400) += s3c2400-gpio.o | |||
20 | 22 | ||
21 | obj-$(CONFIG_CPU_S3C2410) += s3c2410.o | 23 | obj-$(CONFIG_CPU_S3C2410) += s3c2410.o |
22 | obj-$(CONFIG_CPU_S3C2410) += s3c2410-gpio.o | 24 | obj-$(CONFIG_CPU_S3C2410) += s3c2410-gpio.o |
25 | obj-$(CONFIG_CPU_S3C2410) += s3c2410-irq.o | ||
26 | |||
27 | obj-$(CONFIG_S3C2410_PM) += s3c2410-pm.o s3c2410-sleep.o | ||
28 | obj-$(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 | |||
30 | obj-$(CONFIG_CPU_S3C2412) += s3c2412.o | 36 | obj-$(CONFIG_CPU_S3C2412) += s3c2412.o |
31 | obj-$(CONFIG_CPU_S3C2412) += s3c2412-irq.o | 37 | obj-$(CONFIG_CPU_S3C2412) += s3c2412-irq.o |
32 | obj-$(CONFIG_CPU_S3C2412) += s3c2412-clock.o | 38 | obj-$(CONFIG_CPU_S3C2412) += s3c2412-clock.o |
39 | obj-dma-$(CONFIG_CPU_S3C2412) += s3c2412-dma.o | ||
40 | |||
41 | obj-$(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 | |||
47 | obj-$(CONFIG_CPU_S3C2440) += s3c2440-irq.o | 56 | obj-$(CONFIG_CPU_S3C2440) += s3c2440-irq.o |
48 | obj-$(CONFIG_CPU_S3C2440) += s3c2440-clock.o | 57 | obj-$(CONFIG_CPU_S3C2440) += s3c2440-clock.o |
49 | obj-$(CONFIG_CPU_S3C2440) += s3c2410-gpio.o | 58 | obj-$(CONFIG_CPU_S3C2440) += s3c2410-gpio.o |
59 | obj-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 | ||
58 | obj-$(CONFIG_BAST_PC104_IRQ) += bast-irq.o | 68 | obj-$(CONFIG_BAST_PC104_IRQ) += bast-irq.o |
59 | 69 | ||
70 | # merge in dma objects | ||
71 | |||
72 | obj-y += $(obj-dma-y) | ||
73 | |||
60 | # machine specific support | 74 | # machine specific support |
61 | 75 | ||
76 | obj-$(CONFIG_MACH_AML_M5900) += mach-amlm5900.o | ||
62 | obj-$(CONFIG_MACH_ANUBIS) += mach-anubis.o | 77 | obj-$(CONFIG_MACH_ANUBIS) += mach-anubis.o |
63 | obj-$(CONFIG_MACH_OSIRIS) += mach-osiris.o | 78 | obj-$(CONFIG_MACH_OSIRIS) += mach-osiris.o |
64 | obj-$(CONFIG_ARCH_BAST) += mach-bast.o usb-simtec.o | 79 | obj-$(CONFIG_ARCH_BAST) += mach-bast.o usb-simtec.o |
@@ -71,5 +86,6 @@ obj-$(CONFIG_MACH_VR1000) += mach-vr1000.o usb-simtec.o | |||
71 | obj-$(CONFIG_MACH_RX3715) += mach-rx3715.o | 86 | obj-$(CONFIG_MACH_RX3715) += mach-rx3715.o |
72 | obj-$(CONFIG_MACH_OTOM) += mach-otom.o | 87 | obj-$(CONFIG_MACH_OTOM) += mach-otom.o |
73 | obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o | 88 | obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o |
89 | obj-$(CONFIG_MACH_VSTMS) += mach-vstms.o | ||
74 | 90 | ||
75 | obj-$(CONFIG_MACH_SMDK) += common-smdk.o \ No newline at end of file | 91 | obj-$(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 */ |
59 | static void __iomem *dma_base; | 42 | static void __iomem *dma_base; |
60 | static kmem_cache_t *dma_kmem; | 43 | static kmem_cache_t *dma_kmem; |
61 | 44 | ||
45 | struct s3c24xx_dma_selection dma_sel; | ||
46 | |||
62 | /* dma channel state information */ | 47 | /* dma channel state information */ |
63 | struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS]; | 48 | struct 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) \ | 138 | static 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 | |||
145 | static 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 | |||
321 | s3c2410_dma_buffdone(struct s3c2410_dma_chan *chan, struct s3c2410_dma_buf *buf, | 313 | s3c2410_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) | |||
460 | int s3c2410_dma_enqueue(unsigned int channel, void *id, | 453 | int 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) | |||
562 | static inline void | 556 | static inline void |
563 | s3c2410_dma_lastxfer(struct s3c2410_dma_chan *chan) | 557 | s3c2410_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 | ||
726 | static 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 | ||
734 | int s3c2410_dma_request(unsigned int channel, struct s3c2410_dma_client *client, | 733 | int 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 | ||
810 | int s3c2410_dma_free(dmach_t channel, struct s3c2410_dma_client *client) | 804 | int 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 | ||
849 | static int s3c2410_dma_dostop(struct s3c2410_dma_chan *chan) | 847 | static 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) | |||
997 | int | 995 | int |
998 | s3c2410_dma_ctrl(dmach_t channel, enum s3c2410_chan_op op) | 996 | s3c2410_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 | ||
1087 | int s3c2410_dma_setflags(dmach_t channel, unsigned int flags) | 1093 | int 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 | ||
1107 | int s3c2410_dma_set_opfn(dmach_t channel, s3c2410_dma_opfn_t rtn) | 1114 | int 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 | ||
1122 | int s3c2410_dma_set_buffdone_fn(dmach_t channel, s3c2410_dma_cbfn_t rtn) | 1130 | int 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 | ||
1201 | int s3c2410_dma_getposition(dmach_t channel, dma_addr_t *src, dma_addr_t *dst) | 1211 | int 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 | ||
1255 | static struct sysdev_class dma_sysclass = { | 1266 | struct 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 | ||
1271 | static int __init s3c2410_init_dma(void) | 1281 | static 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); | 1350 | core_initcall(s3c2410_init_dma); |
1351 | |||
1352 | static 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 | |||
1367 | struct 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 | |||
1403 | static 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 | |||
1414 | static 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 | |||
1422 | int __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 | |||
13 | extern struct sysdev_class dma_sysclass; | ||
14 | extern struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS]; | ||
15 | |||
16 | #define DMA_CH_VALID (1<<31) | ||
17 | |||
18 | struct 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 | |||
29 | struct s3c24xx_dma_map { | ||
30 | const char *name; | ||
31 | struct s3c24xx_dma_addr hw_addr; | ||
32 | |||
33 | unsigned long channels[S3C2410_DMA_CHANNELS]; | ||
34 | }; | ||
35 | |||
36 | struct 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 | |||
45 | extern 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 | ||
183 | struct irqchip s3c_irq_level_chip = { | 183 | struct 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 | ||
190 | static struct irqchip s3c_irq_chip = { | 191 | static 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 | ||
197 | static void | 199 | static void |
@@ -343,19 +345,21 @@ s3c_irqext_type(unsigned int irq, unsigned int type) | |||
343 | } | 345 | } |
344 | 346 | ||
345 | static struct irqchip s3c_irqext_chip = { | 347 | static 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 | ||
353 | static struct irqchip s3c_irq_eint0t4 = { | 356 | static 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 | ||
389 | static struct irqchip s3c_irq_uart0 = { | 393 | static 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 | ||
415 | static struct irqchip s3c_irq_uart1 = { | 420 | static 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 | ||
441 | static struct irqchip s3c_irq_uart2 = { | 447 | static 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 | ||
467 | static struct irqchip s3c_irq_adc = { | 474 | static 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 | ||
571 | static void | 579 | static void |
572 | s3c_irq_demux_extint(unsigned int irq, | 580 | s3c_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 | |||
602 | static void | ||
603 | s3c_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 | |||
627 | static 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 | |||
637 | static unsigned long save_extint[3]; | ||
638 | static unsigned long save_eintflt[4]; | ||
639 | static unsigned long save_eintmask; | ||
640 | |||
641 | int 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 | ||
657 | int 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 | |||
65 | static struct resource amlm5900_nor_resource = { | ||
66 | .start = 0x00000000, | ||
67 | .end = 0x01000000 - 1, | ||
68 | .flags = IORESOURCE_MEM, | ||
69 | }; | ||
70 | |||
71 | |||
72 | |||
73 | static 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 | |||
98 | static 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 | |||
104 | static 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 | |||
115 | static 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 | |||
128 | static 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 | |||
153 | static 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 | |||
169 | static struct s3c24xx_board amlm5900_board __initdata = { | ||
170 | .devices = amlm5900_devices, | ||
171 | .devices_count = ARRAY_SIZE(amlm5900_devices) | ||
172 | }; | ||
173 | |||
174 | void __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 | ||
183 | static 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 | |||
228 | static irqreturn_t | ||
229 | amlm5900_wake_interrupt(int irq, void *ignored, struct pt_regs *regs) | ||
230 | { | ||
231 | return IRQ_HANDLED; | ||
232 | } | ||
233 | |||
234 | static 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 | } | ||
250 | static 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 | |||
258 | MACHINE_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, | ||
266 | MACHINE_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 | |||
52 | static struct map_desc vstms_iodesc[] __initdata = { | ||
53 | }; | ||
54 | |||
55 | static 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 | |||
79 | static 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 | |||
102 | static 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 | |||
115 | static 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 | |||
123 | static 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 | |||
132 | static struct s3c24xx_board vstms_board __initdata = { | ||
133 | .devices = vstms_devices, | ||
134 | .devices_count = ARRAY_SIZE(vstms_devices) | ||
135 | }; | ||
136 | |||
137 | static 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 | |||
149 | static 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 | |||
159 | MACHINE_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, | ||
168 | MACHINE_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 | ||
56 | unsigned long s3c_pm_flags; | 54 | unsigned long s3c_pm_flags; |
57 | 55 | ||
58 | /* cache functions from arch/arm/mm/proc-arm920.S */ | ||
59 | |||
60 | #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH | ||
61 | extern void arm920_flush_kern_cache_all(void); | ||
62 | #else | ||
63 | static void arm920_flush_kern_cache_all(void) { } | ||
64 | #endif | ||
65 | |||
66 | #define PFX "s3c24xx-pm: " | 56 | #define PFX "s3c24xx-pm: " |
67 | 57 | ||
68 | static struct sleep_save core_save[] = { | 58 | static 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 */ | ||
96 | static 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 | |||
108 | static struct sleep_save gpio_save[] = { | 85 | static 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 | ||
166 | extern void printascii(const char *); | 143 | extern void printascii(const char *); |
167 | 144 | ||
168 | static void pm_dbg(const char *fmt, ...) | 145 | void 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 | ||
489 | void (*pm_cpu_prep)(void); | ||
490 | void (*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) | |||
519 | static int s3c2410_pm_enter(suspend_state_t state) | 499 | static 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; | |||
34 | extern unsigned long s3c_irqwake_intallow; | 34 | extern unsigned long s3c_irqwake_intallow; |
35 | extern unsigned long s3c_irqwake_eintallow; | 35 | extern unsigned long s3c_irqwake_eintallow; |
36 | 36 | ||
37 | /* per-cpu sleep functions */ | ||
38 | |||
39 | extern void (*pm_cpu_prep)(void); | ||
40 | extern void (*pm_cpu_sleep)(void); | ||
41 | |||
37 | /* Flags for PM Control */ | 42 | /* Flags for PM Control */ |
38 | 43 | ||
39 | extern unsigned long s3c_pm_flags; | 44 | extern unsigned long s3c_pm_flags; |
40 | 45 | ||
41 | /* from sleep.S */ | 46 | /* from sleep.S */ |
42 | 47 | ||
43 | extern void s3c2410_cpu_suspend(unsigned long *saveblk); | 48 | extern int s3c2410_cpu_save(unsigned long *saveblk); |
49 | extern void s3c2410_cpu_suspend(void); | ||
44 | extern void s3c2410_cpu_resume(void); | 50 | extern void s3c2410_cpu_resume(void); |
45 | 51 | ||
46 | extern unsigned long s3c2410_sleep_save_phys; | 52 | extern unsigned long s3c2410_sleep_save_phys; |
@@ -57,3 +63,11 @@ struct sleep_save { | |||
57 | 63 | ||
58 | extern void s3c2410_pm_do_save(struct sleep_save *ptr, int count); | 64 | extern void s3c2410_pm_do_save(struct sleep_save *ptr, int count); |
59 | extern void s3c2410_pm_do_restore(struct sleep_save *ptr, int count); | 65 | extern void s3c2410_pm_do_restore(struct sleep_save *ptr, int count); |
66 | |||
67 | #ifdef CONFIG_PM | ||
68 | extern int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state); | ||
69 | extern 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 | |||
34 | static 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 | |||
116 | static 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 | |||
122 | static 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 | |||
129 | static int s3c2410_dma_add(struct sys_device *sysdev) | ||
130 | { | ||
131 | return s3c24xx_dma_init_map(&s3c2410_dma_sel); | ||
132 | } | ||
133 | |||
134 | static struct sysdev_driver s3c2410_dma_driver = { | ||
135 | .add = s3c2410_dma_add, | ||
136 | }; | ||
137 | |||
138 | static int __init s3c2410_dma_init(void) | ||
139 | { | ||
140 | return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_dma_driver); | ||
141 | } | ||
142 | |||
143 | arch_initcall(s3c2410_dma_init); | ||
144 | |||
145 | /* S3C2442 DMA contains the same selection table as the S3C2410 */ | ||
146 | |||
147 | static struct sysdev_driver s3c2442_dma_driver = { | ||
148 | .add = s3c2410_dma_add, | ||
149 | }; | ||
150 | |||
151 | static int __init s3c2442_dma_init(void) | ||
152 | { | ||
153 | return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_dma_driver); | ||
154 | } | ||
155 | |||
156 | arch_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 | |||
32 | static int s3c2410_irq_add(struct sys_device *sysdev) | ||
33 | { | ||
34 | return 0; | ||
35 | } | ||
36 | |||
37 | static struct sysdev_driver s3c2410_irq_driver = { | ||
38 | .add = s3c2410_irq_add, | ||
39 | .suspend = s3c24xx_irq_suspend, | ||
40 | .resume = s3c24xx_irq_resume, | ||
41 | }; | ||
42 | |||
43 | static int s3c2410_irq_init(void) | ||
44 | { | ||
45 | return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_irq_driver); | ||
46 | } | ||
47 | |||
48 | arch_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 | ||
40 | extern 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 | |||
46 | static 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 | |||
60 | int 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 | |||
76 | static 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 | |||
84 | static struct sysdev_driver s3c2410_pm_driver = { | ||
85 | .add = s3c2410_pm_add, | ||
86 | .resume = s3c2410_pm_resume, | ||
87 | }; | ||
88 | |||
89 | /* register ourselves */ | ||
90 | |||
91 | static int __init s3c2410_pm_drvinit(void) | ||
92 | { | ||
93 | return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_pm_driver); | ||
94 | } | ||
95 | |||
96 | arch_initcall(s3c2410_pm_drvinit); | ||
97 | |||
98 | static struct sysdev_driver s3c2440_pm_driver = { | ||
99 | .add = s3c2410_pm_add, | ||
100 | .resume = s3c2410_pm_resume, | ||
101 | }; | ||
102 | |||
103 | static int __init s3c2440_pm_drvinit(void) | ||
104 | { | ||
105 | return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_pm_driver); | ||
106 | } | ||
107 | |||
108 | arch_initcall(s3c2440_pm_drvinit); | ||
109 | |||
110 | static struct sysdev_driver s3c2442_pm_driver = { | ||
111 | .add = s3c2410_pm_add, | ||
112 | .resume = s3c2410_pm_resume, | ||
113 | }; | ||
114 | |||
115 | static int __init s3c2442_pm_drvinit(void) | ||
116 | { | ||
117 | return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_pm_driver); | ||
118 | } | ||
119 | |||
120 | arch_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 | |||
42 | ENTRY(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 | ||
63 | s3c2410_do_sleep: | ||
64 | streq r7, [ r4 ] @ SDRAM sleep command | ||
65 | streq r8, [ r5 ] @ SDRAM power-down config | ||
66 | streq r9, [ r6 ] @ CPU sleep | ||
67 | 1: 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 | |||
37 | static 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 | |||
132 | static 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 | |||
139 | static 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 | |||
146 | static int s3c2412_dma_add(struct sys_device *sysdev) | ||
147 | { | ||
148 | return s3c24xx_dma_init_map(&s3c2412_dma_sel); | ||
149 | } | ||
150 | |||
151 | static struct sysdev_driver s3c2412_dma_driver = { | ||
152 | .add = s3c2412_dma_add, | ||
153 | }; | ||
154 | |||
155 | static int __init s3c2412_dma_init(void) | ||
156 | { | ||
157 | return sysdev_driver_register(&s3c2412_sysclass, &s3c2412_dma_driver); | ||
158 | } | ||
159 | |||
160 | arch_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 | ||
121 | static struct sysdev_driver s3c2412_irq_driver = { | 122 | static 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 | ||
125 | static int s3c2412_irq_init(void) | 128 | static 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 | |||
36 | static 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 | |||
62 | static void s3c2412_pm_prepare(void) | ||
63 | { | ||
64 | } | ||
65 | |||
66 | static 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 | |||
74 | static 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 | |||
98 | static 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 | |||
104 | static 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 | |||
117 | static struct sysdev_driver s3c2412_pm_driver = { | ||
118 | .add = s3c2412_pm_add, | ||
119 | .suspend = s3c2412_pm_suspend, | ||
120 | .resume = s3c2412_pm_resume, | ||
121 | }; | ||
122 | |||
123 | static __init int s3c2412_pm_init(void) | ||
124 | { | ||
125 | return sysdev_driver_register(&s3c2412_sysclass, &s3c2412_pm_driver); | ||
126 | } | ||
127 | |||
128 | arch_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 |
58 | void __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO; | 47 | void __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO; |
48 | |||
49 | static 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 | ||
165 | static 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 | |||
185 | static 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 | |||
191 | static 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 | |||
202 | struct sysdev_class s3c2412_sysclass = { | 161 | struct 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 | ||
208 | static int __init s3c2412_core_init(void) | 165 | static 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 | |||
34 | static 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 | |||
136 | static 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 | |||
142 | static 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 | |||
149 | static int s3c2440_dma_add(struct sys_device *sysdev) | ||
150 | { | ||
151 | return s3c24xx_dma_init_map(&s3c2440_dma_sel); | ||
152 | } | ||
153 | |||
154 | static struct sysdev_driver s3c2440_dma_driver = { | ||
155 | .add = s3c2440_dma_add, | ||
156 | }; | ||
157 | |||
158 | static int __init s3c2440_dma_init(void) | ||
159 | { | ||
160 | return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_dma_driver); | ||
161 | } | ||
162 | |||
163 | arch_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 | ||
121 | static struct sysdev_driver s3c2440_irq_driver = { | 121 | static struct sysdev_driver s3c2440_irq_driver = { |
122 | .add = s3c2440_irq_add, | 122 | .add = s3c2440_irq_add, |
123 | }; | 123 | }; |
124 | 124 | ||
125 | static int s3c2440_irq_init(void) | 125 | static 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 | ||
122 | static struct sysdev_driver s3c2440_irq_driver = { | 122 | static 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 | ||
126 | static int s3c2440_irq_init(void) | 128 | static int s3c2440_irq_init(void) |
@@ -131,9 +133,12 @@ static int s3c2440_irq_init(void) | |||
131 | arch_initcall(s3c2440_irq_init); | 133 | arch_initcall(s3c2440_irq_init); |
132 | 134 | ||
133 | static struct sysdev_driver s3c2442_irq_driver = { | 135 | static 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 | |||
137 | static int s3c2442_irq_init(void) | 142 | static 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 | ||
52 | ENTRY(s3c2410_cpu_suspend) | 62 | ENTRY(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 | ||
92 | s3c2410_do_sleep: | ||
93 | streq r7, [ r4 ] @ SDRAM sleep command | ||
94 | streq r8, [ r5 ] @ SDRAM power-down config | ||
95 | streq r9, [ r6 ] @ CPU sleep | ||
96 | 1: 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 |
102 | resume_with_mmu: | 81 | resume_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 |