aboutsummaryrefslogtreecommitdiff
path: root/arch/sparc/include
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2012-03-28 18:30:03 +0100
committerDavid Howells <dhowells@redhat.com>2012-03-28 18:30:03 +0100
commitd550bbd40c0e10aefa05103dadbe0ae42e683707 (patch)
treec1f32662f605f2b87c73901fbf66d12b2ca69b04 /arch/sparc/include
parente839ca528718e68cad32a307dc9aabf01ef3eb05 (diff)
Disintegrate asm/system.h for Sparc
Disintegrate asm/system.h for Sparc. Signed-off-by: David Howells <dhowells@redhat.com> cc: sparclinux@vger.kernel.org
Diffstat (limited to 'arch/sparc/include')
-rw-r--r--arch/sparc/include/asm/atomic_32.h2
-rw-r--r--arch/sparc/include/asm/atomic_64.h3
-rw-r--r--arch/sparc/include/asm/auxio_32.h1
-rw-r--r--arch/sparc/include/asm/barrier.h8
-rw-r--r--arch/sparc/include/asm/barrier_32.h15
-rw-r--r--arch/sparc/include/asm/barrier_64.h56
-rw-r--r--arch/sparc/include/asm/bug.h3
-rw-r--r--arch/sparc/include/asm/cacheflush_32.h9
-rw-r--r--arch/sparc/include/asm/cacheflush_64.h10
-rw-r--r--arch/sparc/include/asm/cmpxchg.h8
-rw-r--r--arch/sparc/include/asm/cmpxchg_32.h112
-rw-r--r--arch/sparc/include/asm/cmpxchg_64.h145
-rw-r--r--arch/sparc/include/asm/cpu_type.h34
-rw-r--r--arch/sparc/include/asm/exec.h6
-rw-r--r--arch/sparc/include/asm/floppy_32.h1
-rw-r--r--arch/sparc/include/asm/futex_64.h1
-rw-r--r--arch/sparc/include/asm/io_32.h1
-rw-r--r--arch/sparc/include/asm/io_64.h1
-rw-r--r--arch/sparc/include/asm/irqflags_32.h1
-rw-r--r--arch/sparc/include/asm/mmu_context_64.h1
-rw-r--r--arch/sparc/include/asm/ns87303.h1
-rw-r--r--arch/sparc/include/asm/perfctr.h23
-rw-r--r--arch/sparc/include/asm/pgtable_32.h2
-rw-r--r--arch/sparc/include/asm/pgtable_64.h1
-rw-r--r--arch/sparc/include/asm/processor.h3
-rw-r--r--arch/sparc/include/asm/processor_64.h3
-rw-r--r--arch/sparc/include/asm/ptrace.h5
-rw-r--r--arch/sparc/include/asm/setup.h16
-rw-r--r--arch/sparc/include/asm/switch_to.h8
-rw-r--r--arch/sparc/include/asm/switch_to_32.h106
-rw-r--r--arch/sparc/include/asm/switch_to_64.h72
-rw-r--r--arch/sparc/include/asm/system.h14
-rw-r--r--arch/sparc/include/asm/system_32.h284
-rw-r--r--arch/sparc/include/asm/system_64.h331
-rw-r--r--arch/sparc/include/asm/timer_32.h3
-rw-r--r--arch/sparc/include/asm/uaccess_64.h1
36 files changed, 651 insertions, 640 deletions
diff --git a/arch/sparc/include/asm/atomic_32.h b/arch/sparc/include/asm/atomic_32.h
index 9dd0a769fa1..905832aa9e9 100644
--- a/arch/sparc/include/asm/atomic_32.h
+++ b/arch/sparc/include/asm/atomic_32.h
@@ -13,9 +13,9 @@
#include <linux/types.h>
+#include <asm/cmpxchg.h>
#include <asm-generic/atomic64.h>
-#include <asm/system.h>
#define ATOMIC_INIT(i) { (i) }
diff --git a/arch/sparc/include/asm/atomic_64.h b/arch/sparc/include/asm/atomic_64.h
index 9f421df46ae..ce35a1cf1a2 100644
--- a/arch/sparc/include/asm/atomic_64.h
+++ b/arch/sparc/include/asm/atomic_64.h
@@ -8,7 +8,7 @@
#define __ARCH_SPARC64_ATOMIC__
#include <linux/types.h>
-#include <asm/system.h>
+#include <asm/cmpxchg.h>
#define ATOMIC_INIT(i) { (i) }
#define ATOMIC64_INIT(i) { (i) }
@@ -85,7 +85,6 @@ static inline int __atomic_add_unless(atomic_t *v, int a, int u)
return c;
}
-
#define atomic64_cmpxchg(v, o, n) \
((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n)))
#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
diff --git a/arch/sparc/include/asm/auxio_32.h b/arch/sparc/include/asm/auxio_32.h
index e03e088be95..3a319775ae3 100644
--- a/arch/sparc/include/asm/auxio_32.h
+++ b/arch/sparc/include/asm/auxio_32.h
@@ -6,7 +6,6 @@
#ifndef _SPARC_AUXIO_H
#define _SPARC_AUXIO_H
-#include <asm/system.h>
#include <asm/vaddrs.h>
/* This register is an unsigned char in IO space. It does two things.
diff --git a/arch/sparc/include/asm/barrier.h b/arch/sparc/include/asm/barrier.h
new file mode 100644
index 00000000000..b25f02a029e
--- /dev/null
+++ b/arch/sparc/include/asm/barrier.h
@@ -0,0 +1,8 @@
+#ifndef ___ASM_SPARC_BARRIER_H
+#define ___ASM_SPARC_BARRIER_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm/barrier_64.h>
+#else
+#include <asm/barrier_32.h>
+#endif
+#endif
diff --git a/arch/sparc/include/asm/barrier_32.h b/arch/sparc/include/asm/barrier_32.h
new file mode 100644
index 00000000000..c1b76654ee7
--- /dev/null
+++ b/arch/sparc/include/asm/barrier_32.h
@@ -0,0 +1,15 @@
+#ifndef __SPARC_BARRIER_H
+#define __SPARC_BARRIER_H
+
+/* XXX Change this if we ever use a PSO mode kernel. */
+#define mb() __asm__ __volatile__ ("" : : : "memory")
+#define rmb() mb()
+#define wmb() mb()
+#define read_barrier_depends() do { } while(0)
+#define set_mb(__var, __value) do { __var = __value; mb(); } while(0)
+#define smp_mb() __asm__ __volatile__("":::"memory")
+#define smp_rmb() __asm__ __volatile__("":::"memory")
+#define smp_wmb() __asm__ __volatile__("":::"memory")
+#define smp_read_barrier_depends() do { } while(0)
+
+#endif /* !(__SPARC_BARRIER_H) */
diff --git a/arch/sparc/include/asm/barrier_64.h b/arch/sparc/include/asm/barrier_64.h
new file mode 100644
index 00000000000..95d45986f90
--- /dev/null
+++ b/arch/sparc/include/asm/barrier_64.h
@@ -0,0 +1,56 @@
+#ifndef __SPARC64_BARRIER_H
+#define __SPARC64_BARRIER_H
+
+/* These are here in an effort to more fully work around Spitfire Errata
+ * #51. Essentially, if a memory barrier occurs soon after a mispredicted
+ * branch, the chip can stop executing instructions until a trap occurs.
+ * Therefore, if interrupts are disabled, the chip can hang forever.
+ *
+ * It used to be believed that the memory barrier had to be right in the
+ * delay slot, but a case has been traced recently wherein the memory barrier
+ * was one instruction after the branch delay slot and the chip still hung.
+ * The offending sequence was the following in sym_wakeup_done() of the
+ * sym53c8xx_2 driver:
+ *
+ * call sym_ccb_from_dsa, 0
+ * movge %icc, 0, %l0
+ * brz,pn %o0, .LL1303
+ * mov %o0, %l2
+ * membar #LoadLoad
+ *
+ * The branch has to be mispredicted for the bug to occur. Therefore, we put
+ * the memory barrier explicitly into a "branch always, predicted taken"
+ * delay slot to avoid the problem case.
+ */
+#define membar_safe(type) \
+do { __asm__ __volatile__("ba,pt %%xcc, 1f\n\t" \
+ " membar " type "\n" \
+ "1:\n" \
+ : : : "memory"); \
+} while (0)
+
+/* The kernel always executes in TSO memory model these days,
+ * and furthermore most sparc64 chips implement more stringent
+ * memory ordering than required by the specifications.
+ */
+#define mb() membar_safe("#StoreLoad")
+#define rmb() __asm__ __volatile__("":::"memory")
+#define wmb() __asm__ __volatile__("":::"memory")
+
+#define read_barrier_depends() do { } while(0)
+#define set_mb(__var, __value) \
+ do { __var = __value; membar_safe("#StoreLoad"); } while(0)
+
+#ifdef CONFIG_SMP
+#define smp_mb() mb()
+#define smp_rmb() rmb()
+#define smp_wmb() wmb()
+#else
+#define smp_mb() __asm__ __volatile__("":::"memory")
+#define smp_rmb() __asm__ __volatile__("":::"memory")
+#define smp_wmb() __asm__ __volatile__("":::"memory")
+#endif
+
+#define smp_read_barrier_depends() do { } while(0)
+
+#endif /* !(__SPARC64_BARRIER_H) */
diff --git a/arch/sparc/include/asm/bug.h b/arch/sparc/include/asm/bug.h
index 8a59e5a8c21..6bd9f43cb5a 100644
--- a/arch/sparc/include/asm/bug.h
+++ b/arch/sparc/include/asm/bug.h
@@ -19,4 +19,7 @@ extern void do_BUG(const char *file, int line);
#include <asm-generic/bug.h>
+struct pt_regs;
+extern void die_if_kernel(char *str, struct pt_regs *regs) __attribute__ ((noreturn));
+
#endif
diff --git a/arch/sparc/include/asm/cacheflush_32.h b/arch/sparc/include/asm/cacheflush_32.h
index 2e468773f25..68431b47a22 100644
--- a/arch/sparc/include/asm/cacheflush_32.h
+++ b/arch/sparc/include/asm/cacheflush_32.h
@@ -83,4 +83,13 @@ extern void sparc_flush_page_to_ram(struct page *page);
#define flush_cache_vmap(start, end) flush_cache_all()
#define flush_cache_vunmap(start, end) flush_cache_all()
+/* When a context switch happens we must flush all user windows so that
+ * the windows of the current process are flushed onto its stack. This
+ * way the windows are all clean for the next process and the stack
+ * frames are up to date.
+ */
+extern void flush_user_windows(void);
+extern void kill_user_windows(void);
+extern void flushw_all(void);
+
#endif /* _SPARC_CACHEFLUSH_H */
diff --git a/arch/sparc/include/asm/cacheflush_64.h b/arch/sparc/include/asm/cacheflush_64.h
index b95384033e8..2efea2ff88b 100644
--- a/arch/sparc/include/asm/cacheflush_64.h
+++ b/arch/sparc/include/asm/cacheflush_64.h
@@ -9,6 +9,16 @@
/* Cache flush operations. */
+
+#define flushi(addr) __asm__ __volatile__ ("flush %0" : : "r" (addr) : "memory")
+#define flushw_all() __asm__ __volatile__("flushw")
+
+extern void __flushw_user(void);
+#define flushw_user() __flushw_user()
+
+#define flush_user_windows flushw_user
+#define flush_register_windows flushw_all
+
/* These are the same regardless of whether this is an SMP kernel or not. */
#define flush_cache_mm(__mm) \
do { if ((__mm) == current->mm) flushw_user(); } while(0)
diff --git a/arch/sparc/include/asm/cmpxchg.h b/arch/sparc/include/asm/cmpxchg.h
new file mode 100644
index 00000000000..9355893efa5
--- /dev/null
+++ b/arch/sparc/include/asm/cmpxchg.h
@@ -0,0 +1,8 @@
+#ifndef ___ASM_SPARC_CMPXCHG_H
+#define ___ASM_SPARC_CMPXCHG_H
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm/cmpxchg_64.h>
+#else
+#include <asm/cmpxchg_32.h>
+#endif
+#endif
diff --git a/arch/sparc/include/asm/cmpxchg_32.h b/arch/sparc/include/asm/cmpxchg_32.h
new file mode 100644
index 00000000000..c786b0a92b5
--- /dev/null
+++ b/arch/sparc/include/asm/cmpxchg_32.h
@@ -0,0 +1,112 @@
+/* 32-bit atomic xchg() and cmpxchg() definitions.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com.au)
+ * Copyright (C) 2007 Kyle McMartin (kyle@parisc-linux.org)
+ *
+ * Additions by Keith M Wesolowski (wesolows@foobazco.org) based
+ * on asm-parisc/atomic.h Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>.
+ */
+
+#ifndef __ARCH_SPARC_CMPXCHG__
+#define __ARCH_SPARC_CMPXCHG__
+
+#include <asm/btfixup.h>
+
+/* This has special calling conventions */
+#ifndef CONFIG_SMP
+BTFIXUPDEF_CALL(void, ___xchg32, void)
+#endif
+
+static inline unsigned long xchg_u32(__volatile__ unsigned long *m, unsigned long val)
+{
+#ifdef CONFIG_SMP
+ __asm__ __volatile__("swap [%2], %0"
+ : "=&r" (val)
+ : "0" (val), "r" (m)
+ : "memory");
+ return val;
+#else
+ register unsigned long *ptr asm("g1");
+ register unsigned long ret asm("g2");
+
+ ptr = (unsigned long *) m;
+ ret = val;
+
+ /* Note: this is magic and the nop there is
+ really needed. */
+ __asm__ __volatile__(
+ "mov %%o7, %%g4\n\t"
+ "call ___f____xchg32\n\t"
+ " nop\n\t"
+ : "=&r" (ret)
+ : "0" (ret), "r" (ptr)
+ : "g3", "g4", "g7", "memory", "cc");
+
+ return ret;
+#endif
+}
+
+extern void __xchg_called_with_bad_pointer(void);
+
+static inline unsigned long __xchg(unsigned long x, __volatile__ void * ptr, int size)
+{
+ switch (size) {
+ case 4:
+ return xchg_u32(ptr, x);
+ }
+ __xchg_called_with_bad_pointer();
+ return x;
+}
+
+#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
+
+/* Emulate cmpxchg() the same way we emulate atomics,
+ * by hashing the object address and indexing into an array
+ * of spinlocks to get a bit of performance...
+ *
+ * See arch/sparc/lib/atomic32.c for implementation.
+ *
+ * Cribbed from <asm-parisc/atomic.h>
+ */
+#define __HAVE_ARCH_CMPXCHG 1
+
+/* bug catcher for when unsupported size is used - won't link */
+extern void __cmpxchg_called_with_bad_pointer(void);
+/* we only need to support cmpxchg of a u32 on sparc */
+extern unsigned long __cmpxchg_u32(volatile u32 *m, u32 old, u32 new_);
+
+/* don't worry...optimizer will get rid of most of this */
+static inline unsigned long
+__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new_, int size)
+{
+ switch (size) {
+ case 4:
+ return __cmpxchg_u32((u32 *)ptr, (u32)old, (u32)new_);
+ default:
+ __cmpxchg_called_with_bad_pointer();
+ break;
+ }
+ return old;
+}
+
+#define cmpxchg(ptr, o, n) \
+({ \
+ __typeof__(*(ptr)) _o_ = (o); \
+ __typeof__(*(ptr)) _n_ = (n); \
+ (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \
+ (unsigned long)_n_, sizeof(*(ptr))); \
+})
+
+#include <asm-generic/cmpxchg-local.h>
+
+/*
+ * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
+ * them available.
+ */
+#define cmpxchg_local(ptr, o, n) \
+ ((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), (unsigned long)(o),\
+ (unsigned long)(n), sizeof(*(ptr))))
+#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
+
+#endif /* __ARCH_SPARC_CMPXCHG__ */
diff --git a/arch/sparc/include/asm/cmpxchg_64.h b/arch/sparc/include/asm/cmpxchg_64.h
new file mode 100644
index 00000000000..b30eb37294c
--- /dev/null
+++ b/arch/sparc/include/asm/cmpxchg_64.h
@@ -0,0 +1,145 @@
+/* 64-bit atomic xchg() and cmpxchg() definitions.
+ *
+ * Copyright (C) 1996, 1997, 2000 David S. Miller (davem@redhat.com)
+ */
+
+#ifndef __ARCH_SPARC64_CMPXCHG__
+#define __ARCH_SPARC64_CMPXCHG__
+
+static inline unsigned long xchg32(__volatile__ unsigned int *m, unsigned int val)
+{
+ unsigned long tmp1, tmp2;
+
+ __asm__ __volatile__(
+" mov %0, %1\n"
+"1: lduw [%4], %2\n"
+" cas [%4], %2, %0\n"
+" cmp %2, %0\n"
+" bne,a,pn %%icc, 1b\n"
+" mov %1, %0\n"
+ : "=&r" (val), "=&r" (tmp1), "=&r" (tmp2)
+ : "0" (val), "r" (m)
+ : "cc", "memory");
+ return val;
+}
+
+static inline unsigned long xchg64(__volatile__ unsigned long *m, unsigned long val)
+{
+ unsigned long tmp1, tmp2;
+
+ __asm__ __volatile__(
+" mov %0, %1\n"
+"1: ldx [%4], %2\n"
+" casx [%4], %2, %0\n"
+" cmp %2, %0\n"
+" bne,a,pn %%xcc, 1b\n"
+" mov %1, %0\n"
+ : "=&r" (val), "=&r" (tmp1), "=&r" (tmp2)
+ : "0" (val), "r" (m)
+ : "cc", "memory");
+ return val;
+}
+
+#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
+
+extern void __xchg_called_with_bad_pointer(void);
+
+static inline unsigned long __xchg(unsigned long x, __volatile__ void * ptr,
+ int size)
+{
+ switch (size) {
+ case 4:
+ return xchg32(ptr, x);
+ case 8:
+ return xchg64(ptr, x);
+ }
+ __xchg_called_with_bad_pointer();
+ return x;
+}
+
+/*
+ * Atomic compare and exchange. Compare OLD with MEM, if identical,
+ * store NEW in MEM. Return the initial value in MEM. Success is
+ * indicated by comparing RETURN with OLD.
+ */
+
+#include <asm-generic/cmpxchg-local.h>
+
+#define __HAVE_ARCH_CMPXCHG 1
+
+static inline unsigned long
+__cmpxchg_u32(volatile int *m, int old, int new)
+{
+ __asm__ __volatile__("cas [%2], %3, %0"
+ : "=&r" (new)
+ : "0" (new), "r" (m), "r" (old)
+ : "memory");
+
+ return new;
+}
+
+static inline unsigned long
+__cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new)
+{
+ __asm__ __volatile__("casx [%2], %3, %0"
+ : "=&r" (new)
+ : "0" (new), "r" (m), "r" (old)
+ : "memory");
+
+ return new;
+}
+
+/* This function doesn't exist, so you'll get a linker error
+ if something tries to do an invalid cmpxchg(). */
+extern void __cmpxchg_called_with_bad_pointer(void);
+
+static inline unsigned long
+__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
+{
+ switch (size) {
+ case 4:
+ return __cmpxchg_u32(ptr, old, new);
+ case 8:
+ return __cmpxchg_u64(ptr, old, new);
+ }
+ __cmpxchg_called_with_bad_pointer();
+ return old;
+}
+
+#define cmpxchg(ptr,o,n) \
+ ({ \
+ __typeof__(*(ptr)) _o_ = (o); \
+ __typeof__(*(ptr)) _n_ = (n); \
+ (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \
+ (unsigned long)_n_, sizeof(*(ptr))); \
+ })
+
+/*
+ * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
+ * them available.
+ */
+
+static inline unsigned long __cmpxchg_local(volatile void *ptr,
+ unsigned long old,
+ unsigned long new, int size)
+{
+ switch (size) {
+ case 4:
+ case 8: return __cmpxchg(ptr, old, new, size);
+ default:
+ return __cmpxchg_local_generic(ptr, old, new, size);
+ }
+
+ return old;
+}
+
+#define cmpxchg_local(ptr, o, n) \
+ ((__typeof__(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(o), \
+ (unsigned long)(n), sizeof(*(ptr))))
+#define cmpxchg64_local(ptr, o, n) \
+ ({ \
+ BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
+ cmpxchg_local((ptr), (o), (n)); \
+ })
+
+#endif /* __ARCH_SPARC64_CMPXCHG__ */
diff --git a/arch/sparc/include/asm/cpu_type.h b/arch/sparc/include/asm/cpu_type.h
new file mode 100644
index 00000000000..4ca184d95d8
--- /dev/null
+++ b/arch/sparc/include/asm/cpu_type.h
@@ -0,0 +1,34 @@
+#ifndef __ASM_CPU_TYPE_H
+#define __ASM_CPU_TYPE_H
+
+/*
+ * Sparc (general) CPU types
+ */
+enum sparc_cpu {
+ sun4 = 0x00,
+ sun4c = 0x01,
+ sun4m = 0x02,
+ sun4d = 0x03,
+ sun4e = 0x04,
+ sun4u = 0x05, /* V8 ploos ploos */
+ sun_unknown = 0x06,
+ ap1000 = 0x07, /* almost a sun4m */
+ sparc_leon = 0x08, /* Leon SoC */
+};
+
+#ifdef CONFIG_SPARC32
+extern enum sparc_cpu sparc_cpu_model;
+
+#define ARCH_SUN4C (sparc_cpu_model==sun4c)
+
+#define SUN4M_NCPUS 4 /* Architectural limit of sun4m. */
+
+#else
+
+#define sparc_cpu_model sun4u
+
+/* This cannot ever be a sun4c :) That's just history. */
+#define ARCH_SUN4C 0
+#endif
+
+#endif /* __ASM_CPU_TYPE_H */
diff --git a/arch/sparc/include/asm/exec.h b/arch/sparc/include/asm/exec.h
new file mode 100644
index 00000000000..2e085881e0d
--- /dev/null
+++ b/arch/sparc/include/asm/exec.h
@@ -0,0 +1,6 @@
+#ifndef __SPARC_EXEC_H
+#define __SPARC_EXEC_H
+
+#define arch_align_stack(x) (x)
+
+#endif /* __SPARC_EXEC_H */
diff --git a/arch/sparc/include/asm/floppy_32.h b/arch/sparc/include/asm/floppy_32.h
index 7440915e86d..698d9559fea 100644
--- a/arch/sparc/include/asm/floppy_32.h
+++ b/arch/sparc/include/asm/floppy_32.h
@@ -11,7 +11,6 @@
#include <asm/page.h>
#include <asm/pgtable.h>
-#include <asm/system.h>
#include <asm/idprom.h>
#include <asm/machines.h>
#include <asm/oplib.h>
diff --git a/arch/sparc/include/asm/futex_64.h b/arch/sparc/include/asm/futex_64.h
index 444e7bea23b..4e899b0dabf 100644
--- a/arch/sparc/include/asm/futex_64.h
+++ b/arch/sparc/include/asm/futex_64.h
@@ -4,7 +4,6 @@
#include <linux/futex.h>
#include <linux/uaccess.h>
#include <asm/errno.h>
-#include <asm/system.h>
#define __futex_cas_op(insn, ret, oldval, uaddr, oparg) \
__asm__ __volatile__( \
diff --git a/arch/sparc/include/asm/io_32.h b/arch/sparc/include/asm/io_32.h
index 2006e5d359d..c1acbd891cb 100644
--- a/arch/sparc/include/asm/io_32.h
+++ b/arch/sparc/include/asm/io_32.h
@@ -6,7 +6,6 @@
#include <linux/ioport.h> /* struct resource */
#include <asm/page.h> /* IO address mapping routines need this */
-#include <asm/system.h>
#include <asm-generic/pci_iomap.h>
#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT)
diff --git a/arch/sparc/include/asm/io_64.h b/arch/sparc/include/asm/io_64.h
index 9481e5a6fa9..09b0b88aeb2 100644
--- a/arch/sparc/include/asm/io_64.h
+++ b/arch/sparc/include/asm/io_64.h
@@ -6,7 +6,6 @@
#include <linux/types.h>
#include <asm/page.h> /* IO address mapping routines need this */
-#include <asm/system.h>
#include <asm/asi.h>
#include <asm-generic/pci_iomap.h>
diff --git a/arch/sparc/include/asm/irqflags_32.h b/arch/sparc/include/asm/irqflags_32.h
index 14848909e0d..e414c06615c 100644
--- a/arch/sparc/include/asm/irqflags_32.h
+++ b/arch/sparc/include/asm/irqflags_32.h
@@ -13,6 +13,7 @@
#ifndef __ASSEMBLY__
#include <linux/types.h>
+#include <asm/psr.h>
extern void arch_local_irq_restore(unsigned long);
extern unsigned long arch_local_irq_save(void);
diff --git a/arch/sparc/include/asm/mmu_context_64.h b/arch/sparc/include/asm/mmu_context_64.h
index 666a73fef28..a97fd085ceb 100644
--- a/arch/sparc/include/asm/mmu_context_64.h
+++ b/arch/sparc/include/asm/mmu_context_64.h
@@ -6,7 +6,6 @@
#ifndef __ASSEMBLY__
#include <linux/spinlock.h>
-#include <asm/system.h>
#include <asm/spitfire.h>
#include <asm-generic/mm_hooks.h>
diff --git a/arch/sparc/include/asm/ns87303.h b/arch/sparc/include/asm/ns87303.h
index af755483e17..6b947ee0f6a 100644
--- a/arch/sparc/include/asm/ns87303.h
+++ b/arch/sparc/include/asm/ns87303.h
@@ -79,7 +79,6 @@
#include <linux/spinlock.h>
-#include <asm/system.h>
#include <asm/io.h>
extern spinlock_t ns87303_lock;
diff --git a/arch/sparc/include/asm/perfctr.h b/arch/sparc/include/asm/perfctr.h
index 8d8720a8770..3332d2cba6c 100644
--- a/arch/sparc/include/asm/perfctr.h
+++ b/arch/sparc/include/asm/perfctr.h
@@ -168,6 +168,29 @@ struct vcounter_struct {
unsigned long long vcnt1;
};
+#else /* !(__KERNEL__) */
+
+#ifndef CONFIG_SPARC32
+
+/* Performance counter register access. */
+#define read_pcr(__p) __asm__ __volatile__("rd %%pcr, %0" : "=r" (__p))
+#define write_pcr(__p) __asm__ __volatile__("wr %0, 0x0, %%pcr" : : "r" (__p))
+#define read_pic(__p) __asm__ __volatile__("rd %%pic, %0" : "=r" (__p))
+
+/* Blackbird errata workaround. See commentary in
+ * arch/sparc64/kernel/smp.c:smp_percpu_timer_interrupt()
+ * for more information.
+ */
+#define write_pic(__p) \
+ __asm__ __volatile__("ba,pt %%xcc, 99f\n\t" \
+ " nop\n\t" \
+ ".align 64\n" \
+ "99:wr %0, 0x0, %%pic\n\t" \
+ "rd %%pic, %%g0" : : "r" (__p))
+#define reset_pic() write_pic(0)
+
+#endif /* !CONFIG_SPARC32 */
+
#endif /* !(__KERNEL__) */
#endif /* !(PERF_COUNTER_API) */
diff --git a/arch/sparc/include/asm/pgtable_32.h b/arch/sparc/include/asm/pgtable_32.h
index a790cc65747..3d7101860e6 100644
--- a/arch/sparc/include/asm/pgtable_32.h
+++ b/arch/sparc/include/asm/pgtable_32.h
@@ -21,7 +21,7 @@
#include <asm/vac-ops.h>
#include <asm/oplib.h>
#include <asm/btfixup.h>
-#include <asm/system.h>
+#include <asm/cpu_type.h>
struct vm_area_struct;
diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h
index 38ebb2c6013..6fa2f7980e6 100644
--- a/arch/sparc/include/asm/pgtable_64.h
+++ b/arch/sparc/include/asm/pgtable_64.h
@@ -19,7 +19,6 @@
#include <asm/types.h>
#include <asm/spitfire.h>
#include <asm/asi.h>
-#include <asm/system.h>
#include <asm/page.h>
#include <asm/processor.h>
diff --git a/arch/sparc/include/asm/processor.h b/arch/sparc/include/asm/processor.h
index 9da9646bf6c..2fe99e66e76 100644
--- a/arch/sparc/include/asm/processor.h
+++ b/arch/sparc/include/asm/processor.h
@@ -5,4 +5,7 @@
#else
#include <asm/processor_32.h>
#endif
+
+#define nop() __asm__ __volatile__ ("nop")
+
#endif
diff --git a/arch/sparc/include/asm/processor_64.h b/arch/sparc/include/asm/processor_64.h
index 59fcebb8f44..e713db24993 100644
--- a/arch/sparc/include/asm/processor_64.h
+++ b/arch/sparc/include/asm/processor_64.h
@@ -18,6 +18,9 @@
#include <asm/ptrace.h>
#include <asm/page.h>
+/* Don't hold the runqueue lock over context switch */
+#define __ARCH_WANT_UNLOCKED_CTXSW
+
/* The sparc has no problems with write protection */
#define wp_works_ok 1
#define wp_works_ok__is_a_macro /* for versions in ksyms.c */
diff --git a/arch/sparc/include/asm/ptrace.h b/arch/sparc/include/asm/ptrace.h
index c00c3b5c280..ef8c7c068f5 100644
--- a/arch/sparc/include/asm/ptrace.h
+++ b/arch/sparc/include/asm/ptrace.h
@@ -98,6 +98,8 @@ struct sparc_trapf {
*/
#ifndef __ASSEMBLY__
+#include <linux/types.h>
+
struct pt_regs {
unsigned long psr;
unsigned long pc;
@@ -163,7 +165,6 @@ struct sparc_stackf {
#ifdef __KERNEL__
#include <linux/threads.h>
-#include <asm/system.h>
static inline int pt_regs_trap_type(struct pt_regs *regs)
{
@@ -240,8 +241,6 @@ extern unsigned long profile_pc(struct pt_regs *);
#ifdef __KERNEL__
-#include <asm/system.h>
-
static inline bool pt_regs_is_syscall(struct pt_regs *regs)
{
return (regs->psr & PSR_SYSCALL);
diff --git a/arch/sparc/include/asm/setup.h b/arch/sparc/include/asm/setup.h
index 64718ba2643..00497abec99 100644
--- a/arch/sparc/include/asm/setup.h
+++ b/arch/sparc/include/asm/setup.h
@@ -13,14 +13,30 @@
#ifdef __KERNEL__
+extern char reboot_command[];
+
#ifdef CONFIG_SPARC32
/* The CPU that was used for booting
* Only sun4d + leon may have boot_cpu_id != 0
*/
extern unsigned char boot_cpu_id;
extern unsigned char boot_cpu_id4;
+
+extern unsigned long empty_bad_page;
+extern unsigned