aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig22
-rw-r--r--arch/arm/boot/compressed/head.S105
-rw-r--r--arch/arm/common/rtctime.c29
-rw-r--r--arch/arm/configs/ixdp2800_defconfig2
-rw-r--r--arch/arm/kernel/Makefile5
-rw-r--r--arch/arm/kernel/asm-offsets.c20
-rw-r--r--arch/arm/kernel/entry-armv.S276
-rw-r--r--arch/arm/kernel/entry-common.S65
-rw-r--r--arch/arm/kernel/entry-header.S143
-rw-r--r--arch/arm/kernel/head.S3
-rw-r--r--arch/arm/kernel/process.c25
-rw-r--r--arch/arm/kernel/ptrace.c5
-rw-r--r--arch/arm/kernel/sys_arm.c14
-rw-r--r--arch/arm/kernel/traps.c69
-rw-r--r--arch/arm/kernel/vmlinux.lds.S3
-rw-r--r--arch/arm/mach-clps711x/Kconfig3
-rw-r--r--arch/arm/mach-footbridge/Kconfig12
-rw-r--r--arch/arm/mach-imx/Kconfig1
-rw-r--r--arch/arm/mach-imx/generic.c16
-rw-r--r--arch/arm/mach-integrator/core.c6
-rw-r--r--arch/arm/mach-integrator/integrator_cp.c17
-rw-r--r--arch/arm/mach-integrator/leds.c2
-rw-r--r--arch/arm/mach-integrator/time.c17
-rw-r--r--arch/arm/mach-ixp2000/ixdp2800.c147
-rw-r--r--arch/arm/mach-ixp2000/pci.c8
-rw-r--r--arch/arm/mach-ixp4xx/common-pci.c10
-rw-r--r--arch/arm/mach-pxa/generic.c25
-rw-r--r--arch/arm/mach-pxa/sleep.S56
-rw-r--r--arch/arm/mm/Kconfig21
-rw-r--r--arch/arm/mm/abort-ev6.S16
-rw-r--r--arch/arm/mm/mm-armv.c5
31 files changed, 775 insertions, 373 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 4055115ae0e2..bf397a9f8ac2 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -85,6 +85,7 @@ choice
85config ARCH_CLPS7500 85config ARCH_CLPS7500
86 bool "Cirrus-CL-PS7500FE" 86 bool "Cirrus-CL-PS7500FE"
87 select TIMER_ACORN 87 select TIMER_ACORN
88 select ISA
88 89
89config ARCH_CLPS711X 90config ARCH_CLPS711X
90 bool "CLPS711x/EP721x-based" 91 bool "CLPS711x/EP721x-based"
@@ -96,6 +97,7 @@ config ARCH_CO285
96 97
97config ARCH_EBSA110 98config ARCH_EBSA110
98 bool "EBSA-110" 99 bool "EBSA-110"
100 select ISA
99 help 101 help
100 This is an evaluation board for the StrongARM processor available 102 This is an evaluation board for the StrongARM processor available
101 from Digital. It has limited hardware on-board, including an onboard 103 from Digital. It has limited hardware on-board, including an onboard
@@ -120,13 +122,16 @@ config ARCH_INTEGRATOR
120 122
121config ARCH_IOP3XX 123config ARCH_IOP3XX
122 bool "IOP3xx-based" 124 bool "IOP3xx-based"
125 select PCI
123 126
124config ARCH_IXP4XX 127config ARCH_IXP4XX
125 bool "IXP4xx-based" 128 bool "IXP4xx-based"
126 select DMABOUNCE 129 select DMABOUNCE
130 select PCI
127 131
128config ARCH_IXP2000 132config ARCH_IXP2000
129 bool "IXP2400/2800-based" 133 bool "IXP2400/2800-based"
134 select PCI
130 135
131config ARCH_L7200 136config ARCH_L7200
132 bool "LinkUp-L7200" 137 bool "LinkUp-L7200"
@@ -155,6 +160,8 @@ config ARCH_RPC
155 160
156config ARCH_SA1100 161config ARCH_SA1100
157 bool "SA1100-based" 162 bool "SA1100-based"
163 select ISA
164 select DISCONTIGMEM
158 165
159config ARCH_S3C2410 166config ARCH_S3C2410
160 bool "Samsung S3C2410" 167 bool "Samsung S3C2410"
@@ -165,6 +172,9 @@ config ARCH_S3C2410
165 172
166config ARCH_SHARK 173config ARCH_SHARK
167 bool "Shark" 174 bool "Shark"
175 select ISA
176 select ISA_DMA
177 select PCI
168 178
169config ARCH_LH7A40X 179config ARCH_LH7A40X
170 bool "Sharp LH7A40X" 180 bool "Sharp LH7A40X"
@@ -252,8 +262,6 @@ config ARM_AMBA
252 262
253config ISA 263config ISA
254 bool 264 bool
255 depends on FOOTBRIDGE_HOST || ARCH_SHARK || ARCH_CLPS7500 || ARCH_EBSA110 || ARCH_CDB89712 || ARCH_EDB7211 || ARCH_SA1100 || ARCH_MX1ADS
256 default y
257 help 265 help
258 Find out whether you have ISA slots on your motherboard. ISA is the 266 Find out whether you have ISA slots on your motherboard. ISA is the
259 name of a bus system, i.e. the way the CPU talks to the other stuff 267 name of a bus system, i.e. the way the CPU talks to the other stuff
@@ -263,12 +271,13 @@ config ISA
263 271
264config ISA_DMA 272config ISA_DMA
265 bool 273 bool
266 depends on FOOTBRIDGE_HOST || ARCH_SHARK 274
275config ISA_DMA_API
276 bool
267 default y 277 default y
268 278
269config PCI 279config PCI
270 bool "PCI support" if ARCH_INTEGRATOR_AP 280 bool "PCI support" if ARCH_INTEGRATOR_AP
271 default y if ARCH_SHARK || FOOTBRIDGE_HOST || ARCH_IOP3XX || ARCH_IXP4XX || ARCH_IXP2000
272 help 281 help
273 Find out whether you have a PCI motherboard. PCI is the name of a 282 Find out whether you have a PCI motherboard. PCI is the name of a
274 bus system, i.e. the way the CPU talks to the other stuff inside 283 bus system, i.e. the way the CPU talks to the other stuff inside
@@ -296,7 +305,7 @@ menu "Kernel Features"
296 305
297config SMP 306config SMP
298 bool "Symmetric Multi-Processing (EXPERIMENTAL)" 307 bool "Symmetric Multi-Processing (EXPERIMENTAL)"
299 depends on EXPERIMENTAL && n 308 depends on EXPERIMENTAL #&& n
300 help 309 help
301 This enables support for systems with more than one CPU. If you have 310 This enables support for systems with more than one CPU. If you have
302 a system with only one CPU, like most personal computers, say N. If 311 a system with only one CPU, like most personal computers, say N. If
@@ -336,8 +345,7 @@ config PREEMPT
336 345
337config DISCONTIGMEM 346config DISCONTIGMEM
338 bool 347 bool
339 depends on ARCH_EDB7211 || ARCH_SA1100 || (ARCH_LH7A40X && !LH7A40X_CONTIGMEM) 348 default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM)
340 default y
341 help 349 help
342 Say Y to support efficient handling of discontiguous physical memory, 350 Say Y to support efficient handling of discontiguous physical memory,
343 for architectures which are either NUMA (Non-Uniform Memory Access) 351 for architectures which are either NUMA (Non-Uniform Memory Access)
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index c0e7aff3dec2..7c7f475e213e 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -18,48 +18,30 @@
18 * Please select one of the following when turning on debugging. 18 * Please select one of the following when turning on debugging.
19 */ 19 */
20#ifdef DEBUG 20#ifdef DEBUG
21#if defined(CONFIG_DEBUG_DC21285_PORT) 21
22 .macro loadsp, rb 22#include <asm/arch/debug-macro.S>
23 mov \rb, #0x42000000 23
24 .endm 24#if defined(CONFIG_DEBUG_ICEDCC)
25 .macro writeb, rb
26 str \rb, [r3, #0x160]
27 .endm
28#elif defined(CONFIG_DEBUG_ICEDCC)
29 .macro loadsp, rb 25 .macro loadsp, rb
30 .endm 26 .endm
31 .macro writeb, rb 27 .macro writeb, ch, rb
32 mcr p14, 0, \rb, c0, c1, 0 28 mcr p14, 0, \ch, c0, c1, 0
33 .endm
34#elif defined(CONFIG_FOOTBRIDGE)
35 .macro loadsp, rb
36 mov \rb, #0x7c000000
37 .endm 29 .endm
38 .macro writeb, rb 30#else
39 strb \rb, [r3, #0x3f8] 31 .macro writeb, ch, rb
32 senduart \ch, \rb
40 .endm 33 .endm
41#elif defined(CONFIG_ARCH_RPC) 34
35#if defined(CONFIG_FOOTBRIDGE) || \
36 defined(CONFIG_ARCH_RPC) || \
37 defined(CONFIG_ARCH_INTEGRATOR) || \
38 defined(CONFIG_ARCH_PXA) || \
39 defined(CONFIG_ARCH_IXP4XX) || \
40 defined(CONFIG_ARCH_IXP2000) || \
41 defined(CONFIG_ARCH_LH7A40X) || \
42 defined(CONFIG_ARCH_OMAP)
42 .macro loadsp, rb 43 .macro loadsp, rb
43 mov \rb, #0x03000000 44 addruart \rb
44 orr \rb, \rb, #0x00010000
45 .endm
46 .macro writeb, rb
47 strb \rb, [r3, #0x3f8 << 2]
48 .endm
49#elif defined(CONFIG_ARCH_INTEGRATOR)
50 .macro loadsp, rb
51 mov \rb, #0x16000000
52 .endm
53 .macro writeb, rb
54 strb \rb, [r3, #0]
55 .endm
56#elif defined(CONFIG_ARCH_PXA) /* Xscale-type */
57 .macro loadsp, rb
58 mov \rb, #0x40000000
59 orr \rb, \rb, #0x00100000
60 .endm
61 .macro writeb, rb
62 strb \rb, [r3, #0]
63 .endm 45 .endm
64#elif defined(CONFIG_ARCH_SA1100) 46#elif defined(CONFIG_ARCH_SA1100)
65 .macro loadsp, rb 47 .macro loadsp, rb
@@ -70,65 +52,22 @@
70 add \rb, \rb, #0x00010000 @ Ser1 52 add \rb, \rb, #0x00010000 @ Ser1
71# endif 53# endif
72 .endm 54 .endm
73 .macro writeb, rb
74 str \rb, [r3, #0x14] @ UTDR
75 .endm
76#elif defined(CONFIG_ARCH_IXP4XX)
77 .macro loadsp, rb
78 mov \rb, #0xc8000000
79 .endm
80 .macro writeb, rb
81 str \rb, [r3, #0]
82#elif defined(CONFIG_ARCH_IXP2000)
83 .macro loadsp, rb
84 mov \rb, #0xc0000000
85 orr \rb, \rb, #0x00030000
86 .endm
87 .macro writeb, rb
88 str \rb, [r3, #0]
89 .endm
90#elif defined(CONFIG_ARCH_LH7A40X)
91 .macro loadsp, rb
92 ldr \rb, =0x80000700 @ UART2 UARTBASE
93 .endm
94 .macro writeb, rb
95 strb \rb, [r3, #0]
96 .endm
97#elif defined(CONFIG_ARCH_OMAP)
98 .macro loadsp, rb
99 mov \rb, #0xff000000 @ physical base address
100 add \rb, \rb, #0x00fb0000
101#if defined(CONFIG_OMAP_LL_DEBUG_UART2) || defined(CONFIG_OMAP_LL_DEBUG_UART3)
102 add \rb, \rb, #0x00000800
103#endif
104#ifdef CONFIG_OMAP_LL_DEBUG_UART3
105 add \rb, \rb, #0x00009000
106#endif
107 .endm
108 .macro writeb, rb
109 strb \rb, [r3]
110 .endm
111#elif defined(CONFIG_ARCH_IOP331) 55#elif defined(CONFIG_ARCH_IOP331)
112 .macro loadsp, rb 56 .macro loadsp, rb
113 mov \rb, #0xff000000 57 mov \rb, #0xff000000
114 orr \rb, \rb, #0x00ff0000 58 orr \rb, \rb, #0x00ff0000
115 orr \rb, \rb, #0x0000f700 @ location of the UART 59 orr \rb, \rb, #0x0000f700 @ location of the UART
116 .endm 60 .endm
117 .macro writeb, rb
118 str \rb, [r3, #0]
119 .endm
120#elif defined(CONFIG_ARCH_S3C2410) 61#elif defined(CONFIG_ARCH_S3C2410)
121 .macro loadsp, rb 62 .macro loadsp, rb
122 mov \rb, #0x50000000 63 mov \rb, #0x50000000
123 add \rb, \rb, #0x4000 * CONFIG_S3C2410_LOWLEVEL_UART_PORT 64 add \rb, \rb, #0x4000 * CONFIG_S3C2410_LOWLEVEL_UART_PORT
124 .endm 65 .endm
125 .macro writeb, rb
126 strb \rb, [r3, #0x20]
127 .endm
128#else 66#else
129#error no serial architecture defined 67#error no serial architecture defined
130#endif 68#endif
131#endif 69#endif
70#endif
132 71
133 .macro kputc,val 72 .macro kputc,val
134 mov r0, \val 73 mov r0, \val
@@ -734,7 +673,7 @@ puts: loadsp r3
7341: ldrb r2, [r0], #1 6731: ldrb r2, [r0], #1
735 teq r2, #0 674 teq r2, #0
736 moveq pc, lr 675 moveq pc, lr
7372: writeb r2 6762: writeb r2, r3
738 mov r1, #0x00020000 677 mov r1, #0x00020000
7393: subs r1, r1, #1 6783: subs r1, r1, #1
740 bne 3b 679 bne 3b
diff --git a/arch/arm/common/rtctime.c b/arch/arm/common/rtctime.c
index c397e71f938d..72b03f201eb9 100644
--- a/arch/arm/common/rtctime.c
+++ b/arch/arm/common/rtctime.c
@@ -141,10 +141,10 @@ void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, struct rtc
141 next->tm_sec = alrm->tm_sec; 141 next->tm_sec = alrm->tm_sec;
142} 142}
143 143
144static inline void rtc_read_time(struct rtc_ops *ops, struct rtc_time *tm) 144static inline int rtc_read_time(struct rtc_ops *ops, struct rtc_time *tm)
145{ 145{
146 memset(tm, 0, sizeof(struct rtc_time)); 146 memset(tm, 0, sizeof(struct rtc_time));
147 ops->read_time(tm); 147 return ops->read_time(tm);
148} 148}
149 149
150static inline int rtc_set_time(struct rtc_ops *ops, struct rtc_time *tm) 150static inline int rtc_set_time(struct rtc_ops *ops, struct rtc_time *tm)
@@ -163,8 +163,7 @@ static inline int rtc_read_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm)
163 int ret = -EINVAL; 163 int ret = -EINVAL;
164 if (ops->read_alarm) { 164 if (ops->read_alarm) {
165 memset(alrm, 0, sizeof(struct rtc_wkalrm)); 165 memset(alrm, 0, sizeof(struct rtc_wkalrm));
166 ops->read_alarm(alrm); 166 ret = ops->read_alarm(alrm);
167 ret = 0;
168 } 167 }
169 return ret; 168 return ret;
170} 169}
@@ -283,7 +282,9 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
283 break; 282 break;
284 283
285 case RTC_RD_TIME: 284 case RTC_RD_TIME:
286 rtc_read_time(ops, &tm); 285 ret = rtc_read_time(ops, &tm);
286 if (ret)
287 break;
287 ret = copy_to_user(uarg, &tm, sizeof(tm)); 288 ret = copy_to_user(uarg, &tm, sizeof(tm));
288 if (ret) 289 if (ret)
289 ret = -EFAULT; 290 ret = -EFAULT;
@@ -424,15 +425,15 @@ static int rtc_read_proc(char *page, char **start, off_t off, int count, int *eo
424 struct rtc_time tm; 425 struct rtc_time tm;
425 char *p = page; 426 char *p = page;
426 427
427 rtc_read_time(ops, &tm); 428 if (rtc_read_time(ops, &tm) == 0) {
428 429 p += sprintf(p,
429 p += sprintf(p, 430 "rtc_time\t: %02d:%02d:%02d\n"
430 "rtc_time\t: %02d:%02d:%02d\n" 431 "rtc_date\t: %04d-%02d-%02d\n"
431 "rtc_date\t: %04d-%02d-%02d\n" 432 "rtc_epoch\t: %04lu\n",
432 "rtc_epoch\t: %04lu\n", 433 tm.tm_hour, tm.tm_min, tm.tm_sec,
433 tm.tm_hour, tm.tm_min, tm.tm_sec, 434 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
434 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, 435 rtc_epoch);
435 rtc_epoch); 436 }
436 437
437 if (rtc_read_alarm(ops, &alrm) == 0) { 438 if (rtc_read_alarm(ops, &alrm) == 0) {
438 p += sprintf(p, "alrm_time\t: "); 439 p += sprintf(p, "alrm_time\t: ");
diff --git a/arch/arm/configs/ixdp2800_defconfig b/arch/arm/configs/ixdp2800_defconfig
index d36f99192962..7be3521f91fc 100644
--- a/arch/arm/configs/ixdp2800_defconfig
+++ b/arch/arm/configs/ixdp2800_defconfig
@@ -133,7 +133,7 @@ CONFIG_ALIGNMENT_TRAP=y
133# 133#
134CONFIG_ZBOOT_ROM_TEXT=0x0 134CONFIG_ZBOOT_ROM_TEXT=0x0
135CONFIG_ZBOOT_ROM_BSS=0x0 135CONFIG_ZBOOT_ROM_BSS=0x0
136CONFIG_CMDLINE="console=ttyS0,9600 root=/dev/nfs ip=bootp mem=64M@0x0 pci=firmware" 136CONFIG_CMDLINE="console=ttyS0,9600 root=/dev/nfs ip=bootp mem=64M@0x0"
137# CONFIG_XIP_KERNEL is not set 137# CONFIG_XIP_KERNEL is not set
138 138
139# 139#
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 07a56ff61494..4a2af55e134b 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -31,8 +31,3 @@ head-y := head.o
31obj-$(CONFIG_DEBUG_LL) += debug.o 31obj-$(CONFIG_DEBUG_LL) += debug.o
32 32
33extra-y := $(head-y) init_task.o vmlinux.lds 33extra-y := $(head-y) init_task.o vmlinux.lds
34
35# Spell out some dependencies that aren't automatically figured out
36$(obj)/entry-armv.o: $(obj)/entry-header.S include/asm-arm/constants.h
37$(obj)/entry-common.o: $(obj)/entry-header.S include/asm-arm/constants.h \
38 $(obj)/calls.S
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index 99d43259ff89..c1ff4d1f1bfd 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -64,6 +64,26 @@ int main(void)
64 DEFINE(TI_VFPSTATE, offsetof(struct thread_info, vfpstate)); 64 DEFINE(TI_VFPSTATE, offsetof(struct thread_info, vfpstate));
65 DEFINE(TI_IWMMXT_STATE, (offsetof(struct thread_info, fpstate)+4)&~7); 65 DEFINE(TI_IWMMXT_STATE, (offsetof(struct thread_info, fpstate)+4)&~7);
66 BLANK(); 66 BLANK();
67 DEFINE(S_R0, offsetof(struct pt_regs, ARM_r0));
68 DEFINE(S_R1, offsetof(struct pt_regs, ARM_r1));
69 DEFINE(S_R2, offsetof(struct pt_regs, ARM_r2));
70 DEFINE(S_R3, offsetof(struct pt_regs, ARM_r3));
71 DEFINE(S_R4, offsetof(struct pt_regs, ARM_r4));
72 DEFINE(S_R5, offsetof(struct pt_regs, ARM_r5));
73 DEFINE(S_R6, offsetof(struct pt_regs, ARM_r6));
74 DEFINE(S_R7, offsetof(struct pt_regs, ARM_r7));
75 DEFINE(S_R8, offsetof(struct pt_regs, ARM_r8));
76 DEFINE(S_R9, offsetof(struct pt_regs, ARM_r9));
77 DEFINE(S_R10, offsetof(struct pt_regs, ARM_r10));
78 DEFINE(S_FP, offsetof(struct pt_regs, ARM_fp));
79 DEFINE(S_IP, offsetof(struct pt_regs, ARM_ip));
80 DEFINE(S_SP, offsetof(struct pt_regs, ARM_sp));
81 DEFINE(S_LR, offsetof(struct pt_regs, ARM_lr));
82 DEFINE(S_PC, offsetof(struct pt_regs, ARM_pc));
83 DEFINE(S_PSR, offsetof(struct pt_regs, ARM_cpsr));
84 DEFINE(S_OLD_R0, offsetof(struct pt_regs, ARM_ORIG_r0));
85 DEFINE(S_FRAME_SIZE, sizeof(struct pt_regs));
86 BLANK();
67#if __LINUX_ARM_ARCH__ >= 6 87#if __LINUX_ARM_ARCH__ >= 6
68 DEFINE(MM_CONTEXT_ID, offsetof(struct mm_struct, context.id)); 88 DEFINE(MM_CONTEXT_ID, offsetof(struct mm_struct, context.id));
69 BLANK(); 89 BLANK();
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index bb27c317d94b..4eb36155dc93 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -14,12 +14,12 @@
14 * it to save wrong values... Be aware! 14 * it to save wrong values... Be aware!
15 */ 15 */
16#include <linux/config.h> 16#include <linux/config.h>
17#include <linux/init.h>
18 17
19#include <asm/thread_info.h>
20#include <asm/glue.h> 18#include <asm/glue.h>
21#include <asm/ptrace.h>
22#include <asm/vfpmacros.h> 19#include <asm/vfpmacros.h>
20#include <asm/hardware.h> /* should be moved into entry-macro.S */
21#include <asm/arch/irqs.h> /* should be moved into entry-macro.S */
22#include <asm/arch/entry-macro.S>
23 23
24#include "entry-header.S" 24#include "entry-header.S"
25 25
@@ -118,7 +118,7 @@ __dabt_svc:
118 @ 118 @
119 @ IRQs off again before pulling preserved data off the stack 119 @ IRQs off again before pulling preserved data off the stack
120 @ 120 @
121 disable_irq r0 121 disable_irq
122 122
123 @ 123 @
124 @ restore SPSR and restart the instruction 124 @ restore SPSR and restart the instruction
@@ -198,7 +198,7 @@ __und_svc:
198 @ 198 @
199 @ IRQs off again before pulling preserved data off the stack 199 @ IRQs off again before pulling preserved data off the stack
200 @ 200 @
2011: disable_irq r0 2011: disable_irq
202 202
203 @ 203 @
204 @ restore SPSR and restart the instruction 204 @ restore SPSR and restart the instruction
@@ -232,7 +232,7 @@ __pabt_svc:
232 @ 232 @
233 @ IRQs off again before pulling preserved data off the stack 233 @ IRQs off again before pulling preserved data off the stack
234 @ 234 @
235 disable_irq r0 235 disable_irq
236 236
237 @ 237 @
238 @ restore SPSR and restart the instruction 238 @ restore SPSR and restart the instruction
@@ -269,6 +269,12 @@ __pabt_svc:
269 add r5, sp, #S_PC 269 add r5, sp, #S_PC
270 ldmia r7, {r2 - r4} @ Get USR pc, cpsr 270 ldmia r7, {r2 - r4} @ Get USR pc, cpsr
271 271
272#if __LINUX_ARM_ARCH__ < 6
273 @ make sure our user space atomic helper is aborted
274 cmp r2, #VIRT_OFFSET
275 bichs r3, r3, #PSR_Z_BIT
276#endif
277
272 @ 278 @
273 @ We are now ready to fill in the remaining blanks on the stack: 279 @ We are now ready to fill in the remaining blanks on the stack:
274 @ 280 @
@@ -316,7 +322,7 @@ __dabt_usr:
316 @ 322 @
317 @ IRQs on, then call the main handler 323 @ IRQs on, then call the main handler
318 @ 324 @
319 enable_irq r2 325 enable_irq
320 mov r2, sp 326 mov r2, sp
321 adr lr, ret_from_exception 327 adr lr, ret_from_exception
322 b do_DataAbort 328 b do_DataAbort
@@ -418,7 +424,7 @@ call_fpe:
418 movcss r7, r5, lsr #(TIF_USING_IWMMXT + 1) 424 movcss r7, r5, lsr #(TIF_USING_IWMMXT + 1)
419 bcs iwmmxt_task_enable 425 bcs iwmmxt_task_enable
420#endif 426#endif
421 enable_irq r7 427 enable_irq
422 add pc, pc, r8, lsr #6 428 add pc, pc, r8, lsr #6
423 mov r0, r0 429 mov r0, r0
424 430
@@ -472,7 +478,7 @@ fpundefinstr:
472__pabt_usr: 478__pabt_usr:
473 usr_entry abt 479 usr_entry abt
474 480
475 enable_irq r0 @ Enable interrupts 481 enable_irq @ Enable interrupts
476 mov r0, r2 @ address (pc) 482 mov r0, r2 @ address (pc)
477 mov r1, sp @ regs 483 mov r1, sp @ regs
478 bl do_PrefetchAbort @ call abort handler 484 bl do_PrefetchAbort @ call abort handler
@@ -499,8 +505,12 @@ ENTRY(__switch_to)
499 mra r4, r5, acc0 505 mra r4, r5, acc0
500 stmia ip, {r4, r5} 506 stmia ip, {r4, r5}
501#endif 507#endif
508#if defined(CONFIG_HAS_TLS_REG)
509 mcr p15, 0, r3, c13, c0, 3 @ set TLS register
510#elif !defined(CONFIG_TLS_REG_EMUL)
502 mov r4, #0xffff0fff 511 mov r4, #0xffff0fff
503 str r3, [r4, #-3] @ Set TLS ptr 512 str r3, [r4, #-15] @ TLS val at 0xffff0ff0
513#endif
504 mcr p15, 0, r6, c3, c0, 0 @ Set domain register 514 mcr p15, 0, r6, c3, c0, 0 @ Set domain register
505#ifdef CONFIG_VFP 515#ifdef CONFIG_VFP
506 @ Always disable VFP so we can lazily save/restore the old 516 @ Always disable VFP so we can lazily save/restore the old
@@ -519,11 +529,209 @@ ENTRY(__switch_to)
519 ldmib r2, {r4 - sl, fp, sp, pc} @ Load all regs saved previously 529 ldmib r2, {r4 - sl, fp, sp, pc} @ Load all regs saved previously
520 530
521 __INIT 531 __INIT
532
533/*
534 * User helpers.
535 *
536 * These are segment of kernel provided user code reachable from user space
537 * at a fixed address in kernel memory. This is used to provide user space
538 * with some operations which require kernel help because of unimplemented
539 * native feature and/or instructions in many ARM CPUs. The idea is for
540 * this code to be executed directly in user mode for best efficiency but
541 * which is too intimate with the kernel counter part to be left to user
542 * libraries. In fact this code might even differ from one CPU to another
543 * depending on the available instruction set and restrictions like on
544 * SMP systems. In other words, the kernel reserves the right to change
545 * this code as needed without warning. Only the entry points and their
546 * results are guaranteed to be stable.
547 *
548 * Each segment is 32-byte aligned and will be moved to the top of the high
549 * vector page. New segments (if ever needed) must be added in front of
550 * existing ones. This mechanism should be used only for things that are
551 * really small and justified, and not be abused freely.
552 *
553 * User space is expected to implement those things inline when optimizing
554 * for a processor that has the necessary native support, but only if such
555 * resulting binaries are already to be incompatible with earlier ARM
556 * processors due to the use of unsupported instructions other than what
557 * is provided here. In other words don't make binaries unable to run on
558 * earlier processors just for the sake of not using these kernel helpers
559 * if your compiled code is not going to use the new instructions for other
560 * purpose.
561 */
562
563 .align 5
564 .globl __kuser_helper_start
565__kuser_helper_start:
566
567/*
568 * Reference prototype:
569 *
570 * int __kernel_cmpxchg(int oldval, int newval, int *ptr)
571 *
572 * Input:
573 *
574 * r0 = oldval
575 * r1 = newval
576 * r2 = ptr
577 * lr = return address
578 *
579 * Output:
580 *
581 * r0 = returned value (zero or non-zero)
582 * C flag = set if r0 == 0, clear if r0 != 0
583 *
584 * Clobbered:
585 *
586 * r3, ip, flags
587 *
588 * Definition and user space usage example:
589 *
590 * typedef int (__kernel_cmpxchg_t)(int oldval, int newval, int *ptr);
591 * #define __kernel_cmpxchg (*(__kernel_cmpxchg_t *)0xffff0fc0)
592 *
593 * Atomically store newval in *ptr if *ptr is equal to oldval for user space.
594 * Return zero if *ptr was changed or non-zero if no exchange happened.
595 * The C flag is also set if *ptr was changed to allow for assembly
596 * optimization in the calling code.
597 *
598 * For example, a user space atomic_add implementation could look like this:
599 *
600 * #define atomic_add(ptr, val) \
601 * ({ register unsigned int *__ptr asm("r2") = (ptr); \
602 * register unsigned int __result asm("r1"); \
603 * asm volatile ( \
604 * "1: @ atomic_add\n\t" \
605 * "ldr r0, [r2]\n\t" \
606 * "mov r3, #0xffff0fff\n\t" \
607 * "add lr, pc, #4\n\t" \
608 * "add r1, r0, %2\n\t" \
609 * "add pc, r3, #(0xffff0fc0 - 0xffff0fff)\n\t" \
610 * "bcc 1b" \
611 * : "=&r" (__result) \
612 * : "r" (__ptr), "rIL" (val) \
613 * : "r0","r3","ip","lr","cc","memory" ); \
614 * __result; })
615 */
616
617__kuser_cmpxchg: @ 0xffff0fc0
618
619#if __LINUX_ARM_ARCH__ < 6
620
621#ifdef CONFIG_SMP /* sanity check */
622#error "CONFIG_SMP on a machine supporting pre-ARMv6 processors?"
623#endif
624
625 /*
626 * Theory of operation:
627 *
628 * We set the Z flag before loading oldval. If ever an exception
629 * occurs we can not be sure the loaded value will still be the same
630 * when the exception returns, therefore the user exception handler
631 * will clear the Z flag whenever the interrupted user code was
632 * actually from the kernel address space (see the usr_entry macro).
633 *
634 * The post-increment on the str is used to prevent a race with an
635 * exception happening just after the str instruction which would
636 * clear the Z flag although the exchange was done.
637 */
638 teq ip, ip @ set Z flag
639 ldr ip, [r2] @ load current val
640 add r3, r2, #1 @ prepare store ptr
641 teqeq ip, r0 @ compare with oldval if still allowed
642 streq r1, [r3, #-1]! @ store newval if still allowed
643 subs r0, r2, r3 @ if r2 == r3 the str occured
644 mov pc, lr
645
646#else
647
648 ldrex r3, [r2]
649 subs r3, r3, r0
650 strexeq r3, r1, [r2]
651 rsbs r0, r3, #0
652 mov pc, lr
653
654#endif
655
656 .align 5
657
658/*
659 * Reference prototype:
660 *
661 * int __kernel_get_tls(void)
662 *
663 * Input:
664 *
665 * lr = return address
666 *
667 * Output:
668 *
669 * r0 = TLS value
670 *
671 * Clobbered:
672 *
673 * the Z flag might be lost
674 *
675 * Definition and user space usage example:
676 *
677 * typedef int (__kernel_get_tls_t)(void);
678 * #define __kernel_get_tls (*(__kernel_get_tls_t *)0xffff0fe0)
679 *
680 * Get the TLS value as previously set via the __ARM_NR_set_tls syscall.
681 *
682 * This could be used as follows:
683 *
684 * #define __kernel_get_tls() \
685 * ({ register unsigned int __val asm("r0"); \
686 * asm( "mov r0, #0xffff0fff; mov lr, pc; sub pc, r0, #31" \
687 * : "=r" (__val) : : "lr","cc" ); \
688 * __val; })
689 */
690
691__kuser_get_tls: @ 0xffff0fe0
692
693#if !defined(CONFIG_HAS_TLS_REG) && !defined(CONFIG_TLS_REG_EMUL)
694
695 ldr r0, [pc, #(16 - 8)] @ TLS stored at 0xffff0ff0
696 mov pc, lr
697
698#else
699
700 mrc p15, 0, r0, c13, c0, 3 @ read TLS register
701 mov pc, lr
702
703#endif
704
705 .rep 5
706 .word 0 @ pad up to __kuser_helper_version
707 .endr
708
709/*
710 * Reference declaration:
711 *
712 * extern unsigned int __kernel_helper_version;
713 *
714 * Definition and user space usage example:
715 *
716 * #define __kernel_helper_version (*(unsigned int *)0xffff0ffc)
717 *
718 * User space may read this to determine the curent number of helpers
719 * available.
720 */
721
722__kuser_helper_version: @ 0xffff0ffc
723 .word ((__kuser_helper_end - __kuser_helper_start) >> 5)
724
725 .globl __kuser_helper_end
726__kuser_helper_end:
727
728
522/* 729/*
523 * Vector stubs. 730 * Vector stubs.
524 * 731 *
525 * This code is copied to 0x200 or 0xffff0200 so we can use branches in the 732 * This code is copied to 0xffff0200 so we can use branches in the
526 * vectors, rather than ldr's. 733 * vectors, rather than ldr's. Note that this code must not
734 * exceed 0x300 bytes.
527 * 735 *
528 * Common stub entry macro: 736 * Common stub entry macro:
529 * Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC 737 * Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
@@ -544,7 +752,7 @@ vector_\name:
544 @ 752 @
545 mrs r13, cpsr 753 mrs r13, cpsr
546 bic r13, r13, #MODE_MASK 754 bic r13, r13, #MODE_MASK
547 orr r13, r13, #MODE_SVC 755 orr r13, r13, #SVC_MODE
548 msr spsr_cxsf, r13 @ switch to SVC_32 mode 756 msr spsr_cxsf, r13 @ switch to SVC_32 mode
549 757
550 and lr, lr, #15 758 and lr, lr, #15
@@ -552,6 +760,7 @@ vector_\name:
552 movs pc, lr @ Changes mode and branches 760 movs pc, lr @ Changes mode and branches
553 .endm 761 .endm
554 762
763 .globl __stubs_start
555__stubs_start: 764__stubs_start:
556/* 765/*
557 * Interrupt dispatcher 766 * Interrupt dispatcher
@@ -686,37 +895,24 @@ vector_addrexcptn:
686.LCsabt: 895.LCsabt:
687 .word __temp_abt 896 .word __temp_abt
688 897
898 .globl __stubs_end
689__stubs_end: 899__stubs_end:
690 900
691 .equ __real_stubs_start, .LCvectors + 0x200 901 .equ stubs_offset, __vectors_start + 0x200 - __stubs_start
692 902
693.LCvectors: 903 .globl __vectors_start
904__vectors_start:
694 swi SYS_ERROR0 905 swi SYS_ERROR0
695 b __real_stubs_start + (vector_und - __stubs_start) 906 b vector_und + stubs_offset
696 ldr pc, __real_stubs_start + (.LCvswi - __stubs_start) 907 ldr pc, .LCvswi + stubs_offset
697 b __real_stubs_start + (vector_pabt - __stubs_start) 908 b vector_pabt + stubs_offset
698 b __real_stubs_start + (vector_dabt - __stubs_start) 909 b vector_dabt + stubs_offset
699 b __real_stubs_start + (vector_addrexcptn - __stubs_start) 910 b vector_addrexcptn + stubs_offset
700 b __real_stubs_start + (vector_irq - __stubs_start) 911 b vector_irq + stubs_offset
701 b __real_stubs_start + (vector_fiq - __stubs_start) 912 b vector_fiq + stubs_offset
702 913
703ENTRY(__trap_init) 914 .globl __vectors_end
704 stmfd sp!, {r4 - r6, lr} 915__vectors_end:
705
706 mov r0, #0xff000000
707 orr r0, r0, #0x00ff0000 @ high vectors position
708 adr r1, .LCvectors @ set up the vectors
709 ldmia r1, {r1, r2, r3, r4, r5, r6, ip, lr}
710 stmia r0, {r1, r2, r3, r4, r5, r6, ip, lr}
711
712 add r2, r0, #0x200
713 adr r0, __stubs_start @ copy stubs to 0x200
714 adr r1, __stubs_end
7151: ldr r3, [r0], #4
716 str r3, [r2], #4
717 cmp r0, r1
718 blt 1b
719 LOADREGS(fd, sp!, {r4 - r6, pc})
720 916
721 .data 917 .data
722 918
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 53a7e0dea44d..3f8d0e3aefab 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -9,19 +9,10 @@
9 */ 9 */
10#include <linux/config.h> 10#include <linux/config.h>
11 11
12#include <asm/thread_info.h>
13#include <asm/ptrace.h>
14#include <asm/unistd.h> 12#include <asm/unistd.h>
15 13
16#include "entry-header.S" 14#include "entry-header.S"
17 15
18/*
19 * We rely on the fact that R0 is at the bottom of the stack (due to
20 * slow/fast restore user regs).
21 */
22#if S_R0 != 0
23#error "Please fix"
24#endif
25 16
26 .align 5 17 .align 5
27/* 18/*
@@ -30,11 +21,19 @@
30 * stack. 21 * stack.
31 */ 22 */
32ret_fast_syscall: 23ret_fast_syscall:
33 disable_irq r1 @ disable interrupts 24 disable_irq @ disable interrupts
34 ldr r1, [tsk, #TI_FLAGS] 25 ldr r1, [tsk, #TI_FLAGS]
35 tst r1, #_TIF_WORK_MASK 26 tst r1, #_TIF_WORK_MASK
36 bne fast_work_pending 27 bne fast_work_pending
37 fast_restore_user_regs 28
29 @ fast_restore_user_regs
30 ldr r1, [sp, #S_OFF + S_PSR] @ get calling cpsr
31 ldr lr, [sp, #S_OFF + S_PC]! @ get pc
32 msr spsr_cxsf, r1 @ save in spsr_svc
33 ldmdb sp, {r1 - lr}^ @ get calling r1 - lr
34 mov r0, r0
35 add sp, sp, #S_FRAME_SIZE - S_PC
36 movs pc, lr @ return & move spsr_svc into cpsr
38 37
39/* 38/*
40 * Ok, we need to do extra processing, enter the slow path. 39 * Ok, we need to do extra processing, enter the slow path.
@@ -49,7 +48,7 @@ work_pending:
49 mov r0, sp @ 'regs' 48 mov r0, sp @ 'regs'
50 mov r2, why @ 'syscall' 49 mov r2, why @ 'syscall'
51 bl do_notify_resume 50 bl do_notify_resume
52 disable_irq r1 @ disable interrupts 51 disable_irq @ disable interrupts
53 b no_work_pending 52 b no_work_pending
54 53
55work_resched: 54work_resched:
@@ -59,12 +58,19 @@ work_resched:
59 */ 58 */
60ENTRY(ret_to_user) 59ENTRY(ret_to_user)
61ret_slow_syscall: 60ret_slow_syscall:
62 disable_irq r1 @ disable interrupts 61 disable_irq @ disable interrupts
63 ldr r1, [tsk, #TI_FLAGS] 62 ldr r1, [tsk, #TI_FLAGS]
64 tst r1, #_TIF_WORK_MASK 63 tst r1, #_TIF_WORK_MASK
65 bne work_pending 64 bne work_pending
66no_work_pending: 65no_work_pending:
67 slow_restore_user_regs 66 @ slow_restore_user_regs
67 ldr r1, [sp, #S_PSR] @ get calling cpsr
68 ldr lr, [sp, #S_PC]! @ get pc
69 msr spsr_cxsf, r1 @ save in spsr_svc
70 ldmdb sp, {r0 - lr}^ @ get calling r1 - lr
71 mov r0, r0
72 add sp, sp, #S_FRAME_SIZE - S_PC
73 movs pc, lr @ return & move spsr_svc into cpsr
68 74
69/* 75/*
70 * This is how we return from a fork. 76 * This is how we return from a fork.
@@ -116,9 +122,26 @@ ENTRY(ret_from_fork)
116 122
117 .align 5 123 .align 5
118ENTRY(vector_swi) 124ENTRY(vector_swi)
119 save_user_regs 125 sub sp, sp, #S_FRAME_SIZE
126 stmia sp, {r0 - r12} @ Calling r0 - r12
127 add r8, sp, #S_PC
128 stmdb r8, {sp, lr}^ @ Calling sp, lr
129 mrs r8, spsr @ called from non-FIQ mode, so ok.
130 str lr, [sp, #S_PC] @ Save calling PC
131 str r8, [sp, #S_PSR] @ Save CPSR
132 str r0, [sp, #S_OLD_R0] @ Save OLD_R0
120 zero_fp 133 zero_fp
121 get_scno 134
135 /*
136 * Get the system call number.
137 */
138#ifdef CONFIG_ARM_THUMB
139 tst r8, #PSR_T_BIT @ this is SPSR from save_user_regs
140 addne scno, r7, #__NR_SYSCALL_BASE @ put OS number in
141 ldreq scno, [lr, #-4]
142#else
143 ldr scno, [lr, #-4] @ get SWI instruction
144#endif
122 arm710_bug_check scno, ip 145 arm710_bug_check scno, ip
123 146
124#ifdef CONFIG_ALIGNMENT_TRAP 147#ifdef CONFIG_ALIGNMENT_TRAP
@@ -126,14 +149,14 @@ ENTRY(vector_swi)
126 ldr ip, [ip] 149 ldr ip, [ip]
127 mcr p15, 0, ip, c1, c0 @ update control register 150 mcr p15, 0, ip, c1, c0 @ update control register
128#endif 151#endif
129 enable_irq ip 152 enable_irq
130 153
131 str r4, [sp, #-S_OFF]! @ push fifth arg 154 str r4, [sp, #-S_OFF]! @ push fifth arg
132 155
133 get_thread_info tsk 156 get_thread_info tsk
134 ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing 157 ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing
135 bic scno, scno, #0xff000000 @ mask off SWI op-code 158 bic scno, scno, #0xff000000 @ mask off SWI op-code
136 eor scno, scno, #OS_NUMBER << 20 @ check OS number 159 eor scno, scno, #__NR_SYSCALL_BASE @ check OS number
137 adr tbl, sys_call_table @ load syscall table pointer 160 adr tbl, sys_call_table @ load syscall table pointer
138 tst ip, #_TIF_SYSCALL_TRACE @ are we tracing syscalls? 161 tst ip, #_TIF_SYSCALL_TRACE @ are we tracing syscalls?
139 bne __sys_trace 162 bne __sys_trace
@@ -144,8 +167,8 @@ ENTRY(vector_swi)
144 167
145 add r1, sp, #S_OFF 168 add r1, sp, #S_OFF
1462: mov why, #0 @ no longer a real syscall 1692: mov why, #0 @ no longer a real syscall
147 cmp scno, #ARMSWI_OFFSET 170 cmp scno, #(__ARM_NR_BASE - __NR_SYSCALL_BASE)
148 eor r0, scno, #OS_NUMBER << 20 @ put OS number back 171 eor r0, scno, #__NR_SYSCALL_BASE @ put OS number back
149 bcs arm_syscall 172 bcs arm_syscall
150 b sys_ni_syscall @ not private func 173 b sys_ni_syscall @ not private func
151 174
@@ -190,7 +213,7 @@ ENTRY(sys_call_table)
190@ r5 = syscall table 213@ r5 = syscall table
191 .type sys_syscall, #function 214 .type sys_syscall, #function
192sys_syscall: 215sys_syscall:
193 eor scno, r0, #OS_NUMBER << 20 216 eor scno, r0, #__NR_SYSCALL_BASE
194 cmp scno, #__NR_syscall - __NR_SYSCALL_BASE 217 cmp scno, #__NR_syscall - __NR_SYSCALL_BASE
195 cmpne scno, #NR_syscalls @ check range 218 cmpne scno, #NR_syscalls @ check range
196 stmloia sp, {r5, r6} @ shuffle args 219 stmloia sp, {r5, r6} @ shuffle args
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
index 4039d8c120b5..a3d40a0e2b04 100644
--- a/arch/arm/kernel/entry-header.S
+++ b/arch/arm/kernel/entry-header.S
@@ -1,24 +1,11 @@
1#include <linux/config.h> /* for CONFIG_ARCH_xxxx */ 1#include <linux/config.h>
2#include <linux/init.h>
2#include <linux/linkage.h> 3#include <linux/linkage.h>
3 4
4#include <asm/assembler.h> 5#include <asm/assembler.h>
5#include <asm/constants.h> 6#include <asm/constants.h>
6#include <asm/errno.h> 7#include <asm/errno.h>
7#include <asm/hardware.h> 8#include <asm/thread_info.h>
8#include <asm/arch/irqs.h>
9#include <asm/arch/entry-macro.S>
10
11#ifndef MODE_SVC
12#define MODE_SVC 0x13
13#endif
14
15 .macro zero_fp
16#ifdef CONFIG_FRAME_POINTER
17 mov fp, #0
18#endif
19 .endm
20
21 .text
22 9
23@ Bad Abort numbers 10@ Bad Abort numbers
24@ ----------------- 11@ -----------------
@@ -29,113 +16,44 @@
29#define BAD_IRQ 3 16#define BAD_IRQ 3
30#define BAD_UNDEFINSTR 4 17#define BAD_UNDEFINSTR 4
31 18
32#define PT_TRACESYS 0x00000002
33
34@ OS version number used in SWIs
35@ RISC OS is 0
36@ RISC iX is 8
37@ 19@
38#define OS_NUMBER 9 20@ Most of the stack format comes from struct pt_regs, but with
39#define ARMSWI_OFFSET 0x000f0000 21@ the addition of 8 bytes for storing syscall args 5 and 6.
40
41@ 22@
42@ Stack format (ensured by USER_* and SVC_*)
43@
44#define S_FRAME_SIZE 72
45#define S_OLD_R0 68
46#define S_PSR 64
47
48#define S_PC 60
49#define S_LR 56
50#define S_SP 52
51#define S_IP 48
52#define S_FP 44
53#define S_R10 40
54#define S_R9 36
55#define S_R8 32
56#define S_R7 28
57#define S_R6 24
58#define S_R5 20
59#define S_R4 16
60#define S_R3 12
61#define S_R2 8
62#define S_R1 4
63#define S_R0 0
64#define S_OFF 8 23#define S_OFF 8
65 24
66 .macro set_cpsr_c, reg, mode 25/*
67 msr cpsr_c, \mode 26 * The SWI code relies on the fact that R0 is at the bottom of the stack
27 * (due to slow/fast restore user regs).
28 */
29#if S_R0 != 0
30#error "Please fix"
31#endif
32
33 .macro zero_fp
34#ifdef CONFIG_FRAME_POINTER
35 mov fp, #0
36#endif
68 .endm 37 .endm
69 38
70#if __LINUX_ARM_ARCH__ >= 6 39#if __LINUX_ARM_ARCH__ >= 6
71 .macro disable_irq, temp 40 .macro disable_irq
72 cpsid i 41 cpsid i
73 .endm 42 .endm
74 43
75 .macro enable_irq, temp 44 .macro enable_irq
76 cpsie i 45 cpsie i
77 .endm 46 .endm
78#else 47#else
79 .macro disable_irq, temp 48 .macro disable_irq
80 set_cpsr_c \temp, #PSR_I_BIT | MODE_SVC 49 msr cpsr_c, #PSR_I_BIT | SVC_MODE
81 .endm 50 .endm
82 51
83 .macro enable_irq, temp 52 .macro enable_irq
84 set_cpsr_c \temp, #MODE_SVC 53 msr cpsr_c, #SVC_MODE
85 .endm 54 .endm
86#endif 55#endif
87 56
88 .macro save_user_regs
89 sub sp, sp, #S_FRAME_SIZE
90 stmia sp, {r0 - r12} @ Calling r0 - r12
91 add r8, sp, #S_PC
92 stmdb r8, {sp, lr}^ @ Calling sp, lr
93 mrs r8, spsr @ called from non-FIQ mode, so ok.
94 str lr, [sp, #S_PC] @ Save calling PC
95 str r8, [sp, #S_PSR] @ Save CPSR
96 str r0, [sp, #S_OLD_R0] @ Save OLD_R0
97 .endm
98
99 .macro restore_user_regs
100 ldr r1, [sp, #S_PSR] @ Get calling cpsr
101 disable_irq ip @ disable IRQs
102 ldr lr, [sp, #S_PC]! @ Get PC
103 msr spsr_cxsf, r1 @ save in spsr_svc
104 ldmdb sp, {r0 - lr}^ @ Get calling r0 - lr
105 mov r0, r0
106 add sp, sp, #S_FRAME_SIZE - S_PC
107 movs pc, lr @ return & move spsr_svc into cpsr
108 .endm
109
110/*
111 * Must be called with IRQs already disabled.
112 */
113 .macro fast_restore_user_regs
114 ldr r1, [sp, #S_OFF + S_PSR] @ get calling cpsr
115 ldr lr, [sp, #S_OFF + S_PC]! @ get pc
116 msr spsr_cxsf, r1 @ save in spsr_svc
117 ldmdb sp, {r1 - lr}^ @ get calling r1 - lr
118 mov r0, r0
119 add sp, sp, #S_FRAME_SIZE - S_PC
120 movs pc, lr @ return & move spsr_svc into cpsr
121 .endm
122
123/*
124 * Must be called with IRQs already disabled.
125 */
126 .macro slow_restore_user_regs
127 ldr r1, [sp, #S_PSR] @ get calling cpsr
128 ldr lr, [sp, #S_PC]! @ get pc
129 msr spsr_cxsf, r1 @ save in spsr_svc
130 ldmdb sp, {r0 - lr}^ @ get calling r1 - lr
131 mov r0, r0
132 add sp, sp, #S_FRAME_SIZE - S_PC
133 movs pc, lr @ return & move spsr_svc into cpsr
134 .endm
135
136 .macro mask_pc, rd, rm
137 .endm
138
139 .macro get_thread_info, rd 57 .macro get_thread_info, rd
140 mov \rd, sp, lsr #13 58 mov \rd, sp, lsr #13
141 mov \rd, \rd, lsl #13 59 mov \rd, \rd, lsl #13
@@ -165,18 +83,3 @@ scno .req r7 @ syscall number
165tbl .req r8 @ syscall table pointer 83tbl .req r8 @ syscall table pointer
166why .req r8 @ Linux syscall (!= 0) 84why .req r8 @ Linux syscall (!= 0)
167tsk .req r9 @ current thread_info 85tsk .req r9 @ current thread_info
168
169/*
170 * Get the system call number.
171 */
172 .macro get_scno
173#ifdef CONFIG_ARM_THUMB
174 tst r8, #PSR_T_BIT @ this is SPSR from save_user_regs
175 addne scno, r7, #OS_NUMBER << 20 @ put OS number in
176 ldreq scno, [lr, #-4]
177
178#else
179 mask_pc lr, lr
180 ldr scno, [lr, #-4] @ get SWI instruction
181#endif
182 .endm
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 171b3e811c71..4733877296d4 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -19,6 +19,7 @@
19#include <asm/procinfo.h> 19#include <asm/procinfo.h>
20#include <asm/ptrace.h> 20#include <asm/ptrace.h>
21#include <asm/constants.h> 21#include <asm/constants.h>
22#include <asm/thread_info.h>
22#include <asm/system.h> 23#include <asm/system.h>
23 24
24#define PROCINFO_MMUFLAGS 8 25#define PROCINFO_MMUFLAGS 8
@@ -131,7 +132,7 @@ __switch_data:
131 .long processor_id @ r4 132 .long processor_id @ r4
132 .long __machine_arch_type @ r5 133 .long __machine_arch_type @ r5
133 .long cr_alignment @ r6 134 .long cr_alignment @ r6
134 .long init_thread_union+8192 @ sp 135 .long init_thread_union + THREAD_START_SP @ sp
135 136
136/* 137/*
137 * The following fragment of code is executed with the MMU on, and uses 138 * The following fragment of code is executed with the MMU on, and uses
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 26eacd3e5def..8f146a4b4752 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -256,8 +256,6 @@ static unsigned long *thread_info_head;
256static unsigned int nr_thread_info; 256static unsigned int nr_thread_info;
257 257
258#define EXTRA_TASK_STRUCT 4 258#define EXTRA_TASK_STRUCT 4
259#define ll_alloc_task_struct() ((struct thread_info *) __get_free_pages(GFP_KERNEL,1))
260#define ll_free_task_struct(p) free_pages((unsigned long)(p),1)
261 259
262struct thread_info *alloc_thread_info(struct task_struct *task) 260struct thread_info *alloc_thread_info(struct task_struct *task)
263{ 261{
@@ -274,17 +272,16 @@ struct thread_info *alloc_thread_info(struct task_struct *task)
274 } 272 }
275 273
276 if (!thread) 274 if (!thread)
277 thread = ll_alloc_task_struct(); 275 thread = (struct thread_info *)
276 __get_free_pages(GFP_KERNEL, THREAD_SIZE_ORDER);
278 277
279#ifdef CONFIG_MAGIC_SYSRQ 278#ifdef CONFIG_DEBUG_STACK_USAGE
280 /* 279 /*
281 * The stack must be cleared if you want SYSRQ-T to 280 * The stack must be cleared if you want SYSRQ-T to
282 * give sensible stack usage information 281 * give sensible stack usage information
283 */ 282 */
284 if (thread) { 283 if (thread)
285 char *p = (char *)thread; 284 memzero(thread, THREAD_SIZE);
286 memzero(p+KERNEL_STACK_SIZE, KERNEL_STACK_SIZE);
287 }
288#endif 285#endif
289 return thread; 286 return thread;
290} 287}
@@ -297,7 +294,7 @@ void free_thread_info(struct thread_info *thread)
297 thread_info_head = p; 294 thread_info_head = p;
298 nr_thread_info += 1; 295 nr_thread_info += 1;
299 } else 296 } else
300 ll_free_task_struct(thread); 297 free_pages((unsigned long)thread, THREAD_SIZE_ORDER);
301} 298}
302 299
303/* 300/*
@@ -350,7 +347,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long stack_start,
350 struct thread_info *thread = p->thread_info; 347 struct thread_info *thread = p->thread_info;
351 struct pt_regs *childregs; 348 struct pt_regs *childregs;
352 349
353 childregs = ((struct pt_regs *)((unsigned long)thread + THREAD_SIZE - 8)) - 1; 350 childregs = ((struct pt_regs *)((unsigned long)thread + THREAD_START_SP)) - 1;
354 *childregs = *regs; 351 *childregs = *regs;
355 childregs->ARM_r0 = 0; 352 childregs->ARM_r0 = 0;
356 childregs->ARM_sp = stack_start; 353 childregs->ARM_sp = stack_start;
@@ -447,15 +444,17 @@ EXPORT_SYMBOL(kernel_thread);
447unsigned long get_wchan(struct task_struct *p) 444unsigned long get_wchan(struct task_struct *p)
448{ 445{
449 unsigned long fp, lr; 446 unsigned long fp, lr;
450 unsigned long stack_page; 447 unsigned long stack_start, stack_end;
451 int count = 0; 448 int count = 0;
452 if (!p || p == current || p->state == TASK_RUNNING) 449 if (!p || p == current || p->state == TASK_RUNNING)
453 return 0; 450 return 0;
454 451
455 stack_page = 4096 + (unsigned long)p->thread_info; 452 stack_start = (unsigned long)(p->thread_info + 1);
453 stack_end = ((unsigned long)p->thread_info) + THREAD_SIZE;
454
456 fp = thread_saved_fp(p); 455 fp = thread_saved_fp(p);
457 do { 456 do {
458 if (fp < stack_page || fp > 4092+stack_page) 457 if (fp < stack_start || fp > stack_end)
459 return 0; 458 return 0;
460 lr = pc_pointer (((unsigned long *)fp)[-1]); 459 lr = pc_pointer (((unsigned long *)fp)[-1]);
461 if (!in_sched_functions(lr)) 460 if (!in_sched_functions(lr))
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index efd7a341614b..cd99b83f14c2 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -19,6 +19,7 @@
19#include <linux/user.h> 19#include <linux/user.h>
20#include <linux/security.h> 20#include <linux/security.h>
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/signal.h>
22 23
23#include <asm/uaccess.h> 24#include <asm/uaccess.h>
24#include <asm/pgtable.h> 25#include <asm/pgtable.h>
@@ -693,7 +694,7 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat
693 case PTRACE_SYSCALL: 694 case PTRACE_SYSCALL:
694 case PTRACE_CONT: 695 case PTRACE_CONT:
695 ret = -EIO; 696 ret = -EIO;
696 if ((unsigned long) data > _NSIG) 697 if (!valid_signal(data))
697 break; 698 break;
698 if (request == PTRACE_SYSCALL) 699 if (request == PTRACE_SYSCALL)
699 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 700 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
@@ -728,7 +729,7 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat
728 */ 729 */
729 case PTRACE_SINGLESTEP: 730 case PTRACE_SINGLESTEP:
730 ret = -EIO; 731 ret = -EIO;
731 if ((unsigned long) data > _NSIG) 732 if (!valid_signal(data))
732 break; 733 break;
733 child->ptrace |= PT_SINGLESTEP; 734 child->ptrace |= PT_SINGLESTEP;
734 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 735 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c
index 7ba6342cf93d..f897ce2ccf0d 100644
--- a/arch/arm/kernel/sys_arm.c
+++ b/arch/arm/kernel/sys_arm.c
@@ -227,18 +227,6 @@ asmlinkage int sys_ipc(uint call, int first, int second, int third,
227 } 227 }
228} 228}
229 229
230asmlinkage long sys_shmat(int shmid, char __user *shmaddr, int shmflg,
231 unsigned long __user *addr)
232{
233 unsigned long ret;
234 long err;
235
236 err = do_shmat(shmid, shmaddr, shmflg, &ret);
237 if (err == 0)
238 err = put_user(ret, addr);
239 return err;
240}
241
242/* Fork a new task - this creates a new program thread. 230/* Fork a new task - this creates a new program thread.
243 * This is called indirectly via a small wrapper 231 * This is called indirectly via a small wrapper
244 */ 232 */
@@ -314,7 +302,7 @@ long execve(const char *filename, char **argv, char **envp)
314 "b ret_to_user" 302 "b ret_to_user"
315 : 303 :
316 : "r" (current_thread_info()), 304 : "r" (current_thread_info()),
317 "Ir" (THREAD_SIZE - 8 - sizeof(regs)), 305 "Ir" (THREAD_START_SP - sizeof(regs)),
318 "r" (&regs), 306 "r" (&regs),
319 "Ir" (sizeof(regs)) 307 "Ir" (sizeof(regs))
320 : "r0", "r1", "r2", "r3", "ip", "memory"); 308 : "r0", "r1", "r2", "r3", "ip", "memory");
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 6e31718f6008..14df16b983f4 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -218,7 +218,8 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
218 tsk->comm, tsk->pid, tsk->thread_info + 1); 218 tsk->comm, tsk->pid, tsk->thread_info + 1);
219 219
220 if (!user_mode(regs) || in_interrupt()) { 220 if (!user_mode(regs) || in_interrupt()) {
221 dump_mem("Stack: ", regs->ARM_sp, 8192+(unsigned long)tsk->thread_info); 221 dump_mem("Stack: ", regs->ARM_sp,
222 THREAD_SIZE + (unsigned long)tsk->thread_info);
222 dump_backtrace(regs, tsk); 223 dump_backtrace(regs, tsk);
223 dump_instr(regs); 224 dump_instr(regs);
224 } 225 }
@@ -450,13 +451,17 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
450 451
451 case NR(set_tls): 452 case NR(set_tls):
452 thread->tp_value = regs->ARM_r0; 453 thread->tp_value = regs->ARM_r0;
454#if defined(CONFIG_HAS_TLS_REG)
455 asm ("mcr p15, 0, %0, c13, c0, 3" : : "r" (regs->ARM_r0) );
456#elif !defined(CONFIG_TLS_REG_EMUL)
453 /* 457 /*
454 * Our user accessible TLS ptr is located at 0xffff0ffc. 458 * User space must never try to access this directly.
455 * On SMP read access to this address must raise a fault 459 * Expect your app to break eventually if you do so.
456 * and be emulated from the data abort handler. 460 * The user helper at 0xffff0fe0 must be used instead.
457 * m 461 * (see entry-armv.S for details)
458 */ 462 */
459 *((unsigned long *)0xffff0ffc) = thread->tp_value; 463 *((unsigned int *)0xffff0ff0) = regs->ARM_r0;
464#endif
460 return 0; 465 return 0;
461 466
462 default: 467 default:
@@ -493,6 +498,44 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
493 return 0; 498 return 0;
494} 499}
495 500
501#ifdef CONFIG_TLS_REG_EMUL
502
503/*
504 * We might be running on an ARMv6+ processor which should have the TLS
505 * register but for some reason we can't use it, or maybe an SMP system
506 * using a pre-ARMv6 processor (there are apparently a few prototypes like
507 * that in existence) and therefore access to that register must be
508 * emulated.
509 */
510
511static int get_tp_trap(struct pt_regs *regs, unsigned int instr)
512{
513 int reg = (instr >> 12) & 15;
514 if (reg == 15)
515 return 1;
516 regs->uregs[reg] = current_thread_info()->tp_value;
517 regs->ARM_pc += 4;
518 return 0;
519}
520
521static struct undef_hook arm_mrc_hook = {
522 .instr_mask = 0x0fff0fff,
523 .instr_val = 0x0e1d0f70,
524 .cpsr_mask = PSR_T_BIT,
525 .cpsr_val = 0,
526 .fn = get_tp_trap,
527};
528
529static int __init arm_mrc_hook_init(void)
530{
531 register_undef_hook(&arm_mrc_hook);
532 return 0;
533}
534
535late_initcall(arm_mrc_hook_init);
536
537#endif
538
496void __bad_xchg(volatile void *ptr, int size) 539void __bad_xchg(volatile void *ptr, int size)
497{ 540{
498 printk("xchg: bad data size: pc 0x%p, ptr 0x%p, size %d\n", 541 printk("xchg: bad data size: pc 0x%p, ptr 0x%p, size %d\n",
@@ -578,9 +621,19 @@ EXPORT_SYMBOL(abort);
578 621
579void __init trap_init(void) 622void __init trap_init(void)
580{ 623{
581 extern void __trap_init(void); 624 extern char __stubs_start[], __stubs_end[];
625 extern char __vectors_start[], __vectors_end[];
626 extern char __kuser_helper_start[], __kuser_helper_end[];
627 int kuser_sz = __kuser_helper_end - __kuser_helper_start;
582 628
583 __trap_init(); 629 /*
630 * Copy the vectors, stubs and kuser helpers (in entry-armv.S)
631 * into the vector page, mapped at 0xffff0000, and ensure these
632 * are visible to the instruction stream.
633 */
634 memcpy((void *)0xffff0000, __vectors_start, __vectors_end - __vectors_start);
635 memcpy((void *)0xffff0200, __stubs_start, __stubs_end - __stubs_start);
636 memcpy((void *)0xffff1000 - kuser_sz, __kuser_helper_start, kuser_sz);
584 flush_icache_range(0xffff0000, 0xffff0000 + PAGE_SIZE); 637 flush_icache_range(0xffff0000, 0xffff0000 + PAGE_SIZE);
585 modify_domain(DOMAIN_USER, DOMAIN_CLIENT); 638 modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
586} 639}
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index a39c6a42d68a..ad2d66c93a5c 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -5,6 +5,7 @@
5 5
6#include <asm-generic/vmlinux.lds.h> 6#include <asm-generic/vmlinux.lds.h>
7#include <linux/config.h> 7#include <linux/config.h>
8#include <asm/thread_info.h>
8 9
9OUTPUT_ARCH(arm) 10OUTPUT_ARCH(arm)
10ENTRY(stext) 11ENTRY(stext)
@@ -103,7 +104,7 @@ SECTIONS
103 __data_loc = ALIGN(4); /* location in binary */ 104 __data_loc = ALIGN(4); /* location in binary */
104 . = DATAADDR; 105 . = DATAADDR;
105#else 106#else
106 . = ALIGN(8192); 107 . = ALIGN(THREAD_SIZE);
107 __data_loc = .; 108 __data_loc = .;
108#endif 109#endif
109 110
diff --git a/arch/arm/mach-clps711x/Kconfig b/arch/arm/mach-clps711x/Kconfig
index f6e676322ca9..45c930ccd064 100644
--- a/arch/arm/mach-clps711x/Kconfig
+++ b/arch/arm/mach-clps711x/Kconfig
@@ -10,6 +10,7 @@ config ARCH_AUTCPU12
10 10
11config ARCH_CDB89712 11config ARCH_CDB89712
12 bool "CDB89712" 12 bool "CDB89712"
13 select ISA
13 help 14 help
14 This is an evaluation board from Cirrus for the CS89712 processor. 15 This is an evaluation board from Cirrus for the CS89712 processor.
15 The board includes 2 serial ports, Ethernet, IRDA, and expansion 16 The board includes 2 serial ports, Ethernet, IRDA, and expansion
@@ -26,6 +27,8 @@ config ARCH_CLEP7312
26 27
27config ARCH_EDB7211 28config ARCH_EDB7211
28 bool "EDB7211" 29 bool "EDB7211"
30 select ISA
31 select DISCONTIGMEM
29 help 32 help
30 Say Y here if you intend to run this kernel on a Cirrus Logic EDB-7211 33 Say Y here if you intend to run this kernel on a Cirrus Logic EDB-7211
31 evaluation board. 34 evaluation board.
diff --git a/arch/arm/mach-footbridge/Kconfig b/arch/arm/mach-footbridge/Kconfig
index 1090c680b6dd..324d9edeec38 100644
--- a/arch/arm/mach-footbridge/Kconfig
+++ b/arch/arm/mach-footbridge/Kconfig
@@ -5,6 +5,9 @@ menu "Footbridge Implementations"
5config ARCH_CATS 5config ARCH_CATS
6 bool "CATS" 6 bool "CATS"
7 select FOOTBRIDGE_HOST 7 select FOOTBRIDGE_HOST
8 select ISA
9 select ISA_DMA
10 select PCI
8 help 11 help
9 Say Y here if you intend to run this kernel on the CATS. 12 Say Y here if you intend to run this kernel on the CATS.
10 13
@@ -13,6 +16,9 @@ config ARCH_CATS
13config ARCH_PERSONAL_SERVER 16config ARCH_PERSONAL_SERVER
14 bool "Compaq Personal Server" 17 bool "Compaq Personal Server"
15 select FOOTBRIDGE_HOST 18 select FOOTBRIDGE_HOST
19 select ISA
20 select ISA_DMA
21 select PCI
16 ---help--- 22 ---help---
17 Say Y here if you intend to run this kernel on the Compaq 23 Say Y here if you intend to run this kernel on the Compaq
18 Personal Server. 24 Personal Server.
@@ -42,6 +48,9 @@ config ARCH_EBSA285_HOST
42 bool "EBSA285 (host mode)" 48 bool "EBSA285 (host mode)"
43 select ARCH_EBSA285 49 select ARCH_EBSA285
44 select FOOTBRIDGE_HOST 50 select FOOTBRIDGE_HOST
51 select ISA
52 select ISA_DMA
53 select PCI
45 help 54 help
46 Say Y here if you intend to run this kernel on the EBSA285 card 55 Say Y here if you intend to run this kernel on the EBSA285 card
47 in host ("central function") mode. 56 in host ("central function") mode.
@@ -51,6 +60,9 @@ config ARCH_EBSA285_HOST
51config ARCH_NETWINDER 60config ARCH_NETWINDER
52 bool "NetWinder" 61 bool "NetWinder"
53 select FOOTBRIDGE_HOST 62 select FOOTBRIDGE_HOST
63 select ISA
64 select ISA_DMA
65 select PCI
54 help 66 help
55 Say Y here if you intend to run this kernel on the Rebel.COM 67 Say Y here if you intend to run this kernel on the Rebel.COM
56 NetWinder. Information about this machine can be found at: 68 NetWinder. Information about this machine can be found at:
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index ec85813ee5dc..cddd194ac6eb 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -4,6 +4,7 @@ menu "IMX Implementations"
4config ARCH_MX1ADS 4config ARCH_MX1ADS
5 bool "mx1ads" 5 bool "mx1ads"
6 depends on ARCH_IMX 6 depends on ARCH_IMX
7 select ISA
7 help 8 help
8 Say Y here if you are using the Motorola MX1ADS board 9 Say Y here if you are using the Motorola MX1ADS board
9 10
diff --git a/arch/arm/mach-imx/generic.c b/arch/arm/mach-imx/generic.c
index 54377d0f578c..41e5849ae8da 100644
--- a/arch/arm/mach-imx/generic.c
+++ b/arch/arm/mach-imx/generic.c
@@ -26,6 +26,7 @@
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/kernel.h> 27#include <linux/kernel.h>
28#include <linux/module.h> 28#include <linux/module.h>
29#include <asm/arch/imxfb.h>
29#include <asm/hardware.h> 30#include <asm/hardware.h>
30 31
31#include <asm/mach/map.h> 32#include <asm/mach/map.h>
@@ -228,6 +229,14 @@ static struct platform_device imx_uart2_device = {
228 .resource = imx_uart2_resources, 229 .resource = imx_uart2_resources,
229}; 230};
230 231
232static struct imxfb_mach_info imx_fb_info;
233
234void __init set_imx_fb_info(struct imxfb_mach_info *hard_imx_fb_info)
235{
236 memcpy(&imx_fb_info,hard_imx_fb_info,sizeof(struct imxfb_mach_info));
237}
238EXPORT_SYMBOL(set_imx_fb_info);
239
231static struct resource imxfb_resources[] = { 240static struct resource imxfb_resources[] = {
232 [0] = { 241 [0] = {
233 .start = 0x00205000, 242 .start = 0x00205000,
@@ -241,9 +250,16 @@ static struct resource imxfb_resources[] = {
241 }, 250 },
242}; 251};
243 252
253static u64 fb_dma_mask = ~(u64)0;
254
244static struct platform_device imxfb_device = { 255static struct platform_device imxfb_device = {
245 .name = "imx-fb", 256 .name = "imx-fb",
246 .id = 0, 257 .id = 0,
258 .dev = {
259 .platform_data = &imx_fb_info,
260 .dma_mask = &fb_dma_mask,
261 .coherent_dma_mask = 0xffffffff,
262 },
247 .num_resources = ARRAY_SIZE(imxfb_resources), 263 .num_resources = ARRAY_SIZE(imxfb_resources),
248 .resource = imxfb_resources, 264 .resource = imxfb_resources,
249}; 265};
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
index 86c50c3889b7..bd17b5154311 100644
--- a/arch/arm/mach-integrator/core.c
+++ b/arch/arm/mach-integrator/core.c
@@ -216,7 +216,9 @@ integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
216 216
217 write_seqlock(&xtime_lock); 217 write_seqlock(&xtime_lock);
218 218
219 // ...clear the interrupt 219 /*
220 * clear the interrupt
221 */
220 timer1->TimerClear = 1; 222 timer1->TimerClear = 1;
221 223
222 timer_tick(regs); 224 timer_tick(regs);
@@ -264,7 +266,7 @@ void __init integrator_time_init(unsigned long reload, unsigned int ctrl)
264 timer1->TimerValue = timer_reload; 266 timer1->TimerValue = timer_reload;
265 timer1->TimerControl = timer_ctrl; 267 timer1->TimerControl = timer_ctrl;
266 268
267 /* 269 /*
268 * Make irqs happen for the system timer 270 * Make irqs happen for the system timer
269 */ 271 */
270 setup_irq(IRQ_TIMERINT1, &integrator_timer_irq); 272 setup_irq(IRQ_TIMERINT1, &integrator_timer_irq);
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index 68e15c36e336..3b948e8c2751 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -420,7 +420,22 @@ static struct clcd_panel vga = {
420 */ 420 */
421static void cp_clcd_enable(struct clcd_fb *fb) 421static void cp_clcd_enable(struct clcd_fb *fb)
422{ 422{
423 cm_control(CM_CTRL_LCDMUXSEL_MASK, CM_CTRL_LCDMUXSEL_VGA); 423 u32 val;
424
425 if (fb->fb.var.bits_per_pixel <= 8)
426 val = CM_CTRL_LCDMUXSEL_VGA_8421BPP;
427 else if (fb->fb.var.bits_per_pixel <= 16)
428 val = CM_CTRL_LCDMUXSEL_VGA_16BPP;
429 else
430 val = 0; /* no idea for this, don't trust the docs */
431
432 cm_control(CM_CTRL_LCDMUXSEL_MASK|
433 CM_CTRL_LCDEN0|
434 CM_CTRL_LCDEN1|
435 CM_CTRL_STATIC1|
436 CM_CTRL_STATIC2|
437 CM_CTRL_STATIC|
438 CM_CTRL_n24BITEN, val);
424} 439}
425 440
426static unsigned long framesize = SZ_1M; 441static unsigned long framesize = SZ_1M;
diff --git a/arch/arm/mach-integrator/leds.c b/arch/arm/mach-integrator/leds.c
index 9d182b77b312..d2c0ab21150c 100644
--- a/arch/arm/mach-integrator/leds.c
+++ b/arch/arm/mach-integrator/leds.c
@@ -37,7 +37,7 @@ static void integrator_leds_event(led_event_t ledevt)
37 unsigned long flags; 37 unsigned long flags;
38 const unsigned int dbg_base = IO_ADDRESS(INTEGRATOR_DBG_BASE); 38 const unsigned int dbg_base = IO_ADDRESS(INTEGRATOR_DBG_BASE);
39 unsigned int update_alpha_leds; 39 unsigned int update_alpha_leds;
40 40
41 // yup, change the LEDs 41 // yup, change the LEDs
42 local_irq_save(flags); 42 local_irq_save(flags);
43 update_alpha_leds = 0; 43 update_alpha_leds = 0;
diff --git a/arch/arm/mach-integrator/time.c b/arch/arm/mach-integrator/time.c
index 20729de2af28..1a844ca139e0 100644
--- a/arch/arm/mach-integrator/time.c
+++ b/arch/arm/mach-integrator/time.c
@@ -40,25 +40,32 @@ static int integrator_set_rtc(void)
40 return 1; 40 return 1;
41} 41}
42 42
43static void rtc_read_alarm(struct rtc_wkalrm *alrm) 43static int rtc_read_alarm(struct rtc_wkalrm *alrm)
44{ 44{
45 rtc_time_to_tm(readl(rtc_base + RTC_MR), &alrm->time); 45 rtc_time_to_tm(readl(rtc_base + RTC_MR), &alrm->time);
46 return 0;
46} 47}
47 48
48static int rtc_set_alarm(struct rtc_wkalrm *alrm) 49static inline int rtc_set_alarm(struct rtc_wkalrm *alrm)
49{ 50{
50 unsigned long time; 51 unsigned long time;
51 int ret; 52 int ret;
52 53
53 ret = rtc_tm_to_time(&alrm->time, &time); 54 /*
55 * At the moment, we can only deal with non-wildcarded alarm times.
56 */
57 ret = rtc_valid_tm(&alrm->time);
58 if (ret == 0)
59 ret = rtc_tm_to_time(&alrm->time, &time);
54 if (ret == 0) 60 if (ret == 0)
55 writel(time, rtc_base + RTC_MR); 61 writel(time, rtc_base + RTC_MR);
56 return ret; 62 return ret;
57} 63}
58 64
59static void rtc_read_time(struct rtc_time *tm) 65static int rtc_read_time(struct rtc_time *tm)
60{ 66{
61 rtc_time_to_tm(readl(rtc_base + RTC_DR), tm); 67 rtc_time_to_tm(readl(rtc_base + RTC_DR), tm);
68 return 0;
62} 69}
63 70
64/* 71/*
@@ -69,7 +76,7 @@ static void rtc_read_time(struct rtc_time *tm)
69 * edge of the 1Hz clock, we must write the time one second 76 * edge of the 1Hz clock, we must write the time one second
70 * in advance. 77 * in advance.
71 */ 78 */
72static int rtc_set_time(struct rtc_time *tm) 79static inline int rtc_set_time(struct rtc_time *tm)
73{ 80{
74 unsigned long time; 81 unsigned long time;
75 int ret; 82 int ret;
diff --git a/arch/arm/mach-ixp2000/ixdp2800.c b/arch/arm/mach-ixp2000/ixdp2800.c
index c4683aaff84a..aec13c7108a9 100644
--- a/arch/arm/mach-ixp2000/ixdp2800.c
+++ b/arch/arm/mach-ixp2000/ixdp2800.c
@@ -65,19 +65,102 @@ static struct sys_timer ixdp2800_timer = {
65/************************************************************************* 65/*************************************************************************
66 * IXDP2800 PCI 66 * IXDP2800 PCI
67 *************************************************************************/ 67 *************************************************************************/
68static void __init ixdp2800_slave_disable_pci_master(void)
69{
70 *IXP2000_PCI_CMDSTAT &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
71}
72
73static void __init ixdp2800_master_wait_for_slave(void)
74{
75 volatile u32 *addr;
76
77 printk(KERN_INFO "IXDP2800: waiting for slave NPU to configure "
78 "its BAR sizes\n");
79
80 addr = ixp2000_pci_config_addr(0, IXDP2X00_SLAVE_NPU_DEVFN,
81 PCI_BASE_ADDRESS_1);
82 do {
83 *addr = 0xffffffff;
84 cpu_relax();
85 } while (*addr != 0xfe000008);
86
87 addr = ixp2000_pci_config_addr(0, IXDP2X00_SLAVE_NPU_DEVFN,
88 PCI_BASE_ADDRESS_2);
89 do {
90 *addr = 0xffffffff;
91 cpu_relax();
92 } while (*addr != 0xc0000008);
93
94 /*
95 * Configure the slave's SDRAM BAR by hand.
96 */
97 *addr = 0x40000008;
98}
99
100static void __init ixdp2800_slave_wait_for_master_enable(void)
101{
102 printk(KERN_INFO "IXDP2800: waiting for master NPU to enable us\n");
103
104 while ((*IXP2000_PCI_CMDSTAT & PCI_COMMAND_MASTER) == 0)
105 cpu_relax();
106}
107
68void __init ixdp2800_pci_preinit(void) 108void __init ixdp2800_pci_preinit(void)
69{ 109{
70 printk("ixdp2x00_pci_preinit called\n"); 110 printk("ixdp2x00_pci_preinit called\n");
71 111
72 *IXP2000_PCI_ADDR_EXT = 0x0000e000; 112 *IXP2000_PCI_ADDR_EXT = 0x0001e000;
113
114 if (!ixdp2x00_master_npu())
115 ixdp2800_slave_disable_pci_master();
73 116
74 *IXP2000_PCI_DRAM_BASE_ADDR_MASK = (0x40000000 - 1) & ~0xfffff;
75 *IXP2000_PCI_SRAM_BASE_ADDR_MASK = (0x2000000 - 1) & ~0x3ffff; 117 *IXP2000_PCI_SRAM_BASE_ADDR_MASK = (0x2000000 - 1) & ~0x3ffff;
118 *IXP2000_PCI_DRAM_BASE_ADDR_MASK = (0x40000000 - 1) & ~0xfffff;
76 119
77 ixp2000_pci_preinit(); 120 ixp2000_pci_preinit();
121
122 if (ixdp2x00_master_npu()) {
123 /*
124 * Wait until the slave set its SRAM/SDRAM BAR sizes
125 * correctly before we proceed to scan and enumerate
126 * the bus.
127 */
128 ixdp2800_master_wait_for_slave();
129
130 /*
131 * We configure the SDRAM BARs by hand because they
132 * are 1G and fall outside of the regular allocated
133 * PCI address space.
134 */
135 *IXP2000_PCI_SDRAM_BAR = 0x00000008;
136 } else {
137 /*
138 * Wait for the master to complete scanning the bus
139 * and assigning resources before we proceed to scan
140 * the bus ourselves. Set pci=firmware to honor the
141 * master's resource assignment.
142 */
143 ixdp2800_slave_wait_for_master_enable();
144 pcibios_setup("firmware");
145 }
78} 146}
79 147
80int ixdp2800_pci_setup(int nr, struct pci_sys_data *sys) 148/*
149 * We assign the SDRAM BARs for the two IXP2800 CPUs by hand, outside
150 * of the regular PCI window, because there's only 512M of outbound PCI
151 * memory window on each IXP, while we need 1G for each of the BARs.
152 */
153static void __devinit ixp2800_pci_fixup(struct pci_dev *dev)
154{
155 if (machine_is_ixdp2800()) {
156 dev->resource[2].start = 0;
157 dev->resource[2].end = 0;
158 dev->resource[2].flags = 0;
159 }
160}
161DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IXP2800, ixp2800_pci_fixup);
162
163static int __init ixdp2800_pci_setup(int nr, struct pci_sys_data *sys)
81{ 164{
82 sys->mem_offset = 0x00000000; 165 sys->mem_offset = 0x00000000;
83 166
@@ -129,22 +212,47 @@ static int __init ixdp2800_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
129 } else return IRQ_IXP2000_PCIB; /* Slave NIC interrupt */ 212 } else return IRQ_IXP2000_PCIB; /* Slave NIC interrupt */
130} 213}
131 214
132static void ixdp2800_pci_postinit(void) 215static void __init ixdp2800_master_enable_slave(void)
133{ 216{
134 struct pci_dev *dev; 217 volatile u32 *addr;
135 218
136 if (ixdp2x00_master_npu()) { 219 printk(KERN_INFO "IXDP2800: enabling slave NPU\n");
137 dev = pci_find_slot(1, IXDP2800_SLAVE_ENET_DEVFN); 220
138 pci_remove_bus_device(dev); 221 addr = (volatile u32 *)ixp2000_pci_config_addr(0,
139 } else { 222 IXDP2X00_SLAVE_NPU_DEVFN,
140 dev = pci_find_slot(1, IXDP2800_MASTER_ENET_DEVFN); 223 PCI_COMMAND);
141 pci_remove_bus_device(dev); 224
225 *addr |= PCI_COMMAND_MASTER;
226}
142 227
228static void __init ixdp2800_master_wait_for_slave_bus_scan(void)
229{
230 volatile u32 *addr;
231
232 printk(KERN_INFO "IXDP2800: waiting for slave to finish bus scan\n");
233
234 addr = (volatile u32 *)ixp2000_pci_config_addr(0,
235 IXDP2X00_SLAVE_NPU_DEVFN,
236 PCI_COMMAND);
237 while ((*addr & PCI_COMMAND_MEMORY) == 0)
238 cpu_relax();
239}
240
241static void __init ixdp2800_slave_signal_bus_scan_completion(void)
242{
243 printk(KERN_INFO "IXDP2800: bus scan done, signaling master\n");
244 *IXP2000_PCI_CMDSTAT |= PCI_COMMAND_MEMORY;
245}
246
247static void __init ixdp2800_pci_postinit(void)
248{
249 if (!ixdp2x00_master_npu()) {
143 ixdp2x00_slave_pci_postinit(); 250 ixdp2x00_slave_pci_postinit();
251 ixdp2800_slave_signal_bus_scan_completion();
144 } 252 }
145} 253}
146 254
147struct hw_pci ixdp2800_pci __initdata = { 255struct __initdata hw_pci ixdp2800_pci __initdata = {
148 .nr_controllers = 1, 256 .nr_controllers = 1,
149 .setup = ixdp2800_pci_setup, 257 .setup = ixdp2800_pci_setup,
150 .preinit = ixdp2800_pci_preinit, 258 .preinit = ixdp2800_pci_preinit,
@@ -155,8 +263,21 @@ struct hw_pci ixdp2800_pci __initdata = {
155 263
156int __init ixdp2800_pci_init(void) 264int __init ixdp2800_pci_init(void)
157{ 265{
158 if (machine_is_ixdp2800()) 266 if (machine_is_ixdp2800()) {
267 struct pci_dev *dev;
268
159 pci_common_init(&ixdp2800_pci); 269 pci_common_init(&ixdp2800_pci);
270 if (ixdp2x00_master_npu()) {
271 dev = pci_find_slot(1, IXDP2800_SLAVE_ENET_DEVFN);
272 pci_remove_bus_device(dev);
273
274 ixdp2800_master_enable_slave();
275 ixdp2800_master_wait_for_slave_bus_scan();
276 } else {
277 dev = pci_find_slot(1, IXDP2800_MASTER_ENET_DEVFN);
278 pci_remove_bus_device(dev);
279 }
280 }
160 281
161 return 0; 282 return 0;
162} 283}
diff --git a/arch/arm/mach-ixp2000/pci.c b/arch/arm/mach-ixp2000/pci.c
index 831f8ffb6b61..5ff2f2718c58 100644
--- a/arch/arm/mach-ixp2000/pci.c
+++ b/arch/arm/mach-ixp2000/pci.c
@@ -37,7 +37,7 @@ static int pci_master_aborts = 0;
37 37
38static int clear_master_aborts(void); 38static int clear_master_aborts(void);
39 39
40static u32 * 40u32 *
41ixp2000_pci_config_addr(unsigned int bus_nr, unsigned int devfn, int where) 41ixp2000_pci_config_addr(unsigned int bus_nr, unsigned int devfn, int where)
42{ 42{
43 u32 *paddress; 43 u32 *paddress;
@@ -208,15 +208,15 @@ ixp2000_pci_preinit(void)
208 * use our own resource space. 208 * use our own resource space.
209 */ 209 */
210static struct resource ixp2000_pci_mem_space = { 210static struct resource ixp2000_pci_mem_space = {
211 .start = 0x00000000, 211 .start = 0xe0000000,
212 .end = 0xffffffff, 212 .end = 0xffffffff,
213 .flags = IORESOURCE_MEM, 213 .flags = IORESOURCE_MEM,
214 .name = "PCI Mem Space" 214 .name = "PCI Mem Space"
215}; 215};
216 216
217static struct resource ixp2000_pci_io_space = { 217static struct resource ixp2000_pci_io_space = {
218 .start = 0x00000000, 218 .start = 0x00010000,
219 .end = 0xffffffff, 219 .end = 0x0001ffff,
220 .flags = IORESOURCE_IO, 220 .flags = IORESOURCE_IO,
221 .name = "PCI I/O Space" 221 .name = "PCI I/O Space"
222}; 222};
diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c
index 94bcdb933e41..aa92e3708838 100644
--- a/arch/arm/mach-ixp4xx/common-pci.c
+++ b/arch/arm/mach-ixp4xx/common-pci.c
@@ -502,15 +502,6 @@ pci_set_dma_mask(struct pci_dev *dev, u64 mask)
502} 502}
503 503
504int 504int
505pci_dac_set_dma_mask(struct pci_dev *dev, u64 mask)
506{
507 if (mask >= SZ_64M - 1 )
508 return 0;
509
510 return -EIO;
511}
512
513int
514pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask) 505pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
515{ 506{
516 if (mask >= SZ_64M - 1 ) 507 if (mask >= SZ_64M - 1 )
@@ -520,7 +511,6 @@ pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
520} 511}
521 512
522EXPORT_SYMBOL(pci_set_dma_mask); 513EXPORT_SYMBOL(pci_set_dma_mask);
523EXPORT_SYMBOL(pci_dac_set_dma_mask);
524EXPORT_SYMBOL(pci_set_consistent_dma_mask); 514EXPORT_SYMBOL(pci_set_consistent_dma_mask);
525EXPORT_SYMBOL(ixp4xx_pci_read); 515EXPORT_SYMBOL(ixp4xx_pci_read);
526EXPORT_SYMBOL(ixp4xx_pci_write); 516EXPORT_SYMBOL(ixp4xx_pci_write);
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
index b1575b8dc1cd..a45aaa115a76 100644
--- a/arch/arm/mach-pxa/generic.c
+++ b/arch/arm/mach-pxa/generic.c
@@ -220,6 +220,30 @@ static struct platform_device stuart_device = {
220 .id = 2, 220 .id = 2,
221}; 221};
222 222
223static struct resource i2c_resources[] = {
224 {
225 .start = 0x40301680,
226 .end = 0x403016a3,
227 .flags = IORESOURCE_MEM,
228 }, {
229 .start = IRQ_I2C,
230 .end = IRQ_I2C,
231 .flags = IORESOURCE_IRQ,
232 },
233};
234
235static struct platform_device i2c_device = {
236 .name = "pxa2xx-i2c",
237 .id = 0,
238 .resource = i2c_resources,
239 .num_resources = ARRAY_SIZE(i2c_resources),
240};
241
242void __init pxa_set_i2c_info(struct i2c_pxa_platform_data *info)
243{
244 i2c_device.dev.platform_data = info;
245}
246
223static struct platform_device *devices[] __initdata = { 247static struct platform_device *devices[] __initdata = {
224 &pxamci_device, 248 &pxamci_device,
225 &udc_device, 249 &udc_device,
@@ -227,6 +251,7 @@ static struct platform_device *devices[] __initdata = {
227 &ffuart_device, 251 &ffuart_device,
228 &btuart_device, 252 &btuart_device,
229 &stuart_device, 253 &stuart_device,
254 &i2c_device,
230}; 255};
231 256
232static int __init pxa_init(void) 257static int __init pxa_init(void)
diff --git a/arch/arm/mach-pxa/sleep.S b/arch/arm/mach-pxa/sleep.S
index 16cad2c2497c..5786ccad938c 100644
--- a/arch/arm/mach-pxa/sleep.S
+++ b/arch/arm/mach-pxa/sleep.S
@@ -18,6 +18,11 @@
18 18
19#include <asm/arch/pxa-regs.h> 19#include <asm/arch/pxa-regs.h>
20 20
21#ifdef CONFIG_PXA27x // workaround for Errata 50
22#define MDREFR_KDIV 0x200a4000 // all banks
23#define CCCR_SLEEP 0x00000107 // L=7 2N=2 A=0 PPDIS=0 CPDIS=0
24#endif
25
21 .text 26 .text
22 27
23/* 28/*
@@ -28,7 +33,9 @@
28 33
29ENTRY(pxa_cpu_suspend) 34ENTRY(pxa_cpu_suspend)
30 35
36#ifndef CONFIG_IWMMXT
31 mra r2, r3, acc0 37 mra r2, r3, acc0
38#endif
32 stmfd sp!, {r2 - r12, lr} @ save registers on stack 39 stmfd sp!, {r2 - r12, lr} @ save registers on stack
33 40
34 @ get coprocessor registers 41 @ get coprocessor registers
@@ -61,14 +68,23 @@ ENTRY(pxa_cpu_suspend)
61 @ prepare value for sleep mode 68 @ prepare value for sleep mode
62 mov r1, #3 @ sleep mode 69 mov r1, #3 @ sleep mode
63 70
64 @ prepare to put SDRAM into self-refresh manually 71 @ prepare pointer to physical address 0 (virtual mapping in generic.c)
72 mov r2, #UNCACHED_PHYS_0
73
74 @ prepare SDRAM refresh settings
65 ldr r4, =MDREFR 75 ldr r4, =MDREFR
66 ldr r5, [r4] 76 ldr r5, [r4]
77
78 @ enable SDRAM self-refresh mode
67 orr r5, r5, #MDREFR_SLFRSH 79 orr r5, r5, #MDREFR_SLFRSH
68 80
69 @ prepare pointer to physical address 0 (virtual mapping in generic.c) 81#ifdef CONFIG_PXA27x
70 mov r2, #UNCACHED_PHYS_0 82 @ set SDCLKx divide-by-2 bits (this is part of a workaround for Errata 50)
83 ldr r6, =MDREFR_KDIV
84 orr r5, r5, r6
85#endif
71 86
87#ifdef CONFIG_PXA25x
72 @ Intel PXA255 Specification Update notes problems 88 @ Intel PXA255 Specification Update notes problems
73 @ about suspending with PXBus operating above 133MHz 89 @ about suspending with PXBus operating above 133MHz
74 @ (see Errata 31, GPIO output signals, ... unpredictable in sleep 90 @ (see Errata 31, GPIO output signals, ... unpredictable in sleep
@@ -100,6 +116,18 @@ ENTRY(pxa_cpu_suspend)
100 mov r0, #0 116 mov r0, #0
101 mcr p14, 0, r0, c6, c0, 0 117 mcr p14, 0, r0, c6, c0, 0
102 orr r0, r0, #2 @ initiate change bit 118 orr r0, r0, #2 @ initiate change bit
119#endif
120#ifdef CONFIG_PXA27x
121 @ Intel PXA270 Specification Update notes problems sleeping
122 @ with core operating above 91 MHz
123 @ (see Errata 50, ...processor does not exit from sleep...)
124
125 ldr r6, =CCCR
126 ldr r8, [r6] @ keep original value for resume
127
128 ldr r7, =CCCR_SLEEP @ prepare CCCR sleep value
129 mov r0, #0x2 @ prepare value for CLKCFG
130#endif
103 131
104 @ align execution to a cache line 132 @ align execution to a cache line
105 b 1f 133 b 1f
@@ -111,6 +139,7 @@ ENTRY(pxa_cpu_suspend)
111 @ All needed values are now in registers. 139 @ All needed values are now in registers.
112 @ These last instructions should be in cache 140 @ These last instructions should be in cache
113 141
142#if defined(CONFIG_PXA25x) || defined(CONFIG_PXA27x)
114 @ initiate the frequency change... 143 @ initiate the frequency change...
115 str r7, [r6] 144 str r7, [r6]
116 mcr p14, 0, r0, c6, c0, 0 145 mcr p14, 0, r0, c6, c0, 0
@@ -118,14 +147,27 @@ ENTRY(pxa_cpu_suspend)
118 @ restore the original cpu speed value for resume 147 @ restore the original cpu speed value for resume
119 str r8, [r6] 148 str r8, [r6]
120 149
121 @ put SDRAM into self-refresh 150 @ need 6 13-MHz cycles before changing PWRMODE
122 str r5, [r4] 151 @ just set frequency to 91-MHz... 6*91/13 = 42
152
153 mov r0, #42
15410: subs r0, r0, #1
155 bne 10b
156#endif
157
158 @ Do not reorder...
159 @ Intel PXA270 Specification Update notes problems performing
160 @ external accesses after SDRAM is put in self-refresh mode
161 @ (see Errata 39 ...hangs when entering self-refresh mode)
123 162
124 @ force address lines low by reading at physical address 0 163 @ force address lines low by reading at physical address 0
125 ldr r3, [r2] 164 ldr r3, [r2]
126 165
166 @ put SDRAM into self-refresh
167 str r5, [r4]
168
127 @ enter sleep mode 169 @ enter sleep mode
128 mcr p14, 0, r1, c7, c0, 0 170 mcr p14, 0, r1, c7, c0, 0 @ PWRMODE
129 171
13020: b 20b @ loop waiting for sleep 17220: b 20b @ loop waiting for sleep
131 173
@@ -188,7 +230,9 @@ resume_after_mmu:
188 bl cpu_xscale_proc_init 230 bl cpu_xscale_proc_init
189#endif 231#endif
190 ldmfd sp!, {r2, r3} 232 ldmfd sp!, {r2, r3}
233#ifndef CONFIG_IWMMXT
191 mar acc0, r2, r3 234 mar acc0, r2, r3
235#endif
192 ldmfd sp!, {r4 - r12, pc} @ return to caller 236 ldmfd sp!, {r4 - r12, pc} @ return to caller
193 237
194 238
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 5b670c9ac5ef..c4fc6be629de 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -409,3 +409,24 @@ config CPU_BPREDICT_DISABLE
409 depends on CPU_ARM1020 409 depends on CPU_ARM1020
410 help 410 help
411 Say Y here to disable branch prediction. If unsure, say N. 411 Say Y here to disable branch prediction. If unsure, say N.
412
413config TLS_REG_EMUL
414 bool
415 default y if (SMP || CPU_32v6) && (CPU_32v5 || CPU_32v4 || CPU_32v3)
416 help
417 We might be running on an ARMv6+ processor which should have the TLS
418 register but for some reason we can't use it, or maybe an SMP system
419 using a pre-ARMv6 processor (there are apparently a few prototypes
420 like that in existence) and therefore access to that register must
421 be emulated.
422
423config HAS_TLS_REG
424 bool
425 depends on CPU_32v6
426 default y if !TLS_REG_EMUL
427 help
428 This selects support for the CP15 thread register.
429 It is defined to be available on ARMv6 or later. If a particular
430 ARMv6 or later CPU doesn't support it then it must omc;ide "select
431 TLS_REG_EMUL" along with its other caracteristics.
432
diff --git a/arch/arm/mm/abort-ev6.S b/arch/arm/mm/abort-ev6.S
index 38b2cbb89beb..8f76f3df7b4c 100644
--- a/arch/arm/mm/abort-ev6.S
+++ b/arch/arm/mm/abort-ev6.S
@@ -1,5 +1,6 @@
1#include <linux/linkage.h> 1#include <linux/linkage.h>
2#include <asm/assembler.h> 2#include <asm/assembler.h>
3#include "abort-macro.S"
3/* 4/*
4 * Function: v6_early_abort 5 * Function: v6_early_abort
5 * 6 *
@@ -13,11 +14,26 @@
13 * : sp = pointer to registers 14 * : sp = pointer to registers
14 * 15 *
15 * Purpose : obtain information about current aborted instruction. 16 * Purpose : obtain information about current aborted instruction.
17 * Note: we read user space. This means we might cause a data
18 * abort here if the I-TLB and D-TLB aren't seeing the same
19 * picture. Unfortunately, this does happen. We live with it.
16 */ 20 */
17 .align 5 21 .align 5
18ENTRY(v6_early_abort) 22ENTRY(v6_early_abort)
19 mrc p15, 0, r1, c5, c0, 0 @ get FSR 23 mrc p15, 0, r1, c5, c0, 0 @ get FSR
20 mrc p15, 0, r0, c6, c0, 0 @ get FAR 24 mrc p15, 0, r0, c6, c0, 0 @ get FAR
25/*
26 * Faulty SWP instruction on 1136 doesn't set bit 11 in DFSR.
27 * The test below covers all the write situations, including Java bytecodes
28 */
29 bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR
30 tst r3, #PSR_J_BIT @ Java?
31 movne pc, lr
32 do_thumb_abort
33 ldreq r3, [r2] @ read aborted ARM instruction
34 do_ldrd_abort
35 tst r3, #1 << 20 @ L = 0 -> write
36 orreq r1, r1, #1 << 11 @ yes.
21 mov pc, lr 37 mov pc, lr
22 38
23 39
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
index f5a87db8b498..585dfb8e20b9 100644
--- a/arch/arm/mm/mm-armv.c
+++ b/arch/arm/mm/mm-armv.c
@@ -411,9 +411,10 @@ static void __init build_mem_type_table(void)
411 mem_types[MT_MEMORY].prot_sect &= ~PMD_BIT4; 411 mem_types[MT_MEMORY].prot_sect &= ~PMD_BIT4;
412 mem_types[MT_ROM].prot_sect &= ~PMD_BIT4; 412 mem_types[MT_ROM].prot_sect &= ~PMD_BIT4;
413 /* 413 /*
414 * Mark cache clean areas read only from SVC mode 414 * Mark cache clean areas and XIP ROM read only
415 * and no access from userspace. 415 * from SVC mode and no access from userspace.
416 */ 416 */
417 mem_types[MT_ROM].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
417 mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; 418 mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
418 mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; 419 mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
419 } 420 }