diff options
author | Paul Mundt <lethal@linux-sh.org> | 2011-01-13 15:06:28 +0900 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2011-01-13 15:06:28 +0900 |
commit | f43dc23d5ea91fca257be02138a255f02d98e806 (patch) | |
tree | b29722f6e965316e90ac97abf79923ced250dc21 /arch/sh/include/asm | |
parent | f8e53553f452dcbf67cb89c8cba63a1cd6eb4cc0 (diff) | |
parent | 4162cf64973df51fc885825bc9ca4d055891c49f (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')
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 */ |