aboutsummaryrefslogtreecommitdiffstats
path: root/arch/parisc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-01-09 14:53:07 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-01-09 14:53:07 -0500
commit29a41e9e029d21c306e3ad6e723700348b04706a (patch)
tree3c7f807016a1e16c70992bbcba1269ac4cfe2fa5 /arch/parisc
parentd9e8a3a5b8298a3c814ed37ac5756e6f67b6be41 (diff)
parentae16489eb1175066c8f3008fc3c0396c525e1906 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/kyle/parisc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/kyle/parisc-2.6: parisc: export length of os_hpmc vector parisc: fix kernel crash (protection id trap) when compiling ruby1.9 parisc: Use DEFINE_SPINLOCK parisc: add uevent helper for parisc bus parisc: fix ipv6 checksum parisc: quiet palo not-found message from "which" parisc: Replace NR_CPUS in parisc code parisc: trivial fixes parisc: fix braino in commit adding __space_to_prot parisc: factor out sid to protid conversion parisc: use leX_to_cpu in place of __fswabX parisc: fix GFP_KERNEL use while atomic in unwinder parisc: remove dead BIO_VMERGE_BOUNDARY and BIO_VMERGE_MAX_SIZE definitions parisc: set_time() catch errors parisc: use the new byteorder headers parisc: drivers/parisc/: make code static parisc: lib/: make code static
Diffstat (limited to 'arch/parisc')
-rw-r--r--arch/parisc/Makefile2
-rw-r--r--arch/parisc/include/asm/byteorder.h37
-rw-r--r--arch/parisc/include/asm/checksum.h2
-rw-r--r--arch/parisc/include/asm/io.h12
-rw-r--r--arch/parisc/include/asm/mmu_context.h13
-rw-r--r--arch/parisc/include/asm/processor.h4
-rw-r--r--arch/parisc/include/asm/uaccess.h2
-rw-r--r--arch/parisc/kernel/drivers.c40
-rw-r--r--arch/parisc/kernel/hpmc.S8
-rw-r--r--arch/parisc/kernel/irq.c11
-rw-r--r--arch/parisc/kernel/pdc_cons.c2
-rw-r--r--arch/parisc/kernel/perf.c4
-rw-r--r--arch/parisc/kernel/processor.c68
-rw-r--r--arch/parisc/kernel/setup.c11
-rw-r--r--arch/parisc/kernel/smp.c32
-rw-r--r--arch/parisc/kernel/time.c4
-rw-r--r--arch/parisc/kernel/topology.c4
-rw-r--r--arch/parisc/kernel/traps.c9
-rw-r--r--arch/parisc/kernel/unwind.c2
-rw-r--r--arch/parisc/lib/iomap.c2
-rw-r--r--arch/parisc/lib/memcpy.c2
-rw-r--r--arch/parisc/mm/fault.c58
22 files changed, 177 insertions, 152 deletions
diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile
index 5ddad7bd60ac..0d428278356d 100644
--- a/arch/parisc/Makefile
+++ b/arch/parisc/Makefile
@@ -77,7 +77,7 @@ libs-y += arch/parisc/lib/ `$(CC) -print-libgcc-file-name`
77 77
78drivers-$(CONFIG_OPROFILE) += arch/parisc/oprofile/ 78drivers-$(CONFIG_OPROFILE) += arch/parisc/oprofile/
79 79
80PALO := $(shell if which palo; then : ; \ 80PALO := $(shell if (which palo 2>&1); then : ; \
81 elif [ -x /sbin/palo ]; then echo /sbin/palo; \ 81 elif [ -x /sbin/palo ]; then echo /sbin/palo; \
82 fi) 82 fi)
83 83
diff --git a/arch/parisc/include/asm/byteorder.h b/arch/parisc/include/asm/byteorder.h
index db148313de5d..83095c5bb379 100644
--- a/arch/parisc/include/asm/byteorder.h
+++ b/arch/parisc/include/asm/byteorder.h
@@ -4,9 +4,10 @@
4#include <asm/types.h> 4#include <asm/types.h>
5#include <linux/compiler.h> 5#include <linux/compiler.h>
6 6
7#ifdef __GNUC__ 7#define __BIG_ENDIAN
8#define __SWAB_64_THRU_32__
8 9
9static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 x) 10static inline __attribute_const__ __u16 __arch_swab16(__u16 x)
10{ 11{
11 __asm__("dep %0, 15, 8, %0\n\t" /* deposit 00ab -> 0bab */ 12 __asm__("dep %0, 15, 8, %0\n\t" /* deposit 00ab -> 0bab */
12 "shd %%r0, %0, 8, %0" /* shift 000000ab -> 00ba */ 13 "shd %%r0, %0, 8, %0" /* shift 000000ab -> 00ba */
@@ -14,8 +15,9 @@ static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 x)
14 : "0" (x)); 15 : "0" (x));
15 return x; 16 return x;
16} 17}
18#define __arch_swab16 __arch_swab16
17 19
18static __inline__ __attribute_const__ __u32 ___arch__swab24(__u32 x) 20static inline __attribute_const__ __u32 __arch_swab24(__u32 x)
19{ 21{
20 __asm__("shd %0, %0, 8, %0\n\t" /* shift xabcxabc -> cxab */ 22 __asm__("shd %0, %0, 8, %0\n\t" /* shift xabcxabc -> cxab */
21 "dep %0, 15, 8, %0\n\t" /* deposit cxab -> cbab */ 23 "dep %0, 15, 8, %0\n\t" /* deposit cxab -> cbab */
@@ -25,7 +27,7 @@ static __inline__ __attribute_const__ __u32 ___arch__swab24(__u32 x)
25 return x; 27 return x;
26} 28}
27 29
28static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x) 30static inline __attribute_const__ __u32 __arch_swab32(__u32 x)
29{ 31{
30 unsigned int temp; 32 unsigned int temp;
31 __asm__("shd %0, %0, 16, %1\n\t" /* shift abcdabcd -> cdab */ 33 __asm__("shd %0, %0, 16, %1\n\t" /* shift abcdabcd -> cdab */
@@ -35,7 +37,7 @@ static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x)
35 : "0" (x)); 37 : "0" (x));
36 return x; 38 return x;
37} 39}
38 40#define __arch_swab32 __arch_swab32
39 41
40#if BITS_PER_LONG > 32 42#if BITS_PER_LONG > 32
41/* 43/*
@@ -48,7 +50,8 @@ static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x)
48** HSHR 67452301 -> *6*4*2*0 into %0 50** HSHR 67452301 -> *6*4*2*0 into %0
49** OR %0 | %1 -> 76543210 into %0 (all done!) 51** OR %0 | %1 -> 76543210 into %0 (all done!)
50*/ 52*/
51static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 x) { 53static inline __attribute_const__ __u64 __arch_swab64(__u64 x)
54{
52 __u64 temp; 55 __u64 temp;
53 __asm__("permh,3210 %0, %0\n\t" 56 __asm__("permh,3210 %0, %0\n\t"
54 "hshl %0, 8, %1\n\t" 57 "hshl %0, 8, %1\n\t"
@@ -58,25 +61,9 @@ static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 x) {
58 : "0" (x)); 61 : "0" (x));
59 return x; 62 return x;
60} 63}
61#define __arch__swab64(x) ___arch__swab64(x) 64#define __arch_swab64 __arch_swab64
62#define __BYTEORDER_HAS_U64__ 65#endif /* BITS_PER_LONG > 32 */
63#elif !defined(__STRICT_ANSI__)
64static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 x)
65{
66 __u32 t1 = ___arch__swab32((__u32) x);
67 __u32 t2 = ___arch__swab32((__u32) (x >> 32));
68 return (((__u64) t1 << 32) | t2);
69}
70#define __arch__swab64(x) ___arch__swab64(x)
71#define __BYTEORDER_HAS_U64__
72#endif
73
74#define __arch__swab16(x) ___arch__swab16(x)
75#define __arch__swab24(x) ___arch__swab24(x)
76#define __arch__swab32(x) ___arch__swab32(x)
77
78#endif /* __GNUC__ */
79 66
80#include <linux/byteorder/big_endian.h> 67#include <linux/byteorder.h>
81 68
82#endif /* _PARISC_BYTEORDER_H */ 69#endif /* _PARISC_BYTEORDER_H */
diff --git a/arch/parisc/include/asm/checksum.h b/arch/parisc/include/asm/checksum.h
index e9639ccc3fce..c84b2fcb18a9 100644
--- a/arch/parisc/include/asm/checksum.h
+++ b/arch/parisc/include/asm/checksum.h
@@ -182,7 +182,7 @@ static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
182#endif 182#endif
183 : "=r" (sum), "=r" (saddr), "=r" (daddr), "=r" (len) 183 : "=r" (sum), "=r" (saddr), "=r" (daddr), "=r" (len)
184 : "0" (sum), "1" (saddr), "2" (daddr), "3" (len), "r" (proto) 184 : "0" (sum), "1" (saddr), "2" (daddr), "3" (len), "r" (proto)
185 : "r19", "r20", "r21", "r22"); 185 : "r19", "r20", "r21", "r22", "memory");
186 return csum_fold(sum); 186 return csum_fold(sum);
187} 187}
188 188
diff --git a/arch/parisc/include/asm/io.h b/arch/parisc/include/asm/io.h
index 55ddb1842107..d3031d1f9d03 100644
--- a/arch/parisc/include/asm/io.h
+++ b/arch/parisc/include/asm/io.h
@@ -4,12 +4,6 @@
4#include <linux/types.h> 4#include <linux/types.h>
5#include <asm/pgtable.h> 5#include <asm/pgtable.h>
6 6
7extern unsigned long parisc_vmerge_boundary;
8extern unsigned long parisc_vmerge_max_size;
9
10#define BIO_VMERGE_BOUNDARY parisc_vmerge_boundary
11#define BIO_VMERGE_MAX_SIZE parisc_vmerge_max_size
12
13#define virt_to_phys(a) ((unsigned long)__pa(a)) 7#define virt_to_phys(a) ((unsigned long)__pa(a))
14#define phys_to_virt(a) __va(a) 8#define phys_to_virt(a) __va(a)
15#define virt_to_bus virt_to_phys 9#define virt_to_bus virt_to_phys
@@ -182,9 +176,9 @@ static inline void __raw_writeq(unsigned long long b, volatile void __iomem *add
182 176
183/* readb can never be const, so use __fswab instead of le*_to_cpu */ 177/* readb can never be const, so use __fswab instead of le*_to_cpu */
184#define readb(addr) __raw_readb(addr) 178#define readb(addr) __raw_readb(addr)
185#define readw(addr) __fswab16(__raw_readw(addr)) 179#define readw(addr) le16_to_cpu(__raw_readw(addr))
186#define readl(addr) __fswab32(__raw_readl(addr)) 180#define readl(addr) le32_to_cpu(__raw_readl(addr))
187#define readq(addr) __fswab64(__raw_readq(addr)) 181#define readq(addr) le64_to_cpu(__raw_readq(addr))
188#define writeb(b, addr) __raw_writeb(b, addr) 182#define writeb(b, addr) __raw_writeb(b, addr)
189#define writew(b, addr) __raw_writew(cpu_to_le16(b), addr) 183#define writew(b, addr) __raw_writew(cpu_to_le16(b), addr)
190#define writel(b, addr) __raw_writel(cpu_to_le32(b), addr) 184#define writel(b, addr) __raw_writel(cpu_to_le32(b), addr)
diff --git a/arch/parisc/include/asm/mmu_context.h b/arch/parisc/include/asm/mmu_context.h
index 85856c74ad1d..354b2aca990e 100644
--- a/arch/parisc/include/asm/mmu_context.h
+++ b/arch/parisc/include/asm/mmu_context.h
@@ -34,16 +34,21 @@ destroy_context(struct mm_struct *mm)
34 mm->context = 0; 34 mm->context = 0;
35} 35}
36 36
37static inline void load_context(mm_context_t context) 37static inline unsigned long __space_to_prot(mm_context_t context)
38{ 38{
39 mtsp(context, 3);
40#if SPACEID_SHIFT == 0 39#if SPACEID_SHIFT == 0
41 mtctl(context << 1,8); 40 return context << 1;
42#else 41#else
43 mtctl(context >> (SPACEID_SHIFT - 1),8); 42 return context >> (SPACEID_SHIFT - 1);
44#endif 43#endif
45} 44}
46 45
46static inline void load_context(mm_context_t context)
47{
48 mtsp(context, 3);
49 mtctl(__space_to_prot(context), 8);
50}
51
47static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk) 52static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk)
48{ 53{
49 54
diff --git a/arch/parisc/include/asm/processor.h b/arch/parisc/include/asm/processor.h
index 3c9d34844c83..9d64df8754ba 100644
--- a/arch/parisc/include/asm/processor.h
+++ b/arch/parisc/include/asm/processor.h
@@ -17,6 +17,7 @@
17#include <asm/ptrace.h> 17#include <asm/ptrace.h>
18#include <asm/types.h> 18#include <asm/types.h>
19#include <asm/system.h> 19#include <asm/system.h>
20#include <asm/percpu.h>
20#endif /* __ASSEMBLY__ */ 21#endif /* __ASSEMBLY__ */
21 22
22#define KERNEL_STACK_SIZE (4*PAGE_SIZE) 23#define KERNEL_STACK_SIZE (4*PAGE_SIZE)
@@ -109,8 +110,7 @@ struct cpuinfo_parisc {
109}; 110};
110 111
111extern struct system_cpuinfo_parisc boot_cpu_data; 112extern struct system_cpuinfo_parisc boot_cpu_data;
112extern struct cpuinfo_parisc cpu_data[NR_CPUS]; 113DECLARE_PER_CPU(struct cpuinfo_parisc, cpu_data);
113#define current_cpu_data cpu_data[smp_processor_id()]
114 114
115#define CPU_HVERSION ((boot_cpu_data.hversion >> 4) & 0x0FFF) 115#define CPU_HVERSION ((boot_cpu_data.hversion >> 4) & 0x0FFF)
116 116
diff --git a/arch/parisc/include/asm/uaccess.h b/arch/parisc/include/asm/uaccess.h
index 4878b9501f24..1c6dbb6f6e56 100644
--- a/arch/parisc/include/asm/uaccess.h
+++ b/arch/parisc/include/asm/uaccess.h
@@ -241,4 +241,6 @@ unsigned long copy_in_user(void __user *dst, const void __user *src, unsigned lo
241#define __copy_to_user_inatomic __copy_to_user 241#define __copy_to_user_inatomic __copy_to_user
242#define __copy_from_user_inatomic __copy_from_user 242#define __copy_from_user_inatomic __copy_from_user
243 243
244int fixup_exception(struct pt_regs *regs);
245
244#endif /* __PARISC_UACCESS_H */ 246#endif /* __PARISC_UACCESS_H */
diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c
index 884b7ce16a3b..994bcd980909 100644
--- a/arch/parisc/kernel/drivers.c
+++ b/arch/parisc/kernel/drivers.c
@@ -549,6 +549,38 @@ static int parisc_generic_match(struct device *dev, struct device_driver *drv)
549 return match_device(to_parisc_driver(drv), to_parisc_device(dev)); 549 return match_device(to_parisc_driver(drv), to_parisc_device(dev));
550} 550}
551 551
552static ssize_t make_modalias(struct device *dev, char *buf)
553{
554 const struct parisc_device *padev = to_parisc_device(dev);
555 const struct parisc_device_id *id = &padev->id;
556
557 return sprintf(buf, "parisc:t%02Xhv%04Xrev%02Xsv%08X\n",
558 (u8)id->hw_type, (u16)id->hversion, (u8)id->hversion_rev,
559 (u32)id->sversion);
560}
561
562static int parisc_uevent(struct device *dev, struct kobj_uevent_env *env)
563{
564 const struct parisc_device *padev;
565 char modalias[40];
566
567 if (!dev)
568 return -ENODEV;
569
570 padev = to_parisc_device(dev);
571 if (!padev)
572 return -ENODEV;
573
574 if (add_uevent_var(env, "PARISC_NAME=%s", padev->name))
575 return -ENOMEM;
576
577 make_modalias(dev, modalias);
578 if (add_uevent_var(env, "MODALIAS=%s", modalias))
579 return -ENOMEM;
580
581 return 0;
582}
583
552#define pa_dev_attr(name, field, format_string) \ 584#define pa_dev_attr(name, field, format_string) \
553static ssize_t name##_show(struct device *dev, struct device_attribute *attr, char *buf) \ 585static ssize_t name##_show(struct device *dev, struct device_attribute *attr, char *buf) \
554{ \ 586{ \
@@ -566,12 +598,7 @@ pa_dev_attr_id(sversion, "0x%05x\n");
566 598
567static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf) 599static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf)
568{ 600{
569 struct parisc_device *padev = to_parisc_device(dev); 601 return make_modalias(dev, buf);
570 struct parisc_device_id *id = &padev->id;
571
572 return sprintf(buf, "parisc:t%02Xhv%04Xrev%02Xsv%08X\n",
573 (u8)id->hw_type, (u16)id->hversion, (u8)id->hversion_rev,
574 (u32)id->sversion);
575} 602}
576 603
577static struct device_attribute parisc_device_attrs[] = { 604static struct device_attribute parisc_device_attrs[] = {
@@ -587,6 +614,7 @@ static struct device_attribute parisc_device_attrs[] = {
587struct bus_type parisc_bus_type = { 614struct bus_type parisc_bus_type = {
588 .name = "parisc", 615 .name = "parisc",
589 .match = parisc_generic_match, 616 .match = parisc_generic_match,
617 .uevent = parisc_uevent,
590 .dev_attrs = parisc_device_attrs, 618 .dev_attrs = parisc_device_attrs,
591 .probe = parisc_driver_probe, 619 .probe = parisc_driver_probe,
592 .remove = parisc_driver_remove, 620 .remove = parisc_driver_remove,
diff --git a/arch/parisc/kernel/hpmc.S b/arch/parisc/kernel/hpmc.S
index 2cbf13b3ef11..5595a2f31181 100644
--- a/arch/parisc/kernel/hpmc.S
+++ b/arch/parisc/kernel/hpmc.S
@@ -80,6 +80,7 @@ END(hpmc_pim_data)
80 80
81 .import intr_save, code 81 .import intr_save, code
82ENTRY(os_hpmc) 82ENTRY(os_hpmc)
83.os_hpmc:
83 84
84 /* 85 /*
85 * registers modified: 86 * registers modified:
@@ -295,5 +296,10 @@ os_hpmc_6:
295 b . 296 b .
296 nop 297 nop
297ENDPROC(os_hpmc) 298ENDPROC(os_hpmc)
298ENTRY(os_hpmc_end) /* this label used to compute os_hpmc checksum */ 299.os_hpmc_end:
299 nop 300 nop
301.data
302.align 4
303 .export os_hpmc_size
304os_hpmc_size:
305 .word .os_hpmc_end-.os_hpmc
diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
index 4cea935e2f99..ac2c822928c7 100644
--- a/arch/parisc/kernel/irq.c
+++ b/arch/parisc/kernel/irq.c
@@ -298,7 +298,7 @@ unsigned long txn_affinity_addr(unsigned int irq, int cpu)
298 irq_desc[irq].affinity = cpumask_of_cpu(cpu); 298 irq_desc[irq].affinity = cpumask_of_cpu(cpu);
299#endif 299#endif
300 300
301 return cpu_data[cpu].txn_addr; 301 return per_cpu(cpu_data, cpu).txn_addr;
302} 302}
303 303
304 304
@@ -309,8 +309,9 @@ unsigned long txn_alloc_addr(unsigned int virt_irq)
309 next_cpu++; /* assign to "next" CPU we want this bugger on */ 309 next_cpu++; /* assign to "next" CPU we want this bugger on */
310 310
311 /* validate entry */ 311 /* validate entry */
312 while ((next_cpu < NR_CPUS) && (!cpu_data[next_cpu].txn_addr || 312 while ((next_cpu < NR_CPUS) &&
313 !cpu_online(next_cpu))) 313 (!per_cpu(cpu_data, next_cpu).txn_addr ||
314 !cpu_online(next_cpu)))
314 next_cpu++; 315 next_cpu++;
315 316
316 if (next_cpu >= NR_CPUS) 317 if (next_cpu >= NR_CPUS)
@@ -359,7 +360,7 @@ void do_cpu_irq_mask(struct pt_regs *regs)
359 printk(KERN_DEBUG "redirecting irq %d from CPU %d to %d\n", 360 printk(KERN_DEBUG "redirecting irq %d from CPU %d to %d\n",
360 irq, smp_processor_id(), cpu); 361 irq, smp_processor_id(), cpu);
361 gsc_writel(irq + CPU_IRQ_BASE, 362 gsc_writel(irq + CPU_IRQ_BASE,
362 cpu_data[cpu].hpa); 363 per_cpu(cpu_data, cpu).hpa);
363 goto set_out; 364 goto set_out;
364 } 365 }
365#endif 366#endif
@@ -421,5 +422,5 @@ void __init init_IRQ(void)
421 422
422void ack_bad_irq(unsigned int irq) 423void ack_bad_irq(unsigned int irq)
423{ 424{
424 printk("unexpected IRQ %d\n", irq); 425 printk(KERN_WARNING "unexpected IRQ %d\n", irq);
425} 426}
diff --git a/arch/parisc/kernel/pdc_cons.c b/arch/parisc/kernel/pdc_cons.c
index ccb68090781e..1ff366cb9685 100644
--- a/arch/parisc/kernel/pdc_cons.c
+++ b/arch/parisc/kernel/pdc_cons.c
@@ -52,7 +52,7 @@
52#include <linux/tty.h> 52#include <linux/tty.h>
53#include <asm/pdc.h> /* for iodc_call() proto and friends */ 53#include <asm/pdc.h> /* for iodc_call() proto and friends */
54 54
55static spinlock_t pdc_console_lock = SPIN_LOCK_UNLOCKED; 55static DEFINE_SPINLOCK(pdc_console_lock);
56 56
57static void pdc_console_write(struct console *co, const char *s, unsigned count) 57static void pdc_console_write(struct console *co, const char *s, unsigned count)
58{ 58{
diff --git a/arch/parisc/kernel/perf.c b/arch/parisc/kernel/perf.c
index f696f57faa15..75099efb3bf3 100644
--- a/arch/parisc/kernel/perf.c
+++ b/arch/parisc/kernel/perf.c
@@ -541,9 +541,9 @@ static int __init perf_init(void)
541 spin_lock_init(&perf_lock); 541 spin_lock_init(&perf_lock);
542 542
543 /* TODO: this only lets us access the first cpu.. what to do for SMP? */ 543 /* TODO: this only lets us access the first cpu.. what to do for SMP? */
544 cpu_device = cpu_data[0].dev; 544 cpu_device = per_cpu(cpu_data, 0).dev;
545 printk("Performance monitoring counters enabled for %s\n", 545 printk("Performance monitoring counters enabled for %s\n",
546 cpu_data[0].dev->name); 546 per_cpu(cpu_data, 0).dev->name);
547 547
548 return 0; 548 return 0;
549} 549}
diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c
index 370086fb8333..ecb609342feb 100644
--- a/arch/parisc/kernel/processor.c
+++ b/arch/parisc/kernel/processor.c
@@ -3,7 +3,7 @@
3 * Initial setup-routines for HP 9000 based hardware. 3 * Initial setup-routines for HP 9000 based hardware.
4 * 4 *
5 * Copyright (C) 1991, 1992, 1995 Linus Torvalds 5 * Copyright (C) 1991, 1992, 1995 Linus Torvalds
6 * Modifications for PA-RISC (C) 1999 Helge Deller <deller@gmx.de> 6 * Modifications for PA-RISC (C) 1999-2008 Helge Deller <deller@gmx.de>
7 * Modifications copyright 1999 SuSE GmbH (Philipp Rumpf) 7 * Modifications copyright 1999 SuSE GmbH (Philipp Rumpf)
8 * Modifications copyright 2000 Martin K. Petersen <mkp@mkp.net> 8 * Modifications copyright 2000 Martin K. Petersen <mkp@mkp.net>
9 * Modifications copyright 2000 Philipp Rumpf <prumpf@tux.org> 9 * Modifications copyright 2000 Philipp Rumpf <prumpf@tux.org>
@@ -46,7 +46,7 @@
46struct system_cpuinfo_parisc boot_cpu_data __read_mostly; 46struct system_cpuinfo_parisc boot_cpu_data __read_mostly;
47EXPORT_SYMBOL(boot_cpu_data); 47EXPORT_SYMBOL(boot_cpu_data);
48 48
49struct cpuinfo_parisc cpu_data[NR_CPUS] __read_mostly; 49DEFINE_PER_CPU(struct cpuinfo_parisc, cpu_data);
50 50
51extern int update_cr16_clocksource(void); /* from time.c */ 51extern int update_cr16_clocksource(void); /* from time.c */
52 52
@@ -69,6 +69,23 @@ extern int update_cr16_clocksource(void); /* from time.c */
69*/ 69*/
70 70
71/** 71/**
72 * init_cpu_profiler - enable/setup per cpu profiling hooks.
73 * @cpunum: The processor instance.
74 *
75 * FIXME: doesn't do much yet...
76 */
77static void __cpuinit
78init_percpu_prof(unsigned long cpunum)
79{
80 struct cpuinfo_parisc *p;
81
82 p = &per_cpu(cpu_data, cpunum);
83 p->prof_counter = 1;
84 p->prof_multiplier = 1;
85}
86
87
88/**
72 * processor_probe - Determine if processor driver should claim this device. 89 * processor_probe - Determine if processor driver should claim this device.
73 * @dev: The device which has been found. 90 * @dev: The device which has been found.
74 * 91 *
@@ -147,7 +164,7 @@ static int __cpuinit processor_probe(struct parisc_device *dev)
147 } 164 }
148#endif 165#endif
149 166
150 p = &cpu_data[cpuid]; 167 p = &per_cpu(cpu_data, cpuid);
151 boot_cpu_data.cpu_count++; 168 boot_cpu_data.cpu_count++;
152 169
153 /* initialize counters - CPU 0 gets it_value set in time_init() */ 170 /* initialize counters - CPU 0 gets it_value set in time_init() */
@@ -162,12 +179,9 @@ static int __cpuinit processor_probe(struct parisc_device *dev)
162#ifdef CONFIG_SMP 179#ifdef CONFIG_SMP
163 /* 180 /*
164 ** FIXME: review if any other initialization is clobbered 181 ** FIXME: review if any other initialization is clobbered
165 ** for boot_cpu by the above memset(). 182 ** for boot_cpu by the above memset().
166 */ 183 */
167 184 init_percpu_prof(cpuid);
168 /* stolen from init_percpu_prof() */
169 cpu_data[cpuid].prof_counter = 1;
170 cpu_data[cpuid].prof_multiplier = 1;
171#endif 185#endif
172 186
173 /* 187 /*
@@ -261,19 +275,6 @@ void __init collect_boot_cpu_data(void)
261} 275}
262 276
263 277
264/**
265 * init_cpu_profiler - enable/setup per cpu profiling hooks.
266 * @cpunum: The processor instance.
267 *
268 * FIXME: doesn't do much yet...
269 */
270static inline void __init
271init_percpu_prof(int cpunum)
272{
273 cpu_data[cpunum].prof_counter = 1;
274 cpu_data[cpunum].prof_multiplier = 1;
275}
276
277 278
278/** 279/**
279 * init_per_cpu - Handle individual processor initializations. 280 * init_per_cpu - Handle individual processor initializations.
@@ -293,7 +294,7 @@ init_percpu_prof(int cpunum)
293 * 294 *
294 * o Enable CPU profiling hooks. 295 * o Enable CPU profiling hooks.
295 */ 296 */
296int __init init_per_cpu(int cpunum) 297int __cpuinit init_per_cpu(int cpunum)
297{ 298{
298 int ret; 299 int ret;
299 struct pdc_coproc_cfg coproc_cfg; 300 struct pdc_coproc_cfg coproc_cfg;
@@ -307,8 +308,8 @@ int __init init_per_cpu(int cpunum)
307 /* FWIW, FP rev/model is a more accurate way to determine 308 /* FWIW, FP rev/model is a more accurate way to determine
308 ** CPU type. CPU rev/model has some ambiguous cases. 309 ** CPU type. CPU rev/model has some ambiguous cases.
309 */ 310 */
310 cpu_data[cpunum].fp_rev = coproc_cfg.revision; 311 per_cpu(cpu_data, cpunum).fp_rev = coproc_cfg.revision;
311 cpu_data[cpunum].fp_model = coproc_cfg.model; 312 per_cpu(cpu_data, cpunum).fp_model = coproc_cfg.model;
312 313
313 printk(KERN_INFO "FP[%d] enabled: Rev %ld Model %ld\n", 314 printk(KERN_INFO "FP[%d] enabled: Rev %ld Model %ld\n",
314 cpunum, coproc_cfg.revision, coproc_cfg.model); 315 cpunum, coproc_cfg.revision, coproc_cfg.model);
@@ -344,16 +345,17 @@ int __init init_per_cpu(int cpunum)
344int 345int
345show_cpuinfo (struct seq_file *m, void *v) 346show_cpuinfo (struct seq_file *m, void *v)
346{ 347{
347 int n; 348 unsigned long cpu;
348 349
349 for(n=0; n<boot_cpu_data.cpu_count; n++) { 350 for_each_online_cpu(cpu) {
351 const struct cpuinfo_parisc *cpuinfo = &per_cpu(cpu_data, cpu);
350#ifdef CONFIG_SMP 352#ifdef CONFIG_SMP
351 if (0 == cpu_data[n].hpa) 353 if (0 == cpuinfo->hpa)
352 continue; 354 continue;
353#endif 355#endif
354 seq_printf(m, "processor\t: %d\n" 356 seq_printf(m, "processor\t: %lu\n"
355 "cpu family\t: PA-RISC %s\n", 357 "cpu family\t: PA-RISC %s\n",
356 n, boot_cpu_data.family_name); 358 cpu, boot_cpu_data.family_name);
357 359
358 seq_printf(m, "cpu\t\t: %s\n", boot_cpu_data.cpu_name ); 360 seq_printf(m, "cpu\t\t: %s\n", boot_cpu_data.cpu_name );
359 361
@@ -365,8 +367,8 @@ show_cpuinfo (struct seq_file *m, void *v)
365 seq_printf(m, "model\t\t: %s\n" 367 seq_printf(m, "model\t\t: %s\n"
366 "model name\t: %s\n", 368 "model name\t: %s\n",
367 boot_cpu_data.pdc.sys_model_name, 369 boot_cpu_data.pdc.sys_model_name,
368 cpu_data[n].dev ? 370 cpuinfo->dev ?
369 cpu_data[n].dev->name : "Unknown" ); 371 cpuinfo->dev->name : "Unknown");
370 372
371 seq_printf(m, "hversion\t: 0x%08x\n" 373 seq_printf(m, "hversion\t: 0x%08x\n"
372 "sversion\t: 0x%08x\n", 374 "sversion\t: 0x%08x\n",
@@ -377,8 +379,8 @@ show_cpuinfo (struct seq_file *m, void *v)
377 show_cache_info(m); 379 show_cache_info(m);
378 380
379 seq_printf(m, "bogomips\t: %lu.%02lu\n", 381 seq_printf(m, "bogomips\t: %lu.%02lu\n",
380 cpu_data[n].loops_per_jiffy / (500000 / HZ), 382 cpuinfo->loops_per_jiffy / (500000 / HZ),
381 (cpu_data[n].loops_per_jiffy / (5000 / HZ)) % 100); 383 (cpuinfo->loops_per_jiffy / (5000 / HZ)) % 100);
382 384
383 seq_printf(m, "software id\t: %ld\n\n", 385 seq_printf(m, "software id\t: %ld\n\n",
384 boot_cpu_data.pdc.model.sw_id); 386 boot_cpu_data.pdc.model.sw_id);
diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c
index 7d27853ff8c8..82131ca8e05c 100644
--- a/arch/parisc/kernel/setup.c
+++ b/arch/parisc/kernel/setup.c
@@ -58,11 +58,6 @@ int parisc_bus_is_phys __read_mostly = 1; /* Assume no IOMMU is present */
58EXPORT_SYMBOL(parisc_bus_is_phys); 58EXPORT_SYMBOL(parisc_bus_is_phys);
59#endif 59#endif
60 60
61/* This sets the vmerge boundary and size, it's here because it has to
62 * be available on all platforms (zero means no-virtual merging) */
63unsigned long parisc_vmerge_boundary = 0;
64unsigned long parisc_vmerge_max_size = 0;
65
66void __init setup_cmdline(char **cmdline_p) 61void __init setup_cmdline(char **cmdline_p)
67{ 62{
68 extern unsigned int boot_args[]; 63 extern unsigned int boot_args[];
@@ -321,7 +316,7 @@ static int __init parisc_init(void)
321 316
322 processor_init(); 317 processor_init();
323 printk(KERN_INFO "CPU(s): %d x %s at %d.%06d MHz\n", 318 printk(KERN_INFO "CPU(s): %d x %s at %d.%06d MHz\n",
324 boot_cpu_data.cpu_count, 319 num_present_cpus(),
325 boot_cpu_data.cpu_name, 320 boot_cpu_data.cpu_name,
326 boot_cpu_data.cpu_hz / 1000000, 321 boot_cpu_data.cpu_hz / 1000000,
327 boot_cpu_data.cpu_hz % 1000000 ); 322 boot_cpu_data.cpu_hz % 1000000 );
@@ -387,8 +382,8 @@ void start_parisc(void)
387 if (ret >= 0 && coproc_cfg.ccr_functional) { 382 if (ret >= 0 && coproc_cfg.ccr_functional) {
388 mtctl(coproc_cfg.ccr_functional, 10); 383 mtctl(coproc_cfg.ccr_functional, 10);
389 384
390 cpu_data[cpunum].fp_rev = coproc_cfg.revision; 385 per_cpu(cpu_data, cpunum).fp_rev = coproc_cfg.revision;
391 cpu_data[cpunum].fp_model = coproc_cfg.model; 386 per_cpu(cpu_data, cpunum).fp_model = coproc_cfg.model;
392 387
393 asm volatile ("fstd %fr0,8(%sp)"); 388 asm volatile ("fstd %fr0,8(%sp)");
394 } else { 389 } else {
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
index 80bc000523fa..9995d7ed5819 100644
--- a/arch/parisc/kernel/smp.c
+++ b/arch/parisc/kernel/smp.c
@@ -56,16 +56,17 @@ static int smp_debug_lvl = 0;
56 if (lvl >= smp_debug_lvl) \ 56 if (lvl >= smp_debug_lvl) \
57 printk(printargs); 57 printk(printargs);
58#else 58#else
59#define smp_debug(lvl, ...) 59#define smp_debug(lvl, ...) do { } while(0)
60#endif /* DEBUG_SMP */ 60#endif /* DEBUG_SMP */
61 61
62DEFINE_SPINLOCK(smp_lock); 62DEFINE_SPINLOCK(smp_lock);
63 63
64volatile struct task_struct *smp_init_current_idle_task; 64volatile struct task_struct *smp_init_current_idle_task;
65 65
66static volatile int cpu_now_booting __read_mostly = 0; /* track which CPU is booting */ 66/* track which CPU is booting */
67static volatile int cpu_now_booting __cpuinitdata;
67 68
68static int parisc_max_cpus __read_mostly = 1; 69static int parisc_max_cpus __cpuinitdata = 1;
69 70
70DEFINE_PER_CPU(spinlock_t, ipi_lock) = SPIN_LOCK_UNLOCKED; 71DEFINE_PER_CPU(spinlock_t, ipi_lock) = SPIN_LOCK_UNLOCKED;
71 72
@@ -123,7 +124,7 @@ irqreturn_t
123ipi_interrupt(int irq, void *dev_id) 124ipi_interrupt(int irq, void *dev_id)
124{ 125{
125 int this_cpu = smp_processor_id(); 126 int this_cpu = smp_processor_id();
126 struct cpuinfo_parisc *p = &cpu_data[this_cpu]; 127 struct cpuinfo_parisc *p = &per_cpu(cpu_data, this_cpu);
127 unsigned long ops; 128 unsigned long ops;
128 unsigned long flags; 129 unsigned long flags;
129 130
@@ -202,13 +203,13 @@ ipi_interrupt(int irq, void *dev_id)
202static inline void 203static inline void
203ipi_send(int cpu, enum ipi_message_type op) 204ipi_send(int cpu, enum ipi_message_type op)
204{ 205{
205 struct cpuinfo_parisc *p = &cpu_data[cpu]; 206 struct cpuinfo_parisc *p = &per_cpu(cpu_data, cpu);
206 spinlock_t *lock = &per_cpu(ipi_lock, cpu); 207 spinlock_t *lock = &per_cpu(ipi_lock, cpu);
207 unsigned long flags; 208 unsigned long flags;
208 209
209 spin_lock_irqsave(lock, flags); 210 spin_lock_irqsave(lock, flags);
210 p->pending_ipi |= 1 << op; 211 p->pending_ipi |= 1 << op;
211 gsc_writel(IPI_IRQ - CPU_IRQ_BASE, cpu_data[cpu].hpa); 212 gsc_writel(IPI_IRQ - CPU_IRQ_BASE, p->hpa);
212 spin_unlock_irqrestore(lock, flags); 213 spin_unlock_irqrestore(lock, flags);
213} 214}
214 215
@@ -224,10 +225,7 @@ send_IPI_mask(cpumask_t mask, enum ipi_message_type op)
224static inline void 225static inline void
225send_IPI_single(int dest_cpu, enum ipi_message_type op) 226send_IPI_single(int dest_cpu, enum ipi_message_type op)
226{ 227{
227 if (dest_cpu == NO_PROC_ID) { 228 BUG_ON(dest_cpu == NO_PROC_ID);
228 BUG();
229 return;
230 }
231 229
232 ipi_send(dest_cpu, op); 230 ipi_send(dest_cpu, op);
233} 231}
@@ -309,8 +307,7 @@ smp_cpu_init(int cpunum)
309 /* Initialise the idle task for this CPU */ 307 /* Initialise the idle task for this CPU */
310 atomic_inc(&init_mm.mm_count); 308 atomic_inc(&init_mm.mm_count);
311 current->active_mm = &init_mm; 309 current->active_mm = &init_mm;
312 if(current->mm) 310 BUG_ON(current->mm);
313 BUG();
314 enter_lazy_tlb(&init_mm, current); 311 enter_lazy_tlb(&init_mm, current);
315 312
316 init_IRQ(); /* make sure no IRQs are enabled or pending */ 313 init_IRQ(); /* make sure no IRQs are enabled or pending */
@@ -345,6 +342,7 @@ void __init smp_callin(void)
345 */ 342 */
346int __cpuinit smp_boot_one_cpu(int cpuid) 343int __cpuinit smp_boot_one_cpu(int cpuid)
347{ 344{
345 const struct cpuinfo_parisc *p = &per_cpu(cpu_data, cpuid);
348 struct task_struct *idle; 346 struct task_struct *idle;
349 long timeout; 347 long timeout;
350 348
@@ -376,7 +374,7 @@ int __cpuinit smp_boot_one_cpu(int cpuid)
376 smp_init_current_idle_task = idle ; 374 smp_init_current_idle_task = idle ;
377 mb(); 375 mb();
378 376
379 printk("Releasing cpu %d now, hpa=%lx\n", cpuid, cpu_data[cpuid].hpa); 377 printk(KERN_INFO "Releasing cpu %d now, hpa=%lx\n", cpuid, p->hpa);
380 378
381 /* 379 /*
382 ** This gets PDC to release the CPU from a very tight loop. 380 ** This gets PDC to release the CPU from a very tight loop.
@@ -387,7 +385,7 @@ int __cpuinit smp_boot_one_cpu(int cpuid)
387 ** EIR{0}). MEM_RENDEZ is valid only when it is nonzero and the 385 ** EIR{0}). MEM_RENDEZ is valid only when it is nonzero and the
388 ** contents of memory are valid." 386 ** contents of memory are valid."
389 */ 387 */
390 gsc_writel(TIMER_IRQ - CPU_IRQ_BASE, cpu_data[cpuid].hpa); 388 gsc_writel(TIMER_IRQ - CPU_IRQ_BASE, p->hpa);
391 mb(); 389 mb();
392 390
393 /* 391 /*
@@ -419,12 +417,12 @@ alive:
419 return 0; 417 return 0;
420} 418}
421 419
422void __devinit smp_prepare_boot_cpu(void) 420void __init smp_prepare_boot_cpu(void)
423{ 421{
424 int bootstrap_processor=cpu_data[0].cpuid; /* CPU ID of BSP */ 422 int bootstrap_processor = per_cpu(cpu_data, 0).cpuid;
425 423
426 /* Setup BSP mappings */ 424 /* Setup BSP mappings */
427 printk("SMP: bootstrap CPU ID is %d\n",bootstrap_processor); 425 printk(KERN_INFO "SMP: bootstrap CPU ID is %d\n", bootstrap_processor);
428 426
429 cpu_set(bootstrap_processor, cpu_online_map); 427 cpu_set(bootstrap_processor, cpu_online_map);
430 cpu_set(bootstrap_processor, cpu_present_map); 428 cpu_set(bootstrap_processor, cpu_present_map);
diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c
index 4d09203bc693..9d46c43a4152 100644
--- a/arch/parisc/kernel/time.c
+++ b/arch/parisc/kernel/time.c
@@ -60,7 +60,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id)
60 unsigned long cycles_elapsed, ticks_elapsed; 60 unsigned long cycles_elapsed, ticks_elapsed;
61 unsigned long cycles_remainder; 61 unsigned long cycles_remainder;
62 unsigned int cpu = smp_processor_id(); 62 unsigned int cpu = smp_processor_id();
63 struct cpuinfo_parisc *cpuinfo = &cpu_data[cpu]; 63 struct cpuinfo_parisc *cpuinfo = &per_cpu(cpu_data, cpu);
64 64
65 /* gcc can optimize for "read-only" case with a local clocktick */ 65 /* gcc can optimize for "read-only" case with a local clocktick */
66 unsigned long cpt = clocktick; 66 unsigned long cpt = clocktick;
@@ -213,7 +213,7 @@ void __init start_cpu_itimer(void)
213 213
214 mtctl(next_tick, 16); /* kick off Interval Timer (CR16) */ 214 mtctl(next_tick, 16); /* kick off Interval Timer (CR16) */
215 215
216 cpu_data[cpu].it_value = next_tick; 216 per_cpu(cpu_data, cpu).it_value = next_tick;
217} 217}
218 218
219struct platform_device rtc_parisc_dev = { 219struct platform_device rtc_parisc_dev = {
diff --git a/arch/parisc/kernel/topology.c b/arch/parisc/kernel/topology.c
index d71cb018a21e..f5159381fdd6 100644
--- a/arch/parisc/kernel/topology.c
+++ b/arch/parisc/kernel/topology.c
@@ -22,14 +22,14 @@
22#include <linux/cpu.h> 22#include <linux/cpu.h>
23#include <linux/cache.h> 23#include <linux/cache.h>
24 24
25static struct cpu cpu_devices[NR_CPUS] __read_mostly; 25static DEFINE_PER_CPU(struct cpu, cpu_devices);
26 26
27static int __init topology_init(void) 27static int __init topology_init(void)
28{ 28{
29 int num; 29 int num;
30 30
31 for_each_present_cpu(num) { 31 for_each_present_cpu(num) {
32 register_cpu(&cpu_devices[num], num); 32 register_cpu(&per_cpu(cpu_devices, num), num);
33 } 33 }
34 return 0; 34 return 0;
35} 35}
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
index 4c771cd580ec..ba658d2086f7 100644
--- a/arch/parisc/kernel/traps.c
+++ b/arch/parisc/kernel/traps.c
@@ -745,6 +745,10 @@ void handle_interruption(int code, struct pt_regs *regs)
745 /* Fall Through */ 745 /* Fall Through */
746 case 27: 746 case 27:
747 /* Data memory protection ID trap */ 747 /* Data memory protection ID trap */
748 if (code == 27 && !user_mode(regs) &&
749 fixup_exception(regs))
750 return;
751
748 die_if_kernel("Protection id trap", regs, code); 752 die_if_kernel("Protection id trap", regs, code);
749 si.si_code = SEGV_MAPERR; 753 si.si_code = SEGV_MAPERR;
750 si.si_signo = SIGSEGV; 754 si.si_signo = SIGSEGV;
@@ -821,8 +825,8 @@ void handle_interruption(int code, struct pt_regs *regs)
821 825
822int __init check_ivt(void *iva) 826int __init check_ivt(void *iva)
823{ 827{
828 extern u32 os_hpmc_size;
824 extern const u32 os_hpmc[]; 829 extern const u32 os_hpmc[];
825 extern const u32 os_hpmc_end[];
826 830
827 int i; 831 int i;
828 u32 check = 0; 832 u32 check = 0;
@@ -839,8 +843,7 @@ int __init check_ivt(void *iva)
839 *ivap++ = 0; 843 *ivap++ = 0;
840 844
841 /* Compute Checksum for HPMC handler */ 845 /* Compute Checksum for HPMC handler */
842 846 length = os_hpmc_size;
843 length = os_hpmc_end - os_hpmc;
844 ivap[7] = length; 847 ivap[7] = length;
845 848
846 hpmcp = (u32 *)os_hpmc; 849 hpmcp = (u32 *)os_hpmc;
diff --git a/arch/parisc/kernel/unwind.c b/arch/parisc/kernel/unwind.c
index 6773c582e457..69dad5a850a8 100644
--- a/arch/parisc/kernel/unwind.c
+++ b/arch/parisc/kernel/unwind.c
@@ -372,7 +372,7 @@ void unwind_frame_init_from_blocked_task(struct unwind_frame_info *info, struct
372 struct pt_regs *r = &t->thread.regs; 372 struct pt_regs *r = &t->thread.regs;
373 struct pt_regs *r2; 373 struct pt_regs *r2;
374 374
375 r2 = kmalloc(sizeof(struct pt_regs), GFP_KERNEL); 375 r2 = kmalloc(sizeof(struct pt_regs), GFP_ATOMIC);
376 if (!r2) 376 if (!r2)
377 return; 377 return;
378 *r2 = *r; 378 *r2 = *r;
diff --git a/arch/parisc/lib/iomap.c b/arch/parisc/lib/iomap.c
index 9abed07db7fc..5069e8b2ca71 100644
--- a/arch/parisc/lib/iomap.c
+++ b/arch/parisc/lib/iomap.c
@@ -261,7 +261,7 @@ static const struct iomap_ops iomem_ops = {
261 iomem_write32r, 261 iomem_write32r,
262}; 262};
263 263
264const struct iomap_ops *iomap_ops[8] = { 264static const struct iomap_ops *iomap_ops[8] = {
265 [0] = &ioport_ops, 265 [0] = &ioport_ops,
266 [7] = &iomem_ops 266 [7] = &iomem_ops
267}; 267};
diff --git a/arch/parisc/lib/memcpy.c b/arch/parisc/lib/memcpy.c
index 2d68431fc22e..bbda909c866e 100644
--- a/arch/parisc/lib/memcpy.c
+++ b/arch/parisc/lib/memcpy.c
@@ -275,7 +275,7 @@ handle_store_error:
275 275
276 276
277/* Returns 0 for success, otherwise, returns number of bytes not transferred. */ 277/* Returns 0 for success, otherwise, returns number of bytes not transferred. */
278unsigned long pa_memcpy(void *dstp, const void *srcp, unsigned long len) 278static unsigned long pa_memcpy(void *dstp, const void *srcp, unsigned long len)
279{ 279{
280 register unsigned long src, dst, t1, t2, t3; 280 register unsigned long src, dst, t1, t2, t3;
281 register unsigned char *pcs, *pcd; 281 register unsigned char *pcs, *pcd;
diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c
index b2e3e9a8cece..92c7fa4ecc3f 100644
--- a/arch/parisc/mm/fault.c
+++ b/arch/parisc/mm/fault.c
@@ -139,13 +139,41 @@ parisc_acctyp(unsigned long code, unsigned int inst)
139 } 139 }
140#endif 140#endif
141 141
142int fixup_exception(struct pt_regs *regs)
143{
144 const struct exception_table_entry *fix;
145
146 fix = search_exception_tables(regs->iaoq[0]);
147 if (fix) {
148 struct exception_data *d;
149 d = &__get_cpu_var(exception_data);
150 d->fault_ip = regs->iaoq[0];
151 d->fault_space = regs->isr;
152 d->fault_addr = regs->ior;
153
154 regs->iaoq[0] = ((fix->fixup) & ~3);
155 /*
156 * NOTE: In some cases the faulting instruction
157 * may be in the delay slot of a branch. We
158 * don't want to take the branch, so we don't
159 * increment iaoq[1], instead we set it to be
160 * iaoq[0]+4, and clear the B bit in the PSW
161 */
162 regs->iaoq[1] = regs->iaoq[0] + 4;
163 regs->gr[0] &= ~PSW_B; /* IPSW in gr[0] */
164
165 return 1;
166 }
167
168 return 0;
169}
170
142void do_page_fault(struct pt_regs *regs, unsigned long code, 171void do_page_fault(struct pt_regs *regs, unsigned long code,
143 unsigned long address) 172 unsigned long address)
144{ 173{
145 struct vm_area_struct *vma, *prev_vma; 174 struct vm_area_struct *vma, *prev_vma;
146 struct task_struct *tsk = current; 175 struct task_struct *tsk = current;
147 struct mm_struct *mm = tsk->mm; 176 struct mm_struct *mm = tsk->mm;
148 const struct exception_table_entry *fix;
149 unsigned long acc_type; 177 unsigned long acc_type;
150 int fault; 178 int fault;
151 179
@@ -229,32 +257,8 @@ bad_area:
229 257
230no_context: 258no_context:
231 259
232 if (!user_mode(regs)) { 260 if (!user_mode(regs) && fixup_exception(regs)) {
233 fix = search_exception_tables(regs->iaoq[0]); 261 return;
234
235 if (fix) {
236 struct exception_data *d;
237
238 d = &__get_cpu_var(exception_data);
239 d->fault_ip = regs->iaoq[0];
240 d->fault_space = regs->isr;
241 d->fault_addr = regs->ior;
242
243 regs->iaoq[0] = ((fix->fixup) & ~3);
244
245 /*
246 * NOTE: In some cases the faulting instruction
247 * may be in the delay slot of a branch. We
248 * don't want to take the branch, so we don't
249 * increment iaoq[1], instead we set it to be
250 * iaoq[0]+4, and clear the B bit in the PSW
251 */
252
253 regs->iaoq[1] = regs->iaoq[0] + 4;
254 regs->gr[0] &= ~PSW_B; /* IPSW in gr[0] */
255
256 return;
257 }
258 } 262 }
259 263
260 parisc_terminate("Bad Address (null pointer deref?)", regs, code, address); 264 parisc_terminate("Bad Address (null pointer deref?)", regs, code, address);