diff options
Diffstat (limited to 'arch')
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 | ||
878 | config 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. | ||
878 | endchoice | 888 | endchoice |
879 | 889 | ||
880 | # | 890 | # |
@@ -1007,6 +1017,8 @@ source "arch/arm/mach-versatile/Kconfig" | |||
1007 | 1017 | ||
1008 | source "arch/arm/mach-vexpress/Kconfig" | 1018 | source "arch/arm/mach-vexpress/Kconfig" |
1009 | 1019 | ||
1020 | source "arch/arm/mach-vt8500/Kconfig" | ||
1021 | |||
1010 | source "arch/arm/mach-w90x900/Kconfig" | 1022 | source "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 | ||
1217 | config 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 | |||
1228 | config 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 | |||
1205 | endmenu | 1239 | endmenu |
1206 | 1240 | ||
1207 | source "arch/arm/common/Kconfig" | 1241 | source "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 | ||
1681 | config 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 | |||
1647 | config CMDLINE | 1693 | config 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 | |||
190 | machine-$(CONFIG_ARCH_U8500) := ux500 | 190 | machine-$(CONFIG_ARCH_U8500) := ux500 |
191 | machine-$(CONFIG_ARCH_VERSATILE) := versatile | 191 | machine-$(CONFIG_ARCH_VERSATILE) := versatile |
192 | machine-$(CONFIG_ARCH_VEXPRESS) := vexpress | 192 | machine-$(CONFIG_ARCH_VEXPRESS) := vexpress |
193 | machine-$(CONFIG_ARCH_VT8500) := vt8500 | ||
193 | machine-$(CONFIG_ARCH_W90X900) := w90x900 | 194 | machine-$(CONFIG_ARCH_W90X900) := w90x900 |
194 | machine-$(CONFIG_ARCH_NUC93X) := nuc93x | 195 | machine-$(CONFIG_ARCH_NUC93X) := nuc93x |
195 | machine-$(CONFIG_FOOTBRIDGE) := footbridge | 196 | machine-$(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 | ||
7 | OBJS = | ||
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. | ||
12 | ifeq ($(CONFIG_ZBOOT_ROM_MMCIF),y) | ||
13 | ifeq ($(CONFIG_ARCH_SH7372),y) | ||
14 | OBJS += mmcif-sh7372.o | ||
15 | endif | ||
16 | endif | ||
17 | |||
7 | AFLAGS_head.o += -DTEXT_OFFSET=$(TEXT_OFFSET) | 18 | AFLAGS_head.o += -DTEXT_OFFSET=$(TEXT_OFFSET) |
8 | HEAD = head.o | 19 | HEAD = head.o |
9 | OBJS = misc.o decompress.o | 20 | OBJS += misc.o decompress.o |
10 | FONTC = $(srctree)/drivers/video/console/font_acorn_8x8.c | 21 | FONTC = $(srctree)/drivers/video/console/font_acorn_8x8.c |
11 | 22 | ||
12 | # | 23 | # |
@@ -29,6 +40,10 @@ ifeq ($(CONFIG_ARCH_SA1100),y) | |||
29 | OBJS += head-sa1100.o | 40 | OBJS += head-sa1100.o |
30 | endif | 41 | endif |
31 | 42 | ||
43 | ifeq ($(CONFIG_ARCH_VT8500),y) | ||
44 | OBJS += head-vt8500.o | ||
45 | endif | ||
46 | |||
32 | ifeq ($(CONFIG_CPU_XSCALE),y) | 47 | ifeq ($(CONFIG_CPU_XSCALE),y) |
33 | OBJS += head-xscale.o | 48 | OBJS += head-xscale.o |
34 | endif | 49 | endif |
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 | */ | ||
42 | asmlinkage 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 | |||
265 | extern void __cpuc_flush_icache_all(void); | 140 | extern void __cpuc_flush_icache_all(void); |
266 | extern void __cpuc_flush_kern_all(void); | 141 | extern void __cpuc_flush_kern_all(void); |
267 | extern void __cpuc_flush_user_all(void); | 142 | extern 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 | |||
283 | extern void dmac_map_area(const void *, size_t, int); | 154 | extern void dmac_map_area(const void *, size_t, int); |
284 | extern void dmac_unmap_area(const void *, size_t, int); | 155 | extern void dmac_unmap_area(const void *, size_t, int); |
285 | extern void dmac_flush_range(const void *, const void *); | 156 | extern 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 | |||
12 | struct mm_struct; | ||
13 | |||
14 | /* | ||
15 | * Don't change this structure - ASM code | ||
16 | * relies on it. | ||
17 | */ | ||
18 | extern 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 | |||
35 | struct mm_struct; | ||
36 | |||
37 | /* declare all the functions as extern */ | ||
38 | extern void cpu_proc_init(void); | ||
39 | extern void cpu_proc_fin(void); | ||
40 | extern int cpu_do_idle(void); | ||
41 | extern void cpu_dcache_clean_area(void *, int); | ||
42 | extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm); | ||
43 | extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext); | ||
44 | extern 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 | */ | 21 | struct 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 | 26 | extern 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> | 77 | extern void cpu_proc_init(void); |
78 | extern void cpu_proc_fin(void); | ||
79 | extern int cpu_do_idle(void); | ||
80 | extern void cpu_dcache_clean_area(void *, int); | ||
81 | extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm); | ||
82 | extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext); | ||
83 | extern 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 | ||
94 | extern 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 | ||
96 | unsigned long get_wchan(struct task_struct *p); | 96 | unsigned 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__ | ||
4 | unsigned int scu_get_core_count(void __iomem *); | 9 | unsigned int scu_get_core_count(void __iomem *); |
5 | void scu_enable(void __iomem *); | 10 | void scu_enable(void __iomem *); |
11 | int 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 | |||
29 | obj-$(CONFIG_ARTHUR) += arthur.o | 29 | obj-$(CONFIG_ARTHUR) += arthur.o |
30 | obj-$(CONFIG_ISA_DMA) += dma-isa.o | 30 | obj-$(CONFIG_ISA_DMA) += dma-isa.o |
31 | obj-$(CONFIG_PCI) += bios32.o isa.o | 31 | obj-$(CONFIG_PCI) += bios32.o isa.o |
32 | obj-$(CONFIG_PM) += sleep.o | ||
32 | obj-$(CONFIG_HAVE_SCHED_CLOCK) += sched_clock.o | 33 | obj-$(CONFIG_HAVE_SCHED_CLOCK) += sched_clock.o |
33 | obj-$(CONFIG_SMP) += smp.o smp_tlb.o | 34 | obj-$(CONFIG_SMP) += smp.o smp_tlb.o |
34 | obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o | 35 | obj-$(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 | */ | ||
17 | ENTRY(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 | ||
68 | ENDPROC(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 | */ | ||
77 | ENTRY(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 | ||
87 | ENDPROC(cpu_resume_mmu) | ||
88 | .ltorg | ||
89 | .align 5 | ||
90 | cpu_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 | ||
96 | ENDPROC(cpu_resume_turn_mmu_on) | ||
97 | cpu_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 | ||
101 | ENDPROC(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 | ||
112 | ENTRY(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 | ||
129 | ENDPROC(cpu_resume) | ||
130 | |||
131 | sleep_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 | */ | ||
62 | int 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 | ||
223 | static 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 | |||
228 | static 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 | *************************************************************************/ | ||
103 | static struct cs4271_platform_data edb93xx_cs4271_data = { | ||
104 | .gpio_nreset = -EINVAL, /* filled in later */ | ||
105 | }; | ||
106 | |||
107 | static 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 | |||
113 | static void edb93xx_cs4271_hw_cleanup(struct spi_device *spi) | ||
114 | { | ||
115 | gpio_free(EP93XX_GPIO_LINE_EGPIO6); | ||
116 | } | ||
117 | |||
118 | static void edb93xx_cs4271_hw_cs_control(struct spi_device *spi, int value) | ||
119 | { | ||
120 | gpio_set_value(EP93XX_GPIO_LINE_EGPIO6, value); | ||
121 | } | ||
122 | |||
123 | static 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 | |||
129 | static 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 | |||
141 | static struct ep93xx_spi_info edb93xx_spi_info __initdata = { | ||
142 | .num_chipselect = ARRAY_SIZE(edb93xx_spi_board_info), | ||
143 | }; | ||
144 | |||
145 | static 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 | *************************************************************************/ | ||
162 | static 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 | |||
169 | static 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 | *************************************************************************/ |
98 | static void __init edb93xx_register_pwm(void) | 180 | static 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 | *************************************************************************/ | ||
199 | static struct ep93xxfb_mach_info __initdata edb93xxfb_info = { | ||
200 | .num_modes = EP93XXFB_USE_MODEDB, | ||
201 | .bpp = 16, | ||
202 | .flags = 0, | ||
203 | }; | ||
204 | |||
205 | static 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 | |||
213 | static 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 | |||
114 | static void __init edb93xx_init_machine(void) | 227 | static 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 | ||
64 | void ep93xx_gpio_int_debounce(unsigned int irq, int enable) | 64 | static 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 | } |
78 | EXPORT_SYMBOL(ep93xx_gpio_int_debounce); | ||
79 | 78 | ||
80 | static void ep93xx_gpio_ab_irq_handler(unsigned int irq, struct irq_desc *desc) | 79 | static 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 | ||
337 | static 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 | |||
338 | static void ep93xx_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) | 351 | static 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 | ||
102 | extern 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 | /* | 20 | static cycle_t cksrc_dc21285_read(struct clocksource *cs) |
20 | * Footbridge timer 1 support. | 21 | { |
21 | */ | 22 | return cs->mask - *CSR_TIMER2_VALUE; |
22 | static unsigned long timer1_latch; | 23 | } |
23 | 24 | ||
24 | static unsigned long timer1_gettimeoffset (void) | 25 | static 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; | 33 | static int cksrc_dc21285_disable(struct clocksource *cs) |
34 | { | ||
35 | *CSR_TIMER2_CNTL = 0; | ||
29 | } | 36 | } |
30 | 37 | ||
31 | static irqreturn_t | 38 | static struct clocksource cksrc_dc21285 = { |
32 | timer1_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 | |||
48 | static 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 | |||
66 | static 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 | |||
74 | static 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 | ||
41 | static struct irqaction footbridge_timer_irq = { | 85 | static 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 | */ |
50 | static void __init footbridge_timer_init(void) | 95 | static 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 | ||
61 | struct sys_timer footbridge_timer = { | 110 | struct 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 | ||
23 | static unsigned long isa_gettimeoffset(void) | 26 | static 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; | 54 | static 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); | 61 | static 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; | 89 | static int pit_set_next_event(unsigned long delta, |
90 | struct clock_event_device *evt) | ||
91 | { | ||
92 | return 0; | ||
62 | } | 93 | } |
63 | 94 | ||
64 | static irqreturn_t | 95 | static struct clock_event_device pit_ce = { |
65 | isa_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 | |||
103 | static 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 | ||
71 | static struct irqaction isa_timer_irq = { | 110 | static 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 | ||
77 | static void __init isa_timer_init(void) | 117 | static 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 | ||
88 | struct sys_timer isa_timer = { | 130 | struct 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 | ||
103 | MACHINE_START(NAS4220B, "Raidsonic NAS IB-4220-B") | 104 | MACHINE_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 | ||
87 | MACHINE_START(RUT100, "Teltonika RUT100") | 88 | MACHINE_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 | ||
135 | MACHINE_START(WBD111, "Wiliboard WBD-111") | 136 | MACHINE_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 | ||
135 | MACHINE_START(WBD222, "Wiliboard WBD-222") | 136 | MACHINE_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); | |||
18 | extern void gemini_init_irq(void); | 18 | extern void gemini_init_irq(void); |
19 | extern void gemini_timer_init(void); | 19 | extern void gemini_timer_init(void); |
20 | extern void gemini_gpio_init(void); | 20 | extern void gemini_gpio_init(void); |
21 | extern void platform_register_rtc(void); | ||
21 | 22 | ||
22 | /* Common platform devices registration functions */ | 23 | /* Common platform devices registration functions */ |
23 | extern int platform_register_uart(void); | 24 | extern 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 | |||
94 | static 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 | |||
107 | static 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 | |||
114 | int __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 | ||
71 | static void mxs_gpio_ack_irq(u32 irq) | 71 | static 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 | ||
77 | static void mxs_gpio_mask_irq(u32 irq) | 77 | static 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 | ||
83 | static void mxs_gpio_unmask_irq(u32 irq) | 83 | static 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 | ||
89 | static int mxs_gpio_get(struct gpio_chip *chip, unsigned offset); | 89 | static int mxs_gpio_get(struct gpio_chip *chip, unsigned offset); |
90 | 90 | ||
91 | static int mxs_gpio_set_irq_type(u32 irq, u32 type) | 91 | static 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 | */ |
163 | static int mxs_gpio_set_wake_irq(u32 irq, u32 enable) | 163 | static 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 | ||
184 | static struct irq_chip gpio_irq_chip = { | 184 | static 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 | ||
192 | static void mxs_set_gpio_direction(struct gpio_chip *chip, unsigned offset, | 192 | static 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 | ||
35 | static void __iomem *icoll_base = MXS_IO_ADDRESS(MXS_ICOLL_BASE_ADDR); | 35 | static void __iomem *icoll_base = MXS_IO_ADDRESS(MXS_ICOLL_BASE_ADDR); |
36 | 36 | ||
37 | static void icoll_ack_irq(unsigned int irq) | 37 | static 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 | ||
48 | static void icoll_mask_irq(unsigned int irq) | 48 | static 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 | ||
54 | static void icoll_unmask_irq(unsigned int irq) | 54 | static 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 | ||
60 | static struct irq_chip mxs_icoll_chip = { | 60 | static 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 | ||
66 | void __init icoll_init_irq(void) | 66 | void __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); | |||
123 | extern void omap1_pm_idle(void); | 123 | extern void omap1_pm_idle(void); |
124 | extern void omap1_pm_suspend(void); | 124 | extern void omap1_pm_suspend(void); |
125 | 125 | ||
126 | extern void omap7xx_cpu_suspend(unsigned short, unsigned short); | 126 | extern void omap7xx_cpu_suspend(unsigned long, unsigned long); |
127 | extern void omap1510_cpu_suspend(unsigned short, unsigned short); | 127 | extern void omap1510_cpu_suspend(unsigned long, unsigned long); |
128 | extern void omap1610_cpu_suspend(unsigned short, unsigned short); | 128 | extern void omap1610_cpu_suspend(unsigned long, unsigned long); |
129 | extern void omap7xx_idle_loop_suspend(void); | 129 | extern void omap7xx_idle_loop_suspend(void); |
130 | extern void omap1510_idle_loop_suspend(void); | 130 | extern void omap1510_idle_loop_suspend(void); |
131 | extern void omap1610_idle_loop_suspend(void); | 131 | extern 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 | ||
61 | ENTRY(omap7xx_cpu_suspend) | 62 | ENTRY(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 | ||
140 | ENTRY(omap1510_cpu_suspend) | 142 | ENTRY(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 | ||
214 | ENTRY(omap1610_cpu_suspend) | 217 | ENTRY(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 | ||
21 | ENTRY(omap1_sram_reprogram_clock) | 22 | ENTRY(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); | |||
92 | extern void omap24xx_cpu_suspend(u32 dll_ctrl, void __iomem *sdrc_dlla_ctrl, | 92 | extern void omap24xx_cpu_suspend(u32 dll_ctrl, void __iomem *sdrc_dlla_ctrl, |
93 | void __iomem *sdrc_power); | 93 | void __iomem *sdrc_power); |
94 | extern void omap34xx_cpu_suspend(u32 *addr, int save_state); | 94 | extern void omap34xx_cpu_suspend(u32 *addr, int save_state); |
95 | extern void save_secure_ram_context(u32 *addr); | 95 | extern int save_secure_ram_context(u32 *addr); |
96 | extern void omap3_save_scratchpad_contents(void); | 96 | extern void omap3_save_scratchpad_contents(void); |
97 | 97 | ||
98 | extern unsigned int omap24xx_idle_loop_suspend_sz; | 98 | extern 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 | ||
50 | ENTRY(omap24xx_idle_loop_suspend) | 51 | ENTRY(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 | ||
85 | ENTRY(omap24xx_cpu_suspend) | 87 | ENTRY(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 | ||
121 | ENTRY(save_secure_ram_context) | 122 | ENTRY(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 | ||
172 | ENTRY(omap34xx_cpu_suspend) | 174 | ENTRY(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 | ||
42 | ENTRY(omap242x_sram_ddr_init) | 43 | ENTRY(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 | ||
146 | ENTRY(omap242x_sram_reprogram_sdrc) | 148 | ENTRY(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 | ||
241 | ENTRY(omap242x_sram_set_prcm) | 244 | ENTRY(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 | ||
42 | ENTRY(omap243x_sram_ddr_init) | 43 | ENTRY(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 | ||
146 | ENTRY(omap243x_sram_reprogram_sdrc) | 148 | ENTRY(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 | ||
241 | ENTRY(omap243x_sram_set_prcm) | 244 | ENTRY(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 | ||
114 | ENTRY(omap3_sram_configure_core_dpll) | 115 | ENTRY(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 { | |||
22 | extern struct pxa_cpu_pm_fns *pxa_cpu_pm_fns; | 22 | extern struct pxa_cpu_pm_fns *pxa_cpu_pm_fns; |
23 | 23 | ||
24 | /* sleep.S */ | 24 | /* sleep.S */ |
25 | extern void pxa25x_cpu_suspend(unsigned int); | 25 | extern void pxa25x_cpu_suspend(unsigned int, long); |
26 | extern void pxa27x_cpu_suspend(unsigned int); | 26 | extern void pxa27x_cpu_suspend(unsigned int, long); |
27 | extern void pxa_cpu_resume(void); | ||
28 | 27 | ||
29 | extern int pxa_pm_enter(suspend_state_t state); | 28 | extern int pxa_pm_enter(suspend_state_t state); |
30 | extern int pxa_pm_prepare(void); | 29 | extern 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; | |||
212 | static int palmz72_pm_suspend(struct sys_device *dev, pm_message_t msg) | 212 | static 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 | ||
68 | EXPORT_SYMBOL_GPL(pxa_pm_enter); | 68 | EXPORT_SYMBOL_GPL(pxa_pm_enter); |
69 | 69 | ||
70 | unsigned long sleep_phys_sp(void *sp) | ||
71 | { | ||
72 | return virt_to_phys(sp); | ||
73 | } | ||
74 | |||
75 | static int pxa_pm_valid(suspend_state_t state) | 70 | static 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) | |||
252 | static int pxa25x_cpu_pm_prepare(void) | 252 | static 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) | |||
313 | static int pxa27x_cpu_pm_prepare(void) | 313 | static 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 | ||
25 | pxa_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 | |||
43 | pxa_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 | |||
61 | ENTRY(pxa3xx_cpu_suspend) | 31 | ENTRY(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 | ||
94 | 20: b 20b @ waiting for sleep | 44 | 20: b 20b @ waiting for sleep |
95 | |||
96 | .data | ||
97 | .align 5 | ||
98 | /* | ||
99 | * pxa3xx_cpu_resume | ||
100 | */ | ||
101 | |||
102 | ENTRY(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 | ||
146 | pxa3xx_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 | |||
163 | ENTRY(pxa27x_cpu_suspend) | 56 | ENTRY(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 | ||
221 | ENTRY(pxa25x_cpu_suspend) | 110 | ENTRY(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 | ||
330 | ENTRY(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 |
351 | resume_turn_on_mmu: | 205 | pxa_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 | |||
362 | sleep_save_sp: | ||
363 | .word 0 @ preserve stack phys ptr here | ||
364 | |||
365 | .text | ||
366 | resume_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 = { | |||
676 | static void zeus_power_off(void) | 676 | static 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 | ||
38 | ENTRY(s3c_cpu_save) | 38 | ENTRY(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) | |||
61 | resume_with_mmu: | 49 | resume_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 | ||
73 | s3c_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 | ||
41 | ENTRY(s3c_cpu_save) | 41 | ENTRY(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 | ||
64 | resume_with_mmu: | 51 | resume_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 | ||
79 | s3c_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 | ||
98 | ENTRY(s3c_cpu_resume) | 72 | ENTRY(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 | ||
35 | extern void sa1100_cpu_suspend(void); | 35 | extern void sa1100_cpu_suspend(long); |
36 | extern 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 | ||
118 | unsigned long sleep_phys_sp(void *sp) | ||
119 | { | ||
120 | return virt_to_phys(sp); | ||
121 | } | ||
122 | |||
123 | static const struct platform_suspend_ops sa11x0_pm_ops = { | 117 | static 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 | ||
36 | ENTRY(sa1100_cpu_suspend) | 31 | ENTRY(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 | ||
179 | ENTRY(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 |
199 | resume_turn_on_mmu: | 149 | sa1100_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 | |||
207 | sleep_save_sp: | ||
208 | .word 0 @ preserve stack phys ptr here | ||
209 | |||
210 | .text | ||
211 | resume_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 | |||
11 | static 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 | |||
23 | static 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 | |||
12 | static 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 | |||
24 | static 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 | ||
10 | menu "Ux500 SoC" | 11 | menu "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 @@ | |||
1 | if ARCH_VT8500 | ||
2 | |||
3 | config VTWM_VERSION_VT8500 | ||
4 | bool | ||
5 | |||
6 | config VTWM_VERSION_WM8505 | ||
7 | bool | ||
8 | |||
9 | config 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 | |||
19 | config 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 | |||
29 | comment "LCD panel size" | ||
30 | |||
31 | config 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 | |||
43 | config 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 | |||
53 | config 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 | |||
63 | config 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 | |||
73 | endif | ||
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 @@ | |||
1 | obj-y += devices.o gpio.o irq.o timer.o | ||
2 | |||
3 | obj-$(CONFIG_VTWM_VERSION_VT8500) += devices-vt8500.o | ||
4 | obj-$(CONFIG_VTWM_VERSION_WM8505) += devices-wm8505.o | ||
5 | |||
6 | obj-$(CONFIG_MACH_BV07) += bv07.o | ||
7 | obj-$(CONFIG_MACH_WM8505_7IN_NETBOOK) += wm8505_7in.o | ||
8 | |||
9 | obj-$(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 | ||
2 | params_phys-y := 0x00000100 | ||
3 | initrd_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 | |||
29 | static void __iomem *pmc_hiber; | ||
30 | |||
31 | static 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 | |||
41 | static 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 | |||
48 | void __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 | |||
70 | MACHINE_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, | ||
77 | MACHINE_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 | |||
23 | void __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 | |||
63 | static 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 | |||
85 | void __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 | |||
23 | void __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 | |||
70 | static 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 | |||
93 | void __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 */ | ||
31 | unsigned long wmt_ic_base __initdata; | ||
32 | unsigned long wmt_sic_base __initdata; | ||
33 | unsigned long wmt_gpio_base __initdata; | ||
34 | unsigned long wmt_pmc_base __initdata; | ||
35 | unsigned long wmt_i8042_base __initdata; | ||
36 | |||
37 | int wmt_nr_irqs __initdata; | ||
38 | int wmt_timer_irq __initdata; | ||
39 | int wmt_gpio_ext_irq[8] __initdata; | ||
40 | |||
41 | /* Should remain accessible after init. | ||
42 | * i8042 driver desperately calls for attention... | ||
43 | */ | ||
44 | int wmt_i8042_kbd_irq; | ||
45 | int wmt_i8042_aux_irq; | ||
46 | |||
47 | static u64 fb_dma_mask = DMA_BIT_MASK(32); | ||
48 | |||
49 | struct 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 | |||
58 | struct platform_device vt8500_device_wm8505_fb = { | ||
59 | .name = "wm8505-fb", | ||
60 | .id = 0, | ||
61 | }; | ||
62 | |||
63 | /* Smallest to largest */ | ||
64 | static 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 | |||
139 | static int current_panel_idx __initdata = ARRAY_SIZE(panels) - 1; | ||
140 | |||
141 | static 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 | |||
154 | early_param("panel", panel_setup); | ||
155 | |||
156 | static 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 | |||
166 | struct platform_device vt8500_device_uart0 = { | ||
167 | .name = "vt8500_serial", | ||
168 | .id = 0, | ||
169 | }; | ||
170 | |||
171 | struct platform_device vt8500_device_uart1 = { | ||
172 | .name = "vt8500_serial", | ||
173 | .id = 1, | ||
174 | }; | ||
175 | |||
176 | struct platform_device vt8500_device_uart2 = { | ||
177 | .name = "vt8500_serial", | ||
178 | .id = 2, | ||
179 | }; | ||
180 | |||
181 | struct platform_device vt8500_device_uart3 = { | ||
182 | .name = "vt8500_serial", | ||
183 | .id = 3, | ||
184 | }; | ||
185 | |||
186 | struct platform_device vt8500_device_uart4 = { | ||
187 | .name = "vt8500_serial", | ||
188 | .id = 4, | ||
189 | }; | ||
190 | |||
191 | struct platform_device vt8500_device_uart5 = { | ||
192 | .name = "vt8500_serial", | ||
193 | .id = 5, | ||
194 | }; | ||
195 | |||
196 | static u64 ehci_dma_mask = DMA_BIT_MASK(32); | ||
197 | |||
198 | struct 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 | |||
207 | struct platform_device vt8500_device_ge_rops = { | ||
208 | .name = "wmt_ge_rops", | ||
209 | .id = -1, | ||
210 | }; | ||
211 | |||
212 | struct platform_device vt8500_device_pwm = { | ||
213 | .name = "vt8500-pwm", | ||
214 | .id = 0, | ||
215 | }; | ||
216 | |||
217 | static 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 | |||
224 | struct platform_device vt8500_device_pwmbl = { | ||
225 | .name = "pwm-backlight", | ||
226 | .id = 0, | ||
227 | .dev = { | ||
228 | .platform_data = &vt8500_pwmbl_data, | ||
229 | }, | ||
230 | }; | ||
231 | |||
232 | struct platform_device vt8500_device_rtc = { | ||
233 | .name = "vt8500-rtc", | ||
234 | .id = 0, | ||
235 | }; | ||
236 | |||
237 | struct 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 | |||
254 | void __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 | |||
263 | void __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 | |||
22 | void __init vt8500_init_irq(void); | ||
23 | void __init wm8505_init_irq(void); | ||
24 | void __init vt8500_map_io(void); | ||
25 | void __init wm8505_map_io(void); | ||
26 | void __init vt8500_reserve_mem(void); | ||
27 | void __init wm8505_reserve_mem(void); | ||
28 | void __init vt8500_gpio_init(void); | ||
29 | void __init vt8500_set_resources(void); | ||
30 | void __init wm8505_set_resources(void); | ||
31 | |||
32 | extern unsigned long wmt_ic_base __initdata; | ||
33 | extern unsigned long wmt_sic_base __initdata; | ||
34 | extern unsigned long wmt_gpio_base __initdata; | ||
35 | extern unsigned long wmt_pmc_base __initdata; | ||
36 | |||
37 | extern int wmt_nr_irqs __initdata; | ||
38 | extern int wmt_timer_irq __initdata; | ||
39 | extern int wmt_gpio_ext_irq[8] __initdata; | ||
40 | |||
41 | extern struct map_desc wmt_io_desc[2] __initdata; | ||
42 | |||
43 | static 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 | |||
54 | static 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 | |||
65 | static 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 | |||
72 | extern struct sys_timer vt8500_timer; | ||
73 | |||
74 | extern struct platform_device vt8500_device_uart0; | ||
75 | extern struct platform_device vt8500_device_uart1; | ||
76 | extern struct platform_device vt8500_device_uart2; | ||
77 | extern struct platform_device vt8500_device_uart3; | ||
78 | extern struct platform_device vt8500_device_uart4; | ||
79 | extern struct platform_device vt8500_device_uart5; | ||
80 | |||
81 | extern struct platform_device vt8500_device_lcdc; | ||
82 | extern struct platform_device vt8500_device_wm8505_fb; | ||
83 | extern struct platform_device vt8500_device_ehci; | ||
84 | extern struct platform_device vt8500_device_ge_rops; | ||
85 | extern struct platform_device vt8500_device_pwm; | ||
86 | extern struct platform_device vt8500_device_pwmbl; | ||
87 | extern 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 | |||
32 | static void __iomem *regbase; | ||
33 | |||
34 | struct vt8500_gpio_chip { | ||
35 | struct gpio_chip chip; | ||
36 | unsigned int shift; | ||
37 | unsigned int regoff; | ||
38 | }; | ||
39 | |||
40 | static int gpio_to_irq_map[8]; | ||
41 | |||
42 | static 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 | |||
54 | static 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 | |||
64 | static 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 | |||
76 | static 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 | |||
93 | static 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 | |||
102 | static 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 | |||
134 | static 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 | |||
158 | static 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 | |||
168 | static 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 | |||
184 | static 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 | |||
190 | static 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 | |||
203 | static 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 | |||
211 | static 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 | |||
223 | void __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 | ||
25 | 1001: 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 | ||
30 | 1001: | ||
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 | |||
16 | extern unsigned long wmt_i8042_base __initdata; | ||
17 | extern int wmt_i8042_kbd_irq; | ||
18 | extern 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 | |||
10 | static inline void arch_idle(void) | ||
11 | { | ||
12 | cpu_do_idle(); | ||
13 | } | ||
14 | |||
15 | static 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 | |||
21 | static 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 | |||
29 | static 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 | |||
21 | struct 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 | |||
39 | static void __iomem *ic_regbase; | ||
40 | static void __iomem *sic_regbase; | ||
41 | |||
42 | static 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 | |||
67 | static 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 | |||
81 | static 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 | |||
116 | static 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 | |||
124 | void __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 | |||
148 | void __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 | |||
29 | static DEFINE_MUTEX(pwm_lock); | ||
30 | static LIST_HEAD(pwm_list); | ||
31 | |||
32 | struct 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) | ||
45 | static 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 | |||
56 | int 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 | } | ||
94 | EXPORT_SYMBOL(pwm_config); | ||
95 | |||
96 | int 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 | } | ||
102 | EXPORT_SYMBOL(pwm_enable); | ||
103 | |||
104 | void 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 | } | ||
109 | EXPORT_SYMBOL(pwm_disable); | ||
110 | |||
111 | struct 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 | } | ||
139 | EXPORT_SYMBOL(pwm_request); | ||
140 | |||
141 | void 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 | } | ||
154 | EXPORT_SYMBOL(pwm_free); | ||
155 | |||
156 | static 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 | |||
163 | static 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 | |||
212 | err_free_mem: | ||
213 | release_mem_region(r->start, resource_size(r)); | ||
214 | err_free: | ||
215 | kfree(pwms); | ||
216 | return ret; | ||
217 | } | ||
218 | |||
219 | static 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 | |||
244 | static 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 | |||
253 | static int __init pwm_init(void) | ||
254 | { | ||
255 | return platform_driver_register(&pwm_driver); | ||
256 | } | ||
257 | arch_initcall(pwm_init); | ||
258 | |||
259 | static void __exit pwm_exit(void) | ||
260 | { | ||
261 | platform_driver_unregister(&pwm_driver); | ||
262 | } | ||
263 | module_exit(pwm_exit); | ||
264 | |||
265 | MODULE_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 | |||
46 | static void __iomem *regbase; | ||
47 | |||
48 | static 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 | |||
58 | struct 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 | |||
66 | static 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 | |||
84 | static 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 | |||
101 | struct 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 | |||
109 | static 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 | |||
118 | struct 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 | |||
125 | static 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 | |||
153 | struct 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 | |||
29 | static void __iomem *pmc_hiber; | ||
30 | |||
31 | static 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 | |||
41 | static 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 | |||
48 | void __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 | |||
70 | MACHINE_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, | ||
77 | MACHINE_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 | ||
394 | ENTRY(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} | ||
402 | ENDPROC(cpu_arm920_do_suspend) | ||
403 | |||
404 | ENTRY(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 | ||
418 | ENDPROC(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 | ||
408 | ENTRY(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} | ||
416 | ENDPROC(cpu_arm926_do_suspend) | ||
417 | |||
418 | ENTRY(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 | ||
432 | ENDPROC(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 | ||
175 | ENTRY(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} | ||
183 | ENDPROC(cpu_sa1100_do_suspend) | ||
184 | |||
185 | ENTRY(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 | ||
202 | ENDPROC(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 | ||
128 | ENTRY(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} | ||
140 | ENDPROC(cpu_v6_do_suspend) | ||
141 | |||
142 | ENTRY(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 | ||
163 | ENDPROC(cpu_v6_do_resume) | ||
164 | cpu_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 |
113 | 1: mcr p15, 0, r0, c2, c0, 0 @ set TTB 0 | 116 | 1: 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 | ||
215 | ENTRY(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} | ||
227 | ENDPROC(cpu_v7_do_suspend) | ||
228 | |||
229 | ENTRY(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 | ||
252 | ENDPROC(cpu_v7_do_resume) | ||
253 | cpu_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 | ||
421 | ENTRY(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} | ||
433 | ENDPROC(cpu_xsc3_do_suspend) | ||
434 | |||
435 | ENTRY(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 | ||
456 | ENDPROC(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 | ||
522 | ENTRY(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} | ||
534 | ENDPROC(cpu_xscale_do_suspend) | ||
535 | |||
536 | ENTRY(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 | ||
553 | ENDPROC(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__ |
15 | extern void * omap_sram_push(void * start, unsigned long size); | 15 | #include <asm/fncpy.h> |
16 | |||
17 | extern 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 | |||
16 | extern void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl); | 28 | extern void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl); |
17 | 29 | ||
18 | extern void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl, | 30 | extern 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 | ||
245 | void * 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 | */ | ||
252 | void *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 | ||
50 | ENTRY(s3c_cpu_save) | 50 | ENTRY(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 | ||
89 | s3c_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 | ||
109 | ENTRY(s3c_cpu_resume) | 81 | ENTRY(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 | ||
55 | extern int s3c_cpu_save(unsigned long *saveblk); | 55 | extern int s3c_cpu_save(unsigned long *saveblk, long); |
56 | extern void s3c_cpu_resume(void); | 56 | extern void s3c_cpu_resume(void); |
57 | 57 | ||
58 | extern void s3c2410_cpu_suspend(void); | 58 | extern void s3c2410_cpu_suspend(void); |
59 | 59 | ||
60 | extern 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 | */ |
182 | extern void s3c_pm_save_gpios(void); | 180 | extern 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 | */ | ||
190 | extern void s3c_pm_cb_flushcache(void); | ||
191 | |||
192 | extern void s3c_pm_save_core(void); | 182 | extern void s3c_pm_save_core(void); |
193 | extern void s3c_pm_restore_core(void); | 183 | extern 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 | ||
242 | static int s3c_pm_enter(suspend_state_t state) | 242 | static 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 */ | ||
340 | void s3c_pm_cb_flushcache(void) | ||
341 | { | ||
342 | flush_cache_all(); | ||
343 | } | ||
344 | |||
345 | static int s3c_pm_prepare(void) | 331 | static int s3c_pm_prepare(void) |
346 | { | 332 | { |
347 | /* prepare check area if configured */ | 333 | /* prepare check area if configured */ |