aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-29 23:59:55 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-29 23:59:55 -0400
commit92dd7ca0af8f769569bde98a83b4a8f4daec6ac5 (patch)
tree9217bee214128a4a45b2e0a3d9784d05fea2c8fb
parent164cad9bacc2cf190493d2ee4918dc2869ba6f53 (diff)
parentda41119af78864d27ccbf505949df788d5e8aaf5 (diff)
Merge master.kernel.org:/home/rmk/linux-2.6-arm
-rw-r--r--arch/arm/kernel/armksyms.c6
-rw-r--r--arch/arm/kernel/setup.c3
-rw-r--r--arch/arm/kernel/smp.c123
-rw-r--r--arch/arm/lib/Makefile2
-rw-r--r--arch/arm/lib/longlong.h183
-rw-r--r--arch/arm/lib/udivdi3.c222
-rw-r--r--arch/arm/mach-integrator/core.c41
-rw-r--r--arch/arm/mach-omap/pm.c16
-rw-r--r--arch/arm/mach-omap/time.c44
-rw-r--r--arch/arm/mach-s3c2410/Kconfig5
-rw-r--r--arch/arm/mach-s3c2410/Makefile1
-rw-r--r--arch/arm/mach-s3c2410/devs.c4
-rw-r--r--arch/arm/mach-s3c2410/mach-bast.c39
-rw-r--r--arch/arm/mach-s3c2410/mach-vr1000.c8
-rw-r--r--arch/arm/mach-s3c2410/pm-simtec.c65
-rw-r--r--arch/arm/mach-versatile/core.c61
-rw-r--r--arch/arm/mm/init.c2
-rw-r--r--arch/arm/mm/mm-armv.c2
-rw-r--r--arch/arm/vfp/vfp.h15
-rw-r--r--arch/arm/vfp/vfpdouble.c2
-rw-r--r--arch/arm/vfp/vfpmodule.c2
-rw-r--r--arch/arm/vfp/vfpsingle.c14
-rw-r--r--drivers/net/arm/etherh.c16
-rw-r--r--include/asm-arm/arch-pxa/debug-macro.S2
-rw-r--r--include/asm-arm/hardware/arm_timer.h21
-rw-r--r--include/asm-arm/system.h12
-rw-r--r--include/asm-arm/tlbflush.h28
27 files changed, 385 insertions, 554 deletions
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index 4c38bd8bc298..b713c44c6fb4 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -30,9 +30,6 @@ extern void __lshrdi3(void);
30extern void __modsi3(void); 30extern void __modsi3(void);
31extern void __muldi3(void); 31extern void __muldi3(void);
32extern void __ucmpdi2(void); 32extern void __ucmpdi2(void);
33extern void __udivdi3(void);
34extern void __umoddi3(void);
35extern void __udivmoddi4(void);
36extern void __udivsi3(void); 33extern void __udivsi3(void);
37extern void __umodsi3(void); 34extern void __umodsi3(void);
38extern void __do_div64(void); 35extern void __do_div64(void);
@@ -134,9 +131,6 @@ EXPORT_SYMBOL(__lshrdi3);
134EXPORT_SYMBOL(__modsi3); 131EXPORT_SYMBOL(__modsi3);
135EXPORT_SYMBOL(__muldi3); 132EXPORT_SYMBOL(__muldi3);
136EXPORT_SYMBOL(__ucmpdi2); 133EXPORT_SYMBOL(__ucmpdi2);
137EXPORT_SYMBOL(__udivdi3);
138EXPORT_SYMBOL(__umoddi3);
139EXPORT_SYMBOL(__udivmoddi4);
140EXPORT_SYMBOL(__udivsi3); 134EXPORT_SYMBOL(__udivsi3);
141EXPORT_SYMBOL(__umodsi3); 135EXPORT_SYMBOL(__umodsi3);
142EXPORT_SYMBOL(__do_div64); 136EXPORT_SYMBOL(__do_div64);
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 8cf733daa800..35b7273cfdb4 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -359,7 +359,8 @@ void cpu_init(void)
359 "I" (offsetof(struct stack, abt[0])), 359 "I" (offsetof(struct stack, abt[0])),
360 "I" (PSR_F_BIT | PSR_I_BIT | UND_MODE), 360 "I" (PSR_F_BIT | PSR_I_BIT | UND_MODE),
361 "I" (offsetof(struct stack, und[0])), 361 "I" (offsetof(struct stack, und[0])),
362 "I" (PSR_F_BIT | PSR_I_BIT | SVC_MODE)); 362 "I" (PSR_F_BIT | PSR_I_BIT | SVC_MODE)
363 : "r14");
363} 364}
364 365
365static struct machine_desc * __init setup_machine(unsigned int nr) 366static struct machine_desc * __init setup_machine(unsigned int nr)
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 34892758f098..a931409c8fe4 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -502,3 +502,126 @@ int __init setup_profiling_timer(unsigned int multiplier)
502{ 502{
503 return -EINVAL; 503 return -EINVAL;
504} 504}
505
506static int
507on_each_cpu_mask(void (*func)(void *), void *info, int retry, int wait,
508 cpumask_t mask)
509{
510 int ret = 0;
511
512 preempt_disable();
513
514 ret = smp_call_function_on_cpu(func, info, retry, wait, mask);
515 if (cpu_isset(smp_processor_id(), mask))
516 func(info);
517
518 preempt_enable();
519
520 return ret;
521}
522
523/**********************************************************************/
524
525/*
526 * TLB operations
527 */
528struct tlb_args {
529 struct vm_area_struct *ta_vma;
530 unsigned long ta_start;
531 unsigned long ta_end;
532};
533
534static inline void ipi_flush_tlb_all(void *ignored)
535{
536 local_flush_tlb_all();
537}
538
539static inline void ipi_flush_tlb_mm(void *arg)
540{
541 struct mm_struct *mm = (struct mm_struct *)arg;
542
543 local_flush_tlb_mm(mm);
544}
545
546static inline void ipi_flush_tlb_page(void *arg)
547{
548 struct tlb_args *ta = (struct tlb_args *)arg;
549
550 local_flush_tlb_page(ta->ta_vma, ta->ta_start);
551}
552
553static inline void ipi_flush_tlb_kernel_page(void *arg)
554{
555 struct tlb_args *ta = (struct tlb_args *)arg;
556
557 local_flush_tlb_kernel_page(ta->ta_start);
558}
559
560static inline void ipi_flush_tlb_range(void *arg)
561{
562 struct tlb_args *ta = (struct tlb_args *)arg;
563
564 local_flush_tlb_range(ta->ta_vma, ta->ta_start, ta->ta_end);
565}
566
567static inline void ipi_flush_tlb_kernel_range(void *arg)
568{
569 struct tlb_args *ta = (struct tlb_args *)arg;
570
571 local_flush_tlb_kernel_range(ta->ta_start, ta->ta_end);
572}
573
574void flush_tlb_all(void)
575{
576 on_each_cpu(ipi_flush_tlb_all, NULL, 1, 1);
577}
578
579void flush_tlb_mm(struct mm_struct *mm)
580{
581 cpumask_t mask = mm->cpu_vm_mask;
582
583 on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, 1, mask);
584}
585
586void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
587{
588 cpumask_t mask = vma->vm_mm->cpu_vm_mask;
589 struct tlb_args ta;
590
591 ta.ta_vma = vma;
592 ta.ta_start = uaddr;
593
594 on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, 1, mask);
595}
596
597void flush_tlb_kernel_page(unsigned long kaddr)
598{
599 struct tlb_args ta;
600
601 ta.ta_start = kaddr;
602
603 on_each_cpu(ipi_flush_tlb_kernel_page, &ta, 1, 1);
604}
605
606void flush_tlb_range(struct vm_area_struct *vma,
607 unsigned long start, unsigned long end)
608{
609 cpumask_t mask = vma->vm_mm->cpu_vm_mask;
610 struct tlb_args ta;
611
612 ta.ta_vma = vma;
613 ta.ta_start = start;
614 ta.ta_end = end;
615
616 on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, 1, mask);
617}
618
619void flush_tlb_kernel_range(unsigned long start, unsigned long end)
620{
621 struct tlb_args ta;
622
623 ta.ta_start = start;
624 ta.ta_end = end;
625
626 on_each_cpu(ipi_flush_tlb_kernel_range, &ta, 1, 1);
627}
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index c0e65833ffc4..8725d63e4219 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -11,7 +11,7 @@ lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \
11 strnlen_user.o strchr.o strrchr.o testchangebit.o \ 11 strnlen_user.o strchr.o strrchr.o testchangebit.o \
12 testclearbit.o testsetbit.o uaccess.o getuser.o \ 12 testclearbit.o testsetbit.o uaccess.o getuser.o \
13 putuser.o ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ 13 putuser.o ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
14 ucmpdi2.o udivdi3.o lib1funcs.o div64.o \ 14 ucmpdi2.o lib1funcs.o div64.o \
15 io-readsb.o io-writesb.o io-readsl.o io-writesl.o 15 io-readsb.o io-writesb.o io-readsl.o io-writesl.o
16 16
17ifeq ($(CONFIG_CPU_32v3),y) 17ifeq ($(CONFIG_CPU_32v3),y)
diff --git a/arch/arm/lib/longlong.h b/arch/arm/lib/longlong.h
deleted file mode 100644
index 90ae647e4d76..000000000000
--- a/arch/arm/lib/longlong.h
+++ /dev/null
@@ -1,183 +0,0 @@
1/* longlong.h -- based on code from gcc-2.95.3
2
3 definitions for mixed size 32/64 bit arithmetic.
4 Copyright (C) 1991, 92, 94, 95, 96, 1997, 1998 Free Software Foundation, Inc.
5
6 This definition file is free software; you can redistribute it
7 and/or modify it under the terms of the GNU General Public
8 License as published by the Free Software Foundation; either
9 version 2, or (at your option) any later version.
10
11 This definition file is distributed in the hope that it will be
12 useful, but WITHOUT ANY WARRANTY; without even the implied
13 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 See the 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,
19 Boston, MA 02111-1307, USA. */
20
21/* Borrowed from GCC 2.95.3, I Molton 29/07/01 */
22
23#ifndef SI_TYPE_SIZE
24#define SI_TYPE_SIZE 32
25#endif
26
27#define __BITS4 (SI_TYPE_SIZE / 4)
28#define __ll_B (1L << (SI_TYPE_SIZE / 2))
29#define __ll_lowpart(t) ((u32) (t) % __ll_B)
30#define __ll_highpart(t) ((u32) (t) / __ll_B)
31
32/* Define auxiliary asm macros.
33
34 1) umul_ppmm(high_prod, low_prod, multipler, multiplicand)
35 multiplies two u32 integers MULTIPLER and MULTIPLICAND,
36 and generates a two-part u32 product in HIGH_PROD and
37 LOW_PROD.
38
39 2) __umulsidi3(a,b) multiplies two u32 integers A and B,
40 and returns a u64 product. This is just a variant of umul_ppmm.
41
42 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
43 denominator) divides a two-word unsigned integer, composed by the
44 integers HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and
45 places the quotient in QUOTIENT and the remainder in REMAINDER.
46 HIGH_NUMERATOR must be less than DENOMINATOR for correct operation.
47 If, in addition, the most significant bit of DENOMINATOR must be 1,
48 then the pre-processor symbol UDIV_NEEDS_NORMALIZATION is defined to 1.
49
50 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
51 denominator). Like udiv_qrnnd but the numbers are signed. The
52 quotient is rounded towards 0.
53
54 5) count_leading_zeros(count, x) counts the number of zero-bits from
55 the msb to the first non-zero bit. This is the number of steps X
56 needs to be shifted left to set the msb. Undefined for X == 0.
57
58 6) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1,
59 high_addend_2, low_addend_2) adds two two-word unsigned integers,
60 composed by HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and
61 LOW_ADDEND_2 respectively. The result is placed in HIGH_SUM and
62 LOW_SUM. Overflow (i.e. carry out) is not stored anywhere, and is
63 lost.
64
65 7) sub_ddmmss(high_difference, low_difference, high_minuend,
66 low_minuend, high_subtrahend, low_subtrahend) subtracts two
67 two-word unsigned integers, composed by HIGH_MINUEND_1 and
68 LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and LOW_SUBTRAHEND_2
69 respectively. The result is placed in HIGH_DIFFERENCE and
70 LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere,
71 and is lost.
72
73 If any of these macros are left undefined for a particular CPU,
74 C macros are used. */
75
76#if defined (__arm__)
77#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
78 __asm__ ("adds %1, %4, %5 \n\
79 adc %0, %2, %3" \
80 : "=r" ((u32) (sh)), \
81 "=&r" ((u32) (sl)) \
82 : "%r" ((u32) (ah)), \
83 "rI" ((u32) (bh)), \
84 "%r" ((u32) (al)), \
85 "rI" ((u32) (bl)))
86#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
87 __asm__ ("subs %1, %4, %5 \n\
88 sbc %0, %2, %3" \
89 : "=r" ((u32) (sh)), \
90 "=&r" ((u32) (sl)) \
91 : "r" ((u32) (ah)), \
92 "rI" ((u32) (bh)), \
93 "r" ((u32) (al)), \
94 "rI" ((u32) (bl)))
95#define umul_ppmm(xh, xl, a, b) \
96{register u32 __t0, __t1, __t2; \
97 __asm__ ("%@ Inlined umul_ppmm \n\
98 mov %2, %5, lsr #16 \n\
99 mov %0, %6, lsr #16 \n\
100 bic %3, %5, %2, lsl #16 \n\
101 bic %4, %6, %0, lsl #16 \n\
102 mul %1, %3, %4 \n\
103 mul %4, %2, %4 \n\
104 mul %3, %0, %3 \n\
105 mul %0, %2, %0 \n\
106 adds %3, %4, %3 \n\
107 addcs %0, %0, #65536 \n\
108 adds %1, %1, %3, lsl #16 \n\
109 adc %0, %0, %3, lsr #16" \
110 : "=&r" ((u32) (xh)), \
111 "=r" ((u32) (xl)), \
112 "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \
113 : "r" ((u32) (a)), \
114 "r" ((u32) (b)));}
115#define UMUL_TIME 20
116#define UDIV_TIME 100
117#endif /* __arm__ */
118
119#define __umulsidi3(u, v) \
120 ({DIunion __w; \
121 umul_ppmm (__w.s.high, __w.s.low, u, v); \
122 __w.ll; })
123
124#define __udiv_qrnnd_c(q, r, n1, n0, d) \
125 do { \
126 u32 __d1, __d0, __q1, __q0; \
127 u32 __r1, __r0, __m; \
128 __d1 = __ll_highpart (d); \
129 __d0 = __ll_lowpart (d); \
130 \
131 __r1 = (n1) % __d1; \
132 __q1 = (n1) / __d1; \
133 __m = (u32) __q1 * __d0; \
134 __r1 = __r1 * __ll_B | __ll_highpart (n0); \
135 if (__r1 < __m) \
136 { \
137 __q1--, __r1 += (d); \
138 if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
139 if (__r1 < __m) \
140 __q1--, __r1 += (d); \
141 } \
142 __r1 -= __m; \
143 \
144 __r0 = __r1 % __d1; \
145 __q0 = __r1 / __d1; \
146 __m = (u32) __q0 * __d0; \
147 __r0 = __r0 * __ll_B | __ll_lowpart (n0); \
148 if (__r0 < __m) \
149 { \
150 __q0--, __r0 += (d); \
151 if (__r0 >= (d)) \
152 if (__r0 < __m) \
153 __q0--, __r0 += (d); \
154 } \
155 __r0 -= __m; \
156 \
157 (q) = (u32) __q1 * __ll_B | __q0; \
158 (r) = __r0; \
159 } while (0)
160
161#define UDIV_NEEDS_NORMALIZATION 1
162#define udiv_qrnnd __udiv_qrnnd_c
163
164#define count_leading_zeros(count, x) \
165 do { \
166 u32 __xr = (x); \
167 u32 __a; \
168 \
169 if (SI_TYPE_SIZE <= 32) \
170 { \
171 __a = __xr < ((u32)1<<2*__BITS4) \
172 ? (__xr < ((u32)1<<__BITS4) ? 0 : __BITS4) \
173 : (__xr < ((u32)1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \
174 } \
175 else \
176 { \
177 for (__a = SI_TYPE_SIZE - 8; __a > 0; __a -= 8) \
178 if (((__xr >> __a) & 0xff) != 0) \
179 break; \
180 } \
181 \
182 (count) = SI_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \
183 } while (0)
diff --git a/arch/arm/lib/udivdi3.c b/arch/arm/lib/udivdi3.c
deleted file mode 100644
index e343be4c6642..000000000000
--- a/arch/arm/lib/udivdi3.c
+++ /dev/null
@@ -1,222 +0,0 @@
1/* More subroutines needed by GCC output code on some machines. */
2/* Compile this one with gcc. */
3/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
4
5This file is part of GNU CC.
6
7GNU CC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU CC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU CC; see the file COPYING. If not, write to
19the Free Software Foundation, 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */
21
22/* As a special exception, if you link this library with other files,
23 some of which are compiled with GCC, to produce an executable,
24 this library does not by itself cause the resulting executable
25 to be covered by the GNU General Public License.
26 This exception does not however invalidate any other reasons why
27 the executable file might be covered by the GNU General Public License.
28 */
29/* support functions required by the kernel. based on code from gcc-2.95.3 */
30/* I Molton 29/07/01 */
31
32#include "gcclib.h"
33#include "longlong.h"
34
35static const u8 __clz_tab[] = {
36 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5,
37 5, 5, 5, 5, 5, 5, 5, 5,
38 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
39 6, 6, 6, 6, 6, 6, 6, 6,
40 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
41 7, 7, 7, 7, 7, 7, 7, 7,
42 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
43 7, 7, 7, 7, 7, 7, 7, 7,
44 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
45 8, 8, 8, 8, 8, 8, 8, 8,
46 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
47 8, 8, 8, 8, 8, 8, 8, 8,
48 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
49 8, 8, 8, 8, 8, 8, 8, 8,
50 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
51 8, 8, 8, 8, 8, 8, 8, 8,
52};
53
54u64 __udivmoddi4(u64 n, u64 d, u64 * rp)
55{
56 DIunion ww;
57 DIunion nn, dd;
58 DIunion rr;
59 u32 d0, d1, n0, n1, n2;
60 u32 q0, q1;
61 u32 b, bm;
62
63 nn.ll = n;
64 dd.ll = d;
65
66 d0 = dd.s.low;
67 d1 = dd.s.high;
68 n0 = nn.s.low;
69 n1 = nn.s.high;
70
71 if (d1 == 0) {
72 if (d0 > n1) {
73 /* 0q = nn / 0D */
74
75 count_leading_zeros(bm, d0);
76
77 if (bm != 0) {
78 /* Normalize, i.e. make the most significant bit of the
79 denominator set. */
80
81 d0 = d0 << bm;
82 n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
83 n0 = n0 << bm;
84 }
85
86 udiv_qrnnd(q0, n0, n1, n0, d0);
87 q1 = 0;
88
89 /* Remainder in n0 >> bm. */
90 } else {
91 /* qq = NN / 0d */
92
93 if (d0 == 0)
94 d0 = 1 / d0; /* Divide intentionally by zero. */
95
96 count_leading_zeros(bm, d0);
97
98 if (bm == 0) {
99 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
100 conclude (the most significant bit of n1 is set) /\ (the
101 leading quotient digit q1 = 1).
102
103 This special case is necessary, not an optimization.
104 (Shifts counts of SI_TYPE_SIZE are undefined.) */
105
106 n1 -= d0;
107 q1 = 1;
108 } else {
109 /* Normalize. */
110
111 b = SI_TYPE_SIZE - bm;
112
113 d0 = d0 << bm;
114 n2 = n1 >> b;
115 n1 = (n1 << bm) | (n0 >> b);
116 n0 = n0 << bm;
117
118 udiv_qrnnd(q1, n1, n2, n1, d0);
119 }
120
121 /* n1 != d0... */
122
123 udiv_qrnnd(q0, n0, n1, n0, d0);
124
125 /* Remainder in n0 >> bm. */
126 }
127
128 if (rp != 0) {
129 rr.s.low = n0 >> bm;
130 rr.s.high = 0;
131 *rp = rr.ll;
132 }
133 } else {
134 if (d1 > n1) {
135 /* 00 = nn / DD */
136
137 q0 = 0;
138 q1 = 0;
139
140 /* Remainder in n1n0. */
141 if (rp != 0) {
142 rr.s.low = n0;
143 rr.s.high = n1;
144 *rp = rr.ll;
145 }
146 } else {
147 /* 0q = NN / dd */
148
149 count_leading_zeros(bm, d1);
150 if (bm == 0) {
151 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
152 conclude (the most significant bit of n1 is set) /\ (the
153 quotient digit q0 = 0 or 1).
154
155 This special case is necessary, not an optimization. */
156
157 /* The condition on the next line takes advantage of that
158 n1 >= d1 (true due to program flow). */
159 if (n1 > d1 || n0 >= d0) {
160 q0 = 1;
161 sub_ddmmss(n1, n0, n1, n0, d1, d0);
162 } else
163 q0 = 0;
164
165 q1 = 0;
166
167 if (rp != 0) {
168 rr.s.low = n0;
169 rr.s.high = n1;
170 *rp = rr.ll;
171 }
172 } else {
173 u32 m1, m0;
174 /* Normalize. */
175
176 b = SI_TYPE_SIZE - bm;
177
178 d1 = (d1 << bm) | (d0 >> b);
179 d0 = d0 << bm;
180 n2 = n1 >> b;
181 n1 = (n1 << bm) | (n0 >> b);
182 n0 = n0 << bm;
183
184 udiv_qrnnd(q0, n1, n2, n1, d1);
185 umul_ppmm(m1, m0, q0, d0);
186
187 if (m1 > n1 || (m1 == n1 && m0 > n0)) {
188 q0--;
189 sub_ddmmss(m1, m0, m1, m0, d1, d0);
190 }
191
192 q1 = 0;
193
194 /* Remainder in (n1n0 - m1m0) >> bm. */
195 if (rp != 0) {
196 sub_ddmmss(n1, n0, n1, n0, m1, m0);
197 rr.s.low = (n1 << b) | (n0 >> bm);
198 rr.s.high = n1 >> bm;
199 *rp = rr.ll;
200 }
201 }
202 }
203 }
204
205 ww.s.low = q0;
206 ww.s.high = q1;
207 return ww.ll;
208}
209
210u64 __udivdi3(u64 n, u64 d)
211{
212 return __udivmoddi4(n, d, (u64 *) 0);
213}
214
215u64 __umoddi3(u64 u, u64 v)
216{
217 u64 w;
218
219 (void)__udivmoddi4(u, v, &w);
220
221 return w;
222}
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
index 9222e57bd872..dacbf504dae2 100644
--- a/arch/arm/mach-integrator/core.c
+++ b/arch/arm/mach-integrator/core.c
@@ -20,6 +20,7 @@
20#include <asm/irq.h> 20#include <asm/irq.h>
21#include <asm/io.h> 21#include <asm/io.h>
22#include <asm/hardware/amba.h> 22#include <asm/hardware/amba.h>
23#include <asm/hardware/arm_timer.h>
23#include <asm/arch/cm.h> 24#include <asm/arch/cm.h>
24#include <asm/system.h> 25#include <asm/system.h>
25#include <asm/leds.h> 26#include <asm/leds.h>
@@ -156,16 +157,6 @@ EXPORT_SYMBOL(cm_control);
156#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC) 157#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC)
157#endif 158#endif
158 159
159/*
160 * What does it look like?
161 */
162typedef struct TimerStruct {
163 unsigned long TimerLoad;
164 unsigned long TimerValue;
165 unsigned long TimerControl;
166 unsigned long TimerClear;
167} TimerStruct_t;
168
169static unsigned long timer_reload; 160static unsigned long timer_reload;
170 161
171/* 162/*
@@ -174,7 +165,6 @@ static unsigned long timer_reload;
174 */ 165 */
175unsigned long integrator_gettimeoffset(void) 166unsigned long integrator_gettimeoffset(void)
176{ 167{
177 volatile TimerStruct_t *timer1 = (TimerStruct_t *)TIMER1_VA_BASE;
178 unsigned long ticks1, ticks2, status; 168 unsigned long ticks1, ticks2, status;
179 169
180 /* 170 /*
@@ -183,11 +173,11 @@ unsigned long integrator_gettimeoffset(void)
183 * an interrupt. We get around this by ensuring that the 173 * an interrupt. We get around this by ensuring that the
184 * counter has not reloaded between our two reads. 174 * counter has not reloaded between our two reads.
185 */ 175 */
186 ticks2 = timer1->TimerValue & 0xffff; 176 ticks2 = readl(TIMER1_VA_BASE + TIMER_VALUE) & 0xffff;
187 do { 177 do {
188 ticks1 = ticks2; 178 ticks1 = ticks2;
189 status = __raw_readl(VA_IC_BASE + IRQ_RAW_STATUS); 179 status = __raw_readl(VA_IC_BASE + IRQ_RAW_STATUS);
190 ticks2 = timer1->TimerValue & 0xffff; 180 ticks2 = readl(TIMER1_VA_BASE + TIMER_VALUE) & 0xffff;
191 } while (ticks2 > ticks1); 181 } while (ticks2 > ticks1);
192 182
193 /* 183 /*
@@ -213,14 +203,12 @@ unsigned long integrator_gettimeoffset(void)
213static irqreturn_t 203static irqreturn_t
214integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) 204integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
215{ 205{
216 volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE;
217
218 write_seqlock(&xtime_lock); 206 write_seqlock(&xtime_lock);
219 207
220 /* 208 /*
221 * clear the interrupt 209 * clear the interrupt
222 */ 210 */
223 timer1->TimerClear = 1; 211 writel(1, TIMER1_VA_BASE + TIMER_INTCLR);
224 212
225 /* 213 /*
226 * the clock tick routines are only processed on the 214 * the clock tick routines are only processed on the
@@ -256,32 +244,29 @@ static struct irqaction integrator_timer_irq = {
256 */ 244 */
257void __init integrator_time_init(unsigned long reload, unsigned int ctrl) 245void __init integrator_time_init(unsigned long reload, unsigned int ctrl)
258{ 246{
259 volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE; 247 unsigned int timer_ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC;
260 volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE;
261 volatile TimerStruct_t *timer2 = (volatile TimerStruct_t *)TIMER2_VA_BASE;
262 unsigned int timer_ctrl = 0x80 | 0x40; /* periodic */
263 248
264 timer_reload = reload; 249 timer_reload = reload;
265 timer_ctrl |= ctrl; 250 timer_ctrl |= ctrl;
266 251
267 if (timer_reload > 0x100000) { 252 if (timer_reload > 0x100000) {
268 timer_reload >>= 8; 253 timer_reload >>= 8;
269 timer_ctrl |= 0x08; /* /256 */ 254 timer_ctrl |= TIMER_CTRL_DIV256;
270 } else if (timer_reload > 0x010000) { 255 } else if (timer_reload > 0x010000) {
271 timer_reload >>= 4; 256 timer_reload >>= 4;
272 timer_ctrl |= 0x04; /* /16 */ 257 timer_ctrl |= TIMER_CTRL_DIV16;
273 } 258 }
274 259
275 /* 260 /*
276 * Initialise to a known state (all timers off) 261 * Initialise to a known state (all timers off)
277 */ 262 */
278 timer0->TimerControl = 0; 263 writel(0, TIMER0_VA_BASE + TIMER_CTRL);
279 timer1->TimerControl = 0; 264 writel(0, TIMER1_VA_BASE + TIMER_CTRL);
280 timer2->TimerControl = 0; 265 writel(0, TIMER2_VA_BASE + TIMER_CTRL);
281 266
282 timer1->TimerLoad = timer_reload; 267 writel(timer_reload, TIMER1_VA_BASE + TIMER_LOAD);
283 timer1->TimerValue = timer_reload; 268 writel(timer_reload, TIMER1_VA_BASE + TIMER_VALUE);
284 timer1->TimerControl = timer_ctrl; 269 writel(timer_ctrl, TIMER1_VA_BASE + TIMER_CTRL);
285 270
286 /* 271 /*
287 * Make irqs happen for the system timer 272 * Make irqs happen for the system timer
diff --git a/arch/arm/mach-omap/pm.c b/arch/arm/mach-omap/pm.c
index 00fac155df2a..6b03ccdc1e92 100644
--- a/arch/arm/mach-omap/pm.c
+++ b/arch/arm/mach-omap/pm.c
@@ -41,7 +41,9 @@
41#include <linux/pm.h> 41#include <linux/pm.h>
42 42
43#include <asm/io.h> 43#include <asm/io.h>
44#include <asm/mach/time.h>
44#include <asm/mach-types.h> 45#include <asm/mach-types.h>
46
45#include <asm/arch/omap16xx.h> 47#include <asm/arch/omap16xx.h>
46#include <asm/arch/pm.h> 48#include <asm/arch/pm.h>
47#include <asm/arch/mux.h> 49#include <asm/arch/mux.h>
@@ -80,13 +82,13 @@ void omap_pm_idle(void)
80 return; 82 return;
81 } 83 }
82 mask32 = omap_readl(ARM_SYSST); 84 mask32 = omap_readl(ARM_SYSST);
83 local_fiq_enable();
84 local_irq_enable();
85 85
86#if defined(CONFIG_OMAP_32K_TIMER) && defined(CONFIG_NO_IDLE_HZ) 86 /*
87 /* Override timer to use VST for the next cycle */ 87 * Since an interrupt may set up a timer, we don't want to
88 omap_32k_timer_next_vst_interrupt(); 88 * reprogram the hardware timer with interrupts enabled.
89#endif 89 * Re-enable interrupts only after returning from idle.
90 */
91 timer_dyn_reprogram();
90 92
91 if ((mask32 & DSP_IDLE) == 0) { 93 if ((mask32 & DSP_IDLE) == 0) {
92 __asm__ volatile ("mcr p15, 0, r0, c7, c0, 4"); 94 __asm__ volatile ("mcr p15, 0, r0, c7, c0, 4");
@@ -102,6 +104,8 @@ void omap_pm_idle(void)
102 104
103 func_ptr(); 105 func_ptr();
104 } 106 }
107 local_fiq_enable();
108 local_irq_enable();
105} 109}
106 110
107/* 111/*
diff --git a/arch/arm/mach-omap/time.c b/arch/arm/mach-omap/time.c
index 589e8b2740dd..dd34e9f4c413 100644
--- a/arch/arm/mach-omap/time.c
+++ b/arch/arm/mach-omap/time.c
@@ -4,7 +4,7 @@
4 * OMAP Timers 4 * OMAP Timers
5 * 5 *
6 * Copyright (C) 2004 Nokia Corporation 6 * Copyright (C) 2004 Nokia Corporation
7 * Partial timer rewrite and additional VST timer support by 7 * Partial timer rewrite and additional dynamic tick timer support by
8 * Tony Lindgen <tony@atomide.com> and 8 * Tony Lindgen <tony@atomide.com> and
9 * Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com> 9 * Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
10 * 10 *
@@ -261,7 +261,6 @@ unsigned long long sched_clock(void)
261 * so with HZ = 100, TVR = 327.68. 261 * so with HZ = 100, TVR = 327.68.
262 */ 262 */
263#define OMAP_32K_TIMER_TICK_PERIOD ((32768 / HZ) - 1) 263#define OMAP_32K_TIMER_TICK_PERIOD ((32768 / HZ) - 1)
264#define MAX_SKIP_JIFFIES 25
265#define TIMER_32K_SYNCHRONIZED 0xfffbc410 264#define TIMER_32K_SYNCHRONIZED 0xfffbc410
266 265
267#define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate) \ 266#define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate) \
@@ -347,6 +346,42 @@ static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id,
347 return IRQ_HANDLED; 346 return IRQ_HANDLED;
348} 347}
349 348
349#ifdef CONFIG_NO_IDLE_HZ
350/*
351 * Programs the next timer interrupt needed. Called when dynamic tick is
352 * enabled, and to reprogram the ticks to skip from pm_idle. Note that
353 * we can keep the timer continuous, and don't need to set it to run in
354 * one-shot mode. This is because the timer will get reprogrammed again
355 * after next interrupt.
356 */
357void omap_32k_timer_reprogram(unsigned long next_tick)
358{
359 omap_32k_timer_start(JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1);
360}
361
362static struct irqaction omap_32k_timer_irq;
363extern struct timer_update_handler timer_update;
364
365static int omap_32k_timer_enable_dyn_tick(void)
366{
367 /* No need to reprogram timer, just use the next interrupt */
368 return 0;
369}
370
371static int omap_32k_timer_disable_dyn_tick(void)
372{
373 omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD);
374 return 0;
375}
376
377static struct dyn_tick_timer omap_dyn_tick_timer = {
378 .enable = omap_32k_timer_enable_dyn_tick,
379 .disable = omap_32k_timer_disable_dyn_tick,
380 .reprogram = omap_32k_timer_reprogram,
381 .handler = omap_32k_timer_interrupt,
382};
383#endif /* CONFIG_NO_IDLE_HZ */
384
350static struct irqaction omap_32k_timer_irq = { 385static struct irqaction omap_32k_timer_irq = {
351 .name = "32KHz timer", 386 .name = "32KHz timer",
352 .flags = SA_INTERRUPT | SA_TIMER, 387 .flags = SA_INTERRUPT | SA_TIMER,
@@ -355,6 +390,11 @@ static struct irqaction omap_32k_timer_irq = {
355 390
356static __init void omap_init_32k_timer(void) 391static __init void omap_init_32k_timer(void)
357{ 392{
393
394#ifdef CONFIG_NO_IDLE_HZ
395 omap_timer.dyn_tick = &omap_dyn_tick_timer;
396#endif
397
358 setup_irq(INT_OS_TIMER, &omap_32k_timer_irq); 398 setup_irq(INT_OS_TIMER, &omap_32k_timer_irq);
359 omap_timer.offset = omap_32k_timer_gettimeoffset; 399 omap_timer.offset = omap_32k_timer_gettimeoffset;
360 omap_32k_last_tick = omap_32k_sync_timer_read(); 400 omap_32k_last_tick = omap_32k_sync_timer_read();
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig
index 534df0c6c770..d4d03d0daaec 100644
--- a/arch/arm/mach-s3c2410/Kconfig
+++ b/arch/arm/mach-s3c2410/Kconfig
@@ -154,6 +154,11 @@ config S3C2410_PM_CHECK_CHUNKSIZE
154 the CRC data block will take more memory, but wil identify any 154 the CRC data block will take more memory, but wil identify any
155 faults with better precision. 155 faults with better precision.
156 156
157config PM_SIMTEC
158 bool
159 depends on PM && (ARCH_BAST || MACH_VR1000)
160 default y
161
157config S3C2410_LOWLEVEL_UART_PORT 162config S3C2410_LOWLEVEL_UART_PORT
158 int "S3C2410 UART to use for low-level messages" 163 int "S3C2410 UART to use for low-level messages"
159 default 0 164 default 0
diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile
index 7c379aad5d62..f99b689e4392 100644
--- a/arch/arm/mach-s3c2410/Makefile
+++ b/arch/arm/mach-s3c2410/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_S3C2410_DMA) += dma.o
18# Power Management support 18# Power Management support
19 19
20obj-$(CONFIG_PM) += pm.o sleep.o 20obj-$(CONFIG_PM) += pm.o sleep.o
21obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o
21 22
22# S3C2440 support 23# S3C2440 support
23 24
diff --git a/arch/arm/mach-s3c2410/devs.c b/arch/arm/mach-s3c2410/devs.c
index 64792f678668..4664bd11adc1 100644
--- a/arch/arm/mach-s3c2410/devs.c
+++ b/arch/arm/mach-s3c2410/devs.c
@@ -96,8 +96,8 @@ struct platform_device s3c_device_lcd = {
96 .num_resources = ARRAY_SIZE(s3c_lcd_resource), 96 .num_resources = ARRAY_SIZE(s3c_lcd_resource),
97 .resource = s3c_lcd_resource, 97 .resource = s3c_lcd_resource,
98 .dev = { 98 .dev = {
99 .dma_mask = &s3c_device_lcd_dmamask, 99 .dma_mask = &s3c_device_lcd_dmamask,
100 .coherent_dma_mask = 0xffffffffUL 100 .coherent_dma_mask = 0xffffffffUL
101 } 101 }
102}; 102};
103 103
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index f3e970039b65..549bcb1f32c0 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -27,6 +27,7 @@
27 * 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA 27 * 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
28 * 14-Mar-2006 BJD Updated for __iomem changes 28 * 14-Mar-2006 BJD Updated for __iomem changes
29 * 22-Jun-2006 BJD Added DM9000 platform information 29 * 22-Jun-2006 BJD Added DM9000 platform information
30 * 28-Jun-2006 BJD Moved pm functionality out to common code
30*/ 31*/
31 32
32#include <linux/kernel.h> 33#include <linux/kernel.h>
@@ -67,7 +68,6 @@
67#include "devs.h" 68#include "devs.h"
68#include "cpu.h" 69#include "cpu.h"
69#include "usb-simtec.h" 70#include "usb-simtec.h"
70#include "pm.h"
71 71
72#define COPYRIGHT ", (c) 2004-2005 Simtec Electronics" 72#define COPYRIGHT ", (c) 2004-2005 Simtec Electronics"
73 73
@@ -405,44 +405,13 @@ void __init bast_map_io(void)
405 usb_simtec_init(); 405 usb_simtec_init();
406} 406}
407 407
408void __init bast_init_irq(void)
409{
410 s3c24xx_init_irq();
411}
412
413#ifdef CONFIG_PM
414
415/* bast_init_machine
416 *
417 * enable the power management functions for the EB2410ITX
418*/
419
420static __init void bast_init_machine(void)
421{
422 unsigned long gstatus4;
423
424 printk(KERN_INFO "BAST Power Manangement" COPYRIGHT "\n");
425
426 gstatus4 = (__raw_readl(S3C2410_BANKCON7) & 0x3) << 30;
427 gstatus4 |= (__raw_readl(S3C2410_BANKCON6) & 0x3) << 28;
428 gstatus4 |= (__raw_readl(S3C2410_BANKSIZE) & S3C2410_BANKSIZE_MASK);
429
430 __raw_writel(gstatus4, S3C2410_GSTATUS4);
431
432 s3c2410_pm_init();
433}
434
435#else
436#define bast_init_machine NULL
437#endif
438
439 408
440MACHINE_START(BAST, "Simtec-BAST") 409MACHINE_START(BAST, "Simtec-BAST")
441 MAINTAINER("Ben Dooks <ben@simtec.co.uk>") 410 MAINTAINER("Ben Dooks <ben@simtec.co.uk>")
442 BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) 411 BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART)
443 BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) 412 BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
444 MAPIO(bast_map_io) 413
445 INITIRQ(bast_init_irq) 414 .map_io = bast_map_io,
446 .init_machine = bast_init_machine, 415 .init_irq = s3c24xx_init_irq,
447 .timer = &s3c24xx_timer, 416 .timer = &s3c24xx_timer,
448MACHINE_END 417MACHINE_END
diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c
index 76be074944a0..1db2855e3e56 100644
--- a/arch/arm/mach-s3c2410/mach-vr1000.c
+++ b/arch/arm/mach-s3c2410/mach-vr1000.c
@@ -371,16 +371,12 @@ void __init vr1000_map_io(void)
371 usb_simtec_init(); 371 usb_simtec_init();
372} 372}
373 373
374void __init vr1000_init_irq(void)
375{
376 s3c24xx_init_irq();
377}
378 374
379MACHINE_START(VR1000, "Thorcom-VR1000") 375MACHINE_START(VR1000, "Thorcom-VR1000")
380 MAINTAINER("Ben Dooks <ben@simtec.co.uk>") 376 MAINTAINER("Ben Dooks <ben@simtec.co.uk>")
381 BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) 377 BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART)
382 BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) 378 BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
383 MAPIO(vr1000_map_io) 379 .map_io = vr1000_map_io,
384 INITIRQ(vr1000_init_irq) 380 .init_irq = s3c24xx_init_irq,
385 .timer = &s3c24xx_timer, 381 .timer = &s3c24xx_timer,
386MACHINE_END 382MACHINE_END
diff --git a/arch/arm/mach-s3c2410/pm-simtec.c b/arch/arm/mach-s3c2410/pm-simtec.c
new file mode 100644
index 000000000000..2cb798832223
--- /dev/null
+++ b/arch/arm/mach-s3c2410/pm-simtec.c
@@ -0,0 +1,65 @@
1/* linux/arch/arm/mach-s3c2410/pm-simtec.c
2 *
3 * Copyright (c) 2004 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * http://armlinux.simtec.co.uk/
7 *
8 * Power Management helpers for Simtec S3C24XX implementations
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#include <linux/kernel.h>
16#include <linux/types.h>
17#include <linux/interrupt.h>
18#include <linux/list.h>
19#include <linux/timer.h>
20#include <linux/init.h>
21#include <linux/device.h>
22
23#include <asm/mach/arch.h>
24#include <asm/mach/map.h>
25
26#include <asm/hardware.h>
27#include <asm/io.h>
28
29#include <asm/arch/map.h>
30#include <asm/arch/regs-serial.h>
31#include <asm/arch/regs-gpio.h>
32#include <asm/arch/regs-mem.h>
33
34#include <asm/mach-types.h>
35
36#include "pm.h"
37
38#define COPYRIGHT ", (c) 2005 Simtec Electronics"
39
40/* pm_simtec_init
41 *
42 * enable the power management functions
43*/
44
45static __init int pm_simtec_init(void)
46{
47 unsigned long gstatus4;
48
49 /* check which machine we are running on */
50
51 if (!machine_is_bast() && !machine_is_vr1000())
52 return 0;
53
54 printk(KERN_INFO "Simtec Board Power Manangement" COPYRIGHT "\n");
55
56 gstatus4 = (__raw_readl(S3C2410_BANKCON7) & 0x3) << 30;
57 gstatus4 |= (__raw_readl(S3C2410_BANKCON6) & 0x3) << 28;
58 gstatus4 |= (__raw_readl(S3C2410_BANKSIZE) & S3C2410_BANKSIZE_MASK);
59
60 __raw_writel(gstatus4, S3C2410_GSTATUS4);
61
62 return s3c2410_pm_init();
63}
64
65arch_initcall(pm_simtec_init);
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 9d1f2253e987..f01c0f8a2bb3 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -33,6 +33,7 @@
33#include <asm/mach-types.h> 33#include <asm/mach-types.h>
34#include <asm/hardware/amba.h> 34#include <asm/hardware/amba.h>
35#include <asm/hardware/amba_clcd.h> 35#include <asm/hardware/amba_clcd.h>
36#include <asm/hardware/arm_timer.h>
36#include <asm/hardware/icst307.h> 37#include <asm/hardware/icst307.h>
37 38
38#include <asm/mach/arch.h> 39#include <asm/mach/arch.h>
@@ -788,38 +789,25 @@ void __init versatile_init(void)
788 */ 789 */
789#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10) 790#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10)
790#if TIMER_INTERVAL >= 0x100000 791#if TIMER_INTERVAL >= 0x100000
791#define TIMER_RELOAD (TIMER_INTERVAL >> 8) /* Divide by 256 */ 792#define TIMER_RELOAD (TIMER_INTERVAL >> 8)
792#define TIMER_CTRL 0x88 /* Enable, Clock / 256 */ 793#define TIMER_DIVISOR (TIMER_CTRL_DIV256)
793#define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC) 794#define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC)
794#elif TIMER_INTERVAL >= 0x10000 795#elif TIMER_INTERVAL >= 0x10000
795#define TIMER_RELOAD (TIMER_INTERVAL >> 4) /* Divide by 16 */ 796#define TIMER_RELOAD (TIMER_INTERVAL >> 4) /* Divide by 16 */
796#define TIMER_CTRL 0x84 /* Enable, Clock / 16 */ 797#define TIMER_DIVISOR (TIMER_CTRL_DIV16)
797#define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC) 798#define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC)
798#else 799#else
799#define TIMER_RELOAD (TIMER_INTERVAL) 800#define TIMER_RELOAD (TIMER_INTERVAL)
800#define TIMER_CTRL 0x80 /* Enable */ 801#define TIMER_DIVISOR (TIMER_CTRL_DIV1)
801#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC) 802#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC)
802#endif 803#endif
803 804
804#define TIMER_CTRL_IE (1 << 5) /* Interrupt Enable */
805
806/*
807 * What does it look like?
808 */
809typedef struct TimerStruct {
810 unsigned long TimerLoad;
811 unsigned long TimerValue;
812 unsigned long TimerControl;
813 unsigned long TimerClear;
814} TimerStruct_t;
815
816/* 805/*
817 * Returns number of ms since last clock interrupt. Note that interrupts 806 * Returns number of ms since last clock interrupt. Note that interrupts
818 * will have been disabled by do_gettimeoffset() 807 * will have been disabled by do_gettimeoffset()
819 */ 808 */
820static unsigned long versatile_gettimeoffset(void) 809static unsigned long versatile_gettimeoffset(void)
821{ 810{
822 volatile TimerStruct_t *timer0 = (TimerStruct_t *)TIMER0_VA_BASE;
823 unsigned long ticks1, ticks2, status; 811 unsigned long ticks1, ticks2, status;
824 812
825 /* 813 /*
@@ -828,11 +816,11 @@ static unsigned long versatile_gettimeoffset(void)
828 * an interrupt. We get around this by ensuring that the 816 * an interrupt. We get around this by ensuring that the
829 * counter has not reloaded between our two reads. 817 * counter has not reloaded between our two reads.
830 */ 818 */
831 ticks2 = timer0->TimerValue & 0xffff; 819 ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff;
832 do { 820 do {
833 ticks1 = ticks2; 821 ticks1 = ticks2;
834 status = __raw_readl(VA_IC_BASE + VIC_IRQ_RAW_STATUS); 822 status = __raw_readl(VA_IC_BASE + VIC_IRQ_RAW_STATUS);
835 ticks2 = timer0->TimerValue & 0xffff; 823 ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff;
836 } while (ticks2 > ticks1); 824 } while (ticks2 > ticks1);
837 825
838 /* 826 /*
@@ -859,12 +847,10 @@ static unsigned long versatile_gettimeoffset(void)
859 */ 847 */
860static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) 848static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
861{ 849{
862 volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE;
863
864 write_seqlock(&xtime_lock); 850 write_seqlock(&xtime_lock);
865 851
866 // ...clear the interrupt 852 // ...clear the interrupt
867 timer0->TimerClear = 1; 853 writel(1, TIMER0_VA_BASE + TIMER_INTCLR);
868 854
869 timer_tick(regs); 855 timer_tick(regs);
870 856
@@ -884,31 +870,32 @@ static struct irqaction versatile_timer_irq = {
884 */ 870 */
885static void __init versatile_timer_init(void) 871static void __init versatile_timer_init(void)
886{ 872{
887 volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE; 873 u32 val;
888 volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE;
889 volatile TimerStruct_t *timer2 = (volatile TimerStruct_t *)TIMER2_VA_BASE;
890 volatile TimerStruct_t *timer3 = (volatile TimerStruct_t *)TIMER3_VA_BASE;
891 874
892 /* 875 /*
893 * set clock frequency: 876 * set clock frequency:
894 * VERSATILE_REFCLK is 32KHz 877 * VERSATILE_REFCLK is 32KHz
895 * VERSATILE_TIMCLK is 1MHz 878 * VERSATILE_TIMCLK is 1MHz
896 */ 879 */
897 *(volatile unsigned int *)IO_ADDRESS(VERSATILE_SCTL_BASE) |= 880 val = readl(IO_ADDRESS(VERSATILE_SCTL_BASE));
898 ((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) | (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) | 881 writel((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) |
899 (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) | (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel)); 882 (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) |
883 (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) |
884 (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel) | val,
885 IO_ADDRESS(VERSATILE_SCTL_BASE));
900 886
901 /* 887 /*
902 * Initialise to a known state (all timers off) 888 * Initialise to a known state (all timers off)
903 */ 889 */
904 timer0->TimerControl = 0; 890 writel(0, TIMER0_VA_BASE + TIMER_CTRL);
905 timer1->TimerControl = 0; 891 writel(0, TIMER1_VA_BASE + TIMER_CTRL);
906 timer2->TimerControl = 0; 892 writel(0, TIMER2_VA_BASE + TIMER_CTRL);
907 timer3->TimerControl = 0; 893 writel(0, TIMER3_VA_BASE + TIMER_CTRL);
908 894
909 timer0->TimerLoad = TIMER_RELOAD; 895 writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_LOAD);
910 timer0->TimerValue = TIMER_RELOAD; 896 writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_VALUE);
911 timer0->TimerControl = TIMER_CTRL | 0x40 | TIMER_CTRL_IE; /* periodic + IE */ 897 writel(TIMER_DIVISOR | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC |
898 TIMER_CTRL_IE, TIMER0_VA_BASE + TIMER_CTRL);
912 899
913 /* 900 /*
914 * Make irqs happen for the system timer 901 * Make irqs happen for the system timer
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 6dcb23d64bf5..edffa47a4b2a 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -437,7 +437,7 @@ void __init paging_init(struct meminfo *mi, struct machine_desc *mdesc)
437 memtable_init(mi); 437 memtable_init(mi);
438 if (mdesc->map_io) 438 if (mdesc->map_io)
439 mdesc->map_io(); 439 mdesc->map_io();
440 flush_tlb_all(); 440 local_flush_tlb_all();
441 441
442 /* 442 /*
443 * initialise the zones within each node 443 * initialise the zones within each node
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
index 052ab443ec4e..c3bd503b43a2 100644
--- a/arch/arm/mm/mm-armv.c
+++ b/arch/arm/mm/mm-armv.c
@@ -682,7 +682,7 @@ void __init memtable_init(struct meminfo *mi)
682 } 682 }
683 683
684 flush_cache_all(); 684 flush_cache_all();
685 flush_tlb_all(); 685 local_flush_tlb_all();
686 686
687 top_pmd = pmd_off_k(0xffff0000); 687 top_pmd = pmd_off_k(0xffff0000);
688} 688}
diff --git a/arch/arm/vfp/vfp.h b/arch/arm/vfp/vfp.h
index 55a02bc994a3..4b97950984e9 100644
--- a/arch/arm/vfp/vfp.h
+++ b/arch/arm/vfp/vfp.h
@@ -117,7 +117,13 @@ static inline u64 vfp_estimate_div128to64(u64 nh, u64 nl, u64 m)
117 if (nh >= m) 117 if (nh >= m)
118 return ~0ULL; 118 return ~0ULL;
119 mh = m >> 32; 119 mh = m >> 32;
120 z = (mh << 32 <= nh) ? 0xffffffff00000000ULL : (nh / mh) << 32; 120 if (mh << 32 <= nh) {
121 z = 0xffffffff00000000ULL;
122 } else {
123 z = nh;
124 do_div(z, mh);
125 z <<= 32;
126 }
121 mul64to128(&termh, &terml, m, z); 127 mul64to128(&termh, &terml, m, z);
122 sub128(&remh, &reml, nh, nl, termh, terml); 128 sub128(&remh, &reml, nh, nl, termh, terml);
123 ml = m << 32; 129 ml = m << 32;
@@ -126,7 +132,12 @@ static inline u64 vfp_estimate_div128to64(u64 nh, u64 nl, u64 m)
126 add128(&remh, &reml, remh, reml, mh, ml); 132 add128(&remh, &reml, remh, reml, mh, ml);
127 } 133 }
128 remh = (remh << 32) | (reml >> 32); 134 remh = (remh << 32) | (reml >> 32);
129 z |= (mh << 32 <= remh) ? 0xffffffff : remh / mh; 135 if (mh << 32 <= remh) {
136 z |= 0xffffffff;
137 } else {
138 do_div(remh, mh);
139 z |= remh;
140 }
130 return z; 141 return z;
131} 142}
132 143
diff --git a/arch/arm/vfp/vfpdouble.c b/arch/arm/vfp/vfpdouble.c
index fa3053e84db5..b801cd66b6ea 100644
--- a/arch/arm/vfp/vfpdouble.c
+++ b/arch/arm/vfp/vfpdouble.c
@@ -32,6 +32,8 @@
32 */ 32 */
33#include <linux/kernel.h> 33#include <linux/kernel.h>
34#include <linux/bitops.h> 34#include <linux/bitops.h>
35
36#include <asm/div64.h>
35#include <asm/ptrace.h> 37#include <asm/ptrace.h>
36#include <asm/vfp.h> 38#include <asm/vfp.h>
37 39
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index 3aeedd2afc70..22f3da4e0829 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -89,7 +89,7 @@ void vfp_raise_sigfpe(unsigned int sicode, struct pt_regs *regs)
89 current->thread.error_code = 0; 89 current->thread.error_code = 0;
90 current->thread.trap_no = 6; 90 current->thread.trap_no = 6;
91 91
92 force_sig_info(SIGFPE, &info, current); 92 send_sig_info(SIGFPE, &info, current);
93} 93}
94 94
95static void vfp_panic(char *reason) 95static void vfp_panic(char *reason)
diff --git a/arch/arm/vfp/vfpsingle.c b/arch/arm/vfp/vfpsingle.c
index 6849fe35cb2e..14dd696ddeb1 100644
--- a/arch/arm/vfp/vfpsingle.c
+++ b/arch/arm/vfp/vfpsingle.c
@@ -32,6 +32,8 @@
32 */ 32 */
33#include <linux/kernel.h> 33#include <linux/kernel.h>
34#include <linux/bitops.h> 34#include <linux/bitops.h>
35
36#include <asm/div64.h>
35#include <asm/ptrace.h> 37#include <asm/ptrace.h>
36#include <asm/vfp.h> 38#include <asm/vfp.h>
37 39
@@ -303,7 +305,11 @@ u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand)
303 if (z <= a) 305 if (z <= a)
304 return (s32)a >> 1; 306 return (s32)a >> 1;
305 } 307 }
306 return (u32)(((u64)a << 31) / z) + (z >> 1); 308 {
309 u64 v = (u64)a << 31;
310 do_div(v, z);
311 return v + (z >> 1);
312 }
307} 313}
308 314
309static u32 vfp_single_fsqrt(int sd, int unused, s32 m, u32 fpscr) 315static u32 vfp_single_fsqrt(int sd, int unused, s32 m, u32 fpscr)
@@ -1107,7 +1113,11 @@ static u32 vfp_single_fdiv(int sd, int sn, s32 m, u32 fpscr)
1107 vsn.significand >>= 1; 1113 vsn.significand >>= 1;
1108 vsd.exponent++; 1114 vsd.exponent++;
1109 } 1115 }
1110 vsd.significand = ((u64)vsn.significand << 32) / vsm.significand; 1116 {
1117 u64 significand = (u64)vsn.significand << 32;
1118 do_div(significand, vsm.significand);
1119 vsd.significand = significand;
1120 }
1111 if ((vsd.significand & 0x3f) == 0) 1121 if ((vsd.significand & 0x3f) == 0)
1112 vsd.significand |= ((u64)vsm.significand * vsd.significand != (u64)vsn.significand << 32); 1122 vsd.significand |= ((u64)vsm.significand * vsd.significand != (u64)vsn.significand << 32);
1113 1123
diff --git a/drivers/net/arm/etherh.c b/drivers/net/arm/etherh.c
index 2e28c201dcc0..942a2819576c 100644
--- a/drivers/net/arm/etherh.c
+++ b/drivers/net/arm/etherh.c
@@ -68,7 +68,6 @@ struct etherh_priv {
68 void __iomem *dma_base; 68 void __iomem *dma_base;
69 unsigned int id; 69 unsigned int id;
70 void __iomem *ctrl_port; 70 void __iomem *ctrl_port;
71 void __iomem *base;
72 unsigned char ctrl; 71 unsigned char ctrl;
73 u32 supported; 72 u32 supported;
74}; 73};
@@ -178,7 +177,7 @@ etherh_setif(struct net_device *dev)
178 switch (etherh_priv(dev)->id) { 177 switch (etherh_priv(dev)->id) {
179 case PROD_I3_ETHERLAN600: 178 case PROD_I3_ETHERLAN600:
180 case PROD_I3_ETHERLAN600A: 179 case PROD_I3_ETHERLAN600A:
181 addr = etherh_priv(dev)->base + EN0_RCNTHI; 180 addr = (void *)dev->base_addr + EN0_RCNTHI;
182 181
183 switch (dev->if_port) { 182 switch (dev->if_port) {
184 case IF_PORT_10BASE2: 183 case IF_PORT_10BASE2:
@@ -219,7 +218,7 @@ etherh_getifstat(struct net_device *dev)
219 switch (etherh_priv(dev)->id) { 218 switch (etherh_priv(dev)->id) {
220 case PROD_I3_ETHERLAN600: 219 case PROD_I3_ETHERLAN600:
221 case PROD_I3_ETHERLAN600A: 220 case PROD_I3_ETHERLAN600A:
222 addr = etherh_priv(dev)->base + EN0_RCNTHI; 221 addr = (void *)dev->base_addr + EN0_RCNTHI;
223 switch (dev->if_port) { 222 switch (dev->if_port) {
224 case IF_PORT_10BASE2: 223 case IF_PORT_10BASE2:
225 stat = 1; 224 stat = 1;
@@ -282,7 +281,7 @@ static void
282etherh_reset(struct net_device *dev) 281etherh_reset(struct net_device *dev)
283{ 282{
284 struct ei_device *ei_local = netdev_priv(dev); 283 struct ei_device *ei_local = netdev_priv(dev);
285 void __iomem *addr = etherh_priv(dev)->base; 284 void __iomem *addr = (void *)dev->base_addr;
286 285
287 writeb(E8390_NODMA+E8390_PAGE0+E8390_STOP, addr); 286 writeb(E8390_NODMA+E8390_PAGE0+E8390_STOP, addr);
288 287
@@ -328,7 +327,7 @@ etherh_block_output (struct net_device *dev, int count, const unsigned char *buf
328 327
329 ei_local->dmaing = 1; 328 ei_local->dmaing = 1;
330 329
331 addr = etherh_priv(dev)->base; 330 addr = (void *)dev->base_addr;
332 dma_base = etherh_priv(dev)->dma_base; 331 dma_base = etherh_priv(dev)->dma_base;
333 332
334 count = (count + 1) & ~1; 333 count = (count + 1) & ~1;
@@ -388,7 +387,7 @@ etherh_block_input (struct net_device *dev, int count, struct sk_buff *skb, int
388 387
389 ei_local->dmaing = 1; 388 ei_local->dmaing = 1;
390 389
391 addr = etherh_priv(dev)->base; 390 addr = (void *)dev->base_addr;
392 dma_base = etherh_priv(dev)->dma_base; 391 dma_base = etherh_priv(dev)->dma_base;
393 392
394 buf = skb->data; 393 buf = skb->data;
@@ -428,7 +427,7 @@ etherh_get_header (struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_p
428 427
429 ei_local->dmaing = 1; 428 ei_local->dmaing = 1;
430 429
431 addr = etherh_priv(dev)->base; 430 addr = (void *)dev->base_addr;
432 dma_base = etherh_priv(dev)->dma_base; 431 dma_base = etherh_priv(dev)->dma_base;
433 432
434 writeb (E8390_NODMA | E8390_PAGE0 | E8390_START, addr + E8390_CMD); 433 writeb (E8390_NODMA | E8390_PAGE0 | E8390_START, addr + E8390_CMD);
@@ -697,8 +696,7 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id)
697 eh->ctrl_port = eh->ioc_fast; 696 eh->ctrl_port = eh->ioc_fast;
698 } 697 }
699 698
700 eh->base = eh->memc + data->ns8390_offset; 699 dev->base_addr = (unsigned long)eh->memc + data->ns8390_offset;
701 dev->base_addr = (unsigned long)eh->base;
702 eh->dma_base = eh->memc + data->dataport_offset; 700 eh->dma_base = eh->memc + data->dataport_offset;
703 eh->ctrl_port += data->ctrlport_offset; 701 eh->ctrl_port += data->ctrlport_offset;
704 702
diff --git a/include/asm-arm/arch-pxa/debug-macro.S b/include/asm-arm/arch-pxa/debug-macro.S
index f288e74b67c2..b6ec68879176 100644
--- a/include/asm-arm/arch-pxa/debug-macro.S
+++ b/include/asm-arm/arch-pxa/debug-macro.S
@@ -11,6 +11,8 @@
11 * 11 *
12*/ 12*/
13 13
14#include "hardware.h"
15
14 .macro addruart,rx 16 .macro addruart,rx
15 mrc p15, 0, \rx, c1, c0 17 mrc p15, 0, \rx, c1, c0
16 tst \rx, #1 @ MMU enabled? 18 tst \rx, #1 @ MMU enabled?
diff --git a/include/asm-arm/hardware/arm_timer.h b/include/asm-arm/hardware/arm_timer.h
new file mode 100644
index 000000000000..04be3bdf46b8
--- /dev/null
+++ b/include/asm-arm/hardware/arm_timer.h
@@ -0,0 +1,21 @@
1#ifndef __ASM_ARM_HARDWARE_ARM_TIMER_H
2#define __ASM_ARM_HARDWARE_ARM_TIMER_H
3
4#define TIMER_LOAD 0x00
5#define TIMER_VALUE 0x04
6#define TIMER_CTRL 0x08
7#define TIMER_CTRL_ONESHOT (1 << 0)
8#define TIMER_CTRL_32BIT (1 << 1)
9#define TIMER_CTRL_DIV1 (0 << 2)
10#define TIMER_CTRL_DIV16 (1 << 2)
11#define TIMER_CTRL_DIV256 (2 << 2)
12#define TIMER_CTRL_IE (1 << 5) /* Interrupt Enable (versatile only) */
13#define TIMER_CTRL_PERIODIC (1 << 6)
14#define TIMER_CTRL_ENABLE (1 << 7)
15
16#define TIMER_INTCLR 0x0c
17#define TIMER_RIS 0x10
18#define TIMER_MIS 0x14
19#define TIMER_BGLOAD 0x18
20
21#endif
diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h
index 3d0d2860b6db..cdf49f442fd2 100644
--- a/include/asm-arm/system.h
+++ b/include/asm-arm/system.h
@@ -290,7 +290,6 @@ do { \
290}) 290})
291 291
292#ifdef CONFIG_SMP 292#ifdef CONFIG_SMP
293#error SMP not supported
294 293
295#define smp_mb() mb() 294#define smp_mb() mb()
296#define smp_rmb() rmb() 295#define smp_rmb() rmb()
@@ -304,6 +303,8 @@ do { \
304#define smp_wmb() barrier() 303#define smp_wmb() barrier()
305#define smp_read_barrier_depends() do { } while(0) 304#define smp_read_barrier_depends() do { } while(0)
306 305
306#endif /* CONFIG_SMP */
307
307#if defined(CONFIG_CPU_SA1100) || defined(CONFIG_CPU_SA110) 308#if defined(CONFIG_CPU_SA1100) || defined(CONFIG_CPU_SA110)
308/* 309/*
309 * On the StrongARM, "swp" is terminally broken since it bypasses the 310 * On the StrongARM, "swp" is terminally broken since it bypasses the
@@ -316,9 +317,16 @@ do { \
316 * 317 *
317 * We choose (1) since its the "easiest" to achieve here and is not 318 * We choose (1) since its the "easiest" to achieve here and is not
318 * dependent on the processor type. 319 * dependent on the processor type.
320 *
321 * NOTE that this solution won't work on an SMP system, so explcitly
322 * forbid it here.
319 */ 323 */
324#ifdef CONFIG_SMP
325#error SMP is not supported on SA1100/SA110
326#else
320#define swp_is_buggy 327#define swp_is_buggy
321#endif 328#endif
329#endif
322 330
323static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size) 331static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
324{ 332{
@@ -361,8 +369,6 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size
361 return ret; 369 return ret;
362} 370}
363 371
364#endif /* CONFIG_SMP */
365
366#endif /* __ASSEMBLY__ */ 372#endif /* __ASSEMBLY__ */
367 373
368#define arch_align_stack(x) (x) 374#define arch_align_stack(x) (x)
diff --git a/include/asm-arm/tlbflush.h b/include/asm-arm/tlbflush.h
index 8a864b118569..9387a5e1ffe0 100644
--- a/include/asm-arm/tlbflush.h
+++ b/include/asm-arm/tlbflush.h
@@ -235,7 +235,7 @@ extern struct cpu_tlb_fns cpu_tlb;
235 235
236#define tlb_flag(f) ((always_tlb_flags & (f)) || (__tlb_flag & possible_tlb_flags & (f))) 236#define tlb_flag(f) ((always_tlb_flags & (f)) || (__tlb_flag & possible_tlb_flags & (f)))
237 237
238static inline void flush_tlb_all(void) 238static inline void local_flush_tlb_all(void)
239{ 239{
240 const int zero = 0; 240 const int zero = 0;
241 const unsigned int __tlb_flag = __cpu_tlb_flags; 241 const unsigned int __tlb_flag = __cpu_tlb_flags;
@@ -253,7 +253,7 @@ static inline void flush_tlb_all(void)
253 asm("mcr%? p15, 0, %0, c8, c5, 0" : : "r" (zero)); 253 asm("mcr%? p15, 0, %0, c8, c5, 0" : : "r" (zero));
254} 254}
255 255
256static inline void flush_tlb_mm(struct mm_struct *mm) 256static inline void local_flush_tlb_mm(struct mm_struct *mm)
257{ 257{
258 const int zero = 0; 258 const int zero = 0;
259 const int asid = ASID(mm); 259 const int asid = ASID(mm);
@@ -282,7 +282,7 @@ static inline void flush_tlb_mm(struct mm_struct *mm)
282} 282}
283 283
284static inline void 284static inline void
285flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) 285local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
286{ 286{
287 const int zero = 0; 287 const int zero = 0;
288 const unsigned int __tlb_flag = __cpu_tlb_flags; 288 const unsigned int __tlb_flag = __cpu_tlb_flags;
@@ -313,7 +313,7 @@ flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
313 asm("mcr%? p15, 0, %0, c8, c5, 1" : : "r" (uaddr)); 313 asm("mcr%? p15, 0, %0, c8, c5, 1" : : "r" (uaddr));
314} 314}
315 315
316static inline void flush_tlb_kernel_page(unsigned long kaddr) 316static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
317{ 317{
318 const int zero = 0; 318 const int zero = 0;
319 const unsigned int __tlb_flag = __cpu_tlb_flags; 319 const unsigned int __tlb_flag = __cpu_tlb_flags;
@@ -384,8 +384,24 @@ static inline void clean_pmd_entry(pmd_t *pmd)
384/* 384/*
385 * Convert calls to our calling convention. 385 * Convert calls to our calling convention.
386 */ 386 */
387#define flush_tlb_range(vma,start,end) __cpu_flush_user_tlb_range(start,end,vma) 387#define local_flush_tlb_range(vma,start,end) __cpu_flush_user_tlb_range(start,end,vma)
388#define flush_tlb_kernel_range(s,e) __cpu_flush_kern_tlb_range(s,e) 388#define local_flush_tlb_kernel_range(s,e) __cpu_flush_kern_tlb_range(s,e)
389
390#ifndef CONFIG_SMP
391#define flush_tlb_all local_flush_tlb_all
392#define flush_tlb_mm local_flush_tlb_mm
393#define flush_tlb_page local_flush_tlb_page
394#define flush_tlb_kernel_page local_flush_tlb_kernel_page
395#define flush_tlb_range local_flush_tlb_range
396#define flush_tlb_kernel_range local_flush_tlb_kernel_range
397#else
398extern void flush_tlb_all(void);
399extern void flush_tlb_mm(struct mm_struct *mm);
400extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr);
401extern void flush_tlb_kernel_page(unsigned long kaddr);
402extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end);
403extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
404#endif
389 405
390/* 406/*
391 * if PG_dcache_dirty is set for the page, we need to ensure that any 407 * if PG_dcache_dirty is set for the page, we need to ensure that any