aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/Kconfig48
-rw-r--r--arch/arm/Makefile1
-rw-r--r--arch/arm/boot/compressed/Makefile17
-rw-r--r--arch/arm/boot/compressed/head-shmobile.S30
-rw-r--r--arch/arm/boot/compressed/head-vt8500.S46
-rw-r--r--arch/arm/boot/compressed/mmcif-sh7372.c87
-rw-r--r--arch/arm/include/asm/cacheflush.h133
-rw-r--r--arch/arm/include/asm/cpu-multi32.h69
-rw-r--r--arch/arm/include/asm/cpu-single.h44
-rw-r--r--arch/arm/include/asm/fncpy.h94
-rw-r--r--arch/arm/include/asm/glue-cache.h146
-rw-r--r--arch/arm/include/asm/glue-df.h110
-rw-r--r--arch/arm/include/asm/glue-pf.h57
-rw-r--r--arch/arm/include/asm/glue-proc.h264
-rw-r--r--arch/arm/include/asm/glue.h138
-rw-r--r--arch/arm/include/asm/proc-fns.h306
-rw-r--r--arch/arm/include/asm/processor.h2
-rw-r--r--arch/arm/include/asm/smp_scu.h7
-rw-r--r--arch/arm/kernel/Makefile1
-rw-r--r--arch/arm/kernel/asm-offsets.c11
-rw-r--r--arch/arm/kernel/entry-armv.S3
-rw-r--r--arch/arm/kernel/sleep.S134
-rw-r--r--arch/arm/kernel/smp_scu.c23
-rw-r--r--arch/arm/mach-at91/board-snapper9260.c1
-rw-r--r--arch/arm/mach-at91/include/mach/gpio.h11
-rw-r--r--arch/arm/mach-ep93xx/edb93xx.c116
-rw-r--r--arch/arm/mach-ep93xx/gpio.c33
-rw-r--r--arch/arm/mach-ep93xx/include/mach/gpio.h2
-rw-r--r--arch/arm/mach-footbridge/dc21285-timer.c84
-rw-r--r--arch/arm/mach-footbridge/isa-timer.c129
-rw-r--r--arch/arm/mach-gemini/board-nas4220b.c1
-rw-r--r--arch/arm/mach-gemini/board-rut1xx.c1
-rw-r--r--arch/arm/mach-gemini/board-wbd111.c1
-rw-r--r--arch/arm/mach-gemini/board-wbd222.c1
-rw-r--r--arch/arm/mach-gemini/common.h1
-rw-r--r--arch/arm/mach-gemini/devices.c26
-rw-r--r--arch/arm/mach-mxs/gpio.c30
-rw-r--r--arch/arm/mach-mxs/icoll.c16
-rw-r--r--arch/arm/mach-omap1/pm.h6
-rw-r--r--arch/arm/mach-omap1/sleep.S3
-rw-r--r--arch/arm/mach-omap1/sram.S1
-rw-r--r--arch/arm/mach-omap2/pm.h2
-rw-r--r--arch/arm/mach-omap2/sleep24xx.S2
-rw-r--r--arch/arm/mach-omap2/sleep34xx.S2
-rw-r--r--arch/arm/mach-omap2/sram242x.S3
-rw-r--r--arch/arm/mach-omap2/sram243x.S3
-rw-r--r--arch/arm/mach-omap2/sram34xx.S1
-rw-r--r--arch/arm/mach-pxa/include/mach/pm.h5
-rw-r--r--arch/arm/mach-pxa/palmz72.c2
-rw-r--r--arch/arm/mach-pxa/pm.c5
-rw-r--r--arch/arm/mach-pxa/pxa25x.c4
-rw-r--r--arch/arm/mach-pxa/pxa27x.c4
-rw-r--r--arch/arm/mach-pxa/pxa3xx.c7
-rw-r--r--arch/arm/mach-pxa/sleep.S191
-rw-r--r--arch/arm/mach-pxa/zeus.c2
-rw-r--r--arch/arm/mach-s3c64xx/sleep.S63
-rw-r--r--arch/arm/mach-s5pv210/sleep.S105
-rw-r--r--arch/arm/mach-sa1100/pm.c12
-rw-r--r--arch/arm/mach-sa1100/sleep.S72
-rw-r--r--arch/arm/mach-shmobile/include/mach/mmcif-ap4eb.h29
-rw-r--r--arch/arm/mach-shmobile/include/mach/mmcif-mackerel.h39
-rw-r--r--arch/arm/mach-shmobile/include/mach/mmcif.h18
-rw-r--r--arch/arm/mach-ux500/Kconfig1
-rw-r--r--arch/arm/mach-vt8500/Kconfig73
-rw-r--r--arch/arm/mach-vt8500/Makefile9
-rw-r--r--arch/arm/mach-vt8500/Makefile.boot3
-rw-r--r--arch/arm/mach-vt8500/bv07.c77
-rw-r--r--arch/arm/mach-vt8500/devices-vt8500.c91
-rw-r--r--arch/arm/mach-vt8500/devices-wm8505.c99
-rw-r--r--arch/arm/mach-vt8500/devices.c270
-rw-r--r--arch/arm/mach-vt8500/devices.h88
-rw-r--r--arch/arm/mach-vt8500/gpio.c240
-rw-r--r--arch/arm/mach-vt8500/include/mach/debug-macro.S31
-rw-r--r--arch/arm/mach-vt8500/include/mach/entry-macro.S32
-rw-r--r--arch/arm/mach-vt8500/include/mach/gpio.h6
-rw-r--r--arch/arm/mach-vt8500/include/mach/hardware.h12
-rw-r--r--arch/arm/mach-vt8500/include/mach/i8042.h18
-rw-r--r--arch/arm/mach-vt8500/include/mach/io.h28
-rw-r--r--arch/arm/mach-vt8500/include/mach/irqs.h22
-rw-r--r--arch/arm/mach-vt8500/include/mach/memory.h28
-rw-r--r--arch/arm/mach-vt8500/include/mach/system.h18
-rw-r--r--arch/arm/mach-vt8500/include/mach/timex.h26
-rw-r--r--arch/arm/mach-vt8500/include/mach/uncompress.h37
-rw-r--r--arch/arm/mach-vt8500/include/mach/vmalloc.h20
-rw-r--r--arch/arm/mach-vt8500/include/mach/vt8500_irqs.h88
-rw-r--r--arch/arm/mach-vt8500/include/mach/vt8500_regs.h79
-rw-r--r--arch/arm/mach-vt8500/include/mach/vt8500fb.h31
-rw-r--r--arch/arm/mach-vt8500/include/mach/wm8505_irqs.h115
-rw-r--r--arch/arm/mach-vt8500/include/mach/wm8505_regs.h78
-rw-r--r--arch/arm/mach-vt8500/irq.c177
-rw-r--r--arch/arm/mach-vt8500/pwm.c265
-rw-r--r--arch/arm/mach-vt8500/timer.c155
-rw-r--r--arch/arm/mach-vt8500/wm8505_7in.c77
-rw-r--r--arch/arm/mm/proc-arm1020.S3
-rw-r--r--arch/arm/mm/proc-arm1020e.S3
-rw-r--r--arch/arm/mm/proc-arm1022.S3
-rw-r--r--arch/arm/mm/proc-arm1026.S3
-rw-r--r--arch/arm/mm/proc-arm6_7.S6
-rw-r--r--arch/arm/mm/proc-arm720.S3
-rw-r--r--arch/arm/mm/proc-arm740.S3
-rw-r--r--arch/arm/mm/proc-arm7tdmi.S3
-rw-r--r--arch/arm/mm/proc-arm920.S37
-rw-r--r--arch/arm/mm/proc-arm922.S3
-rw-r--r--arch/arm/mm/proc-arm925.S3
-rw-r--r--arch/arm/mm/proc-arm926.S37
-rw-r--r--arch/arm/mm/proc-arm940.S3
-rw-r--r--arch/arm/mm/proc-arm946.S3
-rw-r--r--arch/arm/mm/proc-arm9tdmi.S3
-rw-r--r--arch/arm/mm/proc-fa526.S3
-rw-r--r--arch/arm/mm/proc-feroceon.S3
-rw-r--r--arch/arm/mm/proc-mohawk.S3
-rw-r--r--arch/arm/mm/proc-sa110.S3
-rw-r--r--arch/arm/mm/proc-sa1100.S39
-rw-r--r--arch/arm/mm/proc-v6.S50
-rw-r--r--arch/arm/mm/proc-v7.S122
-rw-r--r--arch/arm/mm/proc-xsc3.S48
-rw-r--r--arch/arm/mm/proc-xscale.S45
-rw-r--r--arch/arm/plat-omap/include/plat/sram.h14
-rw-r--r--arch/arm/plat-omap/sram.c14
-rw-r--r--arch/arm/plat-s3c24xx/sleep.S57
-rw-r--r--arch/arm/plat-samsung/include/plat/pm.h12
-rw-r--r--arch/arm/plat-samsung/pm.c16
122 files changed, 4370 insertions, 1274 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 166efa2a19cd..38bf684448e7 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -346,7 +346,7 @@ config ARCH_FOOTBRIDGE
346 bool "FootBridge" 346 bool "FootBridge"
347 select CPU_SA110 347 select CPU_SA110
348 select FOOTBRIDGE 348 select FOOTBRIDGE
349 select ARCH_USES_GETTIMEOFFSET 349 select GENERIC_CLOCKEVENTS
350 help 350 help
351 Support for systems based on the DC21285 companion chip 351 Support for systems based on the DC21285 companion chip
352 ("FootBridge"), such as the Simtec CATS and the Rebel NetWinder. 352 ("FootBridge"), such as the Simtec CATS and the Rebel NetWinder.
@@ -875,6 +875,16 @@ config PLAT_SPEAR
875 help 875 help
876 Support for ST's SPEAr platform (SPEAr3xx, SPEAr6xx and SPEAr13xx). 876 Support for ST's SPEAr platform (SPEAr3xx, SPEAr6xx and SPEAr13xx).
877 877
878config ARCH_VT8500
879 bool "VIA/WonderMedia 85xx"
880 select CPU_ARM926T
881 select GENERIC_GPIO
882 select ARCH_HAS_CPUFREQ
883 select GENERIC_CLOCKEVENTS
884 select ARCH_REQUIRE_GPIOLIB
885 select HAVE_PWM
886 help
887 Support for VIA/WonderMedia VT8500/WM85xx System-on-Chip.
878endchoice 888endchoice
879 889
880# 890#
@@ -1007,6 +1017,8 @@ source "arch/arm/mach-versatile/Kconfig"
1007 1017
1008source "arch/arm/mach-vexpress/Kconfig" 1018source "arch/arm/mach-vexpress/Kconfig"
1009 1019
1020source "arch/arm/mach-vt8500/Kconfig"
1021
1010source "arch/arm/mach-w90x900/Kconfig" 1022source "arch/arm/mach-w90x900/Kconfig"
1011 1023
1012# Definitions to make life easier 1024# Definitions to make life easier
@@ -1202,6 +1214,28 @@ config ARM_ERRATA_753970
1202 This has the same effect as the cache sync operation: store buffer 1214 This has the same effect as the cache sync operation: store buffer
1203 drain and waiting for all buffers empty. 1215 drain and waiting for all buffers empty.
1204 1216
1217config ARM_ERRATA_754322
1218 bool "ARM errata: possible faulty MMU translations following an ASID switch"
1219 depends on CPU_V7
1220 help
1221 This option enables the workaround for the 754322 Cortex-A9 (r2p*,
1222 r3p*) erratum. A speculative memory access may cause a page table walk
1223 which starts prior to an ASID switch but completes afterwards. This
1224 can populate the micro-TLB with a stale entry which may be hit with
1225 the new ASID. This workaround places two dsb instructions in the mm
1226 switching code so that no page table walks can cross the ASID switch.
1227
1228config ARM_ERRATA_754327
1229 bool "ARM errata: no automatic Store Buffer drain"
1230 depends on CPU_V7 && SMP
1231 help
1232 This option enables the workaround for the 754327 Cortex-A9 (prior to
1233 r2p0) erratum. The Store Buffer does not have any automatic draining
1234 mechanism and therefore a livelock may occur if an external agent
1235 continuously polls a memory location waiting to observe an update.
1236 This workaround defines cpu_relax() as smp_mb(), preventing correctly
1237 written polling loops from denying visibility of updates to memory.
1238
1205endmenu 1239endmenu
1206 1240
1207source "arch/arm/common/Kconfig" 1241source "arch/arm/common/Kconfig"
@@ -1644,6 +1678,18 @@ config ZBOOT_ROM
1644 Say Y here if you intend to execute your compressed kernel image 1678 Say Y here if you intend to execute your compressed kernel image
1645 (zImage) directly from ROM or flash. If unsure, say N. 1679 (zImage) directly from ROM or flash. If unsure, say N.
1646 1680
1681config ZBOOT_ROM_MMCIF
1682 bool "Include MMCIF loader in zImage (EXPERIMENTAL)"
1683 depends on ZBOOT_ROM && ARCH_SH7372 && EXPERIMENTAL
1684 help
1685 Say Y here to include experimental MMCIF loading code in the
1686 ROM-able zImage. With this enabled it is possible to write the
1687 the ROM-able zImage kernel image to an MMC card and boot the
1688 kernel straight from the reset vector. At reset the processor
1689 Mask ROM will load the first part of the the ROM-able zImage
1690 which in turn loads the rest the kernel image to RAM using the
1691 MMCIF hardware block.
1692
1647config CMDLINE 1693config CMDLINE
1648 string "Default kernel command string" 1694 string "Default kernel command string"
1649 default "" 1695 default ""
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 6f7b29294c80..cd56c9129a1a 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -190,6 +190,7 @@ machine-$(CONFIG_ARCH_U300) := u300
190machine-$(CONFIG_ARCH_U8500) := ux500 190machine-$(CONFIG_ARCH_U8500) := ux500
191machine-$(CONFIG_ARCH_VERSATILE) := versatile 191machine-$(CONFIG_ARCH_VERSATILE) := versatile
192machine-$(CONFIG_ARCH_VEXPRESS) := vexpress 192machine-$(CONFIG_ARCH_VEXPRESS) := vexpress
193machine-$(CONFIG_ARCH_VT8500) := vt8500
193machine-$(CONFIG_ARCH_W90X900) := w90x900 194machine-$(CONFIG_ARCH_W90X900) := w90x900
194machine-$(CONFIG_ARCH_NUC93X) := nuc93x 195machine-$(CONFIG_ARCH_NUC93X) := nuc93x
195machine-$(CONFIG_FOOTBRIDGE) := footbridge 196machine-$(CONFIG_FOOTBRIDGE) := footbridge
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 0a8f748e506a..5f3a1614dc63 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -4,9 +4,20 @@
4# create a compressed vmlinuz image from the original vmlinux 4# create a compressed vmlinuz image from the original vmlinux
5# 5#
6 6
7OBJS =
8
9# Ensure that mmcif loader code appears early in the image
10# to minimise that number of bocks that have to be read in
11# order to load it.
12ifeq ($(CONFIG_ZBOOT_ROM_MMCIF),y)
13ifeq ($(CONFIG_ARCH_SH7372),y)
14OBJS += mmcif-sh7372.o
15endif
16endif
17
7AFLAGS_head.o += -DTEXT_OFFSET=$(TEXT_OFFSET) 18AFLAGS_head.o += -DTEXT_OFFSET=$(TEXT_OFFSET)
8HEAD = head.o 19HEAD = head.o
9OBJS = misc.o decompress.o 20OBJS += misc.o decompress.o
10FONTC = $(srctree)/drivers/video/console/font_acorn_8x8.c 21FONTC = $(srctree)/drivers/video/console/font_acorn_8x8.c
11 22
12# 23#
@@ -29,6 +40,10 @@ ifeq ($(CONFIG_ARCH_SA1100),y)
29OBJS += head-sa1100.o 40OBJS += head-sa1100.o
30endif 41endif
31 42
43ifeq ($(CONFIG_ARCH_VT8500),y)
44OBJS += head-vt8500.o
45endif
46
32ifeq ($(CONFIG_CPU_XSCALE),y) 47ifeq ($(CONFIG_CPU_XSCALE),y)
33OBJS += head-xscale.o 48OBJS += head-xscale.o
34endif 49endif
diff --git a/arch/arm/boot/compressed/head-shmobile.S b/arch/arm/boot/compressed/head-shmobile.S
index 30973b76e6ae..c943d2e7da9d 100644
--- a/arch/arm/boot/compressed/head-shmobile.S
+++ b/arch/arm/boot/compressed/head-shmobile.S
@@ -25,6 +25,36 @@
25 /* load board-specific initialization code */ 25 /* load board-specific initialization code */
26#include <mach/zboot.h> 26#include <mach/zboot.h>
27 27
28#ifdef CONFIG_ZBOOT_ROM_MMCIF
29 /* Load image from MMC */
30 adr sp, __tmp_stack + 128
31 ldr r0, __image_start
32 ldr r1, __image_end
33 subs r1, r1, r0
34 ldr r0, __load_base
35 bl mmcif_loader
36
37 /* Jump to loaded code */
38 ldr r0, __loaded
39 ldr r1, __image_start
40 sub r0, r0, r1
41 ldr r1, __load_base
42 add pc, r0, r1
43
44__image_start:
45 .long _start
46__image_end:
47 .long _got_end
48__load_base:
49 .long CONFIG_MEMORY_START + 0x02000000 @ Load at 32Mb into SDRAM
50__loaded:
51 .long __continue
52 .align
53__tmp_stack:
54 .space 128
55__continue:
56#endif /* CONFIG_ZBOOT_ROM_MMCIF */
57
28 b 1f 58 b 1f
29__atags:@ tag #1 59__atags:@ tag #1
30 .long 12 @ tag->hdr.size = tag_size(tag_core); 60 .long 12 @ tag->hdr.size = tag_size(tag_core);
diff --git a/arch/arm/boot/compressed/head-vt8500.S b/arch/arm/boot/compressed/head-vt8500.S
new file mode 100644
index 000000000000..1dc1e21a3be3
--- /dev/null
+++ b/arch/arm/boot/compressed/head-vt8500.S
@@ -0,0 +1,46 @@
1/*
2 * linux/arch/arm/boot/compressed/head-vt8500.S
3 *
4 * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
5 *
6 * VIA VT8500 specific tweaks. This is merged into head.S by the linker.
7 *
8 */
9
10#include <linux/linkage.h>
11#include <asm/mach-types.h>
12
13 .section ".start", "ax"
14
15__VT8500_start:
16 @ Compare the SCC ID register against a list of known values
17 ldr r1, .SCCID
18 ldr r3, [r1]
19
20 @ VT8500 override
21 ldr r4, .VT8500SCC
22 cmp r3, r4
23 ldreq r7, .ID_BV07
24 beq .Lendvt8500
25
26 @ WM8505 override
27 ldr r4, .WM8505SCC
28 cmp r3, r4
29 ldreq r7, .ID_8505
30 beq .Lendvt8500
31
32 @ Otherwise, leave the bootloader's machine id untouched
33
34.SCCID:
35 .word 0xd8120000
36.VT8500SCC:
37 .word 0x34000102
38.WM8505SCC:
39 .word 0x34260103
40
41.ID_BV07:
42 .word MACH_TYPE_BV07
43.ID_8505:
44 .word MACH_TYPE_WM8505_7IN_NETBOOK
45
46.Lendvt8500:
diff --git a/arch/arm/boot/compressed/mmcif-sh7372.c b/arch/arm/boot/compressed/mmcif-sh7372.c
new file mode 100644
index 000000000000..e6180af241f6
--- /dev/null
+++ b/arch/arm/boot/compressed/mmcif-sh7372.c
@@ -0,0 +1,87 @@
1/*
2 * sh7372 MMCIF loader
3 *
4 * Copyright (C) 2010 Magnus Damm
5 * Copyright (C) 2010 Simon Horman
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details.
10 */
11
12#include <linux/mmc/sh_mmcif.h>
13#include <mach/mmcif.h>
14
15#define MMCIF_BASE (void __iomem *)0xe6bd0000
16
17#define PORT84CR (void __iomem *)0xe6050054
18#define PORT85CR (void __iomem *)0xe6050055
19#define PORT86CR (void __iomem *)0xe6050056
20#define PORT87CR (void __iomem *)0xe6050057
21#define PORT88CR (void __iomem *)0xe6050058
22#define PORT89CR (void __iomem *)0xe6050059
23#define PORT90CR (void __iomem *)0xe605005a
24#define PORT91CR (void __iomem *)0xe605005b
25#define PORT92CR (void __iomem *)0xe605005c
26#define PORT99CR (void __iomem *)0xe6050063
27
28#define SMSTPCR3 (void __iomem *)0xe615013c
29
30/* SH7372 specific MMCIF loader
31 *
32 * loads the zImage from an MMC card starting from block 1.
33 *
34 * The image must be start with a vrl4 header and
35 * the zImage must start at offset 512 of the image. That is,
36 * at block 2 (=byte 1024) on the media
37 *
38 * Use the following line to write the vrl4 formated zImage
39 * to an MMC card
40 * # dd if=vrl4.out of=/dev/sdx bs=512 seek=1
41 */
42asmlinkage void mmcif_loader(unsigned char *buf, unsigned long len)
43{
44 mmcif_init_progress();
45 mmcif_update_progress(MMCIF_PROGRESS_ENTER);
46
47 /* Initialise MMC
48 * registers: PORT84CR-PORT92CR
49 * (MMCD0_0-MMCD0_7,MMCCMD0 Control)
50 * value: 0x04 - select function 4
51 */
52 __raw_writeb(0x04, PORT84CR);
53 __raw_writeb(0x04, PORT85CR);
54 __raw_writeb(0x04, PORT86CR);
55 __raw_writeb(0x04, PORT87CR);
56 __raw_writeb(0x04, PORT88CR);
57 __raw_writeb(0x04, PORT89CR);
58 __raw_writeb(0x04, PORT90CR);
59 __raw_writeb(0x04, PORT91CR);
60 __raw_writeb(0x04, PORT92CR);
61
62 /* Initialise MMC
63 * registers: PORT99CR (MMCCLK0 Control)
64 * value: 0x10 | 0x04 - enable output | select function 4
65 */
66 __raw_writeb(0x14, PORT99CR);
67
68 /* Enable clock to MMC hardware block */
69 __raw_writel(__raw_readl(SMSTPCR3) & ~(1 << 12), SMSTPCR3);
70
71 mmcif_update_progress(MMCIF_PROGRESS_INIT);
72
73 /* setup MMCIF hardware */
74 sh_mmcif_boot_init(MMCIF_BASE);
75
76 mmcif_update_progress(MMCIF_PROGRESS_LOAD);
77
78 /* load kernel via MMCIF interface */
79 sh_mmcif_boot_do_read(MMCIF_BASE, 2, /* Kernel is at block 2 */
80 (len + SH_MMCIF_BBS - 1) / SH_MMCIF_BBS, buf);
81
82
83 /* Disable clock to MMC hardware block */
84 __raw_writel(__raw_readl(SMSTPCR3) & (1 << 12), SMSTPCR3);
85
86 mmcif_update_progress(MMCIF_PROGRESS_DONE);
87}
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
index 3acd8fa25e34..18a56640d97d 100644
--- a/arch/arm/include/asm/cacheflush.h
+++ b/arch/arm/include/asm/cacheflush.h
@@ -12,7 +12,7 @@
12 12
13#include <linux/mm.h> 13#include <linux/mm.h>
14 14
15#include <asm/glue.h> 15#include <asm/glue-cache.h>
16#include <asm/shmparam.h> 16#include <asm/shmparam.h>
17#include <asm/cachetype.h> 17#include <asm/cachetype.h>
18#include <asm/outercache.h> 18#include <asm/outercache.h>
@@ -20,123 +20,6 @@
20#define CACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT) 20#define CACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT)
21 21
22/* 22/*
23 * Cache Model
24 * ===========
25 */
26#undef _CACHE
27#undef MULTI_CACHE
28
29#if defined(CONFIG_CPU_CACHE_V3)
30# ifdef _CACHE
31# define MULTI_CACHE 1
32# else
33# define _CACHE v3
34# endif
35#endif
36
37#if defined(CONFIG_CPU_CACHE_V4)
38# ifdef _CACHE
39# define MULTI_CACHE 1
40# else
41# define _CACHE v4
42# endif
43#endif
44
45#if defined(CONFIG_CPU_ARM920T) || defined(CONFIG_CPU_ARM922T) || \
46 defined(CONFIG_CPU_ARM925T) || defined(CONFIG_CPU_ARM1020) || \
47 defined(CONFIG_CPU_ARM1026)
48# define MULTI_CACHE 1
49#endif
50
51#if defined(CONFIG_CPU_FA526)
52# ifdef _CACHE
53# define MULTI_CACHE 1
54# else
55# define _CACHE fa
56# endif
57#endif
58
59#if defined(CONFIG_CPU_ARM926T)
60# ifdef _CACHE
61# define MULTI_CACHE 1
62# else
63# define _CACHE arm926
64# endif
65#endif
66
67#if defined(CONFIG_CPU_ARM940T)
68# ifdef _CACHE
69# define MULTI_CACHE 1
70# else
71# define _CACHE arm940
72# endif
73#endif
74
75#if defined(CONFIG_CPU_ARM946E)
76# ifdef _CACHE
77# define MULTI_CACHE 1
78# else
79# define _CACHE arm946
80# endif
81#endif
82
83#if defined(CONFIG_CPU_CACHE_V4WB)
84# ifdef _CACHE
85# define MULTI_CACHE 1
86# else
87# define _CACHE v4wb
88# endif
89#endif
90
91#if defined(CONFIG_CPU_XSCALE)
92# ifdef _CACHE
93# define MULTI_CACHE 1
94# else
95# define _CACHE xscale
96# endif
97#endif
98
99#if defined(CONFIG_CPU_XSC3)
100# ifdef _CACHE
101# define MULTI_CACHE 1
102# else
103# define _CACHE xsc3
104# endif
105#endif
106
107#if defined(CONFIG_CPU_MOHAWK)
108# ifdef _CACHE
109# define MULTI_CACHE 1
110# else
111# define _CACHE mohawk
112# endif
113#endif
114
115#if defined(CONFIG_CPU_FEROCEON)
116# define MULTI_CACHE 1
117#endif
118
119#if defined(CONFIG_CPU_V6)
120//# ifdef _CACHE
121# define MULTI_CACHE 1
122//# else
123//# define _CACHE v6
124//# endif
125#endif
126
127#if defined(CONFIG_CPU_V7)
128//# ifdef _CACHE
129# define MULTI_CACHE 1
130//# else
131//# define _CACHE v7
132//# endif
133#endif
134
135#if !defined(_CACHE) && !defined(MULTI_CACHE)
136#error Unknown cache maintainence model
137#endif
138
139/*
140 * This flag is used to indicate that the page pointed to by a pte is clean 23 * This flag is used to indicate that the page pointed to by a pte is clean
141 * and does not require cleaning before returning it to the user. 24 * and does not require cleaning before returning it to the user.
142 */ 25 */
@@ -249,19 +132,11 @@ extern struct cpu_cache_fns cpu_cache;
249 * visible to the CPU. 132 * visible to the CPU.
250 */ 133 */
251#define dmac_map_area cpu_cache.dma_map_area 134#define dmac_map_area cpu_cache.dma_map_area
252#define dmac_unmap_area cpu_cache.dma_unmap_area 135#define dmac_unmap_area cpu_cache.dma_unmap_area
253#define dmac_flush_range cpu_cache.dma_flush_range 136#define dmac_flush_range cpu_cache.dma_flush_range
254 137
255#else 138#else
256 139
257#define __cpuc_flush_icache_all __glue(_CACHE,_flush_icache_all)
258#define __cpuc_flush_kern_all __glue(_CACHE,_flush_kern_cache_all)
259#define __cpuc_flush_user_all __glue(_CACHE,_flush_user_cache_all)
260#define __cpuc_flush_user_range __glue(_CACHE,_flush_user_cache_range)
261#define __cpuc_coherent_kern_range __glue(_CACHE,_coherent_kern_range)
262#define __cpuc_coherent_user_range __glue(_CACHE,_coherent_user_range)
263#define __cpuc_flush_dcache_area __glue(_CACHE,_flush_kern_dcache_area)
264
265extern void __cpuc_flush_icache_all(void); 140extern void __cpuc_flush_icache_all(void);
266extern void __cpuc_flush_kern_all(void); 141extern void __cpuc_flush_kern_all(void);
267extern void __cpuc_flush_user_all(void); 142extern void __cpuc_flush_user_all(void);
@@ -276,10 +151,6 @@ extern void __cpuc_flush_dcache_area(void *, size_t);
276 * is visible to DMA, or data written by DMA to system memory is 151 * is visible to DMA, or data written by DMA to system memory is
277 * visible to the CPU. 152 * visible to the CPU.
278 */ 153 */
279#define dmac_map_area __glue(_CACHE,_dma_map_area)
280#define dmac_unmap_area __glue(_CACHE,_dma_unmap_area)
281#define dmac_flush_range __glue(_CACHE,_dma_flush_range)
282
283extern void dmac_map_area(const void *, size_t, int); 154extern void dmac_map_area(const void *, size_t, int);
284extern void dmac_unmap_area(const void *, size_t, int); 155extern void dmac_unmap_area(const void *, size_t, int);
285extern void dmac_flush_range(const void *, const void *); 156extern void dmac_flush_range(const void *, const void *);
diff --git a/arch/arm/include/asm/cpu-multi32.h b/arch/arm/include/asm/cpu-multi32.h
deleted file mode 100644
index e2b5b0b2116a..000000000000
--- a/arch/arm/include/asm/cpu-multi32.h
+++ /dev/null
@@ -1,69 +0,0 @@
1/*
2 * arch/arm/include/asm/cpu-multi32.h
3 *
4 * Copyright (C) 2000 Russell King
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 version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <asm/page.h>
11
12struct mm_struct;
13
14/*
15 * Don't change this structure - ASM code
16 * relies on it.
17 */
18extern struct processor {
19 /* MISC
20 * get data abort address/flags
21 */
22 void (*_data_abort)(unsigned long pc);
23 /*
24 * Retrieve prefetch fault address
25 */
26 unsigned long (*_prefetch_abort)(unsigned long lr);
27 /*
28 * Set up any processor specifics
29 */
30 void (*_proc_init)(void);
31 /*
32 * Disable any processor specifics
33 */
34 void (*_proc_fin)(void);
35 /*
36 * Special stuff for a reset
37 */
38 void (*reset)(unsigned long addr) __attribute__((noreturn));
39 /*
40 * Idle the processor
41 */
42 int (*_do_idle)(void);
43 /*
44 * Processor architecture specific
45 */
46 /*
47 * clean a virtual address range from the
48 * D-cache without flushing the cache.
49 */
50 void (*dcache_clean_area)(void *addr, int size);
51
52 /*
53 * Set the page table
54 */
55 void (*switch_mm)(unsigned long pgd_phys, struct mm_struct *mm);
56 /*
57 * Set a possibly extended PTE. Non-extended PTEs should
58 * ignore 'ext'.
59 */
60 void (*set_pte_ext)(pte_t *ptep, pte_t pte, unsigned int ext);
61} processor;
62
63#define cpu_proc_init() processor._proc_init()
64#define cpu_proc_fin() processor._proc_fin()
65#define cpu_reset(addr) processor.reset(addr)
66#define cpu_do_idle() processor._do_idle()
67#define cpu_dcache_clean_area(addr,sz) processor.dcache_clean_area(addr,sz)
68#define cpu_set_pte_ext(ptep,pte,ext) processor.set_pte_ext(ptep,pte,ext)
69#define cpu_do_switch_mm(pgd,mm) processor.switch_mm(pgd,mm)
diff --git a/arch/arm/include/asm/cpu-single.h b/arch/arm/include/asm/cpu-single.h
deleted file mode 100644
index f073a6d2a406..000000000000
--- a/arch/arm/include/asm/cpu-single.h
+++ /dev/null
@@ -1,44 +0,0 @@
1/*
2 * arch/arm/include/asm/cpu-single.h
3 *
4 * Copyright (C) 2000 Russell King
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 version 2 as
8 * published by the Free Software Foundation.
9 */
10/*
11 * Single CPU
12 */
13#ifdef __STDC__
14#define __catify_fn(name,x) name##x
15#else
16#define __catify_fn(name,x) name/**/x
17#endif
18#define __cpu_fn(name,x) __catify_fn(name,x)
19
20/*
21 * If we are supporting multiple CPUs, then we must use a table of
22 * function pointers for this lot. Otherwise, we can optimise the
23 * table away.
24 */
25#define cpu_proc_init __cpu_fn(CPU_NAME,_proc_init)
26#define cpu_proc_fin __cpu_fn(CPU_NAME,_proc_fin)
27#define cpu_reset __cpu_fn(CPU_NAME,_reset)
28#define cpu_do_idle __cpu_fn(CPU_NAME,_do_idle)
29#define cpu_dcache_clean_area __cpu_fn(CPU_NAME,_dcache_clean_area)
30#define cpu_do_switch_mm __cpu_fn(CPU_NAME,_switch_mm)
31#define cpu_set_pte_ext __cpu_fn(CPU_NAME,_set_pte_ext)
32
33#include <asm/page.h>
34
35struct mm_struct;
36
37/* declare all the functions as extern */
38extern void cpu_proc_init(void);
39extern void cpu_proc_fin(void);
40extern int cpu_do_idle(void);
41extern void cpu_dcache_clean_area(void *, int);
42extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm);
43extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
44extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
diff --git a/arch/arm/include/asm/fncpy.h b/arch/arm/include/asm/fncpy.h
new file mode 100644
index 000000000000..de5354746924
--- /dev/null
+++ b/arch/arm/include/asm/fncpy.h
@@ -0,0 +1,94 @@
1/*
2 * arch/arm/include/asm/fncpy.h - helper macros for function body copying
3 *
4 * Copyright (C) 2011 Linaro Limited
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 version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20/*
21 * These macros are intended for use when there is a need to copy a low-level
22 * function body into special memory.
23 *
24 * For example, when reconfiguring the SDRAM controller, the code doing the
25 * reconfiguration may need to run from SRAM.
26 *
27 * NOTE: that the copied function body must be entirely self-contained and
28 * position-independent in order for this to work properly.
29 *
30 * NOTE: in order for embedded literals and data to get referenced correctly,
31 * the alignment of functions must be preserved when copying. To ensure this,
32 * the source and destination addresses for fncpy() must be aligned to a
33 * multiple of 8 bytes: you will be get a BUG() if this condition is not met.
34 * You will typically need a ".align 3" directive in the assembler where the
35 * function to be copied is defined, and ensure that your allocator for the
36 * destination buffer returns 8-byte-aligned pointers.
37 *
38 * Typical usage example:
39 *
40 * extern int f(args);
41 * extern uint32_t size_of_f;
42 * int (*copied_f)(args);
43 * void *sram_buffer;
44 *
45 * copied_f = fncpy(sram_buffer, &f, size_of_f);
46 *
47 * ... later, call the function: ...
48 *
49 * copied_f(args);
50 *
51 * The size of the function to be copied can't be determined from C:
52 * this must be determined by other means, such as adding assmbler directives
53 * in the file where f is defined.
54 */
55
56#ifndef __ASM_FNCPY_H
57#define __ASM_FNCPY_H
58
59#include <linux/types.h>
60#include <linux/string.h>
61
62#include <asm/bug.h>
63#include <asm/cacheflush.h>
64
65/*
66 * Minimum alignment requirement for the source and destination addresses
67 * for function copying.
68 */
69#define FNCPY_ALIGN 8
70
71#define fncpy(dest_buf, funcp, size) ({ \
72 uintptr_t __funcp_address; \
73 typeof(funcp) __result; \
74 \
75 asm("" : "=r" (__funcp_address) : "0" (funcp)); \
76 \
77 /* \
78 * Ensure alignment of source and destination addresses, \
79 * disregarding the function's Thumb bit: \
80 */ \
81 BUG_ON((uintptr_t)(dest_buf) & (FNCPY_ALIGN - 1) || \
82 (__funcp_address & ~(uintptr_t)1 & (FNCPY_ALIGN - 1))); \
83 \
84 memcpy(dest_buf, (void const *)(__funcp_address & ~1), size); \
85 flush_icache_range((unsigned long)(dest_buf), \
86 (unsigned long)(dest_buf) + (size)); \
87 \
88 asm("" : "=r" (__result) \
89 : "0" ((uintptr_t)(dest_buf) | (__funcp_address & 1))); \
90 \
91 __result; \
92})
93
94#endif /* !__ASM_FNCPY_H */
diff --git a/arch/arm/include/asm/glue-cache.h b/arch/arm/include/asm/glue-cache.h
new file mode 100644
index 000000000000..0591d35001e5
--- /dev/null
+++ b/arch/arm/include/asm/glue-cache.h
@@ -0,0 +1,146 @@
1/*
2 * arch/arm/include/asm/glue-cache.h
3 *
4 * Copyright (C) 1999-2002 Russell King
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 version 2 as
8 * published by the Free Software Foundation.
9 */
10#ifndef ASM_GLUE_CACHE_H
11#define ASM_GLUE_CACHE_H
12
13#include <asm/glue.h>
14
15/*
16 * Cache Model
17 * ===========
18 */
19#undef _CACHE
20#undef MULTI_CACHE
21
22#if defined(CONFIG_CPU_CACHE_V3)
23# ifdef _CACHE
24# define MULTI_CACHE 1
25# else
26# define _CACHE v3
27# endif
28#endif
29
30#if defined(CONFIG_CPU_CACHE_V4)
31# ifdef _CACHE
32# define MULTI_CACHE 1
33# else
34# define _CACHE v4
35# endif
36#endif
37
38#if defined(CONFIG_CPU_ARM920T) || defined(CONFIG_CPU_ARM922T) || \
39 defined(CONFIG_CPU_ARM925T) || defined(CONFIG_CPU_ARM1020) || \
40 defined(CONFIG_CPU_ARM1026)
41# define MULTI_CACHE 1
42#endif
43
44#if defined(CONFIG_CPU_FA526)
45# ifdef _CACHE
46# define MULTI_CACHE 1
47# else
48# define _CACHE fa
49# endif
50#endif
51
52#if defined(CONFIG_CPU_ARM926T)
53# ifdef _CACHE
54# define MULTI_CACHE 1
55# else
56# define _CACHE arm926
57# endif
58#endif
59
60#if defined(CONFIG_CPU_ARM940T)
61# ifdef _CACHE
62# define MULTI_CACHE 1
63# else
64# define _CACHE arm940
65# endif
66#endif
67
68#if defined(CONFIG_CPU_ARM946E)
69# ifdef _CACHE
70# define MULTI_CACHE 1
71# else
72# define _CACHE arm946
73# endif
74#endif
75
76#if defined(CONFIG_CPU_CACHE_V4WB)
77# ifdef _CACHE
78# define MULTI_CACHE 1
79# else
80# define _CACHE v4wb
81# endif
82#endif
83
84#if defined(CONFIG_CPU_XSCALE)
85# ifdef _CACHE
86# define MULTI_CACHE 1
87# else
88# define _CACHE xscale
89# endif
90#endif
91
92#if defined(CONFIG_CPU_XSC3)
93# ifdef _CACHE
94# define MULTI_CACHE 1
95# else
96# define _CACHE xsc3
97# endif
98#endif
99
100#if defined(CONFIG_CPU_MOHAWK)
101# ifdef _CACHE
102# define MULTI_CACHE 1
103# else
104# define _CACHE mohawk
105# endif
106#endif
107
108#if defined(CONFIG_CPU_FEROCEON)
109# define MULTI_CACHE 1
110#endif
111
112#if defined(CONFIG_CPU_V6)
113//# ifdef _CACHE
114# define MULTI_CACHE 1
115//# else
116//# define _CACHE v6
117//# endif
118#endif
119
120#if defined(CONFIG_CPU_V7)
121//# ifdef _CACHE
122# define MULTI_CACHE 1
123//# else
124//# define _CACHE v7
125//# endif
126#endif
127
128#if !defined(_CACHE) && !defined(MULTI_CACHE)
129#error Unknown cache maintainence model
130#endif
131
132#ifndef MULTI_CACHE
133#define __cpuc_flush_icache_all __glue(_CACHE,_flush_icache_all)
134#define __cpuc_flush_kern_all __glue(_CACHE,_flush_kern_cache_all)
135#define __cpuc_flush_user_all __glue(_CACHE,_flush_user_cache_all)
136#define __cpuc_flush_user_range __glue(_CACHE,_flush_user_cache_range)
137#define __cpuc_coherent_kern_range __glue(_CACHE,_coherent_kern_range)
138#define __cpuc_coherent_user_range __glue(_CACHE,_coherent_user_range)
139#define __cpuc_flush_dcache_area __glue(_CACHE,_flush_kern_dcache_area)
140
141#define dmac_map_area __glue(_CACHE,_dma_map_area)
142#define dmac_unmap_area __glue(_CACHE,_dma_unmap_area)
143#define dmac_flush_range __glue(_CACHE,_dma_flush_range)
144#endif
145
146#endif
diff --git a/arch/arm/include/asm/glue-df.h b/arch/arm/include/asm/glue-df.h
new file mode 100644
index 000000000000..354d571e8bcc
--- /dev/null
+++ b/arch/arm/include/asm/glue-df.h
@@ -0,0 +1,110 @@
1/*
2 * arch/arm/include/asm/glue-df.h
3 *
4 * Copyright (C) 1997-1999 Russell King
5 * Copyright (C) 2000-2002 Deep Blue Solutions Ltd.
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#ifndef ASM_GLUE_DF_H
12#define ASM_GLUE_DF_H
13
14#include <asm/glue.h>
15
16/*
17 * Data Abort Model
18 * ================
19 *
20 * We have the following to choose from:
21 * arm6 - ARM6 style
22 * arm7 - ARM7 style
23 * v4_early - ARMv4 without Thumb early abort handler
24 * v4t_late - ARMv4 with Thumb late abort handler
25 * v4t_early - ARMv4 with Thumb early abort handler
26 * v5tej_early - ARMv5 with Thumb and Java early abort handler
27 * xscale - ARMv5 with Thumb with Xscale extensions
28 * v6_early - ARMv6 generic early abort handler
29 * v7_early - ARMv7 generic early abort handler
30 */
31#undef CPU_DABORT_HANDLER
32#undef MULTI_DABORT
33
34#if defined(CONFIG_CPU_ARM610)
35# ifdef CPU_DABORT_HANDLER
36# define MULTI_DABORT 1
37# else
38# define CPU_DABORT_HANDLER cpu_arm6_data_abort
39# endif
40#endif
41
42#if defined(CONFIG_CPU_ARM710)
43# ifdef CPU_DABORT_HANDLER
44# define MULTI_DABORT 1
45# else
46# define CPU_DABORT_HANDLER cpu_arm7_data_abort
47# endif
48#endif
49
50#ifdef CONFIG_CPU_ABRT_LV4T
51# ifdef CPU_DABORT_HANDLER
52# define MULTI_DABORT 1
53# else
54# define CPU_DABORT_HANDLER v4t_late_abort
55# endif
56#endif
57
58#ifdef CONFIG_CPU_ABRT_EV4
59# ifdef CPU_DABORT_HANDLER
60# define MULTI_DABORT 1
61# else
62# define CPU_DABORT_HANDLER v4_early_abort
63# endif
64#endif
65
66#ifdef CONFIG_CPU_ABRT_EV4T
67# ifdef CPU_DABORT_HANDLER
68# define MULTI_DABORT 1
69# else
70# define CPU_DABORT_HANDLER v4t_early_abort
71# endif
72#endif
73
74#ifdef CONFIG_CPU_ABRT_EV5TJ
75# ifdef CPU_DABORT_HANDLER
76# define MULTI_DABORT 1
77# else
78# define CPU_DABORT_HANDLER v5tj_early_abort
79# endif
80#endif
81
82#ifdef CONFIG_CPU_ABRT_EV5T
83# ifdef CPU_DABORT_HANDLER
84# define MULTI_DABORT 1
85# else
86# define CPU_DABORT_HANDLER v5t_early_abort
87# endif
88#endif
89
90#ifdef CONFIG_CPU_ABRT_EV6
91# ifdef CPU_DABORT_HANDLER
92# define MULTI_DABORT 1
93# else
94# define CPU_DABORT_HANDLER v6_early_abort
95# endif
96#endif
97
98#ifdef CONFIG_CPU_ABRT_EV7
99# ifdef CPU_DABORT_HANDLER
100# define MULTI_DABORT 1
101# else
102# define CPU_DABORT_HANDLER v7_early_abort
103# endif
104#endif
105
106#ifndef CPU_DABORT_HANDLER
107#error Unknown data abort handler type
108#endif
109
110#endif
diff --git a/arch/arm/include/asm/glue-pf.h b/arch/arm/include/asm/glue-pf.h
new file mode 100644
index 000000000000..d385f37c13f0
--- /dev/null
+++ b/arch/arm/include/asm/glue-pf.h
@@ -0,0 +1,57 @@
1/*
2 * arch/arm/include/asm/glue-pf.h
3 *
4 * Copyright (C) 1997-1999 Russell King
5 * Copyright (C) 2000-2002 Deep Blue Solutions Ltd.
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#ifndef ASM_GLUE_PF_H
12#define ASM_GLUE_PF_H
13
14#include <asm/glue.h>
15
16/*
17 * Prefetch Abort Model
18 * ================
19 *
20 * We have the following to choose from:
21 * legacy - no IFSR, no IFAR
22 * v6 - ARMv6: IFSR, no IFAR
23 * v7 - ARMv7: IFSR and IFAR
24 */
25
26#undef CPU_PABORT_HANDLER
27#undef MULTI_PABORT
28
29#ifdef CONFIG_CPU_PABRT_LEGACY
30# ifdef CPU_PABORT_HANDLER
31# define MULTI_PABORT 1
32# else
33# define CPU_PABORT_HANDLER legacy_pabort
34# endif
35#endif
36
37#ifdef CONFIG_CPU_PABRT_V6
38# ifdef CPU_PABORT_HANDLER
39# define MULTI_PABORT 1
40# else
41# define CPU_PABORT_HANDLER v6_pabort
42# endif
43#endif
44
45#ifdef CONFIG_CPU_PABRT_V7
46# ifdef CPU_PABORT_HANDLER
47# define MULTI_PABORT 1
48# else
49# define CPU_PABORT_HANDLER v7_pabort
50# endif
51#endif
52
53#ifndef CPU_PABORT_HANDLER
54#error Unknown prefetch abort handler type
55#endif
56
57#endif
diff --git a/arch/arm/include/asm/glue-proc.h b/arch/arm/include/asm/glue-proc.h
new file mode 100644
index 000000000000..6469521d092f
--- /dev/null
+++ b/arch/arm/include/asm/glue-proc.h
@@ -0,0 +1,264 @@
1/*
2 * arch/arm/include/asm/glue-proc.h
3 *
4 * Copyright (C) 1997-1999 Russell King
5 * Copyright (C) 2000 Deep Blue Solutions Ltd
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#ifndef ASM_GLUE_PROC_H
12#define ASM_GLUE_PROC_H
13
14#include <asm/glue.h>
15
16/*
17 * Work out if we need multiple CPU support
18 */
19#undef MULTI_CPU
20#undef CPU_NAME
21
22/*
23 * CPU_NAME - the prefix for CPU related functions
24 */
25
26#ifdef CONFIG_CPU_ARM610
27# ifdef CPU_NAME
28# undef MULTI_CPU
29# define MULTI_CPU
30# else
31# define CPU_NAME cpu_arm6
32# endif
33#endif
34
35#ifdef CONFIG_CPU_ARM7TDMI
36# ifdef CPU_NAME
37# undef MULTI_CPU
38# define MULTI_CPU
39# else
40# define CPU_NAME cpu_arm7tdmi
41# endif
42#endif
43
44#ifdef CONFIG_CPU_ARM710
45# ifdef CPU_NAME
46# undef MULTI_CPU
47# define MULTI_CPU
48# else
49# define CPU_NAME cpu_arm7
50# endif
51#endif
52
53#ifdef CONFIG_CPU_ARM720T
54# ifdef CPU_NAME
55# undef MULTI_CPU
56# define MULTI_CPU
57# else
58# define CPU_NAME cpu_arm720
59# endif
60#endif
61
62#ifdef CONFIG_CPU_ARM740T
63# ifdef CPU_NAME
64# undef MULTI_CPU
65# define MULTI_CPU
66# else
67# define CPU_NAME cpu_arm740
68# endif
69#endif
70
71#ifdef CONFIG_CPU_ARM9TDMI
72# ifdef CPU_NAME
73# undef MULTI_CPU
74# define MULTI_CPU
75# else
76# define CPU_NAME cpu_arm9tdmi
77# endif
78#endif
79
80#ifdef CONFIG_CPU_ARM920T
81# ifdef CPU_NAME
82# undef MULTI_CPU
83# define MULTI_CPU
84# else
85# define CPU_NAME cpu_arm920
86# endif
87#endif
88
89#ifdef CONFIG_CPU_ARM922T
90# ifdef CPU_NAME
91# undef MULTI_CPU
92# define MULTI_CPU
93# else
94# define CPU_NAME cpu_arm922
95# endif
96#endif
97
98#ifdef CONFIG_CPU_FA526
99# ifdef CPU_NAME
100# undef MULTI_CPU
101# define MULTI_CPU
102# else
103# define CPU_NAME cpu_fa526
104# endif
105#endif
106
107#ifdef CONFIG_CPU_ARM925T
108# ifdef CPU_NAME
109# undef MULTI_CPU
110# define MULTI_CPU
111# else
112# define CPU_NAME cpu_arm925
113# endif
114#endif
115
116#ifdef CONFIG_CPU_ARM926T
117# ifdef CPU_NAME
118# undef MULTI_CPU
119# define MULTI_CPU
120# else
121# define CPU_NAME cpu_arm926
122# endif
123#endif
124
125#ifdef CONFIG_CPU_ARM940T
126# ifdef CPU_NAME
127# undef MULTI_CPU
128# define MULTI_CPU
129# else
130# define CPU_NAME cpu_arm940
131# endif
132#endif
133
134#ifdef CONFIG_CPU_ARM946E
135# ifdef CPU_NAME
136# undef MULTI_CPU
137# define MULTI_CPU
138# else
139# define CPU_NAME cpu_arm946
140# endif
141#endif
142
143#ifdef CONFIG_CPU_SA110
144# ifdef CPU_NAME
145# undef MULTI_CPU
146# define MULTI_CPU
147# else
148# define CPU_NAME cpu_sa110
149# endif
150#endif
151
152#ifdef CONFIG_CPU_SA1100
153# ifdef CPU_NAME
154# undef MULTI_CPU
155# define MULTI_CPU
156# else
157# define CPU_NAME cpu_sa1100
158# endif
159#endif
160
161#ifdef CONFIG_CPU_ARM1020
162# ifdef CPU_NAME
163# undef MULTI_CPU
164# define MULTI_CPU
165# else
166# define CPU_NAME cpu_arm1020
167# endif
168#endif
169
170#ifdef CONFIG_CPU_ARM1020E
171# ifdef CPU_NAME
172# undef MULTI_CPU
173# define MULTI_CPU
174# else
175# define CPU_NAME cpu_arm1020e
176# endif
177#endif
178
179#ifdef CONFIG_CPU_ARM1022
180# ifdef CPU_NAME
181# undef MULTI_CPU
182# define MULTI_CPU
183# else
184# define CPU_NAME cpu_arm1022
185# endif
186#endif
187
188#ifdef CONFIG_CPU_ARM1026
189# ifdef CPU_NAME
190# undef MULTI_CPU
191# define MULTI_CPU
192# else
193# define CPU_NAME cpu_arm1026
194# endif
195#endif
196
197#ifdef CONFIG_CPU_XSCALE
198# ifdef CPU_NAME
199# undef MULTI_CPU
200# define MULTI_CPU
201# else
202# define CPU_NAME cpu_xscale
203# endif
204#endif
205
206#ifdef CONFIG_CPU_XSC3
207# ifdef CPU_NAME
208# undef MULTI_CPU
209# define MULTI_CPU
210# else
211# define CPU_NAME cpu_xsc3
212# endif
213#endif
214
215#ifdef CONFIG_CPU_MOHAWK
216# ifdef CPU_NAME
217# undef MULTI_CPU
218# define MULTI_CPU
219# else
220# define CPU_NAME cpu_mohawk
221# endif
222#endif
223
224#ifdef CONFIG_CPU_FEROCEON
225# ifdef CPU_NAME
226# undef MULTI_CPU
227# define MULTI_CPU
228# else
229# define CPU_NAME cpu_feroceon
230# endif
231#endif
232
233#ifdef CONFIG_CPU_V6
234# ifdef CPU_NAME
235# undef MULTI_CPU
236# define MULTI_CPU
237# else
238# define CPU_NAME cpu_v6
239# endif
240#endif
241
242#ifdef CONFIG_CPU_V7
243# ifdef CPU_NAME
244# undef MULTI_CPU
245# define MULTI_CPU
246# else
247# define CPU_NAME cpu_v7
248# endif
249#endif
250
251#ifndef MULTI_CPU
252#define cpu_proc_init __glue(CPU_NAME,_proc_init)
253#define cpu_proc_fin __glue(CPU_NAME,_proc_fin)
254#define cpu_reset __glue(CPU_NAME,_reset)
255#define cpu_do_idle __glue(CPU_NAME,_do_idle)
256#define cpu_dcache_clean_area __glue(CPU_NAME,_dcache_clean_area)
257#define cpu_do_switch_mm __glue(CPU_NAME,_switch_mm)
258#define cpu_set_pte_ext __glue(CPU_NAME,_set_pte_ext)
259#define cpu_suspend_size __glue(CPU_NAME,_suspend_size)
260#define cpu_do_suspend __glue(CPU_NAME,_do_suspend)
261#define cpu_do_resume __glue(CPU_NAME,_do_resume)
262#endif
263
264#endif
diff --git a/arch/arm/include/asm/glue.h b/arch/arm/include/asm/glue.h
index 234a3fc1c78e..0ec35d1698aa 100644
--- a/arch/arm/include/asm/glue.h
+++ b/arch/arm/include/asm/glue.h
@@ -15,7 +15,6 @@
15 */ 15 */
16#ifdef __KERNEL__ 16#ifdef __KERNEL__
17 17
18
19#ifdef __STDC__ 18#ifdef __STDC__
20#define ____glue(name,fn) name##fn 19#define ____glue(name,fn) name##fn
21#else 20#else
@@ -23,141 +22,4 @@
23#endif 22#endif
24#define __glue(name,fn) ____glue(name,fn) 23#define __glue(name,fn) ____glue(name,fn)
25 24
26
27
28/*
29 * Data Abort Model
30 * ================
31 *
32 * We have the following to choose from:
33 * arm6 - ARM6 style
34 * arm7 - ARM7 style
35 * v4_early - ARMv4 without Thumb early abort handler
36 * v4t_late - ARMv4 with Thumb late abort handler
37 * v4t_early - ARMv4 with Thumb early abort handler
38 * v5tej_early - ARMv5 with Thumb and Java early abort handler
39 * xscale - ARMv5 with Thumb with Xscale extensions
40 * v6_early - ARMv6 generic early abort handler
41 * v7_early - ARMv7 generic early abort handler
42 */
43#undef CPU_DABORT_HANDLER
44#undef MULTI_DABORT
45
46#if defined(CONFIG_CPU_ARM610)
47# ifdef CPU_DABORT_HANDLER
48# define MULTI_DABORT 1
49# else
50# define CPU_DABORT_HANDLER cpu_arm6_data_abort
51# endif
52#endif
53
54#if defined(CONFIG_CPU_ARM710)
55# ifdef CPU_DABORT_HANDLER
56# define MULTI_DABORT 1
57# else
58# define CPU_DABORT_HANDLER cpu_arm7_data_abort
59# endif
60#endif
61
62#ifdef CONFIG_CPU_ABRT_LV4T
63# ifdef CPU_DABORT_HANDLER
64# define MULTI_DABORT 1
65# else
66# define CPU_DABORT_HANDLER v4t_late_abort
67# endif
68#endif
69
70#ifdef CONFIG_CPU_ABRT_EV4
71# ifdef CPU_DABORT_HANDLER
72# define MULTI_DABORT 1
73# else
74# define CPU_DABORT_HANDLER v4_early_abort
75# endif
76#endif
77
78#ifdef CONFIG_CPU_ABRT_EV4T
79# ifdef CPU_DABORT_HANDLER
80# define MULTI_DABORT 1
81# else
82# define CPU_DABORT_HANDLER v4t_early_abort
83# endif
84#endif
85
86#ifdef CONFIG_CPU_ABRT_EV5TJ
87# ifdef CPU_DABORT_HANDLER
88# define MULTI_DABORT 1
89# else
90# define CPU_DABORT_HANDLER v5tj_early_abort
91# endif
92#endif
93
94#ifdef CONFIG_CPU_ABRT_EV5T
95# ifdef CPU_DABORT_HANDLER
96# define MULTI_DABORT 1
97# else
98# define CPU_DABORT_HANDLER v5t_early_abort
99# endif
100#endif
101
102#ifdef CONFIG_CPU_ABRT_EV6
103# ifdef CPU_DABORT_HANDLER
104# define MULTI_DABORT 1
105# else
106# define CPU_DABORT_HANDLER v6_early_abort
107# endif
108#endif
109
110#ifdef CONFIG_CPU_ABRT_EV7
111# ifdef CPU_DABORT_HANDLER
112# define MULTI_DABORT 1
113# else
114# define CPU_DABORT_HANDLER v7_early_abort
115# endif
116#endif
117
118#ifndef CPU_DABORT_HANDLER
119#error Unknown data abort handler type
120#endif
121
122/*
123 * Prefetch Abort Model
124 * ================
125 *
126 * We have the following to choose from:
127 * legacy - no IFSR, no IFAR
128 * v6 - ARMv6: IFSR, no IFAR
129 * v7 - ARMv7: IFSR and IFAR
130 */
131
132#undef CPU_PABORT_HANDLER
133#undef MULTI_PABORT
134
135#ifdef CONFIG_CPU_PABRT_LEGACY
136# ifdef CPU_PABORT_HANDLER
137# define MULTI_PABORT 1
138# else
139# define CPU_PABORT_HANDLER legacy_pabort
140# endif
141#endif
142
143#ifdef CONFIG_CPU_PABRT_V6
144# ifdef CPU_PABORT_HANDLER
145# define MULTI_PABORT 1
146# else
147# define CPU_PABORT_HANDLER v6_pabort
148# endif
149#endif
150
151#ifdef CONFIG_CPU_PABRT_V7
152# ifdef CPU_PABORT_HANDLER
153# define MULTI_PABORT 1
154# else
155# define CPU_PABORT_HANDLER v7_pabort
156# endif
157#endif
158
159#ifndef CPU_PABORT_HANDLER
160#error Unknown prefetch abort handler type
161#endif
162
163#endif 25#endif
diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
index 8fdae9bc9abb..8ec535e11fd7 100644
--- a/arch/arm/include/asm/proc-fns.h
+++ b/arch/arm/include/asm/proc-fns.h
@@ -13,250 +13,86 @@
13 13
14#ifdef __KERNEL__ 14#ifdef __KERNEL__
15 15
16#include <asm/glue-proc.h>
17#include <asm/page.h>
16 18
17/* 19#ifndef __ASSEMBLY__
18 * Work out if we need multiple CPU support 20
19 */ 21struct mm_struct;
20#undef MULTI_CPU
21#undef CPU_NAME
22 22
23/* 23/*
24 * CPU_NAME - the prefix for CPU related functions 24 * Don't change this structure - ASM code relies on it.
25 */ 25 */
26 26extern struct processor {
27#ifdef CONFIG_CPU_ARM610 27 /* MISC
28# ifdef CPU_NAME 28 * get data abort address/flags
29# undef MULTI_CPU 29 */
30# define MULTI_CPU 30 void (*_data_abort)(unsigned long pc);
31# else 31 /*
32# define CPU_NAME cpu_arm6 32 * Retrieve prefetch fault address
33# endif 33 */
34#endif 34 unsigned long (*_prefetch_abort)(unsigned long lr);
35 35 /*
36#ifdef CONFIG_CPU_ARM7TDMI 36 * Set up any processor specifics
37# ifdef CPU_NAME 37 */
38# undef MULTI_CPU 38 void (*_proc_init)(void);
39# define MULTI_CPU 39 /*
40# else 40 * Disable any processor specifics
41# define CPU_NAME cpu_arm7tdmi 41 */
42# endif 42 void (*_proc_fin)(void);
43#endif 43 /*
44 44 * Special stuff for a reset
45#ifdef CONFIG_CPU_ARM710 45 */
46# ifdef CPU_NAME 46 void (*reset)(unsigned long addr) __attribute__((noreturn));
47# undef MULTI_CPU 47 /*
48# define MULTI_CPU 48 * Idle the processor
49# else 49 */
50# define CPU_NAME cpu_arm7 50 int (*_do_idle)(void);
51# endif 51 /*
52#endif 52 * Processor architecture specific
53 53 */
54#ifdef CONFIG_CPU_ARM720T 54 /*
55# ifdef CPU_NAME 55 * clean a virtual address range from the
56# undef MULTI_CPU 56 * D-cache without flushing the cache.
57# define MULTI_CPU 57 */
58# else 58 void (*dcache_clean_area)(void *addr, int size);
59# define CPU_NAME cpu_arm720 59
60# endif 60 /*
61#endif 61 * Set the page table
62 62 */
63#ifdef CONFIG_CPU_ARM740T 63 void (*switch_mm)(unsigned long pgd_phys, struct mm_struct *mm);
64# ifdef CPU_NAME 64 /*
65# undef MULTI_CPU 65 * Set a possibly extended PTE. Non-extended PTEs should
66# define MULTI_CPU 66 * ignore 'ext'.
67# else 67 */
68# define CPU_NAME cpu_arm740 68 void (*set_pte_ext)(pte_t *ptep, pte_t pte, unsigned int ext);
69# endif 69
70#endif 70 /* Suspend/resume */
71 71 unsigned int suspend_size;
72#ifdef CONFIG_CPU_ARM9TDMI 72 void (*do_suspend)(void *);
73# ifdef CPU_NAME 73 void (*do_resume)(void *);
74# undef MULTI_CPU 74} processor;
75# define MULTI_CPU
76# else
77# define CPU_NAME cpu_arm9tdmi
78# endif
79#endif
80
81#ifdef CONFIG_CPU_ARM920T
82# ifdef CPU_NAME
83# undef MULTI_CPU
84# define MULTI_CPU
85# else
86# define CPU_NAME cpu_arm920
87# endif
88#endif
89
90#ifdef CONFIG_CPU_ARM922T
91# ifdef CPU_NAME
92# undef MULTI_CPU
93# define MULTI_CPU
94# else
95# define CPU_NAME cpu_arm922
96# endif
97#endif
98
99#ifdef CONFIG_CPU_FA526
100# ifdef CPU_NAME
101# undef MULTI_CPU
102# define MULTI_CPU
103# else
104# define CPU_NAME cpu_fa526
105# endif
106#endif
107
108#ifdef CONFIG_CPU_ARM925T
109# ifdef CPU_NAME
110# undef MULTI_CPU
111# define MULTI_CPU
112# else
113# define CPU_NAME cpu_arm925
114# endif
115#endif
116
117#ifdef CONFIG_CPU_ARM926T
118# ifdef CPU_NAME
119# undef MULTI_CPU
120# define MULTI_CPU
121# else
122# define CPU_NAME cpu_arm926
123# endif
124#endif
125
126#ifdef CONFIG_CPU_ARM940T
127# ifdef CPU_NAME
128# undef MULTI_CPU
129# define MULTI_CPU
130# else
131# define CPU_NAME cpu_arm940
132# endif
133#endif
134
135#ifdef CONFIG_CPU_ARM946E
136# ifdef CPU_NAME
137# undef MULTI_CPU
138# define MULTI_CPU
139# else
140# define CPU_NAME cpu_arm946
141# endif
142#endif
143
144#ifdef CONFIG_CPU_SA110
145# ifdef CPU_NAME
146# undef MULTI_CPU
147# define MULTI_CPU
148# else
149# define CPU_NAME cpu_sa110
150# endif
151#endif
152
153#ifdef CONFIG_CPU_SA1100
154# ifdef CPU_NAME
155# undef MULTI_CPU
156# define MULTI_CPU
157# else
158# define CPU_NAME cpu_sa1100
159# endif
160#endif
161
162#ifdef CONFIG_CPU_ARM1020
163# ifdef CPU_NAME
164# undef MULTI_CPU
165# define MULTI_CPU
166# else
167# define CPU_NAME cpu_arm1020
168# endif
169#endif
170
171#ifdef CONFIG_CPU_ARM1020E
172# ifdef CPU_NAME
173# undef MULTI_CPU
174# define MULTI_CPU
175# else
176# define CPU_NAME cpu_arm1020e
177# endif
178#endif
179
180#ifdef CONFIG_CPU_ARM1022
181# ifdef CPU_NAME
182# undef MULTI_CPU
183# define MULTI_CPU
184# else
185# define CPU_NAME cpu_arm1022
186# endif
187#endif
188
189#ifdef CONFIG_CPU_ARM1026
190# ifdef CPU_NAME
191# undef MULTI_CPU
192# define MULTI_CPU
193# else
194# define CPU_NAME cpu_arm1026
195# endif
196#endif
197
198#ifdef CONFIG_CPU_XSCALE
199# ifdef CPU_NAME
200# undef MULTI_CPU
201# define MULTI_CPU
202# else
203# define CPU_NAME cpu_xscale
204# endif
205#endif
206
207#ifdef CONFIG_CPU_XSC3
208# ifdef CPU_NAME
209# undef MULTI_CPU
210# define MULTI_CPU
211# else
212# define CPU_NAME cpu_xsc3
213# endif
214#endif
215
216#ifdef CONFIG_CPU_MOHAWK
217# ifdef CPU_NAME
218# undef MULTI_CPU
219# define MULTI_CPU
220# else
221# define CPU_NAME cpu_mohawk
222# endif
223#endif
224
225#ifdef CONFIG_CPU_FEROCEON
226# ifdef CPU_NAME
227# undef MULTI_CPU
228# define MULTI_CPU
229# else
230# define CPU_NAME cpu_feroceon
231# endif
232#endif
233
234#ifdef CONFIG_CPU_V6
235# ifdef CPU_NAME
236# undef MULTI_CPU
237# define MULTI_CPU
238# else
239# define CPU_NAME cpu_v6
240# endif
241#endif
242
243#ifdef CONFIG_CPU_V7
244# ifdef CPU_NAME
245# undef MULTI_CPU
246# define MULTI_CPU
247# else
248# define CPU_NAME cpu_v7
249# endif
250#endif
251
252#ifndef __ASSEMBLY__
253 75
254#ifndef MULTI_CPU 76#ifndef MULTI_CPU
255#include <asm/cpu-single.h> 77extern void cpu_proc_init(void);
78extern void cpu_proc_fin(void);
79extern int cpu_do_idle(void);
80extern void cpu_dcache_clean_area(void *, int);
81extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm);
82extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
83extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
256#else 84#else
257#include <asm/cpu-multi32.h> 85#define cpu_proc_init() processor._proc_init()
86#define cpu_proc_fin() processor._proc_fin()
87#define cpu_reset(addr) processor.reset(addr)
88#define cpu_do_idle() processor._do_idle()
89#define cpu_dcache_clean_area(addr,sz) processor.dcache_clean_area(addr,sz)
90#define cpu_set_pte_ext(ptep,pte,ext) processor.set_pte_ext(ptep,pte,ext)
91#define cpu_do_switch_mm(pgd,mm) processor.switch_mm(pgd,mm)
258#endif 92#endif
259 93
94extern void cpu_resume(void);
95
260#include <asm/memory.h> 96#include <asm/memory.h>
261 97
262#ifdef CONFIG_MMU 98#ifdef CONFIG_MMU
diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h
index 67357baaeeeb..7a1f03c10f1b 100644
--- a/arch/arm/include/asm/processor.h
+++ b/arch/arm/include/asm/processor.h
@@ -95,7 +95,7 @@ extern void release_thread(struct task_struct *);
95 95
96unsigned long get_wchan(struct task_struct *p); 96unsigned long get_wchan(struct task_struct *p);
97 97
98#if __LINUX_ARM_ARCH__ == 6 98#if __LINUX_ARM_ARCH__ == 6 || defined(CONFIG_ARM_ERRATA_754327)
99#define cpu_relax() smp_mb() 99#define cpu_relax() smp_mb()
100#else 100#else
101#define cpu_relax() barrier() 101#define cpu_relax() barrier()
diff --git a/arch/arm/include/asm/smp_scu.h b/arch/arm/include/asm/smp_scu.h
index 2376835015d6..4eb6d005ffaa 100644
--- a/arch/arm/include/asm/smp_scu.h
+++ b/arch/arm/include/asm/smp_scu.h
@@ -1,7 +1,14 @@
1#ifndef __ASMARM_ARCH_SCU_H 1#ifndef __ASMARM_ARCH_SCU_H
2#define __ASMARM_ARCH_SCU_H 2#define __ASMARM_ARCH_SCU_H
3 3
4#define SCU_PM_NORMAL 0
5#define SCU_PM_DORMANT 2
6#define SCU_PM_POWEROFF 3
7
8#ifndef __ASSEMBLER__
4unsigned int scu_get_core_count(void __iomem *); 9unsigned int scu_get_core_count(void __iomem *);
5void scu_enable(void __iomem *); 10void scu_enable(void __iomem *);
11int scu_power_mode(void __iomem *, unsigned int);
12#endif
6 13
7#endif 14#endif
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 185ee822c935..74554f1742d7 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_MODULES) += armksyms.o module.o
29obj-$(CONFIG_ARTHUR) += arthur.o 29obj-$(CONFIG_ARTHUR) += arthur.o
30obj-$(CONFIG_ISA_DMA) += dma-isa.o 30obj-$(CONFIG_ISA_DMA) += dma-isa.o
31obj-$(CONFIG_PCI) += bios32.o isa.o 31obj-$(CONFIG_PCI) += bios32.o isa.o
32obj-$(CONFIG_PM) += sleep.o
32obj-$(CONFIG_HAVE_SCHED_CLOCK) += sched_clock.o 33obj-$(CONFIG_HAVE_SCHED_CLOCK) += sched_clock.o
33obj-$(CONFIG_SMP) += smp.o smp_tlb.o 34obj-$(CONFIG_SMP) += smp.o smp_tlb.o
34obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o 35obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index 82da66172132..927522cfc12e 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -13,6 +13,9 @@
13#include <linux/sched.h> 13#include <linux/sched.h>
14#include <linux/mm.h> 14#include <linux/mm.h>
15#include <linux/dma-mapping.h> 15#include <linux/dma-mapping.h>
16#include <asm/cacheflush.h>
17#include <asm/glue-df.h>
18#include <asm/glue-pf.h>
16#include <asm/mach/arch.h> 19#include <asm/mach/arch.h>
17#include <asm/thread_info.h> 20#include <asm/thread_info.h>
18#include <asm/memory.h> 21#include <asm/memory.h>
@@ -114,6 +117,14 @@ int main(void)
114#ifdef MULTI_PABORT 117#ifdef MULTI_PABORT
115 DEFINE(PROCESSOR_PABT_FUNC, offsetof(struct processor, _prefetch_abort)); 118 DEFINE(PROCESSOR_PABT_FUNC, offsetof(struct processor, _prefetch_abort));
116#endif 119#endif
120#ifdef MULTI_CPU
121 DEFINE(CPU_SLEEP_SIZE, offsetof(struct processor, suspend_size));
122 DEFINE(CPU_DO_SUSPEND, offsetof(struct processor, do_suspend));
123 DEFINE(CPU_DO_RESUME, offsetof(struct processor, do_resume));
124#endif
125#ifdef MULTI_CACHE
126 DEFINE(CACHE_FLUSH_KERN_ALL, offsetof(struct cpu_cache_fns, flush_kern_all));
127#endif
117 BLANK(); 128 BLANK();
118 DEFINE(DMA_BIDIRECTIONAL, DMA_BIDIRECTIONAL); 129 DEFINE(DMA_BIDIRECTIONAL, DMA_BIDIRECTIONAL);
119 DEFINE(DMA_TO_DEVICE, DMA_TO_DEVICE); 130 DEFINE(DMA_TO_DEVICE, DMA_TO_DEVICE);
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 2b46fea36c9f..e8d885676807 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -16,7 +16,8 @@
16 */ 16 */
17 17
18#include <asm/memory.h> 18#include <asm/memory.h>
19#include <asm/glue.h> 19#include <asm/glue-df.h>
20#include <asm/glue-pf.h>
20#include <asm/vfpmacros.h> 21#include <asm/vfpmacros.h>
21#include <mach/entry-macro.S> 22#include <mach/entry-macro.S>
22#include <asm/thread_notify.h> 23#include <asm/thread_notify.h>
diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
new file mode 100644
index 000000000000..bfad698a02e7
--- /dev/null
+++ b/arch/arm/kernel/sleep.S
@@ -0,0 +1,134 @@
1#include <linux/linkage.h>
2#include <linux/threads.h>
3#include <asm/asm-offsets.h>
4#include <asm/assembler.h>
5#include <asm/glue-cache.h>
6#include <asm/glue-proc.h>
7#include <asm/system.h>
8 .text
9
10/*
11 * Save CPU state for a suspend
12 * r1 = v:p offset
13 * r3 = virtual return function
14 * Note: sp is decremented to allocate space for CPU state on stack
15 * r0-r3,r9,r10,lr corrupted
16 */
17ENTRY(cpu_suspend)
18 mov r9, lr
19#ifdef MULTI_CPU
20 ldr r10, =processor
21 mov r2, sp @ current virtual SP
22 ldr r0, [r10, #CPU_SLEEP_SIZE] @ size of CPU sleep state
23 ldr ip, [r10, #CPU_DO_RESUME] @ virtual resume function
24 sub sp, sp, r0 @ allocate CPU state on stack
25 mov r0, sp @ save pointer
26 add ip, ip, r1 @ convert resume fn to phys
27 stmfd sp!, {r1, r2, r3, ip} @ save v:p, virt SP, retfn, phys resume fn
28 ldr r3, =sleep_save_sp
29 add r2, sp, r1 @ convert SP to phys
30#ifdef CONFIG_SMP
31 ALT_SMP(mrc p15, 0, lr, c0, c0, 5)
32 ALT_UP(mov lr, #0)
33 and lr, lr, #15
34 str r2, [r3, lr, lsl #2] @ save phys SP
35#else
36 str r2, [r3] @ save phys SP
37#endif
38 mov lr, pc
39 ldr pc, [r10, #CPU_DO_SUSPEND] @ save CPU state
40#else
41 mov r2, sp @ current virtual SP
42 ldr r0, =cpu_suspend_size
43 sub sp, sp, r0 @ allocate CPU state on stack
44 mov r0, sp @ save pointer
45 stmfd sp!, {r1, r2, r3} @ save v:p, virt SP, return fn
46 ldr r3, =sleep_save_sp
47 add r2, sp, r1 @ convert SP to phys
48#ifdef CONFIG_SMP
49 ALT_SMP(mrc p15, 0, lr, c0, c0, 5)
50 ALT_UP(mov lr, #0)
51 and lr, lr, #15
52 str r2, [r3, lr, lsl #2] @ save phys SP
53#else
54 str r2, [r3] @ save phys SP
55#endif
56 bl cpu_do_suspend
57#endif
58
59 @ flush data cache
60#ifdef MULTI_CACHE
61 ldr r10, =cpu_cache
62 mov lr, r9
63 ldr pc, [r10, #CACHE_FLUSH_KERN_ALL]
64#else
65 mov lr, r9
66 b __cpuc_flush_kern_all
67#endif
68ENDPROC(cpu_suspend)
69 .ltorg
70
71/*
72 * r0 = control register value
73 * r1 = v:p offset (preserved by cpu_do_resume)
74 * r2 = phys page table base
75 * r3 = L1 section flags
76 */
77ENTRY(cpu_resume_mmu)
78 adr r4, cpu_resume_turn_mmu_on
79 mov r4, r4, lsr #20
80 orr r3, r3, r4, lsl #20
81 ldr r5, [r2, r4, lsl #2] @ save old mapping
82 str r3, [r2, r4, lsl #2] @ setup 1:1 mapping for mmu code
83 sub r2, r2, r1
84 ldr r3, =cpu_resume_after_mmu
85 bic r1, r0, #CR_C @ ensure D-cache is disabled
86 b cpu_resume_turn_mmu_on
87ENDPROC(cpu_resume_mmu)
88 .ltorg
89 .align 5
90cpu_resume_turn_mmu_on:
91 mcr p15, 0, r1, c1, c0, 0 @ turn on MMU, I-cache, etc
92 mrc p15, 0, r1, c0, c0, 0 @ read id reg
93 mov r1, r1
94 mov r1, r1
95 mov pc, r3 @ jump to virtual address
96ENDPROC(cpu_resume_turn_mmu_on)
97cpu_resume_after_mmu:
98 str r5, [r2, r4, lsl #2] @ restore old mapping
99 mcr p15, 0, r0, c1, c0, 0 @ turn on D-cache
100 mov pc, lr
101ENDPROC(cpu_resume_after_mmu)
102
103/*
104 * Note: Yes, part of the following code is located into the .data section.
105 * This is to allow sleep_save_sp to be accessed with a relative load
106 * while we can't rely on any MMU translation. We could have put
107 * sleep_save_sp in the .text section as well, but some setups might
108 * insist on it to be truly read-only.
109 */
110 .data
111 .align
112ENTRY(cpu_resume)
113#ifdef CONFIG_SMP
114 adr r0, sleep_save_sp
115 ALT_SMP(mrc p15, 0, r1, c0, c0, 5)
116 ALT_UP(mov r1, #0)
117 and r1, r1, #15
118 ldr r0, [r0, r1, lsl #2] @ stack phys addr
119#else
120 ldr r0, sleep_save_sp @ stack phys addr
121#endif
122 msr cpsr_c, #PSR_I_BIT | PSR_F_BIT | SVC_MODE @ set SVC, irqs off
123#ifdef MULTI_CPU
124 ldmia r0!, {r1, sp, lr, pc} @ load v:p, stack, return fn, resume fn
125#else
126 ldmia r0!, {r1, sp, lr} @ load v:p, stack, return fn
127 b cpu_do_resume
128#endif
129ENDPROC(cpu_resume)
130
131sleep_save_sp:
132 .rept CONFIG_NR_CPUS
133 .long 0 @ preserve stack phys ptr here
134 .endr
diff --git a/arch/arm/kernel/smp_scu.c b/arch/arm/kernel/smp_scu.c
index 9ab4149bd983..a1e757c3439b 100644
--- a/arch/arm/kernel/smp_scu.c
+++ b/arch/arm/kernel/smp_scu.c
@@ -50,3 +50,26 @@ void __init scu_enable(void __iomem *scu_base)
50 */ 50 */
51 flush_cache_all(); 51 flush_cache_all();
52} 52}
53
54/*
55 * Set the executing CPUs power mode as defined. This will be in
56 * preparation for it executing a WFI instruction.
57 *
58 * This function must be called with preemption disabled, and as it
59 * has the side effect of disabling coherency, caches must have been
60 * flushed. Interrupts must also have been disabled.
61 */
62int scu_power_mode(void __iomem *scu_base, unsigned int mode)
63{
64 unsigned int val;
65 int cpu = smp_processor_id();
66
67 if (mode > 3 || mode == 1 || cpu > 3)
68 return -EINVAL;
69
70 val = __raw_readb(scu_base + SCU_CPU_STATUS + cpu) & ~0x03;
71 val |= mode;
72 __raw_writeb(val, scu_base + SCU_CPU_STATUS + cpu);
73
74 return 0;
75}
diff --git a/arch/arm/mach-at91/board-snapper9260.c b/arch/arm/mach-at91/board-snapper9260.c
index 0a99b3cedd7a..17f7d9b32142 100644
--- a/arch/arm/mach-at91/board-snapper9260.c
+++ b/arch/arm/mach-at91/board-snapper9260.c
@@ -153,6 +153,7 @@ static struct i2c_board_info __initdata snapper9260_i2c_devices[] = {
153 { 153 {
154 /* RTC */ 154 /* RTC */
155 I2C_BOARD_INFO("isl1208", 0x6f), 155 I2C_BOARD_INFO("isl1208", 0x6f),
156 .irq = gpio_to_irq(AT91_PIN_PA31),
156 }, 157 },
157}; 158};
158 159
diff --git a/arch/arm/mach-at91/include/mach/gpio.h b/arch/arm/mach-at91/include/mach/gpio.h
index bfdd8ab26dc8..ddeb64536756 100644
--- a/arch/arm/mach-at91/include/mach/gpio.h
+++ b/arch/arm/mach-at91/include/mach/gpio.h
@@ -220,15 +220,8 @@ extern void at91_gpio_resume(void);
220#define gpio_set_value __gpio_set_value 220#define gpio_set_value __gpio_set_value
221#define gpio_cansleep __gpio_cansleep 221#define gpio_cansleep __gpio_cansleep
222 222
223static inline int gpio_to_irq(unsigned gpio) 223#define gpio_to_irq(gpio) (gpio)
224{ 224#define irq_to_gpio(irq) (irq)
225 return gpio;
226}
227
228static inline int irq_to_gpio(unsigned irq)
229{
230 return irq;
231}
232 225
233#endif /* __ASSEMBLY__ */ 226#endif /* __ASSEMBLY__ */
234 227
diff --git a/arch/arm/mach-ep93xx/edb93xx.c b/arch/arm/mach-ep93xx/edb93xx.c
index 4b0431652131..9969bb115f60 100644
--- a/arch/arm/mach-ep93xx/edb93xx.c
+++ b/arch/arm/mach-ep93xx/edb93xx.c
@@ -30,8 +30,13 @@
30#include <linux/gpio.h> 30#include <linux/gpio.h>
31#include <linux/i2c.h> 31#include <linux/i2c.h>
32#include <linux/i2c-gpio.h> 32#include <linux/i2c-gpio.h>
33#include <linux/spi/spi.h>
34
35#include <sound/cs4271.h>
33 36
34#include <mach/hardware.h> 37#include <mach/hardware.h>
38#include <mach/fb.h>
39#include <mach/ep93xx_spi.h>
35 40
36#include <asm/mach-types.h> 41#include <asm/mach-types.h>
37#include <asm/mach/arch.h> 42#include <asm/mach/arch.h>
@@ -93,6 +98,83 @@ static void __init edb93xx_register_i2c(void)
93 98
94 99
95/************************************************************************* 100/*************************************************************************
101 * EDB93xx SPI peripheral handling
102 *************************************************************************/
103static struct cs4271_platform_data edb93xx_cs4271_data = {
104 .gpio_nreset = -EINVAL, /* filled in later */
105};
106
107static int edb93xx_cs4271_hw_setup(struct spi_device *spi)
108{
109 return gpio_request_one(EP93XX_GPIO_LINE_EGPIO6,
110 GPIOF_OUT_INIT_HIGH, spi->modalias);
111}
112
113static void edb93xx_cs4271_hw_cleanup(struct spi_device *spi)
114{
115 gpio_free(EP93XX_GPIO_LINE_EGPIO6);
116}
117
118static void edb93xx_cs4271_hw_cs_control(struct spi_device *spi, int value)
119{
120 gpio_set_value(EP93XX_GPIO_LINE_EGPIO6, value);
121}
122
123static struct ep93xx_spi_chip_ops edb93xx_cs4271_hw = {
124 .setup = edb93xx_cs4271_hw_setup,
125 .cleanup = edb93xx_cs4271_hw_cleanup,
126 .cs_control = edb93xx_cs4271_hw_cs_control,
127};
128
129static struct spi_board_info edb93xx_spi_board_info[] __initdata = {
130 {
131 .modalias = "cs4271",
132 .platform_data = &edb93xx_cs4271_data,
133 .controller_data = &edb93xx_cs4271_hw,
134 .max_speed_hz = 6000000,
135 .bus_num = 0,
136 .chip_select = 0,
137 .mode = SPI_MODE_3,
138 },
139};
140
141static struct ep93xx_spi_info edb93xx_spi_info __initdata = {
142 .num_chipselect = ARRAY_SIZE(edb93xx_spi_board_info),
143};
144
145static void __init edb93xx_register_spi(void)
146{
147 if (machine_is_edb9301() || machine_is_edb9302())
148 edb93xx_cs4271_data.gpio_nreset = EP93XX_GPIO_LINE_EGPIO1;
149 else if (machine_is_edb9302a() || machine_is_edb9307a())
150 edb93xx_cs4271_data.gpio_nreset = EP93XX_GPIO_LINE_H(2);
151 else if (machine_is_edb9315a())
152 edb93xx_cs4271_data.gpio_nreset = EP93XX_GPIO_LINE_EGPIO14;
153
154 ep93xx_register_spi(&edb93xx_spi_info, edb93xx_spi_board_info,
155 ARRAY_SIZE(edb93xx_spi_board_info));
156}
157
158
159/*************************************************************************
160 * EDB93xx I2S
161 *************************************************************************/
162static int __init edb93xx_has_audio(void)
163{
164 return (machine_is_edb9301() || machine_is_edb9302() ||
165 machine_is_edb9302a() || machine_is_edb9307a() ||
166 machine_is_edb9315a());
167}
168
169static void __init edb93xx_register_i2s(void)
170{
171 if (edb93xx_has_audio()) {
172 ep93xx_register_i2s();
173 }
174}
175
176
177/*************************************************************************
96 * EDB93xx pwm 178 * EDB93xx pwm
97 *************************************************************************/ 179 *************************************************************************/
98static void __init edb93xx_register_pwm(void) 180static void __init edb93xx_register_pwm(void)
@@ -111,13 +193,47 @@ static void __init edb93xx_register_pwm(void)
111} 193}
112 194
113 195
196/*************************************************************************
197 * EDB93xx framebuffer
198 *************************************************************************/
199static struct ep93xxfb_mach_info __initdata edb93xxfb_info = {
200 .num_modes = EP93XXFB_USE_MODEDB,
201 .bpp = 16,
202 .flags = 0,
203};
204
205static int __init edb93xx_has_fb(void)
206{
207 /* These platforms have an ep93xx with video capability */
208 return machine_is_edb9307() || machine_is_edb9307a() ||
209 machine_is_edb9312() || machine_is_edb9315() ||
210 machine_is_edb9315a();
211}
212
213static void __init edb93xx_register_fb(void)
214{
215 if (!edb93xx_has_fb())
216 return;
217
218 if (machine_is_edb9307a() || machine_is_edb9315a())
219 edb93xxfb_info.flags |= EP93XXFB_USE_SDCSN0;
220 else
221 edb93xxfb_info.flags |= EP93XXFB_USE_SDCSN3;
222
223 ep93xx_register_fb(&edb93xxfb_info);
224}
225
226
114static void __init edb93xx_init_machine(void) 227static void __init edb93xx_init_machine(void)
115{ 228{
116 ep93xx_init_devices(); 229 ep93xx_init_devices();
117 edb93xx_register_flash(); 230 edb93xx_register_flash();
118 ep93xx_register_eth(&edb93xx_eth_data, 1); 231 ep93xx_register_eth(&edb93xx_eth_data, 1);
119 edb93xx_register_i2c(); 232 edb93xx_register_i2c();
233 edb93xx_register_spi();
234 edb93xx_register_i2s();
120 edb93xx_register_pwm(); 235 edb93xx_register_pwm();
236 edb93xx_register_fb();
121} 237}
122 238
123 239
diff --git a/arch/arm/mach-ep93xx/gpio.c b/arch/arm/mach-ep93xx/gpio.c
index bec34b834958..a889fa7c3ba1 100644
--- a/arch/arm/mach-ep93xx/gpio.c
+++ b/arch/arm/mach-ep93xx/gpio.c
@@ -61,7 +61,7 @@ static inline void ep93xx_gpio_int_mask(unsigned line)
61 gpio_int_unmasked[line >> 3] &= ~(1 << (line & 7)); 61 gpio_int_unmasked[line >> 3] &= ~(1 << (line & 7));
62} 62}
63 63
64void ep93xx_gpio_int_debounce(unsigned int irq, int enable) 64static void ep93xx_gpio_int_debounce(unsigned int irq, bool enable)
65{ 65{
66 int line = irq_to_gpio(irq); 66 int line = irq_to_gpio(irq);
67 int port = line >> 3; 67 int port = line >> 3;
@@ -75,7 +75,6 @@ void ep93xx_gpio_int_debounce(unsigned int irq, int enable)
75 __raw_writeb(gpio_int_debounce[port], 75 __raw_writeb(gpio_int_debounce[port],
76 EP93XX_GPIO_REG(int_debounce_register_offset[port])); 76 EP93XX_GPIO_REG(int_debounce_register_offset[port]));
77} 77}
78EXPORT_SYMBOL(ep93xx_gpio_int_debounce);
79 78
80static void ep93xx_gpio_ab_irq_handler(unsigned int irq, struct irq_desc *desc) 79static void ep93xx_gpio_ab_irq_handler(unsigned int irq, struct irq_desc *desc)
81{ 80{
@@ -335,6 +334,20 @@ static void ep93xx_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
335 local_irq_restore(flags); 334 local_irq_restore(flags);
336} 335}
337 336
337static int ep93xx_gpio_set_debounce(struct gpio_chip *chip,
338 unsigned offset, unsigned debounce)
339{
340 int gpio = chip->base + offset;
341 int irq = gpio_to_irq(gpio);
342
343 if (irq < 0)
344 return -EINVAL;
345
346 ep93xx_gpio_int_debounce(irq, debounce ? true : false);
347
348 return 0;
349}
350
338static void ep93xx_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) 351static void ep93xx_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
339{ 352{
340 struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip); 353 struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip);
@@ -434,6 +447,18 @@ void __init ep93xx_gpio_init(void)
434 EP93XX_SYSCON_DEVCFG_GONIDE | 447 EP93XX_SYSCON_DEVCFG_GONIDE |
435 EP93XX_SYSCON_DEVCFG_HONIDE); 448 EP93XX_SYSCON_DEVCFG_HONIDE);
436 449
437 for (i = 0; i < ARRAY_SIZE(ep93xx_gpio_banks); i++) 450 for (i = 0; i < ARRAY_SIZE(ep93xx_gpio_banks); i++) {
438 gpiochip_add(&ep93xx_gpio_banks[i].chip); 451 struct gpio_chip *chip = &ep93xx_gpio_banks[i].chip;
452
453 /*
454 * Ports A, B, and F support input debouncing when
455 * used as interrupts.
456 */
457 if (!strcmp(chip->label, "A") ||
458 !strcmp(chip->label, "B") ||
459 !strcmp(chip->label, "F"))
460 chip->set_debounce = ep93xx_gpio_set_debounce;
461
462 gpiochip_add(chip);
463 }
439} 464}
diff --git a/arch/arm/mach-ep93xx/include/mach/gpio.h b/arch/arm/mach-ep93xx/include/mach/gpio.h
index c991b149bdf2..c57152c231f1 100644
--- a/arch/arm/mach-ep93xx/include/mach/gpio.h
+++ b/arch/arm/mach-ep93xx/include/mach/gpio.h
@@ -99,8 +99,6 @@
99/* maximum value for irq capable line identifiers */ 99/* maximum value for irq capable line identifiers */
100#define EP93XX_GPIO_LINE_MAX_IRQ EP93XX_GPIO_LINE_F(7) 100#define EP93XX_GPIO_LINE_MAX_IRQ EP93XX_GPIO_LINE_F(7)
101 101
102extern void ep93xx_gpio_int_debounce(unsigned int irq, int enable);
103
104/* new generic GPIO API - see Documentation/gpio.txt */ 102/* new generic GPIO API - see Documentation/gpio.txt */
105 103
106#include <asm-generic/gpio.h> 104#include <asm-generic/gpio.h>
diff --git a/arch/arm/mach-footbridge/dc21285-timer.c b/arch/arm/mach-footbridge/dc21285-timer.c
index bc5e83fb5819..a921fe92b858 100644
--- a/arch/arm/mach-footbridge/dc21285-timer.c
+++ b/arch/arm/mach-footbridge/dc21285-timer.c
@@ -4,10 +4,11 @@
4 * Copyright (C) 1998 Russell King. 4 * Copyright (C) 1998 Russell King.
5 * Copyright (C) 1998 Phil Blundell 5 * Copyright (C) 1998 Phil Blundell
6 */ 6 */
7#include <linux/clockchips.h>
8#include <linux/clocksource.h>
7#include <linux/init.h> 9#include <linux/init.h>
8#include <linux/interrupt.h> 10#include <linux/interrupt.h>
9#include <linux/irq.h> 11#include <linux/irq.h>
10#include <linux/spinlock.h>
11 12
12#include <asm/irq.h> 13#include <asm/irq.h>
13 14
@@ -16,32 +17,76 @@
16 17
17#include "common.h" 18#include "common.h"
18 19
19/* 20static cycle_t cksrc_dc21285_read(struct clocksource *cs)
20 * Footbridge timer 1 support. 21{
21 */ 22 return cs->mask - *CSR_TIMER2_VALUE;
22static unsigned long timer1_latch; 23}
23 24
24static unsigned long timer1_gettimeoffset (void) 25static int cksrc_dc21285_enable(struct clocksource *cs)
25{ 26{
26 unsigned long value = timer1_latch - *CSR_TIMER1_VALUE; 27 *CSR_TIMER2_LOAD = cs->mask;
28 *CSR_TIMER2_CLR = 0;
29 *CSR_TIMER2_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_DIV16;
30 return 0;
31}
27 32
28 return ((tick_nsec / 1000) * value) / timer1_latch; 33static int cksrc_dc21285_disable(struct clocksource *cs)
34{
35 *CSR_TIMER2_CNTL = 0;
29} 36}
30 37
31static irqreturn_t 38static struct clocksource cksrc_dc21285 = {
32timer1_interrupt(int irq, void *dev_id) 39 .name = "dc21285_timer2",
40 .rating = 200,
41 .read = cksrc_dc21285_read,
42 .enable = cksrc_dc21285_enable,
43 .disable = cksrc_dc21285_disable,
44 .mask = CLOCKSOURCE_MASK(24),
45 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
46};
47
48static void ckevt_dc21285_set_mode(enum clock_event_mode mode,
49 struct clock_event_device *c)
33{ 50{
51 switch (mode) {
52 case CLOCK_EVT_MODE_RESUME:
53 case CLOCK_EVT_MODE_PERIODIC:
54 *CSR_TIMER1_CLR = 0;
55 *CSR_TIMER1_LOAD = (mem_fclk_21285 + 8 * HZ) / (16 * HZ);
56 *CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD |
57 TIMER_CNTL_DIV16;
58 break;
59
60 default:
61 *CSR_TIMER1_CNTL = 0;
62 break;
63 }
64}
65
66static struct clock_event_device ckevt_dc21285 = {
67 .name = "dc21285_timer1",
68 .features = CLOCK_EVT_FEAT_PERIODIC,
69 .rating = 200,
70 .irq = IRQ_TIMER1,
71 .set_mode = ckevt_dc21285_set_mode,
72};
73
74static irqreturn_t timer1_interrupt(int irq, void *dev_id)
75{
76 struct clock_event_device *ce = dev_id;
77
34 *CSR_TIMER1_CLR = 0; 78 *CSR_TIMER1_CLR = 0;
35 79
36 timer_tick(); 80 ce->event_handler(ce);
37 81
38 return IRQ_HANDLED; 82 return IRQ_HANDLED;
39} 83}
40 84
41static struct irqaction footbridge_timer_irq = { 85static struct irqaction footbridge_timer_irq = {
42 .name = "Timer1 timer tick", 86 .name = "dc21285_timer1",
43 .handler = timer1_interrupt, 87 .handler = timer1_interrupt,
44 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, 88 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
89 .dev_id = &ckevt_dc21285,
45}; 90};
46 91
47/* 92/*
@@ -49,16 +94,19 @@ static struct irqaction footbridge_timer_irq = {
49 */ 94 */
50static void __init footbridge_timer_init(void) 95static void __init footbridge_timer_init(void)
51{ 96{
52 timer1_latch = (mem_fclk_21285 + 8 * HZ) / (16 * HZ); 97 struct clock_event_device *ce = &ckevt_dc21285;
98
99 clocksource_register_hz(&cksrc_dc21285, (mem_fclk_21285 + 8) / 16);
100
101 setup_irq(ce->irq, &footbridge_timer_irq);
53 102
54 *CSR_TIMER1_CLR = 0; 103 clockevents_calc_mult_shift(ce, mem_fclk_21285, 5);
55 *CSR_TIMER1_LOAD = timer1_latch; 104 ce->max_delta_ns = clockevent_delta2ns(0xffffff, ce);
56 *CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD | TIMER_CNTL_DIV16; 105 ce->min_delta_ns = clockevent_delta2ns(0x000004, ce);
57 106
58 setup_irq(IRQ_TIMER1, &footbridge_timer_irq); 107 clockevents_register_device(ce);
59} 108}
60 109
61struct sys_timer footbridge_timer = { 110struct sys_timer footbridge_timer = {
62 .init = footbridge_timer_init, 111 .init = footbridge_timer_init,
63 .offset = timer1_gettimeoffset,
64}; 112};
diff --git a/arch/arm/mach-footbridge/isa-timer.c b/arch/arm/mach-footbridge/isa-timer.c
index f488fa2082d7..441c6ce0d555 100644
--- a/arch/arm/mach-footbridge/isa-timer.c
+++ b/arch/arm/mach-footbridge/isa-timer.c
@@ -4,10 +4,13 @@
4 * Copyright (C) 1998 Russell King. 4 * Copyright (C) 1998 Russell King.
5 * Copyright (C) 1998 Phil Blundell 5 * Copyright (C) 1998 Phil Blundell
6 */ 6 */
7#include <linux/clockchips.h>
8#include <linux/clocksource.h>
7#include <linux/init.h> 9#include <linux/init.h>
8#include <linux/interrupt.h> 10#include <linux/interrupt.h>
9#include <linux/irq.h> 11#include <linux/irq.h>
10#include <linux/io.h> 12#include <linux/io.h>
13#include <linux/timex.h>
11 14
12#include <asm/irq.h> 15#include <asm/irq.h>
13 16
@@ -15,77 +18,115 @@
15 18
16#include "common.h" 19#include "common.h"
17 20
18/* 21#define PIT_MODE 0x43
19 * ISA timer tick support 22#define PIT_CH0 0x40
20 */ 23
21#define mSEC_10_from_14 ((14318180 + 100) / 200) 24#define PIT_LATCH ((PIT_TICK_RATE + HZ / 2) / HZ)
22 25
23static unsigned long isa_gettimeoffset(void) 26static cycle_t pit_read(struct clocksource *cs)
24{ 27{
28 unsigned long flags;
29 static int old_count;
30 static u32 old_jifs;
25 int count; 31 int count;
32 u32 jifs;
26 33
27 static int count_p = (mSEC_10_from_14/6); /* for the first call after boot */ 34 raw_local_irq_save(flags);
28 static unsigned long jiffies_p = 0;
29 35
30 /* 36 jifs = jiffies;
31 * cache volatile jiffies temporarily; we have IRQs turned off. 37 outb_p(0x00, PIT_MODE); /* latch the count */
32 */ 38 count = inb_p(PIT_CH0); /* read the latched count */
33 unsigned long jiffies_t; 39 count |= inb_p(PIT_CH0) << 8;
34 40
35 /* timer count may underflow right here */ 41 if (count > old_count && jifs == old_jifs)
36 outb_p(0x00, 0x43); /* latch the count ASAP */ 42 count = old_count;
37 43
38 count = inb_p(0x40); /* read the latched count */ 44 old_count = count;
45 old_jifs = jifs;
39 46
40 /* 47 raw_local_irq_restore(flags);
41 * We do this guaranteed double memory access instead of a _p
42 * postfix in the previous port access. Wheee, hackady hack
43 */
44 jiffies_t = jiffies;
45 48
46 count |= inb_p(0x40) << 8; 49 count = (PIT_LATCH - 1) - count;
47 50
48 /* Detect timer underflows. If we haven't had a timer tick since 51 return (cycle_t)(jifs * PIT_LATCH) + count;
49 the last time we were called, and time is apparently going 52}
50 backwards, the counter must have wrapped during this routine. */
51 if ((jiffies_t == jiffies_p) && (count > count_p))
52 count -= (mSEC_10_from_14/6);
53 else
54 jiffies_p = jiffies_t;
55 53
56 count_p = count; 54static struct clocksource pit_cs = {
55 .name = "pit",
56 .rating = 110,
57 .read = pit_read,
58 .mask = CLOCKSOURCE_MASK(32),
59};
57 60
58 count = (((mSEC_10_from_14/6)-1) - count) * (tick_nsec / 1000); 61static void pit_set_mode(enum clock_event_mode mode,
59 count = (count + (mSEC_10_from_14/6)/2) / (mSEC_10_from_14/6); 62 struct clock_event_device *evt)
63{
64 unsigned long flags;
65
66 raw_local_irq_save(flags);
67
68 switch (mode) {
69 case CLOCK_EVT_MODE_PERIODIC:
70 outb_p(0x34, PIT_MODE);
71 outb_p(PIT_LATCH & 0xff, PIT_CH0);
72 outb_p(PIT_LATCH >> 8, PIT_CH0);
73 break;
74
75 case CLOCK_EVT_MODE_SHUTDOWN:
76 case CLOCK_EVT_MODE_UNUSED:
77 outb_p(0x30, PIT_MODE);
78 outb_p(0, PIT_CH0);
79 outb_p(0, PIT_CH0);
80 break;
81
82 case CLOCK_EVT_MODE_ONESHOT:
83 case CLOCK_EVT_MODE_RESUME:
84 break;
85 }
86 local_irq_restore(flags);
87}
60 88
61 return count; 89static int pit_set_next_event(unsigned long delta,
90 struct clock_event_device *evt)
91{
92 return 0;
62} 93}
63 94
64static irqreturn_t 95static struct clock_event_device pit_ce = {
65isa_timer_interrupt(int irq, void *dev_id) 96 .name = "pit",
97 .features = CLOCK_EVT_FEAT_PERIODIC,
98 .set_mode = pit_set_mode,
99 .set_next_event = pit_set_next_event,
100 .shift = 32,
101};
102
103static irqreturn_t pit_timer_interrupt(int irq, void *dev_id)
66{ 104{
67 timer_tick(); 105 struct clock_event_device *ce = dev_id;
106 ce->event_handler(ce);
68 return IRQ_HANDLED; 107 return IRQ_HANDLED;
69} 108}
70 109
71static struct irqaction isa_timer_irq = { 110static struct irqaction pit_timer_irq = {
72 .name = "ISA timer tick", 111 .name = "pit",
73 .handler = isa_timer_interrupt, 112 .handler = pit_timer_interrupt,
74 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, 113 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
114 .dev_id = &pit_ce,
75}; 115};
76 116
77static void __init isa_timer_init(void) 117static void __init isa_timer_init(void)
78{ 118{
79 /* enable PIT timer */ 119 pit_ce.cpumask = cpumask_of(smp_processor_id());
80 /* set for periodic (4) and LSB/MSB write (0x30) */ 120 pit_ce.mult = div_sc(PIT_TICK_RATE, NSEC_PER_SEC, pit_ce.shift);
81 outb(0x34, 0x43); 121 pit_ce.max_delta_ns = clockevent_delta2ns(0x7fff, &pit_ce);
82 outb((mSEC_10_from_14/6) & 0xFF, 0x40); 122 pit_ce.min_delta_ns = clockevent_delta2ns(0x000f, &pit_ce);
83 outb((mSEC_10_from_14/6) >> 8, 0x40); 123
124 clocksource_register_hz(&pit_cs, PIT_TICK_RATE);
84 125
85 setup_irq(IRQ_ISA_TIMER, &isa_timer_irq); 126 setup_irq(pit_ce.irq, &pit_timer_irq);
127 clockevents_register_device(&pit_ce);
86} 128}
87 129
88struct sys_timer isa_timer = { 130struct sys_timer isa_timer = {
89 .init = isa_timer_init, 131 .init = isa_timer_init,
90 .offset = isa_gettimeoffset,
91}; 132};
diff --git a/arch/arm/mach-gemini/board-nas4220b.c b/arch/arm/mach-gemini/board-nas4220b.c
index 2ba096de0034..0cf7a07c3f3f 100644
--- a/arch/arm/mach-gemini/board-nas4220b.c
+++ b/arch/arm/mach-gemini/board-nas4220b.c
@@ -98,6 +98,7 @@ static void __init ib4220b_init(void)
98 platform_register_pflash(SZ_16M, NULL, 0); 98 platform_register_pflash(SZ_16M, NULL, 0);
99 platform_device_register(&ib4220b_led_device); 99 platform_device_register(&ib4220b_led_device);
100 platform_device_register(&ib4220b_key_device); 100 platform_device_register(&ib4220b_key_device);
101 platform_register_rtc();
101} 102}
102 103
103MACHINE_START(NAS4220B, "Raidsonic NAS IB-4220-B") 104MACHINE_START(NAS4220B, "Raidsonic NAS IB-4220-B")
diff --git a/arch/arm/mach-gemini/board-rut1xx.c b/arch/arm/mach-gemini/board-rut1xx.c
index a9a0d8b01942..4fa09af99495 100644
--- a/arch/arm/mach-gemini/board-rut1xx.c
+++ b/arch/arm/mach-gemini/board-rut1xx.c
@@ -82,6 +82,7 @@ static void __init rut1xx_init(void)
82 platform_register_pflash(SZ_8M, NULL, 0); 82 platform_register_pflash(SZ_8M, NULL, 0);
83 platform_device_register(&rut1xx_leds); 83 platform_device_register(&rut1xx_leds);
84 platform_device_register(&rut1xx_keys_device); 84 platform_device_register(&rut1xx_keys_device);
85 platform_register_rtc();
85} 86}
86 87
87MACHINE_START(RUT100, "Teltonika RUT100") 88MACHINE_START(RUT100, "Teltonika RUT100")
diff --git a/arch/arm/mach-gemini/board-wbd111.c b/arch/arm/mach-gemini/board-wbd111.c
index 8b88d50d4337..af7b68a6b258 100644
--- a/arch/arm/mach-gemini/board-wbd111.c
+++ b/arch/arm/mach-gemini/board-wbd111.c
@@ -130,6 +130,7 @@ static void __init wbd111_init(void)
130 wbd111_num_partitions); 130 wbd111_num_partitions);
131 platform_device_register(&wbd111_leds_device); 131 platform_device_register(&wbd111_leds_device);
132 platform_device_register(&wbd111_keys_device); 132 platform_device_register(&wbd111_keys_device);
133 platform_register_rtc();
133} 134}
134 135
135MACHINE_START(WBD111, "Wiliboard WBD-111") 136MACHINE_START(WBD111, "Wiliboard WBD-111")
diff --git a/arch/arm/mach-gemini/board-wbd222.c b/arch/arm/mach-gemini/board-wbd222.c
index 1eebcecd1c33..99e5bbecf923 100644
--- a/arch/arm/mach-gemini/board-wbd222.c
+++ b/arch/arm/mach-gemini/board-wbd222.c
@@ -130,6 +130,7 @@ static void __init wbd222_init(void)
130 wbd222_num_partitions); 130 wbd222_num_partitions);
131 platform_device_register(&wbd222_leds_device); 131 platform_device_register(&wbd222_leds_device);
132 platform_device_register(&wbd222_keys_device); 132 platform_device_register(&wbd222_keys_device);
133 platform_register_rtc();
133} 134}
134 135
135MACHINE_START(WBD222, "Wiliboard WBD-222") 136MACHINE_START(WBD222, "Wiliboard WBD-222")
diff --git a/arch/arm/mach-gemini/common.h b/arch/arm/mach-gemini/common.h
index 9392834a214f..7670c39acb2f 100644
--- a/arch/arm/mach-gemini/common.h
+++ b/arch/arm/mach-gemini/common.h
@@ -18,6 +18,7 @@ extern void gemini_map_io(void);
18extern void gemini_init_irq(void); 18extern void gemini_init_irq(void);
19extern void gemini_timer_init(void); 19extern void gemini_timer_init(void);
20extern void gemini_gpio_init(void); 20extern void gemini_gpio_init(void);
21extern void platform_register_rtc(void);
21 22
22/* Common platform devices registration functions */ 23/* Common platform devices registration functions */
23extern int platform_register_uart(void); 24extern int platform_register_uart(void);
diff --git a/arch/arm/mach-gemini/devices.c b/arch/arm/mach-gemini/devices.c
index 6b525253d027..5cff29818b73 100644
--- a/arch/arm/mach-gemini/devices.c
+++ b/arch/arm/mach-gemini/devices.c
@@ -90,3 +90,29 @@ int platform_register_pflash(unsigned int size, struct mtd_partition *parts,
90 90
91 return platform_device_register(&pflash_device); 91 return platform_device_register(&pflash_device);
92} 92}
93
94static struct resource gemini_rtc_resources[] = {
95 [0] = {
96 .start = GEMINI_RTC_BASE,
97 .end = GEMINI_RTC_BASE + 0x24,
98 .flags = IORESOURCE_MEM,
99 },
100 [1] = {
101 .start = IRQ_RTC,
102 .end = IRQ_RTC,
103 .flags = IORESOURCE_IRQ,
104 },
105};
106
107static struct platform_device gemini_rtc_device = {
108 .name = "rtc-gemini",
109 .id = 0,
110 .num_resources = ARRAY_SIZE(gemini_rtc_resources),
111 .resource = gemini_rtc_resources,
112};
113
114int __init platform_register_rtc(void)
115{
116 return platform_device_register(&gemini_rtc_device);
117}
118
diff --git a/arch/arm/mach-mxs/gpio.c b/arch/arm/mach-mxs/gpio.c
index cb0c0e83a527..61991e4dde44 100644
--- a/arch/arm/mach-mxs/gpio.c
+++ b/arch/arm/mach-mxs/gpio.c
@@ -68,29 +68,29 @@ static void set_gpio_irqenable(struct mxs_gpio_port *port, u32 index,
68 } 68 }
69} 69}
70 70
71static void mxs_gpio_ack_irq(u32 irq) 71static void mxs_gpio_ack_irq(struct irq_data *d)
72{ 72{
73 u32 gpio = irq_to_gpio(irq); 73 u32 gpio = irq_to_gpio(d->irq);
74 clear_gpio_irqstatus(&mxs_gpio_ports[gpio / 32], gpio & 0x1f); 74 clear_gpio_irqstatus(&mxs_gpio_ports[gpio / 32], gpio & 0x1f);
75} 75}
76 76
77static void mxs_gpio_mask_irq(u32 irq) 77static void mxs_gpio_mask_irq(struct irq_data *d)
78{ 78{
79 u32 gpio = irq_to_gpio(irq); 79 u32 gpio = irq_to_gpio(d->irq);
80 set_gpio_irqenable(&mxs_gpio_ports[gpio / 32], gpio & 0x1f, 0); 80 set_gpio_irqenable(&mxs_gpio_ports[gpio / 32], gpio & 0x1f, 0);
81} 81}
82 82
83static void mxs_gpio_unmask_irq(u32 irq) 83static void mxs_gpio_unmask_irq(struct irq_data *d)
84{ 84{
85 u32 gpio = irq_to_gpio(irq); 85 u32 gpio = irq_to_gpio(d->irq);
86 set_gpio_irqenable(&mxs_gpio_ports[gpio / 32], gpio & 0x1f, 1); 86 set_gpio_irqenable(&mxs_gpio_ports[gpio / 32], gpio & 0x1f, 1);
87} 87}
88 88
89static int mxs_gpio_get(struct gpio_chip *chip, unsigned offset); 89static int mxs_gpio_get(struct gpio_chip *chip, unsigned offset);
90 90
91static int mxs_gpio_set_irq_type(u32 irq, u32 type) 91static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type)
92{ 92{
93 u32 gpio = irq_to_gpio(irq); 93 u32 gpio = irq_to_gpio(d->irq);
94 u32 pin_mask = 1 << (gpio & 31); 94 u32 pin_mask = 1 << (gpio & 31);
95 struct mxs_gpio_port *port = &mxs_gpio_ports[gpio / 32]; 95 struct mxs_gpio_port *port = &mxs_gpio_ports[gpio / 32];
96 void __iomem *pin_addr; 96 void __iomem *pin_addr;
@@ -160,9 +160,9 @@ static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc)
160 * @param enable enable as wake-up if equal to non-zero 160 * @param enable enable as wake-up if equal to non-zero
161 * @return This function returns 0 on success. 161 * @return This function returns 0 on success.
162 */ 162 */
163static int mxs_gpio_set_wake_irq(u32 irq, u32 enable) 163static int mxs_gpio_set_wake_irq(struct irq_data *d, unsigned int enable)
164{ 164{
165 u32 gpio = irq_to_gpio(irq); 165 u32 gpio = irq_to_gpio(d->irq);
166 u32 gpio_idx = gpio & 0x1f; 166 u32 gpio_idx = gpio & 0x1f;
167 struct mxs_gpio_port *port = &mxs_gpio_ports[gpio / 32]; 167 struct mxs_gpio_port *port = &mxs_gpio_ports[gpio / 32];
168 168
@@ -182,11 +182,11 @@ static int mxs_gpio_set_wake_irq(u32 irq, u32 enable)
182} 182}
183 183
184static struct irq_chip gpio_irq_chip = { 184static struct irq_chip gpio_irq_chip = {
185 .ack = mxs_gpio_ack_irq, 185 .irq_ack = mxs_gpio_ack_irq,
186 .mask = mxs_gpio_mask_irq, 186 .irq_mask = mxs_gpio_mask_irq,
187 .unmask = mxs_gpio_unmask_irq, 187 .irq_unmask = mxs_gpio_unmask_irq,
188 .set_type = mxs_gpio_set_irq_type, 188 .irq_set_type = mxs_gpio_set_irq_type,
189 .set_wake = mxs_gpio_set_wake_irq, 189 .irq_set_wake = mxs_gpio_set_wake_irq,
190}; 190};
191 191
192static void mxs_set_gpio_direction(struct gpio_chip *chip, unsigned offset, 192static void mxs_set_gpio_direction(struct gpio_chip *chip, unsigned offset,
diff --git a/arch/arm/mach-mxs/icoll.c b/arch/arm/mach-mxs/icoll.c
index 5dd43ba70058..0f4c120fc169 100644
--- a/arch/arm/mach-mxs/icoll.c
+++ b/arch/arm/mach-mxs/icoll.c
@@ -34,7 +34,7 @@
34 34
35static void __iomem *icoll_base = MXS_IO_ADDRESS(MXS_ICOLL_BASE_ADDR); 35static void __iomem *icoll_base = MXS_IO_ADDRESS(MXS_ICOLL_BASE_ADDR);
36 36
37static void icoll_ack_irq(unsigned int irq) 37static void icoll_ack_irq(struct irq_data *d)
38{ 38{
39 /* 39 /*
40 * The Interrupt Collector is able to prioritize irqs. 40 * The Interrupt Collector is able to prioritize irqs.
@@ -45,22 +45,22 @@ static void icoll_ack_irq(unsigned int irq)
45 icoll_base + HW_ICOLL_LEVELACK); 45 icoll_base + HW_ICOLL_LEVELACK);
46} 46}
47 47
48static void icoll_mask_irq(unsigned int irq) 48static void icoll_mask_irq(struct irq_data *d)
49{ 49{
50 __raw_writel(BM_ICOLL_INTERRUPTn_ENABLE, 50 __raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
51 icoll_base + HW_ICOLL_INTERRUPTn_CLR(irq)); 51 icoll_base + HW_ICOLL_INTERRUPTn_CLR(d->irq));
52} 52}
53 53
54static void icoll_unmask_irq(unsigned int irq) 54static void icoll_unmask_irq(struct irq_data *d)
55{ 55{
56 __raw_writel(BM_ICOLL_INTERRUPTn_ENABLE, 56 __raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
57 icoll_base + HW_ICOLL_INTERRUPTn_SET(irq)); 57 icoll_base + HW_ICOLL_INTERRUPTn_SET(d->irq));
58} 58}
59 59
60static struct irq_chip mxs_icoll_chip = { 60static struct irq_chip mxs_icoll_chip = {
61 .ack = icoll_ack_irq, 61 .irq_ack = icoll_ack_irq,
62 .mask = icoll_mask_irq, 62 .irq_mask = icoll_mask_irq,
63 .unmask = icoll_unmask_irq, 63 .irq_unmask = icoll_unmask_irq,
64}; 64};
65 65
66void __init icoll_init_irq(void) 66void __init icoll_init_irq(void)
diff --git a/arch/arm/mach-omap1/pm.h b/arch/arm/mach-omap1/pm.h
index 56a647986ae9..cd926dcb5e7f 100644
--- a/arch/arm/mach-omap1/pm.h
+++ b/arch/arm/mach-omap1/pm.h
@@ -123,9 +123,9 @@ extern void allow_idle_sleep(void);
123extern void omap1_pm_idle(void); 123extern void omap1_pm_idle(void);
124extern void omap1_pm_suspend(void); 124extern void omap1_pm_suspend(void);
125 125
126extern void omap7xx_cpu_suspend(unsigned short, unsigned short); 126extern void omap7xx_cpu_suspend(unsigned long, unsigned long);
127extern void omap1510_cpu_suspend(unsigned short, unsigned short); 127extern void omap1510_cpu_suspend(unsigned long, unsigned long);
128extern void omap1610_cpu_suspend(unsigned short, unsigned short); 128extern void omap1610_cpu_suspend(unsigned long, unsigned long);
129extern void omap7xx_idle_loop_suspend(void); 129extern void omap7xx_idle_loop_suspend(void);
130extern void omap1510_idle_loop_suspend(void); 130extern void omap1510_idle_loop_suspend(void);
131extern void omap1610_idle_loop_suspend(void); 131extern void omap1610_idle_loop_suspend(void);
diff --git a/arch/arm/mach-omap1/sleep.S b/arch/arm/mach-omap1/sleep.S
index ef771ce8b030..c875bdc902c5 100644
--- a/arch/arm/mach-omap1/sleep.S
+++ b/arch/arm/mach-omap1/sleep.S
@@ -58,6 +58,7 @@
58 */ 58 */
59 59
60#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) 60#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
61 .align 3
61ENTRY(omap7xx_cpu_suspend) 62ENTRY(omap7xx_cpu_suspend)
62 63
63 @ save registers on stack 64 @ save registers on stack
@@ -137,6 +138,7 @@ ENTRY(omap7xx_cpu_suspend_sz)
137#endif /* CONFIG_ARCH_OMAP730 || CONFIG_ARCH_OMAP850 */ 138#endif /* CONFIG_ARCH_OMAP730 || CONFIG_ARCH_OMAP850 */
138 139
139#ifdef CONFIG_ARCH_OMAP15XX 140#ifdef CONFIG_ARCH_OMAP15XX
141 .align 3
140ENTRY(omap1510_cpu_suspend) 142ENTRY(omap1510_cpu_suspend)
141 143
142 @ save registers on stack 144 @ save registers on stack
@@ -211,6 +213,7 @@ ENTRY(omap1510_cpu_suspend_sz)
211#endif /* CONFIG_ARCH_OMAP15XX */ 213#endif /* CONFIG_ARCH_OMAP15XX */
212 214
213#if defined(CONFIG_ARCH_OMAP16XX) 215#if defined(CONFIG_ARCH_OMAP16XX)
216 .align 3
214ENTRY(omap1610_cpu_suspend) 217ENTRY(omap1610_cpu_suspend)
215 218
216 @ save registers on stack 219 @ save registers on stack
diff --git a/arch/arm/mach-omap1/sram.S b/arch/arm/mach-omap1/sram.S
index 7724e520d07c..692587d07ea5 100644
--- a/arch/arm/mach-omap1/sram.S
+++ b/arch/arm/mach-omap1/sram.S
@@ -18,6 +18,7 @@
18/* 18/*
19 * Reprograms ULPD and CKCTL. 19 * Reprograms ULPD and CKCTL.
20 */ 20 */
21 .align 3
21ENTRY(omap1_sram_reprogram_clock) 22ENTRY(omap1_sram_reprogram_clock)
22 stmfd sp!, {r0 - r12, lr} @ save registers on stack 23 stmfd sp!, {r0 - r12, lr} @ save registers on stack
23 24
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 1c1b0ab5b978..39580e6060e8 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -92,7 +92,7 @@ extern void omap24xx_idle_loop_suspend(void);
92extern void omap24xx_cpu_suspend(u32 dll_ctrl, void __iomem *sdrc_dlla_ctrl, 92extern void omap24xx_cpu_suspend(u32 dll_ctrl, void __iomem *sdrc_dlla_ctrl,
93 void __iomem *sdrc_power); 93 void __iomem *sdrc_power);
94extern void omap34xx_cpu_suspend(u32 *addr, int save_state); 94extern void omap34xx_cpu_suspend(u32 *addr, int save_state);
95extern void save_secure_ram_context(u32 *addr); 95extern int save_secure_ram_context(u32 *addr);
96extern void omap3_save_scratchpad_contents(void); 96extern void omap3_save_scratchpad_contents(void);
97 97
98extern unsigned int omap24xx_idle_loop_suspend_sz; 98extern unsigned int omap24xx_idle_loop_suspend_sz;
diff --git a/arch/arm/mach-omap2/sleep24xx.S b/arch/arm/mach-omap2/sleep24xx.S
index c7780cc8d919..b5071a47ec39 100644
--- a/arch/arm/mach-omap2/sleep24xx.S
+++ b/arch/arm/mach-omap2/sleep24xx.S
@@ -47,6 +47,7 @@
47 * Note: This code get's copied to internal SRAM at boot. When the OMAP 47 * Note: This code get's copied to internal SRAM at boot. When the OMAP
48 * wakes up it continues execution at the point it went to sleep. 48 * wakes up it continues execution at the point it went to sleep.
49 */ 49 */
50 .align 3
50ENTRY(omap24xx_idle_loop_suspend) 51ENTRY(omap24xx_idle_loop_suspend)
51 stmfd sp!, {r0, lr} @ save registers on stack 52 stmfd sp!, {r0, lr} @ save registers on stack
52 mov r0, #0 @ clear for mcr setup 53 mov r0, #0 @ clear for mcr setup
@@ -82,6 +83,7 @@ ENTRY(omap24xx_idle_loop_suspend_sz)
82 * The DLL load value is not kept in RETENTION or OFF. It needs to be restored 83 * The DLL load value is not kept in RETENTION or OFF. It needs to be restored
83 * at wake 84 * at wake
84 */ 85 */
86 .align 3
85ENTRY(omap24xx_cpu_suspend) 87ENTRY(omap24xx_cpu_suspend)
86 stmfd sp!, {r0 - r12, lr} @ save registers on stack 88 stmfd sp!, {r0 - r12, lr} @ save registers on stack
87 mov r3, #0x0 @ clear for mcr call 89 mov r3, #0x0 @ clear for mcr call
diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S
index 98d8232808b8..951a0be66cf7 100644
--- a/arch/arm/mach-omap2/sleep34xx.S
+++ b/arch/arm/mach-omap2/sleep34xx.S
@@ -118,6 +118,7 @@ ENTRY(enable_omap3630_toggle_l2_on_restore)
118 118
119 .text 119 .text
120/* Function to call rom code to save secure ram context */ 120/* Function to call rom code to save secure ram context */
121 .align 3
121ENTRY(save_secure_ram_context) 122ENTRY(save_secure_ram_context)
122 stmfd sp!, {r1-r12, lr} @ save registers on stack 123 stmfd sp!, {r1-r12, lr} @ save registers on stack
123 adr r3, api_params @ r3 points to parameters 124 adr r3, api_params @ r3 points to parameters
@@ -169,6 +170,7 @@ ENTRY(save_secure_ram_context_sz)
169 * depending on the low power mode (non-OFF vs OFF modes), 170 * depending on the low power mode (non-OFF vs OFF modes),
170 * cf. 'Resume path for xxx mode' comments. 171 * cf. 'Resume path for xxx mode' comments.
171 */ 172 */
173 .align 3
172ENTRY(omap34xx_cpu_suspend) 174ENTRY(omap34xx_cpu_suspend)
173 stmfd sp!, {r0-r12, lr} @ save registers on stack 175 stmfd sp!, {r0-r12, lr} @ save registers on stack
174 176
diff --git a/arch/arm/mach-omap2/sram242x.S b/arch/arm/mach-omap2/sram242x.S
index 055310cc77de..ff9b9dbcb30e 100644
--- a/arch/arm/mach-omap2/sram242x.S
+++ b/arch/arm/mach-omap2/sram242x.S
@@ -39,6 +39,7 @@
39 39
40 .text 40 .text
41 41
42 .align 3
42ENTRY(omap242x_sram_ddr_init) 43ENTRY(omap242x_sram_ddr_init)
43 stmfd sp!, {r0 - r12, lr} @ save registers on stack 44 stmfd sp!, {r0 - r12, lr} @ save registers on stack
44 45
@@ -143,6 +144,7 @@ ENTRY(omap242x_sram_ddr_init_sz)
143 * r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR] 144 * r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR]
144 * PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0 145 * PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0
145 */ 146 */
147 .align 3
146ENTRY(omap242x_sram_reprogram_sdrc) 148ENTRY(omap242x_sram_reprogram_sdrc)
147 stmfd sp!, {r0 - r10, lr} @ save registers on stack 149 stmfd sp!, {r0 - r10, lr} @ save registers on stack
148 mov r3, #0x0 @ clear for mrc call 150 mov r3, #0x0 @ clear for mrc call
@@ -238,6 +240,7 @@ ENTRY(omap242x_sram_reprogram_sdrc_sz)
238/* 240/*
239 * Set dividers and pll. Also recalculate DLL value for DDR and unlock mode. 241 * Set dividers and pll. Also recalculate DLL value for DDR and unlock mode.
240 */ 242 */
243 .align 3
241ENTRY(omap242x_sram_set_prcm) 244ENTRY(omap242x_sram_set_prcm)
242 stmfd sp!, {r0-r12, lr} @ regs to stack 245 stmfd sp!, {r0-r12, lr} @ regs to stack
243 adr r4, pbegin @ addr of preload start 246 adr r4, pbegin @ addr of preload start
diff --git a/arch/arm/mach-omap2/sram243x.S b/arch/arm/mach-omap2/sram243x.S
index f9007580aea3..76730209fa0e 100644
--- a/arch/arm/mach-omap2/sram243x.S
+++ b/arch/arm/mach-omap2/sram243x.S
@@ -39,6 +39,7 @@
39 39
40 .text 40 .text
41 41
42 .align 3
42ENTRY(omap243x_sram_ddr_init) 43ENTRY(omap243x_sram_ddr_init)
43 stmfd sp!, {r0 - r12, lr} @ save registers on stack 44 stmfd sp!, {r0 - r12, lr} @ save registers on stack
44 45
@@ -143,6 +144,7 @@ ENTRY(omap243x_sram_ddr_init_sz)
143 * r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR] 144 * r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR]
144 * PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0 145 * PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0
145 */ 146 */
147 .align 3
146ENTRY(omap243x_sram_reprogram_sdrc) 148ENTRY(omap243x_sram_reprogram_sdrc)
147 stmfd sp!, {r0 - r10, lr} @ save registers on stack 149 stmfd sp!, {r0 - r10, lr} @ save registers on stack
148 mov r3, #0x0 @ clear for mrc call 150 mov r3, #0x0 @ clear for mrc call
@@ -238,6 +240,7 @@ ENTRY(omap243x_sram_reprogram_sdrc_sz)
238/* 240/*
239 * Set dividers and pll. Also recalculate DLL value for DDR and unlock mode. 241 * Set dividers and pll. Also recalculate DLL value for DDR and unlock mode.
240 */ 242 */
243 .align 3
241ENTRY(omap243x_sram_set_prcm) 244ENTRY(omap243x_sram_set_prcm)
242 stmfd sp!, {r0-r12, lr} @ regs to stack 245 stmfd sp!, {r0-r12, lr} @ regs to stack
243 adr r4, pbegin @ addr of preload start 246 adr r4, pbegin @ addr of preload start
diff --git a/arch/arm/mach-omap2/sram34xx.S b/arch/arm/mach-omap2/sram34xx.S
index 7f893a29d500..25011ca2145d 100644
--- a/arch/arm/mach-omap2/sram34xx.S
+++ b/arch/arm/mach-omap2/sram34xx.S
@@ -111,6 +111,7 @@
111 * since it will cause the ARM MMU to attempt to walk the page tables. 111 * since it will cause the ARM MMU to attempt to walk the page tables.
112 * These crashes may be intermittent. 112 * These crashes may be intermittent.
113 */ 113 */
114 .align 3
114ENTRY(omap3_sram_configure_core_dpll) 115ENTRY(omap3_sram_configure_core_dpll)
115 stmfd sp!, {r1-r12, lr} @ store regs to stack 116 stmfd sp!, {r1-r12, lr} @ store regs to stack
116 117
diff --git a/arch/arm/mach-pxa/include/mach/pm.h b/arch/arm/mach-pxa/include/mach/pm.h
index fd8360c6839d..f15afe012995 100644
--- a/arch/arm/mach-pxa/include/mach/pm.h
+++ b/arch/arm/mach-pxa/include/mach/pm.h
@@ -22,9 +22,8 @@ struct pxa_cpu_pm_fns {
22extern struct pxa_cpu_pm_fns *pxa_cpu_pm_fns; 22extern struct pxa_cpu_pm_fns *pxa_cpu_pm_fns;
23 23
24/* sleep.S */ 24/* sleep.S */
25extern void pxa25x_cpu_suspend(unsigned int); 25extern void pxa25x_cpu_suspend(unsigned int, long);
26extern void pxa27x_cpu_suspend(unsigned int); 26extern void pxa27x_cpu_suspend(unsigned int, long);
27extern void pxa_cpu_resume(void);
28 27
29extern int pxa_pm_enter(suspend_state_t state); 28extern int pxa_pm_enter(suspend_state_t state);
30extern int pxa_pm_prepare(void); 29extern int pxa_pm_prepare(void);
diff --git a/arch/arm/mach-pxa/palmz72.c b/arch/arm/mach-pxa/palmz72.c
index 7bf4017326e3..3010193b081e 100644
--- a/arch/arm/mach-pxa/palmz72.c
+++ b/arch/arm/mach-pxa/palmz72.c
@@ -212,7 +212,7 @@ static unsigned long store_ptr;
212static int palmz72_pm_suspend(struct sys_device *dev, pm_message_t msg) 212static int palmz72_pm_suspend(struct sys_device *dev, pm_message_t msg)
213{ 213{
214 /* setup the resume_info struct for the original bootloader */ 214 /* setup the resume_info struct for the original bootloader */
215 palmz72_resume_info.resume_addr = (u32) pxa_cpu_resume; 215 palmz72_resume_info.resume_addr = (u32) cpu_resume;
216 216
217 /* Storing memory touched by ROM */ 217 /* Storing memory touched by ROM */
218 store_ptr = *PALMZ72_SAVE_DWORD; 218 store_ptr = *PALMZ72_SAVE_DWORD;
diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c
index 1807c9abdde0..51e1583265b2 100644
--- a/arch/arm/mach-pxa/pm.c
+++ b/arch/arm/mach-pxa/pm.c
@@ -67,11 +67,6 @@ int pxa_pm_enter(suspend_state_t state)
67 67
68EXPORT_SYMBOL_GPL(pxa_pm_enter); 68EXPORT_SYMBOL_GPL(pxa_pm_enter);
69 69
70unsigned long sleep_phys_sp(void *sp)
71{
72 return virt_to_phys(sp);
73}
74
75static int pxa_pm_valid(suspend_state_t state) 70static int pxa_pm_valid(suspend_state_t state)
76{ 71{
77 if (pxa_cpu_pm_fns) 72 if (pxa_cpu_pm_fns)
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index b166b1d845d7..6bde5956358d 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -244,7 +244,7 @@ static void pxa25x_cpu_pm_enter(suspend_state_t state)
244 244
245 switch (state) { 245 switch (state) {
246 case PM_SUSPEND_MEM: 246 case PM_SUSPEND_MEM:
247 pxa25x_cpu_suspend(PWRMODE_SLEEP); 247 pxa25x_cpu_suspend(PWRMODE_SLEEP, PLAT_PHYS_OFFSET - PAGE_OFFSET);
248 break; 248 break;
249 } 249 }
250} 250}
@@ -252,7 +252,7 @@ static void pxa25x_cpu_pm_enter(suspend_state_t state)
252static int pxa25x_cpu_pm_prepare(void) 252static int pxa25x_cpu_pm_prepare(void)
253{ 253{
254 /* set resume return address */ 254 /* set resume return address */
255 PSPR = virt_to_phys(pxa_cpu_resume); 255 PSPR = virt_to_phys(cpu_resume);
256 return 0; 256 return 0;
257} 257}
258 258
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 987301ff4c33..28b11be00b3f 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -300,7 +300,7 @@ void pxa27x_cpu_pm_enter(suspend_state_t state)
300 pxa_cpu_standby(); 300 pxa_cpu_standby();
301 break; 301 break;
302 case PM_SUSPEND_MEM: 302 case PM_SUSPEND_MEM:
303 pxa27x_cpu_suspend(pwrmode); 303 pxa27x_cpu_suspend(pwrmode, PLAT_PHYS_OFFSET - PAGE_OFFSET);
304 break; 304 break;
305 } 305 }
306} 306}
@@ -313,7 +313,7 @@ static int pxa27x_cpu_pm_valid(suspend_state_t state)
313static int pxa27x_cpu_pm_prepare(void) 313static int pxa27x_cpu_pm_prepare(void)
314{ 314{
315 /* set resume return address */ 315 /* set resume return address */
316 PSPR = virt_to_phys(pxa_cpu_resume); 316 PSPR = virt_to_phys(cpu_resume);
317 return 0; 317 return 0;
318} 318}
319 319
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
index a7a19e1cd640..1230343d9c70 100644
--- a/arch/arm/mach-pxa/pxa3xx.c
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -142,8 +142,7 @@ static void pxa3xx_cpu_pm_suspend(void)
142 volatile unsigned long *p = (volatile void *)0xc0000000; 142 volatile unsigned long *p = (volatile void *)0xc0000000;
143 unsigned long saved_data = *p; 143 unsigned long saved_data = *p;
144 144
145 extern void pxa3xx_cpu_suspend(void); 145 extern void pxa3xx_cpu_suspend(long);
146 extern void pxa3xx_cpu_resume(void);
147 146
148 /* resuming from D2 requires the HSIO2/BOOT/TPM clocks enabled */ 147 /* resuming from D2 requires the HSIO2/BOOT/TPM clocks enabled */
149 CKENA |= (1 << CKEN_BOOT) | (1 << CKEN_TPM); 148 CKENA |= (1 << CKEN_BOOT) | (1 << CKEN_TPM);
@@ -161,9 +160,9 @@ static void pxa3xx_cpu_pm_suspend(void)
161 PSPR = 0x5c014000; 160 PSPR = 0x5c014000;
162 161
163 /* overwrite with the resume address */ 162 /* overwrite with the resume address */
164 *p = virt_to_phys(pxa3xx_cpu_resume); 163 *p = virt_to_phys(cpu_resume);
165 164
166 pxa3xx_cpu_suspend(); 165 pxa3xx_cpu_suspend(PLAT_PHYS_OFFSET - PAGE_OFFSET);
167 166
168 *p = saved_data; 167 *p = saved_data;
169 168
diff --git a/arch/arm/mach-pxa/sleep.S b/arch/arm/mach-pxa/sleep.S
index c551da86baf6..6f5368899d84 100644
--- a/arch/arm/mach-pxa/sleep.S
+++ b/arch/arm/mach-pxa/sleep.S
@@ -22,133 +22,26 @@
22 22
23 .text 23 .text
24 24
25pxa_cpu_save_cp:
26 @ get coprocessor registers
27 mrc p14, 0, r3, c6, c0, 0 @ clock configuration, for turbo mode
28 mrc p15, 0, r4, c15, c1, 0 @ CP access reg
29 mrc p15, 0, r5, c13, c0, 0 @ PID
30 mrc p15, 0, r6, c3, c0, 0 @ domain ID
31 mrc p15, 0, r7, c2, c0, 0 @ translation table base addr
32 mrc p15, 0, r8, c1, c1, 0 @ auxiliary control reg
33 mrc p15, 0, r9, c1, c0, 0 @ control reg
34
35 bic r3, r3, #2 @ clear frequency change bit
36
37 @ store them plus current virtual stack ptr on stack
38 mov r10, sp
39 stmfd sp!, {r3 - r10}
40
41 mov pc, lr
42
43pxa_cpu_save_sp:
44 @ preserve phys address of stack
45 mov r0, sp
46 str lr, [sp, #-4]!
47 bl sleep_phys_sp
48 ldr r1, =sleep_save_sp
49 str r0, [r1]
50 ldr pc, [sp], #4
51
52#ifdef CONFIG_PXA3xx 25#ifdef CONFIG_PXA3xx
53/* 26/*
54 * pxa3xx_cpu_suspend() - forces CPU into sleep state (S2D3C4) 27 * pxa3xx_cpu_suspend() - forces CPU into sleep state (S2D3C4)
55 * 28 *
56 * NOTE: unfortunately, pxa_cpu_save_cp can not be reused here since 29 * r0 = v:p offset
57 * the auxiliary control register address is different between pxa3xx
58 * and pxa{25x,27x}
59 */ 30 */
60
61ENTRY(pxa3xx_cpu_suspend) 31ENTRY(pxa3xx_cpu_suspend)
62 32
63#ifndef CONFIG_IWMMXT 33#ifndef CONFIG_IWMMXT
64 mra r2, r3, acc0 34 mra r2, r3, acc0
65#endif 35#endif
66 stmfd sp!, {r2 - r12, lr} @ save registers on stack 36 stmfd sp!, {r2 - r12, lr} @ save registers on stack
67 37 mov r1, r0
68 mrc p14, 0, r3, c6, c0, 0 @ clock configuration, for turbo mode 38 ldr r3, =pxa_cpu_resume @ resume function
69 mrc p15, 0, r4, c15, c1, 0 @ CP access reg 39 bl cpu_suspend
70 mrc p15, 0, r5, c13, c0, 0 @ PID
71 mrc p15, 0, r6, c3, c0, 0 @ domain ID
72 mrc p15, 0, r7, c2, c0, 0 @ translation table base addr
73 mrc p15, 0, r8, c1, c0, 1 @ auxiliary control reg
74 mrc p15, 0, r9, c1, c0, 0 @ control reg
75
76 bic r3, r3, #2 @ clear frequency change bit
77
78 @ store them plus current virtual stack ptr on stack
79 mov r10, sp
80 stmfd sp!, {r3 - r10}
81
82 @ store physical address of stack pointer
83 mov r0, sp
84 bl sleep_phys_sp
85 ldr r1, =sleep_save_sp
86 str r0, [r1]
87
88 @ clean data cache
89 bl xsc3_flush_kern_cache_all
90 40
91 mov r0, #0x06 @ S2D3C4 mode 41 mov r0, #0x06 @ S2D3C4 mode
92 mcr p14, 0, r0, c7, c0, 0 @ enter sleep 42 mcr p14, 0, r0, c7, c0, 0 @ enter sleep
93 43
9420: b 20b @ waiting for sleep 4420: b 20b @ waiting for sleep
95
96 .data
97 .align 5
98/*
99 * pxa3xx_cpu_resume
100 */
101
102ENTRY(pxa3xx_cpu_resume)
103
104 mov r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE @ set SVC, irqs off
105 msr cpsr_c, r0
106
107 ldr r0, sleep_save_sp @ stack phys addr
108 ldmfd r0, {r3 - r9, sp} @ CP regs + virt stack ptr
109
110 mov r1, #0
111 mcr p15, 0, r1, c7, c7, 0 @ invalidate I & D caches, BTB
112 mcr p15, 0, r1, c7, c10, 4 @ drain write (&fill) buffer
113 mcr p15, 0, r1, c7, c5, 4 @ flush prefetch buffer
114 mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs
115
116 mcr p14, 0, r3, c6, c0, 0 @ clock configuration, turbo mode.
117 mcr p15, 0, r4, c15, c1, 0 @ CP access reg
118 mcr p15, 0, r5, c13, c0, 0 @ PID
119 mcr p15, 0, r6, c3, c0, 0 @ domain ID
120 mcr p15, 0, r7, c2, c0, 0 @ translation table base addr
121 mcr p15, 0, r8, c1, c0, 1 @ auxiliary control reg
122
123 @ temporarily map resume_turn_on_mmu into the page table,
124 @ otherwise prefetch abort occurs after MMU is turned on
125 mov r1, r7
126 bic r1, r1, #0x00ff
127 bic r1, r1, #0x3f00
128 ldr r2, =0x542e
129
130 adr r3, resume_turn_on_mmu
131 mov r3, r3, lsr #20
132 orr r4, r2, r3, lsl #20
133 ldr r5, [r1, r3, lsl #2]
134 str r4, [r1, r3, lsl #2]
135
136 @ Mapping page table address in the page table
137 mov r6, r1, lsr #20
138 orr r7, r2, r6, lsl #20
139 ldr r8, [r1, r6, lsl #2]
140 str r7, [r1, r6, lsl #2]
141
142 ldr r2, =pxa3xx_resume_after_mmu @ absolute virtual address
143 b resume_turn_on_mmu @ cache align execution
144
145 .text
146pxa3xx_resume_after_mmu:
147 /* restore the temporary mapping */
148 str r5, [r1, r3, lsl #2]
149 str r8, [r1, r6, lsl #2]
150 b resume_after_mmu
151
152#endif /* CONFIG_PXA3xx */ 45#endif /* CONFIG_PXA3xx */
153 46
154#ifdef CONFIG_PXA27x 47#ifdef CONFIG_PXA27x
@@ -158,28 +51,23 @@ pxa3xx_resume_after_mmu:
158 * Forces CPU into sleep state. 51 * Forces CPU into sleep state.
159 * 52 *
160 * r0 = value for PWRMODE M field for desired sleep state 53 * r0 = value for PWRMODE M field for desired sleep state
54 * r1 = v:p offset
161 */ 55 */
162
163ENTRY(pxa27x_cpu_suspend) 56ENTRY(pxa27x_cpu_suspend)
164 57
165#ifndef CONFIG_IWMMXT 58#ifndef CONFIG_IWMMXT
166 mra r2, r3, acc0 59 mra r2, r3, acc0
167#endif 60#endif
168 stmfd sp!, {r2 - r12, lr} @ save registers on stack 61 stmfd sp!, {r2 - r12, lr} @ save registers on stack
169 62 mov r4, r0 @ save sleep mode
170 bl pxa_cpu_save_cp 63 ldr r3, =pxa_cpu_resume @ resume function
171 64 bl cpu_suspend
172 mov r5, r0 @ save sleep mode
173 bl pxa_cpu_save_sp
174
175 @ clean data cache
176 bl xscale_flush_kern_cache_all
177 65
178 @ Put the processor to sleep 66 @ Put the processor to sleep
179 @ (also workaround for sighting 28071) 67 @ (also workaround for sighting 28071)
180 68
181 @ prepare value for sleep mode 69 @ prepare value for sleep mode
182 mov r1, r5 @ sleep mode 70 mov r1, r4 @ sleep mode
183 71
184 @ prepare pointer to physical address 0 (virtual mapping in generic.c) 72 @ prepare pointer to physical address 0 (virtual mapping in generic.c)
185 mov r2, #UNCACHED_PHYS_0 73 mov r2, #UNCACHED_PHYS_0
@@ -216,21 +104,16 @@ ENTRY(pxa27x_cpu_suspend)
216 * Forces CPU into sleep state. 104 * Forces CPU into sleep state.
217 * 105 *
218 * r0 = value for PWRMODE M field for desired sleep state 106 * r0 = value for PWRMODE M field for desired sleep state
107 * r1 = v:p offset
219 */ 108 */
220 109
221ENTRY(pxa25x_cpu_suspend) 110ENTRY(pxa25x_cpu_suspend)
222 stmfd sp!, {r2 - r12, lr} @ save registers on stack 111 stmfd sp!, {r2 - r12, lr} @ save registers on stack
223 112 mov r4, r0 @ save sleep mode
224 bl pxa_cpu_save_cp 113 ldr r3, =pxa_cpu_resume @ resume function
225 114 bl cpu_suspend
226 mov r5, r0 @ save sleep mode
227 bl pxa_cpu_save_sp
228
229 @ clean data cache
230 bl xscale_flush_kern_cache_all
231
232 @ prepare value for sleep mode 115 @ prepare value for sleep mode
233 mov r1, r5 @ sleep mode 116 mov r1, r4 @ sleep mode
234 117
235 @ prepare pointer to physical address 0 (virtual mapping in generic.c) 118 @ prepare pointer to physical address 0 (virtual mapping in generic.c)
236 mov r2, #UNCACHED_PHYS_0 119 mov r2, #UNCACHED_PHYS_0
@@ -317,53 +200,9 @@ pxa_cpu_do_suspend:
317 * pxa_cpu_resume() 200 * pxa_cpu_resume()
318 * 201 *
319 * entry point from bootloader into kernel during resume 202 * entry point from bootloader into kernel during resume
320 *
321 * Note: Yes, part of the following code is located into the .data section.
322 * This is to allow sleep_save_sp to be accessed with a relative load
323 * while we can't rely on any MMU translation. We could have put
324 * sleep_save_sp in the .text section as well, but some setups might
325 * insist on it to be truly read-only.
326 */ 203 */
327
328 .data
329 .align 5
330ENTRY(pxa_cpu_resume)
331 mov r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE @ set SVC, irqs off
332 msr cpsr_c, r0
333
334 ldr r0, sleep_save_sp @ stack phys addr
335 ldr r2, =resume_after_mmu @ its absolute virtual address
336 ldmfd r0, {r3 - r9, sp} @ CP regs + virt stack ptr
337
338 mov r1, #0
339 mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs
340 mcr p15, 0, r1, c7, c7, 0 @ invalidate I & D caches, BTB
341
342 mcr p14, 0, r3, c6, c0, 0 @ clock configuration, turbo mode.
343 mcr p15, 0, r4, c15, c1, 0 @ CP access reg
344 mcr p15, 0, r5, c13, c0, 0 @ PID
345 mcr p15, 0, r6, c3, c0, 0 @ domain ID
346 mcr p15, 0, r7, c2, c0, 0 @ translation table base addr
347 mcr p15, 0, r8, c1, c1, 0 @ auxiliary control reg
348 b resume_turn_on_mmu @ cache align execution
349
350 .align 5 204 .align 5
351resume_turn_on_mmu: 205pxa_cpu_resume:
352 mcr p15, 0, r9, c1, c0, 0 @ turn on MMU, caches, etc.
353
354 @ Let us ensure we jump to resume_after_mmu only when the mcr above
355 @ actually took effect. They call it the "cpwait" operation.
356 mrc p15, 0, r0, c2, c0, 0 @ queue a dependency on CP15
357 sub pc, r2, r0, lsr #32 @ jump to virtual addr
358 nop
359 nop
360 nop
361
362sleep_save_sp:
363 .word 0 @ preserve stack phys ptr here
364
365 .text
366resume_after_mmu:
367 ldmfd sp!, {r2, r3} 206 ldmfd sp!, {r2, r3}
368#ifndef CONFIG_IWMMXT 207#ifndef CONFIG_IWMMXT
369 mar acc0, r2, r3 208 mar acc0, r2, r3
diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c
index f4b053b35815..b92aa3b8c4f7 100644
--- a/arch/arm/mach-pxa/zeus.c
+++ b/arch/arm/mach-pxa/zeus.c
@@ -676,7 +676,7 @@ static struct pxa2xx_udc_mach_info zeus_udc_info = {
676static void zeus_power_off(void) 676static void zeus_power_off(void)
677{ 677{
678 local_irq_disable(); 678 local_irq_disable();
679 pxa27x_cpu_suspend(PWRMODE_DEEPSLEEP); 679 pxa27x_cpu_suspend(PWRMODE_DEEPSLEEP, PLAT_PHYS_OFFSET - PAGE_OFFSET);
680} 680}
681#else 681#else
682#define zeus_power_off NULL 682#define zeus_power_off NULL
diff --git a/arch/arm/mach-s3c64xx/sleep.S b/arch/arm/mach-s3c64xx/sleep.S
index b2ef44317368..afe5a762f46e 100644
--- a/arch/arm/mach-s3c64xx/sleep.S
+++ b/arch/arm/mach-s3c64xx/sleep.S
@@ -32,25 +32,13 @@
32 * code after resume. 32 * code after resume.
33 * 33 *
34 * entry: 34 * entry:
35 * r0 = pointer to the save block 35 * r1 = v:p offset
36 */ 36 */
37 37
38ENTRY(s3c_cpu_save) 38ENTRY(s3c_cpu_save)
39 stmfd sp!, { r4 - r12, lr } 39 stmfd sp!, { r4 - r12, lr }
40 40 ldr r3, =resume_with_mmu
41 mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID 41 bl cpu_suspend
42 mrc p15, 0, r5, c3, c0, 0 @ Domain ID
43 mrc p15, 0, r6, c2, c0, 0 @ Translation Table BASE0
44 mrc p15, 0, r7, c2, c0, 1 @ Translation Table BASE1
45 mrc p15, 0, r8, c2, c0, 2 @ Translation Table Control
46 mrc p15, 0, r9, c1, c0, 0 @ Control register
47 mrc p15, 0, r10, c1, c0, 1 @ Auxiliary control register
48 mrc p15, 0, r11, c1, c0, 2 @ Co-processor access controls
49
50 stmia r0, { r4 - r13 } @ Save CP registers and SP
51
52 @@ save our state to ram
53 bl s3c_pm_cb_flushcache
54 42
55 @@ call final suspend code 43 @@ call final suspend code
56 ldr r0, =pm_cpu_sleep 44 ldr r0, =pm_cpu_sleep
@@ -61,18 +49,6 @@ ENTRY(s3c_cpu_save)
61resume_with_mmu: 49resume_with_mmu:
62 ldmfd sp!, { r4 - r12, pc } @ return, from sp from s3c_cpu_save 50 ldmfd sp!, { r4 - r12, pc } @ return, from sp from s3c_cpu_save
63 51
64 .data
65
66 /* the next bit is code, but it requires easy access to the
67 * s3c_sleep_save_phys data before the MMU is switched on, so
68 * we store the code that needs this variable in the .data where
69 * the value can be written to (the .text segment is RO).
70 */
71
72 .global s3c_sleep_save_phys
73s3c_sleep_save_phys:
74 .word 0
75
76 /* Sleep magic, the word before the resume entry point so that the 52 /* Sleep magic, the word before the resume entry point so that the
77 * bootloader can check for a resumeable image. */ 53 * bootloader can check for a resumeable image. */
78 54
@@ -110,35 +86,4 @@ ENTRY(s3c_cpu_resume)
110 orr r0, r0, #1 << 15 @ GPN15 86 orr r0, r0, #1 << 15 @ GPN15
111 str r0, [ r3, #S3C64XX_GPNDAT ] 87 str r0, [ r3, #S3C64XX_GPNDAT ]
112#endif 88#endif
113 89 b cpu_resume
114 /* __v6_setup from arch/arm/mm/proc-v6.S, ensure that the caches
115 * are thoroughly cleaned just in case the bootloader didn't do it
116 * for us. */
117 mov r0, #0
118 mcr p15, 0, r0, c7, c14, 0 @ clean+invalidate D cache
119 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
120 mcr p15, 0, r0, c7, c15, 0 @ clean+invalidate cache
121 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
122 @@mcr p15, 0, r0, c8, c7, 0 @ invalidate I + D TLBs
123 @@mcr p15, 0, r0, c7, c7, 0 @ Invalidate I + D caches
124
125 ldr r0, s3c_sleep_save_phys
126 ldmia r0, { r4 - r13 }
127
128 mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID
129 mcr p15, 0, r5, c3, c0, 0 @ Domain ID
130 mcr p15, 0, r6, c2, c0, 0 @ Translation Table BASE0
131 mcr p15, 0, r7, c2, c0, 1 @ Translation Table BASE1
132 mcr p15, 0, r8, c2, c0, 2 @ Translation Table Control
133 mcr p15, 0, r10, c1, c0, 1 @ Auxiliary control register
134
135 mov r0, #0 @ restore copro access controls
136 mcr p15, 0, r11, c1, c0, 2 @ Co-processor access controls
137 mcr p15, 0, r0, c7, c5, 4
138
139 ldr r2, =resume_with_mmu
140 mcr p15, 0, r9, c1, c0, 0 /* turn mmu back on */
141 nop
142 mov pc, r2 /* jump back */
143
144 .end
diff --git a/arch/arm/mach-s5pv210/sleep.S b/arch/arm/mach-s5pv210/sleep.S
index d4d222b716b4..a3d649466fb1 100644
--- a/arch/arm/mach-s5pv210/sleep.S
+++ b/arch/arm/mach-s5pv210/sleep.S
@@ -35,50 +35,24 @@
35 /* s3c_cpu_save 35 /* s3c_cpu_save
36 * 36 *
37 * entry: 37 * entry:
38 * r0 = save address (virtual addr of s3c_sleep_save_phys) 38 * r1 = v:p offset
39 */ 39 */
40 40
41ENTRY(s3c_cpu_save) 41ENTRY(s3c_cpu_save)
42 42
43 stmfd sp!, { r3 - r12, lr } 43 stmfd sp!, { r3 - r12, lr }
44 44 ldr r3, =resume_with_mmu
45 mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID 45 bl cpu_suspend
46 mrc p15, 0, r5, c3, c0, 0 @ Domain ID
47 mrc p15, 0, r6, c2, c0, 0 @ Translation Table BASE0
48 mrc p15, 0, r7, c2, c0, 1 @ Translation Table BASE1
49 mrc p15, 0, r8, c2, c0, 2 @ Translation Table Control
50 mrc p15, 0, r9, c1, c0, 0 @ Control register
51 mrc p15, 0, r10, c1, c0, 1 @ Auxiliary control register
52 mrc p15, 0, r11, c1, c0, 2 @ Co-processor access controls
53 mrc p15, 0, r12, c10, c2, 0 @ Read PRRR
54 mrc p15, 0, r3, c10, c2, 1 @ READ NMRR
55
56 stmia r0, { r3 - r13 }
57
58 bl s3c_pm_cb_flushcache
59 46
60 ldr r0, =pm_cpu_sleep 47 ldr r0, =pm_cpu_sleep
61 ldr r0, [ r0 ] 48 ldr r0, [ r0 ]
62 mov pc, r0 49 mov pc, r0
63 50
64resume_with_mmu: 51resume_with_mmu:
65 /*
66 * After MMU is turned on, restore the previous MMU table.
67 */
68 ldr r9 , =(PAGE_OFFSET - PHYS_OFFSET)
69 add r4, r4, r9
70 str r12, [r4]
71
72 ldmfd sp!, { r3 - r12, pc } 52 ldmfd sp!, { r3 - r12, pc }
73 53
74 .ltorg 54 .ltorg
75 55
76 .data
77
78 .global s3c_sleep_save_phys
79s3c_sleep_save_phys:
80 .word 0
81
82 /* sleep magic, to allow the bootloader to check for an valid 56 /* sleep magic, to allow the bootloader to check for an valid
83 * image to resume to. Must be the first word before the 57 * image to resume to. Must be the first word before the
84 * s3c_cpu_resume entry. 58 * s3c_cpu_resume entry.
@@ -96,75 +70,4 @@ s3c_sleep_save_phys:
96 */ 70 */
97 71
98ENTRY(s3c_cpu_resume) 72ENTRY(s3c_cpu_resume)
99 mov r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE 73 b cpu_resume
100 msr cpsr_c, r0
101
102 mov r1, #0
103 mcr p15, 0, r1, c8, c7, 0 @ invalidate TLBs
104 mcr p15, 0, r1, c7, c5, 0 @ invalidate I Cache
105
106 ldr r0, s3c_sleep_save_phys @ address of restore block
107 ldmia r0, { r3 - r13 }
108
109 mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID
110 mcr p15, 0, r5, c3, c0, 0 @ Domain ID
111
112 mcr p15, 0, r8, c2, c0, 2 @ Translation Table Control
113 mcr p15, 0, r7, c2, c0, 1 @ Translation Table BASE1
114 mcr p15, 0, r6, c2, c0, 0 @ Translation Table BASE0
115
116 mcr p15, 0, r10, c1, c0, 1 @ Auxiliary control register
117
118 mov r0, #0
119 mcr p15, 0, r0, c8, c7, 0 @ Invalidate I & D TLB
120
121 mov r0, #0 @ restore copro access
122 mcr p15, 0, r11, c1, c0, 2 @ Co-processor access
123 mcr p15, 0, r0, c7, c5, 4
124
125 mcr p15, 0, r12, c10, c2, 0 @ write PRRR
126 mcr p15, 0, r3, c10, c2, 1 @ write NMRR
127
128 /*
129 * In Cortex-A8, when MMU is turned on, the pipeline is flushed.
130 * And there are no valid entries in the MMU table at this point.
131 * So before turning on the MMU, the MMU entry for the DRAM address
132 * range is added. After the MMU is turned on, the other entries
133 * in the MMU table will be restored.
134 */
135
136 /* r6 = Translation Table BASE0 */
137 mov r4, r6
138 mov r4, r4, LSR #14
139 mov r4, r4, LSL #14
140
141 /* Load address for adding to MMU table list */
142 ldr r11, =0xE010F000 @ INFORM0 reg.
143 ldr r10, [r11, #0]
144 mov r10, r10, LSR #18
145 bic r10, r10, #0x3
146 orr r4, r4, r10
147
148 /* Calculate MMU table entry */
149 mov r10, r10, LSL #18
150 ldr r5, =0x40E
151 orr r10, r10, r5
152
153 /* Back up originally data */
154 ldr r12, [r4]
155
156 /* Add calculated MMU table entry into MMU table list */
157 str r10, [r4]
158
159 ldr r2, =resume_with_mmu
160 mcr p15, 0, r9, c1, c0, 0 @ turn on MMU, etc
161
162 nop
163 nop
164 nop
165 nop
166 nop @ second-to-last before mmu
167
168 mov pc, r2 @ go back to virtual address
169
170 .ltorg
diff --git a/arch/arm/mach-sa1100/pm.c b/arch/arm/mach-sa1100/pm.c
index ab9fc4470d36..c4661aab22fb 100644
--- a/arch/arm/mach-sa1100/pm.c
+++ b/arch/arm/mach-sa1100/pm.c
@@ -32,8 +32,7 @@
32#include <asm/system.h> 32#include <asm/system.h>
33#include <asm/mach/time.h> 33#include <asm/mach/time.h>
34 34
35extern void sa1100_cpu_suspend(void); 35extern void sa1100_cpu_suspend(long);
36extern void sa1100_cpu_resume(void);
37 36
38#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x 37#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x
39#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] 38#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x]
@@ -73,10 +72,10 @@ static int sa11x0_pm_enter(suspend_state_t state)
73 RCSR = RCSR_HWR | RCSR_SWR | RCSR_WDR | RCSR_SMR; 72 RCSR = RCSR_HWR | RCSR_SWR | RCSR_WDR | RCSR_SMR;
74 73
75 /* set resume return address */ 74 /* set resume return address */
76 PSPR = virt_to_phys(sa1100_cpu_resume); 75 PSPR = virt_to_phys(cpu_resume);
77 76
78 /* go zzz */ 77 /* go zzz */
79 sa1100_cpu_suspend(); 78 sa1100_cpu_suspend(PLAT_PHYS_OFFSET - PAGE_OFFSET);
80 79
81 cpu_init(); 80 cpu_init();
82 81
@@ -115,11 +114,6 @@ static int sa11x0_pm_enter(suspend_state_t state)
115 return 0; 114 return 0;
116} 115}
117 116
118unsigned long sleep_phys_sp(void *sp)
119{
120 return virt_to_phys(sp);
121}
122
123static const struct platform_suspend_ops sa11x0_pm_ops = { 117static const struct platform_suspend_ops sa11x0_pm_ops = {
124 .enter = sa11x0_pm_enter, 118 .enter = sa11x0_pm_enter,
125 .valid = suspend_valid_only_mem, 119 .valid = suspend_valid_only_mem,
diff --git a/arch/arm/mach-sa1100/sleep.S b/arch/arm/mach-sa1100/sleep.S
index 80f31bad707c..04f2a618d4ef 100644
--- a/arch/arm/mach-sa1100/sleep.S
+++ b/arch/arm/mach-sa1100/sleep.S
@@ -20,12 +20,7 @@
20#include <asm/assembler.h> 20#include <asm/assembler.h>
21#include <mach/hardware.h> 21#include <mach/hardware.h>
22 22
23
24
25 .text 23 .text
26
27
28
29/* 24/*
30 * sa1100_cpu_suspend() 25 * sa1100_cpu_suspend()
31 * 26 *
@@ -34,27 +29,10 @@
34 */ 29 */
35 30
36ENTRY(sa1100_cpu_suspend) 31ENTRY(sa1100_cpu_suspend)
37
38 stmfd sp!, {r4 - r12, lr} @ save registers on stack 32 stmfd sp!, {r4 - r12, lr} @ save registers on stack
39 33 mov r1, r0
40 @ get coprocessor registers 34 ldr r3, =sa1100_cpu_resume @ return function
41 mrc p15, 0, r4, c3, c0, 0 @ domain ID 35 bl cpu_suspend
42 mrc p15, 0, r5, c2, c0, 0 @ translation table base addr
43 mrc p15, 0, r6, c13, c0, 0 @ PID
44 mrc p15, 0, r7, c1, c0, 0 @ control reg
45
46 @ store them plus current virtual stack ptr on stack
47 mov r8, sp
48 stmfd sp!, {r4 - r8}
49
50 @ preserve phys address of stack
51 mov r0, sp
52 bl sleep_phys_sp
53 ldr r1, =sleep_save_sp
54 str r0, [r1]
55
56 @ clean data cache and invalidate WB
57 bl v4wb_flush_kern_cache_all
58 36
59 @ disable clock switching 37 @ disable clock switching
60 mcr p15, 0, r1, c15, c2, 2 38 mcr p15, 0, r1, c15, c2, 2
@@ -166,50 +144,8 @@ sa1110_sdram_controller_fix:
166 * cpu_sa1100_resume() 144 * cpu_sa1100_resume()
167 * 145 *
168 * entry point from bootloader into kernel during resume 146 * entry point from bootloader into kernel during resume
169 *
170 * Note: Yes, part of the following code is located into the .data section.
171 * This is to allow sleep_save_sp to be accessed with a relative load
172 * while we can't rely on any MMU translation. We could have put
173 * sleep_save_sp in the .text section as well, but some setups might
174 * insist on it to be truly read-only.
175 */ 147 */
176
177 .data
178 .align 5
179ENTRY(sa1100_cpu_resume)
180 mov r0, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
181 msr cpsr_c, r0 @ set SVC, irqs off
182
183 ldr r0, sleep_save_sp @ stack phys addr
184 ldr r2, =resume_after_mmu @ its absolute virtual address
185 ldmfd r0, {r4 - r7, sp} @ CP regs + virt stack ptr
186
187 mov r1, #0
188 mcr p15, 0, r1, c8, c7, 0 @ flush I+D TLBs
189 mcr p15, 0, r1, c7, c7, 0 @ flush I&D cache
190 mcr p15, 0, r1, c9, c0, 0 @ invalidate RB
191 mcr p15, 0, r1, c9, c0, 5 @ allow user space to use RB
192
193 mcr p15, 0, r4, c3, c0, 0 @ domain ID
194 mcr p15, 0, r5, c2, c0, 0 @ translation table base addr
195 mcr p15, 0, r6, c13, c0, 0 @ PID
196 b resume_turn_on_mmu @ cache align execution
197
198 .align 5 148 .align 5
199resume_turn_on_mmu: 149sa1100_cpu_resume:
200 mcr p15, 0, r7, c1, c0, 0 @ turn on MMU, caches, etc.
201 nop
202 mov pc, r2 @ jump to virtual addr
203 nop
204 nop
205 nop
206
207sleep_save_sp:
208 .word 0 @ preserve stack phys ptr here
209
210 .text
211resume_after_mmu:
212 mcr p15, 0, r1, c15, c1, 2 @ enable clock switching 150 mcr p15, 0, r1, c15, c1, 2 @ enable clock switching
213 ldmfd sp!, {r4 - r12, pc} @ return to caller 151 ldmfd sp!, {r4 - r12, pc} @ return to caller
214
215
diff --git a/arch/arm/mach-shmobile/include/mach/mmcif-ap4eb.h b/arch/arm/mach-shmobile/include/mach/mmcif-ap4eb.h
new file mode 100644
index 000000000000..a8d02be8d2b6
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/mmcif-ap4eb.h
@@ -0,0 +1,29 @@
1#ifndef MMCIF_AP4EB_H
2#define MMCIF_AP4EB_H
3
4#define PORT185CR (void __iomem *)0xe60520b9
5#define PORT186CR (void __iomem *)0xe60520ba
6#define PORT187CR (void __iomem *)0xe60520bb
7#define PORT188CR (void __iomem *)0xe60520bc
8
9#define PORTR191_160DR (void __iomem *)0xe6056014
10
11static inline void mmcif_init_progress(void)
12{
13 /* Initialise LEDS1-4
14 * registers: PORT185CR-PORT188CR (LED1-LED4 Control)
15 * value: 0x10 - enable output
16 */
17 __raw_writeb(0x10, PORT185CR);
18 __raw_writeb(0x10, PORT186CR);
19 __raw_writeb(0x10, PORT187CR);
20 __raw_writeb(0x10, PORT188CR);
21}
22
23static inline void mmcif_update_progress(int n)
24{
25 __raw_writel((__raw_readl(PORTR191_160DR) & ~(0xf << 25)) |
26 (1 << (25 + n)), PORTR191_160DR);
27}
28
29#endif /* MMCIF_AP4EB_H */
diff --git a/arch/arm/mach-shmobile/include/mach/mmcif-mackerel.h b/arch/arm/mach-shmobile/include/mach/mmcif-mackerel.h
new file mode 100644
index 000000000000..4b4f6949a868
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/mmcif-mackerel.h
@@ -0,0 +1,39 @@
1#ifndef MMCIF_MACKEREL_H
2#define MMCIF_MACKEREL_H
3
4#define PORT0CR (void __iomem *)0xe6051000
5#define PORT1CR (void __iomem *)0xe6051001
6#define PORT2CR (void __iomem *)0xe6051002
7#define PORT159CR (void __iomem *)0xe605009f
8
9#define PORTR031_000DR (void __iomem *)0xe6055000
10#define PORTL159_128DR (void __iomem *)0xe6054010
11
12static inline void mmcif_init_progress(void)
13{
14 /* Initialise LEDS0-3
15 * registers: PORT0CR-PORT2CR,PORT159CR (LED0-LED3 Control)
16 * value: 0x10 - enable output
17 */
18 __raw_writeb(0x10, PORT0CR);
19 __raw_writeb(0x10, PORT1CR);
20 __raw_writeb(0x10, PORT2CR);
21 __raw_writeb(0x10, PORT159CR);
22}
23
24static inline void mmcif_update_progress(int n)
25{
26 unsigned a = 0, b = 0;
27
28 if (n < 3)
29 a = 1 << n;
30 else
31 b = 1 << 31;
32
33 __raw_writel((__raw_readl(PORTR031_000DR) & ~0x7) | a,
34 PORTR031_000DR);
35 __raw_writel((__raw_readl(PORTL159_128DR) & ~(1 << 31)) | b,
36 PORTL159_128DR);
37}
38
39#endif /* MMCIF_MACKEREL_H */
diff --git a/arch/arm/mach-shmobile/include/mach/mmcif.h b/arch/arm/mach-shmobile/include/mach/mmcif.h
new file mode 100644
index 000000000000..f4dc3279cf03
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/mmcif.h
@@ -0,0 +1,18 @@
1#ifndef MMCIF_H
2#define MMCIF_H
3
4/**************************************************
5 *
6 * board specific settings
7 *
8 **************************************************/
9
10#ifdef CONFIG_MACH_AP4EVB
11#include "mach/mmcif-ap4eb.h"
12#elif CONFIG_MACH_MACKEREL
13#include "mach/mmcif-mackerel.h"
14#else
15#error "unsupported board."
16#endif
17
18#endif /* MMCIF_H */
diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig
index 247caa3400d0..203b986280f5 100644
--- a/arch/arm/mach-ux500/Kconfig
+++ b/arch/arm/mach-ux500/Kconfig
@@ -6,6 +6,7 @@ config UX500_SOC_COMMON
6 select ARM_GIC 6 select ARM_GIC
7 select HAS_MTU 7 select HAS_MTU
8 select NOMADIK_GPIO 8 select NOMADIK_GPIO
9 select ARM_ERRATA_753970
9 10
10menu "Ux500 SoC" 11menu "Ux500 SoC"
11 12
diff --git a/arch/arm/mach-vt8500/Kconfig b/arch/arm/mach-vt8500/Kconfig
new file mode 100644
index 000000000000..2c20a341c11a
--- /dev/null
+++ b/arch/arm/mach-vt8500/Kconfig
@@ -0,0 +1,73 @@
1if ARCH_VT8500
2
3config VTWM_VERSION_VT8500
4 bool
5
6config VTWM_VERSION_WM8505
7 bool
8
9config MACH_BV07
10 bool "Benign BV07-8500 Mini Netbook"
11 depends on ARCH_VT8500
12 select VTWM_VERSION_VT8500
13 help
14 Add support for the inexpensive 7-inch netbooks sold by many
15 Chinese distributors under various names. Note that there are
16 many hardware implementations in identical exterior, make sure
17 that yours is indeed based on a VIA VT8500 chip.
18
19config MACH_WM8505_7IN_NETBOOK
20 bool "WM8505 7-inch generic netbook"
21 depends on ARCH_VT8500
22 select VTWM_VERSION_WM8505
23 help
24 Add support for the inexpensive 7-inch netbooks sold by many
25 Chinese distributors under various names. Note that there are
26 many hardware implementations in identical exterior, make sure
27 that yours is indeed based on a WonderMedia WM8505 chip.
28
29comment "LCD panel size"
30
31config WMT_PANEL_800X480
32 bool "7-inch with 800x480 resolution"
33 depends on (FB_VT8500 || FB_WM8505)
34 default y
35 help
36 These are found in most of the netbooks in generic cases, as
37 well as in Eken M001 tablets and possibly elsewhere.
38
39 To select this panel at runtime, say y here and append
40 'panel=800x480' to your kernel command line. Otherwise, the
41 largest one available will be used.
42
43config WMT_PANEL_800X600
44 bool "8-inch with 800x600 resolution"
45 depends on (FB_VT8500 || FB_WM8505)
46 help
47 These are found in Eken M003 tablets and possibly elsewhere.
48
49 To select this panel at runtime, say y here and append
50 'panel=800x600' to your kernel command line. Otherwise, the
51 largest one available will be used.
52
53config WMT_PANEL_1024X576
54 bool "10-inch with 1024x576 resolution"
55 depends on (FB_VT8500 || FB_WM8505)
56 help
57 These are found in CherryPal netbooks and possibly elsewhere.
58
59 To select this panel at runtime, say y here and append
60 'panel=1024x576' to your kernel command line. Otherwise, the
61 largest one available will be used.
62
63config WMT_PANEL_1024X600
64 bool "10-inch with 1024x600 resolution"
65 depends on (FB_VT8500 || FB_WM8505)
66 help
67 These are found in Eken M006 tablets and possibly elsewhere.
68
69 To select this panel at runtime, say y here and append
70 'panel=1024x600' to your kernel command line. Otherwise, the
71 largest one available will be used.
72
73endif
diff --git a/arch/arm/mach-vt8500/Makefile b/arch/arm/mach-vt8500/Makefile
new file mode 100644
index 000000000000..81aedb7c893c
--- /dev/null
+++ b/arch/arm/mach-vt8500/Makefile
@@ -0,0 +1,9 @@
1obj-y += devices.o gpio.o irq.o timer.o
2
3obj-$(CONFIG_VTWM_VERSION_VT8500) += devices-vt8500.o
4obj-$(CONFIG_VTWM_VERSION_WM8505) += devices-wm8505.o
5
6obj-$(CONFIG_MACH_BV07) += bv07.o
7obj-$(CONFIG_MACH_WM8505_7IN_NETBOOK) += wm8505_7in.o
8
9obj-$(CONFIG_HAVE_PWM) += pwm.o
diff --git a/arch/arm/mach-vt8500/Makefile.boot b/arch/arm/mach-vt8500/Makefile.boot
new file mode 100644
index 000000000000..a8acc4e24902
--- /dev/null
+++ b/arch/arm/mach-vt8500/Makefile.boot
@@ -0,0 +1,3 @@
1 zreladdr-y := 0x00008000
2params_phys-y := 0x00000100
3initrd_phys-y := 0x01000000
diff --git a/arch/arm/mach-vt8500/bv07.c b/arch/arm/mach-vt8500/bv07.c
new file mode 100644
index 000000000000..94a261d86bf0
--- /dev/null
+++ b/arch/arm/mach-vt8500/bv07.c
@@ -0,0 +1,77 @@
1/*
2 * arch/arm/mach-vt8500/bv07.c
3 *
4 * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
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#include <linux/io.h>
22#include <linux/pm.h>
23
24#include <asm/mach-types.h>
25#include <asm/mach/arch.h>
26
27#include "devices.h"
28
29static void __iomem *pmc_hiber;
30
31static struct platform_device *devices[] __initdata = {
32 &vt8500_device_uart0,
33 &vt8500_device_lcdc,
34 &vt8500_device_ehci,
35 &vt8500_device_ge_rops,
36 &vt8500_device_pwm,
37 &vt8500_device_pwmbl,
38 &vt8500_device_rtc,
39};
40
41static void vt8500_power_off(void)
42{
43 local_irq_disable();
44 writew(5, pmc_hiber);
45 asm("mcr%? p15, 0, %0, c7, c0, 4" : : "r" (0));
46}
47
48void __init bv07_init(void)
49{
50#ifdef CONFIG_FB_VT8500
51 void __iomem *gpio_mux_reg = ioremap(wmt_gpio_base + 0x200, 4);
52 if (gpio_mux_reg) {
53 writel(readl(gpio_mux_reg) | 1, gpio_mux_reg);
54 iounmap(gpio_mux_reg);
55 } else {
56 printk(KERN_ERR "Could not remap the GPIO mux register, display may not work properly!\n");
57 }
58#endif
59 pmc_hiber = ioremap(wmt_pmc_base + 0x12, 2);
60 if (pmc_hiber)
61 pm_power_off = &vt8500_power_off;
62 else
63 printk(KERN_ERR "PMC Hibernation register could not be remapped, not enabling power off!\n");
64
65 vt8500_set_resources();
66 platform_add_devices(devices, ARRAY_SIZE(devices));
67 vt8500_gpio_init();
68}
69
70MACHINE_START(BV07, "Benign BV07 Mini Netbook")
71 .boot_params = 0x00000100,
72 .reserve = vt8500_reserve_mem,
73 .map_io = vt8500_map_io,
74 .init_irq = vt8500_init_irq,
75 .timer = &vt8500_timer,
76 .init_machine = bv07_init,
77MACHINE_END
diff --git a/arch/arm/mach-vt8500/devices-vt8500.c b/arch/arm/mach-vt8500/devices-vt8500.c
new file mode 100644
index 000000000000..19519aeecf37
--- /dev/null
+++ b/arch/arm/mach-vt8500/devices-vt8500.c
@@ -0,0 +1,91 @@
1/* linux/arch/arm/mach-vt8500/devices-vt8500.c
2 *
3 * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#include <linux/platform_device.h>
17
18#include <mach/vt8500_regs.h>
19#include <mach/vt8500_irqs.h>
20#include <mach/i8042.h>
21#include "devices.h"
22
23void __init vt8500_set_resources(void)
24{
25 struct resource tmp[3];
26
27 tmp[0] = wmt_mmio_res(VT8500_LCDC_BASE, SZ_1K);
28 tmp[1] = wmt_irq_res(IRQ_LCDC);
29 wmt_res_add(&vt8500_device_lcdc, tmp, 2);
30
31 tmp[0] = wmt_mmio_res(VT8500_UART0_BASE, 0x1040);
32 tmp[1] = wmt_irq_res(IRQ_UART0);
33 wmt_res_add(&vt8500_device_uart0, tmp, 2);
34
35 tmp[0] = wmt_mmio_res(VT8500_UART1_BASE, 0x1040);
36 tmp[1] = wmt_irq_res(IRQ_UART1);
37 wmt_res_add(&vt8500_device_uart1, tmp, 2);
38
39 tmp[0] = wmt_mmio_res(VT8500_UART2_BASE, 0x1040);
40 tmp[1] = wmt_irq_res(IRQ_UART2);
41 wmt_res_add(&vt8500_device_uart2, tmp, 2);
42
43 tmp[0] = wmt_mmio_res(VT8500_UART3_BASE, 0x1040);
44 tmp[1] = wmt_irq_res(IRQ_UART3);
45 wmt_res_add(&vt8500_device_uart3, tmp, 2);
46
47 tmp[0] = wmt_mmio_res(VT8500_EHCI_BASE, SZ_512);
48 tmp[1] = wmt_irq_res(IRQ_EHCI);
49 wmt_res_add(&vt8500_device_ehci, tmp, 2);
50
51 tmp[0] = wmt_mmio_res(VT8500_GEGEA_BASE, SZ_256);
52 wmt_res_add(&vt8500_device_ge_rops, tmp, 1);
53
54 tmp[0] = wmt_mmio_res(VT8500_PWM_BASE, 0x44);
55 wmt_res_add(&vt8500_device_pwm, tmp, 1);
56
57 tmp[0] = wmt_mmio_res(VT8500_RTC_BASE, 0x2c);
58 tmp[1] = wmt_irq_res(IRQ_RTC);
59 tmp[2] = wmt_irq_res(IRQ_RTCSM);
60 wmt_res_add(&vt8500_device_rtc, tmp, 3);
61}
62
63static void __init vt8500_set_externs(void)
64{
65 /* Non-resource-aware stuff */
66 wmt_ic_base = VT8500_IC_BASE;
67 wmt_gpio_base = VT8500_GPIO_BASE;
68 wmt_pmc_base = VT8500_PMC_BASE;
69 wmt_i8042_base = VT8500_PS2_BASE;
70
71 wmt_nr_irqs = VT8500_NR_IRQS;
72 wmt_timer_irq = IRQ_PMCOS0;
73 wmt_gpio_ext_irq[0] = IRQ_EXT0;
74 wmt_gpio_ext_irq[1] = IRQ_EXT1;
75 wmt_gpio_ext_irq[2] = IRQ_EXT2;
76 wmt_gpio_ext_irq[3] = IRQ_EXT3;
77 wmt_gpio_ext_irq[4] = IRQ_EXT4;
78 wmt_gpio_ext_irq[5] = IRQ_EXT5;
79 wmt_gpio_ext_irq[6] = IRQ_EXT6;
80 wmt_gpio_ext_irq[7] = IRQ_EXT7;
81 wmt_i8042_kbd_irq = IRQ_PS2KBD;
82 wmt_i8042_aux_irq = IRQ_PS2MOUSE;
83}
84
85void __init vt8500_map_io(void)
86{
87 iotable_init(wmt_io_desc, ARRAY_SIZE(wmt_io_desc));
88
89 /* Should be done before interrupts and timers are initialized */
90 vt8500_set_externs();
91}
diff --git a/arch/arm/mach-vt8500/devices-wm8505.c b/arch/arm/mach-vt8500/devices-wm8505.c
new file mode 100644
index 000000000000..db4594e029f4
--- /dev/null
+++ b/arch/arm/mach-vt8500/devices-wm8505.c
@@ -0,0 +1,99 @@
1/* linux/arch/arm/mach-vt8500/devices-wm8505.c
2 *
3 * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#include <linux/platform_device.h>
17
18#include <mach/wm8505_regs.h>
19#include <mach/wm8505_irqs.h>
20#include <mach/i8042.h>
21#include "devices.h"
22
23void __init wm8505_set_resources(void)
24{
25 struct resource tmp[3];
26
27 tmp[0] = wmt_mmio_res(WM8505_GOVR_BASE, SZ_512);
28 wmt_res_add(&vt8500_device_wm8505_fb, tmp, 1);
29
30 tmp[0] = wmt_mmio_res(WM8505_UART0_BASE, 0x1040);
31 tmp[1] = wmt_irq_res(IRQ_UART0);
32 wmt_res_add(&vt8500_device_uart0, tmp, 2);
33
34 tmp[0] = wmt_mmio_res(WM8505_UART1_BASE, 0x1040);
35 tmp[1] = wmt_irq_res(IRQ_UART1);
36 wmt_res_add(&vt8500_device_uart1, tmp, 2);
37
38 tmp[0] = wmt_mmio_res(WM8505_UART2_BASE, 0x1040);
39 tmp[1] = wmt_irq_res(IRQ_UART2);
40 wmt_res_add(&vt8500_device_uart2, tmp, 2);
41
42 tmp[0] = wmt_mmio_res(WM8505_UART3_BASE, 0x1040);
43 tmp[1] = wmt_irq_res(IRQ_UART3);
44 wmt_res_add(&vt8500_device_uart3, tmp, 2);
45
46 tmp[0] = wmt_mmio_res(WM8505_UART4_BASE, 0x1040);
47 tmp[1] = wmt_irq_res(IRQ_UART4);
48 wmt_res_add(&vt8500_device_uart4, tmp, 2);
49
50 tmp[0] = wmt_mmio_res(WM8505_UART5_BASE, 0x1040);
51 tmp[1] = wmt_irq_res(IRQ_UART5);
52 wmt_res_add(&vt8500_device_uart5, tmp, 2);
53
54 tmp[0] = wmt_mmio_res(WM8505_EHCI_BASE, SZ_512);
55 tmp[1] = wmt_irq_res(IRQ_EHCI);
56 wmt_res_add(&vt8500_device_ehci, tmp, 2);
57
58 tmp[0] = wmt_mmio_res(WM8505_GEGEA_BASE, SZ_256);
59 wmt_res_add(&vt8500_device_ge_rops, tmp, 1);
60
61 tmp[0] = wmt_mmio_res(WM8505_PWM_BASE, 0x44);
62 wmt_res_add(&vt8500_device_pwm, tmp, 1);
63
64 tmp[0] = wmt_mmio_res(WM8505_RTC_BASE, 0x2c);
65 tmp[1] = wmt_irq_res(IRQ_RTC);
66 tmp[2] = wmt_irq_res(IRQ_RTCSM);
67 wmt_res_add(&vt8500_device_rtc, tmp, 3);
68}
69
70static void __init wm8505_set_externs(void)
71{
72 /* Non-resource-aware stuff */
73 wmt_ic_base = WM8505_IC_BASE;
74 wmt_sic_base = WM8505_SIC_BASE;
75 wmt_gpio_base = WM8505_GPIO_BASE;
76 wmt_pmc_base = WM8505_PMC_BASE;
77 wmt_i8042_base = WM8505_PS2_BASE;
78
79 wmt_nr_irqs = WM8505_NR_IRQS;
80 wmt_timer_irq = IRQ_PMCOS0;
81 wmt_gpio_ext_irq[0] = IRQ_EXT0;
82 wmt_gpio_ext_irq[1] = IRQ_EXT1;
83 wmt_gpio_ext_irq[2] = IRQ_EXT2;
84 wmt_gpio_ext_irq[3] = IRQ_EXT3;
85 wmt_gpio_ext_irq[4] = IRQ_EXT4;
86 wmt_gpio_ext_irq[5] = IRQ_EXT5;
87 wmt_gpio_ext_irq[6] = IRQ_EXT6;
88 wmt_gpio_ext_irq[7] = IRQ_EXT7;
89 wmt_i8042_kbd_irq = IRQ_PS2KBD;
90 wmt_i8042_aux_irq = IRQ_PS2MOUSE;
91}
92
93void __init wm8505_map_io(void)
94{
95 iotable_init(wmt_io_desc, ARRAY_SIZE(wmt_io_desc));
96
97 /* Should be done before interrupts and timers are initialized */
98 wm8505_set_externs();
99}
diff --git a/arch/arm/mach-vt8500/devices.c b/arch/arm/mach-vt8500/devices.c
new file mode 100644
index 000000000000..1fcdc36b358d
--- /dev/null
+++ b/arch/arm/mach-vt8500/devices.c
@@ -0,0 +1,270 @@
1/* linux/arch/arm/mach-vt8500/devices.c
2 *
3 * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#include <linux/kernel.h>
17#include <linux/io.h>
18#include <linux/device.h>
19#include <linux/dma-mapping.h>
20#include <linux/platform_device.h>
21#include <linux/pwm_backlight.h>
22#include <linux/memblock.h>
23
24#include <asm/mach/arch.h>
25
26#include <mach/vt8500fb.h>
27#include <mach/i8042.h>
28#include "devices.h"
29
30/* These can't use resources currently */
31unsigned long wmt_ic_base __initdata;
32unsigned long wmt_sic_base __initdata;
33unsigned long wmt_gpio_base __initdata;
34unsigned long wmt_pmc_base __initdata;
35unsigned long wmt_i8042_base __initdata;
36
37int wmt_nr_irqs __initdata;
38int wmt_timer_irq __initdata;
39int wmt_gpio_ext_irq[8] __initdata;
40
41/* Should remain accessible after init.
42 * i8042 driver desperately calls for attention...
43 */
44int wmt_i8042_kbd_irq;
45int wmt_i8042_aux_irq;
46
47static u64 fb_dma_mask = DMA_BIT_MASK(32);
48
49struct platform_device vt8500_device_lcdc = {
50 .name = "vt8500-lcd",
51 .id = 0,
52 .dev = {
53 .dma_mask = &fb_dma_mask,
54 .coherent_dma_mask = DMA_BIT_MASK(32),
55 },
56};
57
58struct platform_device vt8500_device_wm8505_fb = {
59 .name = "wm8505-fb",
60 .id = 0,
61};
62
63/* Smallest to largest */
64static struct vt8500fb_platform_data panels[] = {
65#ifdef CONFIG_WMT_PANEL_800X480
66{
67 .xres_virtual = 800,
68 .yres_virtual = 480 * 2,
69 .mode = {
70 .name = "800x480",
71 .xres = 800,
72 .yres = 480,
73 .left_margin = 88,
74 .right_margin = 40,
75 .upper_margin = 32,
76 .lower_margin = 11,
77 .hsync_len = 0,
78 .vsync_len = 1,
79 .vmode = FB_VMODE_NONINTERLACED,
80 },
81},
82#endif
83#ifdef CONFIG_WMT_PANEL_800X600
84{
85 .xres_virtual = 800,
86 .yres_virtual = 600 * 2,
87 .mode = {
88 .name = "800x600",
89 .xres = 800,
90 .yres = 600,
91 .left_margin = 88,
92 .right_margin = 40,
93 .upper_margin = 32,
94 .lower_margin = 11,
95 .hsync_len = 0,
96 .vsync_len = 1,
97 .vmode = FB_VMODE_NONINTERLACED,
98 },
99},
100#endif
101#ifdef CONFIG_WMT_PANEL_1024X576
102{
103 .xres_virtual = 1024,
104 .yres_virtual = 576 * 2,
105 .mode = {
106 .name = "1024x576",
107 .xres = 1024,
108 .yres = 576,
109 .left_margin = 40,
110 .right_margin = 24,
111 .upper_margin = 32,
112 .lower_margin = 11,
113 .hsync_len = 96,
114 .vsync_len = 2,
115 .vmode = FB_VMODE_NONINTERLACED,
116 },
117},
118#endif
119#ifdef CONFIG_WMT_PANEL_1024X600
120{
121 .xres_virtual = 1024,
122 .yres_virtual = 600 * 2,
123 .mode = {
124 .name = "1024x600",
125 .xres = 1024,
126 .yres = 600,
127 .left_margin = 66,
128 .right_margin = 2,
129 .upper_margin = 19,
130 .lower_margin = 1,
131 .hsync_len = 23,
132 .vsync_len = 8,
133 .vmode = FB_VMODE_NONINTERLACED,
134 },
135},
136#endif
137};
138
139static int current_panel_idx __initdata = ARRAY_SIZE(panels) - 1;
140
141static int __init panel_setup(char *str)
142{
143 int i;
144
145 for (i = 0; i < ARRAY_SIZE(panels); i++) {
146 if (strcmp(panels[i].mode.name, str) == 0) {
147 current_panel_idx = i;
148 break;
149 }
150 }
151 return 0;
152}
153
154early_param("panel", panel_setup);
155
156static inline void preallocate_fb(struct vt8500fb_platform_data *p,
157 unsigned long align) {
158 p->video_mem_len = (p->xres_virtual * p->yres_virtual * 4) >>
159 (p->bpp > 16 ? 0 : (p->bpp > 8 ? 1 :
160 (8 / p->bpp) + 1));
161 p->video_mem_phys = (unsigned long)memblock_alloc(p->video_mem_len,
162 align);
163 p->video_mem_virt = phys_to_virt(p->video_mem_phys);
164}
165
166struct platform_device vt8500_device_uart0 = {
167 .name = "vt8500_serial",
168 .id = 0,
169};
170
171struct platform_device vt8500_device_uart1 = {
172 .name = "vt8500_serial",
173 .id = 1,
174};
175
176struct platform_device vt8500_device_uart2 = {
177 .name = "vt8500_serial",
178 .id = 2,
179};
180
181struct platform_device vt8500_device_uart3 = {
182 .name = "vt8500_serial",
183 .id = 3,
184};
185
186struct platform_device vt8500_device_uart4 = {
187 .name = "vt8500_serial",
188 .id = 4,
189};
190
191struct platform_device vt8500_device_uart5 = {
192 .name = "vt8500_serial",
193 .id = 5,
194};
195
196static u64 ehci_dma_mask = DMA_BIT_MASK(32);
197
198struct platform_device vt8500_device_ehci = {
199 .name = "vt8500-ehci",
200 .id = 0,
201 .dev = {
202 .dma_mask = &ehci_dma_mask,
203 .coherent_dma_mask = DMA_BIT_MASK(32),
204 },
205};
206
207struct platform_device vt8500_device_ge_rops = {
208 .name = "wmt_ge_rops",
209 .id = -1,
210};
211
212struct platform_device vt8500_device_pwm = {
213 .name = "vt8500-pwm",
214 .id = 0,
215};
216
217static struct platform_pwm_backlight_data vt8500_pwmbl_data = {
218 .pwm_id = 0,
219 .max_brightness = 128,
220 .dft_brightness = 70,
221 .pwm_period_ns = 250000, /* revisit when clocks are implemented */
222};
223
224struct platform_device vt8500_device_pwmbl = {
225 .name = "pwm-backlight",
226 .id = 0,
227 .dev = {
228 .platform_data = &vt8500_pwmbl_data,
229 },
230};
231
232struct platform_device vt8500_device_rtc = {
233 .name = "vt8500-rtc",
234 .id = 0,
235};
236
237struct map_desc wmt_io_desc[] __initdata = {
238 /* SoC MMIO registers */
239 [0] = {
240 .virtual = 0xf8000000,
241 .pfn = __phys_to_pfn(0xd8000000),
242 .length = 0x00390000, /* max of all chip variants */
243 .type = MT_DEVICE
244 },
245 /* PCI I/O space, numbers tied to those in <mach/io.h> */
246 [1] = {
247 .virtual = 0xf0000000,
248 .pfn = __phys_to_pfn(0xc0000000),
249 .length = SZ_64K,
250 .type = MT_DEVICE
251 },
252};
253
254void __init vt8500_reserve_mem(void)
255{
256#ifdef CONFIG_FB_VT8500
257 panels[current_panel_idx].bpp = 16; /* Always use RGB565 */
258 preallocate_fb(&panels[current_panel_idx], SZ_4M);
259 vt8500_device_lcdc.dev.platform_data = &panels[current_panel_idx];
260#endif
261}
262
263void __init wm8505_reserve_mem(void)
264{
265#if defined CONFIG_FB_WM8505
266 panels[current_panel_idx].bpp = 32; /* Always use RGB888 */
267 preallocate_fb(&panels[current_panel_idx], 32);
268 vt8500_device_wm8505_fb.dev.platform_data = &panels[current_panel_idx];
269#endif
270}
diff --git a/arch/arm/mach-vt8500/devices.h b/arch/arm/mach-vt8500/devices.h
new file mode 100644
index 000000000000..188d4e17f35c
--- /dev/null
+++ b/arch/arm/mach-vt8500/devices.h
@@ -0,0 +1,88 @@
1/* linux/arch/arm/mach-vt8500/devices.h
2 *
3 * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#ifndef __ARCH_ARM_MACH_VT8500_DEVICES_H
17#define __ARCH_ARM_MACH_VT8500_DEVICES_H
18
19#include <linux/platform_device.h>
20#include <asm/mach/map.h>
21
22void __init vt8500_init_irq(void);
23void __init wm8505_init_irq(void);
24void __init vt8500_map_io(void);
25void __init wm8505_map_io(void);
26void __init vt8500_reserve_mem(void);
27void __init wm8505_reserve_mem(void);
28void __init vt8500_gpio_init(void);
29void __init vt8500_set_resources(void);
30void __init wm8505_set_resources(void);
31
32extern unsigned long wmt_ic_base __initdata;
33extern unsigned long wmt_sic_base __initdata;
34extern unsigned long wmt_gpio_base __initdata;
35extern unsigned long wmt_pmc_base __initdata;
36
37extern int wmt_nr_irqs __initdata;
38extern int wmt_timer_irq __initdata;
39extern int wmt_gpio_ext_irq[8] __initdata;
40
41extern struct map_desc wmt_io_desc[2] __initdata;
42
43static inline struct resource wmt_mmio_res(u32 start, u32 size)
44{
45 struct resource tmp = {
46 .flags = IORESOURCE_MEM,
47 .start = start,
48 .end = start + size - 1,
49 };
50
51 return tmp;
52}
53
54static inline struct resource wmt_irq_res(int irq)
55{
56 struct resource tmp = {
57 .flags = IORESOURCE_IRQ,
58 .start = irq,
59 .end = irq,
60 };
61
62 return tmp;
63}
64
65static inline void wmt_res_add(struct platform_device *pdev,
66 const struct resource *res, unsigned int num)
67{
68 if (unlikely(platform_device_add_resources(pdev, res, num)))
69 pr_err("Failed to assign resources\n");
70}
71
72extern struct sys_timer vt8500_timer;
73
74extern struct platform_device vt8500_device_uart0;
75extern struct platform_device vt8500_device_uart1;
76extern struct platform_device vt8500_device_uart2;
77extern struct platform_device vt8500_device_uart3;
78extern struct platform_device vt8500_device_uart4;
79extern struct platform_device vt8500_device_uart5;
80
81extern struct platform_device vt8500_device_lcdc;
82extern struct platform_device vt8500_device_wm8505_fb;
83extern struct platform_device vt8500_device_ehci;
84extern struct platform_device vt8500_device_ge_rops;
85extern struct platform_device vt8500_device_pwm;
86extern struct platform_device vt8500_device_pwmbl;
87extern struct platform_device vt8500_device_rtc;
88#endif
diff --git a/arch/arm/mach-vt8500/gpio.c b/arch/arm/mach-vt8500/gpio.c
new file mode 100644
index 000000000000..2bcc0ec783df
--- /dev/null
+++ b/arch/arm/mach-vt8500/gpio.c
@@ -0,0 +1,240 @@
1/* linux/arch/arm/mach-vt8500/gpio.c
2 *
3 * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16#include <linux/gpio.h>
17#include <linux/init.h>
18#include <linux/irq.h>
19#include <linux/io.h>
20
21#include "devices.h"
22
23#define to_vt8500(__chip) container_of(__chip, struct vt8500_gpio_chip, chip)
24
25#define ENABLE_REGS 0x0
26#define DIRECTION_REGS 0x20
27#define OUTVALUE_REGS 0x40
28#define INVALUE_REGS 0x60
29
30#define EXT_REGOFF 0x1c
31
32static void __iomem *regbase;
33
34struct vt8500_gpio_chip {
35 struct gpio_chip chip;
36 unsigned int shift;
37 unsigned int regoff;
38};
39
40static int gpio_to_irq_map[8];
41
42static int vt8500_muxed_gpio_request(struct gpio_chip *chip,
43 unsigned offset)
44{
45 struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
46 unsigned val = readl(regbase + ENABLE_REGS + vt8500_chip->regoff);
47
48 val |= (1 << vt8500_chip->shift << offset);
49 writel(val, regbase + ENABLE_REGS + vt8500_chip->regoff);
50
51 return 0;
52}
53
54static void vt8500_muxed_gpio_free(struct gpio_chip *chip,
55 unsigned offset)
56{
57 struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
58 unsigned val = readl(regbase + ENABLE_REGS + vt8500_chip->regoff);
59
60 val &= ~(1 << vt8500_chip->shift << offset);
61 writel(val, regbase + ENABLE_REGS + vt8500_chip->regoff);
62}
63
64static int vt8500_muxed_gpio_direction_input(struct gpio_chip *chip,
65 unsigned offset)
66{
67 struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
68 unsigned val = readl(regbase + DIRECTION_REGS + vt8500_chip->regoff);
69
70 val &= ~(1 << vt8500_chip->shift << offset);
71 writel(val, regbase + DIRECTION_REGS + vt8500_chip->regoff);
72
73 return 0;
74}
75
76static int vt8500_muxed_gpio_direction_output(struct gpio_chip *chip,
77 unsigned offset, int value)
78{
79 struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
80 unsigned val = readl(regbase + DIRECTION_REGS + vt8500_chip->regoff);
81
82 val |= (1 << vt8500_chip->shift << offset);
83 writel(val, regbase + DIRECTION_REGS + vt8500_chip->regoff);
84
85 if (value) {
86 val = readl(regbase + OUTVALUE_REGS + vt8500_chip->regoff);
87 val |= (1 << vt8500_chip->shift << offset);
88 writel(val, regbase + OUTVALUE_REGS + vt8500_chip->regoff);
89 }
90 return 0;
91}
92
93static int vt8500_muxed_gpio_get_value(struct gpio_chip *chip,
94 unsigned offset)
95{
96 struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
97
98 return (readl(regbase + INVALUE_REGS + vt8500_chip->regoff)
99 >> vt8500_chip->shift >> offset) & 1;
100}
101
102static void vt8500_muxed_gpio_set_value(struct gpio_chip *chip,
103 unsigned offset, int value)
104{
105 struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
106 unsigned val = readl(regbase + INVALUE_REGS + vt8500_chip->regoff);
107
108 if (value)
109 val |= (1 << vt8500_chip->shift << offset);
110 else
111 val &= ~(1 << vt8500_chip->shift << offset);
112
113 writel(val, regbase + INVALUE_REGS + vt8500_chip->regoff);
114}
115
116#define VT8500_GPIO_BANK(__name, __shift, __off, __base, __num) \
117{ \
118 .chip = { \
119 .label = __name, \
120 .request = vt8500_muxed_gpio_request, \
121 .free = vt8500_muxed_gpio_free, \
122 .direction_input = vt8500_muxed_gpio_direction_input, \
123 .direction_output = vt8500_muxed_gpio_direction_output, \
124 .get = vt8500_muxed_gpio_get_value, \
125 .set = vt8500_muxed_gpio_set_value, \
126 .can_sleep = 0, \
127 .base = __base, \
128 .ngpio = __num, \
129 }, \
130 .shift = __shift, \
131 .regoff = __off, \
132}
133
134static struct vt8500_gpio_chip vt8500_muxed_gpios[] = {
135 VT8500_GPIO_BANK("uart0", 0, 0x0, 8, 4),
136 VT8500_GPIO_BANK("uart1", 4, 0x0, 12, 4),
137 VT8500_GPIO_BANK("spi0", 8, 0x0, 16, 4),
138 VT8500_GPIO_BANK("spi1", 12, 0x0, 20, 4),
139 VT8500_GPIO_BANK("spi2", 16, 0x0, 24, 4),
140 VT8500_GPIO_BANK("pwmout", 24, 0x0, 28, 2),
141
142 VT8500_GPIO_BANK("sdmmc", 0, 0x4, 30, 11),
143 VT8500_GPIO_BANK("ms", 16, 0x4, 41, 7),
144 VT8500_GPIO_BANK("i2c0", 24, 0x4, 48, 2),
145 VT8500_GPIO_BANK("i2c1", 26, 0x4, 50, 2),
146
147 VT8500_GPIO_BANK("mii", 0, 0x8, 52, 20),
148 VT8500_GPIO_BANK("see", 20, 0x8, 72, 4),
149 VT8500_GPIO_BANK("ide", 24, 0x8, 76, 7),
150
151 VT8500_GPIO_BANK("ccir", 0, 0xc, 83, 19),
152
153 VT8500_GPIO_BANK("ts", 8, 0x10, 102, 11),
154
155 VT8500_GPIO_BANK("lcd", 0, 0x14, 113, 23),
156};
157
158static int vt8500_gpio_direction_input(struct gpio_chip *chip,
159 unsigned offset)
160{
161 unsigned val = readl(regbase + DIRECTION_REGS + EXT_REGOFF);
162
163 val &= ~(1 << offset);
164 writel(val, regbase + DIRECTION_REGS + EXT_REGOFF);
165 return 0;
166}
167
168static int vt8500_gpio_direction_output(struct gpio_chip *chip,
169 unsigned offset, int value)
170{
171 unsigned val = readl(regbase + DIRECTION_REGS + EXT_REGOFF);
172
173 val |= (1 << offset);
174 writel(val, regbase + DIRECTION_REGS + EXT_REGOFF);
175
176 if (value) {
177 val = readl(regbase + OUTVALUE_REGS + EXT_REGOFF);
178 val |= (1 << offset);
179 writel(val, regbase + OUTVALUE_REGS + EXT_REGOFF);
180 }
181 return 0;
182}
183
184static int vt8500_gpio_get_value(struct gpio_chip *chip,
185 unsigned offset)
186{
187 return (readl(regbase + INVALUE_REGS + EXT_REGOFF) >> offset) & 1;
188}
189
190static void vt8500_gpio_set_value(struct gpio_chip *chip,
191 unsigned offset, int value)
192{
193 unsigned val = readl(regbase + OUTVALUE_REGS + EXT_REGOFF);
194
195 if (value)
196 val |= (1 << offset);
197 else
198 val &= ~(1 << offset);
199
200 writel(val, regbase + OUTVALUE_REGS + EXT_REGOFF);
201}
202
203static int vt8500_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
204{
205 if (offset > 7)
206 return -EINVAL;
207
208 return gpio_to_irq_map[offset];
209}
210
211static struct gpio_chip vt8500_external_gpios = {
212 .label = "extgpio",
213 .direction_input = vt8500_gpio_direction_input,
214 .direction_output = vt8500_gpio_direction_output,
215 .get = vt8500_gpio_get_value,
216 .set = vt8500_gpio_set_value,
217 .to_irq = vt8500_gpio_to_irq,
218 .can_sleep = 0,
219 .base = 0,
220 .ngpio = 8,
221};
222
223void __init vt8500_gpio_init(void)
224{
225 int i;
226
227 for (i = 0; i < 8; i++)
228 gpio_to_irq_map[i] = wmt_gpio_ext_irq[i];
229
230 regbase = ioremap(wmt_gpio_base, SZ_64K);
231 if (!regbase) {
232 printk(KERN_ERR "Failed to map MMIO registers for GPIO\n");
233 return;
234 }
235
236 gpiochip_add(&vt8500_external_gpios);
237
238 for (i = 0; i < ARRAY_SIZE(vt8500_muxed_gpios); i++)
239 gpiochip_add(&vt8500_muxed_gpios[i].chip);
240}
diff --git a/arch/arm/mach-vt8500/include/mach/debug-macro.S b/arch/arm/mach-vt8500/include/mach/debug-macro.S
new file mode 100644
index 000000000000..f1191626ad51
--- /dev/null
+++ b/arch/arm/mach-vt8500/include/mach/debug-macro.S
@@ -0,0 +1,31 @@
1/*
2 * arch/arm/mach-vt8500/include/mach/debug-macro.S
3 *
4 * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
5 *
6 * Debugging macro include header
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
14 .macro addruart, rp, rv
15 mov \rp, #0x00200000
16 orr \rv, \rp, #0xf8000000
17 orr \rp, \rp, #0xd8000000
18 .endm
19
20 .macro senduart,rd,rx
21 strb \rd, [\rx, #0]
22 .endm
23
24 .macro busyuart,rd,rx
251001: ldr \rd, [\rx, #0x1c]
26 ands \rd, \rd, #0x2
27 bne 1001b
28 .endm
29
30 .macro waituart,rd,rx
31 .endm
diff --git a/arch/arm/mach-vt8500/include/mach/entry-macro.S b/arch/arm/mach-vt8500/include/mach/entry-macro.S
new file mode 100644
index 000000000000..92684c7eaed3
--- /dev/null
+++ b/arch/arm/mach-vt8500/include/mach/entry-macro.S
@@ -0,0 +1,32 @@
1/*
2 * arch/arm/mach-vt8500/include/mach/entry-macro.S
3 *
4 * Low-level IRQ helper macros for VIA VT8500
5 *
6 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without any
8 * warranty of any kind, whether express or implied.
9 */
10
11 .macro disable_fiq
12 .endm
13
14 .macro get_irqnr_preamble, base, tmp
15 @ physical 0xd8140000 is virtual 0xf8140000
16 mov \base, #0xf8000000
17 orr \base, \base, #0x00140000
18 .endm
19
20 .macro arch_ret_to_user, tmp1, tmp2
21 .endm
22
23 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
24 ldr \irqnr, [\base]
25 cmp \irqnr, #63 @ may be false positive, check interrupt status
26 bne 1001f
27 ldr \irqstat, [\base, #0x84]
28 ands \irqstat, #0x80000000
29 moveq \irqnr, #0
301001:
31 .endm
32
diff --git a/arch/arm/mach-vt8500/include/mach/gpio.h b/arch/arm/mach-vt8500/include/mach/gpio.h
new file mode 100644
index 000000000000..94ff27678a46
--- /dev/null
+++ b/arch/arm/mach-vt8500/include/mach/gpio.h
@@ -0,0 +1,6 @@
1#include <asm-generic/gpio.h>
2
3#define gpio_get_value __gpio_get_value
4#define gpio_set_value __gpio_set_value
5#define gpio_cansleep __gpio_cansleep
6#define gpio_to_irq __gpio_to_irq
diff --git a/arch/arm/mach-vt8500/include/mach/hardware.h b/arch/arm/mach-vt8500/include/mach/hardware.h
new file mode 100644
index 000000000000..db4163f72c39
--- /dev/null
+++ b/arch/arm/mach-vt8500/include/mach/hardware.h
@@ -0,0 +1,12 @@
1/* arch/arm/mach-vt8500/include/mach/hardware.h
2 *
3 * This software is licensed under the terms of the GNU General Public
4 * License version 2, as published by the Free Software Foundation, and
5 * may be copied, distributed, and modified under those terms.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
diff --git a/arch/arm/mach-vt8500/include/mach/i8042.h b/arch/arm/mach-vt8500/include/mach/i8042.h
new file mode 100644
index 000000000000..cd7143cad6f3
--- /dev/null
+++ b/arch/arm/mach-vt8500/include/mach/i8042.h
@@ -0,0 +1,18 @@
1/* arch/arm/mach-vt8500/include/mach/i8042.h
2 *
3 * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15
16extern unsigned long wmt_i8042_base __initdata;
17extern int wmt_i8042_kbd_irq;
18extern int wmt_i8042_aux_irq;
diff --git a/arch/arm/mach-vt8500/include/mach/io.h b/arch/arm/mach-vt8500/include/mach/io.h
new file mode 100644
index 000000000000..9077239f78c9
--- /dev/null
+++ b/arch/arm/mach-vt8500/include/mach/io.h
@@ -0,0 +1,28 @@
1/*
2 * arch/arm/mach-vt8500/include/mach/io.h
3 *
4 * Copyright (C) 2010 Alexey Charkov
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#ifndef __ASM_ARM_ARCH_IO_H
21#define __ASM_ARM_ARCH_IO_H
22
23#define IO_SPACE_LIMIT 0xffff
24
25#define __io(a) __typesafe_io((a) + 0xf0000000)
26#define __mem_pci(a) (a)
27
28#endif
diff --git a/arch/arm/mach-vt8500/include/mach/irqs.h b/arch/arm/mach-vt8500/include/mach/irqs.h
new file mode 100644
index 000000000000..a129fd1222fb
--- /dev/null
+++ b/arch/arm/mach-vt8500/include/mach/irqs.h
@@ -0,0 +1,22 @@
1/*
2 * arch/arm/mach-vt8500/include/mach/irqs.h
3 *
4 * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
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/* This value is just to make the core happy, never used otherwise */
22#define NR_IRQS 128
diff --git a/arch/arm/mach-vt8500/include/mach/memory.h b/arch/arm/mach-vt8500/include/mach/memory.h
new file mode 100644
index 000000000000..175f914eff93
--- /dev/null
+++ b/arch/arm/mach-vt8500/include/mach/memory.h
@@ -0,0 +1,28 @@
1/*
2 * arch/arm/mach-vt8500/include/mach/memory.h
3 *
4 * Copyright (C) 2003 ARM Limited
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#ifndef __ASM_ARCH_MEMORY_H
21#define __ASM_ARCH_MEMORY_H
22
23/*
24 * Physical DRAM offset.
25 */
26#define PHYS_OFFSET UL(0x00000000)
27
28#endif
diff --git a/arch/arm/mach-vt8500/include/mach/system.h b/arch/arm/mach-vt8500/include/mach/system.h
new file mode 100644
index 000000000000..d6c757eaf26b
--- /dev/null
+++ b/arch/arm/mach-vt8500/include/mach/system.h
@@ -0,0 +1,18 @@
1/*
2 * arch/arm/mach-vt8500/include/mach/system.h
3 *
4 */
5#include <asm/io.h>
6
7/* PM Software Reset request register */
8#define VT8500_PMSR_VIRT 0xf8130060
9
10static inline void arch_idle(void)
11{
12 cpu_do_idle();
13}
14
15static inline void arch_reset(char mode, const char *cmd)
16{
17 writel(1, VT8500_PMSR_VIRT);
18}
diff --git a/arch/arm/mach-vt8500/include/mach/timex.h b/arch/arm/mach-vt8500/include/mach/timex.h
new file mode 100644
index 000000000000..8487e4c690b7
--- /dev/null
+++ b/arch/arm/mach-vt8500/include/mach/timex.h
@@ -0,0 +1,26 @@
1/*
2 * arch/arm/mach-vt8500/include/mach/timex.h
3 *
4 * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
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#ifndef MACH_TIMEX_H
22#define MACH_TIMEX_H
23
24#define CLOCK_TICK_RATE (3000000)
25
26#endif /* MACH_TIMEX_H */
diff --git a/arch/arm/mach-vt8500/include/mach/uncompress.h b/arch/arm/mach-vt8500/include/mach/uncompress.h
new file mode 100644
index 000000000000..bb9e2d23fee3
--- /dev/null
+++ b/arch/arm/mach-vt8500/include/mach/uncompress.h
@@ -0,0 +1,37 @@
1/* arch/arm/mach-vt8500/include/mach/uncompress.h
2 *
3 * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
4 *
5 * Based on arch/arm/mach-dove/include/mach/uncompress.h
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
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 */
17
18#define UART0_PHYS 0xd8200000
19#include <asm/io.h>
20
21static void putc(const char c)
22{
23 while (readb(UART0_PHYS + 0x1c) & 0x2)
24 /* Tx busy, wait and poll */;
25
26 writeb(c, UART0_PHYS);
27}
28
29static void flush(void)
30{
31}
32
33/*
34 * nothing to do
35 */
36#define arch_decomp_setup()
37#define arch_decomp_wdog()
diff --git a/arch/arm/mach-vt8500/include/mach/vmalloc.h b/arch/arm/mach-vt8500/include/mach/vmalloc.h
new file mode 100644
index 000000000000..4642290ce416
--- /dev/null
+++ b/arch/arm/mach-vt8500/include/mach/vmalloc.h
@@ -0,0 +1,20 @@
1/*
2 * arch/arm/mach-vt8500/include/mach/vmalloc.h
3 *
4 * Copyright (C) 2000 Russell King.
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#define VMALLOC_END 0xd0000000UL
diff --git a/arch/arm/mach-vt8500/include/mach/vt8500_irqs.h b/arch/arm/mach-vt8500/include/mach/vt8500_irqs.h
new file mode 100644
index 000000000000..ecfee9124711
--- /dev/null
+++ b/arch/arm/mach-vt8500/include/mach/vt8500_irqs.h
@@ -0,0 +1,88 @@
1/*
2 * arch/arm/mach-vt8500/include/mach/vt8500_irqs.h
3 *
4 * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
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/* VT8500 Interrupt Sources */
22
23#define IRQ_JPEGENC 0 /* JPEG Encoder */
24#define IRQ_JPEGDEC 1 /* JPEG Decoder */
25 /* Reserved */
26#define IRQ_PATA 3 /* PATA Controller */
27 /* Reserved */
28#define IRQ_DMA 5 /* DMA Controller */
29#define IRQ_EXT0 6 /* External Interrupt 0 */
30#define IRQ_EXT1 7 /* External Interrupt 1 */
31#define IRQ_GE 8 /* Graphic Engine */
32#define IRQ_GOV 9 /* Graphic Overlay Engine */
33#define IRQ_ETHER 10 /* Ethernet MAC */
34#define IRQ_MPEGTS 11 /* Transport Stream Interface */
35#define IRQ_LCDC 12 /* LCD Controller */
36#define IRQ_EXT2 13 /* External Interrupt 2 */
37#define IRQ_EXT3 14 /* External Interrupt 3 */
38#define IRQ_EXT4 15 /* External Interrupt 4 */
39#define IRQ_CIPHER 16 /* Cipher */
40#define IRQ_VPP 17 /* Video Post-Processor */
41#define IRQ_I2C1 18 /* I2C 1 */
42#define IRQ_I2C0 19 /* I2C 0 */
43#define IRQ_SDMMC 20 /* SD/MMC Controller */
44#define IRQ_SDMMC_DMA 21 /* SD/MMC Controller DMA */
45#define IRQ_PMC_WU 22 /* Power Management Controller Wakeup */
46 /* Reserved */
47#define IRQ_SPI0 24 /* SPI 0 */
48#define IRQ_SPI1 25 /* SPI 1 */
49#define IRQ_SPI2 26 /* SPI 2 */
50#define IRQ_LCDDF 27 /* LCD Data Formatter */
51#define IRQ_NAND 28 /* NAND Flash Controller */
52#define IRQ_NAND_DMA 29 /* NAND Flash Controller DMA */
53#define IRQ_MS 30 /* MemoryStick Controller */
54#define IRQ_MS_DMA 31 /* MemoryStick Controller DMA */
55#define IRQ_UART0 32 /* UART 0 */
56#define IRQ_UART1 33 /* UART 1 */
57#define IRQ_I2S 34 /* I2S */
58#define IRQ_PCM 35 /* PCM */
59#define IRQ_PMCOS0 36 /* PMC OS Timer 0 */
60#define IRQ_PMCOS1 37 /* PMC OS Timer 1 */
61#define IRQ_PMCOS2 38 /* PMC OS Timer 2 */
62#define IRQ_PMCOS3 39 /* PMC OS Timer 3 */
63#define IRQ_VPU 40 /* Video Processing Unit */
64#define IRQ_VID 41 /* Video Digital Input Interface */
65#define IRQ_AC97 42 /* AC97 Interface */
66#define IRQ_EHCI 43 /* USB */
67#define IRQ_NOR 44 /* NOR Flash Controller */
68#define IRQ_PS2MOUSE 45 /* PS/2 Mouse */
69#define IRQ_PS2KBD 46 /* PS/2 Keyboard */
70#define IRQ_UART2 47 /* UART 2 */
71#define IRQ_RTC 48 /* RTC Interrupt */
72#define IRQ_RTCSM 49 /* RTC Second/Minute Update Interrupt */
73#define IRQ_UART3 50 /* UART 3 */
74#define IRQ_ADC 51 /* ADC */
75#define IRQ_EXT5 52 /* External Interrupt 5 */
76#define IRQ_EXT6 53 /* External Interrupt 6 */
77#define IRQ_EXT7 54 /* External Interrupt 7 */
78#define IRQ_CIR 55 /* CIR */
79#define IRQ_DMA0 56 /* DMA Channel 0 */
80#define IRQ_DMA1 57 /* DMA Channel 1 */
81#define IRQ_DMA2 58 /* DMA Channel 2 */
82#define IRQ_DMA3 59 /* DMA Channel 3 */
83#define IRQ_DMA4 60 /* DMA Channel 4 */
84#define IRQ_DMA5 61 /* DMA Channel 5 */
85#define IRQ_DMA6 62 /* DMA Channel 6 */
86#define IRQ_DMA7 63 /* DMA Channel 7 */
87
88#define VT8500_NR_IRQS 64
diff --git a/arch/arm/mach-vt8500/include/mach/vt8500_regs.h b/arch/arm/mach-vt8500/include/mach/vt8500_regs.h
new file mode 100644
index 000000000000..29c63ecb2383
--- /dev/null
+++ b/arch/arm/mach-vt8500/include/mach/vt8500_regs.h
@@ -0,0 +1,79 @@
1/*
2 * arch/arm/mach-vt8500/include/mach/vt8500_regs.h
3 *
4 * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
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#ifndef __ASM_ARM_ARCH_VT8500_REGS_H
21#define __ASM_ARM_ARCH_VT8500_REGS_H
22
23/* VT8500 Registers Map */
24
25#define VT8500_REGS_START_PHYS 0xd8000000 /* Start of MMIO registers */
26#define VT8500_REGS_START_VIRT 0xf8000000 /* Virtual mapping start */
27
28#define VT8500_DDR_BASE 0xd8000000 /* 1k DDR/DDR2 Memory
29 Controller */
30#define VT8500_DMA_BASE 0xd8001000 /* 1k DMA Controller */
31#define VT8500_SFLASH_BASE 0xd8002000 /* 1k Serial Flash Memory
32 Controller */
33#define VT8500_ETHER_BASE 0xd8004000 /* 1k Ethernet MAC 0 */
34#define VT8500_CIPHER_BASE 0xd8006000 /* 4k Cipher */
35#define VT8500_USB_BASE 0xd8007800 /* 2k USB OTG */
36# define VT8500_EHCI_BASE 0xd8007900 /* EHCI */
37# define VT8500_UHCI_BASE 0xd8007b01 /* UHCI */
38#define VT8500_PATA_BASE 0xd8008000 /* 512 PATA */
39#define VT8500_PS2_BASE 0xd8008800 /* 1k PS/2 */
40#define VT8500_NAND_BASE 0xd8009000 /* 1k NAND Controller */
41#define VT8500_NOR_BASE 0xd8009400 /* 1k NOR Controller */
42#define VT8500_SDMMC_BASE 0xd800a000 /* 1k SD/MMC Controller */
43#define VT8500_MS_BASE 0xd800b000 /* 1k MS/MSPRO Controller */
44#define VT8500_LCDC_BASE 0xd800e400 /* 1k LCD Controller */
45#define VT8500_VPU_BASE 0xd8050000 /* 256 VPU */
46#define VT8500_GOV_BASE 0xd8050300 /* 256 GOV */
47#define VT8500_GEGEA_BASE 0xd8050400 /* 768 GE/GE Alpha Mixing */
48#define VT8500_LCDF_BASE 0xd8050900 /* 256 LCD Formatter */
49#define VT8500_VID_BASE 0xd8050a00 /* 256 VID */
50#define VT8500_VPP_BASE 0xd8050b00 /* 256 VPP */
51#define VT8500_TSBK_BASE 0xd80f4000 /* 4k TSBK */
52#define VT8500_JPEGDEC_BASE 0xd80fe000 /* 4k JPEG Decoder */
53#define VT8500_JPEGENC_BASE 0xd80ff000 /* 4k JPEG Encoder */
54#define VT8500_RTC_BASE 0xd8100000 /* 64k RTC */
55#define VT8500_GPIO_BASE 0xd8110000 /* 64k GPIO Configuration */
56#define VT8500_SCC_BASE 0xd8120000 /* 64k System Configuration*/
57#define VT8500_PMC_BASE 0xd8130000 /* 64k PMC Configuration */
58#define VT8500_IC_BASE 0xd8140000 /* 64k Interrupt Controller*/
59#define VT8500_UART0_BASE 0xd8200000 /* 64k UART 0 */
60#define VT8500_UART2_BASE 0xd8210000 /* 64k UART 2 */
61#define VT8500_PWM_BASE 0xd8220000 /* 64k PWM Configuration */
62#define VT8500_SPI0_BASE 0xd8240000 /* 64k SPI 0 */
63#define VT8500_SPI1_BASE 0xd8250000 /* 64k SPI 1 */
64#define VT8500_CIR_BASE 0xd8270000 /* 64k CIR */
65#define VT8500_I2C0_BASE 0xd8280000 /* 64k I2C 0 */
66#define VT8500_AC97_BASE 0xd8290000 /* 64k AC97 */
67#define VT8500_SPI2_BASE 0xd82a0000 /* 64k SPI 2 */
68#define VT8500_UART1_BASE 0xd82b0000 /* 64k UART 1 */
69#define VT8500_UART3_BASE 0xd82c0000 /* 64k UART 3 */
70#define VT8500_PCM_BASE 0xd82d0000 /* 64k PCM */
71#define VT8500_I2C1_BASE 0xd8320000 /* 64k I2C 1 */
72#define VT8500_I2S_BASE 0xd8330000 /* 64k I2S */
73#define VT8500_ADC_BASE 0xd8340000 /* 64k ADC */
74
75#define VT8500_REGS_END_PHYS 0xd834ffff /* End of MMIO registers */
76#define VT8500_REGS_LENGTH (VT8500_REGS_END_PHYS \
77 - VT8500_REGS_START_PHYS + 1)
78
79#endif
diff --git a/arch/arm/mach-vt8500/include/mach/vt8500fb.h b/arch/arm/mach-vt8500/include/mach/vt8500fb.h
new file mode 100644
index 000000000000..7f399c370fe0
--- /dev/null
+++ b/arch/arm/mach-vt8500/include/mach/vt8500fb.h
@@ -0,0 +1,31 @@
1/*
2 * VT8500/WM8505 Frame Buffer platform data definitions
3 *
4 * Copyright (C) 2010 Ed Spiridonov <edo.rus@gmail.com>
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#ifndef _VT8500FB_H
17#define _VT8500FB_H
18
19#include <linux/fb.h>
20
21struct vt8500fb_platform_data {
22 struct fb_videomode mode;
23 u32 xres_virtual;
24 u32 yres_virtual;
25 u32 bpp;
26 unsigned long video_mem_phys;
27 void *video_mem_virt;
28 unsigned long video_mem_len;
29};
30
31#endif /* _VT8500FB_H */
diff --git a/arch/arm/mach-vt8500/include/mach/wm8505_irqs.h b/arch/arm/mach-vt8500/include/mach/wm8505_irqs.h
new file mode 100644
index 000000000000..6128627ac753
--- /dev/null
+++ b/arch/arm/mach-vt8500/include/mach/wm8505_irqs.h
@@ -0,0 +1,115 @@
1/*
2 * arch/arm/mach-vt8500/include/mach/wm8505_irqs.h
3 *
4 * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
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/* WM8505 Interrupt Sources */
22
23#define IRQ_UHCI 0 /* UHC FS (UHCI?) */
24#define IRQ_EHCI 1 /* UHC HS */
25#define IRQ_UDCDMA 2 /* UDC DMA */
26 /* Reserved */
27#define IRQ_PS2MOUSE 4 /* PS/2 Mouse */
28#define IRQ_UDC 5 /* UDC */
29#define IRQ_EXT0 6 /* External Interrupt 0 */
30#define IRQ_EXT1 7 /* External Interrupt 1 */
31#define IRQ_KEYPAD 8 /* Keypad */
32#define IRQ_DMA 9 /* DMA Controller */
33#define IRQ_ETHER 10 /* Ethernet MAC */
34 /* Reserved */
35 /* Reserved */
36#define IRQ_EXT2 13 /* External Interrupt 2 */
37#define IRQ_EXT3 14 /* External Interrupt 3 */
38#define IRQ_EXT4 15 /* External Interrupt 4 */
39#define IRQ_APB 16 /* APB Bridge */
40#define IRQ_DMA0 17 /* DMA Channel 0 */
41#define IRQ_I2C1 18 /* I2C 1 */
42#define IRQ_I2C0 19 /* I2C 0 */
43#define IRQ_SDMMC 20 /* SD/MMC Controller */
44#define IRQ_SDMMC_DMA 21 /* SD/MMC Controller DMA */
45#define IRQ_PMC_WU 22 /* Power Management Controller Wakeup */
46#define IRQ_PS2KBD 23 /* PS/2 Keyboard */
47#define IRQ_SPI0 24 /* SPI 0 */
48#define IRQ_SPI1 25 /* SPI 1 */
49#define IRQ_SPI2 26 /* SPI 2 */
50#define IRQ_DMA1 27 /* DMA Channel 1 */
51#define IRQ_NAND 28 /* NAND Flash Controller */
52#define IRQ_NAND_DMA 29 /* NAND Flash Controller DMA */
53#define IRQ_UART5 30 /* UART 5 */
54#define IRQ_UART4 31 /* UART 4 */
55#define IRQ_UART0 32 /* UART 0 */
56#define IRQ_UART1 33 /* UART 1 */
57#define IRQ_DMA2 34 /* DMA Channel 2 */
58#define IRQ_I2S 35 /* I2S */
59#define IRQ_PMCOS0 36 /* PMC OS Timer 0 */
60#define IRQ_PMCOS1 37 /* PMC OS Timer 1 */
61#define IRQ_PMCOS2 38 /* PMC OS Timer 2 */
62#define IRQ_PMCOS3 39 /* PMC OS Timer 3 */
63#define IRQ_DMA3 40 /* DMA Channel 3 */
64#define IRQ_DMA4 41 /* DMA Channel 4 */
65#define IRQ_AC97 42 /* AC97 Interface */
66 /* Reserved */
67#define IRQ_NOR 44 /* NOR Flash Controller */
68#define IRQ_DMA5 45 /* DMA Channel 5 */
69#define IRQ_DMA6 46 /* DMA Channel 6 */
70#define IRQ_UART2 47 /* UART 2 */
71#define IRQ_RTC 48 /* RTC Interrupt */
72#define IRQ_RTCSM 49 /* RTC Second/Minute Update Interrupt */
73#define IRQ_UART3 50 /* UART 3 */
74#define IRQ_DMA7 51 /* DMA Channel 7 */
75#define IRQ_EXT5 52 /* External Interrupt 5 */
76#define IRQ_EXT6 53 /* External Interrupt 6 */
77#define IRQ_EXT7 54 /* External Interrupt 7 */
78#define IRQ_CIR 55 /* CIR */
79#define IRQ_SIC0 56 /* SIC IRQ0 */
80#define IRQ_SIC1 57 /* SIC IRQ1 */
81#define IRQ_SIC2 58 /* SIC IRQ2 */
82#define IRQ_SIC3 59 /* SIC IRQ3 */
83#define IRQ_SIC4 60 /* SIC IRQ4 */
84#define IRQ_SIC5 61 /* SIC IRQ5 */
85#define IRQ_SIC6 62 /* SIC IRQ6 */
86#define IRQ_SIC7 63 /* SIC IRQ7 */
87 /* Reserved */
88#define IRQ_JPEGDEC 65 /* JPEG Decoder */
89#define IRQ_SAE 66 /* SAE (?) */
90 /* Reserved */
91#define IRQ_VPU 79 /* Video Processing Unit */
92#define IRQ_VPP 80 /* Video Post-Processor */
93#define IRQ_VID 81 /* Video Digital Input Interface */
94#define IRQ_SPU 82 /* SPU (?) */
95#define IRQ_PIP 83 /* PIP Error */
96#define IRQ_GE 84 /* Graphic Engine */
97#define IRQ_GOV 85 /* Graphic Overlay Engine */
98#define IRQ_DVO 86 /* Digital Video Output */
99 /* Reserved */
100#define IRQ_DMA8 92 /* DMA Channel 8 */
101#define IRQ_DMA9 93 /* DMA Channel 9 */
102#define IRQ_DMA10 94 /* DMA Channel 10 */
103#define IRQ_DMA11 95 /* DMA Channel 11 */
104#define IRQ_DMA12 96 /* DMA Channel 12 */
105#define IRQ_DMA13 97 /* DMA Channel 13 */
106#define IRQ_DMA14 98 /* DMA Channel 14 */
107#define IRQ_DMA15 99 /* DMA Channel 15 */
108 /* Reserved */
109#define IRQ_GOVW 111 /* GOVW (?) */
110#define IRQ_GOVRSDSCD 112 /* GOVR SDSCD (?) */
111#define IRQ_GOVRSDMIF 113 /* GOVR SDMIF (?) */
112#define IRQ_GOVRHDSCD 114 /* GOVR HDSCD (?) */
113#define IRQ_GOVRHDMIF 115 /* GOVR HDMIF (?) */
114
115#define WM8505_NR_IRQS 116
diff --git a/arch/arm/mach-vt8500/include/mach/wm8505_regs.h b/arch/arm/mach-vt8500/include/mach/wm8505_regs.h
new file mode 100644
index 000000000000..df1550941efb
--- /dev/null
+++ b/arch/arm/mach-vt8500/include/mach/wm8505_regs.h
@@ -0,0 +1,78 @@
1/*
2 * arch/arm/mach-vt8500/include/mach/wm8505_regs.h
3 *
4 * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
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#ifndef __ASM_ARM_ARCH_WM8505_REGS_H
21#define __ASM_ARM_ARCH_WM8505_REGS_H
22
23/* WM8505 Registers Map */
24
25#define WM8505_REGS_START_PHYS 0xd8000000 /* Start of MMIO registers */
26#define WM8505_REGS_START_VIRT 0xf8000000 /* Virtual mapping start */
27
28#define WM8505_DDR_BASE 0xd8000400 /* 1k DDR/DDR2 Memory
29 Controller */
30#define WM8505_DMA_BASE 0xd8001800 /* 1k DMA Controller */
31#define WM8505_VDMA_BASE 0xd8001c00 /* 1k VDMA */
32#define WM8505_SFLASH_BASE 0xd8002000 /* 1k Serial Flash Memory
33 Controller */
34#define WM8505_ETHER_BASE 0xd8004000 /* 1k Ethernet MAC 0 */
35#define WM8505_CIPHER_BASE 0xd8006000 /* 4k Cipher */
36#define WM8505_USB_BASE 0xd8007000 /* 2k USB 2.0 Host */
37# define WM8505_EHCI_BASE 0xd8007100 /* EHCI */
38# define WM8505_UHCI_BASE 0xd8007301 /* UHCI */
39#define WM8505_PS2_BASE 0xd8008800 /* 1k PS/2 */
40#define WM8505_NAND_BASE 0xd8009000 /* 1k NAND Controller */
41#define WM8505_NOR_BASE 0xd8009400 /* 1k NOR Controller */
42#define WM8505_SDMMC_BASE 0xd800a000 /* 1k SD/MMC Controller */
43#define WM8505_VPU_BASE 0xd8050000 /* 256 VPU */
44#define WM8505_GOV_BASE 0xd8050300 /* 256 GOV */
45#define WM8505_GEGEA_BASE 0xd8050400 /* 768 GE/GE Alpha Mixing */
46#define WM8505_GOVR_BASE 0xd8050800 /* 512 GOVR (frambuffer) */
47#define WM8505_VID_BASE 0xd8050a00 /* 256 VID */
48#define WM8505_SCL_BASE 0xd8050d00 /* 256 SCL */
49#define WM8505_VPP_BASE 0xd8050f00 /* 256 VPP */
50#define WM8505_JPEGDEC_BASE 0xd80fe000 /* 4k JPEG Decoder */
51#define WM8505_RTC_BASE 0xd8100000 /* 64k RTC */
52#define WM8505_GPIO_BASE 0xd8110000 /* 64k GPIO Configuration */
53#define WM8505_SCC_BASE 0xd8120000 /* 64k System Configuration*/
54#define WM8505_PMC_BASE 0xd8130000 /* 64k PMC Configuration */
55#define WM8505_IC_BASE 0xd8140000 /* 64k Interrupt Controller*/
56#define WM8505_SIC_BASE 0xd8150000 /* 64k Secondary IC */
57#define WM8505_UART0_BASE 0xd8200000 /* 64k UART 0 */
58#define WM8505_UART2_BASE 0xd8210000 /* 64k UART 2 */
59#define WM8505_PWM_BASE 0xd8220000 /* 64k PWM Configuration */
60#define WM8505_SPI0_BASE 0xd8240000 /* 64k SPI 0 */
61#define WM8505_SPI1_BASE 0xd8250000 /* 64k SPI 1 */
62#define WM8505_KEYPAD_BASE 0xd8260000 /* 64k Keypad control */
63#define WM8505_CIR_BASE 0xd8270000 /* 64k CIR */
64#define WM8505_I2C0_BASE 0xd8280000 /* 64k I2C 0 */
65#define WM8505_AC97_BASE 0xd8290000 /* 64k AC97 */
66#define WM8505_SPI2_BASE 0xd82a0000 /* 64k SPI 2 */
67#define WM8505_UART1_BASE 0xd82b0000 /* 64k UART 1 */
68#define WM8505_UART3_BASE 0xd82c0000 /* 64k UART 3 */
69#define WM8505_I2C1_BASE 0xd8320000 /* 64k I2C 1 */
70#define WM8505_I2S_BASE 0xd8330000 /* 64k I2S */
71#define WM8505_UART4_BASE 0xd8370000 /* 64k UART 4 */
72#define WM8505_UART5_BASE 0xd8380000 /* 64k UART 5 */
73
74#define WM8505_REGS_END_PHYS 0xd838ffff /* End of MMIO registers */
75#define WM8505_REGS_LENGTH (WM8505_REGS_END_PHYS \
76 - WM8505_REGS_START_PHYS + 1)
77
78#endif
diff --git a/arch/arm/mach-vt8500/irq.c b/arch/arm/mach-vt8500/irq.c
new file mode 100644
index 000000000000..5f4ddde4f02a
--- /dev/null
+++ b/arch/arm/mach-vt8500/irq.c
@@ -0,0 +1,177 @@
1/*
2 * arch/arm/mach-vt8500/irq.c
3 *
4 * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
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#include <linux/io.h>
22#include <linux/irq.h>
23#include <linux/interrupt.h>
24
25#include <asm/irq.h>
26
27#include "devices.h"
28
29#define VT8500_IC_DCTR 0x40 /* Destination control
30 register, 64*u8 */
31#define VT8500_INT_ENABLE (1 << 3)
32#define VT8500_TRIGGER_HIGH (0 << 4)
33#define VT8500_TRIGGER_RISING (1 << 4)
34#define VT8500_TRIGGER_FALLING (2 << 4)
35#define VT8500_EDGE ( VT8500_TRIGGER_RISING \
36 | VT8500_TRIGGER_FALLING)
37#define VT8500_IC_STATUS 0x80 /* Interrupt status, 2*u32 */
38
39static void __iomem *ic_regbase;
40static void __iomem *sic_regbase;
41
42static void vt8500_irq_mask(unsigned int irq)
43{
44 void __iomem *base = ic_regbase;
45 u8 edge;
46
47 if (irq >= 64) {
48 base = sic_regbase;
49 irq -= 64;
50 }
51 edge = readb(base + VT8500_IC_DCTR + irq) & VT8500_EDGE;
52 if (edge) {
53 void __iomem *stat_reg = base + VT8500_IC_STATUS
54 + (irq < 32 ? 0 : 4);
55 unsigned status = readl(stat_reg);
56
57 status |= (1 << (irq & 0x1f));
58 writel(status, stat_reg);
59 } else {
60 u8 dctr = readb(base + VT8500_IC_DCTR + irq);
61
62 dctr &= ~VT8500_INT_ENABLE;
63 writeb(dctr, base + VT8500_IC_DCTR + irq);
64 }
65}
66
67static void vt8500_irq_unmask(unsigned int irq)
68{
69 void __iomem *base = ic_regbase;
70 u8 dctr;
71
72 if (irq >= 64) {
73 base = sic_regbase;
74 irq -= 64;
75 }
76 dctr = readb(base + VT8500_IC_DCTR + irq);
77 dctr |= VT8500_INT_ENABLE;
78 writeb(dctr, base + VT8500_IC_DCTR + irq);
79}
80
81static int vt8500_irq_set_type(unsigned int irq, unsigned int flow_type)
82{
83 void __iomem *base = ic_regbase;
84 unsigned int orig_irq = irq;
85 u8 dctr;
86
87 if (irq >= 64) {
88 base = sic_regbase;
89 irq -= 64;
90 }
91
92 dctr = readb(base + VT8500_IC_DCTR + irq);
93 dctr &= ~VT8500_EDGE;
94
95 switch (flow_type) {
96 case IRQF_TRIGGER_LOW:
97 return -EINVAL;
98 case IRQF_TRIGGER_HIGH:
99 dctr |= VT8500_TRIGGER_HIGH;
100 irq_desc[orig_irq].handle_irq = handle_level_irq;
101 break;
102 case IRQF_TRIGGER_FALLING:
103 dctr |= VT8500_TRIGGER_FALLING;
104 irq_desc[orig_irq].handle_irq = handle_edge_irq;
105 break;
106 case IRQF_TRIGGER_RISING:
107 dctr |= VT8500_TRIGGER_RISING;
108 irq_desc[orig_irq].handle_irq = handle_edge_irq;
109 break;
110 }
111 writeb(dctr, base + VT8500_IC_DCTR + irq);
112
113 return 0;
114}
115
116static struct irq_chip vt8500_irq_chip = {
117 .name = "vt8500",
118 .ack = vt8500_irq_mask,
119 .mask = vt8500_irq_mask,
120 .unmask = vt8500_irq_unmask,
121 .set_type = vt8500_irq_set_type,
122};
123
124void __init vt8500_init_irq(void)
125{
126 unsigned int i;
127
128 ic_regbase = ioremap(wmt_ic_base, SZ_64K);
129
130 if (ic_regbase) {
131 /* Enable rotating priority for IRQ */
132 writel((1 << 6), ic_regbase + 0x20);
133 writel(0, ic_regbase + 0x24);
134
135 for (i = 0; i < wmt_nr_irqs; i++) {
136 /* Disable all interrupts and route them to IRQ */
137 writeb(0x00, ic_regbase + VT8500_IC_DCTR + i);
138
139 set_irq_chip(i, &vt8500_irq_chip);
140 set_irq_handler(i, handle_level_irq);
141 set_irq_flags(i, IRQF_VALID);
142 }
143 } else {
144 printk(KERN_ERR "Unable to remap the Interrupt Controller registers, not enabling IRQs!\n");
145 }
146}
147
148void __init wm8505_init_irq(void)
149{
150 unsigned int i;
151
152 ic_regbase = ioremap(wmt_ic_base, SZ_64K);
153 sic_regbase = ioremap(wmt_sic_base, SZ_64K);
154
155 if (ic_regbase && sic_regbase) {
156 /* Enable rotating priority for IRQ */
157 writel((1 << 6), ic_regbase + 0x20);
158 writel(0, ic_regbase + 0x24);
159 writel((1 << 6), sic_regbase + 0x20);
160 writel(0, sic_regbase + 0x24);
161
162 for (i = 0; i < wmt_nr_irqs; i++) {
163 /* Disable all interrupts and route them to IRQ */
164 if (i < 64)
165 writeb(0x00, ic_regbase + VT8500_IC_DCTR + i);
166 else
167 writeb(0x00, sic_regbase + VT8500_IC_DCTR
168 + i - 64);
169
170 set_irq_chip(i, &vt8500_irq_chip);
171 set_irq_handler(i, handle_level_irq);
172 set_irq_flags(i, IRQF_VALID);
173 }
174 } else {
175 printk(KERN_ERR "Unable to remap the Interrupt Controller registers, not enabling IRQs!\n");
176 }
177}
diff --git a/arch/arm/mach-vt8500/pwm.c b/arch/arm/mach-vt8500/pwm.c
new file mode 100644
index 000000000000..8ad825e93592
--- /dev/null
+++ b/arch/arm/mach-vt8500/pwm.c
@@ -0,0 +1,265 @@
1/*
2 * arch/arm/mach-vt8500/pwm.c
3 *
4 * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <linux/module.h>
17#include <linux/kernel.h>
18#include <linux/platform_device.h>
19#include <linux/slab.h>
20#include <linux/err.h>
21#include <linux/io.h>
22#include <linux/pwm.h>
23#include <linux/delay.h>
24
25#include <asm/div64.h>
26
27#define VT8500_NR_PWMS 4
28
29static DEFINE_MUTEX(pwm_lock);
30static LIST_HEAD(pwm_list);
31
32struct pwm_device {
33 struct list_head node;
34 struct platform_device *pdev;
35
36 const char *label;
37
38 void __iomem *regbase;
39
40 unsigned int use_count;
41 unsigned int pwm_id;
42};
43
44#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
45static inline void pwm_busy_wait(void __iomem *reg, u8 bitmask)
46{
47 int loops = msecs_to_loops(10);
48 while ((readb(reg) & bitmask) && --loops)
49 cpu_relax();
50
51 if (unlikely(!loops))
52 pr_warning("Waiting for status bits 0x%x to clear timed out\n",
53 bitmask);
54}
55
56int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
57{
58 unsigned long long c;
59 unsigned long period_cycles, prescale, pv, dc;
60
61 if (pwm == NULL || period_ns == 0 || duty_ns > period_ns)
62 return -EINVAL;
63
64 c = 25000000/2; /* wild guess --- need to implement clocks */
65 c = c * period_ns;
66 do_div(c, 1000000000);
67 period_cycles = c;
68
69 if (period_cycles < 1)
70 period_cycles = 1;
71 prescale = (period_cycles - 1) / 4096;
72 pv = period_cycles / (prescale + 1) - 1;
73 if (pv > 4095)
74 pv = 4095;
75
76 if (prescale > 1023)
77 return -EINVAL;
78
79 c = (unsigned long long)pv * duty_ns;
80 do_div(c, period_ns);
81 dc = c;
82
83 pwm_busy_wait(pwm->regbase + 0x40 + pwm->pwm_id, (1 << 1));
84 writel(prescale, pwm->regbase + 0x4 + (pwm->pwm_id << 4));
85
86 pwm_busy_wait(pwm->regbase + 0x40 + pwm->pwm_id, (1 << 2));
87 writel(pv, pwm->regbase + 0x8 + (pwm->pwm_id << 4));
88
89 pwm_busy_wait(pwm->regbase + 0x40 + pwm->pwm_id, (1 << 3));
90 writel(dc, pwm->regbase + 0xc + (pwm->pwm_id << 4));
91
92 return 0;
93}
94EXPORT_SYMBOL(pwm_config);
95
96int pwm_enable(struct pwm_device *pwm)
97{
98 pwm_busy_wait(pwm->regbase + 0x40 + pwm->pwm_id, (1 << 0));
99 writel(5, pwm->regbase + (pwm->pwm_id << 4));
100 return 0;
101}
102EXPORT_SYMBOL(pwm_enable);
103
104void pwm_disable(struct pwm_device *pwm)
105{
106 pwm_busy_wait(pwm->regbase + 0x40 + pwm->pwm_id, (1 << 0));
107 writel(0, pwm->regbase + (pwm->pwm_id << 4));
108}
109EXPORT_SYMBOL(pwm_disable);
110
111struct pwm_device *pwm_request(int pwm_id, const char *label)
112{
113 struct pwm_device *pwm;
114 int found = 0;
115
116 mutex_lock(&pwm_lock);
117
118 list_for_each_entry(pwm, &pwm_list, node) {
119 if (pwm->pwm_id == pwm_id) {
120 found = 1;
121 break;
122 }
123 }
124
125 if (found) {
126 if (pwm->use_count == 0) {
127 pwm->use_count++;
128 pwm->label = label;
129 } else {
130 pwm = ERR_PTR(-EBUSY);
131 }
132 } else {
133 pwm = ERR_PTR(-ENOENT);
134 }
135
136 mutex_unlock(&pwm_lock);
137 return pwm;
138}
139EXPORT_SYMBOL(pwm_request);
140
141void pwm_free(struct pwm_device *pwm)
142{
143 mutex_lock(&pwm_lock);
144
145 if (pwm->use_count) {
146 pwm->use_count--;
147 pwm->label = NULL;
148 } else {
149 pr_warning("PWM device already freed\n");
150 }
151
152 mutex_unlock(&pwm_lock);
153}
154EXPORT_SYMBOL(pwm_free);
155
156static inline void __add_pwm(struct pwm_device *pwm)
157{
158 mutex_lock(&pwm_lock);
159 list_add_tail(&pwm->node, &pwm_list);
160 mutex_unlock(&pwm_lock);
161}
162
163static int __devinit pwm_probe(struct platform_device *pdev)
164{
165 struct pwm_device *pwms;
166 struct resource *r;
167 int ret = 0;
168 int i;
169
170 pwms = kzalloc(sizeof(struct pwm_device) * VT8500_NR_PWMS, GFP_KERNEL);
171 if (pwms == NULL) {
172 dev_err(&pdev->dev, "failed to allocate memory\n");
173 return -ENOMEM;
174 }
175
176 for (i = 0; i < VT8500_NR_PWMS; i++) {
177 pwms[i].use_count = 0;
178 pwms[i].pwm_id = i;
179 pwms[i].pdev = pdev;
180 }
181
182 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
183 if (r == NULL) {
184 dev_err(&pdev->dev, "no memory resource defined\n");
185 ret = -ENODEV;
186 goto err_free;
187 }
188
189 r = request_mem_region(r->start, resource_size(r), pdev->name);
190 if (r == NULL) {
191 dev_err(&pdev->dev, "failed to request memory resource\n");
192 ret = -EBUSY;
193 goto err_free;
194 }
195
196 pwms[0].regbase = ioremap(r->start, resource_size(r));
197 if (pwms[0].regbase == NULL) {
198 dev_err(&pdev->dev, "failed to ioremap() registers\n");
199 ret = -ENODEV;
200 goto err_free_mem;
201 }
202
203 for (i = 1; i < VT8500_NR_PWMS; i++)
204 pwms[i].regbase = pwms[0].regbase;
205
206 for (i = 0; i < VT8500_NR_PWMS; i++)
207 __add_pwm(&pwms[i]);
208
209 platform_set_drvdata(pdev, pwms);
210 return 0;
211
212err_free_mem:
213 release_mem_region(r->start, resource_size(r));
214err_free:
215 kfree(pwms);
216 return ret;
217}
218
219static int __devexit pwm_remove(struct platform_device *pdev)
220{
221 struct pwm_device *pwms;
222 struct resource *r;
223 int i;
224
225 pwms = platform_get_drvdata(pdev);
226 if (pwms == NULL)
227 return -ENODEV;
228
229 mutex_lock(&pwm_lock);
230
231 for (i = 0; i < VT8500_NR_PWMS; i++)
232 list_del(&pwms[i].node);
233 mutex_unlock(&pwm_lock);
234
235 iounmap(pwms[0].regbase);
236
237 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
238 release_mem_region(r->start, resource_size(r));
239
240 kfree(pwms);
241 return 0;
242}
243
244static struct platform_driver pwm_driver = {
245 .driver = {
246 .name = "vt8500-pwm",
247 .owner = THIS_MODULE,
248 },
249 .probe = pwm_probe,
250 .remove = __devexit_p(pwm_remove),
251};
252
253static int __init pwm_init(void)
254{
255 return platform_driver_register(&pwm_driver);
256}
257arch_initcall(pwm_init);
258
259static void __exit pwm_exit(void)
260{
261 platform_driver_unregister(&pwm_driver);
262}
263module_exit(pwm_exit);
264
265MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-vt8500/timer.c b/arch/arm/mach-vt8500/timer.c
new file mode 100644
index 000000000000..d5376c592ab6
--- /dev/null
+++ b/arch/arm/mach-vt8500/timer.c
@@ -0,0 +1,155 @@
1/*
2 * arch/arm/mach-vt8500/timer.c
3 *
4 * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
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#include <linux/io.h>
22#include <linux/irq.h>
23#include <linux/interrupt.h>
24#include <linux/clocksource.h>
25#include <linux/clockchips.h>
26#include <linux/delay.h>
27
28#include <asm/mach/time.h>
29
30#include "devices.h"
31
32#define VT8500_TIMER_OFFSET 0x0100
33#define TIMER_MATCH_VAL 0x0000
34#define TIMER_COUNT_VAL 0x0010
35#define TIMER_STATUS_VAL 0x0014
36#define TIMER_IER_VAL 0x001c /* interrupt enable */
37#define TIMER_CTRL_VAL 0x0020
38#define TIMER_AS_VAL 0x0024 /* access status */
39#define TIMER_COUNT_R_ACTIVE (1 << 5) /* not ready for read */
40#define TIMER_COUNT_W_ACTIVE (1 << 4) /* not ready for write */
41#define TIMER_MATCH_W_ACTIVE (1 << 0) /* not ready for write */
42#define VT8500_TIMER_HZ 3000000
43
44#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
45
46static void __iomem *regbase;
47
48static cycle_t vt8500_timer_read(struct clocksource *cs)
49{
50 int loops = msecs_to_loops(10);
51 writel(3, regbase + TIMER_CTRL_VAL);
52 while ((readl((regbase + TIMER_AS_VAL)) & TIMER_COUNT_R_ACTIVE)
53 && --loops)
54 cpu_relax();
55 return readl(regbase + TIMER_COUNT_VAL);
56}
57
58struct clocksource clocksource = {
59 .name = "vt8500_timer",
60 .rating = 200,
61 .read = vt8500_timer_read,
62 .mask = CLOCKSOURCE_MASK(32),
63 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
64};
65
66static int vt8500_timer_set_next_event(unsigned long cycles,
67 struct clock_event_device *evt)
68{
69 int loops = msecs_to_loops(10);
70 cycle_t alarm = clocksource.read(&clocksource) + cycles;
71 while ((readl(regbase + TIMER_AS_VAL) & TIMER_MATCH_W_ACTIVE)
72 && --loops)
73 cpu_relax();
74 writel((unsigned long)alarm, regbase + TIMER_MATCH_VAL);
75
76 if ((signed)(alarm - clocksource.read(&clocksource)) <= 16)
77 return -ETIME;
78
79 writel(1, regbase + TIMER_IER_VAL);
80
81 return 0;
82}
83
84static void vt8500_timer_set_mode(enum clock_event_mode mode,
85 struct clock_event_device *evt)
86{
87 switch (mode) {
88 case CLOCK_EVT_MODE_RESUME:
89 case CLOCK_EVT_MODE_PERIODIC:
90 break;
91 case CLOCK_EVT_MODE_ONESHOT:
92 case CLOCK_EVT_MODE_UNUSED:
93 case CLOCK_EVT_MODE_SHUTDOWN:
94 writel(readl(regbase + TIMER_CTRL_VAL) | 1,
95 regbase + TIMER_CTRL_VAL);
96 writel(0, regbase + TIMER_IER_VAL);
97 break;
98 }
99}
100
101struct clock_event_device clockevent = {
102 .name = "vt8500_timer",
103 .features = CLOCK_EVT_FEAT_ONESHOT,
104 .rating = 200,
105 .set_next_event = vt8500_timer_set_next_event,
106 .set_mode = vt8500_timer_set_mode,
107};
108
109static irqreturn_t vt8500_timer_interrupt(int irq, void *dev_id)
110{
111 struct clock_event_device *evt = dev_id;
112 writel(0xf, regbase + TIMER_STATUS_VAL);
113 evt->event_handler(evt);
114
115 return IRQ_HANDLED;
116}
117
118struct irqaction irq = {
119 .name = "vt8500_timer",
120 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
121 .handler = vt8500_timer_interrupt,
122 .dev_id = &clockevent,
123};
124
125static void __init vt8500_timer_init(void)
126{
127 regbase = ioremap(wmt_pmc_base + VT8500_TIMER_OFFSET, 0x28);
128 if (!regbase)
129 printk(KERN_ERR "vt8500_timer_init: failed to map MMIO registers\n");
130
131 writel(1, regbase + TIMER_CTRL_VAL);
132 writel(0xf, regbase + TIMER_STATUS_VAL);
133 writel(~0, regbase + TIMER_MATCH_VAL);
134
135 if (clocksource_register_hz(&clocksource, VT8500_TIMER_HZ))
136 printk(KERN_ERR "vt8500_timer_init: clocksource_register failed for %s\n",
137 clocksource.name);
138
139 clockevents_calc_mult_shift(&clockevent, VT8500_TIMER_HZ, 4);
140
141 /* copy-pasted from mach-msm; no idea */
142 clockevent.max_delta_ns =
143 clockevent_delta2ns(0xf0000000, &clockevent);
144 clockevent.min_delta_ns = clockevent_delta2ns(4, &clockevent);
145 clockevent.cpumask = cpumask_of(0);
146
147 if (setup_irq(wmt_timer_irq, &irq))
148 printk(KERN_ERR "vt8500_timer_init: setup_irq failed for %s\n",
149 clockevent.name);
150 clockevents_register_device(&clockevent);
151}
152
153struct sys_timer vt8500_timer = {
154 .init = vt8500_timer_init
155};
diff --git a/arch/arm/mach-vt8500/wm8505_7in.c b/arch/arm/mach-vt8500/wm8505_7in.c
new file mode 100644
index 000000000000..e73aadbcafd6
--- /dev/null
+++ b/arch/arm/mach-vt8500/wm8505_7in.c
@@ -0,0 +1,77 @@
1/*
2 * arch/arm/mach-vt8500/wm8505_7in.c
3 *
4 * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
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#include <linux/io.h>
22#include <linux/pm.h>
23
24#include <asm/mach-types.h>
25#include <asm/mach/arch.h>
26
27#include "devices.h"
28
29static void __iomem *pmc_hiber;
30
31static struct platform_device *devices[] __initdata = {
32 &vt8500_device_uart0,
33 &vt8500_device_ehci,
34 &vt8500_device_wm8505_fb,
35 &vt8500_device_ge_rops,
36 &vt8500_device_pwm,
37 &vt8500_device_pwmbl,
38 &vt8500_device_rtc,
39};
40
41static void vt8500_power_off(void)
42{
43 local_irq_disable();
44 writew(5, pmc_hiber);
45 asm("mcr%? p15, 0, %0, c7, c0, 4" : : "r" (0));
46}
47
48void __init wm8505_7in_init(void)
49{
50#ifdef CONFIG_FB_WM8505
51 void __iomem *gpio_mux_reg = ioremap(wmt_gpio_base + 0x200, 4);
52 if (gpio_mux_reg) {
53 writel(readl(gpio_mux_reg) | 0x80000000, gpio_mux_reg);
54 iounmap(gpio_mux_reg);
55 } else {
56 printk(KERN_ERR "Could not remap the GPIO mux register, display may not work properly!\n");
57 }
58#endif
59 pmc_hiber = ioremap(wmt_pmc_base + 0x12, 2);
60 if (pmc_hiber)
61 pm_power_off = &vt8500_power_off;
62 else
63 printk(KERN_ERR "PMC Hibernation register could not be remapped, not enabling power off!\n");
64
65 wm8505_set_resources();
66 platform_add_devices(devices, ARRAY_SIZE(devices));
67 vt8500_gpio_init();
68}
69
70MACHINE_START(WM8505_7IN_NETBOOK, "WM8505 7-inch generic netbook")
71 .boot_params = 0x00000100,
72 .reserve = wm8505_reserve_mem,
73 .map_io = wm8505_map_io,
74 .init_irq = wm8505_init_irq,
75 .timer = &vt8500_timer,
76 .init_machine = wm8505_7in_init,
77MACHINE_END
diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S
index bcf748d9f4e2..226e3d8351c2 100644
--- a/arch/arm/mm/proc-arm1020.S
+++ b/arch/arm/mm/proc-arm1020.S
@@ -493,6 +493,9 @@ arm1020_processor_functions:
493 .word cpu_arm1020_dcache_clean_area 493 .word cpu_arm1020_dcache_clean_area
494 .word cpu_arm1020_switch_mm 494 .word cpu_arm1020_switch_mm
495 .word cpu_arm1020_set_pte_ext 495 .word cpu_arm1020_set_pte_ext
496 .word 0
497 .word 0
498 .word 0
496 .size arm1020_processor_functions, . - arm1020_processor_functions 499 .size arm1020_processor_functions, . - arm1020_processor_functions
497 500
498 .section ".rodata" 501 .section ".rodata"
diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S
index ab7ec26657ea..86d9c2cf0bce 100644
--- a/arch/arm/mm/proc-arm1020e.S
+++ b/arch/arm/mm/proc-arm1020e.S
@@ -474,6 +474,9 @@ arm1020e_processor_functions:
474 .word cpu_arm1020e_dcache_clean_area 474 .word cpu_arm1020e_dcache_clean_area
475 .word cpu_arm1020e_switch_mm 475 .word cpu_arm1020e_switch_mm
476 .word cpu_arm1020e_set_pte_ext 476 .word cpu_arm1020e_set_pte_ext
477 .word 0
478 .word 0
479 .word 0
477 .size arm1020e_processor_functions, . - arm1020e_processor_functions 480 .size arm1020e_processor_functions, . - arm1020e_processor_functions
478 481
479 .section ".rodata" 482 .section ".rodata"
diff --git a/arch/arm/mm/proc-arm1022.S b/arch/arm/mm/proc-arm1022.S
index 831c5e54e22f..83d3dd34f846 100644
--- a/arch/arm/mm/proc-arm1022.S
+++ b/arch/arm/mm/proc-arm1022.S
@@ -457,6 +457,9 @@ arm1022_processor_functions:
457 .word cpu_arm1022_dcache_clean_area 457 .word cpu_arm1022_dcache_clean_area
458 .word cpu_arm1022_switch_mm 458 .word cpu_arm1022_switch_mm
459 .word cpu_arm1022_set_pte_ext 459 .word cpu_arm1022_set_pte_ext
460 .word 0
461 .word 0
462 .word 0
460 .size arm1022_processor_functions, . - arm1022_processor_functions 463 .size arm1022_processor_functions, . - arm1022_processor_functions
461 464
462 .section ".rodata" 465 .section ".rodata"
diff --git a/arch/arm/mm/proc-arm1026.S b/arch/arm/mm/proc-arm1026.S
index e3f7e9a166bf..686043ee7281 100644
--- a/arch/arm/mm/proc-arm1026.S
+++ b/arch/arm/mm/proc-arm1026.S
@@ -452,6 +452,9 @@ arm1026_processor_functions:
452 .word cpu_arm1026_dcache_clean_area 452 .word cpu_arm1026_dcache_clean_area
453 .word cpu_arm1026_switch_mm 453 .word cpu_arm1026_switch_mm
454 .word cpu_arm1026_set_pte_ext 454 .word cpu_arm1026_set_pte_ext
455 .word 0
456 .word 0
457 .word 0
455 .size arm1026_processor_functions, . - arm1026_processor_functions 458 .size arm1026_processor_functions, . - arm1026_processor_functions
456 459
457 .section .rodata 460 .section .rodata
diff --git a/arch/arm/mm/proc-arm6_7.S b/arch/arm/mm/proc-arm6_7.S
index 6a7be1863edd..5f79dc4ce3fb 100644
--- a/arch/arm/mm/proc-arm6_7.S
+++ b/arch/arm/mm/proc-arm6_7.S
@@ -284,6 +284,9 @@ ENTRY(arm6_processor_functions)
284 .word cpu_arm6_dcache_clean_area 284 .word cpu_arm6_dcache_clean_area
285 .word cpu_arm6_switch_mm 285 .word cpu_arm6_switch_mm
286 .word cpu_arm6_set_pte_ext 286 .word cpu_arm6_set_pte_ext
287 .word 0
288 .word 0
289 .word 0
287 .size arm6_processor_functions, . - arm6_processor_functions 290 .size arm6_processor_functions, . - arm6_processor_functions
288 291
289/* 292/*
@@ -301,6 +304,9 @@ ENTRY(arm7_processor_functions)
301 .word cpu_arm7_dcache_clean_area 304 .word cpu_arm7_dcache_clean_area
302 .word cpu_arm7_switch_mm 305 .word cpu_arm7_switch_mm
303 .word cpu_arm7_set_pte_ext 306 .word cpu_arm7_set_pte_ext
307 .word 0
308 .word 0
309 .word 0
304 .size arm7_processor_functions, . - arm7_processor_functions 310 .size arm7_processor_functions, . - arm7_processor_functions
305 311
306 .section ".rodata" 312 .section ".rodata"
diff --git a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S
index c285395f44b2..665266da143c 100644
--- a/arch/arm/mm/proc-arm720.S
+++ b/arch/arm/mm/proc-arm720.S
@@ -185,6 +185,9 @@ ENTRY(arm720_processor_functions)
185 .word cpu_arm720_dcache_clean_area 185 .word cpu_arm720_dcache_clean_area
186 .word cpu_arm720_switch_mm 186 .word cpu_arm720_switch_mm
187 .word cpu_arm720_set_pte_ext 187 .word cpu_arm720_set_pte_ext
188 .word 0
189 .word 0
190 .word 0
188 .size arm720_processor_functions, . - arm720_processor_functions 191 .size arm720_processor_functions, . - arm720_processor_functions
189 192
190 .section ".rodata" 193 .section ".rodata"
diff --git a/arch/arm/mm/proc-arm740.S b/arch/arm/mm/proc-arm740.S
index 38b27dcba727..6f9d12effee1 100644
--- a/arch/arm/mm/proc-arm740.S
+++ b/arch/arm/mm/proc-arm740.S
@@ -130,6 +130,9 @@ ENTRY(arm740_processor_functions)
130 .word cpu_arm740_dcache_clean_area 130 .word cpu_arm740_dcache_clean_area
131 .word cpu_arm740_switch_mm 131 .word cpu_arm740_switch_mm
132 .word 0 @ cpu_*_set_pte 132 .word 0 @ cpu_*_set_pte
133 .word 0
134 .word 0
135 .word 0
133 .size arm740_processor_functions, . - arm740_processor_functions 136 .size arm740_processor_functions, . - arm740_processor_functions
134 137
135 .section ".rodata" 138 .section ".rodata"
diff --git a/arch/arm/mm/proc-arm7tdmi.S b/arch/arm/mm/proc-arm7tdmi.S
index 0c9786de20af..e4c165ca6696 100644
--- a/arch/arm/mm/proc-arm7tdmi.S
+++ b/arch/arm/mm/proc-arm7tdmi.S
@@ -70,6 +70,9 @@ ENTRY(arm7tdmi_processor_functions)
70 .word cpu_arm7tdmi_dcache_clean_area 70 .word cpu_arm7tdmi_dcache_clean_area
71 .word cpu_arm7tdmi_switch_mm 71 .word cpu_arm7tdmi_switch_mm
72 .word 0 @ cpu_*_set_pte 72 .word 0 @ cpu_*_set_pte
73 .word 0
74 .word 0
75 .word 0
73 .size arm7tdmi_processor_functions, . - arm7tdmi_processor_functions 76 .size arm7tdmi_processor_functions, . - arm7tdmi_processor_functions
74 77
75 .section ".rodata" 78 .section ".rodata"
diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
index 6109f278a904..219980ec8b6e 100644
--- a/arch/arm/mm/proc-arm920.S
+++ b/arch/arm/mm/proc-arm920.S
@@ -387,6 +387,40 @@ ENTRY(cpu_arm920_set_pte_ext)
387#endif 387#endif
388 mov pc, lr 388 mov pc, lr
389 389
390/* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */
391.globl cpu_arm920_suspend_size
392.equ cpu_arm920_suspend_size, 4 * 3
393#ifdef CONFIG_PM
394ENTRY(cpu_arm920_do_suspend)
395 stmfd sp!, {r4 - r7, lr}
396 mrc p15, 0, r4, c13, c0, 0 @ PID
397 mrc p15, 0, r5, c3, c0, 0 @ Domain ID
398 mrc p15, 0, r6, c2, c0, 0 @ TTB address
399 mrc p15, 0, r7, c1, c0, 0 @ Control register
400 stmia r0, {r4 - r7}
401 ldmfd sp!, {r4 - r7, pc}
402ENDPROC(cpu_arm920_do_suspend)
403
404ENTRY(cpu_arm920_do_resume)
405 mov ip, #0
406 mcr p15, 0, ip, c8, c7, 0 @ invalidate I+D TLBs
407 mcr p15, 0, ip, c7, c7, 0 @ invalidate I+D caches
408 ldmia r0, {r4 - r7}
409 mcr p15, 0, r4, c13, c0, 0 @ PID
410 mcr p15, 0, r5, c3, c0, 0 @ Domain ID
411 mcr p15, 0, r6, c2, c0, 0 @ TTB address
412 mov r0, r7 @ control register
413 mov r2, r6, lsr #14 @ get TTB0 base
414 mov r2, r2, lsl #14
415 ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
416 PMD_SECT_CACHEABLE | PMD_BIT4 | PMD_SECT_AP_WRITE
417 b cpu_resume_mmu
418ENDPROC(cpu_arm920_do_resume)
419#else
420#define cpu_arm920_do_suspend 0
421#define cpu_arm920_do_resume 0
422#endif
423
390 __CPUINIT 424 __CPUINIT
391 425
392 .type __arm920_setup, #function 426 .type __arm920_setup, #function
@@ -432,6 +466,9 @@ arm920_processor_functions:
432 .word cpu_arm920_dcache_clean_area 466 .word cpu_arm920_dcache_clean_area
433 .word cpu_arm920_switch_mm 467 .word cpu_arm920_switch_mm
434 .word cpu_arm920_set_pte_ext 468 .word cpu_arm920_set_pte_ext
469 .word cpu_arm920_suspend_size
470 .word cpu_arm920_do_suspend
471 .word cpu_arm920_do_resume
435 .size arm920_processor_functions, . - arm920_processor_functions 472 .size arm920_processor_functions, . - arm920_processor_functions
436 473
437 .section ".rodata" 474 .section ".rodata"
diff --git a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S
index bb2f0f46a5e6..36154b1e792a 100644
--- a/arch/arm/mm/proc-arm922.S
+++ b/arch/arm/mm/proc-arm922.S
@@ -436,6 +436,9 @@ arm922_processor_functions:
436 .word cpu_arm922_dcache_clean_area 436 .word cpu_arm922_dcache_clean_area
437 .word cpu_arm922_switch_mm 437 .word cpu_arm922_switch_mm
438 .word cpu_arm922_set_pte_ext 438 .word cpu_arm922_set_pte_ext
439 .word 0
440 .word 0
441 .word 0
439 .size arm922_processor_functions, . - arm922_processor_functions 442 .size arm922_processor_functions, . - arm922_processor_functions
440 443
441 .section ".rodata" 444 .section ".rodata"
diff --git a/arch/arm/mm/proc-arm925.S b/arch/arm/mm/proc-arm925.S
index c13e01accfe2..89c5e0009c4c 100644
--- a/arch/arm/mm/proc-arm925.S
+++ b/arch/arm/mm/proc-arm925.S
@@ -503,6 +503,9 @@ arm925_processor_functions:
503 .word cpu_arm925_dcache_clean_area 503 .word cpu_arm925_dcache_clean_area
504 .word cpu_arm925_switch_mm 504 .word cpu_arm925_switch_mm
505 .word cpu_arm925_set_pte_ext 505 .word cpu_arm925_set_pte_ext
506 .word 0
507 .word 0
508 .word 0
506 .size arm925_processor_functions, . - arm925_processor_functions 509 .size arm925_processor_functions, . - arm925_processor_functions
507 510
508 .section ".rodata" 511 .section ".rodata"
diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S
index 42eb4315740b..6a4bdb2c94a7 100644
--- a/arch/arm/mm/proc-arm926.S
+++ b/arch/arm/mm/proc-arm926.S
@@ -401,6 +401,40 @@ ENTRY(cpu_arm926_set_pte_ext)
401#endif 401#endif
402 mov pc, lr 402 mov pc, lr
403 403
404/* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */
405.globl cpu_arm926_suspend_size
406.equ cpu_arm926_suspend_size, 4 * 3
407#ifdef CONFIG_PM
408ENTRY(cpu_arm926_do_suspend)
409 stmfd sp!, {r4 - r7, lr}
410 mrc p15, 0, r4, c13, c0, 0 @ PID
411 mrc p15, 0, r5, c3, c0, 0 @ Domain ID
412 mrc p15, 0, r6, c2, c0, 0 @ TTB address
413 mrc p15, 0, r7, c1, c0, 0 @ Control register
414 stmia r0, {r4 - r7}
415 ldmfd sp!, {r4 - r7, pc}
416ENDPROC(cpu_arm926_do_suspend)
417
418ENTRY(cpu_arm926_do_resume)
419 mov ip, #0
420 mcr p15, 0, ip, c8, c7, 0 @ invalidate I+D TLBs
421 mcr p15, 0, ip, c7, c7, 0 @ invalidate I+D caches
422 ldmia r0, {r4 - r7}
423 mcr p15, 0, r4, c13, c0, 0 @ PID
424 mcr p15, 0, r5, c3, c0, 0 @ Domain ID
425 mcr p15, 0, r6, c2, c0, 0 @ TTB address
426 mov r0, r7 @ control register
427 mov r2, r6, lsr #14 @ get TTB0 base
428 mov r2, r2, lsl #14
429 ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
430 PMD_SECT_CACHEABLE | PMD_BIT4 | PMD_SECT_AP_WRITE
431 b cpu_resume_mmu
432ENDPROC(cpu_arm926_do_resume)
433#else
434#define cpu_arm926_do_suspend 0
435#define cpu_arm926_do_resume 0
436#endif
437
404 __CPUINIT 438 __CPUINIT
405 439
406 .type __arm926_setup, #function 440 .type __arm926_setup, #function
@@ -456,6 +490,9 @@ arm926_processor_functions:
456 .word cpu_arm926_dcache_clean_area 490 .word cpu_arm926_dcache_clean_area
457 .word cpu_arm926_switch_mm 491 .word cpu_arm926_switch_mm
458 .word cpu_arm926_set_pte_ext 492 .word cpu_arm926_set_pte_ext
493 .word cpu_arm926_suspend_size
494 .word cpu_arm926_do_suspend
495 .word cpu_arm926_do_resume
459 .size arm926_processor_functions, . - arm926_processor_functions 496 .size arm926_processor_functions, . - arm926_processor_functions
460 497
461 .section ".rodata" 498 .section ".rodata"
diff --git a/arch/arm/mm/proc-arm940.S b/arch/arm/mm/proc-arm940.S
index 7b11cdb9935f..26aea3f71c26 100644
--- a/arch/arm/mm/proc-arm940.S
+++ b/arch/arm/mm/proc-arm940.S
@@ -363,6 +363,9 @@ ENTRY(arm940_processor_functions)
363 .word cpu_arm940_dcache_clean_area 363 .word cpu_arm940_dcache_clean_area
364 .word cpu_arm940_switch_mm 364 .word cpu_arm940_switch_mm
365 .word 0 @ cpu_*_set_pte 365 .word 0 @ cpu_*_set_pte
366 .word 0
367 .word 0
368 .word 0
366 .size arm940_processor_functions, . - arm940_processor_functions 369 .size arm940_processor_functions, . - arm940_processor_functions
367 370
368 .section ".rodata" 371 .section ".rodata"
diff --git a/arch/arm/mm/proc-arm946.S b/arch/arm/mm/proc-arm946.S
index 1a5bbf080342..8063345406fe 100644
--- a/arch/arm/mm/proc-arm946.S
+++ b/arch/arm/mm/proc-arm946.S
@@ -419,6 +419,9 @@ ENTRY(arm946_processor_functions)
419 .word cpu_arm946_dcache_clean_area 419 .word cpu_arm946_dcache_clean_area
420 .word cpu_arm946_switch_mm 420 .word cpu_arm946_switch_mm
421 .word 0 @ cpu_*_set_pte 421 .word 0 @ cpu_*_set_pte
422 .word 0
423 .word 0
424 .word 0
422 .size arm946_processor_functions, . - arm946_processor_functions 425 .size arm946_processor_functions, . - arm946_processor_functions
423 426
424 .section ".rodata" 427 .section ".rodata"
diff --git a/arch/arm/mm/proc-arm9tdmi.S b/arch/arm/mm/proc-arm9tdmi.S
index db67e3134d7a..7b7ebd4d096d 100644
--- a/arch/arm/mm/proc-arm9tdmi.S
+++ b/arch/arm/mm/proc-arm9tdmi.S
@@ -70,6 +70,9 @@ ENTRY(arm9tdmi_processor_functions)
70 .word cpu_arm9tdmi_dcache_clean_area 70 .word cpu_arm9tdmi_dcache_clean_area
71 .word cpu_arm9tdmi_switch_mm 71 .word cpu_arm9tdmi_switch_mm
72 .word 0 @ cpu_*_set_pte 72 .word 0 @ cpu_*_set_pte
73 .word 0
74 .word 0
75 .word 0
73 .size arm9tdmi_processor_functions, . - arm9tdmi_processor_functions 76 .size arm9tdmi_processor_functions, . - arm9tdmi_processor_functions
74 77
75 .section ".rodata" 78 .section ".rodata"
diff --git a/arch/arm/mm/proc-fa526.S b/arch/arm/mm/proc-fa526.S
index 7c9ad621f0e6..fc2a4ae15cf4 100644
--- a/arch/arm/mm/proc-fa526.S
+++ b/arch/arm/mm/proc-fa526.S
@@ -195,6 +195,9 @@ fa526_processor_functions:
195 .word cpu_fa526_dcache_clean_area 195 .word cpu_fa526_dcache_clean_area
196 .word cpu_fa526_switch_mm 196 .word cpu_fa526_switch_mm
197 .word cpu_fa526_set_pte_ext 197 .word cpu_fa526_set_pte_ext
198 .word 0
199 .word 0
200 .word 0
198 .size fa526_processor_functions, . - fa526_processor_functions 201 .size fa526_processor_functions, . - fa526_processor_functions
199 202
200 .section ".rodata" 203 .section ".rodata"
diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S
index b4597edbff97..d3883eed7a4a 100644
--- a/arch/arm/mm/proc-feroceon.S
+++ b/arch/arm/mm/proc-feroceon.S
@@ -554,6 +554,9 @@ feroceon_processor_functions:
554 .word cpu_feroceon_dcache_clean_area 554 .word cpu_feroceon_dcache_clean_area
555 .word cpu_feroceon_switch_mm 555 .word cpu_feroceon_switch_mm
556 .word cpu_feroceon_set_pte_ext 556 .word cpu_feroceon_set_pte_ext
557 .word 0
558 .word 0
559 .word 0
557 .size feroceon_processor_functions, . - feroceon_processor_functions 560 .size feroceon_processor_functions, . - feroceon_processor_functions
558 561
559 .section ".rodata" 562 .section ".rodata"
diff --git a/arch/arm/mm/proc-mohawk.S b/arch/arm/mm/proc-mohawk.S
index 4458ee6aa713..9d4f2ae63370 100644
--- a/arch/arm/mm/proc-mohawk.S
+++ b/arch/arm/mm/proc-mohawk.S
@@ -388,6 +388,9 @@ mohawk_processor_functions:
388 .word cpu_mohawk_dcache_clean_area 388 .word cpu_mohawk_dcache_clean_area
389 .word cpu_mohawk_switch_mm 389 .word cpu_mohawk_switch_mm
390 .word cpu_mohawk_set_pte_ext 390 .word cpu_mohawk_set_pte_ext
391 .word 0
392 .word 0
393 .word 0
391 .size mohawk_processor_functions, . - mohawk_processor_functions 394 .size mohawk_processor_functions, . - mohawk_processor_functions
392 395
393 .section ".rodata" 396 .section ".rodata"
diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S
index 5aa8d59c2e85..46f09ed16b98 100644
--- a/arch/arm/mm/proc-sa110.S
+++ b/arch/arm/mm/proc-sa110.S
@@ -203,6 +203,9 @@ ENTRY(sa110_processor_functions)
203 .word cpu_sa110_dcache_clean_area 203 .word cpu_sa110_dcache_clean_area
204 .word cpu_sa110_switch_mm 204 .word cpu_sa110_switch_mm
205 .word cpu_sa110_set_pte_ext 205 .word cpu_sa110_set_pte_ext
206 .word 0
207 .word 0
208 .word 0
206 .size sa110_processor_functions, . - sa110_processor_functions 209 .size sa110_processor_functions, . - sa110_processor_functions
207 210
208 .section ".rodata" 211 .section ".rodata"
diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S
index 2ac4e6f10713..74483d1977fe 100644
--- a/arch/arm/mm/proc-sa1100.S
+++ b/arch/arm/mm/proc-sa1100.S
@@ -169,6 +169,42 @@ ENTRY(cpu_sa1100_set_pte_ext)
169#endif 169#endif
170 mov pc, lr 170 mov pc, lr
171 171
172.globl cpu_sa1100_suspend_size
173.equ cpu_sa1100_suspend_size, 4*4
174#ifdef CONFIG_PM
175ENTRY(cpu_sa1100_do_suspend)
176 stmfd sp!, {r4 - r7, lr}
177 mrc p15, 0, r4, c3, c0, 0 @ domain ID
178 mrc p15, 0, r5, c2, c0, 0 @ translation table base addr
179 mrc p15, 0, r6, c13, c0, 0 @ PID
180 mrc p15, 0, r7, c1, c0, 0 @ control reg
181 stmia r0, {r4 - r7} @ store cp regs
182 ldmfd sp!, {r4 - r7, pc}
183ENDPROC(cpu_sa1100_do_suspend)
184
185ENTRY(cpu_sa1100_do_resume)
186 ldmia r0, {r4 - r7} @ load cp regs
187 mov r1, #0
188 mcr p15, 0, r1, c8, c7, 0 @ flush I+D TLBs
189 mcr p15, 0, r1, c7, c7, 0 @ flush I&D cache
190 mcr p15, 0, r1, c9, c0, 0 @ invalidate RB
191 mcr p15, 0, r1, c9, c0, 5 @ allow user space to use RB
192
193 mcr p15, 0, r4, c3, c0, 0 @ domain ID
194 mcr p15, 0, r5, c2, c0, 0 @ translation table base addr
195 mcr p15, 0, r6, c13, c0, 0 @ PID
196 mov r0, r7 @ control register
197 mov r2, r5, lsr #14 @ get TTB0 base
198 mov r2, r2, lsl #14
199 ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
200 PMD_SECT_CACHEABLE | PMD_SECT_AP_WRITE
201 b cpu_resume_mmu
202ENDPROC(cpu_sa1100_do_resume)
203#else
204#define cpu_sa1100_do_suspend 0
205#define cpu_sa1100_do_resume 0
206#endif
207
172 __CPUINIT 208 __CPUINIT
173 209
174 .type __sa1100_setup, #function 210 .type __sa1100_setup, #function
@@ -218,6 +254,9 @@ ENTRY(sa1100_processor_functions)
218 .word cpu_sa1100_dcache_clean_area 254 .word cpu_sa1100_dcache_clean_area
219 .word cpu_sa1100_switch_mm 255 .word cpu_sa1100_switch_mm
220 .word cpu_sa1100_set_pte_ext 256 .word cpu_sa1100_set_pte_ext
257 .word cpu_sa1100_suspend_size
258 .word cpu_sa1100_do_suspend
259 .word cpu_sa1100_do_resume
221 .size sa1100_processor_functions, . - sa1100_processor_functions 260 .size sa1100_processor_functions, . - sa1100_processor_functions
222 261
223 .section ".rodata" 262 .section ".rodata"
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 59a7e1ffe7bc..832b6bdc192c 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -121,6 +121,53 @@ ENTRY(cpu_v6_set_pte_ext)
121#endif 121#endif
122 mov pc, lr 122 mov pc, lr
123 123
124/* Suspend/resume support: taken from arch/arm/mach-s3c64xx/sleep.S */
125.globl cpu_v6_suspend_size
126.equ cpu_v6_suspend_size, 4 * 8
127#ifdef CONFIG_PM
128ENTRY(cpu_v6_do_suspend)
129 stmfd sp!, {r4 - r11, lr}
130 mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID
131 mrc p15, 0, r5, c13, c0, 1 @ Context ID
132 mrc p15, 0, r6, c3, c0, 0 @ Domain ID
133 mrc p15, 0, r7, c2, c0, 0 @ Translation table base 0
134 mrc p15, 0, r8, c2, c0, 1 @ Translation table base 1
135 mrc p15, 0, r9, c1, c0, 1 @ auxillary control register
136 mrc p15, 0, r10, c1, c0, 2 @ co-processor access control
137 mrc p15, 0, r11, c1, c0, 0 @ control register
138 stmia r0, {r4 - r11}
139 ldmfd sp!, {r4- r11, pc}
140ENDPROC(cpu_v6_do_suspend)
141
142ENTRY(cpu_v6_do_resume)
143 mov ip, #0
144 mcr p15, 0, ip, c7, c14, 0 @ clean+invalidate D cache
145 mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
146 mcr p15, 0, ip, c7, c15, 0 @ clean+invalidate cache
147 mcr p15, 0, ip, c7, c10, 4 @ drain write buffer
148 ldmia r0, {r4 - r11}
149 mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID
150 mcr p15, 0, r5, c13, c0, 1 @ Context ID
151 mcr p15, 0, r6, c3, c0, 0 @ Domain ID
152 mcr p15, 0, r7, c2, c0, 0 @ Translation table base 0
153 mcr p15, 0, r8, c2, c0, 1 @ Translation table base 1
154 mcr p15, 0, r9, c1, c0, 1 @ auxillary control register
155 mcr p15, 0, r10, c1, c0, 2 @ co-processor access control
156 mcr p15, 0, ip, c2, c0, 2 @ TTB control register
157 mcr p15, 0, ip, c7, c5, 4 @ ISB
158 mov r0, r11 @ control register
159 mov r2, r7, lsr #14 @ get TTB0 base
160 mov r2, r2, lsl #14
161 ldr r3, cpu_resume_l1_flags
162 b cpu_resume_mmu
163ENDPROC(cpu_v6_do_resume)
164cpu_resume_l1_flags:
165 ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_SMP)
166 ALT_UP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_UP)
167#else
168#define cpu_v6_do_suspend 0
169#define cpu_v6_do_resume 0
170#endif
124 171
125 172
126 .type cpu_v6_name, #object 173 .type cpu_v6_name, #object
@@ -206,6 +253,9 @@ ENTRY(v6_processor_functions)
206 .word cpu_v6_dcache_clean_area 253 .word cpu_v6_dcache_clean_area
207 .word cpu_v6_switch_mm 254 .word cpu_v6_switch_mm
208 .word cpu_v6_set_pte_ext 255 .word cpu_v6_set_pte_ext
256 .word cpu_v6_suspend_size
257 .word cpu_v6_do_suspend
258 .word cpu_v6_do_resume
209 .size v6_processor_functions, . - v6_processor_functions 259 .size v6_processor_functions, . - v6_processor_functions
210 260
211 .section ".rodata" 261 .section ".rodata"
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 8e3356239136..262fa88a7439 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -108,10 +108,16 @@ ENTRY(cpu_v7_switch_mm)
108#ifdef CONFIG_ARM_ERRATA_430973 108#ifdef CONFIG_ARM_ERRATA_430973
109 mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB 109 mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB
110#endif 110#endif
111#ifdef CONFIG_ARM_ERRATA_754322
112 dsb
113#endif
111 mcr p15, 0, r2, c13, c0, 1 @ set reserved context ID 114 mcr p15, 0, r2, c13, c0, 1 @ set reserved context ID
112 isb 115 isb
1131: mcr p15, 0, r0, c2, c0, 0 @ set TTB 0 1161: mcr p15, 0, r0, c2, c0, 0 @ set TTB 0
114 isb 117 isb
118#ifdef CONFIG_ARM_ERRATA_754322
119 dsb
120#endif
115 mcr p15, 0, r1, c13, c0, 1 @ set context ID 121 mcr p15, 0, r1, c13, c0, 1 @ set context ID
116 isb 122 isb
117#endif 123#endif
@@ -171,6 +177,87 @@ cpu_v7_name:
171 .ascii "ARMv7 Processor" 177 .ascii "ARMv7 Processor"
172 .align 178 .align
173 179
180 /*
181 * Memory region attributes with SCTLR.TRE=1
182 *
183 * n = TEX[0],C,B
184 * TR = PRRR[2n+1:2n] - memory type
185 * IR = NMRR[2n+1:2n] - inner cacheable property
186 * OR = NMRR[2n+17:2n+16] - outer cacheable property
187 *
188 * n TR IR OR
189 * UNCACHED 000 00
190 * BUFFERABLE 001 10 00 00
191 * WRITETHROUGH 010 10 10 10
192 * WRITEBACK 011 10 11 11
193 * reserved 110
194 * WRITEALLOC 111 10 01 01
195 * DEV_SHARED 100 01
196 * DEV_NONSHARED 100 01
197 * DEV_WC 001 10
198 * DEV_CACHED 011 10
199 *
200 * Other attributes:
201 *
202 * DS0 = PRRR[16] = 0 - device shareable property
203 * DS1 = PRRR[17] = 1 - device shareable property
204 * NS0 = PRRR[18] = 0 - normal shareable property
205 * NS1 = PRRR[19] = 1 - normal shareable property
206 * NOS = PRRR[24+n] = 1 - not outer shareable
207 */
208.equ PRRR, 0xff0a81a8
209.equ NMRR, 0x40e040e0
210
211/* Suspend/resume support: derived from arch/arm/mach-s5pv210/sleep.S */
212.globl cpu_v7_suspend_size
213.equ cpu_v7_suspend_size, 4 * 8
214#ifdef CONFIG_PM
215ENTRY(cpu_v7_do_suspend)
216 stmfd sp!, {r4 - r11, lr}
217 mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID
218 mrc p15, 0, r5, c13, c0, 1 @ Context ID
219 mrc p15, 0, r6, c3, c0, 0 @ Domain ID
220 mrc p15, 0, r7, c2, c0, 0 @ TTB 0
221 mrc p15, 0, r8, c2, c0, 1 @ TTB 1
222 mrc p15, 0, r9, c1, c0, 0 @ Control register
223 mrc p15, 0, r10, c1, c0, 1 @ Auxiliary control register
224 mrc p15, 0, r11, c1, c0, 2 @ Co-processor access control
225 stmia r0, {r4 - r11}
226 ldmfd sp!, {r4 - r11, pc}
227ENDPROC(cpu_v7_do_suspend)
228
229ENTRY(cpu_v7_do_resume)
230 mov ip, #0
231 mcr p15, 0, ip, c8, c7, 0 @ invalidate TLBs
232 mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
233 ldmia r0, {r4 - r11}
234 mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID
235 mcr p15, 0, r5, c13, c0, 1 @ Context ID
236 mcr p15, 0, r6, c3, c0, 0 @ Domain ID
237 mcr p15, 0, r7, c2, c0, 0 @ TTB 0
238 mcr p15, 0, r8, c2, c0, 1 @ TTB 1
239 mcr p15, 0, ip, c2, c0, 2 @ TTB control register
240 mcr p15, 0, r10, c1, c0, 1 @ Auxillary control register
241 mcr p15, 0, r11, c1, c0, 2 @ Co-processor access control
242 ldr r4, =PRRR @ PRRR
243 ldr r5, =NMRR @ NMRR
244 mcr p15, 0, r4, c10, c2, 0 @ write PRRR
245 mcr p15, 0, r5, c10, c2, 1 @ write NMRR
246 isb
247 mov r0, r9 @ control register
248 mov r2, r7, lsr #14 @ get TTB0 base
249 mov r2, r2, lsl #14
250 ldr r3, cpu_resume_l1_flags
251 b cpu_resume_mmu
252ENDPROC(cpu_v7_do_resume)
253cpu_resume_l1_flags:
254 ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_SMP)
255 ALT_UP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_UP)
256#else
257#define cpu_v7_do_suspend 0
258#define cpu_v7_do_resume 0
259#endif
260
174 __CPUINIT 261 __CPUINIT
175 262
176/* 263/*
@@ -282,36 +369,8 @@ __v7_setup:
282 ALT_SMP(orr r4, r4, #TTB_FLAGS_SMP) 369 ALT_SMP(orr r4, r4, #TTB_FLAGS_SMP)
283 ALT_UP(orr r4, r4, #TTB_FLAGS_UP) 370 ALT_UP(orr r4, r4, #TTB_FLAGS_UP)
284 mcr p15, 0, r4, c2, c0, 1 @ load TTB1 371 mcr p15, 0, r4, c2, c0, 1 @ load TTB1
285 /* 372 ldr r5, =PRRR @ PRRR
286 * Memory region attributes with SCTLR.TRE=1 373 ldr r6, =NMRR @ NMRR
287 *
288 * n = TEX[0],C,B
289 * TR = PRRR[2n+1:2n] - memory type
290 * IR = NMRR[2n+1:2n] - inner cacheable property
291 * OR = NMRR[2n+17:2n+16] - outer cacheable property
292 *
293 * n TR IR OR
294 * UNCACHED 000 00
295 * BUFFERABLE 001 10 00 00
296 * WRITETHROUGH 010 10 10 10
297 * WRITEBACK 011 10 11 11
298 * reserved 110
299 * WRITEALLOC 111 10 01 01
300 * DEV_SHARED 100 01
301 * DEV_NONSHARED 100 01
302 * DEV_WC 001 10
303 * DEV_CACHED 011 10
304 *
305 * Other attributes:
306 *
307 * DS0 = PRRR[16] = 0 - device shareable property
308 * DS1 = PRRR[17] = 1 - device shareable property
309 * NS0 = PRRR[18] = 0 - normal shareable property
310 * NS1 = PRRR[19] = 1 - normal shareable property
311 * NOS = PRRR[24+n] = 1 - not outer shareable
312 */
313 ldr r5, =0xff0a81a8 @ PRRR
314 ldr r6, =0x40e040e0 @ NMRR
315 mcr p15, 0, r5, c10, c2, 0 @ write PRRR 374 mcr p15, 0, r5, c10, c2, 0 @ write PRRR
316 mcr p15, 0, r6, c10, c2, 1 @ write NMRR 375 mcr p15, 0, r6, c10, c2, 1 @ write NMRR
317#endif 376#endif
@@ -357,6 +416,9 @@ ENTRY(v7_processor_functions)
357 .word cpu_v7_dcache_clean_area 416 .word cpu_v7_dcache_clean_area
358 .word cpu_v7_switch_mm 417 .word cpu_v7_switch_mm
359 .word cpu_v7_set_pte_ext 418 .word cpu_v7_set_pte_ext
419 .word 0
420 .word 0
421 .word 0
360 .size v7_processor_functions, . - v7_processor_functions 422 .size v7_processor_functions, . - v7_processor_functions
361 423
362 .section ".rodata" 424 .section ".rodata"
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
index ec26355cb7c2..63d8b2044e84 100644
--- a/arch/arm/mm/proc-xsc3.S
+++ b/arch/arm/mm/proc-xsc3.S
@@ -413,9 +413,52 @@ ENTRY(cpu_xsc3_set_pte_ext)
413 mov pc, lr 413 mov pc, lr
414 414
415 .ltorg 415 .ltorg
416
417 .align 416 .align
418 417
418.globl cpu_xsc3_suspend_size
419.equ cpu_xsc3_suspend_size, 4 * 8
420#ifdef CONFIG_PM
421ENTRY(cpu_xsc3_do_suspend)
422 stmfd sp!, {r4 - r10, lr}
423 mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode
424 mrc p15, 0, r5, c15, c1, 0 @ CP access reg
425 mrc p15, 0, r6, c13, c0, 0 @ PID
426 mrc p15, 0, r7, c3, c0, 0 @ domain ID
427 mrc p15, 0, r8, c2, c0, 0 @ translation table base addr
428 mrc p15, 0, r9, c1, c0, 1 @ auxiliary control reg
429 mrc p15, 0, r10, c1, c0, 0 @ control reg
430 bic r4, r4, #2 @ clear frequency change bit
431 stmia r0, {r1, r4 - r10} @ store v:p offset + cp regs
432 ldmia sp!, {r4 - r10, pc}
433ENDPROC(cpu_xsc3_do_suspend)
434
435ENTRY(cpu_xsc3_do_resume)
436 ldmia r0, {r1, r4 - r10} @ load v:p offset + cp regs
437 mov ip, #0
438 mcr p15, 0, ip, c7, c7, 0 @ invalidate I & D caches, BTB
439 mcr p15, 0, ip, c7, c10, 4 @ drain write (&fill) buffer
440 mcr p15, 0, ip, c7, c5, 4 @ flush prefetch buffer
441 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
442 mcr p14, 0, r4, c6, c0, 0 @ clock configuration, turbo mode.
443 mcr p15, 0, r5, c15, c1, 0 @ CP access reg
444 mcr p15, 0, r6, c13, c0, 0 @ PID
445 mcr p15, 0, r7, c3, c0, 0 @ domain ID
446 mcr p15, 0, r8, c2, c0, 0 @ translation table base addr
447 mcr p15, 0, r9, c1, c0, 1 @ auxiliary control reg
448
449 @ temporarily map resume_turn_on_mmu into the page table,
450 @ otherwise prefetch abort occurs after MMU is turned on
451 mov r0, r10 @ control register
452 mov r2, r8, lsr #14 @ get TTB0 base
453 mov r2, r2, lsl #14
454 ldr r3, =0x542e @ section flags
455 b cpu_resume_mmu
456ENDPROC(cpu_xsc3_do_resume)
457#else
458#define cpu_xsc3_do_suspend 0
459#define cpu_xsc3_do_resume 0
460#endif
461
419 __CPUINIT 462 __CPUINIT
420 463
421 .type __xsc3_setup, #function 464 .type __xsc3_setup, #function
@@ -476,6 +519,9 @@ ENTRY(xsc3_processor_functions)
476 .word cpu_xsc3_dcache_clean_area 519 .word cpu_xsc3_dcache_clean_area
477 .word cpu_xsc3_switch_mm 520 .word cpu_xsc3_switch_mm
478 .word cpu_xsc3_set_pte_ext 521 .word cpu_xsc3_set_pte_ext
522 .word cpu_xsc3_suspend_size
523 .word cpu_xsc3_do_suspend
524 .word cpu_xsc3_do_resume
479 .size xsc3_processor_functions, . - xsc3_processor_functions 525 .size xsc3_processor_functions, . - xsc3_processor_functions
480 526
481 .section ".rodata" 527 .section ".rodata"
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
index 5a37c5e45c41..086038cd86ab 100644
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -513,11 +513,49 @@ ENTRY(cpu_xscale_set_pte_ext)
513 xscale_set_pte_ext_epilogue 513 xscale_set_pte_ext_epilogue
514 mov pc, lr 514 mov pc, lr
515 515
516
517 .ltorg 516 .ltorg
518
519 .align 517 .align
520 518
519.globl cpu_xscale_suspend_size
520.equ cpu_xscale_suspend_size, 4 * 7
521#ifdef CONFIG_PM
522ENTRY(cpu_xscale_do_suspend)
523 stmfd sp!, {r4 - r10, lr}
524 mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode
525 mrc p15, 0, r5, c15, c1, 0 @ CP access reg
526 mrc p15, 0, r6, c13, c0, 0 @ PID
527 mrc p15, 0, r7, c3, c0, 0 @ domain ID
528 mrc p15, 0, r8, c2, c0, 0 @ translation table base addr
529 mrc p15, 0, r9, c1, c1, 0 @ auxiliary control reg
530 mrc p15, 0, r10, c1, c0, 0 @ control reg
531 bic r4, r4, #2 @ clear frequency change bit
532 stmia r0, {r4 - r10} @ store cp regs
533 ldmfd sp!, {r4 - r10, pc}
534ENDPROC(cpu_xscale_do_suspend)
535
536ENTRY(cpu_xscale_do_resume)
537 ldmia r0, {r4 - r10} @ load cp regs
538 mov ip, #0
539 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
540 mcr p15, 0, ip, c7, c7, 0 @ invalidate I & D caches, BTB
541 mcr p14, 0, r4, c6, c0, 0 @ clock configuration, turbo mode.
542 mcr p15, 0, r5, c15, c1, 0 @ CP access reg
543 mcr p15, 0, r6, c13, c0, 0 @ PID
544 mcr p15, 0, r7, c3, c0, 0 @ domain ID
545 mcr p15, 0, r8, c2, c0, 0 @ translation table base addr
546 mcr p15, 0, r9, c1, c1, 0 @ auxiliary control reg
547 mov r0, r10 @ control register
548 mov r2, r8, lsr #14 @ get TTB0 base
549 mov r2, r2, lsl #14
550 ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
551 PMD_SECT_CACHEABLE | PMD_SECT_AP_WRITE
552 b cpu_resume_mmu
553ENDPROC(cpu_xscale_do_resume)
554#else
555#define cpu_xscale_do_suspend 0
556#define cpu_xscale_do_resume 0
557#endif
558
521 __CPUINIT 559 __CPUINIT
522 560
523 .type __xscale_setup, #function 561 .type __xscale_setup, #function
@@ -565,6 +603,9 @@ ENTRY(xscale_processor_functions)
565 .word cpu_xscale_dcache_clean_area 603 .word cpu_xscale_dcache_clean_area
566 .word cpu_xscale_switch_mm 604 .word cpu_xscale_switch_mm
567 .word cpu_xscale_set_pte_ext 605 .word cpu_xscale_set_pte_ext
606 .word cpu_xscale_suspend_size
607 .word cpu_xscale_do_suspend
608 .word cpu_xscale_do_resume
568 .size xscale_processor_functions, . - xscale_processor_functions 609 .size xscale_processor_functions, . - xscale_processor_functions
569 610
570 .section ".rodata" 611 .section ".rodata"
diff --git a/arch/arm/plat-omap/include/plat/sram.h b/arch/arm/plat-omap/include/plat/sram.h
index 9967d5e855c7..f500fc34d065 100644
--- a/arch/arm/plat-omap/include/plat/sram.h
+++ b/arch/arm/plat-omap/include/plat/sram.h
@@ -12,7 +12,19 @@
12#define __ARCH_ARM_OMAP_SRAM_H 12#define __ARCH_ARM_OMAP_SRAM_H
13 13
14#ifndef __ASSEMBLY__ 14#ifndef __ASSEMBLY__
15extern void * omap_sram_push(void * start, unsigned long size); 15#include <asm/fncpy.h>
16
17extern void *omap_sram_push_address(unsigned long size);
18
19/* Macro to push a function to the internal SRAM, using the fncpy API */
20#define omap_sram_push(funcp, size) ({ \
21 typeof(&(funcp)) _res = NULL; \
22 void *_sram_address = omap_sram_push_address(size); \
23 if (_sram_address) \
24 _res = fncpy(_sram_address, &(funcp), size); \
25 _res; \
26})
27
16extern void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl); 28extern void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl);
17 29
18extern void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl, 30extern void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
index e26e50487d60..68fcc7dc56e7 100644
--- a/arch/arm/plat-omap/sram.c
+++ b/arch/arm/plat-omap/sram.c
@@ -242,7 +242,14 @@ static void __init omap_map_sram(void)
242 omap_sram_size - SRAM_BOOTLOADER_SZ); 242 omap_sram_size - SRAM_BOOTLOADER_SZ);
243} 243}
244 244
245void * omap_sram_push(void * start, unsigned long size) 245/*
246 * Memory allocator for SRAM: calculates the new ceiling address
247 * for pushing a function using the fncpy API.
248 *
249 * Note that fncpy requires the returned address to be aligned
250 * to an 8-byte boundary.
251 */
252void *omap_sram_push_address(unsigned long size)
246{ 253{
247 if (size > (omap_sram_ceil - (omap_sram_base + SRAM_BOOTLOADER_SZ))) { 254 if (size > (omap_sram_ceil - (omap_sram_base + SRAM_BOOTLOADER_SZ))) {
248 printk(KERN_ERR "Not enough space in SRAM\n"); 255 printk(KERN_ERR "Not enough space in SRAM\n");
@@ -250,10 +257,7 @@ void * omap_sram_push(void * start, unsigned long size)
250 } 257 }
251 258
252 omap_sram_ceil -= size; 259 omap_sram_ceil -= size;
253 omap_sram_ceil = ROUND_DOWN(omap_sram_ceil, sizeof(void *)); 260 omap_sram_ceil = ROUND_DOWN(omap_sram_ceil, FNCPY_ALIGN);
254 memcpy((void *)omap_sram_ceil, start, size);
255 flush_icache_range((unsigned long)omap_sram_ceil,
256 (unsigned long)(omap_sram_ceil + size));
257 261
258 return (void *)omap_sram_ceil; 262 return (void *)omap_sram_ceil;
259} 263}
diff --git a/arch/arm/plat-s3c24xx/sleep.S b/arch/arm/plat-s3c24xx/sleep.S
index e73e3b6e88d2..fd7032f84ae7 100644
--- a/arch/arm/plat-s3c24xx/sleep.S
+++ b/arch/arm/plat-s3c24xx/sleep.S
@@ -44,23 +44,13 @@
44 /* s3c_cpu_save 44 /* s3c_cpu_save
45 * 45 *
46 * entry: 46 * entry:
47 * r0 = save address (virtual addr of s3c_sleep_save_phys) 47 * r1 = v:p offset
48 */ 48 */
49 49
50ENTRY(s3c_cpu_save) 50ENTRY(s3c_cpu_save)
51 stmfd sp!, { r4 - r12, lr } 51 stmfd sp!, { r4 - r12, lr }
52 52 ldr r3, =resume_with_mmu
53 @@ store co-processor registers 53 bl cpu_suspend
54
55 mrc p15, 0, r4, c13, c0, 0 @ PID
56 mrc p15, 0, r5, c3, c0, 0 @ Domain ID
57 mrc p15, 0, r6, c2, c0, 0 @ translation table base address
58 mrc p15, 0, r7, c1, c0, 0 @ control register
59
60 stmia r0, { r4 - r13 }
61
62 @@ write our state back to RAM
63 bl s3c_pm_cb_flushcache
64 54
65 @@ jump to final code to send system to sleep 55 @@ jump to final code to send system to sleep
66 ldr r0, =pm_cpu_sleep 56 ldr r0, =pm_cpu_sleep
@@ -76,20 +66,6 @@ resume_with_mmu:
76 66
77 .ltorg 67 .ltorg
78 68
79 @@ the next bits sit in the .data segment, even though they
80 @@ happen to be code... the s3c_sleep_save_phys needs to be
81 @@ accessed by the resume code before it can restore the MMU.
82 @@ This means that the variable has to be close enough for the
83 @@ code to read it... since the .text segment needs to be RO,
84 @@ the data segment can be the only place to put this code.
85
86 .data
87
88 .global s3c_sleep_save_phys
89s3c_sleep_save_phys:
90 .word 0
91
92
93 /* sleep magic, to allow the bootloader to check for an valid 69 /* sleep magic, to allow the bootloader to check for an valid
94 * image to resume to. Must be the first word before the 70 * image to resume to. Must be the first word before the
95 * s3c_cpu_resume entry. 71 * s3c_cpu_resume entry.
@@ -100,10 +76,6 @@ s3c_sleep_save_phys:
100 /* s3c_cpu_resume 76 /* s3c_cpu_resume
101 * 77 *
102 * resume code entry for bootloader to call 78 * resume code entry for bootloader to call
103 *
104 * we must put this code here in the data segment as we have no
105 * other way of restoring the stack pointer after sleep, and we
106 * must not write to the code segment (code is read-only)
107 */ 79 */
108 80
109ENTRY(s3c_cpu_resume) 81ENTRY(s3c_cpu_resume)
@@ -134,25 +106,4 @@ ENTRY(s3c_cpu_resume)
134 beq 1001b 106 beq 1001b
135#endif /* CONFIG_DEBUG_RESUME */ 107#endif /* CONFIG_DEBUG_RESUME */
136 108
137 mov r1, #0 109 b cpu_resume
138 mcr p15, 0, r1, c8, c7, 0 @@ invalidate I & D TLBs
139 mcr p15, 0, r1, c7, c7, 0 @@ invalidate I & D caches
140
141 ldr r0, s3c_sleep_save_phys @ address of restore block
142 ldmia r0, { r4 - r13 }
143
144 mcr p15, 0, r4, c13, c0, 0 @ PID
145 mcr p15, 0, r5, c3, c0, 0 @ Domain ID
146 mcr p15, 0, r6, c2, c0, 0 @ translation table base
147
148#ifdef CONFIG_DEBUG_RESUME
149 mov r3, #'R'
150 strb r3, [ r2, #S3C2410_UTXH ]
151#endif
152
153 ldr r2, =resume_with_mmu
154 mcr p15, 0, r7, c1, c0, 0 @ turn on MMU, etc
155 nop @ second-to-last before mmu
156 mov pc, r2 @ go back to virtual address
157
158 .ltorg
diff --git a/arch/arm/plat-samsung/include/plat/pm.h b/arch/arm/plat-samsung/include/plat/pm.h
index 30518cc9a67c..937cc2ace517 100644
--- a/arch/arm/plat-samsung/include/plat/pm.h
+++ b/arch/arm/plat-samsung/include/plat/pm.h
@@ -52,13 +52,11 @@ extern unsigned char pm_uart_udivslot; /* true to save UART UDIVSLOT */
52 52
53/* from sleep.S */ 53/* from sleep.S */
54 54
55extern int s3c_cpu_save(unsigned long *saveblk); 55extern int s3c_cpu_save(unsigned long *saveblk, long);
56extern void s3c_cpu_resume(void); 56extern void s3c_cpu_resume(void);
57 57
58extern void s3c2410_cpu_suspend(void); 58extern void s3c2410_cpu_suspend(void);
59 59
60extern unsigned long s3c_sleep_save_phys;
61
62/* sleep save info */ 60/* sleep save info */
63 61
64/** 62/**
@@ -181,13 +179,5 @@ extern void s3c_pm_restore_gpios(void);
181 */ 179 */
182extern void s3c_pm_save_gpios(void); 180extern void s3c_pm_save_gpios(void);
183 181
184/**
185 * s3c_pm_cb_flushcache - callback for assembly code
186 *
187 * Callback to issue flush_cache_all() as this call is
188 * not a directly callable object.
189 */
190extern void s3c_pm_cb_flushcache(void);
191
192extern void s3c_pm_save_core(void); 182extern void s3c_pm_save_core(void);
193extern void s3c_pm_restore_core(void); 183extern void s3c_pm_restore_core(void);
diff --git a/arch/arm/plat-samsung/pm.c b/arch/arm/plat-samsung/pm.c
index 02d531fb3f81..d5b58d31903c 100644
--- a/arch/arm/plat-samsung/pm.c
+++ b/arch/arm/plat-samsung/pm.c
@@ -241,8 +241,6 @@ void (*pm_cpu_sleep)(void);
241 241
242static int s3c_pm_enter(suspend_state_t state) 242static int s3c_pm_enter(suspend_state_t state)
243{ 243{
244 static unsigned long regs_save[16];
245
246 /* ensure the debug is initialised (if enabled) */ 244 /* ensure the debug is initialised (if enabled) */
247 245
248 s3c_pm_debug_init(); 246 s3c_pm_debug_init();
@@ -266,12 +264,6 @@ static int s3c_pm_enter(suspend_state_t state)
266 return -EINVAL; 264 return -EINVAL;
267 } 265 }
268 266
269 /* store the physical address of the register recovery block */
270
271 s3c_sleep_save_phys = virt_to_phys(regs_save);
272
273 S3C_PMDBG("s3c_sleep_save_phys=0x%08lx\n", s3c_sleep_save_phys);
274
275 /* save all necessary core registers not covered by the drivers */ 267 /* save all necessary core registers not covered by the drivers */
276 268
277 s3c_pm_save_gpios(); 269 s3c_pm_save_gpios();
@@ -305,7 +297,7 @@ static int s3c_pm_enter(suspend_state_t state)
305 * we resume as it saves its own register state and restores it 297 * we resume as it saves its own register state and restores it
306 * during the resume. */ 298 * during the resume. */
307 299
308 s3c_cpu_save(regs_save); 300 s3c_cpu_save(0, PLAT_PHYS_OFFSET - PAGE_OFFSET);
309 301
310 /* restore the cpu state using the kernel's cpu init code. */ 302 /* restore the cpu state using the kernel's cpu init code. */
311 303
@@ -336,12 +328,6 @@ static int s3c_pm_enter(suspend_state_t state)
336 return 0; 328 return 0;
337} 329}
338 330
339/* callback from assembly code */
340void s3c_pm_cb_flushcache(void)
341{
342 flush_cache_all();
343}
344
345static int s3c_pm_prepare(void) 331static int s3c_pm_prepare(void)
346{ 332{
347 /* prepare check area if configured */ 333 /* prepare check area if configured */