summaryrefslogtreecommitdiffstats
path: root/arch/sh/include/asm
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2011-01-13 15:06:28 +0900
committerPaul Mundt <lethal@linux-sh.org>2011-01-13 15:06:28 +0900
commitf43dc23d5ea91fca257be02138a255f02d98e806 (patch)
treeb29722f6e965316e90ac97abf79923ced250dc21 /arch/sh/include/asm
parentf8e53553f452dcbf67cb89c8cba63a1cd6eb4cc0 (diff)
parent4162cf64973df51fc885825bc9ca4d055891c49f (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6 into common/serial-rework
Conflicts: arch/sh/kernel/cpu/sh2/setup-sh7619.c arch/sh/kernel/cpu/sh2a/setup-mxg.c arch/sh/kernel/cpu/sh2a/setup-sh7201.c arch/sh/kernel/cpu/sh2a/setup-sh7203.c arch/sh/kernel/cpu/sh2a/setup-sh7206.c arch/sh/kernel/cpu/sh3/setup-sh7705.c arch/sh/kernel/cpu/sh3/setup-sh770x.c arch/sh/kernel/cpu/sh3/setup-sh7710.c arch/sh/kernel/cpu/sh3/setup-sh7720.c arch/sh/kernel/cpu/sh4/setup-sh4-202.c arch/sh/kernel/cpu/sh4/setup-sh7750.c arch/sh/kernel/cpu/sh4/setup-sh7760.c arch/sh/kernel/cpu/sh4a/setup-sh7343.c arch/sh/kernel/cpu/sh4a/setup-sh7366.c arch/sh/kernel/cpu/sh4a/setup-sh7722.c arch/sh/kernel/cpu/sh4a/setup-sh7723.c arch/sh/kernel/cpu/sh4a/setup-sh7724.c arch/sh/kernel/cpu/sh4a/setup-sh7763.c arch/sh/kernel/cpu/sh4a/setup-sh7770.c arch/sh/kernel/cpu/sh4a/setup-sh7780.c arch/sh/kernel/cpu/sh4a/setup-sh7785.c arch/sh/kernel/cpu/sh4a/setup-sh7786.c arch/sh/kernel/cpu/sh4a/setup-shx3.c arch/sh/kernel/cpu/sh5/setup-sh5.c drivers/serial/sh-sci.c drivers/serial/sh-sci.h include/linux/serial_sci.h
Diffstat (limited to 'arch/sh/include/asm')
-rw-r--r--arch/sh/include/asm/.gitignore1
-rw-r--r--arch/sh/include/asm/Kbuild13
-rw-r--r--arch/sh/include/asm/addrspace.h15
-rw-r--r--arch/sh/include/asm/alignment.h21
-rw-r--r--arch/sh/include/asm/asm-offsets.h1
-rw-r--r--arch/sh/include/asm/atomic-grb.h46
-rw-r--r--arch/sh/include/asm/atomic-llsc.h27
-rw-r--r--arch/sh/include/asm/atomic.h84
-rw-r--r--arch/sh/include/asm/bitops.h4
-rw-r--r--arch/sh/include/asm/bug.h35
-rw-r--r--arch/sh/include/asm/bugs.h28
-rw-r--r--arch/sh/include/asm/cache.h6
-rw-r--r--arch/sh/include/asm/cachectl.h19
-rw-r--r--arch/sh/include/asm/cacheflush.h129
-rw-r--r--arch/sh/include/asm/clkdev.h31
-rw-r--r--arch/sh/include/asm/clock.h152
-rw-r--r--arch/sh/include/asm/cmpxchg-grb.h7
-rw-r--r--arch/sh/include/asm/device.h16
-rw-r--r--arch/sh/include/asm/dma-mapping.h226
-rw-r--r--arch/sh/include/asm/dma-register.h51
-rw-r--r--arch/sh/include/asm/dma-sh.h51
-rw-r--r--arch/sh/include/asm/dma.h6
-rw-r--r--arch/sh/include/asm/dwarf.h421
-rw-r--r--arch/sh/include/asm/elf.h34
-rw-r--r--arch/sh/include/asm/entry-macros.S86
-rw-r--r--arch/sh/include/asm/fixmap.h29
-rw-r--r--arch/sh/include/asm/fpu.h55
-rw-r--r--arch/sh/include/asm/ftrace.h25
-rw-r--r--arch/sh/include/asm/gpio.h88
-rw-r--r--arch/sh/include/asm/hardirq.h2
-rw-r--r--arch/sh/include/asm/heartbeat.h1
-rw-r--r--arch/sh/include/asm/hw_breakpoint.h70
-rw-r--r--arch/sh/include/asm/hwblk.h70
-rw-r--r--arch/sh/include/asm/ilsel.h45
-rw-r--r--arch/sh/include/asm/io.h402
-rw-r--r--arch/sh/include/asm/io_generic.h26
-rw-r--r--arch/sh/include/asm/ioctls.h3
-rw-r--r--arch/sh/include/asm/irq.h21
-rw-r--r--arch/sh/include/asm/irqflags.h31
-rw-r--r--arch/sh/include/asm/irqflags_32.h99
-rw-r--r--arch/sh/include/asm/irqflags_64.h85
-rw-r--r--arch/sh/include/asm/kdebug.h3
-rw-r--r--arch/sh/include/asm/kexec.h8
-rw-r--r--arch/sh/include/asm/kgdb.h3
-rw-r--r--arch/sh/include/asm/kprobes.h1
-rw-r--r--arch/sh/include/asm/local64.h1
-rw-r--r--arch/sh/include/asm/machvec.h28
-rw-r--r--arch/sh/include/asm/memblock.h4
-rw-r--r--arch/sh/include/asm/mmu.h82
-rw-r--r--arch/sh/include/asm/mmu_context.h8
-rw-r--r--arch/sh/include/asm/mmu_context_32.h4
-rw-r--r--arch/sh/include/asm/mmzone.h3
-rw-r--r--arch/sh/include/asm/module.h17
-rw-r--r--arch/sh/include/asm/page.h58
-rw-r--r--arch/sh/include/asm/pci.h97
-rw-r--r--arch/sh/include/asm/perf_counter.h7
-rw-r--r--arch/sh/include/asm/perf_event.h29
-rw-r--r--arch/sh/include/asm/pgalloc.h42
-rw-r--r--arch/sh/include/asm/pgtable-2level.h23
-rw-r--r--arch/sh/include/asm/pgtable-3level.h56
-rw-r--r--arch/sh/include/asm/pgtable.h81
-rw-r--r--arch/sh/include/asm/pgtable_32.h44
-rw-r--r--arch/sh/include/asm/pgtable_64.h42
-rw-r--r--arch/sh/include/asm/processor.h44
-rw-r--r--arch/sh/include/asm/processor_32.h50
-rw-r--r--arch/sh/include/asm/processor_64.h26
-rw-r--r--arch/sh/include/asm/ptrace.h191
-rw-r--r--arch/sh/include/asm/ptrace_32.h83
-rw-r--r--arch/sh/include/asm/ptrace_64.h20
-rw-r--r--arch/sh/include/asm/reboot.h21
-rw-r--r--arch/sh/include/asm/romimage-macros.h73
-rw-r--r--arch/sh/include/asm/rwsem.h2
-rw-r--r--arch/sh/include/asm/scatterlist.h2
-rw-r--r--arch/sh/include/asm/sections.h1
-rw-r--r--arch/sh/include/asm/setup.h2
-rw-r--r--arch/sh/include/asm/sh_bios.h15
-rw-r--r--arch/sh/include/asm/sh_eth.h4
-rw-r--r--arch/sh/include/asm/sh_keysc.h13
-rw-r--r--arch/sh/include/asm/siu.h24
-rw-r--r--arch/sh/include/asm/sizes.h1
-rw-r--r--arch/sh/include/asm/smp-ops.h51
-rw-r--r--arch/sh/include/asm/smp.h41
-rw-r--r--arch/sh/include/asm/spinlock.h58
-rw-r--r--arch/sh/include/asm/spinlock_types.h8
-rw-r--r--arch/sh/include/asm/sram.h38
-rw-r--r--arch/sh/include/asm/stacktrace.h25
-rw-r--r--arch/sh/include/asm/suspend.h75
-rw-r--r--arch/sh/include/asm/syscall.h2
-rw-r--r--arch/sh/include/asm/syscall_32.h2
-rw-r--r--arch/sh/include/asm/syscalls.h5
-rw-r--r--arch/sh/include/asm/syscalls_32.h7
-rw-r--r--arch/sh/include/asm/syscalls_64.h2
-rw-r--r--arch/sh/include/asm/system.h26
-rw-r--r--arch/sh/include/asm/system_32.h122
-rw-r--r--arch/sh/include/asm/system_64.h45
-rw-r--r--arch/sh/include/asm/thread_info.h53
-rw-r--r--arch/sh/include/asm/timex.h10
-rw-r--r--arch/sh/include/asm/tlb.h23
-rw-r--r--arch/sh/include/asm/tlbflush.h2
-rw-r--r--arch/sh/include/asm/topology.h21
-rw-r--r--arch/sh/include/asm/types.h2
-rw-r--r--arch/sh/include/asm/ubc.h75
-rw-r--r--arch/sh/include/asm/unaligned-sh4a.h164
-rw-r--r--arch/sh/include/asm/uncached.h58
-rw-r--r--arch/sh/include/asm/unistd_32.h32
-rw-r--r--arch/sh/include/asm/unistd_64.h13
-rw-r--r--arch/sh/include/asm/unwinder.h31
-rw-r--r--arch/sh/include/asm/vmlinux.lds.h25
-rw-r--r--arch/sh/include/asm/watchdog.h86
109 files changed, 2966 insertions, 1911 deletions
diff --git a/arch/sh/include/asm/.gitignore b/arch/sh/include/asm/.gitignore
deleted file mode 100644
index 378db779fb6..00000000000
--- a/arch/sh/include/asm/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-machtypes.h
diff --git a/arch/sh/include/asm/Kbuild b/arch/sh/include/asm/Kbuild
index 43910cdf78a..7beb42322f6 100644
--- a/arch/sh/include/asm/Kbuild
+++ b/arch/sh/include/asm/Kbuild
@@ -1,8 +1,11 @@
include include/asm-generic/Kbuild.asm
+header-y += cachectl.h
header-y += cpu-features.h
-
-unifdef-y += unistd_32.h
-unifdef-y += unistd_64.h
-unifdef-y += posix_types_32.h
-unifdef-y += posix_types_64.h
+header-y += hw_breakpoint.h
+header-y += posix_types_32.h
+header-y += posix_types_64.h
+header-y += ptrace_32.h
+header-y += ptrace_64.h
+header-y += unistd_32.h
+header-y += unistd_64.h
diff --git a/arch/sh/include/asm/addrspace.h b/arch/sh/include/asm/addrspace.h
index 80d40813e05..3d1ae2bfaa6 100644
--- a/arch/sh/include/asm/addrspace.h
+++ b/arch/sh/include/asm/addrspace.h
@@ -28,10 +28,7 @@
/* Returns the privileged segment base of a given address */
#define PXSEG(a) (((unsigned long)(a)) & 0xe0000000)
-/* Returns the physical address of a PnSEG (n=1,2) address */
-#define PHYSADDR(a) (((unsigned long)(a)) & 0x1fffffff)
-
-#if defined(CONFIG_29BIT) || defined(CONFIG_PMB_FIXED)
+#ifdef CONFIG_29BIT
/*
* Map an address to a certain privileged segment
*/
@@ -43,7 +40,15 @@
((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | P3SEG))
#define P4SEGADDR(a) \
((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | P4SEG))
-#endif /* 29BIT || PMB_FIXED */
+#else
+/*
+ * These will never work in 32-bit, don't even bother.
+ */
+#define P1SEGADDR(a) ({ (void)(a); BUG(); NULL; })
+#define P2SEGADDR(a) ({ (void)(a); BUG(); NULL; })
+#define P3SEGADDR(a) ({ (void)(a); BUG(); NULL; })
+#define P4SEGADDR(a) ({ (void)(a); BUG(); NULL; })
+#endif
#endif /* P1SEG */
/* Check if an address can be reached in 29 bits */
diff --git a/arch/sh/include/asm/alignment.h b/arch/sh/include/asm/alignment.h
new file mode 100644
index 00000000000..b12efecf529
--- /dev/null
+++ b/arch/sh/include/asm/alignment.h
@@ -0,0 +1,21 @@
+#ifndef __ASM_SH_ALIGNMENT_H
+#define __ASM_SH_ALIGNMENT_H
+
+#include <linux/types.h>
+
+extern void inc_unaligned_byte_access(void);
+extern void inc_unaligned_word_access(void);
+extern void inc_unaligned_dword_access(void);
+extern void inc_unaligned_multi_access(void);
+extern void inc_unaligned_user_access(void);
+extern void inc_unaligned_kernel_access(void);
+
+#define UM_WARN (1 << 0)
+#define UM_FIXUP (1 << 1)
+#define UM_SIGNAL (1 << 2)
+
+extern unsigned int unaligned_user_action(void);
+
+extern void unaligned_fixups_notify(struct task_struct *, insn_size_t, struct pt_regs *);
+
+#endif /* __ASM_SH_ALIGNMENT_H */
diff --git a/arch/sh/include/asm/asm-offsets.h b/arch/sh/include/asm/asm-offsets.h
new file mode 100644
index 00000000000..d370ee36a18
--- /dev/null
+++ b/arch/sh/include/asm/asm-offsets.h
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>
diff --git a/arch/sh/include/asm/atomic-grb.h b/arch/sh/include/asm/atomic-grb.h
index 4c5b7dbfced..a273c88578f 100644
--- a/arch/sh/include/asm/atomic-grb.h
+++ b/arch/sh/include/asm/atomic-grb.h
@@ -120,50 +120,4 @@ static inline void atomic_set_mask(unsigned int mask, atomic_t *v)
: "memory" , "r0", "r1");
}
-static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
-{
- int ret;
-
- __asm__ __volatile__ (
- " .align 2 \n\t"
- " mova 1f, r0 \n\t"
- " nop \n\t"
- " mov r15, r1 \n\t"
- " mov #-8, r15 \n\t"
- " mov.l @%1, %0 \n\t"
- " cmp/eq %2, %0 \n\t"
- " bf 1f \n\t"
- " mov.l %3, @%1 \n\t"
- "1: mov r1, r15 \n\t"
- : "=&r" (ret)
- : "r" (v), "r" (old), "r" (new)
- : "memory" , "r0", "r1" , "t");
-
- return ret;
-}
-
-static inline int atomic_add_unless(atomic_t *v, int a, int u)
-{
- int ret;
- unsigned long tmp;
-
- __asm__ __volatile__ (
- " .align 2 \n\t"
- " mova 1f, r0 \n\t"
- " nop \n\t"
- " mov r15, r1 \n\t"
- " mov #-12, r15 \n\t"
- " mov.l @%2, %1 \n\t"
- " mov %1, %0 \n\t"
- " cmp/eq %4, %0 \n\t"
- " bt/s 1f \n\t"
- " add %3, %1 \n\t"
- " mov.l %1, @%2 \n\t"
- "1: mov r1, r15 \n\t"
- : "=&r" (ret), "=&r" (tmp)
- : "r" (v), "r" (a), "r" (u)
- : "memory" , "r0", "r1" , "t");
-
- return ret != u;
-}
#endif /* __ASM_SH_ATOMIC_GRB_H */
diff --git a/arch/sh/include/asm/atomic-llsc.h b/arch/sh/include/asm/atomic-llsc.h
index b040e1e0861..4b00b78e3f4 100644
--- a/arch/sh/include/asm/atomic-llsc.h
+++ b/arch/sh/include/asm/atomic-llsc.h
@@ -104,31 +104,4 @@ static inline void atomic_set_mask(unsigned int mask, atomic_t *v)
: "t");
}
-#define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
-
-/**
- * atomic_add_unless - add unless the number is a given value
- * @v: pointer of type atomic_t
- * @a: the amount to add to v...
- * @u: ...unless v is equal to u.
- *
- * Atomically adds @a to @v, so long as it was not @u.
- * Returns non-zero if @v was not @u, and zero otherwise.
- */
-static inline int atomic_add_unless(atomic_t *v, int a, int u)
-{
- int c, old;
- c = atomic_read(v);
- for (;;) {
- if (unlikely(c == (u)))
- break;
- old = atomic_cmpxchg((v), c, c + (a));
- if (likely(old == c))
- break;
- c = old;
- }
-
- return c != (u);
-}
-
#endif /* __ASM_SH_ATOMIC_LLSC_H */
diff --git a/arch/sh/include/asm/atomic.h b/arch/sh/include/asm/atomic.h
index e8e78137c6f..c7983124d99 100644
--- a/arch/sh/include/asm/atomic.h
+++ b/arch/sh/include/asm/atomic.h
@@ -13,7 +13,7 @@
#define ATOMIC_INIT(i) ( (atomic_t) { (i) } )
-#define atomic_read(v) ((v)->counter)
+#define atomic_read(v) (*(volatile int *)&(v)->counter)
#define atomic_set(v,i) ((v)->counter = (i))
#if defined(CONFIG_GUSA_RB)
@@ -25,64 +25,48 @@
#endif
#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0)
+#define atomic_dec_return(v) atomic_sub_return(1, (v))
+#define atomic_inc_return(v) atomic_add_return(1, (v))
+#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
+#define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0)
+#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
-#define atomic_dec_return(v) atomic_sub_return(1,(v))
-#define atomic_inc_return(v) atomic_add_return(1,(v))
+#define atomic_inc(v) atomic_add(1, (v))
+#define atomic_dec(v) atomic_sub(1, (v))
-/*
- * atomic_inc_and_test - increment and test
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+#define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
+
+/**
+ * atomic_add_unless - add unless the number is a given value
* @v: pointer of type atomic_t
+ * @a: the amount to add to v...
+ * @u: ...unless v is equal to u.
*
- * Atomically increments @v by 1
- * and returns true if the result is zero, or false for all
- * other cases.
+ * Atomically adds @a to @v, so long as it was not @u.
+ * Returns non-zero if @v was not @u, and zero otherwise.
*/
-#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
-
-#define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0)
-#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
-
-#define atomic_inc(v) atomic_add(1,(v))
-#define atomic_dec(v) atomic_sub(1,(v))
-
-#if !defined(CONFIG_GUSA_RB) && !defined(CONFIG_CPU_SH4A)
-static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
-{
- int ret;
- unsigned long flags;
-
- local_irq_save(flags);
- ret = v->counter;
- if (likely(ret == old))
- v->counter = new;
- local_irq_restore(flags);
-
- return ret;
-}
-
static inline int atomic_add_unless(atomic_t *v, int a, int u)
{
- int ret;
- unsigned long flags;
-
- local_irq_save(flags);
- ret = v->counter;
- if (ret != u)
- v->counter += a;
- local_irq_restore(flags);
-
- return ret != u;
+ int c, old;
+ c = atomic_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+
+ return c != (u);
}
-#endif /* !CONFIG_GUSA_RB && !CONFIG_CPU_SH4A */
-
-#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
-#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
-/* Atomic operations are already serializing on SH */
-#define smp_mb__before_atomic_dec() barrier()
-#define smp_mb__after_atomic_dec() barrier()
-#define smp_mb__before_atomic_inc() barrier()
-#define smp_mb__after_atomic_inc() barrier()
+#define smp_mb__before_atomic_dec() smp_mb()
+#define smp_mb__after_atomic_dec() smp_mb()
+#define smp_mb__before_atomic_inc() smp_mb()
+#define smp_mb__after_atomic_inc() smp_mb()
#include <asm-generic/atomic-long.h>
#include <asm-generic/atomic64.h>
diff --git a/arch/sh/include/asm/bitops.h b/arch/sh/include/asm/bitops.h
index ebe595b7ab1..98511e4d28c 100644
--- a/arch/sh/include/asm/bitops.h
+++ b/arch/sh/include/asm/bitops.h
@@ -26,8 +26,8 @@
/*
* clear_bit() doesn't provide any barrier for the compiler.
*/
-#define smp_mb__before_clear_bit() barrier()
-#define smp_mb__after_clear_bit() barrier()
+#define smp_mb__before_clear_bit() smp_mb()
+#define smp_mb__after_clear_bit() smp_mb()
#ifdef CONFIG_SUPERH32
static inline unsigned long ffz(unsigned long word)
diff --git a/arch/sh/include/asm/bug.h b/arch/sh/include/asm/bug.h
index c0171804016..6323f864d11 100644
--- a/arch/sh/include/asm/bug.h
+++ b/arch/sh/include/asm/bug.h
@@ -2,6 +2,7 @@
#define __ASM_SH_BUG_H
#define TRAPA_BUG_OPCODE 0xc33e /* trapa #0x3e */
+#define BUGFLAG_UNWINDER (1 << 1)
#ifdef CONFIG_GENERIC_BUG
#define HAVE_ARCH_BUG
@@ -47,7 +48,7 @@ do { \
"i" (sizeof(struct bug_entry))); \
} while (0)
-#define __WARN() \
+#define __WARN_TAINT(taint) \
do { \
__asm__ __volatile__ ( \
"1:\t.short %O0\n" \
@@ -56,7 +57,7 @@ do { \
: "n" (TRAPA_BUG_OPCODE), \
"i" (__FILE__), \
"i" (__LINE__), \
- "i" (BUGFLAG_WARNING), \
+ "i" (BUGFLAG_TAINT(taint)), \
"i" (sizeof(struct bug_entry))); \
} while (0)
@@ -72,6 +73,36 @@ do { \
unlikely(__ret_warn_on); \
})
+#define UNWINDER_BUG() \
+do { \
+ __asm__ __volatile__ ( \
+ "1:\t.short %O0\n" \
+ _EMIT_BUG_ENTRY \
+ : \
+ : "n" (TRAPA_BUG_OPCODE), \
+ "i" (__FILE__), \
+ "i" (__LINE__), \
+ "i" (BUGFLAG_UNWINDER), \
+ "i" (sizeof(struct bug_entry))); \
+} while (0)
+
+#define UNWINDER_BUG_ON(x) ({ \
+ int __ret_unwinder_on = !!(x); \
+ if (__builtin_constant_p(__ret_unwinder_on)) { \
+ if (__ret_unwinder_on) \
+ UNWINDER_BUG(); \
+ } else { \
+ if (unlikely(__ret_unwinder_on)) \
+ UNWINDER_BUG(); \
+ } \
+ unlikely(__ret_unwinder_on); \
+})
+
+#else
+
+#define UNWINDER_BUG BUG
+#define UNWINDER_BUG_ON BUG_ON
+
#endif /* CONFIG_GENERIC_BUG */
#include <asm-generic/bug.h>
diff --git a/arch/sh/include/asm/bugs.h b/arch/sh/include/asm/bugs.h
index 4924ff6f543..02a19a1c033 100644
--- a/arch/sh/include/asm/bugs.h
+++ b/arch/sh/include/asm/bugs.h
@@ -14,32 +14,36 @@
#include <asm/processor.h>
+extern void select_idle_routine(void);
+
static void __init check_bugs(void)
{
extern unsigned long loops_per_jiffy;
char *p = &init_utsname()->machine[2]; /* "sh" */
+ select_idle_routine();
+
current_cpu_data.loops_per_jiffy = loops_per_jiffy;
- switch (current_cpu_data.type) {
- case CPU_SH7619:
+ switch (current_cpu_data.family) {
+ case CPU_FAMILY_SH2:
*p++ = '2';
break;
- case CPU_SH7201 ... CPU_MXG:
+ case CPU_FAMILY_SH2A:
*p++ = '2';
*p++ = 'a';
break;
- case CPU_SH7705 ... CPU_SH7729:
+ case CPU_FAMILY_SH3:
*p++ = '3';
break;
- case CPU_SH7750 ... CPU_SH4_501:
+ case CPU_FAMILY_SH4:
*p++ = '4';
break;
- case CPU_SH7763 ... CPU_SHX3:
+ case CPU_FAMILY_SH4A:
*p++ = '4';
*p++ = 'a';
break;
- case CPU_SH7343 ... CPU_SH7366:
+ case CPU_FAMILY_SH4AL_DSP:
*p++ = '4';
*p++ = 'a';
*p++ = 'l';
@@ -48,15 +52,15 @@ static void __init check_bugs(void)
*p++ = 's';
*p++ = 'p';
break;
- case CPU_SH5_101 ... CPU_SH5_103:
+ case CPU_FAMILY_SH5:
*p++ = '6';
*p++ = '4';
break;
- case CPU_SH_NONE:
+ case CPU_FAMILY_UNKNOWN:
/*
- * Specifically use CPU_SH_NONE rather than default:,
- * so we're able to have the compiler whine about
- * unhandled enumerations.
+ * Specifically use CPU_FAMILY_UNKNOWN rather than
+ * default:, so we're able to have the compiler whine
+ * about unhandled enumerations.
*/
break;
}
diff --git a/arch/sh/include/asm/cache.h b/arch/sh/include/asm/cache.h
index 02df18ea960..ef9e555aafb 100644
--- a/arch/sh/include/asm/cache.h
+++ b/arch/sh/include/asm/cache.h
@@ -14,7 +14,7 @@
#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
-#define __read_mostly __attribute__((__section__(".data.read_mostly")))
+#define __read_mostly __attribute__((__section__(".data..read_mostly")))
#ifndef __ASSEMBLY__
struct cache_info {
@@ -38,14 +38,10 @@ struct cache_info {
* 2. those in the physical page number.
*/
unsigned int alias_mask;
-
unsigned int n_aliases; /* Number of aliases */
unsigned long flags;
};
-
-int __init detect_cpu_and_cache_system(void);
-
#endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */
#endif /* __ASM_SH_CACHE_H */
diff --git a/arch/sh/include/asm/cachectl.h b/arch/sh/include/asm/cachectl.h
new file mode 100644
index 00000000000..6ffb4b7a212
--- /dev/null
+++ b/arch/sh/include/asm/cachectl.h
@@ -0,0 +1,19 @@
+#ifndef _SH_CACHECTL_H
+#define _SH_CACHECTL_H
+
+/* Definitions for the cacheflush system call. */
+
+#define CACHEFLUSH_D_INVAL 0x1 /* invalidate (without write back) */
+#define CACHEFLUSH_D_WB 0x2 /* write back (without invalidate) */
+#define CACHEFLUSH_D_PURGE 0x3 /* writeback and invalidate */
+
+#define CACHEFLUSH_I 0x4
+
+/*
+ * Options for cacheflush system call
+ */
+#define ICACHE CACHEFLUSH_I /* flush instruction cache */
+#define DCACHE CACHEFLUSH_D_PURGE /* writeback and flush data cache */
+#define BCACHE (ICACHE|DCACHE) /* flush both caches */
+
+#endif /* _SH_CACHECTL_H */
diff --git a/arch/sh/include/asm/cacheflush.h b/arch/sh/include/asm/cacheflush.h
index 4c5462daa74..82e1eabeac9 100644
--- a/arch/sh/include/asm/cacheflush.h
+++ b/arch/sh/include/asm/cacheflush.h
@@ -3,45 +3,74 @@
#ifdef __KERNEL__
-#ifdef CONFIG_CACHE_OFF
+#include <linux/mm.h>
+
/*
- * Nothing to do when the cache is disabled, initial flush and explicit
- * disabling is handled at CPU init time.
+ * Cache flushing:
+ *
+ * - flush_cache_all() flushes entire cache
+ * - flush_cache_mm(mm) flushes the specified mm context's cache lines
+ * - flush_cache_dup mm(mm) handles cache flushing when forking
+ * - flush_cache_page(mm, vmaddr, pfn) flushes a single page
+ * - flush_cache_range(vma, start, end) flushes a range of pages
*
- * See arch/sh/kernel/cpu/init.c:cache_init().
+ * - flush_dcache_page(pg) flushes(wback&invalidates) a page for dcache
+ * - flush_icache_range(start, end) flushes(invalidates) a range for icache
+ * - flush_icache_page(vma, pg) flushes(invalidates) a page for icache
+ * - flush_cache_sigtramp(vaddr) flushes the signal trampoline
*/
-#define p3_cache_init() do { } while (0)
-#define flush_cache_all() do { } while (0)
-#define flush_cache_mm(mm) do { } while (0)
-#define flush_cache_dup_mm(mm) do { } while (0)
-#define flush_cache_range(vma, start, end) do { } while (0)
-#define flush_cache_page(vma, vmaddr, pfn) do { } while (0)
-#define flush_dcache_page(page) do { } while (0)
-#define flush_icache_range(start, end) do { } while (0)
-#define flush_icache_page(vma,pg) do { } while (0)
-#define flush_dcache_mmap_lock(mapping) do { } while (0)
-#define flush_dcache_mmap_unlock(mapping) do { } while (0)
-#define flush_cache_sigtramp(vaddr) do { } while (0)
-#define flush_icache_user_range(vma,pg,adr,len) do { } while (0)
-#define __flush_wback_region(start, size) do { (void)(start); } while (0)
-#define __flush_purge_region(start, size) do { (void)(start); } while (0)
-#define __flush_invalidate_region(start, size) do { (void)(start); } while (0)
-#else
-#include <cpu/cacheflush.h>
+extern void (*local_flush_cache_all)(void *args);
+extern void (*local_flush_cache_mm)(void *args);
+extern void (*local_flush_cache_dup_mm)(void *args);
+extern void (*local_flush_cache_page)(void *args);
+extern void (*local_flush_cache_range)(void *args);
+extern void (*local_flush_dcache_page)(void *args);
+extern void (*local_flush_icache_range)(void *args);
+extern void (*local_flush_icache_page)(void *args);
+extern void (*local_flush_cache_sigtramp)(void *args);
-/*
- * Consistent DMA requires that the __flush_xxx() primitives must be set
- * for any of the enabled non-coherent caches (most of the UP CPUs),
- * regardless of PIPT or VIPT cache configurations.
- */
+static inline void cache_noop(void *args) { }
-/* Flush (write-back only) a region (smaller than a page) */
-extern void __flush_wback_region(void *start, int size);
-/* Flush (write-back & invalidate) a region (smaller than a page) */
-extern void __flush_purge_region(void *start, int size);
-/* Flush (invalidate only) a region (smaller than a page) */
-extern void __flush_invalidate_region(void *start, int size);
-#endif
+extern void (*__flush_wback_region)(void *start, int size);
+extern void (*__flush_purge_region)(void *start, int size);
+extern void (*__flush_invalidate_region)(void *start, int size);
+
+extern void flush_cache_all(void);
+extern void flush_cache_mm(struct mm_struct *mm);
+extern void flush_cache_dup_mm(struct mm_struct *mm);
+extern void flush_cache_page(struct vm_area_struct *vma,
+ unsigned long addr, unsigned long pfn);
+extern void flush_cache_range(struct vm_area_struct *vma,
+ unsigned long start, unsigned long end);
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
+extern void flush_dcache_page(struct page *page);
+extern void flush_icache_range(unsigned long start, unsigned long end);
+extern void flush_icache_page(struct vm_area_struct *vma,
+ struct page *page);
+extern void flush_cache_sigtramp(unsigned long address);
+
+struct flusher_data {
+ struct vm_area_struct *vma;
+ unsigned long addr1, addr2;
+};
+
+#define ARCH_HAS_FLUSH_ANON_PAGE
+extern void __flush_anon_page(struct page *page, unsigned long);
+
+static inline void flush_anon_page(struct vm_area_struct *vma,
+ struct page *page, unsigned long vmaddr)
+{
+ if (boot_cpu_data.dcache.n_aliases && PageAnon(page))
+ __flush_anon_page(page, vmaddr);
+}
+static inline void flush_kernel_vmap_range(void *addr, int size)
+{
+ __flush_wback_region(addr, size);
+}
+static inline void invalidate_kernel_vmap_range(void *addr, int size)
+{
+ __flush_invalidate_region(addr, size);
+}
#define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
static inline void flush_kernel_dcache_page(struct page *page)
@@ -49,7 +78,6 @@ static inline void flush_kernel_dcache_page(struct page *page)
flush_dcache_page(page);
}
-#if defined(CONFIG_CPU_SH4) && !defined(CONFIG_CACHE_OFF)
extern void copy_to_user_page(struct vm_area_struct *vma,
struct page *page, unsigned long vaddr, void *dst, const void *src,
unsigned long len);
@@ -57,23 +85,20 @@ extern void copy_to_user_page(struct vm_area_struct *vma,
extern void copy_from_user_page(struct vm_area_struct *vma,
struct page *page, unsigned long vaddr, void *dst, const void *src,
unsigned long len);
-#else
-#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
- do { \
- flush_cache_page(vma, vaddr, page_to_pfn(page));\
- memcpy(dst, src, len); \
- flush_icache_user_range(vma, page, vaddr, len); \
- } while (0)
-
-#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
- do { \
- flush_cache_page(vma, vaddr, page_to_pfn(page));\
- memcpy(dst, src, len); \
- } while (0)
-#endif
-
-#define flush_cache_vmap(start, end) flush_cache_all()
-#define flush_cache_vunmap(start, end) flush_cache_all()
+
+#define flush_cache_vmap(start, end) local_flush_cache_all(NULL)
+#define flush_cache_vunmap(start, end) local_flush_cache_all(NULL)
+
+#define flush_dcache_mmap_lock(mapping) do { } while (0)
+#define flush_dcache_mmap_unlock(mapping) do { } while (0)
+
+void kmap_coherent_init(void);
+void *kmap_coherent(struct page *page, unsigned long addr);
+void kunmap_coherent(void *kvaddr);
+
+#define PG_dcache_clean PG_arch_1
+
+void cpu_cache_init(void);
#endif /* __KERNEL__ */
#endif /* __ASM_SH_CACHEFLUSH_H */
diff --git a/arch/sh/include/asm/clkdev.h b/arch/sh/include/asm/clkdev.h
new file mode 100644
index 00000000000..6ba91868201
--- /dev/null
+++ b/arch/sh/include/asm/clkdev.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2010 Paul Mundt <lethal@linux-sh.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Helper for the clk API to assist looking up a struct clk.
+ */
+
+#ifndef __CLKDEV__H_
+#define __CLKDEV__H_
+
+#include <linux/bootmem.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+
+#include <asm/clock.h>
+
+static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size)
+{
+ if (!slab_is_available())
+ return alloc_bootmem_low_pages(size);
+ else
+ return kzalloc(size, GFP_KERNEL);
+}
+
+#define __clk_put(clk)
+#define __clk_get(clk) ({ 1; })
+
+#endif /* __CLKDEV_H__ */
diff --git a/arch/sh/include/asm/clock.h b/arch/sh/include/asm/clock.h
index 9fe7d7f8af4..803d4c7f09d 100644
--- a/arch/sh/include/asm/clock.h
+++ b/arch/sh/include/asm/clock.h
@@ -1,162 +1,16 @@
#ifndef __ASM_SH_CLOCK_H
#define __ASM_SH_CLOCK_H
-#include <linux/list.h>
-#include <linux/seq_file.h>
-#include <linux/cpufreq.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-
-struct clk;
-
-struct clk_ops {
- void (*init)(struct clk *clk);
- int (*enable)(struct clk *clk);
- void (*disable)(struct clk *clk);
- unsigned long (*recalc)(struct clk *clk);
- int (*set_rate)(struct clk *clk, unsigned long rate, int algo_id);
- int (*set_parent)(struct clk *clk, struct clk *parent);
- long (*round_rate)(struct clk *clk, unsigned long rate);
-};
-
-struct clk {
- struct list_head node;
- const char *name;
- int id;
- struct module *owner;
-
- struct clk *parent;
- struct clk_ops *ops;
-
- struct list_head children;
- struct list_head sibling; /* node for children */
-
- int usecount;
-
- unsigned long rate;
- unsigned long flags;
-
- void __iomem *enable_reg;
- unsigned int enable_bit;
-
- unsigned long arch_flags;
- void *priv;
- struct dentry *dentry;
- struct cpufreq_frequency_table *freq_table;
-};
-
-struct clk_lookup {
- struct list_head node;
- const char *dev_id;
- const char *con_id;
- struct clk *clk;
-};
-
-#define CLK_ENABLE_ON_INIT (1 << 0)
+#include <linux/sh_clk.h>
/* Should be defined by processor-specific code */
void __deprecated arch_init_clk_ops(struct clk_ops **, int type);
int __init arch_clk_init(void);
-/* arch/sh/kernel/cpu/clock.c */
-int clk_init(void);
-unsigned long followparent_recalc(struct clk *);
-void recalculate_root_clocks(void);
-void propagate_rate(struct clk *);
-int clk_reparent(struct clk *child, struct clk *parent);
-int clk_register(struct clk *);
-void clk_unregister(struct clk *);
-
/* arch/sh/kernel/cpu/clock-cpg.c */
int __init __deprecated cpg_clk_init(void);
-/* the exported API, in addition to clk_set_rate */
-/**
- * clk_set_rate_ex - set the clock rate for a clock source, with additional parameter
- * @clk: clock source
- * @rate: desired clock rate in Hz
- * @algo_id: algorithm id to be passed down to ops->set_rate
- *
- * Returns success (0) or negative errno.
- */
-int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id);
-
-enum clk_sh_algo_id {
- NO_CHANGE = 0,
-
- IUS_N1_N1,
- IUS_322,
- IUS_522,
- IUS_N11,
-
- SB_N1,
-
- SB3_N1,
- SB3_32,
- SB3_43,
- SB3_54,
-
- BP_N1,
-
- IP_N1,
-};
-
-struct clk_div_mult_table {
- unsigned int *divisors;
- unsigned int nr_divisors;
- unsigned int *multipliers;
- unsigned int nr_multipliers;
-};
-
-struct cpufreq_frequency_table;
-void clk_rate_table_build(struct clk *clk,
- struct cpufreq_frequency_table *freq_table,
- int nr_freqs,
- struct clk_div_mult_table *src_table,
- unsigned long *bitmap);
-
-long clk_rate_table_round(struct clk *clk,
- struct cpufreq_frequency_table *freq_table,
- unsigned long rate);
-
-int clk_rate_table_find(struct clk *clk,
- struct cpufreq_frequency_table *freq_table,
- unsigned long rate);
-
-#define SH_CLK_MSTP32(_name, _id, _parent, _enable_reg, \
- _enable_bit, _flags) \
-{ \
- .name = _name, \
- .id = _id, \
- .parent = _parent, \
- .enable_reg = (void __iomem *)_enable_reg, \
- .enable_bit = _enable_bit, \
- .flags = _flags, \
-}
-
-int sh_clk_mstp32_register(struct clk *clks, int nr);
-
-#define SH_CLK_DIV4(_name, _parent, _reg, _shift, _div_bitmap, _flags) \
-{ \
- .name = _name, \
- .parent = _parent, \
- .enable_reg = (void __iomem *)_reg, \
- .enable_bit = _shift, \
- .arch_flags = _div_bitmap, \
- .flags = _flags, \
-}
-
-int sh_clk_div4_register(struct clk *clks, int nr,
- struct clk_div_mult_table *table);
-
-#define SH_CLK_DIV6(_name, _parent, _reg, _flags) \
-{ \
- .name = _name, \
- .parent = _parent, \
- .enable_reg = (void __iomem *)_reg, \
- .flags = _flags, \
-}
-
-int sh_clk_div6_register(struct clk *clks, int nr);
+/* arch/sh/kernel/cpu/clock.c */
+int clk_init(void);
#endif /* __ASM_SH_CLOCK_H */
diff --git a/arch/sh/include/asm/cmpxchg-grb.h b/arch/sh/include/asm/cmpxchg-grb.h
index e2681abe764..4676bf57693 100644
--- a/arch/sh/include/asm/cmpxchg-grb.h
+++ b/arch/sh/include/asm/cmpxchg-grb.h
@@ -57,11 +57,10 @@ static inline unsigned long __cmpxchg_u32(volatile int *m, unsigned long old,
" mov.l @%1, %0 \n\t" /* load old value */
" cmp/eq %0, %2 \n\t"
" bf 1f \n\t" /* if not equal */
- " mov.l %2, @%1 \n\t" /* store new value */
+ " mov.l %3, @%1 \n\t" /* store new value */
"1: mov r1, r15 \n\t" /* LOGOUT */
- : "=&r" (retval),
- "+r" (m)
- : "r" (new)
+ : "=&r" (retval)
+ : "r" (m), "r" (old), "r" (new)
: "memory" , "r0", "r1", "t");
return retval;
diff --git a/arch/sh/include/asm/device.h b/arch/sh/include/asm/device.h
index 8688a88303e..b16debfe8c1 100644
--- a/arch/sh/include/asm/device.h
+++ b/arch/sh/include/asm/device.h
@@ -3,7 +3,9 @@
*
* This file is released under the GPLv2
*/
-#include <asm-generic/device.h>
+
+struct dev_archdata {
+};
struct platform_device;
/* allocate contiguous memory chunk and fill in struct resource */
@@ -12,3 +14,15 @@ int platform_resource_setup_memory(struct platform_device *pdev,
void plat_early_device_setup(void);
+#define PDEV_ARCHDATA_FLAG_INIT 0
+#define PDEV_ARCHDATA_FLAG_IDLE 1
+#define PDEV_ARCHDATA_FLAG_SUSP 2
+
+struct pdev_archdata {
+ int hwblk_id;
+#ifdef CONFIG_PM_RUNTIME
+ unsigned long flags;
+ struct list_head entry;
+ struct mutex mutex;
+#endif
+};
diff --git a/arch/sh/include/asm/dma-mapping.h b/arch/sh/include/asm/dma-mapping.h
index 69d56dd4c96..1a73c3e759a 100644
--- a/arch/sh/include/asm/dma-mapping.h
+++ b/arch/sh/include/asm/dma-mapping.h
@@ -1,219 +1,91 @@
#ifndef __ASM_SH_DMA_MAPPING_H
#define __ASM_SH_DMA_MAPPING_H
-#include <linux/mm.h>
-#include <linux/scatterlist.h>
-#include <linux/dma-debug.h>
-#include <asm/cacheflush.h>
-#include <asm/io.h>
+extern struct dma_map_ops *dma_ops;
+extern void no_iommu_init(void);
+
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
+{
+ return dma_ops;
+}
+
#include <asm-generic/dma-coherent.h>
+#include <asm-generic/dma-mapping-common.h>
-extern struct bus_type pci_bus_type;
+static inline int dma_supported(struct device *dev, u64 mask)
+{
+ struct dma_map_ops *ops = get_dma_ops(dev);
+
+ if (ops->dma_supported)
+ return ops->dma_supported(dev, mask);
-#define dma_supported(dev, mask) (1)
+ return 1;
+}
static inline int dma_set_mask(struct device *dev, u64 mask)
{
+ struct dma_map_ops *ops = get_dma_ops(dev);
+
if (!dev->dma_mask || !dma_supported(dev, mask))
return -EIO;
+ if (ops->set_dma_mask)
+ return ops->set_dma_mask(dev, mask);
*dev->dma_mask = mask;
return 0;
}
-void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t flag);
-
-void dma_free_coherent(struct device *dev, size_t size,
- void *vaddr, dma_addr_t dma_handle);
-
void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
enum dma_data_direction dir);
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
-#define dma_is_consistent(d, h) (1)
-static inline dma_addr_t dma_map_single(struct device *dev,
- void *ptr, size_t size,
- enum dma_data_direction dir)
+static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
{
- dma_addr_t addr = virt_to_phys(ptr);
-
-#if defined(CONFIG_PCI) && !defined(CONFIG_SH_PCIDMA_NONCOHERENT)
- if (dev->bus == &pci_bus_type)
- return addr;
-#endif
- dma_cache_sync(dev, ptr, size, dir);
+ struct dma_map_ops *ops = get_dma_ops(dev);
- debug_dma_map_page(dev, virt_to_page(ptr),
- (unsigned long)ptr & ~PAGE_MASK, size,
- dir, addr, true);
+ if (ops->mapping_error)
+ return ops->mapping_error(dev, dma_addr);
- return addr;
-}
-
-static inline void dma_unmap_single(struct device *dev, dma_addr_t addr,
- size_t size, enum dma_data_direction dir)
-{
- debug_dma_unmap_page(dev, addr, size, dir, true);
+ return dma_addr == 0;
}
-static inline int dma_map_sg(struct device *dev, struct scatterlist *sg,
- int nents, enum dma_data_direction dir)
+static inline void *dma_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t gfp)
{
- int i;
-
- for (i = 0; i < nents; i++) {
-#if !defined(CONFIG_PCI) || defined(CONFIG_SH_PCIDMA_NONCOHERENT)
- dma_cache_sync(dev, sg_virt(&sg[i]), sg[i].length, dir);
-#endif
- sg[i].dma_address = sg_phys(&sg[i]);
- sg[i].dma_length = sg[i].length;
- }
+ struct dma_map_ops *ops = get_dma_ops(dev);
+ void *memory;
- debug_dma_map_sg(dev, sg, nents, i, dir);
-
- return nents;
-}
+ if (dma_alloc_from_coherent(dev, size, dma_handle, &memory))
+ return memory;
+ if (!ops->alloc_coherent)
+ return NULL;
-static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
- int nents, enum dma_data_direction dir)
-{
- debug_dma_unmap_sg(dev, sg, nents, dir);
-}
+ memory = ops->alloc_coherent(dev, size, dma_handle, gfp);
+ debug_dma_alloc_coherent(dev, size, *dma_handle, memory);
-static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
- unsigned long offset, size_t size,
- enum dma_data_direction dir)
-{
- return dma_map_single(dev, page_address(page) + offset, size, dir);
+ return memory;
}
-static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
- size_t size, enum dma_data_direction dir)
+static inline void dma_free_coherent(struct device *dev, size_t size,
+ void *vaddr, dma_addr_t dma_handle)
{
- dma_unmap_single(dev, dma_address, size, dir);
-}
+ struct dma_map_ops *ops = get_dma_ops(dev);
-static inline void __dma_sync_single(struct device *dev, dma_addr_t dma_handle,
- size_t size, enum dma_data_direction dir)
-{
-#if defined(CONFIG_PCI) && !defined(CONFIG_SH_PCIDMA_NONCOHERENT)
- if (dev->bus == &pci_bus_type)
+ if (dma_release_from_coherent(dev, get_order(size), vaddr))
return;
-#endif
- dma_cache_sync(dev, phys_to_virt(dma_handle), size, dir);
-}
-
-static inline void dma_sync_single_range(struct device *dev,
- dma_addr_t dma_handle,
- unsigned long offset, size_t size,
- enum dma_data_direction dir)
-{
-#if defined(CONFIG_PCI) && !defined(CONFIG_SH_PCIDMA_NONCOHERENT)
- if (dev->bus == &pci_bus_type)
- return;
-#endif
- dma_cache_sync(dev, phys_to_virt(dma_handle) + offset, size, dir);
-}
-
-static inline void __dma_sync_sg(struct device *dev, struct scatterlist *sg,
- int nelems, enum dma_data_direction dir)
-{
- int i;
-
- for (i = 0; i < nelems; i++) {
-#if !defined(CONFIG_PCI) || defined(CONFIG_SH_PCIDMA_NONCOHERENT)
- dma_cache_sync(dev, sg_virt(&sg[i]), sg[i].length, dir);
-#endif
- sg[i].dma_address = sg_phys(&sg[i]);
- sg[i].dma_length = sg[i].length;
- }
-}
-
-static inline void dma_sync_single_for_cpu(struct device *dev,
- dma_addr_t dma_handle, size_t size,
- enum dma_data_direction dir)
-{
- __dma_sync_single(dev, dma_handle, size, dir);
- debug_dma_sync_single_for_cpu(dev, dma_handle, size, dir);
-}
-
-static inline void dma_sync_single_for_device(struct device *dev,
- dma_addr_t dma_handle,
- size_t size,
- enum dma_data_direction dir)
-{
- __dma_sync_single(dev, dma_handle, size, dir);
- debug_dma_sync_single_for_device(dev, dma_handle, size, dir);
-}
-
-static inline void dma_sync_single_range_for_cpu(struct device *dev,
- dma_addr_t dma_handle,
- unsigned long offset,
- size_t size,
- enum dma_data_direction direction)
-{
- dma_sync_single_for_cpu(dev, dma_handle+offset, size, direction);
- debug_dma_sync_single_range_for_cpu(dev, dma_handle,
- offset, size, direction);
-}
-
-static inline void dma_sync_single_range_for_device(struct device *dev,
- dma_addr_t dma_handle,
- unsigned long offset,
- size_t size,
- enum dma_data_direction direction)
-{
- dma_sync_single_for_device(dev, dma_handle+offset, size, direction);
- debug_dma_sync_single_range_for_device(dev, dma_handle,
- offset, size, direction);
-}
-
-static inline void dma_sync_sg_for_cpu(struct device *dev,
- struct scatterlist *sg, int nelems,
- enum dma_data_direction dir)
-{
- __dma_sync_sg(dev, sg, nelems, dir);
- debug_dma_sync_sg_for_cpu(dev, sg, nelems, dir);
-}
-
-static inline void dma_sync_sg_for_device(struct device *dev,
- struct scatterlist *sg, int nelems,
- enum dma_data_direction dir)
-{
- __dma_sync_sg(dev, sg, nelems, dir);
- debug_dma_sync_sg_for_device(dev, sg, nelems, dir);
+ debug_dma_free_coherent(dev, size, vaddr, dma_handle);
+ if (ops->free_coherent)
+ ops->free_coherent(dev, size, vaddr, dma_handle);
}
-static inline int dma_get_cache_alignment(void)
-{
- /*
- * Each processor family will define its own L1_CACHE_SHIFT,
- * L1_CACHE_BYTES wraps to this, so this is always safe.
- */
- return L1_CACHE_BYTES;
-}
-
-static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
-{
- return dma_addr == 0;
-}
-
-#define ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY
-
-extern int
-dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
- dma_addr_t device_addr, size_t size, int flags);
-
-extern void
-dma_release_declared_memory(struct device *dev);
-
-extern void *
-dma_mark_declared_memory_occupied(struct device *dev,
- dma_addr_t device_addr, size_t size);
+/* arch/sh/mm/consistent.c */
+extern void *dma_generic_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t *dma_addr, gfp_t flag);
+extern void dma_generic_free_coherent(struct device *dev, size_t size,
+ void *vaddr, dma_addr_t dma_handle);
#endif /* __ASM_SH_DMA_MAPPING_H */
diff --git a/arch/sh/include/asm/dma-register.h b/arch/sh/include/asm/dma-register.h
new file mode 100644
index 00000000000..51cd78feacf
--- /dev/null
+++ b/arch/sh/include/asm/dma-register.h
@@ -0,0 +1,51 @@
+/*
+ * Common header for the legacy SH DMA driver and the new dmaengine driver
+ *
+ * extracted from arch/sh/include/asm/dma-sh.h:
+ *
+ * Copyright (C) 2000 Takashi YOSHII
+ * Copyright (C) 2003 Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#ifndef DMA_REGISTER_H
+#define DMA_REGISTER_H
+
+/* DMA register */
+#define SAR 0x00
+#define DAR 0x04
+#define TCR 0x08
+#define CHCR 0x0C
+#define DMAOR 0x40
+
+/* DMAOR definitions */
+#define DMAOR_AE 0x00000004
+#define DMAOR_NMIF 0x00000002
+#define DMAOR_DME 0x00000001
+
+/* Definitions for the SuperH DMAC */
+#define REQ_L 0x00000000
+#define REQ_E 0x00080000
+#define RACK_H 0x00000000
+#define RACK_L 0x00040000
+#define ACK_R 0x00000000
+#define ACK_W 0x00020000
+#define ACK_H 0x00000000
+#define ACK_L 0x00010000
+#define DM_INC 0x00004000
+#define DM_DEC 0x00008000
+#define DM_FIX 0x0000c000
+#define SM_INC 0x00001000
+#define SM_DEC 0x00002000
+#define SM_FIX 0x00003000
+#define RS_IN 0x00000200
+#define RS_OUT 0x00000300
+#define TS_BLK 0x00000040
+#define TM_BUR 0x00000020
+#define CHCR_DE 0x00000001
+#define CHCR_TE 0x00000002
+#define CHCR_IE 0x00000004
+
+#endif
diff --git a/arch/sh/include/asm/dma-sh.h b/arch/sh/include/asm/dma-sh.h
index 0c8f8e14622..f3acb8e34c6 100644
--- a/arch/sh/include/asm/dma-sh.h
+++ b/arch/sh/include/asm/dma-sh.h
@@ -11,22 +11,24 @@
#ifndef __DMA_SH_H
#define __DMA_SH_H
-#include <asm/dma.h>
+#include <asm/dma-register.h>
+#include <cpu/dma-register.h>
#include <cpu/dma.h>
/* DMAOR contorl: The DMAOR access size is different by CPU.*/
#if defined(CONFIG_CPU_SUBTYPE_SH7723) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7724) || \
defined(CONFIG_CPU_SUBTYPE_SH7780) || \
defined(CONFIG_CPU_SUBTYPE_SH7785)
#define dmaor_read_reg(n) \
- (n ? ctrl_inw(SH_DMAC_BASE1 + DMAOR) \
- : ctrl_inw(SH_DMAC_BASE0 + DMAOR))
+ (n ? __raw_readw(SH_DMAC_BASE1 + DMAOR) \
+ : __raw_readw(SH_DMAC_BASE0 + DMAOR))
#define dmaor_write_reg(n, data) \
- (n ? ctrl_outw(data, SH_DMAC_BASE1 + DMAOR) \
- : ctrl_outw(data, SH_DMAC_BASE0 + DMAOR))
+ (n ? __raw_writew(data, SH_DMAC_BASE1 + DMAOR) \
+ : __raw_writew(data, SH_DMAC_BASE0 + DMAOR))
#else /* Other CPU */
-#define dmaor_read_reg(n) ctrl_inw(SH_DMAC_BASE0 + DMAOR)
-#define dmaor_write_reg(n, data) ctrl_outw(data, SH_DMAC_BASE0 + DMAOR)
+#define dmaor_read_reg(n) __raw_readw(SH_DMAC_BASE0 + DMAOR)
+#define dmaor_write_reg(n, data) __raw_writew(data, SH_DMAC_BASE0 + DMAOR)
#endif
static int dmte_irq_map[] __maybe_unused = {
@@ -52,37 +54,11 @@ static int dmte_irq_map[] __maybe_unused = {
#endif
};
-/* Definitions for the SuperH DMAC */
-#define REQ_L 0x00000000
-#define REQ_E 0x00080000
-#define RACK_H 0x00000000
-#define RACK_L 0x00040000
-#define ACK_R 0x00000000
-#define ACK_W 0x00020000
-#define ACK_H 0x00000000
-#define ACK_L 0x00010000
-#define DM_INC 0x00004000
-#define DM_DEC 0x00008000
-#define SM_INC 0x00001000
-#define SM_DEC 0x00002000
-#define RS_IN 0x00000200
-#define RS_OUT 0x00000300
-#define TS_BLK 0x00000040
-#define TM_BUR 0x00000020
-#define CHCR_DE 0x00000001
-#define CHCR_TE 0x00000002
-#define CHCR_IE 0x00000004
-
-/* DMAOR definitions */
-#define DMAOR_AE 0x00000004
-#define DMAOR_NMIF 0x00000002
-#define DMAOR_DME 0x00000001
-
/*
* Define the default configuration for dual address memory-memory transfer.
* The 0x400 value represents auto-request, external->external.
*/
-#define RS_DUAL (DM_INC | SM_INC | 0x400 | TS_32)
+#define RS_DUAL (DM_INC | SM_INC | 0x400 | TS_INDEX2VAL(XMIT_SZ_32BIT))
/* DMA base address */
static u32 dma_base_addr[] __maybe_unused = {
@@ -108,11 +84,4 @@ static u32 dma_base_addr[] __maybe_unused = {
#endif
};
-/* DMA register */
-#define SAR 0x00
-#define DAR 0x04
-#define TCR 0x08
-#define CHCR 0x0C
-#define DMAOR 0x40
-
#endif /* __DMA_SH_H */
diff --git a/arch/sh/include/asm/dma.h b/arch/sh/include/asm/dma.h
index 04ad0e1e637..07373a07409 100644
--- a/arch/sh/include/asm/dma.h
+++ b/arch/sh/include/asm/dma.h
@@ -19,9 +19,11 @@
#include <asm-generic/dma.h>
#ifdef CONFIG_NR_DMA_CHANNELS
-# define MAX_DMA_CHANNELS (CONFIG_NR_DMA_CHANNELS)
+# define MAX_DMA_CHANNELS (CONFIG_NR_DMA_CHANNELS)
+#elif defined(CONFIG_NR_ONCHIP_DMA_CHANNELS)
+# define MAX_DMA_CHANNELS (CONFIG_NR_ONCHIP_DMA_CHANNELS)
#else
-# define MAX_DMA_CHANNELS (CONFIG_NR_ONCHIP_DMA_CHANNELS)
+# define MAX_DMA_CHANNELS 0
#endif
/*
diff --git a/arch/sh/include/asm/dwarf.h b/arch/sh/include/asm/dwarf.h
new file mode 100644
index 00000000000..d62abd1d0c0
--- /dev/null
+++ b/arch/sh/include/asm/dwarf.h
@@ -0,0 +1,421 @@
+/*
+ * Copyright (C) 2009 Matt Fleming <matt@console-pimps.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+#ifndef __ASM_SH_DWARF_H
+#define __ASM_SH_DWARF_H
+
+#ifdef CONFIG_DWARF_UNWINDER
+
+/*
+ * DWARF expression operations
+ */
+#define DW_OP_addr 0x03
+#define DW_OP_deref 0x06
+#define DW_OP_const1u 0x08
+#define DW_OP_const1s 0x09
+#define DW_OP_const2u 0x0a
+#define DW_OP_const2s 0x0b
+#define DW_OP_const4u 0x0c
+#define DW_OP_const4s 0x0d
+#define DW_OP_const8u 0x0e
+#define DW_OP_const8s 0x0f
+#define DW_OP_constu 0x10
+#define DW_OP_consts 0x11
+#define DW_OP_dup 0x12
+#define DW_OP_drop 0x13
+#define DW_OP_over 0x14
+#define DW_OP_pick 0x15
+#define DW_OP_swap 0x16
+#define DW_OP_rot 0x17
+#define DW_OP_xderef 0x18
+#define DW_OP_abs 0x19
+#define DW_OP_and 0x1a
+#define DW_OP_div 0x1b
+#define DW_OP_minus 0x1c
+#define DW_OP_mod 0x1d
+#define DW_OP_mul 0x1e
+#define DW_OP_neg 0x1f
+#define DW_OP_not 0x20
+#define DW_OP_or 0x21
+#define DW_OP_plus 0x22
+#define DW_OP_plus_uconst 0x23
+#define DW_OP_shl 0x24
+#define DW_OP_shr 0x25
+#define DW_OP_shra 0x26
+#define DW_OP_xor 0x27
+#define DW_OP_skip 0x2f
+#define DW_OP_bra 0x28
+#define DW_OP_eq 0x29
+#define DW_OP_ge 0x2a
+#define DW_OP_gt 0x2b
+#define DW_OP_le 0x2c
+#define DW_OP_lt 0x2d
+#define DW_OP_ne 0x2e
+#define DW_OP_lit0 0x30
+#define DW_OP_lit1 0x31
+#define DW_OP_lit2 0x32
+#define DW_OP_lit3 0x33
+#define DW_OP_lit4 0x34
+#define DW_OP_lit5 0x35
+#define DW_OP_lit6 0x36
+#define DW_OP_lit7 0x37
+#define DW_OP_lit8 0x38
+#define DW_OP_lit9 0x39
+#define DW_OP_lit10 0x3a
+#define DW_OP_lit11 0x3b
+#define DW_OP_lit12 0x3c
+#define DW_OP_lit13 0x3d
+#define DW_OP_lit14 0x3e
+#define DW_OP_lit15 0x3f
+#define DW_OP_lit16 0x40
+#define DW_OP_lit17 0x41
+#define DW_OP_lit18 0x42
+#define DW_OP_lit19 0x43
+#define DW_OP_lit20 0x44
+#define DW_OP_lit21 0x45
+#define DW_OP_lit22 0x46
+#define DW_OP_lit23 0x47
+#define DW_OP_lit24 0x48
+#define DW_OP_lit25 0x49
+#define DW_OP_lit26 0x4a
+#define DW_OP_lit27 0x4b
+#define DW_OP_lit28 0x4c
+#define DW_OP_lit29 0x4d
+#define DW_OP_lit30 0x4e
+#define DW_OP_lit31 0x4f
+#define DW_OP_reg0 0x50
+#define DW_OP_reg1 0x51
+#define DW_OP_reg2 0x52
+#define DW_OP_reg3 0x53
+#define DW_OP_reg4 0x54
+#define DW_OP_reg5 0x55
+#define DW_OP_reg6 0x56
+#define DW_OP_reg7 0x57
+#define DW_OP_reg8 0x58
+#define DW_OP_reg9 0x59
+#define DW_OP_reg10 0x5a
+#define DW_OP_reg11 0x5b
+#define DW_OP_reg12 0x5c
+#define DW_OP_reg13 0x5d
+#define DW_OP_reg14 0x5e
+#define DW_OP_reg15 0x5f
+#define DW_OP_reg16 0x60
+#define DW_OP_reg17 0x61
+#define DW_OP_reg18 0x62
+#define DW_OP_reg19 0x63
+#define DW_OP_reg20 0x64
+#define DW_OP_reg21 0x65
+#define DW_OP_reg22 0x66
+#define DW_OP_reg23 0x67
+#define DW_OP_reg24 0x68
+#define DW_OP_reg25 0x69
+#define DW_OP_reg26 0x6a
+#define DW_OP_reg27 0x6b
+#define DW_OP_reg28 0x6c
+#define DW_OP_reg29 0x6d
+#define DW_OP_reg30 0x6e
+#define DW_OP_reg31 0x6f
+#define DW_OP_breg0 0x70
+#define DW_OP_breg1 0x71
+#define DW_OP_breg2 0x72
+#define DW_OP_breg3 0x73
+#define DW_OP_breg4 0x74
+#define DW_OP_breg5 0x75
+#define DW_OP_breg6 0x76
+#define DW_OP_breg7 0x77
+#define DW_OP_breg8 0x78
+#define DW_OP_breg9 0x79
+#define DW_OP_breg10 0x7a
+#define DW_OP_breg11 0x7b
+#define DW_OP_breg12 0x7c
+#define DW_OP_breg13 0x7d
+#define DW_OP_breg14 0x7e
+#define DW_OP_breg15 0x7f
+#define DW_OP_breg16 0x80
+#define DW_OP_breg17 0x81
+#define DW_OP_breg18 0x82
+#define DW_OP_breg19 0x83
+#define DW_OP_breg20 0x84
+#define DW_OP_breg21 0x85
+#define DW_OP_breg22 0x86
+#define DW_OP_breg23 0x87
+#define DW_OP_breg24 0x88
+#define DW_OP_breg25 0x89
+#define DW_OP_breg26 0x8a
+#define DW_OP_breg27 0x8b
+#define DW_OP_breg28 0x8c
+#define DW_OP_breg29 0x8d
+#define DW_OP_breg30 0x8e
+#define DW_OP_breg31 0x8f
+#define DW_OP_regx 0x90
+#define DW_OP_fbreg 0x91
+#define DW_OP_bregx 0x92
+#define DW_OP_piece 0x93
+#define DW_OP_deref_size 0x94
+#define DW_OP_xderef_size 0x95
+#define DW_OP_nop 0x96
+#define DW_OP_push_object_address 0x97
+#define DW_OP_call2 0x98
+#define DW_OP_call4 0x99
+#define DW_OP_call_ref 0x9a
+#define DW_OP_form_tls_address 0x9b
+#define DW_OP_call_frame_cfa 0x9c
+#define DW_OP_bit_piece 0x9d
+#define DW_OP_lo_user 0xe0
+#define DW_OP_hi_user 0xff
+
+/*
+ * Addresses used in FDE entries in the .eh_frame section may be encoded
+ * using one of the following encodings.
+ */
+#define DW_EH_PE_absptr 0x00
+#define DW_EH_PE_omit 0xff
+#define DW_EH_PE_uleb128 0x01
+#define DW_EH_PE_udata2 0x02
+#define DW_EH_PE_udata4 0x03
+#define DW_EH_PE_udata8 0x04
+#define DW_EH_PE_sleb128 0x09
+#define DW_EH_PE_sdata2 0x0a
+#define DW_EH_PE_sdata4 0x0b
+#define DW_EH_PE_sdata8 0x0c
+#define DW_EH_PE_signed 0x09
+
+#define DW_EH_PE_pcrel 0x10
+
+/*
+ * The architecture-specific register number that contains the return
+ * address in the .debug_frame table.
+ */
+#define DWARF_ARCH_RA_REG 17
+
+#ifndef __ASSEMBLY__
+
+#include <linux/compiler.h>
+#include <linux/bug.h>
+#include <linux/list.h>
+#include <linux/module.h>
+
+/*
+ * Read either the frame pointer (r14) or the stack pointer (r15).
+ * NOTE: this MUST be inlined.
+ */
+static __always_inline unsigned long dwarf_read_arch_reg(unsigned int reg)
+{
+ unsigned long value = 0;
+
+ switch (reg) {
+ case 14:
+ __asm__ __volatile__("mov r14, %0\n" : "=r" (value));
+ break;
+ case 15:
+ __asm__ __volatile__("mov r15, %0\n" : "=r" (value));
+ break;
+ default:
+ BUG();
+ }
+
+ return value;
+}
+
+/**
+ * dwarf_cie - Common Information Entry
+ */
+struct dwarf_cie {
+ unsigned long length;
+ unsigned long cie_id;
+ unsigned char version;
+ const char *augmentation;
+ unsigned int code_alignment_factor;
+ int data_alignment_factor;
+
+ /* Which column in the rule table represents return addr of func. */
+ unsigned int return_address_reg;
+
+ unsigned char *initial_instructions;
+ unsigned char *instructions_end;
+
+ unsigned char encoding;
+
+ unsigned long cie_pointer;
+
+ unsigned long flags;
+#define DWARF_CIE_Z_AUGMENTATION (1 << 0)
+
+ /* linked-list entry if this CIE is from a module */
+ struct list_head link;
+
+ struct rb_node node;
+};
+
+/**
+ * dwarf_fde - Frame Description Entry
+ */
+struct dwarf_fde {
+ unsigned long length;
+ unsigned long cie_pointer;
+ struct dwarf_cie *cie;
+ unsigned long initial_location;
+ unsigned long address_range;
+ unsigned char *instructions;
+ unsigned char *end;
+
+ /* linked-list entry if this FDE is from a module */
+ struct list_head link;
+
+ struct rb_node node;
+};
+
+/**
+ * dwarf_frame - DWARF information for a frame in the call stack
+ */
+struct dwarf_frame {
+ struct dwarf_frame *prev, *next;
+
+ unsigned long pc;
+
+ struct list_head reg_list;
+
+ unsigned long cfa;
+
+ /* Valid when DW_FRAME_CFA_REG_OFFSET is set in flags */
+ unsigned int cfa_register;
+ unsigned int cfa_offset;
+
+ /* Valid when DW_FRAME_CFA_REG_EXP is set in flags */
+ unsigned char *cfa_expr;
+ unsigned int cfa_expr_len;
+
+ unsigned long flags;
+#define DWARF_FRAME_CFA_REG_OFFSET (1 << 0)
+#define DWARF_FRAME_CFA_REG_EXP (1 << 1)
+
+ unsigned long return_addr;
+};
+
+/**
+ * dwarf_reg - DWARF register
+ * @flags: Describes how to calculate the value of this register
+ */
+struct dwarf_reg {
+ struct list_head link;
+
+ unsigned int number;
+
+ unsigned long addr;
+ unsigned long flags;
+#define DWARF_REG_OFFSET (1 << 0)
+#define DWARF_VAL_OFFSET (1 << 1)
+#define DWARF_UNDEFINED (1 << 2)
+};
+
+/*
+ * Call Frame instruction opcodes.
+ */
+#define DW_CFA_advance_loc 0x40
+#define DW_CFA_offset 0x80
+#define DW_CFA_restore 0xc0
+#define DW_CFA_nop 0x00
+#define DW_CFA_set_loc 0x01
+#define DW_CFA_advance_loc1 0x02
+#define DW_CFA_advance_loc2 0x03
+#define DW_CFA_advance_loc4 0x04
+#define DW_CFA_offset_extended 0x05
+#define DW_CFA_restore_extended 0x06
+#define DW_CFA_undefined 0x07
+#define DW_CFA_same_value 0x08
+#define DW_CFA_register 0x09
+#define DW_CFA_remember_state 0x0a
+#define DW_CFA_restore_state 0x0b
+#define DW_CFA_def_cfa 0x0c
+#define DW_CFA_def_cfa_register 0x0d
+#define DW_CFA_def_cfa_offset 0x0e
+#define DW_CFA_def_cfa_expression 0x0f
+#define DW_CFA_expression 0x10
+#define DW_CFA_offset_extended_sf 0x11
+#define DW_CFA_def_cfa_sf 0x12
+#define DW_CFA_def_cfa_offset_sf 0x13
+#define DW_CFA_val_offset 0x14
+#define DW_CFA_val_offset_sf 0x15
+#define DW_CFA_val_expression 0x16
+#define DW_CFA_lo_user 0x1c
+#define DW_CFA_hi_user 0x3f
+
+/* GNU extension opcodes */
+#define DW_CFA_GNU_args_size 0x2e
+#define DW_CFA_GNU_negative_offset_extended 0x2f
+
+/*
+ * Some call frame instructions encode their operands in the opcode. We
+ * need some helper functions to extract both the opcode and operands
+ * from an instruction.
+ */
+static inline unsigned int DW_CFA_opcode(unsigned long insn)
+{
+ return (insn & 0xc0);
+}
+
+static inline unsigned int DW_CFA_operand(unsigned long insn)
+{
+ return (insn & 0x3f);
+}
+
+#define DW_EH_FRAME_CIE 0 /* .eh_frame CIE IDs are 0 */
+#define DW_CIE_ID 0xffffffff
+#define DW64_CIE_ID 0xffffffffffffffffULL
+
+/*
+ * DWARF FDE/CIE length field values.
+ */
+#define DW_EXT_LO 0xfffffff0
+#define DW_EXT_HI 0xffffffff
+#define DW_EXT_DWARF64 DW_EXT_HI
+
+extern struct dwarf_frame *dwarf_unwind_stack(unsigned long,
+ struct dwarf_frame *);
+extern void dwarf_free_frame(struct dwarf_frame *);
+
+extern int module_dwarf_finalize(const Elf_Ehdr *, const Elf_Shdr *,
+ struct module *);
+extern void module_dwarf_cleanup(struct module *);
+
+#endif /* !__ASSEMBLY__ */
+
+#define CFI_STARTPROC .cfi_startproc
+#define CFI_ENDPROC .cfi_endproc
+#define CFI_DEF_CFA .cfi_def_cfa
+#define CFI_REGISTER .cfi_register
+#define CFI_REL_OFFSET .cfi_rel_offset
+#define CFI_UNDEFINED .cfi_undefined
+
+#else
+
+/*
+ * Use the asm comment character to ignore the rest of the line.
+ */
+#define CFI_IGNORE !
+
+#define CFI_STARTPROC CFI_IGNORE
+#define CFI_ENDPROC CFI_IGNORE
+#define CFI_DEF_CFA CFI_IGNORE
+#define CFI_REGISTER CFI_IGNORE
+#define CFI_REL_OFFSET CFI_IGNORE
+#define CFI_UNDEFINED CFI_IGNORE
+
+#ifndef __ASSEMBLY__
+static inline void dwarf_unwinder_init(void)
+{
+}
+
+#define module_dwarf_finalize(hdr, sechdrs, me) (0)
+#define module_dwarf_cleanup(mod) do { } while (0)
+
+#endif
+
+#endif /* CONFIG_DWARF_UNWINDER */
+
+#endif /* __ASM_SH_DWARF_H */
diff --git a/arch/sh/include/asm/elf.h b/arch/sh/include/asm/elf.h
index ccb1d93bb04..f38112be67d 100644
--- a/arch/sh/include/asm/elf.h
+++ b/arch/sh/include/asm/elf.h
@@ -50,25 +50,14 @@
#define R_SH_GOTPC 167
/* FDPIC relocs */
-#define R_SH_GOT20 70
-#define R_SH_GOTOFF20 71
-#define R_SH_GOTFUNCDESC 72
-#define R_SH_GOTFUNCDESC20 73
-#define R_SH_GOTOFFFUNCDESC 74
-#define R_SH_GOTOFFFUNCDESC20 75
-#define R_SH_FUNCDESC 76
-#define R_SH_FUNCDESC_VALUE 77
-
-#if 0 /* XXX - later .. */
-#define R_SH_GOT20 198
-#define R_SH_GOTOFF20 199
-#define R_SH_GOTFUNCDESC 200
-#define R_SH_GOTFUNCDESC20 201
-#define R_SH_GOTOFFFUNCDESC 202
-#define R_SH_GOTOFFFUNCDESC20 203
-#define R_SH_FUNCDESC 204
-#define R_SH_FUNCDESC_VALUE 205
-#endif
+#define R_SH_GOT20 201
+#define R_SH_GOTOFF20 202
+#define R_SH_GOTFUNCDESC 203
+#define R_SH_GOTFUNCDESC20 204
+#define R_SH_GOTOFFFUNCDESC 205
+#define R_SH_GOTOFFFUNCDESC20 206
+#define R_SH_FUNCDESC 207
+#define R_SH_FUNCDESC_VALUE 208
/* SHmedia relocs */
#define R_SH_IMM_LOW16 246
@@ -114,7 +103,6 @@ typedef struct user_fpu_struct elf_fpregset_t;
*/
#define CORE_DUMP_USE_REGSET
-#define USE_ELF_CORE_DUMP
#define ELF_FDPIC_CORE_EFLAGS EF_SH_FDPIC
#define ELF_EXEC_PAGESIZE PAGE_SIZE
@@ -212,7 +200,9 @@ extern void __kernel_vsyscall;
#define VSYSCALL_AUX_ENT \
if (vdso_enabled) \
- NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_BASE);
+ NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_BASE); \
+ else \
+ NEW_AUX_ENT(AT_IGNORE, 0);
#else
#define VSYSCALL_AUX_ENT
#endif /* CONFIG_VSYSCALL */
@@ -220,7 +210,7 @@ extern void __kernel_vsyscall;
#ifdef CONFIG_SH_FPU
#define FPU_AUX_ENT NEW_AUX_ENT(AT_FPUCW, FPSCR_INIT)
#else
-#define FPU_AUX_ENT
+#define FPU_AUX_ENT NEW_AUX_ENT(AT_IGNORE, 0)
#endif
extern int l1i_cache_shape, l1d_cache_shape, l2_cache_shape;
diff --git a/arch/sh/include/asm/entry-macros.S b/arch/sh/include/asm/entry-macros.S
index 3a4752a6572..cc43a55e1fc 100644
--- a/arch/sh/include/asm/entry-macros.S
+++ b/arch/sh/include/asm/entry-macros.S
@@ -7,7 +7,7 @@
.endm
.macro sti
- mov #0xf0, r11
+ mov #0xfffffff0, r11
extu.b r11, r11
not r11, r11
stc sr, r10
@@ -31,8 +31,92 @@
#endif
.endm
+#ifdef CONFIG_TRACE_IRQFLAGS
+
+ .macro TRACE_IRQS_ON
+ mov.l r0, @-r15
+ mov.l r1, @-r15
+ mov.l r2, @-r15
+ mov.l r3, @-r15
+ mov.l r4, @-r15
+ mov.l r5, @-r15
+ mov.l r6, @-r15
+ mov.l r7, @-r15
+
+ mov.l 7834f, r0
+ jsr @r0
+ nop
+
+ mov.l @r15+, r7
+ mov.l @r15+, r6
+ mov.l @r15+, r5
+ mov.l @r15+, r4
+ mov.l @r15+, r3
+ mov.l @r15+, r2
+ mov.l @r15+, r1
+ mov.l @r15+, r0
+ mov.l 7834f, r0
+
+ bra 7835f
+ nop
+ .balign 4
+7834: .long trace_hardirqs_on
+7835:
+ .endm
+ .macro TRACE_IRQS_OFF
+
+ mov.l r0, @-r15
+ mov.l r1, @-r15
+ mov.l r2, @-r15
+ mov.l r3, @-r15
+ mov.l r4, @-r15
+ mov.l r5, @-r15
+ mov.l r6, @-r15
+ mov.l r7, @-r15
+
+ mov.l 7834f, r0
+ jsr @r0
+ nop
+
+ mov.l @r15+, r7
+ mov.l @r15+, r6
+ mov.l @r15+, r5
+ mov.l @r15+, r4
+ mov.l @r15+, r3
+ mov.l @r15+, r2
+ mov.l @r15+, r1
+ mov.l @r15+, r0
+ mov.l 7834f, r0
+
+ bra 7835f
+ nop
+ .balign 4
+7834: .long trace_hardirqs_off
+7835:
+ .endm
+
+#else
+ .macro TRACE_IRQS_ON
+ .endm
+
+ .macro TRACE_IRQS_OFF
+ .endm
+#endif
+
#if defined(CONFIG_CPU_SH2A) || defined(CONFIG_CPU_SH4)
# define PREF(x) pref @x
#else
# define PREF(x) nop
#endif
+
+ /*
+ * Macro for use within assembly. Because the DWARF unwinder
+ * needs to use the frame register to unwind the stack, we
+ * need to setup r14 with the value of the stack pointer as
+ * the return address is usually on the stack somewhere.
+ */
+ .macro setup_frame_reg
+#ifdef CONFIG_DWARF_UNWINDER
+ mov r15, r14
+#endif
+ .endm
diff --git a/arch/sh/include/asm/fixmap.h b/arch/sh/include/asm/fixmap.h
index 721fcc4d5e9..bd7e79a1265 100644
--- a/arch/sh/include/asm/fixmap.h
+++ b/arch/sh/include/asm/fixmap.h
@@ -14,9 +14,9 @@
#define _ASM_FIXMAP_H
#include <linux/kernel.h>
+#include <linux/threads.h>
#include <asm/page.h>
#ifdef CONFIG_HIGHMEM
-#include <linux/threads.h>
#include <asm/kmap_types.h>
#endif
@@ -46,19 +46,38 @@
* fix-mapped?
*/
enum fixed_addresses {
-#define FIX_N_COLOURS 16
+ /*
+ * The FIX_CMAP entries are used by kmap_coherent() to get virtual
+ * addresses which are of a known color, and so their values are
+ * important. __fix_to_virt(FIX_CMAP_END - n) must give an address
+ * which is the same color as a page (n<<PAGE_SHIFT).
+ */
+#define FIX_N_COLOURS 8
FIX_CMAP_BEGIN,
- FIX_CMAP_END = FIX_CMAP_BEGIN + FIX_N_COLOURS,
- FIX_UNCACHED,
+ FIX_CMAP_END = FIX_CMAP_BEGIN + (FIX_N_COLOURS * NR_CPUS) - 1,
+
#ifdef CONFIG_HIGHMEM
FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
- FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
+ FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * NR_CPUS) - 1,
#endif
+
+#ifdef CONFIG_IOREMAP_FIXED
+ /*
+ * FIX_IOREMAP entries are useful for mapping physical address
+ * space before ioremap() is useable, e.g. really early in boot
+ * before kmalloc() is working.
+ */
+#define FIX_N_IOREMAPS 32
+ FIX_IOREMAP_BEGIN,
+ FIX_IOREMAP_END = FIX_IOREMAP_BEGIN + FIX_N_IOREMAPS - 1,
+#endif
+
__end_of_fixed_addresses
};
extern void __set_fixmap(enum fixed_addresses idx,
unsigned long phys, pgprot_t flags);
+extern void __clear_fixmap(enum fixed_addresses idx, pgprot_t flags);
#define set_fixmap(idx, phys) \
__set_fixmap(idx, phys, PAGE_KERNEL)
diff --git a/arch/sh/include/asm/fpu.h b/arch/sh/include/asm/fpu.h
index 1d3aee04b5c..06c4281aab6 100644
--- a/arch/sh/include/asm/fpu.h
+++ b/arch/sh/include/asm/fpu.h
@@ -2,8 +2,8 @@
#define __ASM_SH_FPU_H
#ifndef __ASSEMBLY__
-#include <linux/preempt.h>
-#include <asm/ptrace.h>
+
+struct task_struct;
#ifdef CONFIG_SH_FPU
static inline void release_fpu(struct pt_regs *regs)
@@ -16,59 +16,56 @@ static inline void grab_fpu(struct pt_regs *regs)
regs->sr &= ~SR_FD;
}
-struct task_struct;
-
-extern void save_fpu(struct task_struct *__tsk, struct pt_regs *regs);
+extern void save_fpu(struct task_struct *__tsk);
+extern void restore_fpu(struct task_struct *__tsk);
+extern void fpu_state_restore(struct pt_regs *regs);
+extern void __fpu_state_restore(void);
#else
-
-#define release_fpu(regs) do { } while (0)
-#define grab_fpu(regs) do { } while (0)
-
-static inline void save_fpu(struct task_struct *tsk, struct pt_regs *regs)
-{
- clear_tsk_thread_flag(tsk, TIF_USEDFPU);
-}
+#define save_fpu(tsk) do { } while (0)
+#define restore_fpu(tsk) do { } while (0)
+#define release_fpu(regs) do { } while (0)
+#define grab_fpu(regs) do { } while (0)
+#define fpu_state_restore(regs) do { } while (0)
+#define __fpu_state_restore(regs) do { } while (0)
#endif
struct user_regset;
extern int do_fpu_inst(unsigned short, struct pt_regs *);
+extern int init_fpu(struct task_struct *);
extern int fpregs_get(struct task_struct *target,
const struct user_regset *regset,
unsigned int pos, unsigned int count,
void *kbuf, void __user *ubuf);
+static inline void __unlazy_fpu(struct task_struct *tsk, struct pt_regs *regs)
+{
+ if (task_thread_info(tsk)->status & TS_USEDFPU) {
+ task_thread_info(tsk)->status &= ~TS_USEDFPU;
+ save_fpu(tsk);
+ release_fpu(regs);
+ } else
+ tsk->fpu_counter = 0;
+}
+
static inline void unlazy_fpu(struct task_struct *tsk, struct pt_regs *regs)
{
preempt_disable();
- if (test_tsk_thread_flag(tsk, TIF_USEDFPU))
- save_fpu(tsk, regs);
+ __unlazy_fpu(tsk, regs);
preempt_enable();
}
static inline void clear_fpu(struct task_struct *tsk, struct pt_regs *regs)
{
preempt_disable();
- if (test_tsk_thread_flag(tsk, TIF_USEDFPU)) {
- clear_tsk_thread_flag(tsk, TIF_USEDFPU);
+ if (task_thread_info(tsk)->status & TS_USEDFPU) {
+ task_thread_info(tsk)->status &= ~TS_USEDFPU;
release_fpu(regs);
}
preempt_enable();
}
-static inline int init_fpu(struct task_struct *tsk)
-{
- if (tsk_used_math(tsk)) {
- if ((boot_cpu_data.flags & CPU_HAS_FPU) && tsk == current)
- unlazy_fpu(tsk, task_pt_regs(tsk));
- return 0;
- }
-
- set_stopped_child_used_math(tsk);
- return 0;
-}
-
#endif /* __ASSEMBLY__ */
#endif /* __ASM_SH_FPU_H */
diff --git a/arch/sh/include/asm/ftrace.h b/arch/sh/include/asm/ftrace.h
index 8fea7d8c825..13e9966464c 100644
--- a/arch/sh/include/asm/ftrace.h
+++ b/arch/sh/include/asm/ftrace.h
@@ -4,6 +4,7 @@
#ifdef CONFIG_FUNCTION_TRACER
#define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */
+#define FTRACE_SYSCALL_MAX NR_syscalls
#ifndef __ASSEMBLY__
extern void mcount(void);
@@ -11,10 +12,13 @@ extern void mcount(void);
#define MCOUNT_ADDR ((long)(mcount))
#ifdef CONFIG_DYNAMIC_FTRACE
-#define CALLER_ADDR ((long)(ftrace_caller))
+#define CALL_ADDR ((long)(ftrace_call))
#define STUB_ADDR ((long)(ftrace_stub))
+#define GRAPH_ADDR ((long)(ftrace_graph_call))
+#define CALLER_ADDR ((long)(ftrace_caller))
-#define MCOUNT_INSN_OFFSET ((STUB_ADDR - CALLER_ADDR) >> 1)
+#define MCOUNT_INSN_OFFSET ((STUB_ADDR - CALL_ADDR) - 4)
+#define GRAPH_INSN_OFFSET ((CALLER_ADDR - GRAPH_ADDR) - 4)
struct dyn_arch_ftrace {
/* No extra data needed on sh */
@@ -31,4 +35,21 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr)
#endif /* __ASSEMBLY__ */
#endif /* CONFIG_FUNCTION_TRACER */
+#ifndef __ASSEMBLY__
+
+/* arch/sh/kernel/return_address.c */
+extern void *return_address(unsigned int);
+
+#define HAVE_ARCH_CALLER_ADDR
+
+#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
+#define CALLER_ADDR1 ((unsigned long)return_address(1))
+#define CALLER_ADDR2 ((unsigned long)return_address(2))
+#define CALLER_ADDR3 ((unsigned long)return_address(3))
+#define CALLER_ADDR4 ((unsigned long)return_address(4))
+#define CALLER_ADDR5 ((unsigned long)return_address(5))
+#define CALLER_ADDR6 ((unsigned long)return_address(6))
+
+#endif /* __ASSEMBLY__ */
+
#endif /* __ASM_SH_FTRACE_H */
diff --git a/arch/sh/include/asm/gpio.h b/arch/sh/include/asm/gpio.h
index 61f93da2c62..04f53d31489 100644
--- a/arch/sh/include/asm/gpio.h
+++ b/arch/sh/include/asm/gpio.h
@@ -20,7 +20,7 @@
#endif
#define ARCH_NR_GPIOS 512
-#include <asm-generic/gpio.h>
+#include <linux/sh_pfc.h>
#ifdef CONFIG_GPIOLIB
@@ -41,96 +41,14 @@ static inline int gpio_cansleep(unsigned gpio)
static inline int gpio_to_irq(unsigned gpio)
{
- WARN_ON(1);
- return -ENOSYS;
+ return __gpio_to_irq(gpio);
}
static inline int irq_to_gpio(unsigned int irq)
{
- WARN_ON(1);
- return -EINVAL;
+ return -ENOSYS;
}
#endif /* CONFIG_GPIOLIB */
-typedef unsigned short pinmux_enum_t;
-typedef unsigned short pinmux_flag_t;
-
-#define PINMUX_TYPE_NONE 0
-#define PINMUX_TYPE_FUNCTION 1
-#define PINMUX_TYPE_GPIO 2
-#define PINMUX_TYPE_OUTPUT 3
-#define PINMUX_TYPE_INPUT 4
-#define PINMUX_TYPE_INPUT_PULLUP 5
-#define PINMUX_TYPE_INPUT_PULLDOWN 6
-
-#define PINMUX_FLAG_TYPE (0x7)
-#define PINMUX_FLAG_WANT_PULLUP (1 << 3)
-#define PINMUX_FLAG_WANT_PULLDOWN (1 << 4)
-
-#define PINMUX_FLAG_DBIT_SHIFT 5
-#define PINMUX_FLAG_DBIT (0x1f << PINMUX_FLAG_DBIT_SHIFT)
-#define PINMUX_FLAG_DREG_SHIFT 10
-#define PINMUX_FLAG_DREG (0x3f << PINMUX_FLAG_DREG_SHIFT)
-
-struct pinmux_gpio {
- pinmux_enum_t enum_id;
- pinmux_flag_t flags;
-};
-
-#define PINMUX_GPIO(gpio, data_or_mark) [gpio] = { data_or_mark }
-#define PINMUX_DATA(data_or_mark, ids...) data_or_mark, ids, 0
-
-struct pinmux_cfg_reg {
- unsigned long reg, reg_width, field_width;
- unsigned long *cnt;
- pinmux_enum_t *enum_ids;
-};
-
-#define PINMUX_CFG_REG(name, r, r_width, f_width) \
- .reg = r, .reg_width = r_width, .field_width = f_width, \
- .cnt = (unsigned long [r_width / f_width]) {}, \
- .enum_ids = (pinmux_enum_t [(r_width / f_width) * (1 << f_width)]) \
-
-struct pinmux_data_reg {
- unsigned long reg, reg_width, reg_shadow;
- pinmux_enum_t *enum_ids;
-};
-
-#define PINMUX_DATA_REG(name, r, r_width) \
- .reg = r, .reg_width = r_width, \
- .enum_ids = (pinmux_enum_t [r_width]) \
-
-struct pinmux_range {
- pinmux_enum_t begin;
- pinmux_enum_t end;
- pinmux_enum_t force;
-};
-
-struct pinmux_info {
- char *name;
- pinmux_enum_t reserved_id;
- struct pinmux_range data;
- struct pinmux_range input;
- struct pinmux_range input_pd;
- struct pinmux_range input_pu;
- struct pinmux_range output;
- struct pinmux_range mark;
- struct pinmux_range function;
-
- unsigned first_gpio, last_gpio;
-
- struct pinmux_gpio *gpios;
- struct pinmux_cfg_reg *cfg_regs;
- struct pinmux_data_reg *data_regs;
-
- pinmux_enum_t *gpio_data;
- unsigned int gpio_data_size;
-
- unsigned long *gpio_in_use;
- struct gpio_chip chip;
-};
-
-int register_pinmux(struct pinmux_info *pip);
-
#endif /* __ASM_SH_GPIO_H */
diff --git a/arch/sh/include/asm/hardirq.h b/arch/sh/include/asm/hardirq.h
index 715ee237fc7..48b191313a9 100644
--- a/arch/sh/include/asm/hardirq.h
+++ b/arch/sh/include/asm/hardirq.h
@@ -4,9 +4,9 @@
#include <linux/threads.h>
#include <linux/irq.h>
-/* entry.S is sensitive to the offsets of these fields */
typedef struct {
unsigned int __softirq_pending;
+ unsigned int __nmi_count; /* arch dependent */
} ____cacheline_aligned irq_cpustat_t;
#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
diff --git a/arch/sh/include/asm/heartbeat.h b/arch/sh/include/asm/heartbeat.h
index 724a43ed245..caaafe5a3ef 100644
--- a/arch/sh/include/asm/heartbeat.h
+++ b/arch/sh/include/asm/heartbeat.h
@@ -11,6 +11,7 @@ struct heartbeat_data {
unsigned int nr_bits;
struct timer_list timer;
unsigned int regsize;
+ unsigned int mask;
unsigned long flags;
};
diff --git a/arch/sh/include/asm/hw_breakpoint.h b/arch/sh/include/asm/hw_breakpoint.h
new file mode 100644
index 00000000000..89890f61a7b
--- /dev/null
+++ b/arch/sh/include/asm/hw_breakpoint.h
@@ -0,0 +1,70 @@
+#ifndef __ASM_SH_HW_BREAKPOINT_H
+#define __ASM_SH_HW_BREAKPOINT_H
+
+#ifdef __KERNEL__
+#define __ARCH_HW_BREAKPOINT_H
+
+#include <linux/kdebug.h>
+#include <linux/types.h>
+
+struct arch_hw_breakpoint {
+ char *name; /* Contains name of the symbol to set bkpt */
+ unsigned long address;
+ u16 len;
+ u16 type;
+};
+
+enum {
+ SH_BREAKPOINT_READ = (1 << 1),
+ SH_BREAKPOINT_WRITE = (1 << 2),
+ SH_BREAKPOINT_RW = SH_BREAKPOINT_READ | SH_BREAKPOINT_WRITE,
+
+ SH_BREAKPOINT_LEN_1 = (1 << 12),
+ SH_BREAKPOINT_LEN_2 = (1 << 13),
+ SH_BREAKPOINT_LEN_4 = SH_BREAKPOINT_LEN_1 | SH_BREAKPOINT_LEN_2,
+ SH_BREAKPOINT_LEN_8 = (1 << 14),
+};
+
+struct sh_ubc {
+ const char *name;
+ unsigned int num_events;
+ unsigned int trap_nr;
+ void (*enable)(struct arch_hw_breakpoint *, int);
+ void (*disable)(struct arch_hw_breakpoint *, int);
+ void (*enable_all)(unsigned long);
+ void (*disable_all)(void);
+ unsigned long (*active_mask)(void);
+ unsigned long (*triggered_mask)(void);
+ void (*clear_triggered_mask)(unsigned long);
+ struct clk *clk; /* optional interface clock / MSTP bit */
+};
+
+struct perf_event;
+struct task_struct;
+struct pmu;
+
+/* Maximum number of UBC channels */
+#define HBP_NUM 2
+
+static inline int hw_breakpoint_slots(int type)
+{
+ return HBP_NUM;
+}
+
+/* arch/sh/kernel/hw_breakpoint.c */
+extern int arch_check_bp_in_kernelspace(struct perf_event *bp);
+extern int arch_validate_hwbkpt_settings(struct perf_event *bp);
+extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
+ unsigned long val, void *data);
+
+int arch_install_hw_breakpoint(struct perf_event *bp);
+void arch_uninstall_hw_breakpoint(struct perf_event *bp);
+void hw_breakpoint_pmu_read(struct perf_event *bp);
+
+extern void arch_fill_perf_breakpoint(struct perf_event *bp);
+extern int register_sh_ubc(struct sh_ubc *);
+
+extern struct pmu perf_ops_bp;
+
+#endif /* __KERNEL__ */
+#endif /* __ASM_SH_HW_BREAKPOINT_H */
diff --git a/arch/sh/include/asm/hwblk.h b/arch/sh/include/asm/hwblk.h
new file mode 100644
index 00000000000..855e945c619
--- /dev/null
+++ b/arch/sh/include/asm/hwblk.h
@@ -0,0 +1,70 @@
+#ifndef __ASM_SH_HWBLK_H
+#define __ASM_SH_HWBLK_H
+
+#include <asm/clock.h>
+#include <asm/io.h>
+
+#define HWBLK_CNT_USAGE 0
+#define HWBLK_CNT_IDLE 1
+#define HWBLK_CNT_DEVICES 2
+#define HWBLK_CNT_NR 3
+
+#define HWBLK_AREA_FLAG_PARENT (1 << 0) /* valid parent */
+
+#define HWBLK_AREA(_flags, _parent) \
+{ \
+ .flags = _flags, \
+ .parent = _parent, \
+}
+
+struct hwblk_area {
+ int cnt[HWBLK_CNT_NR];
+ unsigned char parent;
+ unsigned char flags;
+};
+
+#define HWBLK(_mstp, _bit, _area) \
+{ \
+ .mstp = (void __iomem *)_mstp, \
+ .bit = _bit, \
+ .area = _area, \
+}
+
+struct hwblk {
+ void __iomem *mstp;
+ unsigned char bit;
+ unsigned char area;
+ int cnt[HWBLK_CNT_NR];
+};
+
+struct hwblk_info {
+ struct hwblk_area *areas;
+ int nr_areas;
+ struct hwblk *hwblks;
+ int nr_hwblks;
+};
+
+/* Should be defined by processor-specific code */
+int arch_hwblk_init(void);
+int arch_hwblk_sleep_mode(void);
+
+int hwblk_register(struct hwblk_info *info);
+int hwblk_init(void);
+
+void hwblk_enable(struct hwblk_info *info, int hwblk);
+void hwblk_disable(struct hwblk_info *info, int hwblk);
+
+void hwblk_cnt_inc(struct hwblk_info *info, int hwblk, int cnt);
+void hwblk_cnt_dec(struct hwblk_info *info, int hwblk, int cnt);
+
+/* allow clocks to enable and disable hardware blocks */
+#define SH_HWBLK_CLK(_hwblk, _parent, _flags) \
+[_hwblk] = { \
+ .parent = _parent, \
+ .arch_flags = _hwblk, \
+ .flags = _flags, \
+}
+
+int sh_hwblk_clk_register(struct clk *clks, int nr);
+
+#endif /* __ASM_SH_HWBLK_H */
diff --git a/arch/sh/include/asm/ilsel.h b/arch/sh/include/asm/ilsel.h
deleted file mode 100644
index e3d304b280f..00000000000
--- a/arch/sh/include/asm/ilsel.h
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifndef __ASM_SH_ILSEL_H
-#define __ASM_SH_ILSEL_H
-
-typedef enum {
- ILSEL_NONE,
- ILSEL_LAN,
- ILSEL_USBH_I,
- ILSEL_USBH_S,
- ILSEL_USBH_V,
- ILSEL_RTC,
- ILSEL_USBP_I,
- ILSEL_USBP_S,
- ILSEL_USBP_V,
- ILSEL_KEY,
-
- /*
- * ILSEL Aliases - corner cases for interleaved level tables.
- *
- * Someone thought this was a good idea and less hassle than
- * demuxing a shared vector, really.
- */
-
- /* ILSEL0 and 2 */
- ILSEL_FPGA0,
- ILSEL_FPGA1,
- ILSEL_EX1,
- ILSEL_EX2,
- ILSEL_EX3,
- ILSEL_EX4,
-
- /* ILSEL1 and 3 */
- ILSEL_FPGA2 = ILSEL_FPGA0,
- ILSEL_FPGA3 = ILSEL_FPGA1,
- ILSEL_EX5 = ILSEL_EX1,
- ILSEL_EX6 = ILSEL_EX2,
- ILSEL_EX7 = ILSEL_EX3,
- ILSEL_EX8 = ILSEL_EX4,
-} ilsel_source_t;
-
-/* arch/sh/boards/renesas/x3proto/ilsel.c */
-int ilsel_enable(ilsel_source_t set);
-int ilsel_enable_fixed(ilsel_source_t set, unsigned int level);
-void ilsel_disable(unsigned int irq);
-
-#endif /* __ASM_SH_ILSEL_H */
diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h
index 25348141674..89ab2c57a4c 100644
--- a/arch/sh/include/asm/io.h
+++ b/arch/sh/include/asm/io.h
@@ -1,5 +1,6 @@
#ifndef __ASM_SH_IO_H
#define __ASM_SH_IO_H
+
/*
* Convention:
* read{b,w,l,q}/write{b,w,l,q} are for PCI,
@@ -15,13 +16,8 @@
* SuperH specific I/O (raw I/O to on-chip CPU peripherals). In practice
* these have the same semantics as the __raw variants, and as such, all
* new code should be using the __raw versions.
- *
- * All ISA I/O routines are wrapped through the machine vector. If a
- * board does not provide overrides, a generic set that are copied in
- * from the default machine vector are used instead. These are largely
- * for old compat code for I/O offseting to SuperIOs, all of which are
- * better handled through the machvec ioport mapping routines these days.
*/
+#include <linux/errno.h>
#include <asm/cache.h>
#include <asm/system.h>
#include <asm/addrspace.h>
@@ -30,35 +26,10 @@
#include <asm-generic/iomap.h>
#ifdef __KERNEL__
-/*
- * Depending on which platform we are running on, we need different
- * I/O functions.
- */
-#define __IO_PREFIX generic
+#define __IO_PREFIX generic
#include <asm/io_generic.h>
#include <asm/io_trapped.h>
-#define inb(p) sh_mv.mv_inb((p))
-#define inw(p) sh_mv.mv_inw((p))
-#define inl(p) sh_mv.mv_inl((p))
-#define outb(x,p) sh_mv.mv_outb((x),(p))
-#define outw(x,p) sh_mv.mv_outw((x),(p))
-#define outl(x,p) sh_mv.mv_outl((x),(p))
-
-#define inb_p(p) sh_mv.mv_inb_p((p))
-#define inw_p(p) sh_mv.mv_inw_p((p))
-#define inl_p(p) sh_mv.mv_inl_p((p))
-#define outb_p(x,p) sh_mv.mv_outb_p((x),(p))
-#define outw_p(x,p) sh_mv.mv_outw_p((x),(p))
-#define outl_p(x,p) sh_mv.mv_outl_p((x),(p))
-
-#define insb(p,b,c) sh_mv.mv_insb((p), (b), (c))
-#define insw(p,b,c) sh_mv.mv_insw((p), (b), (c))
-#define insl(p,b,c) sh_mv.mv_insl((p), (b), (c))
-#define outsb(p,b,c) sh_mv.mv_outsb((p), (b), (c))
-#define outsw(p,b,c) sh_mv.mv_outsw((p), (b), (c))
-#define outsl(p,b,c) sh_mv.mv_outsl((p), (b), (c))
-
#define __raw_writeb(v,a) (__chk_io_ptr(a), *(volatile u8 __force *)(a) = (v))
#define __raw_writew(v,a) (__chk_io_ptr(a), *(volatile u16 __force *)(a) = (v))
#define __raw_writel(v,a) (__chk_io_ptr(a), *(volatile u32 __force *)(a) = (v))
@@ -69,38 +40,67 @@
#define __raw_readl(a) (__chk_io_ptr(a), *(volatile u32 __force *)(a))
#define __raw_readq(a) (__chk_io_ptr(a), *(volatile u64 __force *)(a))
-#define readb(a) ({ u8 r_ = __raw_readb(a); mb(); r_; })
-#define readw(a) ({ u16 r_ = __raw_readw(a); mb(); r_; })
-#define readl(a) ({ u32 r_ = __raw_readl(a); mb(); r_; })
-#define readq(a) ({ u64 r_ = __raw_readq(a); mb(); r_; })
-
-#define writeb(v,a) ({ __raw_writeb((v),(a)); mb(); })
-#define writew(v,a) ({ __raw_writew((v),(a)); mb(); })
-#define writel(v,a) ({ __raw_writel((v),(a)); mb(); })
-#define writeq(v,a) ({ __raw_writeq((v),(a)); mb(); })
-
-/* SuperH on-chip I/O functions */
-#define ctrl_inb __raw_readb
-#define ctrl_inw __raw_readw
-#define ctrl_inl __raw_readl
-#define ctrl_inq __raw_readq
-
-#define ctrl_outb __raw_writeb
-#define ctrl_outw __raw_writew
-#define ctrl_outl __raw_writel
-#define ctrl_outq __raw_writeq
-
-static inline void ctrl_delay(void)
-{
-#ifdef P2SEG
- __raw_readw(P2SEG);
-#endif
+#define readb_relaxed(c) ({ u8 __v = __raw_readb(c); __v; })
+#define readw_relaxed(c) ({ u16 __v = le16_to_cpu((__force __le16) \
+ __raw_readw(c)); __v; })
+#define readl_relaxed(c) ({ u32 __v = le32_to_cpu((__force __le32) \
+ __raw_readl(c)); __v; })
+#define readq_relaxed(c) ({ u64 __v = le64_to_cpu((__force __le64) \
+ __raw_readq(c)); __v; })
+
+#define writeb_relaxed(v,c) ((void)__raw_writeb(v,c))
+#define writew_relaxed(v,c) ((void)__raw_writew((__force u16) \
+ cpu_to_le16(v),c))
+#define writel_relaxed(v,c) ((void)__raw_writel((__force u32) \
+ cpu_to_le32(v),c))
+#define writeq_relaxed(v,c) ((void)__raw_writeq((__force u64) \
+ cpu_to_le64(v),c))
+
+#define readb(a) ({ u8 r_ = readb_relaxed(a); rmb(); r_; })
+#define readw(a) ({ u16 r_ = readw_relaxed(a); rmb(); r_; })
+#define readl(a) ({ u32 r_ = readl_relaxed(a); rmb(); r_; })
+#define readq(a) ({ u64 r_ = readq_relaxed(a); rmb(); r_; })
+
+#define writeb(v,a) ({ wmb(); writeb_relaxed((v),(a)); })
+#define writew(v,a) ({ wmb(); writew_relaxed((v),(a)); })
+#define writel(v,a) ({ wmb(); writel_relaxed((v),(a)); })
+#define writeq(v,a) ({ wmb(); writeq_relaxed((v),(a)); })
+
+#define readsb(p,d,l) __raw_readsb(p,d,l)
+#define readsw(p,d,l) __raw_readsw(p,d,l)
+#define readsl(p,d,l) __raw_readsl(p,d,l)
+
+#define writesb(p,d,l) __raw_writesb(p,d,l)
+#define writesw(p,d,l) __raw_writesw(p,d,l)
+#define writesl(p,d,l) __raw_writesl(p,d,l)
+
+#define __BUILD_UNCACHED_IO(bwlq, type) \
+static inline type read##bwlq##_uncached(unsigned long addr) \
+{ \
+ type ret; \
+ jump_to_uncached(); \
+ ret = __raw_read##bwlq(addr); \
+ back_to_cached(); \
+ return ret; \
+} \
+ \
+static inline void write##bwlq##_uncached(type v, unsigned long addr) \
+{ \
+ jump_to_uncached(); \
+ __raw_write##bwlq(v, addr); \
+ back_to_cached(); \
}
-#define __BUILD_MEMORY_STRING(bwlq, type) \
+__BUILD_UNCACHED_IO(b, u8)
+__BUILD_UNCACHED_IO(w, u16)
+__BUILD_UNCACHED_IO(l, u32)
+__BUILD_UNCACHED_IO(q, u64)
+
+#define __BUILD_MEMORY_STRING(pfx, bwlq, type) \
\
-static inline void __raw_writes##bwlq(volatile void __iomem *mem, \
- const void *addr, unsigned int count) \
+static inline void \
+pfx##writes##bwlq(volatile void __iomem *mem, const void *addr, \
+ unsigned int count) \
{ \
const volatile type *__addr = addr; \
\
@@ -110,8 +110,8 @@ static inline void __raw_writes##bwlq(volatile void __iomem *mem, \
} \
} \
\
-static inline void __raw_reads##bwlq(volatile void __iomem *mem, \
- void *addr, unsigned int count) \
+static inline void pfx##reads##bwlq(volatile void __iomem *mem, \
+ void *addr, unsigned int count) \
{ \
volatile type *__addr = addr; \
\
@@ -121,73 +121,166 @@ static inline void __raw_reads##bwlq(volatile void __iomem *mem, \
} \
}
-__BUILD_MEMORY_STRING(b, u8)
-__BUILD_MEMORY_STRING(w, u16)
+__BUILD_MEMORY_STRING(__raw_, b, u8)
+__BUILD_MEMORY_STRING(__raw_, w, u16)
#ifdef CONFIG_SUPERH32
void __raw_writesl(void __iomem *addr, const void *data, int longlen);
void __raw_readsl(const void __iomem *addr, void *data, int longlen);
#else
-__BUILD_MEMORY_STRING(l, u32)
+__BUILD_MEMORY_STRING(__raw_, l, u32)
#endif
-__BUILD_MEMORY_STRING(q, u64)
+__BUILD_MEMORY_STRING(__raw_, q, u64)
-#define writesb __raw_writesb
-#define writesw __raw_writesw
-#define writesl __raw_writesl
+#ifdef CONFIG_HAS_IOPORT
-#define readsb __raw_readsb
-#define readsw __raw_readsw
-#define readsl __raw_readsl
+/*
+ * Slowdown I/O port space accesses for antique hardware.
+ */
+#undef CONF_SLOWDOWN_IO
-#define readb_relaxed(a) readb(a)
-#define readw_relaxed(a) readw(a)
-#define readl_relaxed(a) readl(a)
-#define readq_relaxed(a) readq(a)
+/*
+ * On SuperH I/O ports are memory mapped, so we access them using normal
+ * load/store instructions. sh_io_port_base is the virtual address to
+ * which all ports are being mapped.
+ */
+extern const unsigned long sh_io_port_base;
-/* Simple MMIO */
-#define ioread8(a) __raw_readb(a)
-#define ioread16(a) __raw_readw(a)
-#define ioread16be(a) be16_to_cpu(__raw_readw((a)))
-#define ioread32(a) __raw_readl(a)
-#define ioread32be(a) be32_to_cpu(__raw_readl((a)))
+static inline void __set_io_port_base(unsigned long pbase)
+{
+ *(unsigned long *)&sh_io_port_base = pbase;
+ barrier();
+}
-#define iowrite8(v,a) __raw_writeb((v),(a))
-#define iowrite16(v,a) __raw_writew((v),(a))
-#define iowrite16be(v,a) __raw_writew(cpu_to_be16((v)),(a))
-#define iowrite32(v,a) __raw_writel((v),(a))
-#define iowrite32be(v,a) __raw_writel(cpu_to_be32((v)),(a))
+#ifdef CONFIG_GENERIC_IOMAP
+#define __ioport_map ioport_map
+#else
+extern void __iomem *__ioport_map(unsigned long addr, unsigned int size);
+#endif
-#define ioread8_rep(a, d, c) __raw_readsb((a), (d), (c))
-#define ioread16_rep(a, d, c) __raw_readsw((a), (d), (c))
-#define ioread32_rep(a, d, c) __raw_readsl((a), (d), (c))
+#ifdef CONF_SLOWDOWN_IO
+#define SLOW_DOWN_IO __raw_readw(sh_io_port_base)
+#else
+#define SLOW_DOWN_IO
+#endif
-#define iowrite8_rep(a, s, c) __raw_writesb((a), (s), (c))
-#define iowrite16_rep(a, s, c) __raw_writesw((a), (s), (c))
-#define iowrite32_rep(a, s, c) __raw_writesl((a), (s), (c))
+#define __BUILD_IOPORT_SINGLE(pfx, bwlq, type, p, slow) \
+ \
+static inline void pfx##out##bwlq##p(type val, unsigned long port) \
+{ \
+ volatile type *__addr; \
+ \
+ __addr = __ioport_map(port, sizeof(type)); \
+ *__addr = val; \
+ slow; \
+} \
+ \
+static inline type pfx##in##bwlq##p(unsigned long port) \
+{ \
+ volatile type *__addr; \
+ type __val; \
+ \
+ __addr = __ioport_map(port, sizeof(type)); \
+ __val = *__addr; \
+ slow; \
+ \
+ return __val; \
+}
-/* synco on SH-4A, otherwise a nop */
-#define mmiowb() wmb()
+#define __BUILD_IOPORT_PFX(bus, bwlq, type) \
+ __BUILD_IOPORT_SINGLE(bus, bwlq, type, ,) \
+ __BUILD_IOPORT_SINGLE(bus, bwlq, type, _p, SLOW_DOWN_IO)
-#define IO_SPACE_LIMIT 0xffffffff
+#define BUILDIO_IOPORT(bwlq, type) \
+ __BUILD_IOPORT_PFX(, bwlq, type)
-extern unsigned long generic_io_base;
+BUILDIO_IOPORT(b, u8)
+BUILDIO_IOPORT(w, u16)
+BUILDIO_IOPORT(l, u32)
+BUILDIO_IOPORT(q, u64)
+
+#define __BUILD_IOPORT_STRING(bwlq, type) \
+ \
+static inline void outs##bwlq(unsigned long port, const void *addr, \
+ unsigned int count) \
+{ \
+ const volatile type *__addr = addr; \
+ \
+ while (count--) { \
+ out##bwlq(*__addr, port); \
+ __addr++; \
+ } \
+} \
+ \
+static inline void ins##bwlq(unsigned long port, void *addr, \
+ unsigned int count) \
+{ \
+ volatile type *__addr = addr; \
+ \
+ while (count--) { \
+ *__addr = in##bwlq(port); \
+ __addr++; \
+ } \
+}
+
+__BUILD_IOPORT_STRING(b, u8)
+__BUILD_IOPORT_STRING(w, u16)
+__BUILD_IOPORT_STRING(l, u32)
+__BUILD_IOPORT_STRING(q, u64)
+
+#endif
/*
- * This function provides a method for the generic case where a
- * board-specific ioport_map simply needs to return the port + some
- * arbitrary port base.
+ * Legacy SuperH on-chip I/O functions
*
- * We use this at board setup time to implicitly set the port base, and
- * as a result, we can use the generic ioport_map.
+ * These are all deprecated, all new (and especially cross-platform) code
+ * should be using the __raw_xxx() routines directly.
*/
-static inline void __set_io_port_base(unsigned long pbase)
+static inline u8 __deprecated ctrl_inb(unsigned long addr)
{
- generic_io_base = pbase;
+ return __raw_readb(addr);
}
-#define __ioport_map(p, n) sh_mv.mv_ioport_map((p), (n))
+static inline u16 __deprecated ctrl_inw(unsigned long addr)
+{
+ return __raw_readw(addr);
+}
+
+static inline u32 __deprecated ctrl_inl(unsigned long addr)
+{
+ return __raw_readl(addr);
+}
+
+static inline u64 __deprecated ctrl_inq(unsigned long addr)
+{
+ return __raw_readq(addr);
+}
+
+static inline void __deprecated ctrl_outb(u8 v, unsigned long addr)
+{
+ __raw_writeb(v, addr);
+}
+
+static inline void __deprecated ctrl_outw(u16 v, unsigned long addr)
+{
+ __raw_writew(v, addr);
+}
+
+static inline void __deprecated ctrl_outl(u32 v, unsigned long addr)
+{
+ __raw_writel(v, addr);
+}
+
+static inline void __deprecated ctrl_outq(u64 v, unsigned long addr)
+{
+ __raw_writeq(v, addr);
+}
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/* synco on SH-4A, otherwise a nop */
+#define mmiowb() wmb()
/* We really want to try and get these to memcpy etc */
void memcpy_fromio(void *, const volatile void __iomem *, unsigned long);
@@ -225,23 +318,22 @@ unsigned long long poke_real_address_q(unsigned long long addr,
* doesn't exist, so everything must go through page tables.
*/
#ifdef CONFIG_MMU
-void __iomem *__ioremap(unsigned long offset, unsigned long size,
- unsigned long flags);
+void __iomem *__ioremap_caller(phys_addr_t offset, unsigned long size,
+ pgprot_t prot, void *caller);
void __iounmap(void __iomem *addr);
static inline void __iomem *
-__ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags)
+__ioremap(phys_addr_t offset, unsigned long size, pgprot_t prot)
{
-#if defined(CONFIG_SUPERH32) && !defined(CONFIG_PMB_FIXED)
- unsigned long last_addr = offset + size - 1;
-#endif
- void __iomem *ret;
+ return __ioremap_caller(offset, size, prot, __builtin_return_address(0));
+}
- ret = __ioremap_trapped(offset, size);
- if (ret)
- return ret;
+static inline void __iomem *
+__ioremap_29bit(phys_addr_t offset, unsigned long size, pgprot_t prot)
+{
+#ifdef CONFIG_29BIT
+ phys_addr_t last_addr = offset + size - 1;
-#if defined(CONFIG_SUPERH32) && !defined(CONFIG_PMB_FIXED)
/*
* For P1 and P2 space this is trivial, as everything is already
* mapped. Uncached access for P1 addresses are done through P2.
@@ -249,7 +341,7 @@ __ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags)
* mapping must be done by the PMB or by using page tables.
*/
if (likely(PXSEG(offset) < P3SEG && PXSEG(last_addr) < P3SEG)) {
- if (unlikely(flags & _PAGE_CACHABLE))
+ if (unlikely(pgprot_val(prot) & _PAGE_CACHABLE))
return (void __iomem *)P1SEGADDR(offset);
return (void __iomem *)P2SEGADDR(offset);
@@ -260,29 +352,67 @@ __ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags)
return (void __iomem *)P4SEGADDR(offset);
#endif
- return __ioremap(offset, size, flags);
+ return NULL;
+}
+
+static inline void __iomem *
+__ioremap_mode(phys_addr_t offset, unsigned long size, pgprot_t prot)
+{
+ void __iomem *ret;
+
+ ret = __ioremap_trapped(offset, size);
+ if (ret)
+ return ret;
+
+ ret = __ioremap_29bit(offset, size, prot);
+ if (ret)
+ return ret;
+
+ return __ioremap(offset, size, prot);
}
#else
-#define __ioremap_mode(offset, size, flags) ((void __iomem *)(offset))
+#define __ioremap(offset, size, prot) ((void __iomem *)(offset))
+#define __ioremap_mode(offset, size, prot) ((void __iomem *)(offset))
#define __iounmap(addr) do { } while (0)
#endif /* CONFIG_MMU */
-#define ioremap(offset, size) \
- __ioremap_mode((offset), (size), 0)
-#define ioremap_nocache(offset, size) \
- __ioremap_mode((offset), (size), 0)
-#define ioremap_cache(offset, size) \
- __ioremap_mode((offset), (size), _PAGE_CACHABLE)
-#define p3_ioremap(offset, size, flags) \
- __ioremap((offset), (size), (flags))
-#define ioremap_prot(offset, size, flags) \
- __ioremap_mode((offset), (size), (flags))
-#define iounmap(addr) \
- __iounmap((addr))
-
-#define maybebadio(port) \
- printk(KERN_ERR "bad PC-like io %s:%u for port 0x%lx at 0x%08x\n", \
- __func__, __LINE__, (port), (u32)__builtin_return_address(0))
+static inline void __iomem *ioremap(phys_addr_t offset, unsigned long size)
+{
+ return __ioremap_mode(offset, size, PAGE_KERNEL_NOCACHE);
+}
+
+static inline void __iomem *
+ioremap_cache(phys_addr_t offset, unsigned long size)
+{
+ return __ioremap_mode(offset, size, PAGE_KERNEL);
+}
+
+#ifdef CONFIG_HAVE_IOREMAP_PROT
+static inline void __iomem *
+ioremap_prot(phys_addr_t offset, unsigned long size, unsigned long flags)
+{
+ return __ioremap_mode(offset, size, __pgprot(flags));
+}
+#endif
+
+#ifdef CONFIG_IOREMAP_FIXED
+extern void __iomem *ioremap_fixed(phys_addr_t, unsigned long, pgprot_t);
+extern int iounmap_fixed(void __iomem *);
+extern void ioremap_fixed_init(void);
+#else
+static inline void __iomem *
+ioremap_fixed(phys_addr_t phys_addr, unsigned long size, pgprot_t prot)
+{
+ BUG();
+ return NULL;
+}
+
+static inline void ioremap_fixed_init(void) { }
+static inline int iounmap_fixed(void __iomem *addr) { return -EINVAL; }
+#endif
+
+#define ioremap_nocache ioremap
+#define iounmap __iounmap
/*
* Convert a physical pointer to a virtual kernel pointer for /dev/mem
diff --git a/arch/sh/include/asm/io_generic.h b/arch/sh/include/asm/io_generic.h
index 1e5d375f55d..b5f6956f19c 100644
--- a/arch/sh/include/asm/io_generic.h
+++ b/arch/sh/include/asm/io_generic.h
@@ -11,32 +11,8 @@
#error "Don't include this header without a valid system prefix"
#endif
-u8 IO_CONCAT(__IO_PREFIX,inb)(unsigned long);
-u16 IO_CONCAT(__IO_PREFIX,inw)(unsigned long);
-u32 IO_CONCAT(__IO_PREFIX,inl)(unsigned long);
-
-void IO_CONCAT(__IO_PREFIX,outb)(u8, unsigned long);
-void IO_CONCAT(__IO_PREFIX,outw)(u16, unsigned long);
-void IO_CONCAT(__IO_PREFIX,outl)(u32, unsigned long);
-
-u8 IO_CONCAT(__IO_PREFIX,inb_p)(unsigned long);
-u16 IO_CONCAT(__IO_PREFIX,inw_p)(unsigned long);
-u32 IO_CONCAT(__IO_PREFIX,inl_p)(unsigned long);
-void IO_CONCAT(__IO_PREFIX,outb_p)(u8, unsigned long);
-void IO_CONCAT(__IO_PREFIX,outw_p)(u16, unsigned long);
-void IO_CONCAT(__IO_PREFIX,outl_p)(u32, unsigned long);
-
-void IO_CONCAT(__IO_PREFIX,insb)(unsigned long, void *dst, unsigned long count);
-void IO_CONCAT(__IO_PREFIX,insw)(unsigned long, void *dst, unsigned long count);
-void IO_CONCAT(__IO_PREFIX,insl)(unsigned long, void *dst, unsigned long count);
-void IO_CONCAT(__IO_PREFIX,outsb)(unsigned long, const void *src, unsigned long count);
-void IO_CONCAT(__IO_PREFIX,outsw)(unsigned long, const void *src, unsigned long count);
-void IO_CONCAT(__IO_PREFIX,outsl)(unsigned long, const void *src, unsigned long count);
-
-void *IO_CONCAT(__IO_PREFIX,ioremap)(unsigned long offset, unsigned long size);
-void IO_CONCAT(__IO_PREFIX,iounmap)(void *addr);
-
void __iomem *IO_CONCAT(__IO_PREFIX,ioport_map)(unsigned long addr, unsigned int size);
void IO_CONCAT(__IO_PREFIX,ioport_unmap)(void __iomem *addr);
+void IO_CONCAT(__IO_PREFIX,mem_init)(void);
#undef __IO_PREFIX
diff --git a/arch/sh/include/asm/ioctls.h b/arch/sh/include/asm/ioctls.h
index c212c371a4a..84e85a79263 100644
--- a/arch/sh/include/asm/ioctls.h
+++ b/arch/sh/include/asm/ioctls.h
@@ -69,6 +69,7 @@
# define TIOCPKT_START 8
# define TIOCPKT_NOSTOP 16
# define TIOCPKT_DOSTOP 32
+# define TIOCPKT_IOCTL 64
#define TIOCNOTTY _IO('T', 34) /* 0x5422 */
@@ -84,6 +85,8 @@
#define TCSETSF2 _IOW('T', 45, struct termios2)
#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */
+#define TIOCGDEV _IOR('T',0x32, unsigned int) /* Get primary device node of /dev/console */
+#define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */
#define TIOCSERCONFIG _IO('T', 83) /* 0x5453 */
#define TIOCSERGWILD _IOR('T', 84, int) /* 0x5454 */
diff --git a/arch/sh/include/asm/irq.h b/arch/sh/include/asm/irq.h
index df8e1500527..45d08b6a5ef 100644
--- a/arch/sh/include/asm/irq.h
+++ b/arch/sh/include/asm/irq.h
@@ -1,6 +1,7 @@
#ifndef __ASM_SH_IRQ_H
#define __ASM_SH_IRQ_H
+#include <linux/cpumask.h>
#include <asm/machvec.h>
/*
@@ -8,10 +9,18 @@
* advised to cap this at the hard limit that they're interested in
* through the machvec.
*/
-#define NR_IRQS 256
+#define NR_IRQS 512
#define NR_IRQS_LEGACY 8 /* Legacy external IRQ0-7 */
/*
+ * This is a special IRQ number for indicating that no IRQ has been
+ * triggered and to simply ignore the IRQ dispatch. This is a special
+ * case that can happen with IRQ auto-distribution when multiple CPUs
+ * are woken up and signalled in parallel.
+ */
+#define NO_IRQ_IGNORE ((unsigned int)-1)
+
+/*
* Convert back and forth between INTEVT and IRQ values.
*/
#ifdef CONFIG_CPU_HAS_INTEVT
@@ -42,6 +51,8 @@ static inline int generic_irq_demux(int irq)
#define irq_demux(irq) sh_mv.mv_irq_demux(irq)
void init_IRQ(void);
+void migrate_irqs(void);
+
asmlinkage int do_IRQ(unsigned int irq, struct pt_regs *regs);
#ifdef CONFIG_IRQSTACKS
@@ -53,6 +64,14 @@ extern void irq_ctx_exit(int cpu);
# define irq_ctx_exit(cpu) do { } while (0)
#endif
+#ifdef CONFIG_INTC_BALANCING
+extern unsigned int irq_lookup(unsigned int irq);
+extern void irq_finish(unsigned int irq);
+#else
+#define irq_lookup(irq) (irq)
+#define irq_finish(irq) do { } while (0)
+#endif
+
#include <asm-generic/irq.h>
#ifdef CONFIG_CPU_SH5
#include <cpu/irq.h>
diff --git a/arch/sh/include/asm/irqflags.h b/arch/sh/include/asm/irqflags.h
index 46e71da5be6..43b7608606c 100644
--- a/arch/sh/include/asm/irqflags.h
+++ b/arch/sh/include/asm/irqflags.h
@@ -1,34 +1,9 @@
#ifndef __ASM_SH_IRQFLAGS_H
#define __ASM_SH_IRQFLAGS_H
-#ifdef CONFIG_SUPERH32
-#include "irqflags_32.h"
-#else
-#include "irqflags_64.h"
-#endif
+#define ARCH_IRQ_DISABLED 0xf0
+#define ARCH_IRQ_ENABLED 0x00
-#define raw_local_save_flags(flags) \
- do { (flags) = __raw_local_save_flags(); } while (0)
-
-static inline int raw_irqs_disabled_flags(unsigned long flags)
-{
- return (flags != 0);
-}
-
-static inline int raw_irqs_disabled(void)
-{
- unsigned long flags = __raw_local_save_flags();
-
- return raw_irqs_disabled_flags(flags);
-}
-
-#define raw_local_irq_save(flags) \
- do { (flags) = __raw_local_irq_save(); } while (0)
-
-static inline void raw_local_irq_restore(unsigned long flags)
-{
- if ((flags & 0xf0) != 0xf0)
- raw_local_irq_enable();
-}
+#include <asm-generic/irqflags.h>
#endif /* __ASM_SH_IRQFLAGS_H */
diff --git a/arch/sh/include/asm/irqflags_32.h b/arch/sh/include/asm/irqflags_32.h
deleted file mode 100644
index 60218f54134..00000000000
--- a/arch/sh/include/asm/irqflags_32.h
+++ /dev/null
@@ -1,99 +0,0 @@
-#ifndef __ASM_SH_IRQFLAGS_32_H
-#define __ASM_SH_IRQFLAGS_32_H
-
-static inline void raw_local_irq_enable(void)
-{
- unsigned long __dummy0, __dummy1;
-
- __asm__ __volatile__ (
- "stc sr, %0\n\t"
- "and %1, %0\n\t"
-#ifdef CONFIG_CPU_HAS_SR_RB
- "stc r6_bank, %1\n\t"
- "or %1, %0\n\t"
-#endif
- "ldc %0, sr\n\t"
- : "=&r" (__dummy0), "=r" (__dummy1)
- : "1" (~0x000000f0)
- : "memory"
- );
-}
-
-static inline void raw_local_irq_disable(void)
-{
- unsigned long flags;
-
- __asm__ __volatile__ (
- "stc sr, %0\n\t"
- "or #0xf0, %0\n\t"
- "ldc %0, sr\n\t"
- : "=&z" (flags)
- : /* no inputs */
- : "memory"
- );
-}
-
-static inline void set_bl_bit(void)
-{
- unsigned long __dummy0, __dummy1;
-
- __asm__ __volatile__ (
- "stc sr, %0\n\t"
- "or %2, %0\n\t"
- "and %3, %0\n\t"
- "ldc %0, sr\n\t"
- : "=&r" (__dummy0), "=r" (__dummy1)
- : "r" (0x10000000), "r" (0xffffff0f)
- : "memory"
- );
-}
-
-static inline void clear_bl_bit(void)
-{
- unsigned long __dummy0, __dummy1;
-
- __asm__ __volatile__ (
- "stc sr, %0\n\t"
- "and %2, %0\n\t"
- "ldc %0, sr\n\t"
- : "=&r" (__dummy0), "=r" (__dummy1)
- : "1" (~0x10000000)
- : "memory"
- );
-}
-
-static inline unsigned long __raw_local_save_flags(void)
-{
- unsigned long flags;
-
- __asm__ __volatile__ (
- "stc sr, %0\n\t"
- "and #0xf0, %0\n\t"
- : "=&z" (flags)
- : /* no inputs */
- : "memory"
- );
-
- return flags;
-}
-
-static inline unsigned long __raw_local_irq_save(void)
-{
- unsigned long flags, __dummy;
-
- __asm__ __volatile__ (
- "stc sr, %1\n\t"
- "mov %1, %0\n\t"
- "or #0xf0, %0\n\t"
- "ldc %0, sr\n\t"
- "mov %1, %0\n\t"
- "and #0xf0, %0\n\t"
- : "=&z" (flags), "=&r" (__dummy)
- : /* no inputs */
- : "memory"
- );
-
- return flags;
-}
-
-#endif /* __ASM_SH_IRQFLAGS_32_H */
diff --git a/arch/sh/include/asm/irqflags_64.h b/arch/sh/include/asm/irqflags_64.h
deleted file mode 100644
index 88f65222c1d..00000000000
--- a/arch/sh/include/asm/irqflags_64.h
+++ /dev/null
@@ -1,85 +0,0 @@
-#ifndef __ASM_SH_IRQFLAGS_64_H
-#define __ASM_SH_IRQFLAGS_64_H
-
-#include <cpu/registers.h>
-
-#define SR_MASK_LL 0x00000000000000f0LL
-#define SR_BL_LL 0x0000000010000000LL
-
-static inline void raw_local_irq_enable(void)
-{
- unsigned long long __dummy0, __dummy1 = ~SR_MASK_LL;
-
- __asm__ __volatile__("getcon " __SR ", %0\n\t"
- "and %0, %1, %0\n\t"
- "putcon %0, " __SR "\n\t"
- : "=&r" (__dummy0)
- : "r" (__dummy1));
-}
-
-static inline void raw_local_irq_disable(void)
-{
- unsigned long long __dummy0, __dummy1 = SR_MASK_LL;
-
- __asm__ __volatile__("getcon " __SR ", %0\n\t"
- "or %0, %1, %0\n\t"
- "putcon %0, " __SR "\n\t"
- : "=&r" (__dummy0)
- : "r" (__dummy1));
-}
-
-static inline void set_bl_bit(void)
-{
- unsigned long long __dummy0, __dummy1 = SR_BL_LL;
-
- __asm__ __volatile__("getcon " __SR ", %0\n\t"
- "or %0, %1, %0\n\t"
- "putcon %0, " __SR "\n\t"
- : "=&r" (__dummy0)
- : "r" (__dummy1));
-
-}
-
-static inline void clear_bl_bit(void)
-{
- unsigned long long __dummy0, __dummy1 = ~SR_BL_LL;
-
- __asm__ __volatile__("getcon " __SR ", %0\n\t"
- "and %0, %1, %0\n\t"
- "putcon %0, " __SR "\n\t"
- : "=&r" (__dummy0)
- : "r" (__dummy1));
-}
-
-static inline unsigned long __raw_local_save_flags(void)
-{
- unsigned long long __dummy = SR_MASK_LL;
- unsigned long flags;
-
- __asm__ __volatile__ (
- "getcon " __SR ", %0\n\t"
- "and %0, %1, %0"
- : "=&r" (flags)
- : "r" (__dummy));
-
- return flags;
-}
-
-static inline unsigned long __raw_local_irq_save(void)
-{
- unsigned long long __dummy0, __dummy1 = SR_MASK_LL;
- unsigned long flags;
-
- __asm__ __volatile__ (
- "getcon " __SR ", %1\n\t"
- "or %1, r63, %0\n\t"
- "or %1, %2, %1\n\t"
- "putcon %1, " __SR "\n\t"
- "and %0, %2, %0"
- : "=&r" (flags), "=&r" (__dummy0)
- : "r" (__dummy1));
-
- return flags;
-}
-
-#endif /* __ASM_SH_IRQFLAGS_64_H */
diff --git a/arch/sh/include/asm/kdebug.h b/arch/sh/include/asm/kdebug.h
index 0b9f896f203..5f6d2e9ccb7 100644
--- a/arch/sh/include/asm/kdebug.h
+++ b/arch/sh/include/asm/kdebug.h
@@ -4,7 +4,10 @@
/* Grossly misnamed. */
enum die_val {
DIE_TRAP,
+ DIE_NMI,
DIE_OOPS,
+ DIE_BREAKPOINT,
+ DIE_SSTEP,
};
#endif /* __ASM_SH_KDEBUG_H */
diff --git a/arch/sh/include/asm/kexec.h b/arch/sh/include/asm/kexec.h
index 765a5e1660f..ad6ef8a275e 100644
--- a/arch/sh/include/asm/kexec.h
+++ b/arch/sh/include/asm/kexec.h
@@ -26,6 +26,10 @@
/* The native architecture */
#define KEXEC_ARCH KEXEC_ARCH_SH
+#ifdef CONFIG_KEXEC
+/* arch/sh/kernel/machine_kexec.c */
+void reserve_crashkernel(void);
+
static inline void crash_setup_regs(struct pt_regs *newregs,
struct pt_regs *oldregs)
{
@@ -59,4 +63,8 @@ static inline void crash_setup_regs(struct pt_regs *newregs,
newregs->pc = (unsigned long)current_text_addr();
}
}
+#else
+static inline void reserve_crashkernel(void) { }
+#endif /* CONFIG_KEXEC */
+
#endif /* __ASM_SH_KEXEC_H */
diff --git a/arch/sh/include/asm/kgdb.h b/arch/sh/include/asm/kgdb.h
index 72704ed725e..4235e228d92 100644
--- a/arch/sh/include/asm/kgdb.h
+++ b/arch/sh/include/asm/kgdb.h
@@ -30,9 +30,6 @@ static inline void arch_kgdb_breakpoint(void)
__asm__ __volatile__ ("trapa #0x3c\n");
}
-/* State info */
-extern char in_nmi; /* Debounce flag to prevent NMI reentry*/
-
#define BUFMAX 2048
#define CACHE_FLUSH_IS_SAFE 1
diff --git a/arch/sh/include/asm/kprobes.h b/arch/sh/include/asm/kprobes.h
index 036c3311233..134f3980e44 100644
--- a/arch/sh/include/asm/kprobes.h
+++ b/arch/sh/include/asm/kprobes.h
@@ -16,7 +16,6 @@ typedef insn_size_t kprobe_opcode_t;
? (MAX_STACK_SIZE) \
: (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR)))
-#define regs_return_value(_regs) ((_regs)->regs[0])
#define flush_insn_slot(p) do { } while (0)
#define kretprobe_blacklist_size 0
diff --git a/arch/sh/include/asm/local64.h b/arch/sh/include/asm/local64.h
new file mode 100644
index 00000000000..36c93b5cc23
--- /dev/null
+++ b/arch/sh/include/asm/local64.h
@@ -0,0 +1 @@
+#include <asm-generic/local64.h>
diff --git a/arch/sh/include/asm/machvec.h b/arch/sh/include/asm/machvec.h
index 84dd37761f5..dd5d6e5bf20 100644
--- a/arch/sh/include/asm/machvec.h
+++ b/arch/sh/include/asm/machvec.h
@@ -12,43 +12,25 @@
#include <linux/types.h>
#include <linux/time.h>
-#include <asm/machtypes.h>
+#include <generated/machtypes.h>
struct sh_machine_vector {
void (*mv_setup)(char **cmdline_p);
const char *mv_name;
int mv_nr_irqs;
- u8 (*mv_inb)(unsigned long);
- u16 (*mv_inw)(unsigned long);
- u32 (*mv_inl)(unsigned long);
- void (*mv_outb)(u8, unsigned long);
- void (*mv_outw)(u16, unsigned long);
- void (*mv_outl)(u32, unsigned long);
-
- u8 (*mv_inb_p)(unsigned long);
- u16 (*mv_inw_p)(unsigned long);
- u32 (*mv_inl_p)(unsigned long);
- void (*mv_outb_p)(u8, unsigned long);
- void (*mv_outw_p)(u16, unsigned long);
- void (*mv_outl_p)(u32, unsigned long);
-
- void (*mv_insb)(unsigned long, void *dst, unsigned long count);
- void (*mv_insw)(unsigned long, void *dst, unsigned long count);
- void (*mv_insl)(unsigned long, void *dst, unsigned long count);
- void (*mv_outsb)(unsigned long, const void *src, unsigned long count);
- void (*mv_outsw)(unsigned long, const void *src, unsigned long count);
- void (*mv_outsl)(unsigned long, const void *src, unsigned long count);
-
int (*mv_irq_demux)(int irq);
-
void (*mv_init_irq)(void);
+#ifdef CONFIG_HAS_IOPORT
void __iomem *(*mv_ioport_map)(unsigned long port, unsigned int size);
void (*mv_ioport_unmap)(void __iomem *);
+#endif
int (*mv_clk_init)(void);
int (*mv_mode_pins)(void);
+
+ void (*mv_mem_init)(void);
};
extern struct sh_machine_vector sh_mv;
diff --git a/arch/sh/include/asm/memblock.h b/arch/sh/include/asm/memblock.h
new file mode 100644
index 00000000000..e87063fad2e
--- /dev/null
+++ b/arch/sh/include/asm/memblock.h
@@ -0,0 +1,4 @@
+#ifndef __ASM_SH_MEMBLOCK_H
+#define __ASM_SH_MEMBLOCK_H
+
+#endif /* __ASM_SH_MEMBLOCK_H */
diff --git a/arch/sh/include/asm/mmu.h b/arch/sh/include/asm/mmu.h
index f5963037c9d..56e4418c19b 100644
--- a/arch/sh/include/asm/mmu.h
+++ b/arch/sh/include/asm/mmu.h
@@ -7,12 +7,18 @@
#define PMB_PASCR 0xff000070
#define PMB_IRMCR 0xff000078
+#define PASCR_SE 0x80000000
+
#define PMB_ADDR 0xf6100000
#define PMB_DATA 0xf7100000
-#define PMB_ENTRY_MAX 16
+
+#define NR_PMB_ENTRIES 16
+
#define PMB_E_MASK 0x0000000f
#define PMB_E_SHIFT 8
+#define PMB_PFN_MASK 0xff000000
+
#define PMB_SZ_16M 0x00000000
#define PMB_SZ_64M 0x00000010
#define PMB_SZ_128M 0x00000080
@@ -21,11 +27,15 @@
#define PMB_C 0x00000008
#define PMB_WT 0x00000001
#define PMB_UB 0x00000200
+#define PMB_CACHE_MASK (PMB_C | PMB_WT | PMB_UB)
#define PMB_V 0x00000100
#define PMB_NO_ENTRY (-1)
#ifndef __ASSEMBLY__
+#include <linux/errno.h>
+#include <linux/threads.h>
+#include <asm/page.h>
/* Default "unsigned long" context */
typedef unsigned long mm_context_id_t[NR_CPUS];
@@ -43,36 +53,54 @@ typedef struct {
#endif
} mm_context_t;
-struct pmb_entry;
+#ifdef CONFIG_PMB
+/* arch/sh/mm/pmb.c */
+bool __in_29bit_mode(void);
+
+void pmb_init(void);
+int pmb_bolt_mapping(unsigned long virt, phys_addr_t phys,
+ unsigned long size, pgprot_t prot);
+void __iomem *pmb_remap_caller(phys_addr_t phys, unsigned long size,
+ pgprot_t prot, void *caller);
+int pmb_unmap(void __iomem *addr);
-struct pmb_entry {
- unsigned long vpn;
- unsigned long ppn;
- unsigned long flags;
+#else
- /*
- * 0 .. NR_PMB_ENTRIES for specific entry selection, or
- * PMB_NO_ENTRY to search for a free one
- */
- int entry;
+static inline int
+pmb_bolt_mapping(unsigned long virt, phys_addr_t phys,
+ unsigned long size, pgprot_t prot)
+{
+ return -EINVAL;
+}
- struct pmb_entry *next;
- /* Adjacent entry link for contiguous multi-entry mappings */
- struct pmb_entry *link;
-};
+static inline void __iomem *
+pmb_remap_caller(phys_addr_t phys, unsigned long size,
+ pgprot_t prot, void *caller)
+{
+ return NULL;
+}
+
+static inline int pmb_unmap(void __iomem *addr)
+{
+ return -EINVAL;
+}
+
+#define pmb_init(addr) do { } while (0)
+
+#ifdef CONFIG_29BIT
+#define __in_29bit_mode() (1)
+#else
+#define __in_29bit_mode() (0)
+#endif
+
+#endif /* CONFIG_PMB */
+
+static inline void __iomem *
+pmb_remap(phys_addr_t phys, unsigned long size, pgprot_t prot)
+{
+ return pmb_remap_caller(phys, size, prot, __builtin_return_address(0));
+}
-/* arch/sh/mm/pmb.c */
-int __set_pmb_entry(unsigned long vpn, unsigned long ppn,
- unsigned long flags, int *entry);
-int set_pmb_entry(struct pmb_entry *pmbe);
-void clear_pmb_entry(struct pmb_entry *pmbe);
-struct pmb_entry *pmb_alloc(unsigned long vpn, unsigned long ppn,
- unsigned long flags);
-void pmb_free(struct pmb_entry *pmbe);
-long pmb_remap(unsigned long virt, unsigned long phys,
- unsigned long size, unsigned long flags);
-void pmb_unmap(unsigned long addr);
#endif /* __ASSEMBLY__ */
#endif /* __MMU_H */
-
diff --git a/arch/sh/include/asm/mmu_context.h b/arch/sh/include/asm/mmu_context.h
index 67d8946db19..384c7471a37 100644
--- a/arch/sh/include/asm/mmu_context.h
+++ b/arch/sh/include/asm/mmu_context.h
@@ -69,7 +69,7 @@ static inline void get_mmu_context(struct mm_struct *mm, unsigned int cpu)
* We exhaust ASID of this version.
* Flush all TLB and start new cycle.
*/
- flush_tlb_all();
+ local_flush_tlb_all();
#ifdef CONFIG_SUPERH64
/*
@@ -158,7 +158,7 @@ static inline void enable_mmu(void)
unsigned int cpu = smp_processor_id();
/* Enable MMU */
- ctrl_outl(MMU_CONTROL_INIT, MMUCR);
+ __raw_writel(MMU_CONTROL_INIT, MMUCR);
ctrl_barrier();
if (asid_cache(cpu) == NO_CONTEXT)
@@ -171,9 +171,9 @@ static inline void disable_mmu(void)
{
unsigned long cr;
- cr = ctrl_inl(MMUCR);
+ cr = __raw_readl(MMUCR);
cr &= ~MMU_CONTROL_INIT;
- ctrl_outl(cr, MMUCR);
+ __raw_writel(cr, MMUCR);
ctrl_barrier();
}
diff --git a/arch/sh/include/asm/mmu_context_32.h b/arch/sh/include/asm/mmu_context_32.h
index 8ef800c549a..10e2e17210d 100644
--- a/arch/sh/include/asm/mmu_context_32.h
+++ b/arch/sh/include/asm/mmu_context_32.h
@@ -49,11 +49,11 @@ static inline unsigned long get_asid(void)
/* MMU_TTB is used for optimizing the fault handling. */
static inline void set_TTB(pgd_t *pgd)
{
- ctrl_outl((unsigned long)pgd, MMU_TTB);
+ __raw_writel((unsigned long)pgd, MMU_TTB);
}
static inline pgd_t *get_TTB(void)
{
- return (pgd_t *)ctrl_inl(MMU_TTB);
+ return (pgd_t *)__raw_readl(MMU_TTB);
}
#endif /* __ASM_SH_MMU_CONTEXT_32_H */
diff --git a/arch/sh/include/asm/mmzone.h b/arch/sh/include/asm/mmzone.h
index 7f5363b29ba..8887baff5ef 100644
--- a/arch/sh/include/asm/mmzone.h
+++ b/arch/sh/include/asm/mmzone.h
@@ -42,9 +42,10 @@ setup_bootmem_node(int nid, unsigned long start, unsigned long end)
void __init plat_mem_setup(void);
/* arch/sh/kernel/setup.c */
-void __init setup_bootmem_allocator(unsigned long start_pfn);
void __init __add_active_range(unsigned int nid, unsigned long start_pfn,
unsigned long end_pfn);
+/* arch/sh/mm/init.c */
+void __init allocate_pgdat(unsigned int nid);
#endif /* __KERNEL__ */
#endif /* __ASM_SH_MMZONE_H */
diff --git a/arch/sh/include/asm/module.h b/arch/sh/include/asm/module.h
index 068bf165975..b7927de86f9 100644
--- a/arch/sh/include/asm/module.h
+++ b/arch/sh/include/asm/module.h
@@ -1,7 +1,22 @@
#ifndef _ASM_SH_MODULE_H
#define _ASM_SH_MODULE_H
-#include <asm-generic/module.h>
+struct mod_arch_specific {
+#ifdef CONFIG_DWARF_UNWINDER
+ struct list_head fde_list;
+ struct list_head cie_list;
+#endif
+};
+
+#ifdef CONFIG_64BIT
+#define Elf_Shdr Elf64_Shdr
+#define Elf_Sym Elf64_Sym
+#define Elf_Ehdr Elf64_Ehdr
+#else
+#define Elf_Shdr Elf32_Shdr
+#define Elf_Sym Elf32_Sym
+#define Elf_Ehdr Elf32_Ehdr
+#endif
#ifdef CONFIG_CPU_LITTLE_ENDIAN
# ifdef CONFIG_CPU_SH2
diff --git a/arch/sh/include/asm/page.h b/arch/sh/include/asm/page.h
index 49592c780a6..c4e0b3d472b 100644
--- a/arch/sh/include/asm/page.h
+++ b/arch/sh/include/asm/page.h
@@ -45,31 +45,29 @@
#endif
#ifndef __ASSEMBLY__
+#include <asm/uncached.h>
extern unsigned long shm_align_mask;
extern unsigned long max_low_pfn, min_low_pfn;
-extern unsigned long memory_start, memory_end;
+extern unsigned long memory_start, memory_end, memory_limit;
-extern void clear_page(void *to);
+static inline unsigned long
+pages_do_alias(unsigned long addr1, unsigned long addr2)
+{
+ return (addr1 ^ addr2) & shm_align_mask;
+}
+
+#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
extern void copy_page(void *to, void *from);
-#if !defined(CONFIG_CACHE_OFF) && defined(CONFIG_MMU) && \
- (defined(CONFIG_CPU_SH5) || defined(CONFIG_CPU_SH4) || \
- defined(CONFIG_SH7705_CACHE_32KB))
struct page;
struct vm_area_struct;
-extern void clear_user_page(void *to, unsigned long address, struct page *page);
-extern void copy_user_page(void *to, void *from, unsigned long address,
- struct page *page);
-#if defined(CONFIG_CPU_SH4)
+
extern void copy_user_highpage(struct page *to, struct page *from,
unsigned long vaddr, struct vm_area_struct *vma);
#define __HAVE_ARCH_COPY_USER_HIGHPAGE
-#endif
-#else
-#define clear_user_page(page, vaddr, pg) clear_page(page)
-#define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
-#endif
+extern void clear_user_highpage(struct page *page, unsigned long vaddr);
+#define clear_user_highpage clear_user_highpage
/*
* These are used to make use of C type-checking..
@@ -90,7 +88,7 @@ typedef struct { unsigned long pgd; } pgd_t;
#define __pte(x) ((pte_t) { (x) } )
#else
typedef struct { unsigned long long pte_low; } pte_t;
-typedef struct { unsigned long pgprot; } pgprot_t;
+typedef struct { unsigned long long pgprot; } pgprot_t;
typedef struct { unsigned long pgd; } pgd_t;
#define pte_val(x) ((x).pte_low)
#define __pte(x) ((pte_t) { (x) } )
@@ -129,17 +127,25 @@ typedef struct page *pgtable_t;
* is not visible (it is part of the PMB mapping) and so needs to be
* added or subtracted as required.
*/
-#if defined(CONFIG_PMB_FIXED)
-/* phys = virt - PAGE_OFFSET - (__MEMORY_START & 0xe0000000) */
-#define PMB_OFFSET (PAGE_OFFSET - PXSEG(__MEMORY_START))
-#define __pa(x) ((unsigned long)(x) - PMB_OFFSET)
-#define __va(x) ((void *)((unsigned long)(x) + PMB_OFFSET))
-#elif defined(CONFIG_32BIT)
-#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET+__MEMORY_START)
-#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET-__MEMORY_START))
+#ifdef CONFIG_PMB
+#define ___pa(x) ((x)-PAGE_OFFSET+__MEMORY_START)
+#define ___va(x) ((x)+PAGE_OFFSET-__MEMORY_START)
+#else
+#define ___pa(x) ((x)-PAGE_OFFSET)
+#define ___va(x) ((x)+PAGE_OFFSET)
+#endif
+
+#ifndef __ASSEMBLY__
+#define __pa(x) ___pa((unsigned long)x)
+#define __va(x) (void *)___va((unsigned long)x)
+#endif /* !__ASSEMBLY__ */
+
+#ifdef CONFIG_UNCACHED_MAPPING
+#define UNCAC_ADDR(addr) ((addr) - PAGE_OFFSET + uncached_start)
+#define CAC_ADDR(addr) ((addr) - uncached_start + PAGE_OFFSET)
#else
-#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET)
-#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET))
+#define UNCAC_ADDR(addr) ((addr))
+#define CAC_ADDR(addr) ((addr))
#endif
#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
@@ -174,7 +180,7 @@ typedef struct page *pgtable_t;
* Some drivers need to perform DMA into kmalloc'ed buffers
* and so we have to increase the kmalloc minalign for this.
*/
-#define ARCH_KMALLOC_MINALIGN L1_CACHE_BYTES
+#define ARCH_DMA_MINALIGN L1_CACHE_BYTES
#ifdef CONFIG_SUPERH64
/*
diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h
index d3633f513eb..f0efe97f175 100644
--- a/arch/sh/include/asm/pci.h
+++ b/arch/sh/include/asm/pci.h
@@ -3,14 +3,11 @@
#ifdef __KERNEL__
-#include <linux/dma-mapping.h>
-
/* Can be used to override the logic in pci_scan_bus for skipping
already-configured bus numbers - to be used for buggy BIOSes
or architectures with incomplete PCI setup by the loader */
#define pcibios_assign_all_busses() 1
-#define pcibios_scan_all_fns(a, b) 0
/*
* A board can define one or more PCI channels that represent built-in (or
@@ -18,20 +15,51 @@
*/
struct pci_channel {
struct pci_channel *next;
+ struct pci_bus *bus;
struct pci_ops *pci_ops;
- struct resource *io_resource;
- struct resource *mem_resource;
+
+ struct resource *resources;
+ unsigned int nr_resources;
unsigned long io_offset;
unsigned long mem_offset;
unsigned long reg_base;
-
unsigned long io_map_base;
+
+ unsigned int index;
+ unsigned int need_domain_info;
+
+ /* Optional error handling */
+ struct timer_list err_timer, serr_timer;
+ unsigned int err_irq, serr_irq;
};
-extern void register_pci_controller(struct pci_channel *hose);
+/* arch/sh/drivers/pci/pci.c */
+extern raw_spinlock_t pci_config_lock;
+
+extern int register_pci_controller(struct pci_channel *hose);
+extern void pcibios_report_status(unsigned int status_mask, int warn);
+
+/* arch/sh/drivers/pci/common.c */
+extern int early_read_config_byte(struct pci_channel *hose, int top_bus,
+ int bus, int devfn, int offset, u8 *value);
+extern int early_read_config_word(struct pci_channel *hose, int top_bus,
+ int bus, int devfn, int offset, u16 *value);
+extern int early_read_config_dword(struct pci_channel *hose, int top_bus,
+ int bus, int devfn, int offset, u32 *value);
+extern int early_write_config_byte(struct pci_channel *hose, int top_bus,
+ int bus, int devfn, int offset, u8 value);
+extern int early_write_config_word(struct pci_channel *hose, int top_bus,
+ int bus, int devfn, int offset, u16 value);
+extern int early_write_config_dword(struct pci_channel *hose, int top_bus,
+ int bus, int devfn, int offset, u32 value);
+extern void pcibios_enable_timers(struct pci_channel *hose);
+extern unsigned int pcibios_handle_status_errors(unsigned long addr,
+ unsigned int status, struct pci_channel *hose);
+extern int pci_is_66mhz_capable(struct pci_channel *hose,
+ int top_bus, int current_bus);
extern unsigned long PCIBIOS_MIN_IO, PCIBIOS_MIN_MEM;
@@ -55,38 +83,7 @@ static inline void pcibios_penalize_isa_irq(int irq, int active)
* address space. The networking and block device layers use
* this boolean for bounce buffer decisions.
*/
-#define PCI_DMA_BUS_IS_PHYS (1)
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/scatterlist.h>
-#include <linux/string.h>
-#include <asm/io.h>
-
-/* pci_unmap_{single,page} being a nop depends upon the
- * configuration.
- */
-#ifdef CONFIG_SH_PCIDMA_NONCOHERENT
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \
- dma_addr_t ADDR_NAME;
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) \
- __u32 LEN_NAME;
-#define pci_unmap_addr(PTR, ADDR_NAME) \
- ((PTR)->ADDR_NAME)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) \
- (((PTR)->ADDR_NAME) = (VAL))
-#define pci_unmap_len(PTR, LEN_NAME) \
- ((PTR)->LEN_NAME)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \
- (((PTR)->LEN_NAME) = (VAL))
-#else
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
-#define pci_unmap_addr(PTR, ADDR_NAME) (0)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) do { } while (0)
-#define pci_unmap_len(PTR, LEN_NAME) (0)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0)
-#endif
+#define PCI_DMA_BUS_IS_PHYS (dma_ops->is_phys)
#ifdef CONFIG_PCI
/*
@@ -114,20 +111,6 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev,
}
#endif
-#ifdef CONFIG_SUPERH32
-/*
- * If we're on an SH7751 or SH7780 PCI controller, PCI memory is mapped
- * at the end of the address space in a special non-translatable area.
- */
-#define PCI_MEM_FIXED_START 0xfd000000
-#define PCI_MEM_FIXED_END (PCI_MEM_FIXED_START + 0x01000000)
-
-#define is_pci_memory_fixed_range(s, e) \
- ((s) >= PCI_MEM_FIXED_START && (e) < PCI_MEM_FIXED_END)
-#else
-#define is_pci_memory_fixed_range(s, e) (0)
-#endif
-
/* Board-specific fixup routines. */
int pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin);
@@ -137,6 +120,14 @@ extern void pcibios_resource_to_bus(struct pci_dev *dev,
extern void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
struct pci_bus_region *region);
+#define pci_domain_nr(bus) ((struct pci_channel *)(bus)->sysdata)->index
+
+static inline int pci_proc_domain(struct pci_bus *bus)
+{
+ struct pci_channel *hose = bus->sysdata;
+ return hose->need_domain_info;
+}
+
/* Chances are this interrupt is wired PC-style ... */
static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
{
diff --git a/arch/sh/include/asm/perf_counter.h b/arch/sh/include/asm/perf_counter.h
deleted file mode 100644
index a8153c2aa6f..00000000000
--- a/arch/sh/include/asm/perf_counter.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef __ASM_SH_PERF_COUNTER_H
-#define __ASM_SH_PERF_COUNTER_H
-
-/* SH only supports software counters through this interface. */
-#define set_perf_counter_pending() do { } while (0)
-
-#endif /* __ASM_SH_PERF_COUNTER_H */
diff --git a/arch/sh/include/asm/perf_event.h b/arch/sh/include/asm/perf_event.h
new file mode 100644
index 00000000000..14308bed7ea
--- /dev/null
+++ b/arch/sh/include/asm/perf_event.h
@@ -0,0 +1,29 @@
+#ifndef __ASM_SH_PERF_EVENT_H
+#define __ASM_SH_PERF_EVENT_H
+
+struct hw_perf_event;
+
+#define MAX_HWEVENTS 2
+
+struct sh_pmu {
+ const char *name;
+ unsigned int num_events;
+ void (*disable_all)(void);
+ void (*enable_all)(void);
+ void (*enable)(struct hw_perf_event *, int);
+ void (*disable)(struct hw_perf_event *, int);
+ u64 (*read)(int);
+ int (*event_map)(int);
+ unsigned int max_events;
+ unsigned long raw_event_mask;
+ const int (*cache_events)[PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX];
+};
+
+/* arch/sh/kernel/perf_event.c */
+extern int register_sh_pmu(struct sh_pmu *);
+extern int reserve_pmc_hardware(void);
+extern void release_pmc_hardware(void);
+
+#endif /* __ASM_SH_PERF_EVENT_H */
diff --git a/arch/sh/include/asm/pgalloc.h b/arch/sh/include/asm/pgalloc.h
index 84dd2db7104..8c00785c60d 100644
--- a/arch/sh/include/asm/pgalloc.h
+++ b/arch/sh/include/asm/pgalloc.h
@@ -4,8 +4,16 @@
#include <linux/quicklist.h>
#include <asm/page.h>
-#define QUICK_PGD 0 /* We preserve special mappings over free */
-#define QUICK_PT 1 /* Other page table pages that are zero on free */
+#define QUICK_PT 0 /* Other page table pages that are zero on free */
+
+extern pgd_t *pgd_alloc(struct mm_struct *);
+extern void pgd_free(struct mm_struct *mm, pgd_t *pgd);
+
+#if PAGETABLE_LEVELS > 2
+extern void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmd);
+extern pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address);
+extern void pmd_free(struct mm_struct *mm, pmd_t *pmd);
+#endif
static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
pte_t *pte)
@@ -20,28 +28,9 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
}
#define pmd_pgtable(pmd) pmd_page(pmd)
-static inline void pgd_ctor(void *x)
-{
- pgd_t *pgd = x;
-
- memcpy(pgd + USER_PTRS_PER_PGD,
- swapper_pg_dir + USER_PTRS_PER_PGD,
- (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
-}
-
/*
* Allocate and free page tables.
*/
-static inline pgd_t *pgd_alloc(struct mm_struct *mm)
-{
- return quicklist_alloc(QUICK_PGD, GFP_KERNEL | __GFP_REPEAT, pgd_ctor);
-}
-
-static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
-{
- quicklist_free(QUICK_PGD, NULL, pgd);
-}
-
static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
unsigned long address)
{
@@ -73,23 +62,14 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
quicklist_free_page(QUICK_PT, NULL, pte);
}
-#define __pte_free_tlb(tlb,pte) \
+#define __pte_free_tlb(tlb,pte,addr) \
do { \
pgtable_page_dtor(pte); \
tlb_remove_page((tlb), (pte)); \
} while (0)
-/*
- * allocating and freeing a pmd is trivial: the 1-entry pmd is
- * inside the pgd, so has no extra memory associated with it.
- */
-
-#define pmd_free(mm, x) do { } while (0)
-#define __pmd_free_tlb(tlb,x) do { } while (0)
-
static inline void check_pgt_cache(void)
{
- quicklist_trim(QUICK_PGD, NULL, 25, 16);
quicklist_trim(QUICK_PT, NULL, 25, 16);
}
diff --git a/arch/sh/include/asm/pgtable-2level.h b/arch/sh/include/asm/pgtable-2level.h
new file mode 100644
index 00000000000..19bd89db17e
--- /dev/null
+++ b/arch/sh/include/asm/pgtable-2level.h
@@ -0,0 +1,23 @@
+#ifndef __ASM_SH_PGTABLE_2LEVEL_H
+#define __ASM_SH_PGTABLE_2LEVEL_H
+
+#include <asm-generic/pgtable-nopmd.h>
+
+/*
+ * traditional two-level paging structure
+ */
+#define PAGETABLE_LEVELS 2
+
+/* PTE bits */
+#define PTE_MAGNITUDE 2 /* 32-bit PTEs */
+
+#define PTE_SHIFT PAGE_SHIFT
+#define PTE_BITS (PTE_SHIFT - PTE_MAGNITUDE)
+
+/* PGD bits */
+#define PGDIR_SHIFT (PTE_SHIFT + PTE_BITS)
+
+#define PTRS_PER_PGD (PAGE_SIZE / (1 << PTE_MAGNITUDE))
+#define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE)
+
+#endif /* __ASM_SH_PGTABLE_2LEVEL_H */
diff --git a/arch/sh/include/asm/pgtable-3level.h b/arch/sh/include/asm/pgtable-3level.h
new file mode 100644
index 00000000000..249a985d964
--- /dev/null
+++ b/arch/sh/include/asm/pgtable-3level.h
@@ -0,0 +1,56 @@
+#ifndef __ASM_SH_PGTABLE_3LEVEL_H
+#define __ASM_SH_PGTABLE_3LEVEL_H
+
+#include <asm-generic/pgtable-nopud.h>
+
+/*
+ * Some cores need a 3-level page table layout, for example when using
+ * 64-bit PTEs and 4K pages.
+ */
+#define PAGETABLE_LEVELS 3
+
+#define PTE_MAGNITUDE 3 /* 64-bit PTEs on SH-X2 TLB */
+
+/* PGD bits */
+#define PGDIR_SHIFT 30
+
+#define PTRS_PER_PGD 4
+#define USER_PTRS_PER_PGD 2
+
+/* PMD bits */
+#define PMD_SHIFT (PAGE_SHIFT + (PAGE_SHIFT - PTE_MAGNITUDE))
+#define PMD_SIZE (1UL << PMD_SHIFT)
+#define PMD_MASK (~(PMD_SIZE-1))
+
+#define PTRS_PER_PMD ((1 << PGDIR_SHIFT) / PMD_SIZE)
+
+#define pmd_ERROR(e) \
+ printk("%s:%d: bad pmd %016llx.\n", __FILE__, __LINE__, pmd_val(e))
+
+typedef struct { unsigned long long pmd; } pmd_t;
+#define pmd_val(x) ((x).pmd)
+#define __pmd(x) ((pmd_t) { (x) } )
+
+static inline unsigned long pud_page_vaddr(pud_t pud)
+{
+ return pud_val(pud);
+}
+
+#define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
+static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address)
+{
+ return (pmd_t *)pud_page_vaddr(*pud) + pmd_index(address);
+}
+
+#define pud_none(x) (!pud_val(x))
+#define pud_present(x) (pud_val(x))
+#define pud_clear(xp) do { set_pud(xp, __pud(0)); } while (0)
+#define pud_bad(x) (pud_val(x) & ~PAGE_MASK)
+
+/*
+ * (puds are folded into pgds so this doesn't get actually called,
+ * but the define is needed for a generic inline function.)
+ */
+#define set_pud(pudptr, pudval) do { *(pudptr) = (pudval); } while(0)
+
+#endif /* __ASM_SH_PGTABLE_3LEVEL_H */
diff --git a/arch/sh/include/asm/pgtable.h b/arch/sh/include/asm/pgtable.h
index 2a011b18090..083ea068e81 100644
--- a/arch/sh/include/asm/pgtable.h
+++ b/arch/sh/include/asm/pgtable.h
@@ -12,7 +12,11 @@
#ifndef __ASM_SH_PGTABLE_H
#define __ASM_SH_PGTABLE_H
-#include <asm-generic/pgtable-nopmd.h>
+#ifdef CONFIG_X2TLB
+#include <asm/pgtable-3level.h>
+#else
+#include <asm/pgtable-2level.h>
+#endif
#include <asm/page.h>
#ifndef __ASSEMBLY__
@@ -36,6 +40,12 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
#define NEFF_SIGN (1LL << (NEFF - 1))
#define NEFF_MASK (-1LL << NEFF)
+static inline unsigned long long neff_sign_extend(unsigned long val)
+{
+ unsigned long long extended = val;
+ return (extended & NEFF_SIGN) ? (extended | NEFF_MASK) : extended;
+}
+
#ifdef CONFIG_29BIT
#define NPHYS 29
#else
@@ -45,37 +55,27 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
#define NPHYS_SIGN (1LL << (NPHYS - 1))
#define NPHYS_MASK (-1LL << NPHYS)
-/*
- * traditional two-level paging structure
- */
-/* PTE bits */
-#if defined(CONFIG_X2TLB) || defined(CONFIG_SUPERH64)
-# define PTE_MAGNITUDE 3 /* 64-bit PTEs on extended mode SH-X2 TLB */
-#else
-# define PTE_MAGNITUDE 2 /* 32-bit PTEs */
-#endif
-#define PTE_SHIFT PAGE_SHIFT
-#define PTE_BITS (PTE_SHIFT - PTE_MAGNITUDE)
-
-/* PGD bits */
-#define PGDIR_SHIFT (PTE_SHIFT + PTE_BITS)
#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
#define PGDIR_MASK (~(PGDIR_SIZE-1))
/* Entries per level */
#define PTRS_PER_PTE (PAGE_SIZE / (1 << PTE_MAGNITUDE))
-#define PTRS_PER_PGD (PAGE_SIZE / sizeof(pgd_t))
-#define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE)
#define FIRST_USER_ADDRESS 0
-#ifdef CONFIG_32BIT
-#define PHYS_ADDR_MASK 0xffffffff
-#else
-#define PHYS_ADDR_MASK 0x1fffffff
-#endif
+#define PHYS_ADDR_MASK29 0x1fffffff
+#define PHYS_ADDR_MASK32 0xffffffff
+
+static inline unsigned long phys_addr_mask(void)
+{
+ /* Is the MMU in 29bit mode? */
+ if (__in_29bit_mode())
+ return PHYS_ADDR_MASK29;
-#define PTE_PHYS_MASK (PHYS_ADDR_MASK & PAGE_MASK)
+ return PHYS_ADDR_MASK32;
+}
+
+#define PTE_PHYS_MASK (phys_addr_mask() & PAGE_MASK)
#define PTE_FLAGS_MASK (~(PTE_PHYS_MASK) << PAGE_SHIFT)
#ifdef CONFIG_SUPERH32
@@ -129,35 +129,36 @@ typedef pte_t *pte_addr_t;
#define pte_pfn(x) ((unsigned long)(((x).pte_low >> PAGE_SHIFT)))
/*
- * No page table caches to initialise
+ * Initialise the page table caches
*/
-#define pgtable_cache_init() do { } while (0)
-
-#if !defined(CONFIG_CACHE_OFF) && (defined(CONFIG_CPU_SH4) || \
- defined(CONFIG_SH7705_CACHE_32KB))
-struct mm_struct;
-#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
-pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
-#endif
+extern void pgtable_cache_init(void);
struct vm_area_struct;
-extern void update_mmu_cache(struct vm_area_struct * vma,
- unsigned long address, pte_t pte);
+
+extern void __update_cache(struct vm_area_struct *vma,
+ unsigned long address, pte_t pte);
+extern void __update_tlb(struct vm_area_struct *vma,
+ unsigned long address, pte_t pte);
+
+static inline void
+update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
+{
+ pte_t pte = *ptep;
+ __update_cache(vma, address, pte);
+ __update_tlb(vma, address, pte);
+}
+
extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
extern void paging_init(void);
extern void page_table_range_init(unsigned long start, unsigned long end,
pgd_t *pgd);
-#if !defined(CONFIG_CACHE_OFF) && defined(CONFIG_CPU_SH4) && defined(CONFIG_MMU)
-extern void kmap_coherent_init(void);
-#else
-#define kmap_coherent_init() do { } while (0)
-#endif
-
/* arch/sh/mm/mmap.c */
#define HAVE_ARCH_UNMAPPED_AREA
#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
+#define __HAVE_ARCH_PTE_SPECIAL
+
#include <asm-generic/pgtable.h>
#endif /* __ASM_SH_PGTABLE_H */
diff --git a/arch/sh/include/asm/pgtable_32.h b/arch/sh/include/asm/pgtable_32.h
index 72ea209195b..43528ec656b 100644
--- a/arch/sh/include/asm/pgtable_32.h
+++ b/arch/sh/include/asm/pgtable_32.h
@@ -20,7 +20,7 @@
* - Bit 9 is reserved by everyone and used by _PAGE_PROTNONE.
*
* - Bits 10 and 11 are low bits of the PPN that are reserved on >= 4K pages.
- * Bit 10 is used for _PAGE_ACCESSED, bit 11 remains unused.
+ * Bit 10 is used for _PAGE_ACCESSED, and bit 11 is used for _PAGE_SPECIAL.
*
* - On 29 bit platforms, bits 31 to 29 are used for the space attributes
* and timing control which (together with bit 0) are moved into the
@@ -52,6 +52,7 @@
#define _PAGE_PROTNONE 0x200 /* software: if not present */
#define _PAGE_ACCESSED 0x400 /* software: page referenced */
#define _PAGE_FILE _PAGE_WT /* software: pagecache or swap? */
+#define _PAGE_SPECIAL 0x800 /* software: special page */
#define _PAGE_SZ_MASK (_PAGE_SZ0 | _PAGE_SZ1)
#define _PAGE_PR_MASK (_PAGE_RW | _PAGE_USER)
@@ -70,6 +71,8 @@
#define _PAGE_EXT_KERN_WRITE 0x1000 /* EPR4-bit: Kernel space writable */
#define _PAGE_EXT_KERN_READ 0x2000 /* EPR5-bit: Kernel space readable */
+#define _PAGE_EXT_WIRED 0x4000 /* software: Wire TLB entry */
+
/* Wrapper for extended mode pgprot twiddling */
#define _PAGE_EXT(x) ((unsigned long long)(x) << 32)
@@ -86,6 +89,14 @@
#define _PAGE_PCC_ATR8 0x60000000 /* Attribute Memory space, 8 bit bus */
#define _PAGE_PCC_ATR16 0x60000001 /* Attribute Memory space, 6 bit bus */
+#ifndef CONFIG_X2TLB
+/* copy the ptea attributes */
+static inline unsigned long copy_ptea_attributes(unsigned long x)
+{
+ return ((x >> 28) & 0xe) | (x & 0x1);
+}
+#endif
+
/* Mask which drops unused bits from the PTEL value */
#if defined(CONFIG_CPU_SH3)
#define _PAGE_CLEAR_FLAGS (_PAGE_PROTNONE | _PAGE_ACCESSED| \
@@ -99,7 +110,7 @@
#define _PAGE_CLEAR_FLAGS (_PAGE_PROTNONE | _PAGE_ACCESSED | _PAGE_FILE)
#endif
-#define _PAGE_FLAGS_HARDWARE_MASK (PHYS_ADDR_MASK & ~(_PAGE_CLEAR_FLAGS))
+#define _PAGE_FLAGS_HARDWARE_MASK (phys_addr_mask() & ~(_PAGE_CLEAR_FLAGS))
/* Hardware flags, page size encoding */
#if !defined(CONFIG_MMU)
@@ -132,12 +143,14 @@
# elif defined(CONFIG_HUGETLB_PAGE_SIZE_64MB)
# define _PAGE_SZHUGE (_PAGE_EXT_ESZ2 | _PAGE_EXT_ESZ3)
# endif
+# define _PAGE_WIRED (_PAGE_EXT(_PAGE_EXT_WIRED))
#else
# if defined(CONFIG_HUGETLB_PAGE_SIZE_64K)
# define _PAGE_SZHUGE (_PAGE_SZ1)
# elif defined(CONFIG_HUGETLB_PAGE_SIZE_1MB)
# define _PAGE_SZHUGE (_PAGE_SZ0 | _PAGE_SZ1)
# endif
+# define _PAGE_WIRED (0)
#endif
/*
@@ -148,8 +161,12 @@
# define _PAGE_SZHUGE (_PAGE_FLAGS_HARD)
#endif
+/*
+ * Mask of bits that are to be preserved accross pgprot changes.
+ */
#define _PAGE_CHG_MASK \
- (PTE_MASK | _PAGE_ACCESSED | _PAGE_CACHABLE | _PAGE_DIRTY)
+ (PTE_MASK | _PAGE_ACCESSED | _PAGE_CACHABLE | \
+ _PAGE_DIRTY | _PAGE_SPECIAL)
#ifndef __ASSEMBLY__
@@ -328,10 +345,11 @@ static inline void set_pte(pte_t *ptep, pte_t pte)
#define pte_dirty(pte) ((pte).pte_low & _PAGE_DIRTY)
#define pte_young(pte) ((pte).pte_low & _PAGE_ACCESSED)
#define pte_file(pte) ((pte).pte_low & _PAGE_FILE)
-#define pte_special(pte) (0)
+#define pte_special(pte) ((pte).pte_low & _PAGE_SPECIAL)
#ifdef CONFIG_X2TLB
-#define pte_write(pte) ((pte).pte_high & _PAGE_EXT_USER_WRITE)
+#define pte_write(pte) \
+ ((pte).pte_high & (_PAGE_EXT_USER_WRITE | _PAGE_EXT_KERN_WRITE))
#else
#define pte_write(pte) ((pte).pte_low & _PAGE_RW)
#endif
@@ -345,7 +363,7 @@ static inline pte_t pte_##fn(pte_t pte) { pte.pte_##h op; return pte; }
* individually toggled (and user permissions are entirely decoupled from
* kernel permissions), we attempt to couple them a bit more sanely here.
*/
-PTE_BIT_FUNC(high, wrprotect, &= ~_PAGE_EXT_USER_WRITE);
+PTE_BIT_FUNC(high, wrprotect, &= ~(_PAGE_EXT_USER_WRITE | _PAGE_EXT_KERN_WRITE));
PTE_BIT_FUNC(high, mkwrite, |= _PAGE_EXT_USER_WRITE | _PAGE_EXT_KERN_WRITE);
PTE_BIT_FUNC(high, mkhuge, |= _PAGE_SZHUGE);
#else
@@ -358,8 +376,7 @@ PTE_BIT_FUNC(low, mkclean, &= ~_PAGE_DIRTY);
PTE_BIT_FUNC(low, mkdirty, |= _PAGE_DIRTY);
PTE_BIT_FUNC(low, mkold, &= ~_PAGE_ACCESSED);
PTE_BIT_FUNC(low, mkyoung, |= _PAGE_ACCESSED);
-
-static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
+PTE_BIT_FUNC(low, mkspecial, |= _PAGE_SPECIAL);
/*
* Macro and implementation to make a page protection as uncachable.
@@ -394,20 +411,23 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
/* to find an entry in a page-table-directory. */
#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
-#define pgd_offset(mm, address) ((mm)->pgd+pgd_index(address))
+#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
+#define __pgd_offset(address) pgd_index(address)
/* to find an entry in a kernel page-table-directory */
#define pgd_offset_k(address) pgd_offset(&init_mm, address)
+#define __pud_offset(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1))
+#define __pmd_offset(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
+
/* Find an entry in the third-level page table.. */
#define pte_index(address) ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+#define __pte_offset(address) pte_index(address)
+
#define pte_offset_kernel(dir, address) \
((pte_t *) pmd_page_vaddr(*(dir)) + pte_index(address))
#define pte_offset_map(dir, address) pte_offset_kernel(dir, address)
-#define pte_offset_map_nested(dir, address) pte_offset_kernel(dir, address)
-
#define pte_unmap(pte) do { } while (0)
-#define pte_unmap_nested(pte) do { } while (0)
#ifdef CONFIG_X2TLB
#define pte_ERROR(e) \
diff --git a/arch/sh/include/asm/pgtable_64.h b/arch/sh/include/asm/pgtable_64.h
index c78990cda55..42cb9dd5216 100644
--- a/arch/sh/include/asm/pgtable_64.h
+++ b/arch/sh/include/asm/pgtable_64.h
@@ -43,11 +43,6 @@ static __inline__ void set_pte(pte_t *pteptr, pte_t pteval)
}
#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
-static __inline__ void pmd_set(pmd_t *pmdp,pte_t *ptep)
-{
- pmd_val(*pmdp) = (unsigned long) ptep;
-}
-
/*
* PGD defines. Top level.
*/
@@ -60,6 +55,9 @@ static __inline__ void pmd_set(pmd_t *pmdp,pte_t *ptep)
/* To find an entry in a kernel PGD. */
#define pgd_offset_k(address) pgd_offset(&init_mm, address)
+#define __pud_offset(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1))
+#define __pmd_offset(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
+
/*
* PMD level access routines. Same notes as above.
*/
@@ -80,13 +78,13 @@ static __inline__ void pmd_set(pmd_t *pmdp,pte_t *ptep)
#define pte_index(address) \
((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+#define __pte_offset(address) pte_index(address)
+
#define pte_offset_kernel(dir, addr) \
((pte_t *) ((pmd_val(*(dir))) & PAGE_MASK) + pte_index((addr)))
#define pte_offset_map(dir,addr) pte_offset_kernel(dir, addr)
-#define pte_offset_map_nested(dir,addr) pte_offset_kernel(dir, addr)
#define pte_unmap(pte) do { } while (0)
-#define pte_unmap_nested(pte) do { } while (0)
#ifndef __ASSEMBLY__
#define IOBASE_VADDR 0xff000000
@@ -123,8 +121,22 @@ static __inline__ void pmd_set(pmd_t *pmdp,pte_t *ptep)
#define _PAGE_DIRTY 0x400 /* software: page accessed in write */
#define _PAGE_ACCESSED 0x800 /* software: page referenced */
+/* Wrapper for extended mode pgprot twiddling */
+#define _PAGE_EXT(x) ((unsigned long long)(x) << 32)
+
+/*
+ * We can use the sign-extended bits in the PTEL to get 32 bits of
+ * software flags. This works for now because no implementations uses
+ * anything above the PPN field.
+ */
+#define _PAGE_WIRED _PAGE_EXT(0x001) /* software: wire the tlb entry */
+#define _PAGE_SPECIAL _PAGE_EXT(0x002)
+
+#define _PAGE_CLEAR_FLAGS (_PAGE_PRESENT | _PAGE_FILE | _PAGE_SHARED | \
+ _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_WIRED)
+
/* Mask which drops software flags */
-#define _PAGE_FLAGS_HARDWARE_MASK 0xfffffffffffff3dbLL
+#define _PAGE_FLAGS_HARDWARE_MASK (NEFF_MASK & ~(_PAGE_CLEAR_FLAGS))
/*
* HugeTLB support
@@ -162,7 +174,8 @@ static __inline__ void pmd_set(pmd_t *pmdp,pte_t *ptep)
/* Default flags for a User page */
#define _PAGE_TABLE (_KERNPG_TABLE | _PAGE_USER)
-#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
+#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | \
+ _PAGE_SPECIAL)
/*
* We have full permissions (Read/Write/Execute/Shared).
@@ -198,12 +211,6 @@ static __inline__ void pmd_set(pmd_t *pmdp,pte_t *ptep)
#define pgprot_writecombine(prot) __pgprot(pgprot_val(prot) & ~_PAGE_CACHABLE)
/*
- * Handling allocation failures during page table setup.
- */
-extern void __handle_bad_pmd_kernel(pmd_t * pmd);
-#define __handle_bad_pmd(x) __handle_bad_pmd_kernel(x)
-
-/*
* PTE level access routines.
*
* Note1:
@@ -258,7 +265,7 @@ static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; }
static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WRITE; }
-static inline int pte_special(pte_t pte){ return 0; }
+static inline int pte_special(pte_t pte){ return pte_val(pte) & _PAGE_SPECIAL; }
static inline pte_t pte_wrprotect(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_WRITE)); return pte; }
static inline pte_t pte_mkclean(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_DIRTY)); return pte; }
@@ -267,8 +274,7 @@ static inline pte_t pte_mkwrite(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) |
static inline pte_t pte_mkdirty(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; }
static inline pte_t pte_mkyoung(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; }
static inline pte_t pte_mkhuge(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_SZHUGE)); return pte; }
-static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
-
+static inline pte_t pte_mkspecial(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_SPECIAL)); return pte; }
/*
* Conversion functions: convert a page and protection to a page entry.
diff --git a/arch/sh/include/asm/processor.h b/arch/sh/include/asm/processor.h
index ff7daaf9a62..c9e7cbc4768 100644
--- a/arch/sh/include/asm/processor.h
+++ b/arch/sh/include/asm/processor.h
@@ -32,7 +32,7 @@ enum cpu_type {
/* SH-4A types */
CPU_SH7763, CPU_SH7770, CPU_SH7780, CPU_SH7781, CPU_SH7785, CPU_SH7786,
- CPU_SH7723, CPU_SH7724, CPU_SHX3,
+ CPU_SH7723, CPU_SH7724, CPU_SH7757, CPU_SHX3,
/* SH4AL-DSP types */
CPU_SH7343, CPU_SH7722, CPU_SH7366,
@@ -44,6 +44,17 @@ enum cpu_type {
CPU_SH_NONE
};
+enum cpu_family {
+ CPU_FAMILY_SH2,
+ CPU_FAMILY_SH2A,
+ CPU_FAMILY_SH3,
+ CPU_FAMILY_SH4,
+ CPU_FAMILY_SH4A,
+ CPU_FAMILY_SH4AL_DSP,
+ CPU_FAMILY_SH5,
+ CPU_FAMILY_UNKNOWN,
+};
+
/*
* TLB information structure
*
@@ -61,7 +72,7 @@ struct tlb_info {
};
struct sh_cpuinfo {
- unsigned int type;
+ unsigned int type, family;
int cut_major, cut_minor;
unsigned long loops_per_jiffy;
unsigned long asid_cache;
@@ -74,6 +85,11 @@ struct sh_cpuinfo {
struct tlb_info itlb;
struct tlb_info dtlb;
+#ifdef CONFIG_SMP
+ struct task_struct *idle;
+#endif
+
+ unsigned int phys_bits;
unsigned long flags;
} __attribute__ ((aligned(L1_CACHE_BYTES)));
@@ -87,13 +103,37 @@ extern struct sh_cpuinfo cpu_data[];
/* Forward decl */
struct seq_operations;
+struct task_struct;
extern struct pt_regs fake_swapper_regs;
+extern void cpu_init(void);
+extern void cpu_probe(void);
+
+/* arch/sh/kernel/process.c */
+extern unsigned int xstate_size;
+extern void free_thread_xstate(struct task_struct *);
+extern struct kmem_cache *task_xstate_cachep;
+
+/* arch/sh/mm/alignment.c */
+extern int get_unalign_ctl(struct task_struct *, unsigned long addr);
+extern int set_unalign_ctl(struct task_struct *, unsigned int val);
+
+#define GET_UNALIGN_CTL(tsk, addr) get_unalign_ctl((tsk), (addr))
+#define SET_UNALIGN_CTL(tsk, val) set_unalign_ctl((tsk), (val))
+
+/* arch/sh/mm/init.c */
+extern unsigned int mem_init_done;
+
/* arch/sh/kernel/setup.c */
const char *get_cpu_subtype(struct sh_cpuinfo *c);
extern const struct seq_operations cpuinfo_op;
+/* thread_struct flags */
+#define SH_THREAD_UAC_NOPRINT (1 << 0)
+#define SH_THREAD_UAC_SIGBUS (1 << 1)
+#define SH_THREAD_UAC_MASK (SH_THREAD_UAC_NOPRINT | SH_THREAD_UAC_SIGBUS)
+
/* processor boot mode configuration */
#define MODE_PIN0 (1 << 0)
#define MODE_PIN1 (1 << 1)
diff --git a/arch/sh/include/asm/processor_32.h b/arch/sh/include/asm/processor_32.h
index 9a8714945dc..e3c73cdd8c9 100644
--- a/arch/sh/include/asm/processor_32.h
+++ b/arch/sh/include/asm/processor_32.h
@@ -13,7 +13,7 @@
#include <linux/linkage.h>
#include <asm/page.h>
#include <asm/types.h>
-#include <asm/ptrace.h>
+#include <asm/hw_breakpoint.h>
/*
* Default implementation of macro that returns current
@@ -26,8 +26,6 @@
#define CCN_CVR 0xff000040
#define CCN_PRR 0xff000044
-asmlinkage void __init sh_cpu_init(void);
-
/*
* User space process size: 2GB.
*
@@ -56,6 +54,7 @@ asmlinkage void __init sh_cpu_init(void);
#define SR_DSP 0x00001000
#define SR_IMASK 0x000000f0
#define SR_FD 0x00008000
+#define SR_MD 0x40000000
/*
* DSP structure and data
@@ -89,9 +88,9 @@ struct sh_fpu_soft_struct {
unsigned long entry_pc;
};
-union sh_fpu_union {
- struct sh_fpu_hard_struct hard;
- struct sh_fpu_soft_struct soft;
+union thread_xstate {
+ struct sh_fpu_hard_struct hardfpu;
+ struct sh_fpu_soft_struct softfpu;
};
struct thread_struct {
@@ -99,44 +98,36 @@ struct thread_struct {
unsigned long sp;
unsigned long pc;
- /* Hardware debugging registers */
- unsigned long ubc_pc;
+ /* Various thread flags, see SH_THREAD_xxx */
+ unsigned long flags;
- /* floating point info */
- union sh_fpu_union fpu;
+ /* Save middle states of ptrace breakpoints */
+ struct perf_event *ptrace_bps[HBP_NUM];
#ifdef CONFIG_SH_DSP
/* Dsp status information */
struct sh_dsp_struct dsp_status;
#endif
-};
-/* Count of active tasks with UBC settings */
-extern int ubc_usercnt;
+ /* Extended processor state */
+ union thread_xstate *xstate;
+};
#define INIT_THREAD { \
.sp = sizeof(init_stack) + (long) &init_stack, \
+ .flags = 0, \
}
-/*
- * Do necessary setup to start up a newly executed thread.
- */
-#define start_thread(_regs, new_pc, new_sp) \
- set_fs(USER_DS); \
- _regs->pr = 0; \
- _regs->sr = SR_FD; /* User mode. */ \
- _regs->pc = new_pc; \
- _regs->regs[15] = new_sp
-
/* Forward declaration, a strange C thing */
struct task_struct;
-struct mm_struct;
+
+extern void start_thread(struct pt_regs *regs, unsigned long new_pc, unsigned long new_sp);
/* Free all resources held by a thread. */
extern void release_thread(struct task_struct *);
/* Prepare to copy thread state - unlazy all lazy status */
-#define prepare_to_copy(tsk) do { } while (0)
+void prepare_to_copy(struct task_struct *tsk);
/*
* create a kernel thread without removing it from tasklists
@@ -202,18 +193,19 @@ extern unsigned long get_wchan(struct task_struct *p);
#define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc)
#define KSTK_ESP(tsk) (task_pt_regs(tsk)->regs[15])
-#define user_stack_pointer(_regs) ((_regs)->regs[15])
-
#if defined(CONFIG_CPU_SH2A) || defined(CONFIG_CPU_SH4)
#define PREFETCH_STRIDE L1_CACHE_BYTES
#define ARCH_HAS_PREFETCH
#define ARCH_HAS_PREFETCHW
static inline void prefetch(void *x)
{
- __asm__ __volatile__ ("pref @%0\n\t" : : "r" (x) : "memory");
+ __builtin_prefetch(x, 0, 3);
}
-#define prefetchw(x) prefetch(x)
+static inline void prefetchw(void *x)
+{
+ __builtin_prefetch(x, 1, 3);
+}
#endif
#endif /* __KERNEL__ */
diff --git a/arch/sh/include/asm/processor_64.h b/arch/sh/include/asm/processor_64.h
index 5727d31b0cc..2a541ddb5a1 100644
--- a/arch/sh/include/asm/processor_64.h
+++ b/arch/sh/include/asm/processor_64.h
@@ -17,7 +17,6 @@
#include <linux/compiler.h>
#include <asm/page.h>
#include <asm/types.h>
-#include <asm/ptrace.h>
#include <cpu/registers.h>
/*
@@ -87,26 +86,31 @@ struct sh_fpu_hard_struct {
/* long status; * software status information */
};
-#if 0
/* Dummy fpu emulator */
struct sh_fpu_soft_struct {
- unsigned long long fp_regs[32];
+ unsigned long fp_regs[64];
unsigned int fpscr;
unsigned char lookahead;
unsigned long entry_pc;
};
-#endif
-union sh_fpu_union {
- struct sh_fpu_hard_struct hard;
- /* 'hard' itself only produces 32 bit alignment, yet we need
- to access it using 64 bit load/store as well. */
+union thread_xstate {
+ struct sh_fpu_hard_struct hardfpu;
+ struct sh_fpu_soft_struct softfpu;
+ /*
+ * The structure definitions only produce 32 bit alignment, yet we need
+ * to access them using 64 bit load/store as well.
+ */
unsigned long long alignment_dummy;
};
struct thread_struct {
unsigned long sp;
unsigned long pc;
+
+ /* Various thread flags, see SH_THREAD_xxx */
+ unsigned long flags;
+
/* This stores the address of the pt_regs built during a context
switch, or of the register save area built for a kernel mode
exception. It is used for backtracing the stack of a sleeping task
@@ -122,7 +126,7 @@ struct thread_struct {
/* Hardware debugging registers may come here */
/* floating point info */
- union sh_fpu_union fpu;
+ union thread_xstate *xstate;
};
#define INIT_MMAP \
@@ -137,7 +141,7 @@ struct thread_struct {
.trap_no = 0, \
.error_code = 0, \
.address = 0, \
- .fpu = { { { 0, } }, } \
+ .flags = 0, \
}
/*
@@ -226,7 +230,5 @@ extern unsigned long get_wchan(struct task_struct *p);
#define KSTK_EIP(tsk) ((tsk)->thread.pc)
#define KSTK_ESP(tsk) ((tsk)->thread.sp)
-#define user_stack_pointer(_regs) ((_regs)->regs[15])
-
#endif /* __ASSEMBLY__ */
#endif /* __ASM_SH_PROCESSOR_64_H */
diff --git a/arch/sh/include/asm/ptrace.h b/arch/sh/include/asm/ptrace.h
index 1dc12cb44a2..de167d3a1a8 100644
--- a/arch/sh/include/asm/ptrace.h
+++ b/arch/sh/include/asm/ptrace.h
@@ -3,90 +3,7 @@
/*
* Copyright (C) 1999, 2000 Niibe Yutaka
- *
- */
-#if defined(__SH5__)
-struct pt_regs {
- unsigned long long pc;
- unsigned long long sr;
- long long syscall_nr;
- unsigned long long regs[63];
- unsigned long long tregs[8];
- unsigned long long pad[2];
-};
-#else
-/*
- * GCC defines register number like this:
- * -----------------------------
- * 0 - 15 are integer registers
- * 17 - 22 are control/special registers
- * 24 - 39 fp registers
- * 40 - 47 xd registers
- * 48 - fpscr register
- * -----------------------------
- *
- * We follows above, except:
- * 16 --- program counter (PC)
- * 22 --- syscall #
- * 23 --- floating point communication register
- */
-#define REG_REG0 0
-#define REG_REG15 15
-
-#define REG_PC 16
-
-#define REG_PR 17
-#define REG_SR 18
-#define REG_GBR 19
-#define REG_MACH 20
-#define REG_MACL 21
-
-#define REG_SYSCALL 22
-
-#define REG_FPREG0 23
-#define REG_FPREG15 38
-#define REG_XFREG0 39
-#define REG_XFREG15 54
-
-#define REG_FPSCR 55
-#define REG_FPUL 56
-
-/*
- * This struct defines the way the registers are stored on the
- * kernel stack during a system call or other kernel entry.
- */
-struct pt_regs {
- unsigned long regs[16];
- unsigned long pc;
- unsigned long pr;
- unsigned long sr;
- unsigned long gbr;
- unsigned long mach;
- unsigned long macl;
- long tra;
-};
-
-/*
- * This struct defines the way the DSP registers are stored on the
- * kernel stack during a system call or other kernel entry.
*/
-struct pt_dspregs {
- unsigned long a1;
- unsigned long a0g;
- unsigned long a1g;
- unsigned long m0;
- unsigned long m1;
- unsigned long a0;
- unsigned long x0;
- unsigned long x1;
- unsigned long y0;
- unsigned long y1;
- unsigned long dsr;
- unsigned long rs;
- unsigned long re;
- unsigned long mod;
-};
-#endif
#define PTRACE_GETREGS 12 /* General registers */
#define PTRACE_SETREGS 13
@@ -102,27 +19,113 @@ struct pt_dspregs {
#define PTRACE_GETDSPREGS 55 /* DSP registers */
#define PTRACE_SETDSPREGS 56
-#define PT_TEXT_END_ADDR 240
-#define PT_TEXT_ADDR 244 /* &(struct user)->start_code */
-#define PT_DATA_ADDR 248 /* &(struct user)->start_data */
+#define PT_TEXT_END_ADDR 240
+#define PT_TEXT_ADDR 244 /* &(struct user)->start_code */
+#define PT_DATA_ADDR 248 /* &(struct user)->start_data */
#define PT_TEXT_LEN 252
+#if defined(__SH5__) || defined(CONFIG_CPU_SH5)
+#include "ptrace_64.h"
+#else
+#include "ptrace_32.h"
+#endif
+
#ifdef __KERNEL__
+
+#include <linux/stringify.h>
+#include <linux/stddef.h>
+#include <linux/thread_info.h>
#include <asm/addrspace.h>
+#include <asm/page.h>
+#include <asm/system.h>
#define user_mode(regs) (((regs)->sr & 0x40000000)==0)
+#define user_stack_pointer(_regs) ((unsigned long)(_regs)->regs[15])
+#define kernel_stack_pointer(_regs) ((unsigned long)(_regs)->regs[15])
#define instruction_pointer(regs) ((unsigned long)(regs)->pc)
extern void show_regs(struct pt_regs *);
+#define arch_has_single_step() (1)
+
/*
- * These are defined as per linux/ptrace.h.
+ * kprobe-based event tracer support
*/
-struct task_struct;
+struct pt_regs_offset {
+ const char *name;
+ int offset;
+};
-#define arch_has_single_step() (1)
-extern void user_enable_single_step(struct task_struct *);
-extern void user_disable_single_step(struct task_struct *);
+#define REG_OFFSET_NAME(r) {.name = #r, .offset = offsetof(struct pt_regs, r)}
+#define REGS_OFFSET_NAME(num) \
+ {.name = __stringify(r##num), .offset = offsetof(struct pt_regs, regs[num])}
+#define TREGS_OFFSET_NAME(num) \
+ {.name = __stringify(tr##num), .offset = offsetof(struct pt_regs, tregs[num])}
+#define REG_OFFSET_END {.name = NULL, .offset = 0}
+
+/* Query offset/name of register from its name/offset */
+extern int regs_query_register_offset(const char *name);
+extern const char *regs_query_register_name(unsigned int offset);
+
+extern const struct pt_regs_offset regoffset_table[];
+
+/**
+ * regs_get_register() - get register value from its offset
+ * @regs: pt_regs from which register value is gotten.
+ * @offset: offset number of the register.
+ *
+ * regs_get_register returns the value of a register. The @offset is the
+ * offset of the register in struct pt_regs address which specified by @regs.
+ * If @offset is bigger than MAX_REG_OFFSET, this returns 0.
+ */
+static inline unsigned long regs_get_register(struct pt_regs *regs,
+ unsigned int offset)
+{
+ if (unlikely(offset > MAX_REG_OFFSET))
+ return 0;
+ return *(unsigned long *)((unsigned long)regs + offset);
+}
+
+/**
+ * regs_within_kernel_stack() - check the address in the stack
+ * @regs: pt_regs which contains kernel stack pointer.
+ * @addr: address which is checked.
+ *
+ * regs_within_kernel_stack() checks @addr is within the kernel stack page(s).
+ * If @addr is within the kernel stack, it returns true. If not, returns false.
+ */
+static inline int regs_within_kernel_stack(struct pt_regs *regs,
+ unsigned long addr)
+{
+ return ((addr & ~(THREAD_SIZE - 1)) ==
+ (kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1)));
+}
+
+/**
+ * regs_get_kernel_stack_nth() - get Nth entry of the stack
+ * @regs: pt_regs which contains kernel stack pointer.
+ * @n: stack entry number.
+ *
+ * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
+ * is specified by @regs. If the @n th entry is NOT in the kernel stack,
+ * this returns 0.
+ */
+static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
+ unsigned int n)
+{
+ unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs);
+ addr += n;
+ if (regs_within_kernel_stack(regs, (unsigned long)addr))
+ return *addr;
+ else
+ return 0;
+}
+
+struct perf_event;
+struct perf_sample_data;
+
+extern void ptrace_triggered(struct perf_event *bp, int nmi,
+ struct perf_sample_data *data, struct pt_regs *regs);
#define task_pt_regs(task) \
((struct pt_regs *) (task_stack_page(task) + THREAD_SIZE) - 1)
@@ -131,10 +134,8 @@ static inline unsigned long profile_pc(struct pt_regs *regs)
{
unsigned long pc = instruction_pointer(regs);
-#ifdef P2SEG
- if (pc >= P2SEG && pc < P3SEG)
- pc -= 0x20000000;
-#endif
+ if (virt_addr_uncached(pc))
+ return CAC_ADDR(pc);
return pc;
}
diff --git a/arch/sh/include/asm/ptrace_32.h b/arch/sh/include/asm/ptrace_32.h
new file mode 100644
index 00000000000..6c2239cca1a
--- /dev/null
+++ b/arch/sh/include/asm/ptrace_32.h
@@ -0,0 +1,83 @@
+#ifndef __ASM_SH_PTRACE_32_H
+#define __ASM_SH_PTRACE_32_H
+
+/*
+ * GCC defines register number like this:
+ * -----------------------------
+ * 0 - 15 are integer registers
+ * 17 - 22 are control/special registers
+ * 24 - 39 fp registers
+ * 40 - 47 xd registers
+ * 48 - fpscr register
+ * -----------------------------
+ *
+ * We follows above, except:
+ * 16 --- program counter (PC)
+ * 22 --- syscall #
+ * 23 --- floating point communication register
+ */
+#define REG_REG0 0
+#define REG_REG15 15
+
+#define REG_PC 16
+
+#define REG_PR 17
+#define REG_SR 18
+#define REG_GBR 19
+#define REG_MACH 20
+#define REG_MACL 21
+
+#define REG_SYSCALL 22
+
+#define REG_FPREG0 23
+#define REG_FPREG15 38
+#define REG_XFREG0 39
+#define REG_XFREG15 54
+
+#define REG_FPSCR 55
+#define REG_FPUL 56
+
+/*
+ * This struct defines the way the registers are stored on the
+ * kernel stack during a system call or other kernel entry.
+ */
+struct pt_regs {
+ unsigned long regs[16];
+ unsigned long pc;
+ unsigned long pr;
+ unsigned long sr;
+ unsigned long gbr;
+ unsigned long mach;
+ unsigned long macl;
+ long tra;
+};
+
+/*
+ * This struct defines the way the DSP registers are stored on the
+ * kernel stack during a system call or other kernel entry.
+ */
+struct pt_dspregs {
+ unsigned long a1;
+ unsigned long a0g;
+ unsigned long a1g;
+ unsigned long m0;
+ unsigned long m1;
+ unsigned long a0;
+ unsigned long x0;
+ unsigned long x1;
+ unsigned long y0;
+ unsigned long y1;
+ unsigned long dsr;
+ unsigned long rs;
+ unsigned long re;
+ unsigned long mod;
+};
+
+#ifdef __KERNEL__
+
+#define MAX_REG_OFFSET offsetof(struct pt_regs, tra)
+#define regs_return_value(_regs) ((_regs)->regs[0])
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_SH_PTRACE_32_H */
diff --git a/arch/sh/include/asm/ptrace_64.h b/arch/sh/include/asm/ptrace_64.h
new file mode 100644
index 00000000000..bf9be7764d6
--- /dev/null
+++ b/arch/sh/include/asm/ptrace_64.h
@@ -0,0 +1,20 @@
+#ifndef __ASM_SH_PTRACE_64_H
+#define __ASM_SH_PTRACE_64_H
+
+struct pt_regs {
+ unsigned long long pc;
+ unsigned long long sr;
+ long long syscall_nr;
+ unsigned long long regs[63];
+ unsigned long long tregs[8];
+ unsigned long long pad[2];
+};
+
+#ifdef __KERNEL__
+
+#define MAX_REG_OFFSET offsetof(struct pt_regs, tregs[7])
+#define regs_return_value(_regs) ((_regs)->regs[3])
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_SH_PTRACE_64_H */
diff --git a/arch/sh/include/asm/reboot.h b/arch/sh/include/asm/reboot.h
new file mode 100644
index 00000000000..b3da0c63fc3
--- /dev/null
+++ b/arch/sh/include/asm/reboot.h
@@ -0,0 +1,21 @@
+#ifndef __ASM_SH_REBOOT_H
+#define __ASM_SH_REBOOT_H
+
+#include <linux/kdebug.h>
+
+struct pt_regs;
+
+struct machine_ops {
+ void (*restart)(char *cmd);
+ void (*halt)(void);
+ void (*power_off)(void);
+ void (*shutdown)(void);
+ void (*crash_shutdown)(struct pt_regs *);
+};
+
+extern struct machine_ops machine_ops;
+
+/* arch/sh/kernel/machine_kexec.c */
+void native_machine_crash_shutdown(struct pt_regs *regs);
+
+#endif /* __ASM_SH_REBOOT_H */
diff --git a/arch/sh/include/asm/romimage-macros.h b/arch/sh/include/asm/romimage-macros.h
new file mode 100644
index 00000000000..ae17a150bb5
--- /dev/null
+++ b/arch/sh/include/asm/romimage-macros.h
@@ -0,0 +1,73 @@
+#ifndef __ROMIMAGE_MACRO_H
+#define __ROMIMAGE_MACRO_H
+
+/* The LIST command is used to include comments in the script */
+.macro LIST comment
+.endm
+
+/* The ED command is used to write a 32-bit word */
+.macro ED, addr, data
+ mov.l 1f, r1
+ mov.l 2f, r0
+ mov.l r0, @r1
+ bra 3f
+ nop
+ .align 2
+1 : .long \addr
+2 : .long \data
+3 :
+.endm
+
+/* The EW command is used to write a 16-bit word */
+.macro EW, addr, data
+ mov.l 1f, r1
+ mov.l 2f, r0
+ mov.w r0, @r1
+ bra 3f
+ nop
+ .align 2
+1 : .long \addr
+2 : .long \data
+3 :
+.endm
+
+/* The EB command is used to write an 8-bit word */
+.macro EB, addr, data
+ mov.l 1f, r1
+ mov.l 2f, r0
+ mov.b r0, @r1
+ bra 3f
+ nop
+ .align 2
+1 : .long \addr
+2 : .long \data
+3 :
+.endm
+
+/* The WAIT command is used to delay the execution */
+.macro WAIT, time
+ mov.l 2f, r3
+1 :
+ nop
+ tst r3, r3
+ bf/s 1b
+ dt r3
+ bra 3f
+ nop
+ .align 2
+2 : .long \time * 100
+3 :
+.endm
+
+/* The DD command is used to read a 32-bit word */
+.macro DD, addr, addr2, nr
+ mov.l 1f, r1
+ mov.l @r1, r0
+ bra 2f
+ nop
+ .align 2
+1 : .long \addr
+2 :
+.endm
+
+#endif /* __ROMIMAGE_MACRO_H */
diff --git a/arch/sh/include/asm/rwsem.h b/arch/sh/include/asm/rwsem.h
index 1987f3ea7f1..06e2251a5e4 100644
--- a/arch/sh/include/asm/rwsem.h
+++ b/arch/sh/include/asm/rwsem.h
@@ -41,7 +41,7 @@ struct rw_semaphore {
#endif
#define __RWSEM_INITIALIZER(name) \
- { RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, \
+ { RWSEM_UNLOCKED_VALUE, __SPIN_LOCK_UNLOCKED((name).wait_lock), \
LIST_HEAD_INIT((name).wait_list) \
__RWSEM_DEP_MAP_INIT(name) }
diff --git a/arch/sh/include/asm/scatterlist.h b/arch/sh/include/asm/scatterlist.h
index 327cc2e4c97..98dfc3510f1 100644
--- a/arch/sh/include/asm/scatterlist.h
+++ b/arch/sh/include/asm/scatterlist.h
@@ -1,8 +1,6 @@
#ifndef __ASM_SH_SCATTERLIST_H
#define __ASM_SH_SCATTERLIST_H
-#define ISA_DMA_THRESHOLD PHYS_ADDR_MASK
-
#include <asm-generic/scatterlist.h>
#endif /* __ASM_SH_SCATTERLIST_H */
diff --git a/arch/sh/include/asm/sections.h b/arch/sh/include/asm/sections.h
index 01a4076a371..a78701da775 100644
--- a/arch/sh/include/asm/sections.h
+++ b/arch/sh/include/asm/sections.h
@@ -7,6 +7,7 @@ extern void __nosave_begin, __nosave_end;
extern long __machvec_start, __machvec_end;
extern char __uncached_start, __uncached_end;
extern char _ebss[];
+extern char __start_eh_frame[], __stop_eh_frame[];
#endif /* __ASM_SH_SECTIONS_H */
diff --git a/arch/sh/include/asm/setup.h b/arch/sh/include/asm/setup.h
index ce3743599b2..01fa17a3d75 100644
--- a/arch/sh/include/asm/setup.h
+++ b/arch/sh/include/asm/setup.h
@@ -18,8 +18,8 @@
/* ... */
#define COMMAND_LINE ((char *) (PARAM+0x100))
-int setup_early_printk(char *);
void sh_mv_setup(void);
+void check_for_initrd(void);
#endif /* __KERNEL__ */
diff --git a/arch/sh/include/asm/sh_bios.h b/arch/sh/include/asm/sh_bios.h
index d9c96d7cf6c..95714c28422 100644
--- a/arch/sh/include/asm/sh_bios.h
+++ b/arch/sh/include/asm/sh_bios.h
@@ -1,18 +1,27 @@
#ifndef __ASM_SH_BIOS_H
#define __ASM_SH_BIOS_H
+#ifdef CONFIG_SH_STANDARD_BIOS
+
/*
* Copyright (C) 2000 Greg Banks, Mitch Davis
* C API to interface to the standard LinuxSH BIOS
* usually from within the early stages of kernel boot.
*/
-
-
extern void sh_bios_console_write(const char *buf, unsigned int len);
-extern void sh_bios_char_out(char ch);
extern void sh_bios_gdb_detach(void);
extern void sh_bios_get_node_addr(unsigned char *node_addr);
extern void sh_bios_shutdown(unsigned int how);
+extern void sh_bios_vbr_init(void);
+extern void sh_bios_vbr_reload(void);
+
+#else
+
+static inline void sh_bios_vbr_init(void) { }
+static inline void sh_bios_vbr_reload(void) { }
+
+#endif /* CONFIG_SH_STANDARD_BIOS */
+
#endif /* __ASM_SH_BIOS_H */
diff --git a/arch/sh/include/asm/sh_eth.h b/arch/sh/include/asm/sh_eth.h
index bb832584f3c..f739061e2ee 100644
--- a/arch/sh/include/asm/sh_eth.h
+++ b/arch/sh/include/asm/sh_eth.h
@@ -6,6 +6,10 @@ enum {EDMAC_LITTLE_ENDIAN, EDMAC_BIG_ENDIAN};
struct sh_eth_plat_data {
int phy;
int edmac_endian;
+
+ unsigned char mac_addr[6];
+ unsigned no_ether_link:1;
+ unsigned ether_link_active_low:1;
};
#endif
diff --git a/arch/sh/include/asm/sh_keysc.h b/arch/sh/include/asm/sh_keysc.h
deleted file mode 100644
index b5a4dd5a972..00000000000
--- a/arch/sh/include/asm/sh_keysc.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef __ASM_KEYSC_H__
-#define __ASM_KEYSC_H__
-
-#define SH_KEYSC_MAXKEYS 30
-
-struct sh_keysc_info {
- enum { SH_KEYSC_MODE_1, SH_KEYSC_MODE_2, SH_KEYSC_MODE_3 } mode;
- int scan_timing; /* 0 -> 7, see KYCR1, SCN[2:0] */
- int delay;
- int keycodes[SH_KEYSC_MAXKEYS];
-};
-
-#endif /* __ASM_KEYSC_H__ */
diff --git a/arch/sh/include/asm/siu.h b/arch/sh/include/asm/siu.h
new file mode 100644
index 00000000000..1d95c78808d
--- /dev/null
+++ b/arch/sh/include/asm/siu.h
@@ -0,0 +1,24 @@
+/*
+ * platform header for the SIU ASoC driver
+ *
+ * Copyright (C) 2009-2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef ASM_SIU_H
+#define ASM_SIU_H
+
+struct device;
+
+struct siu_platform {
+ struct device *dma_dev;
+ unsigned int dma_slave_tx_a;
+ unsigned int dma_slave_rx_a;
+ unsigned int dma_slave_tx_b;
+ unsigned int dma_slave_rx_b;
+};
+
+#endif /* ASM_SIU_H */
diff --git a/arch/sh/include/asm/sizes.h b/arch/sh/include/asm/sizes.h
index 3a1fb97770f..0b9fe2d5c36 100644
--- a/arch/sh/include/asm/sizes.h
+++ b/arch/sh/include/asm/sizes.h
@@ -32,6 +32,7 @@
#define SZ_512 0x00000200
#define SZ_1K 0x00000400
+#define SZ_2K 0x00000800
#define SZ_4K 0x00001000
#define SZ_8K 0x00002000
#define SZ_16K 0x00004000
diff --git a/arch/sh/include/asm/smp-ops.h b/arch/sh/include/asm/smp-ops.h
new file mode 100644
index 00000000000..c590f76856f
--- /dev/null
+++ b/arch/sh/include/asm/smp-ops.h
@@ -0,0 +1,51 @@
+#ifndef __ASM_SH_SMP_OPS_H
+#define __ASM_SH_SMP_OPS_H
+
+struct plat_smp_ops {
+ void (*smp_setup)(void);
+ unsigned int (*smp_processor_id)(void);
+ void (*prepare_cpus)(unsigned int max_cpus);
+ void (*start_cpu)(unsigned int cpu, unsigned long entry_point);
+ void (*send_ipi)(unsigned int cpu, unsigned int message);
+ int (*cpu_disable)(unsigned int cpu);
+ void (*cpu_die)(unsigned int cpu);
+ void (*play_dead)(void);
+};
+
+extern struct plat_smp_ops *mp_ops;
+extern struct plat_smp_ops shx3_smp_ops;
+
+#ifdef CONFIG_SMP
+
+static inline void plat_smp_setup(void)
+{
+ BUG_ON(!mp_ops);
+ mp_ops->smp_setup();
+}
+
+static inline void play_dead(void)
+{
+ mp_ops->play_dead();
+}
+
+extern void register_smp_ops(struct plat_smp_ops *ops);
+
+#else
+
+static inline void plat_smp_setup(void)
+{
+ /* UP, nothing to do ... */
+}
+
+static inline void register_smp_ops(struct plat_smp_ops *ops)
+{
+}
+
+static inline void play_dead(void)
+{
+ BUG();
+}
+
+#endif /* CONFIG_SMP */
+
+#endif /* __ASM_SH_SMP_OPS_H */
diff --git a/arch/sh/include/asm/smp.h b/arch/sh/include/asm/smp.h
index ca64f43abe6..9070d943ddd 100644
--- a/arch/sh/include/asm/smp.h
+++ b/arch/sh/include/asm/smp.h
@@ -3,15 +3,16 @@
#include <linux/bitops.h>
#include <linux/cpumask.h>
+#include <asm/smp-ops.h>
#ifdef CONFIG_SMP
#include <linux/spinlock.h>
#include <asm/atomic.h>
#include <asm/current.h>
+#include <asm/percpu.h>
#define raw_smp_processor_id() (current_thread_info()->cpu)
-#define hard_smp_processor_id() plat_smp_processor_id()
/* Map from cpu id to sequential logical cpu number. */
extern int __cpu_number_map[NR_CPUS];
@@ -30,21 +31,43 @@ enum {
SMP_MSG_NR, /* must be last */
};
+DECLARE_PER_CPU(int, cpu_state);
+
void smp_message_recv(unsigned int msg);
void smp_timer_broadcast(const struct cpumask *mask);
void local_timer_interrupt(void);
void local_timer_setup(unsigned int cpu);
-
-void plat_smp_setup(void);
-void plat_prepare_cpus(unsigned int max_cpus);
-int plat_smp_processor_id(void);
-void plat_start_cpu(unsigned int cpu, unsigned long entry_point);
-void plat_send_ipi(unsigned int cpu, unsigned int message);
+void local_timer_stop(unsigned int cpu);
void arch_send_call_function_single_ipi(int cpu);
-extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
-#define arch_send_call_function_ipi_mask arch_send_call_function_ipi_mask
+void arch_send_call_function_ipi_mask(const struct cpumask *mask);
+
+void native_play_dead(void);
+void native_cpu_die(unsigned int cpu);
+int native_cpu_disable(unsigned int cpu);
+
+#ifdef CONFIG_HOTPLUG_CPU
+void play_dead_common(void);
+extern int __cpu_disable(void);
+
+static inline void __cpu_die(unsigned int cpu)
+{
+ extern struct plat_smp_ops *mp_ops; /* private */
+
+ mp_ops->cpu_die(cpu);
+}
+#endif
+
+static inline int hard_smp_processor_id(void)
+{
+ extern struct plat_smp_ops *mp_ops; /* private */
+
+ if (!mp_ops)
+ return 0; /* boot CPU */
+
+ return mp_ops->smp_processor_id();
+}
#else
diff --git a/arch/sh/include/asm/spinlock.h b/arch/sh/include/asm/spinlock.h
index a28c9f0053f..bdc0f3b6c56 100644
--- a/arch/sh/include/asm/spinlock.h
+++ b/arch/sh/include/asm/spinlock.h
@@ -23,10 +23,10 @@
* Your basic SMP spinlocks, allowing only a single CPU anywhere
*/
-#define __raw_spin_is_locked(x) ((x)->lock <= 0)
-#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
-#define __raw_spin_unlock_wait(x) \
- do { while (__raw_spin_is_locked(x)) cpu_relax(); } while (0)
+#define arch_spin_is_locked(x) ((x)->lock <= 0)
+#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)
+#define arch_spin_unlock_wait(x) \
+ do { while (arch_spin_is_locked(x)) cpu_relax(); } while (0)
/*
* Simple spin lock operations. There are two variants, one clears IRQ's
@@ -34,14 +34,14 @@
*
* We make no fairness assumptions. They have a cost.
*/
-static inline void __raw_spin_lock(raw_spinlock_t *lock)
+static inline void arch_spin_lock(arch_spinlock_t *lock)
{
unsigned long tmp;
unsigned long oldval;
__asm__ __volatile__ (
"1: \n\t"
- "movli.l @%2, %0 ! __raw_spin_lock \n\t"
+ "movli.l @%2, %0 ! arch_spin_lock \n\t"
"mov %0, %1 \n\t"
"mov #0, %0 \n\t"
"movco.l %0, @%2 \n\t"
@@ -54,12 +54,12 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock)
);
}
-static inline void __raw_spin_unlock(raw_spinlock_t *lock)
+static inline void arch_spin_unlock(arch_spinlock_t *lock)
{
unsigned long tmp;
__asm__ __volatile__ (
- "mov #1, %0 ! __raw_spin_unlock \n\t"
+ "mov #1, %0 ! arch_spin_unlock \n\t"
"mov.l %0, @%1 \n\t"
: "=&z" (tmp)
: "r" (&lock->lock)
@@ -67,13 +67,13 @@ static inline void __raw_spin_unlock(raw_spinlock_t *lock)
);
}
-static inline int __raw_spin_trylock(raw_spinlock_t *lock)
+static inline int arch_spin_trylock(arch_spinlock_t *lock)
{
unsigned long tmp, oldval;
__asm__ __volatile__ (
"1: \n\t"
- "movli.l @%2, %0 ! __raw_spin_trylock \n\t"
+ "movli.l @%2, %0 ! arch_spin_trylock \n\t"
"mov %0, %1 \n\t"
"mov #0, %0 \n\t"
"movco.l %0, @%2 \n\t"
@@ -100,21 +100,21 @@ static inline int __raw_spin_trylock(raw_spinlock_t *lock)
* read_can_lock - would read_trylock() succeed?
* @lock: the rwlock in question.
*/
-#define __raw_read_can_lock(x) ((x)->lock > 0)
+#define arch_read_can_lock(x) ((x)->lock > 0)
/**
* write_can_lock - would write_trylock() succeed?
* @lock: the rwlock in question.
*/
-#define __raw_write_can_lock(x) ((x)->lock == RW_LOCK_BIAS)
+#define arch_write_can_lock(x) ((x)->lock == RW_LOCK_BIAS)
-static inline void __raw_read_lock(raw_rwlock_t *rw)
+static inline void arch_read_lock(arch_rwlock_t *rw)
{
unsigned long tmp;
__asm__ __volatile__ (
"1: \n\t"
- "movli.l @%1, %0 ! __raw_read_lock \n\t"
+ "movli.l @%1, %0 ! arch_read_lock \n\t"
"cmp/pl %0 \n\t"
"bf 1b \n\t"
"add #-1, %0 \n\t"
@@ -126,13 +126,13 @@ static inline void __raw_read_lock(raw_rwlock_t *rw)
);
}
-static inline void __raw_read_unlock(raw_rwlock_t *rw)
+static inline void arch_read_unlock(arch_rwlock_t *rw)
{
unsigned long tmp;
__asm__ __volatile__ (
"1: \n\t"
- "movli.l @%1, %0 ! __raw_read_unlock \n\t"
+ "movli.l @%1, %0 ! arch_read_unlock \n\t"
"add #1, %0 \n\t"
"movco.l %0, @%1 \n\t"
"bf 1b \n\t"
@@ -142,13 +142,13 @@ static inline void __raw_read_unlock(raw_rwlock_t *rw)
);
}
-static inline void __raw_write_lock(raw_rwlock_t *rw)
+static inline void arch_write_lock(arch_rwlock_t *rw)
{
unsigned long tmp;
__asm__ __volatile__ (
"1: \n\t"
- "movli.l @%1, %0 ! __raw_write_lock \n\t"
+ "movli.l @%1, %0 ! arch_write_lock \n\t"
"cmp/hs %2, %0 \n\t"
"bf 1b \n\t"
"sub %2, %0 \n\t"
@@ -160,23 +160,23 @@ static inline void __raw_write_lock(raw_rwlock_t *rw)
);
}
-static inline void __raw_write_unlock(raw_rwlock_t *rw)
+static inline void arch_write_unlock(arch_rwlock_t *rw)
{
__asm__ __volatile__ (
- "mov.l %1, @%0 ! __raw_write_unlock \n\t"
+ "mov.l %1, @%0 ! arch_write_unlock \n\t"
:
: "r" (&rw->lock), "r" (RW_LOCK_BIAS)
: "t", "memory"
);
}
-static inline int __raw_read_trylock(raw_rwlock_t *rw)
+static inline int arch_read_trylock(arch_rwlock_t *rw)
{
unsigned long tmp, oldval;
__asm__ __volatile__ (
"1: \n\t"
- "movli.l @%2, %0 ! __raw_read_trylock \n\t"
+ "movli.l @%2, %0 ! arch_read_trylock \n\t"
"mov %0, %1 \n\t"
"cmp/pl %0 \n\t"
"bf 2f \n\t"
@@ -193,13 +193,13 @@ static inline int __raw_read_trylock(raw_rwlock_t *rw)
return (oldval > 0);
}
-static inline int __raw_write_trylock(raw_rwlock_t *rw)
+static inline int arch_write_trylock(arch_rwlock_t *rw)
{
unsigned long tmp, oldval;
__asm__ __volatile__ (
"1: \n\t"
- "movli.l @%2, %0 ! __raw_write_trylock \n\t"
+ "movli.l @%2, %0 ! arch_write_trylock \n\t"
"mov %0, %1 \n\t"
"cmp/hs %3, %0 \n\t"
"bf 2f \n\t"
@@ -216,11 +216,11 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw)
return (oldval > (RW_LOCK_BIAS - 1));
}
-#define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock)
-#define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock)
+#define arch_read_lock_flags(lock, flags) arch_read_lock(lock)
+#define arch_write_lock_flags(lock, flags) arch_write_lock(lock)
-#define _raw_spin_relax(lock) cpu_relax()
-#define _raw_read_relax(lock) cpu_relax()
-#define _raw_write_relax(lock) cpu_relax()
+#define arch_spin_relax(lock) cpu_relax()
+#define arch_read_relax(lock) cpu_relax()
+#define arch_write_relax(lock) cpu_relax()
#endif /* __ASM_SH_SPINLOCK_H */
diff --git a/arch/sh/include/asm/spinlock_types.h b/arch/sh/include/asm/spinlock_types.h
index b4d244e7b60..9b7560db06c 100644
--- a/arch/sh/include/asm/spinlock_types.h
+++ b/arch/sh/include/asm/spinlock_types.h
@@ -7,15 +7,15 @@
typedef struct {
volatile unsigned int lock;
-} raw_spinlock_t;
+} arch_spinlock_t;
-#define __RAW_SPIN_LOCK_UNLOCKED { 1 }
+#define __ARCH_SPIN_LOCK_UNLOCKED { 1 }
typedef struct {
volatile unsigned int lock;
-} raw_rwlock_t;
+} arch_rwlock_t;
#define RW_LOCK_BIAS 0x01000000
-#define __RAW_RW_LOCK_UNLOCKED { RW_LOCK_BIAS }
+#define __ARCH_RW_LOCK_UNLOCKED { RW_LOCK_BIAS }
#endif
diff --git a/arch/sh/include/asm/sram.h b/arch/sh/include/asm/sram.h
new file mode 100644
index 00000000000..a2808ce4c0a
--- /dev/null
+++ b/arch/sh/include/asm/sram.h
@@ -0,0 +1,38 @@
+#ifndef __ASM_SRAM_H
+#define __ASM_SRAM_H
+
+#ifdef CONFIG_HAVE_SRAM_POOL
+
+#include <linux/spinlock.h>
+#include <linux/genalloc.h>
+
+/* arch/sh/mm/sram.c */
+extern struct gen_pool *sram_pool;
+
+static inline unsigned long sram_alloc(size_t len)
+{
+ if (!sram_pool)
+ return 0UL;
+
+ return gen_pool_alloc(sram_pool, len);
+}
+
+static inline void sram_free(unsigned long addr, size_t len)
+{
+ return gen_pool_free(sram_pool, addr, len);
+}
+
+#else
+
+static inline unsigned long sram_alloc(size_t len)
+{
+ return 0;
+}
+
+static inline void sram_free(unsigned long addr, size_t len)
+{
+}
+
+#endif /* CONFIG_HAVE_SRAM_POOL */
+
+#endif /* __ASM_SRAM_H */
diff --git a/arch/sh/include/asm/stacktrace.h b/arch/sh/include/asm/stacktrace.h
new file mode 100644
index 00000000000..79701821371
--- /dev/null
+++ b/arch/sh/include/asm/stacktrace.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2009 Matt Fleming
+ *
+ * Based on:
+ * The x86 implementation - arch/x86/include/asm/stacktrace.h
+ */
+#ifndef _ASM_SH_STACKTRACE_H
+#define _ASM_SH_STACKTRACE_H
+
+/* Generic stack tracer with callbacks */
+
+struct stacktrace_ops {
+ void (*warning)(void *data, char *msg);
+ /* msg must contain %s for the symbol */
+ void (*warning_symbol)(void *data, char *msg, unsigned long symbol);
+ void (*address)(void *data, unsigned long address, int reliable);
+ /* On negative return stop dumping */
+ int (*stack)(void *data, char *name);
+};
+
+void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
+ unsigned long *stack,
+ const struct stacktrace_ops *ops, void *data);
+
+#endif /* _ASM_SH_STACKTRACE_H */
diff --git a/arch/sh/include/asm/suspend.h b/arch/sh/include/asm/suspend.h
index b1b995370e7..64eb41a063e 100644
--- a/arch/sh/include/asm/suspend.h
+++ b/arch/sh/include/asm/suspend.h
@@ -2,6 +2,7 @@
#define _ASM_SH_SUSPEND_H
#ifndef __ASSEMBLY__
+#include <linux/notifier.h>
static inline int arch_prepare_suspend(void) { return 0; }
#include <asm/ptrace.h>
@@ -10,6 +11,78 @@ struct swsusp_arch_regs {
struct pt_regs user_regs;
unsigned long bank1_regs[8];
};
+
+void sh_mobile_call_standby(unsigned long mode);
+
+#ifdef CONFIG_CPU_IDLE
+void sh_mobile_setup_cpuidle(void);
+#else
+static inline void sh_mobile_setup_cpuidle(void) {}
+#endif
+
+/* notifier chains for pre/post sleep hooks */
+extern struct atomic_notifier_head sh_mobile_pre_sleep_notifier_list;
+extern struct atomic_notifier_head sh_mobile_post_sleep_notifier_list;
+
+/* priority levels for notifiers */
+#define SH_MOBILE_SLEEP_BOARD 0
+#define SH_MOBILE_SLEEP_CPU 1
+#define SH_MOBILE_PRE(x) (x)
+#define SH_MOBILE_POST(x) (-(x))
+
+/* board code registration function for self-refresh assembly snippets */
+void sh_mobile_register_self_refresh(unsigned long flags,
+ void *pre_start, void *pre_end,
+ void *post_start, void *post_end);
+
+/* register structure for address/data information */
+struct sh_sleep_regs {
+ unsigned long stbcr;
+ unsigned long bar;
+
+ /* MMU */
+ unsigned long pteh;
+ unsigned long ptel;
+ unsigned long ttb;
+ unsigned long tea;
+ unsigned long mmucr;
+ unsigned long ptea;
+ unsigned long pascr;
+ unsigned long irmcr;
+
+ /* Cache */
+ unsigned long ccr;
+ unsigned long ramcr;
+};
+
+/* data area for low-level sleep code */
+struct sh_sleep_data {
+ /* current sleep mode (SUSP_SH_...) */
+ unsigned long mode;
+
+ /* addresses of board specific self-refresh snippets */
+ unsigned long sf_pre;
+ unsigned long sf_post;
+
+ /* address of resume code */
+ unsigned long resume;
+
+ /* register state saved and restored by the assembly code */
+ unsigned long vbr;
+ unsigned long spc;
+ unsigned long sr;
+ unsigned long sp;
+
+ /* structure for keeping register addresses */
+ struct sh_sleep_regs addr;
+
+ /* structure for saving/restoring register state */
+ struct sh_sleep_regs data;
+};
+
+/* a bitmap of supported sleep modes (SUSP_SH..) */
+extern unsigned long sh_mobile_sleep_supported;
+
#endif
/* flags passed to assembly suspend code */
@@ -18,5 +91,7 @@ struct swsusp_arch_regs {
#define SUSP_SH_RSTANDBY (1 << 2) /* SH-Mobile R-standby mode */
#define SUSP_SH_USTANDBY (1 << 3) /* SH-Mobile U-standby mode */
#define SUSP_SH_SF (1 << 4) /* Enable self-refresh */
+#define SUSP_SH_MMU (1 << 5) /* Save/restore MMU and cache */
+#define SUSP_SH_REGS (1 << 6) /* Save/restore registers */
#endif /* _ASM_SH_SUSPEND_H */
diff --git a/arch/sh/include/asm/syscall.h b/arch/sh/include/asm/syscall.h
index 6a381429ee9..aa7777bdc37 100644
--- a/arch/sh/include/asm/syscall.h
+++ b/arch/sh/include/asm/syscall.h
@@ -1,6 +1,8 @@
#ifndef __ASM_SH_SYSCALL_H
#define __ASM_SH_SYSCALL_H
+extern const unsigned long sys_call_table[];
+
#ifdef CONFIG_SUPERH32
# include "syscall_32.h"
#else
diff --git a/arch/sh/include/asm/syscall_32.h b/arch/sh/include/asm/syscall_32.h
index 5bc34681d99..7d80df4f09c 100644
--- a/arch/sh/include/asm/syscall_32.h
+++ b/arch/sh/include/asm/syscall_32.h
@@ -3,6 +3,7 @@
#include <linux/kernel.h>
#include <linux/sched.h>
+#include <linux/err.h>
#include <asm/ptrace.h>
/* The system call number is given by the user in R3 */
@@ -64,6 +65,7 @@ static inline void syscall_get_arguments(struct task_struct *task,
case 3: args[2] = regs->regs[6];
case 2: args[1] = regs->regs[5];
case 1: args[0] = regs->regs[4];
+ case 0:
break;
default:
BUG();
diff --git a/arch/sh/include/asm/syscalls.h b/arch/sh/include/asm/syscalls.h
index c1e2b8deb83..507725af2e5 100644
--- a/arch/sh/include/asm/syscalls.h
+++ b/arch/sh/include/asm/syscalls.h
@@ -3,17 +3,12 @@
#ifdef __KERNEL__
-struct old_utsname;
-
asmlinkage int old_mmap(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
int fd, unsigned long off);
asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long pgoff);
-asmlinkage int sys_ipc(uint call, int first, int second,
- int third, void __user *ptr, long fifth);
-asmlinkage int sys_uname(struct old_utsname __user *name);
#ifdef CONFIG_SUPERH32
# include "syscalls_32.h"
diff --git a/arch/sh/include/asm/syscalls_32.h b/arch/sh/include/asm/syscalls_32.h
index 8b30200305c..ae717e3c26d 100644
--- a/arch/sh/include/asm/syscalls_32.h
+++ b/arch/sh/include/asm/syscalls_32.h
@@ -19,9 +19,10 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
asmlinkage int sys_vfork(unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7,
struct pt_regs __regs);
-asmlinkage int sys_execve(char __user *ufilename, char __user * __user *uargv,
- char __user * __user *uenvp, unsigned long r7,
- struct pt_regs __regs);
+asmlinkage int sys_execve(const char __user *ufilename,
+ const char __user *const __user *uargv,
+ const char __user *const __user *uenvp,
+ unsigned long r7, struct pt_regs __regs);
asmlinkage int sys_sigsuspend(old_sigset_t mask, unsigned long r5,
unsigned long r6, unsigned long r7,
struct pt_regs __regs);
diff --git a/arch/sh/include/asm/syscalls_64.h b/arch/sh/include/asm/syscalls_64.h
index 751fd881136..ee519f41d95 100644
--- a/arch/sh/include/asm/syscalls_64.h
+++ b/arch/sh/include/asm/syscalls_64.h
@@ -21,7 +21,7 @@ asmlinkage int sys_vfork(unsigned long r2, unsigned long r3,
unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7,
struct pt_regs *pregs);
-asmlinkage int sys_execve(char *ufilename, char **uargv,
+asmlinkage int sys_execve(const char *ufilename, char **uargv,
char **uenvp, unsigned long r5,
unsigned long r6, unsigned long r7,
struct pt_regs *pregs);
diff --git a/arch/sh/include/asm/system.h b/arch/sh/include/asm/system.h
index ab79e1f4fbe..10c8b1823a1 100644
--- a/arch/sh/include/asm/system.h
+++ b/arch/sh/include/asm/system.h
@@ -10,22 +10,10 @@
#include <linux/compiler.h>
#include <linux/linkage.h>
#include <asm/types.h>
-#include <asm/ptrace.h>
+#include <asm/uncached.h>
#define AT_VECTOR_SIZE_ARCH 5 /* entries in ARCH_DLINFO */
-#if defined(CONFIG_CPU_SH4A) || defined(CONFIG_CPU_SH5)
-#define __icbi() \
-{ \
- unsigned long __addr; \
- __addr = 0xa8000000; \
- __asm__ __volatile__( \
- "icbi %0\n\t" \
- : /* no output */ \
- : "m" (__m(__addr))); \
-}
-#endif
-
/*
* A brief note on ctrl_barrier(), the control register write barrier.
*
@@ -44,7 +32,7 @@
#define mb() __asm__ __volatile__ ("synco": : :"memory")
#define rmb() mb()
#define wmb() __asm__ __volatile__ ("synco": : :"memory")
-#define ctrl_barrier() __icbi()
+#define ctrl_barrier() __icbi(PAGE_OFFSET)
#define read_barrier_depends() do { } while(0)
#else
#define mb() __asm__ __volatile__ ("": : :"memory")
@@ -126,6 +114,8 @@ static inline unsigned long __cmpxchg(volatile void * ptr, unsigned long old,
(unsigned long)_n_, sizeof(*(ptr))); \
})
+struct pt_regs;
+
extern void die(const char *str, struct pt_regs *regs, long err) __attribute__ ((noreturn));
void free_initmem(void);
void free_initrd_mem(unsigned long start, unsigned long end);
@@ -148,15 +138,10 @@ extern unsigned int instruction_size(unsigned int insn);
#define instruction_size(insn) (4)
#endif
-extern unsigned long cached_to_uncached;
-
-extern struct dentry *sh_debugfs_root;
-
void per_cpu_trap_init(void);
void default_idle(void);
void cpu_idle_wait(void);
-
-asmlinkage void break_point_trap(void);
+void stop_this_cpu(void *);
#ifdef CONFIG_SUPERH32
#define BUILD_TRAP_HANDLER(name) \
@@ -181,6 +166,7 @@ BUILD_TRAP_HANDLER(breakpoint);
BUILD_TRAP_HANDLER(singlestep);
BUILD_TRAP_HANDLER(fpu_error);
BUILD_TRAP_HANDLER(fpu_state_restore);
+BUILD_TRAP_HANDLER(nmi);
#define arch_align_stack(x) (x)
diff --git a/arch/sh/include/asm/system_32.h b/arch/sh/include/asm/system_32.h
index 6c68a51f1cc..a4ad1cd9bc4 100644
--- a/arch/sh/include/asm/system_32.h
+++ b/arch/sh/include/asm/system_32.h
@@ -2,6 +2,7 @@
#define __ASM_SH_SYSTEM_32_H
#include <linux/types.h>
+#include <asm/mmu.h>
#ifdef CONFIG_SH_DSP
@@ -14,12 +15,12 @@ do { \
(u32 *)&tsk->thread.dsp_status; \
__asm__ __volatile__ ( \
".balign 4\n\t" \
+ "movs.l @r2+, a0\n\t" \
"movs.l @r2+, a1\n\t" \
"movs.l @r2+, a0g\n\t" \
"movs.l @r2+, a1g\n\t" \
"movs.l @r2+, m0\n\t" \
"movs.l @r2+, m1\n\t" \
- "movs.l @r2+, a0\n\t" \
"movs.l @r2+, x0\n\t" \
"movs.l @r2+, x1\n\t" \
"movs.l @r2+, y0\n\t" \
@@ -39,20 +40,20 @@ do { \
\
__asm__ __volatile__ ( \
".balign 4\n\t" \
- "stc.l mod, @-r2\n\t" \
+ "stc.l mod, @-r2\n\t" \
"stc.l re, @-r2\n\t" \
"stc.l rs, @-r2\n\t" \
- "sts.l dsr, @-r2\n\t" \
- "sts.l y1, @-r2\n\t" \
- "sts.l y0, @-r2\n\t" \
- "sts.l x1, @-r2\n\t" \
- "sts.l x0, @-r2\n\t" \
- "sts.l a0, @-r2\n\t" \
- ".word 0xf653 ! movs.l a1, @-r2\n\t" \
- ".word 0xf6f3 ! movs.l a0g, @-r2\n\t" \
- ".word 0xf6d3 ! movs.l a1g, @-r2\n\t" \
- ".word 0xf6c3 ! movs.l m0, @-r2\n\t" \
- ".word 0xf6e3 ! movs.l m1, @-r2\n\t" \
+ "sts.l dsr, @-r2\n\t" \
+ "movs.l y1, @-r2\n\t" \
+ "movs.l y0, @-r2\n\t" \
+ "movs.l x1, @-r2\n\t" \
+ "movs.l x0, @-r2\n\t" \
+ "movs.l m1, @-r2\n\t" \
+ "movs.l m0, @-r2\n\t" \
+ "movs.l a1g, @-r2\n\t" \
+ "movs.l a0g, @-r2\n\t" \
+ "movs.l a1, @-r2\n\t" \
+ "movs.l a0, @-r2\n\t" \
: : "r" (__ts2)); \
} while (0)
@@ -63,6 +64,16 @@ do { \
#define __restore_dsp(tsk) do { } while (0)
#endif
+#if defined(CONFIG_CPU_SH4A)
+#define __icbi(addr) __asm__ __volatile__ ( "icbi @%0\n\t" : : "r" (addr))
+#else
+#define __icbi(addr) mb()
+#endif
+
+#define __ocbp(addr) __asm__ __volatile__ ( "ocbp @%0\n\t" : : "r" (addr))
+#define __ocbi(addr) __asm__ __volatile__ ( "ocbi @%0\n\t" : : "r" (addr))
+#define __ocbwb(addr) __asm__ __volatile__ ( "ocbwb @%0\n\t" : : "r" (addr))
+
struct task_struct *__switch_to(struct task_struct *prev,
struct task_struct *next);
@@ -134,45 +145,6 @@ do { \
__restore_dsp(prev); \
} while (0)
-#define __uses_jump_to_uncached \
- noinline __attribute__ ((__section__ (".uncached.text")))
-
-/*
- * Jump to uncached area.
- * When handling TLB or caches, we need to do it from an uncached area.
- */
-#define jump_to_uncached() \
-do { \
- unsigned long __dummy; \
- \
- __asm__ __volatile__( \
- "mova 1f, %0\n\t" \
- "add %1, %0\n\t" \
- "jmp @%0\n\t" \
- " nop\n\t" \
- ".balign 4\n" \
- "1:" \
- : "=&z" (__dummy) \
- : "r" (cached_to_uncached)); \
-} while (0)
-
-/*
- * Back to cached area.
- */
-#define back_to_cached() \
-do { \
- unsigned long __dummy; \
- ctrl_barrier(); \
- __asm__ __volatile__( \
- "mov.l 1f, %0\n\t" \
- "jmp @%0\n\t" \
- " nop\n\t" \
- ".balign 4\n" \
- "1: .long 2f\n" \
- "2:" \
- : "=&r" (__dummy)); \
-} while (0)
-
#ifdef CONFIG_CPU_HAS_SR_RB
#define lookup_exception_vector() \
({ \
@@ -198,8 +170,23 @@ do { \
})
#endif
+static inline reg_size_t register_align(void *val)
+{
+ return (unsigned long)(signed long)val;
+}
+
int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs,
- struct mem_access *ma);
+ struct mem_access *ma, int, unsigned long address);
+
+static inline void trigger_address_error(void)
+{
+ __asm__ __volatile__ (
+ "ldc %0, sr\n\t"
+ "mov.l @%1, %0"
+ :
+ : "r" (0x10000000), "r" (0x80000001)
+ );
+}
asmlinkage void do_address_error(struct pt_regs *regs,
unsigned long writeaccess,
@@ -217,4 +204,33 @@ asmlinkage void do_exception_error(unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7,
struct pt_regs __regs);
+static inline void set_bl_bit(void)
+{
+ unsigned long __dummy0, __dummy1;
+
+ __asm__ __volatile__ (
+ "stc sr, %0\n\t"
+ "or %2, %0\n\t"
+ "and %3, %0\n\t"
+ "ldc %0, sr\n\t"
+ : "=&r" (__dummy0), "=r" (__dummy1)
+ : "r" (0x10000000), "r" (0xffffff0f)
+ : "memory"
+ );
+}
+
+static inline void clear_bl_bit(void)
+{
+ unsigned long __dummy0, __dummy1;
+
+ __asm__ __volatile__ (
+ "stc sr, %0\n\t"
+ "and %2, %0\n\t"
+ "ldc %0, sr\n\t"
+ : "=&r" (__dummy0), "=r" (__dummy1)
+ : "1" (~0x10000000)
+ : "memory"
+ );
+}
+
#endif /* __ASM_SH_SYSTEM_32_H */
diff --git a/arch/sh/include/asm/system_64.h b/arch/sh/include/asm/system_64.h
index 943acf5ea07..8593bc8d1a4 100644
--- a/arch/sh/include/asm/system_64.h
+++ b/arch/sh/include/asm/system_64.h
@@ -12,11 +12,13 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
+#include <cpu/registers.h>
#include <asm/processor.h>
/*
* switch_to() should switch tasks to task nr n, first
*/
+struct thread_struct;
struct task_struct *sh64_switch_to(struct task_struct *prev,
struct thread_struct *prev_thread,
struct task_struct *next,
@@ -32,9 +34,46 @@ do { \
&next->thread); \
} while (0)
-#define __uses_jump_to_uncached
+#define __icbi(addr) __asm__ __volatile__ ( "icbi %0, 0\n\t" : : "r" (addr))
+#define __ocbp(addr) __asm__ __volatile__ ( "ocbp %0, 0\n\t" : : "r" (addr))
+#define __ocbi(addr) __asm__ __volatile__ ( "ocbi %0, 0\n\t" : : "r" (addr))
+#define __ocbwb(addr) __asm__ __volatile__ ( "ocbwb %0, 0\n\t" : : "r" (addr))
-#define jump_to_uncached() do { } while (0)
-#define back_to_cached() do { } while (0)
+static inline reg_size_t register_align(void *val)
+{
+ return (unsigned long long)(signed long long)(signed long)val;
+}
+
+extern void phys_stext(void);
+
+static inline void trigger_address_error(void)
+{
+ phys_stext();
+}
+
+#define SR_BL_LL 0x0000000010000000LL
+
+static inline void set_bl_bit(void)
+{
+ unsigned long long __dummy0, __dummy1 = SR_BL_LL;
+
+ __asm__ __volatile__("getcon " __SR ", %0\n\t"
+ "or %0, %1, %0\n\t"
+ "putcon %0, " __SR "\n\t"
+ : "=&r" (__dummy0)
+ : "r" (__dummy1));
+
+}
+
+static inline void clear_bl_bit(void)
+{
+ unsigned long long __dummy0, __dummy1 = ~SR_BL_LL;
+
+ __asm__ __volatile__("getcon " __SR ", %0\n\t"
+ "and %0, %1, %0\n\t"
+ "putcon %0, " __SR "\n\t"
+ : "=&r" (__dummy0)
+ : "r" (__dummy1));
+}
#endif /* __ASM_SH_SYSTEM_64_H */
diff --git a/arch/sh/include/asm/thread_info.h b/arch/sh/include/asm/thread_info.h
index f09ac480629..c228946926e 100644
--- a/arch/sh/include/asm/thread_info.h
+++ b/arch/sh/include/asm/thread_info.h
@@ -19,6 +19,7 @@ struct thread_info {
struct task_struct *task; /* main task structure */
struct exec_domain *exec_domain; /* execution domain */
unsigned long flags; /* low level flags */
+ __u32 status; /* thread synchronous flags */
__u32 cpu;
int preempt_count; /* 0 => preemptable, <0 => BUG */
mm_segment_t addr_limit; /* thread address space */
@@ -50,8 +51,9 @@ struct thread_info {
.task = &tsk, \
.exec_domain = &default_exec_domain, \
.flags = 0, \
+ .status = 0, \
.cpu = 0, \
- .preempt_count = 1, \
+ .preempt_count = INIT_PREEMPT_COUNT, \
.addr_limit = KERNEL_DS, \
.restart_block = { \
.fn = do_no_restart_syscall, \
@@ -91,14 +93,16 @@ static inline struct thread_info *current_thread_info(void)
#define THREAD_SIZE_ORDER (THREAD_SHIFT - PAGE_SHIFT)
-#else /* THREAD_SHIFT < PAGE_SHIFT */
-
-#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR
+#endif
extern struct thread_info *alloc_thread_info(struct task_struct *tsk);
extern void free_thread_info(struct thread_info *ti);
-
-#endif /* THREAD_SHIFT < PAGE_SHIFT */
+extern void arch_task_cache_init(void);
+#define arch_task_cache_init arch_task_cache_init
+extern int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src);
+extern void init_thread_xstate(void);
+
+#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR
#endif /* __ASSEMBLY__ */
@@ -111,48 +115,67 @@ extern void free_thread_info(struct thread_info *ti);
#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
#define TIF_SIGPENDING 1 /* signal pending */
#define TIF_NEED_RESCHED 2 /* rescheduling necessary */
-#define TIF_RESTORE_SIGMASK 3 /* restore signal mask in do_signal() */
#define TIF_SINGLESTEP 4 /* singlestepping active */
#define TIF_SYSCALL_AUDIT 5 /* syscall auditing active */
#define TIF_SECCOMP 6 /* secure computing */
#define TIF_NOTIFY_RESUME 7 /* callback before returning to user */
-#define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */
+#define TIF_SYSCALL_TRACEPOINT 8 /* for ftrace syscall instrumentation */
#define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */
-#define TIF_MEMDIE 18
+#define TIF_MEMDIE 18 /* is terminating due to OOM killer */
#define TIF_FREEZE 19 /* Freezing for suspend */
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
-#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
#define _TIF_SECCOMP (1 << TIF_SECCOMP)
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
-#define _TIF_USEDFPU (1 << TIF_USEDFPU)
+#define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT)
#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
#define _TIF_FREEZE (1 << TIF_FREEZE)
/*
- * _TIF_ALLWORK_MASK and _TIF_WORK_MASK need to fit within a byte, or we
+ * _TIF_ALLWORK_MASK and _TIF_WORK_MASK need to fit within 2 bytes, or we
* blow the tst immediate size constraints and need to fix up
* arch/sh/kernel/entry-common.S.
*/
/* work to do in syscall trace */
#define _TIF_WORK_SYSCALL_MASK (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP | \
- _TIF_SYSCALL_AUDIT | _TIF_SECCOMP)
+ _TIF_SYSCALL_AUDIT | _TIF_SECCOMP | \
+ _TIF_SYSCALL_TRACEPOINT)
/* work to do on any return to u-space */
#define _TIF_ALLWORK_MASK (_TIF_SYSCALL_TRACE | _TIF_SIGPENDING | \
_TIF_NEED_RESCHED | _TIF_SYSCALL_AUDIT | \
- _TIF_SINGLESTEP | _TIF_RESTORE_SIGMASK | \
- _TIF_NOTIFY_RESUME)
+ _TIF_SINGLESTEP | _TIF_NOTIFY_RESUME | \
+ _TIF_SYSCALL_TRACEPOINT)
/* work to do on interrupt/exception return */
#define _TIF_WORK_MASK (_TIF_ALLWORK_MASK & ~(_TIF_SYSCALL_TRACE | \
_TIF_SYSCALL_AUDIT | _TIF_SINGLESTEP))
+/*
+ * Thread-synchronous status.
+ *
+ * This is different from the flags in that nobody else
+ * ever touches our thread-synchronous status, so we don't
+ * have to worry about atomic accesses.
+ */
+#define TS_RESTORE_SIGMASK 0x0001 /* restore signal mask in do_signal() */
+#define TS_USEDFPU 0x0002 /* FPU used by this task this quantum */
+
+#ifndef __ASSEMBLY__
+#define HAVE_SET_RESTORE_SIGMASK 1
+static inline void set_restore_sigmask(void)
+{
+ struct thread_info *ti = current_thread_info();
+ ti->status |= TS_RESTORE_SIGMASK;
+ set_bit(TIF_SIGPENDING, (unsigned long *)&ti->flags);
+}
+#endif /* !__ASSEMBLY__ */
+
#endif /* __KERNEL__ */
#endif /* __ASM_SH_THREAD_INFO_H */
diff --git a/arch/sh/include/asm/timex.h b/arch/sh/include/asm/timex.h
index b556d49e5f2..18bf06d9c76 100644
--- a/arch/sh/include/asm/timex.h
+++ b/arch/sh/include/asm/timex.h
@@ -6,7 +6,17 @@
#ifndef __ASM_SH_TIMEX_H
#define __ASM_SH_TIMEX_H
+/*
+ * Only parts using the legacy CPG code for their clock framework
+ * implementation need to define their own Pclk value. If provided, this
+ * can be used for accurately setting CLOCK_TICK_RATE, otherwise we
+ * simply fall back on the i8253 PIT value.
+ */
+#ifdef CONFIG_SH_PCLK_FREQ
#define CLOCK_TICK_RATE (CONFIG_SH_PCLK_FREQ / 4) /* Underlying HZ */
+#else
+#define CLOCK_TICK_RATE 1193180
+#endif
#include <asm-generic/timex.h>
diff --git a/arch/sh/include/asm/tlb.h b/arch/sh/include/asm/tlb.h
index 9c16f737074..75abb38dffd 100644
--- a/arch/sh/include/asm/tlb.h
+++ b/arch/sh/include/asm/tlb.h
@@ -11,6 +11,7 @@
#ifdef CONFIG_MMU
#include <asm/pgalloc.h>
#include <asm/tlbflush.h>
+#include <asm/mmu_context.h>
/*
* TLB handling. This allows us to remove pages from the page
@@ -91,12 +92,28 @@ tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vma)
}
#define tlb_remove_page(tlb,page) free_page_and_swap_cache(page)
-#define pte_free_tlb(tlb, ptep) pte_free((tlb)->mm, ptep)
-#define pmd_free_tlb(tlb, pmdp) pmd_free((tlb)->mm, pmdp)
-#define pud_free_tlb(tlb, pudp) pud_free((tlb)->mm, pudp)
+#define pte_free_tlb(tlb, ptep, addr) pte_free((tlb)->mm, ptep)
+#define pmd_free_tlb(tlb, pmdp, addr) pmd_free((tlb)->mm, pmdp)
+#define pud_free_tlb(tlb, pudp, addr) pud_free((tlb)->mm, pudp)
#define tlb_migrate_finish(mm) do { } while (0)
+#if defined(CONFIG_CPU_SH4) || defined(CONFIG_SUPERH64)
+extern void tlb_wire_entry(struct vm_area_struct *, unsigned long, pte_t);
+extern void tlb_unwire_entry(void);
+#else
+static inline void tlb_wire_entry(struct vm_area_struct *vma ,
+ unsigned long addr, pte_t pte)
+{
+ BUG();
+}
+
+static inline void tlb_unwire_entry(void)
+{
+ BUG();
+}
+#endif
+
#else /* CONFIG_MMU */
#define tlb_start_vma(tlb, vma) do { } while (0)
diff --git a/arch/sh/include/asm/tlbflush.h b/arch/sh/include/asm/tlbflush.h
index e0ac97221ae..0df66f0c728 100644
--- a/arch/sh/include/asm/tlbflush.h
+++ b/arch/sh/include/asm/tlbflush.h
@@ -21,6 +21,8 @@ extern void local_flush_tlb_kernel_range(unsigned long start,
unsigned long end);
extern void local_flush_tlb_one(unsigned long asid, unsigned long page);
+extern void __flush_tlb_global(void);
+
#ifdef CONFIG_SMP
extern void flush_tlb_all(void);
diff --git a/arch/sh/include/asm/topology.h b/arch/sh/include/asm/topology.h
index b69ee850906..88e734069fa 100644
--- a/arch/sh/include/asm/topology.h
+++ b/arch/sh/include/asm/topology.h
@@ -15,14 +15,14 @@
.cache_nice_tries = 2, \
.busy_idx = 3, \
.idle_idx = 2, \
- .newidle_idx = 2, \
- .wake_idx = 1, \
- .forkexec_idx = 1, \
+ .newidle_idx = 0, \
+ .wake_idx = 0, \
+ .forkexec_idx = 0, \
.flags = SD_LOAD_BALANCE \
| SD_BALANCE_FORK \
| SD_BALANCE_EXEC \
- | SD_SERIALIZE \
- | SD_WAKE_BALANCE, \
+ | SD_BALANCE_NEWIDLE \
+ | SD_SERIALIZE, \
.last_balance = jiffies, \
.balance_interval = 1, \
.nr_balance_failed = 0, \
@@ -31,16 +31,23 @@
#define cpu_to_node(cpu) ((void)(cpu),0)
#define parent_node(node) ((void)(node),0)
-#define node_to_cpumask(node) ((void)node, cpu_online_map)
#define cpumask_of_node(node) ((void)node, cpu_online_mask)
#define pcibus_to_node(bus) ((void)(bus), -1)
#define cpumask_of_pcibus(bus) (pcibus_to_node(bus) == -1 ? \
- CPU_MASK_ALL_PTR : \
+ cpu_all_mask : \
cpumask_of_node(pcibus_to_node(bus)))
#endif
+#define mc_capable() (1)
+
+const struct cpumask *cpu_coregroup_mask(unsigned int cpu);
+
+extern cpumask_t cpu_core_map[NR_CPUS];
+
+#define topology_core_cpumask(cpu) (&cpu_core_map[cpu])
+
#include <asm-generic/topology.h>
#endif /* _ASM_SH_TOPOLOGY_H */
diff --git a/arch/sh/include/asm/types.h b/arch/sh/include/asm/types.h
index c7f3c94837d..f8421f7ad63 100644
--- a/arch/sh/include/asm/types.h
+++ b/arch/sh/include/asm/types.h
@@ -11,8 +11,10 @@
#ifdef CONFIG_SUPERH32
typedef u16 insn_size_t;
+typedef u32 reg_size_t;
#else
typedef u32 insn_size_t;
+typedef u64 reg_size_t;
#endif
#endif /* __ASSEMBLY__ */
diff --git a/arch/sh/include/asm/ubc.h b/arch/sh/include/asm/ubc.h
deleted file mode 100644
index 4ca4b771737..00000000000
--- a/arch/sh/include/asm/ubc.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * include/asm-sh/ubc.h
- *
- * Copyright (C) 1999 Niibe Yutaka
- * Copyright (C) 2002, 2003 Paul Mundt
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-#ifndef __ASM_SH_UBC_H
-#define __ASM_SH_UBC_H
-#ifdef __KERNEL__
-
-#include <cpu/ubc.h>
-
-/* User Break Controller */
-#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709)
-#define UBC_TYPE_SH7729 (current_cpu_data.type == CPU_SH7729)
-#else
-#define UBC_TYPE_SH7729 0
-#endif
-
-#define BAMR_ASID (1 << 2)
-#define BAMR_NONE 0
-#define BAMR_10 0x1
-#define BAMR_12 0x2
-#define BAMR_ALL 0x3
-#define BAMR_16 0x8
-#define BAMR_20 0x9
-
-#define BBR_INST (1 << 4)
-#define BBR_DATA (2 << 4)
-#define BBR_READ (1 << 2)
-#define BBR_WRITE (2 << 2)
-#define BBR_BYTE 0x1
-#define BBR_HALF 0x2
-#define BBR_LONG 0x3
-#define BBR_QUAD (1 << 6) /* SH7750 */
-#define BBR_CPU (1 << 6) /* SH7709A,SH7729 */
-#define BBR_DMA (2 << 6) /* SH7709A,SH7729 */
-
-#define BRCR_CMFA (1 << 15)
-#define BRCR_CMFB (1 << 14)
-
-#if defined CONFIG_CPU_SH2A
-#define BRCR_CMFCA (1 << 15)
-#define BRCR_CMFCB (1 << 14)
-#define BRCR_CMFDA (1 << 13)
-#define BRCR_CMFDB (1 << 12)
-#define BRCR_PCBB (1 << 6) /* 1: after execution */
-#define BRCR_PCBA (1 << 5) /* 1: after execution */
-#define BRCR_PCTE 0
-#else
-#define BRCR_PCTE (1 << 11)
-#define BRCR_PCBA (1 << 10) /* 1: after execution */
-#define BRCR_DBEB (1 << 7)
-#define BRCR_PCBB (1 << 6)
-#define BRCR_SEQ (1 << 3)
-#define BRCR_UBDE (1 << 0)
-#endif
-
-#ifndef __ASSEMBLY__
-/* arch/sh/kernel/cpu/ubc.S */
-extern void ubc_sleep(void);
-
-#ifdef CONFIG_UBC_WAKEUP
-extern void ubc_wakeup(void);
-#else
-#define ubc_wakeup() do { } while (0)
-#endif
-#endif
-
-#endif /* __KERNEL__ */
-#endif /* __ASM_SH_UBC_H */
diff --git a/arch/sh/include/asm/unaligned-sh4a.h b/arch/sh/include/asm/unaligned-sh4a.h
index 9f4dd252c98..c48a9c3420d 100644
--- a/arch/sh/include/asm/unaligned-sh4a.h
+++ b/arch/sh/include/asm/unaligned-sh4a.h
@@ -18,10 +18,20 @@
* of spill registers and blowing up when building at low optimization
* levels. See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34777.
*/
+#include <linux/unaligned/packed_struct.h>
#include <linux/types.h>
#include <asm/byteorder.h>
-static __always_inline u32 __get_unaligned_cpu32(const u8 *p)
+static inline u16 sh4a_get_unaligned_cpu16(const u8 *p)
+{
+#ifdef __LITTLE_ENDIAN
+ return p[0] | p[1] << 8;
+#else
+ return p[0] << 8 | p[1];
+#endif
+}
+
+static __always_inline u32 sh4a_get_unaligned_cpu32(const u8 *p)
{
unsigned long unaligned;
@@ -34,218 +44,148 @@ static __always_inline u32 __get_unaligned_cpu32(const u8 *p)
return unaligned;
}
-struct __una_u16 { u16 x __attribute__((packed)); };
-struct __una_u32 { u32 x __attribute__((packed)); };
-struct __una_u64 { u64 x __attribute__((packed)); };
-
-static inline u16 __get_unaligned_cpu16(const u8 *p)
-{
-#ifdef __LITTLE_ENDIAN
- return p[0] | p[1] << 8;
-#else
- return p[0] << 8 | p[1];
-#endif
-}
-
/*
* Even though movua.l supports auto-increment on the read side, it can
* only store to r0 due to instruction encoding constraints, so just let
* the compiler sort it out on its own.
*/
-static inline u64 __get_unaligned_cpu64(const u8 *p)
+static inline u64 sh4a_get_unaligned_cpu64(const u8 *p)
{
#ifdef __LITTLE_ENDIAN
- return (u64)__get_unaligned_cpu32(p + 4) << 32 |
- __get_unaligned_cpu32(p);
+ return (u64)sh4a_get_unaligned_cpu32(p + 4) << 32 |
+ sh4a_get_unaligned_cpu32(p);
#else
- return (u64)__get_unaligned_cpu32(p) << 32 |
- __get_unaligned_cpu32(p + 4);
+ return (u64)sh4a_get_unaligned_cpu32(p) << 32 |
+ sh4a_get_unaligned_cpu32(p + 4);
#endif
}
static inline u16 get_unaligned_le16(const void *p)
{
- return le16_to_cpu(__get_unaligned_cpu16(p));
+ return le16_to_cpu(sh4a_get_unaligned_cpu16(p));
}
static inline u32 get_unaligned_le32(const void *p)
{
- return le32_to_cpu(__get_unaligned_cpu32(p));
+ return le32_to_cpu(sh4a_get_unaligned_cpu32(p));
}
static inline u64 get_unaligned_le64(const void *p)
{
- return le64_to_cpu(__get_unaligned_cpu64(p));
+ return le64_to_cpu(sh4a_get_unaligned_cpu64(p));
}
static inline u16 get_unaligned_be16(const void *p)
{
- return be16_to_cpu(__get_unaligned_cpu16(p));
+ return be16_to_cpu(sh4a_get_unaligned_cpu16(p));
}
static inline u32 get_unaligned_be32(const void *p)
{
- return be32_to_cpu(__get_unaligned_cpu32(p));
+ return be32_to_cpu(sh4a_get_unaligned_cpu32(p));
}
static inline u64 get_unaligned_be64(const void *p)
{
- return be64_to_cpu(__get_unaligned_cpu64(p));
+ return be64_to_cpu(sh4a_get_unaligned_cpu64(p));
}
-static inline void __put_le16_noalign(u8 *p, u16 val)
+static inline void nonnative_put_le16(u16 val, u8 *p)
{
*p++ = val;
*p++ = val >> 8;
}
-static inline void __put_le32_noalign(u8 *p, u32 val)
+static inline void nonnative_put_le32(u32 val, u8 *p)
{
- __put_le16_noalign(p, val);
- __put_le16_noalign(p + 2, val >> 16);
+ nonnative_put_le16(val, p);
+ nonnative_put_le16(val >> 16, p + 2);
}
-static inline void __put_le64_noalign(u8 *p, u64 val)
+static inline void nonnative_put_le64(u64 val, u8 *p)
{
- __put_le32_noalign(p, val);
- __put_le32_noalign(p + 4, val >> 32);
+ nonnative_put_le32(val, p);
+ nonnative_put_le32(val >> 32, p + 4);
}
-static inline void __put_be16_noalign(u8 *p, u16 val)
+static inline void nonnative_put_be16(u16 val, u8 *p)
{
*p++ = val >> 8;
*p++ = val;
}
-static inline void __put_be32_noalign(u8 *p, u32 val)
+static inline void nonnative_put_be32(u32 val, u8 *p)
{
- __put_be16_noalign(p, val >> 16);
- __put_be16_noalign(p + 2, val);
+ nonnative_put_be16(val >> 16, p);
+ nonnative_put_be16(val, p + 2);
}
-static inline void __put_be64_noalign(u8 *p, u64 val)
+static inline void nonnative_put_be64(u64 val, u8 *p)
{
- __put_be32_noalign(p, val >> 32);
- __put_be32_noalign(p + 4, val);
+ nonnative_put_be32(val >> 32, p);
+ nonnative_put_be32(val, p + 4);
}
static inline void put_unaligned_le16(u16 val, void *p)
{
#ifdef __LITTLE_ENDIAN
- ((struct __una_u16 *)p)->x = val;
+ __put_unaligned_cpu16(val, p);
#else
- __put_le16_noalign(p, val);
+ nonnative_put_le16(val, p);
#endif
}
static inline void put_unaligned_le32(u32 val, void *p)
{
#ifdef __LITTLE_ENDIAN
- ((struct __una_u32 *)p)->x = val;
+ __put_unaligned_cpu32(val, p);
#else
- __put_le32_noalign(p, val);
+ nonnative_put_le32(val, p);
#endif
}
static inline void put_unaligned_le64(u64 val, void *p)
{
#ifdef __LITTLE_ENDIAN
- ((struct __una_u64 *)p)->x = val;
+ __put_unaligned_cpu64(val, p);
#else
- __put_le64_noalign(p, val);
+ nonnative_put_le64(val, p);
#endif
}
static inline void put_unaligned_be16(u16 val, void *p)
{
#ifdef __BIG_ENDIAN
- ((struct __una_u16 *)p)->x = val;
+ __put_unaligned_cpu16(val, p);
#else
- __put_be16_noalign(p, val);
+ nonnative_put_be16(val, p);
#endif
}
static inline void put_unaligned_be32(u32 val, void *p)
{
#ifdef __BIG_ENDIAN
- ((struct __una_u32 *)p)->x = val;
+ __put_unaligned_cpu32(val, p);
#else
- __put_be32_noalign(p, val);
+ nonnative_put_be32(val, p);
#endif
}
static inline void put_unaligned_be64(u64 val, void *p)
{
#ifdef __BIG_ENDIAN
- ((struct __una_u64 *)p)->x = val;
+ __put_unaligned_cpu64(val, p);
#else
- __put_be64_noalign(p, val);
+ nonnative_put_be64(val, p);
#endif
}
/*
- * Cause a link-time error if we try an unaligned access other than
- * 1,2,4 or 8 bytes long
+ * While it's a bit non-obvious, even though the generic le/be wrappers
+ * use the __get/put_xxx prefixing, they actually wrap in to the
+ * non-prefixed get/put_xxx variants as provided above.
*/
-extern void __bad_unaligned_access_size(void);
-
-#define __get_unaligned_le(ptr) ((__force typeof(*(ptr)))({ \
- __builtin_choose_expr(sizeof(*(ptr)) == 1, *(ptr), \
- __builtin_choose_expr(sizeof(*(ptr)) == 2, get_unaligned_le16((ptr)), \
- __builtin_choose_expr(sizeof(*(ptr)) == 4, get_unaligned_le32((ptr)), \
- __builtin_choose_expr(sizeof(*(ptr)) == 8, get_unaligned_le64((ptr)), \
- __bad_unaligned_access_size())))); \
- }))
-
-#define __get_unaligned_be(ptr) ((__force typeof(*(ptr)))({ \
- __builtin_choose_expr(sizeof(*(ptr)) == 1, *(ptr), \
- __builtin_choose_expr(sizeof(*(ptr)) == 2, get_unaligned_be16((ptr)), \
- __builtin_choose_expr(sizeof(*(ptr)) == 4, get_unaligned_be32((ptr)), \
- __builtin_choose_expr(sizeof(*(ptr)) == 8, get_unaligned_be64((ptr)), \
- __bad_unaligned_access_size())))); \
- }))
-
-#define __put_unaligned_le(val, ptr) ({ \
- void *__gu_p = (ptr); \
- switch (sizeof(*(ptr))) { \
- case 1: \
- *(u8 *)__gu_p = (__force u8)(val); \
- break; \
- case 2: \
- put_unaligned_le16((__force u16)(val), __gu_p); \
- break; \
- case 4: \
- put_unaligned_le32((__force u32)(val), __gu_p); \
- break; \
- case 8: \
- put_unaligned_le64((__force u64)(val), __gu_p); \
- break; \
- default: \
- __bad_unaligned_access_size(); \
- break; \
- } \
- (void)0; })
-
-#define __put_unaligned_be(val, ptr) ({ \
- void *__gu_p = (ptr); \
- switch (sizeof(*(ptr))) { \
- case 1: \
- *(u8 *)__gu_p = (__force u8)(val); \
- break; \
- case 2: \
- put_unaligned_be16((__force u16)(val), __gu_p); \
- break; \
- case 4: \
- put_unaligned_be32((__force u32)(val), __gu_p); \
- break; \
- case 8: \
- put_unaligned_be64((__force u64)(val), __gu_p); \
- break; \
- default: \
- __bad_unaligned_access_size(); \
- break; \
- } \
- (void)0; })
+#include <linux/unaligned/generic.h>
#ifdef __LITTLE_ENDIAN
# define get_unaligned __get_unaligned_le
diff --git a/arch/sh/include/asm/uncached.h b/arch/sh/include/asm/uncached.h
new file mode 100644
index 00000000000..6f8816b79cf
--- /dev/null
+++ b/arch/sh/include/asm/uncached.h
@@ -0,0 +1,58 @@
+#ifndef __ASM_SH_UNCACHED_H
+#define __ASM_SH_UNCACHED_H
+
+#include <linux/bug.h>
+
+#ifdef CONFIG_UNCACHED_MAPPING
+extern unsigned long cached_to_uncached;
+extern unsigned long uncached_size;
+extern unsigned long uncached_start, uncached_end;
+
+extern int virt_addr_uncached(unsigned long kaddr);
+extern void uncached_init(void);
+extern void uncached_resize(unsigned long size);
+
+/*
+ * Jump to uncached area.
+ * When handling TLB or caches, we need to do it from an uncached area.
+ */
+#define jump_to_uncached() \
+do { \
+ unsigned long __dummy; \
+ \
+ __asm__ __volatile__( \
+ "mova 1f, %0\n\t" \
+ "add %1, %0\n\t" \
+ "jmp @%0\n\t" \
+ " nop\n\t" \
+ ".balign 4\n" \
+ "1:" \
+ : "=&z" (__dummy) \
+ : "r" (cached_to_uncached)); \
+} while (0)
+
+/*
+ * Back to cached area.
+ */
+#define back_to_cached() \
+do { \
+ unsigned long __dummy; \
+ ctrl_barrier(); \
+ __asm__ __volatile__( \
+ "mov.l 1f, %0\n\t" \
+ "jmp @%0\n\t" \
+ " nop\n\t" \
+ ".balign 4\n" \
+ "1: .long 2f\n" \
+ "2:" \
+ : "=&r" (__dummy)); \
+} while (0)
+#else
+#define virt_addr_uncached(kaddr) (0)
+#define uncached_init() do { } while (0)
+#define uncached_resize(size) BUG()
+#define jump_to_uncached() do { } while (0)
+#define back_to_cached() do { } while (0)
+#endif
+
+#endif /* __ASM_SH_UNCACHED_H */
diff --git a/arch/sh/include/asm/unistd_32.h b/arch/sh/include/asm/unistd_32.h
index 61d6ad93d78..d6741fca89a 100644
--- a/arch/sh/include/asm/unistd_32.h
+++ b/arch/sh/include/asm/unistd_32.h
@@ -132,7 +132,7 @@
#define __NR_clone 120
#define __NR_setdomainname 121
#define __NR_uname 122
-#define __NR_modify_ldt 123
+#define __NR_cacheflush 123
#define __NR_adjtimex 124
#define __NR_mprotect 125
#define __NR_sigprocmask 126
@@ -344,9 +344,33 @@
#define __NR_preadv 333
#define __NR_pwritev 334
#define __NR_rt_tgsigqueueinfo 335
-#define __NR_perf_counter_open 336
+#define __NR_perf_event_open 336
+#define __NR_fanotify_init 337
+#define __NR_fanotify_mark 338
+#define __NR_prlimit64 339
-#define NR_syscalls 337
+/* Non-multiplexed socket family */
+#define __NR_socket 340
+#define __NR_bind 341
+#define __NR_connect 342
+#define __NR_listen 343
+#define __NR_accept 344
+#define __NR_getsockname 345
+#define __NR_getpeername 346
+#define __NR_socketpair 347
+#define __NR_send 348
+#define __NR_sendto 349
+#define __NR_recv 350
+#define __NR_recvfrom 351
+#define __NR_shutdown 352
+#define __NR_setsockopt 353
+#define __NR_getsockopt 354
+#define __NR_sendmsg 355
+#define __NR_recvmsg 356
+#define __NR_recvmmsg 357
+#define __NR_accept4 358
+
+#define NR_syscalls 359
#ifdef __KERNEL__
@@ -356,6 +380,7 @@
#define __ARCH_WANT_STAT64
#define __ARCH_WANT_SYS_ALARM
#define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
#define __ARCH_WANT_SYS_PAUSE
#define __ARCH_WANT_SYS_SGETMASK
#define __ARCH_WANT_SYS_SIGNAL
@@ -368,6 +393,7 @@
#define __ARCH_WANT_SYS_LLSEEK
#define __ARCH_WANT_SYS_NICE
#define __ARCH_WANT_SYS_OLD_GETRLIMIT
+#define __ARCH_WANT_SYS_OLD_UNAME
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
diff --git a/arch/sh/include/asm/unistd_64.h b/arch/sh/include/asm/unistd_64.h
index a751699afda..09aa93f9eb7 100644
--- a/arch/sh/include/asm/unistd_64.h
+++ b/arch/sh/include/asm/unistd_64.h
@@ -137,7 +137,7 @@
#define __NR_clone 120
#define __NR_setdomainname 121
#define __NR_uname 122
-#define __NR_modify_ldt 123
+#define __NR_cacheflush 123
#define __NR_adjtimex 124
#define __NR_mprotect 125
#define __NR_sigprocmask 126
@@ -384,11 +384,16 @@
#define __NR_preadv 361
#define __NR_pwritev 362
#define __NR_rt_tgsigqueueinfo 363
-#define __NR_perf_counter_open 364
+#define __NR_perf_event_open 364
+#define __NR_recvmmsg 365
+#define __NR_accept4 366
+#define __NR_fanotify_init 367
+#define __NR_fanotify_mark 368
+#define __NR_prlimit64 369
#ifdef __KERNEL__
-#define NR_syscalls 365
+#define NR_syscalls 370
#define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_OLD_READDIR
@@ -396,6 +401,7 @@
#define __ARCH_WANT_STAT64
#define __ARCH_WANT_SYS_ALARM
#define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
#define __ARCH_WANT_SYS_PAUSE
#define __ARCH_WANT_SYS_SGETMASK
#define __ARCH_WANT_SYS_SIGNAL
@@ -408,6 +414,7 @@
#define __ARCH_WANT_SYS_LLSEEK
#define __ARCH_WANT_SYS_NICE
#define __ARCH_WANT_SYS_OLD_GETRLIMIT
+#define __ARCH_WANT_SYS_OLD_UNAME
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
diff --git a/arch/sh/include/asm/unwinder.h b/arch/sh/include/asm/unwinder.h
new file mode 100644
index 00000000000..1e65c07b3e1
--- /dev/null
+++ b/arch/sh/include/asm/unwinder.h
@@ -0,0 +1,31 @@
+#ifndef _LINUX_UNWINDER_H
+#define _LINUX_UNWINDER_H
+
+#include <asm/stacktrace.h>
+
+struct unwinder {
+ const char *name;
+ struct list_head list;
+ int rating;
+ void (*dump)(struct task_struct *, struct pt_regs *,
+ unsigned long *, const struct stacktrace_ops *, void *);
+};
+
+extern int unwinder_init(void);
+extern int unwinder_register(struct unwinder *);
+
+extern void unwind_stack(struct task_struct *, struct pt_regs *,
+ unsigned long *, const struct stacktrace_ops *,
+ void *);
+
+extern void stack_reader_dump(struct task_struct *, struct pt_regs *,
+ unsigned long *, const struct stacktrace_ops *,
+ void *);
+
+/*
+ * Used by fault handling code to signal to the unwinder code that it
+ * should switch to a different unwinder.
+ */
+extern int unwinder_faulted;
+
+#endif /* _LINUX_UNWINDER_H */
diff --git a/arch/sh/include/asm/vmlinux.lds.h b/arch/sh/include/asm/vmlinux.lds.h
new file mode 100644
index 00000000000..d58ad493b3a
--- /dev/null
+++ b/arch/sh/include/asm/vmlinux.lds.h
@@ -0,0 +1,25 @@
+#ifndef __ASM_SH_VMLINUX_LDS_H
+#define __ASM_SH_VMLINUX_LDS_H
+
+#include <asm-generic/vmlinux.lds.h>
+
+#ifdef CONFIG_DWARF_UNWINDER
+#define DWARF_EH_FRAME \
+ .eh_frame : AT(ADDR(.eh_frame) - LOAD_OFFSET) { \
+ VMLINUX_SYMBOL(__start_eh_frame) = .; \
+ *(.eh_frame) \
+ VMLINUX_SYMBOL(__stop_eh_frame) = .; \
+ }
+#else
+#define DWARF_EH_FRAME
+#endif
+
+#ifdef CONFIG_SUPERH64
+#define EXTRA_TEXT \
+ *(.text64) \
+ *(.text..SHmedia32)
+#else
+#define EXTRA_TEXT
+#endif
+
+#endif /* __ASM_SH_VMLINUX_LDS_H */
diff --git a/arch/sh/include/asm/watchdog.h b/arch/sh/include/asm/watchdog.h
index f024fed00a7..85a7aca7fb8 100644
--- a/arch/sh/include/asm/watchdog.h
+++ b/arch/sh/include/asm/watchdog.h
@@ -2,6 +2,8 @@
* include/asm-sh/watchdog.h
*
* Copyright (C) 2002, 2003 Paul Mundt
+ * Copyright (C) 2009 Siemens AG
+ * Copyright (C) 2009 Valentin Sitdikov
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -13,10 +15,18 @@
#ifdef __KERNEL__
#include <linux/types.h>
+#include <linux/io.h>
+
+#define WTCNT_HIGH 0x5a
+#define WTCSR_HIGH 0xa5
+
+#define WTCSR_CKS2 0x04
+#define WTCSR_CKS1 0x02
+#define WTCSR_CKS0 0x01
+
#include <cpu/watchdog.h>
-#include <asm/io.h>
-/*
+/*
* See cpu-sh2/watchdog.h for explanation of this stupidity..
*/
#ifndef WTCNT_R
@@ -27,13 +37,6 @@
# define WTCSR_R WTCSR
#endif
-#define WTCNT_HIGH 0x5a
-#define WTCSR_HIGH 0xa5
-
-#define WTCSR_CKS2 0x04
-#define WTCSR_CKS1 0x02
-#define WTCSR_CKS0 0x01
-
/*
* CKS0-2 supports a number of clock division ratios. At the time the watchdog
* is enabled, it defaults to a 41 usec overflow period .. we overload this to
@@ -60,13 +63,68 @@
#define WTCSR_CKS_2048 0x06
#define WTCSR_CKS_4096 0x07
+#if defined(CONFIG_CPU_SUBTYPE_SH7785) || defined(CONFIG_CPU_SUBTYPE_SH7780)
+/**
+ * sh_wdt_read_cnt - Read from Counter
+ * Reads back the WTCNT value.
+ */
+static inline __u32 sh_wdt_read_cnt(void)
+{
+ return __raw_readl(WTCNT_R);
+}
+
+/**
+ * sh_wdt_write_cnt - Write to Counter
+ * @val: Value to write
+ *
+ * Writes the given value @val to the lower byte of the timer counter.
+ * The upper byte is set manually on each write.
+ */
+static inline void sh_wdt_write_cnt(__u32 val)
+{
+ __raw_writel((WTCNT_HIGH << 24) | (__u32)val, WTCNT);
+}
+
+/**
+ * sh_wdt_write_bst - Write to Counter
+ * @val: Value to write
+ *
+ * Writes the given value @val to the lower byte of the timer counter.
+ * The upper byte is set manually on each write.
+ */
+static inline void sh_wdt_write_bst(__u32 val)
+{
+ __raw_writel((WTBST_HIGH << 24) | (__u32)val, WTBST);
+}
+/**
+ * sh_wdt_read_csr - Read from Control/Status Register
+ *
+ * Reads back the WTCSR value.
+ */
+static inline __u32 sh_wdt_read_csr(void)
+{
+ return __raw_readl(WTCSR_R);
+}
+
+/**
+ * sh_wdt_write_csr - Write to Control/Status Register
+ * @val: Value to write
+ *
+ * Writes the given value @val to the lower byte of the control/status
+ * register. The upper byte is set manually on each write.
+ */
+static inline void sh_wdt_write_csr(__u32 val)
+{
+ __raw_writel((WTCSR_HIGH << 24) | (__u32)val, WTCSR);
+}
+#else
/**
* sh_wdt_read_cnt - Read from Counter
* Reads back the WTCNT value.
*/
static inline __u8 sh_wdt_read_cnt(void)
{
- return ctrl_inb(WTCNT_R);
+ return __raw_readb(WTCNT_R);
}
/**
@@ -78,7 +136,7 @@ static inline __u8 sh_wdt_read_cnt(void)
*/
static inline void sh_wdt_write_cnt(__u8 val)
{
- ctrl_outw((WTCNT_HIGH << 8) | (__u16)val, WTCNT);
+ __raw_writew((WTCNT_HIGH << 8) | (__u16)val, WTCNT);
}
/**
@@ -88,7 +146,7 @@ static inline void sh_wdt_write_cnt(__u8 val)
*/
static inline __u8 sh_wdt_read_csr(void)
{
- return ctrl_inb(WTCSR_R);
+ return __raw_readb(WTCSR_R);
}
/**
@@ -100,8 +158,8 @@ static inline __u8 sh_wdt_read_csr(void)
*/
static inline void sh_wdt_write_csr(__u8 val)
{
- ctrl_outw((WTCSR_HIGH << 8) | (__u16)val, WTCSR);
+ __raw_writew((WTCSR_HIGH << 8) | (__u16)val, WTCSR);
}
-
+#endif /* CONFIG_CPU_SUBTYPE_SH7785 || CONFIG_CPU_SUBTYPE_SH7780 */
#endif /* __KERNEL__ */
#endif /* __ASM_SH_WATCHDOG_H */