From 09a072947791088b88ae15111cf68fc5aaaf758d Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 9 Nov 2009 16:27:40 +0900 Subject: sh: hw-breakpoints: Add preliminary support for SH-4A UBC. This adds preliminary support for the SH-4A UBC to the hw-breakpoints API. Presently only a single channel is implemented, and the ptrace interface still needs to be converted. This is the first step to cleaning up the long-standing UBC mess, making the UBC more generally accessible, and finally making it SMP safe. An additional abstraction will be layered on top of this as with the perf events code to permit the various CPU families to wire up support for their own specific UBCs, as many variations exist. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 1 + arch/sh/include/asm/Kbuild | 4 +- arch/sh/include/asm/hw_breakpoint.h | 53 +++++ arch/sh/include/asm/kdebug.h | 2 + arch/sh/include/asm/processor_32.h | 8 +- arch/sh/include/asm/system.h | 2 - arch/sh/include/asm/thread_info.h | 2 + arch/sh/include/asm/ubc.h | 8 +- arch/sh/kernel/Makefile | 1 + arch/sh/kernel/cpu/sh3/ex.S | 2 +- arch/sh/kernel/hw_breakpoint.c | 416 ++++++++++++++++++++++++++++++++++++ arch/sh/kernel/process_32.c | 94 +------- arch/sh/kernel/ptrace_32.c | 19 -- 13 files changed, 495 insertions(+), 117 deletions(-) create mode 100644 arch/sh/include/asm/hw_breakpoint.h create mode 100644 arch/sh/kernel/hw_breakpoint.c (limited to 'arch/sh') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 88cdeb9f72d9..d563884833e9 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -39,6 +39,7 @@ config SUPERH32 select HAVE_FUNCTION_TRACE_MCOUNT_TEST select HAVE_FUNCTION_GRAPH_TRACER select HAVE_ARCH_KGDB + select HAVE_HW_BREAKPOINT if CPU_SH4A select ARCH_HIBERNATION_POSSIBLE if MMU config SUPERH64 diff --git a/arch/sh/include/asm/Kbuild b/arch/sh/include/asm/Kbuild index e121c30f797d..46cb93477bcb 100644 --- a/arch/sh/include/asm/Kbuild +++ b/arch/sh/include/asm/Kbuild @@ -1,6 +1,8 @@ include include/asm-generic/Kbuild.asm -header-y += cachectl.h cpu-features.h +header-y += cachectl.h +header-y += cpu-features.h +header-y += hw_breakpoint.h unifdef-y += unistd_32.h unifdef-y += unistd_64.h diff --git a/arch/sh/include/asm/hw_breakpoint.h b/arch/sh/include/asm/hw_breakpoint.h new file mode 100644 index 000000000000..0f4a00f60058 --- /dev/null +++ b/arch/sh/include/asm/hw_breakpoint.h @@ -0,0 +1,53 @@ +#ifndef __ASM_SH_HW_BREAKPOINT_H +#define __ASM_SH_HW_BREAKPOINT_H + +#include +#include +#include + +#ifdef __KERNEL__ +#define __ARCH_HW_BREAKPOINT_H + +struct arch_hw_breakpoint { + char *name; /* Contains name of the symbol to set bkpt */ + unsigned long address; + unsigned long asid; + 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), +}; + +/* Total number of available UBC channels */ +#define HBP_NUM 1 /* XXX */ + +struct perf_event; +struct task_struct; +struct pmu; + +extern int arch_check_va_in_userspace(unsigned long va, u16 hbp_len); +extern int arch_validate_hwbkpt_settings(struct perf_event *bp, + struct task_struct *tsk); +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); +void hw_breakpoint_pmu_unthrottle(struct perf_event *bp); + +extern void arch_fill_perf_breakpoint(struct perf_event *bp); + +extern struct pmu perf_ops_bp; + +#endif /* __KERNEL__ */ +#endif /* __ASM_SH_HW_BREAKPOINT_H */ diff --git a/arch/sh/include/asm/kdebug.h b/arch/sh/include/asm/kdebug.h index 985219f9759e..5f6d2e9ccb7c 100644 --- a/arch/sh/include/asm/kdebug.h +++ b/arch/sh/include/asm/kdebug.h @@ -6,6 +6,8 @@ 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/processor_32.h b/arch/sh/include/asm/processor_32.h index 9a8714945dc9..f4b54040dbc3 100644 --- a/arch/sh/include/asm/processor_32.h +++ b/arch/sh/include/asm/processor_32.h @@ -14,6 +14,7 @@ #include #include #include +#include /* * Default implementation of macro that returns current @@ -99,8 +100,8 @@ struct thread_struct { unsigned long sp; unsigned long pc; - /* Hardware debugging registers */ - unsigned long ubc_pc; + /* Save middle states of ptrace breakpoints */ + struct perf_event *ptrace_bps[NR_UBC_CHANNELS]; /* floating point info */ union sh_fpu_union fpu; @@ -111,9 +112,6 @@ struct thread_struct { #endif }; -/* Count of active tasks with UBC settings */ -extern int ubc_usercnt; - #define INIT_THREAD { \ .sp = sizeof(init_stack) + (long) &init_stack, \ } diff --git a/arch/sh/include/asm/system.h b/arch/sh/include/asm/system.h index b5c5acdc8c0e..1014da8b3ed3 100644 --- a/arch/sh/include/asm/system.h +++ b/arch/sh/include/asm/system.h @@ -144,8 +144,6 @@ void per_cpu_trap_init(void); void default_idle(void); void cpu_idle_wait(void); -asmlinkage void break_point_trap(void); - #ifdef CONFIG_SUPERH32 #define BUILD_TRAP_HANDLER(name) \ asmlinkage void name##_trap_handler(unsigned long r4, unsigned long r5, \ diff --git a/arch/sh/include/asm/thread_info.h b/arch/sh/include/asm/thread_info.h index bdeb9d46d17d..8ab9145bf50b 100644 --- a/arch/sh/include/asm/thread_info.h +++ b/arch/sh/include/asm/thread_info.h @@ -117,6 +117,7 @@ extern void free_thread_info(struct thread_info *ti); #define TIF_SECCOMP 6 /* secure computing */ #define TIF_NOTIFY_RESUME 7 /* callback before returning to user */ #define TIF_SYSCALL_TRACEPOINT 8 /* for ftrace syscall instrumentation */ +#define TIF_DEBUG 9 /* uses UBC */ #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */ #define TIF_MEMDIE 18 @@ -131,6 +132,7 @@ extern void free_thread_info(struct thread_info *ti); #define _TIF_SECCOMP (1 << TIF_SECCOMP) #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) #define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) +#define _TIF_DEBUG (1 << TIF_DEBUG) #define _TIF_USEDFPU (1 << TIF_USEDFPU) #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) #define _TIF_FREEZE (1 << TIF_FREEZE) diff --git a/arch/sh/include/asm/ubc.h b/arch/sh/include/asm/ubc.h index 4ca4b7717371..dd7878197b6e 100644 --- a/arch/sh/include/asm/ubc.h +++ b/arch/sh/include/asm/ubc.h @@ -10,8 +10,8 @@ */ #ifndef __ASM_SH_UBC_H #define __ASM_SH_UBC_H -#ifdef __KERNEL__ +#ifdef __KERNEL__ #include /* User Break Controller */ @@ -60,6 +60,12 @@ #define BRCR_UBDE (1 << 0) #endif +/* + * All SH parts have 2 UBC channels. I defy any hardware designer to + * invalidate this assertion. + */ +#define NR_UBC_CHANNELS 2 + #ifndef __ASSEMBLY__ /* arch/sh/kernel/cpu/ubc.S */ extern void ubc_sleep(void); diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile index a2d0a40f3848..649daadd4519 100644 --- a/arch/sh/kernel/Makefile +++ b/arch/sh/kernel/Makefile @@ -36,6 +36,7 @@ obj-$(CONFIG_DUMP_CODE) += disassemble.o obj-$(CONFIG_HIBERNATION) += swsusp.o obj-$(CONFIG_DWARF_UNWINDER) += dwarf.o +obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += localtimer.o EXTRA_CFLAGS += -Werror diff --git a/arch/sh/kernel/cpu/sh3/ex.S b/arch/sh/kernel/cpu/sh3/ex.S index 46610c35c232..99b4d020179a 100644 --- a/arch/sh/kernel/cpu/sh3/ex.S +++ b/arch/sh/kernel/cpu/sh3/ex.S @@ -49,7 +49,7 @@ ENTRY(exception_handling_table) .long exception_error ! reserved_instruction (filled by trap_init) /* 180 */ .long exception_error ! illegal_slot_instruction (filled by trap_init) /*1A0*/ .long nmi_trap_handler /* 1C0 */ ! Allow trap to debugger - .long break_point_trap /* 1E0 */ + .long breakpoint_trap_handler /* 1E0 */ /* * Pad the remainder of the table out, exceptions residing in far diff --git a/arch/sh/kernel/hw_breakpoint.c b/arch/sh/kernel/hw_breakpoint.c new file mode 100644 index 000000000000..ff3cb3d7df8f --- /dev/null +++ b/arch/sh/kernel/hw_breakpoint.c @@ -0,0 +1,416 @@ +/* + * arch/sh/kernel/hw_breakpoint.c + * + * Unified kernel/user-space hardware breakpoint facility for the on-chip UBC. + * + * Copyright (C) 2009 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. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct ubc_context { + unsigned long pc; + unsigned long state; +}; + +/* Per cpu ubc channel state */ +static DEFINE_PER_CPU(struct ubc_context, ubc_ctx[HBP_NUM]); + +/* + * Stores the breakpoints currently in use on each breakpoint address + * register for each cpus + */ +static DEFINE_PER_CPU(struct perf_event *, bp_per_reg[HBP_NUM]); + +static int __init ubc_init(void) +{ + __raw_writel(0, UBC_CAMR0); + __raw_writel(0, UBC_CBR0); + __raw_writel(0, UBC_CBCR); + + __raw_writel(UBC_CRR_BIE | UBC_CRR_PCB, UBC_CRR0); + + /* dummy read for write posting */ + (void)__raw_readl(UBC_CRR0); + + return 0; +} +arch_initcall(ubc_init); + +/* + * Install a perf counter breakpoint. + * + * We seek a free UBC channel and use it for this breakpoint. + * + * Atomic: we hold the counter->ctx->lock and we only handle variables + * and registers local to this cpu. + */ +int arch_install_hw_breakpoint(struct perf_event *bp) +{ + struct arch_hw_breakpoint *info = counter_arch_bp(bp); + struct ubc_context *ubc_ctx; + int i; + + for (i = 0; i < HBP_NUM; i++) { + struct perf_event **slot = &__get_cpu_var(bp_per_reg[i]); + + if (!*slot) { + *slot = bp; + break; + } + } + + if (WARN_ONCE(i == HBP_NUM, "Can't find any breakpoint slot")) + return -EBUSY; + + ubc_ctx = &__get_cpu_var(ubc_ctx[i]); + + ubc_ctx->pc = info->address; + ubc_ctx->state = info->len | info->type; + + __raw_writel(UBC_CBR_CE | ubc_ctx->state, UBC_CBR0); + __raw_writel(ubc_ctx->pc, UBC_CAR0); + + return 0; +} + +/* + * Uninstall the breakpoint contained in the given counter. + * + * First we search the debug address register it uses and then we disable + * it. + * + * Atomic: we hold the counter->ctx->lock and we only handle variables + * and registers local to this cpu. + */ +void arch_uninstall_hw_breakpoint(struct perf_event *bp) +{ + struct arch_hw_breakpoint *info = counter_arch_bp(bp); + struct ubc_context *ubc_ctx; + int i; + + for (i = 0; i < HBP_NUM; i++) { + struct perf_event **slot = &__get_cpu_var(bp_per_reg[i]); + + if (*slot == bp) { + *slot = NULL; + break; + } + } + + if (WARN_ONCE(i == HBP_NUM, "Can't find any breakpoint slot")) + return; + + ubc_ctx = &__get_cpu_var(ubc_ctx[i]); + ubc_ctx->pc = 0; + ubc_ctx->state &= ~(info->len | info->type); + + __raw_writel(ubc_ctx->pc, UBC_CBR0); + __raw_writel(ubc_ctx->state, UBC_CAR0); +} + +static int get_hbp_len(u16 hbp_len) +{ + unsigned int len_in_bytes = 0; + + switch (hbp_len) { + case SH_BREAKPOINT_LEN_1: + len_in_bytes = 1; + break; + case SH_BREAKPOINT_LEN_2: + len_in_bytes = 2; + break; + case SH_BREAKPOINT_LEN_4: + len_in_bytes = 4; + break; + case SH_BREAKPOINT_LEN_8: + len_in_bytes = 8; + break; + } + return len_in_bytes; +} + +/* + * Check for virtual address in user space. + */ +int arch_check_va_in_userspace(unsigned long va, u16 hbp_len) +{ + unsigned int len; + + len = get_hbp_len(hbp_len); + + return (va <= TASK_SIZE - len); +} + +/* + * Check for virtual address in kernel space. + */ +static int arch_check_va_in_kernelspace(unsigned long va, u8 hbp_len) +{ + unsigned int len; + + len = get_hbp_len(hbp_len); + + return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE); +} + +/* + * Store a breakpoint's encoded address, length, and type. + */ +static int arch_store_info(struct perf_event *bp) +{ + struct arch_hw_breakpoint *info = counter_arch_bp(bp); + + /* + * User-space requests will always have the address field populated + * For kernel-addresses, either the address or symbol name can be + * specified. + */ + if (info->name) + info->address = (unsigned long)kallsyms_lookup_name(info->name); + if (info->address) { + info->asid = get_asid(); + return 0; + } + + return -EINVAL; +} + +int arch_bp_generic_fields(int sh_len, int sh_type, + int *gen_len, int *gen_type) +{ + /* Len */ + switch (sh_len) { + case SH_BREAKPOINT_LEN_1: + *gen_len = HW_BREAKPOINT_LEN_1; + break; + case SH_BREAKPOINT_LEN_2: + *gen_len = HW_BREAKPOINT_LEN_2; + break; + case SH_BREAKPOINT_LEN_4: + *gen_len = HW_BREAKPOINT_LEN_4; + break; + case SH_BREAKPOINT_LEN_8: + *gen_len = HW_BREAKPOINT_LEN_8; + break; + default: + return -EINVAL; + } + + /* Type */ + switch (sh_type) { + case SH_BREAKPOINT_READ: + *gen_type = HW_BREAKPOINT_R; + case SH_BREAKPOINT_WRITE: + *gen_type = HW_BREAKPOINT_W; + break; + case SH_BREAKPOINT_RW: + *gen_type = HW_BREAKPOINT_W | HW_BREAKPOINT_R; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int arch_build_bp_info(struct perf_event *bp) +{ + struct arch_hw_breakpoint *info = counter_arch_bp(bp); + + info->address = bp->attr.bp_addr; + + /* Len */ + switch (bp->attr.bp_len) { + case HW_BREAKPOINT_LEN_1: + info->len = SH_BREAKPOINT_LEN_1; + break; + case HW_BREAKPOINT_LEN_2: + info->len = SH_BREAKPOINT_LEN_2; + break; + case HW_BREAKPOINT_LEN_4: + info->len = SH_BREAKPOINT_LEN_4; + break; + case HW_BREAKPOINT_LEN_8: + info->len = SH_BREAKPOINT_LEN_8; + break; + default: + return -EINVAL; + } + + /* Type */ + switch (bp->attr.bp_type) { + case HW_BREAKPOINT_R: + info->type = SH_BREAKPOINT_READ; + break; + case HW_BREAKPOINT_W: + info->type = SH_BREAKPOINT_WRITE; + break; + case HW_BREAKPOINT_W | HW_BREAKPOINT_R: + info->type = SH_BREAKPOINT_RW; + break; + default: + return -EINVAL; + } + + return 0; +} + +/* + * Validate the arch-specific HW Breakpoint register settings + */ +int arch_validate_hwbkpt_settings(struct perf_event *bp, + struct task_struct *tsk) +{ + struct arch_hw_breakpoint *info = counter_arch_bp(bp); + unsigned int align; + int ret; + + ret = arch_build_bp_info(bp); + if (ret) + return ret; + + ret = -EINVAL; + + switch (info->len) { + case SH_BREAKPOINT_LEN_1: + align = 0; + break; + case SH_BREAKPOINT_LEN_2: + align = 1; + break; + case SH_BREAKPOINT_LEN_4: + align = 3; + break; + case SH_BREAKPOINT_LEN_8: + align = 7; + break; + default: + return ret; + } + + if (bp->callback) + ret = arch_store_info(bp); + + if (ret < 0) + return ret; + + /* + * Check that the low-order bits of the address are appropriate + * for the alignment implied by len. + */ + if (info->address & align) + return -EINVAL; + + /* Check that the virtual address is in the proper range */ + if (tsk) { + if (!arch_check_va_in_userspace(info->address, info->len)) + return -EFAULT; + } else { + if (!arch_check_va_in_kernelspace(info->address, info->len)) + return -EFAULT; + } + + return 0; +} + +/* + * Release the user breakpoints used by ptrace + */ +void flush_ptrace_hw_breakpoint(struct task_struct *tsk) +{ + int i; + struct thread_struct *t = &tsk->thread; + + for (i = 0; i < HBP_NUM; i++) { + unregister_hw_breakpoint(t->ptrace_bps[i]); + t->ptrace_bps[i] = NULL; + } +} + +static int __kprobes hw_breakpoint_handler(struct die_args *args) +{ + int cpu, i, rc = NOTIFY_STOP; + struct perf_event *bp; + unsigned long val; + + val = __raw_readl(UBC_CBR0); + __raw_writel(val & ~UBC_CBR_CE, UBC_CBR0); + + cpu = get_cpu(); + for (i = 0; i < HBP_NUM; i++) { + /* + * The counter may be concurrently released but that can only + * occur from a call_rcu() path. We can then safely fetch + * the breakpoint, use its callback, touch its counter + * while we are in an rcu_read_lock() path. + */ + rcu_read_lock(); + + bp = per_cpu(bp_per_reg[i], cpu); + if (bp) { + rc = NOTIFY_DONE; + } else { + rcu_read_unlock(); + break; + } + + (bp->callback)(bp, args->regs); + + rcu_read_unlock(); + } + + if (bp) { + struct arch_hw_breakpoint *info = counter_arch_bp(bp); + + __raw_writel(UBC_CBR_CE | info->len | info->type, UBC_CBR0); + __raw_writel(info->address, UBC_CAR0); + } + + put_cpu(); + + return rc; +} + +BUILD_TRAP_HANDLER(breakpoint) +{ + unsigned long ex = lookup_exception_vector(); + TRAP_HANDLER_DECL; + + notify_die(DIE_BREAKPOINT, "breakpoint", regs, 0, ex, SIGTRAP); +} + +/* + * Handle debug exception notifications. + */ +int __kprobes hw_breakpoint_exceptions_notify(struct notifier_block *unused, + unsigned long val, void *data) +{ + if (val != DIE_BREAKPOINT) + return NOTIFY_DONE; + + return hw_breakpoint_handler(data); +} + +void hw_breakpoint_pmu_read(struct perf_event *bp) +{ + /* TODO */ +} + +void hw_breakpoint_pmu_unthrottle(struct perf_event *bp) +{ + /* TODO */ +} diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c index 0673c4746be3..4a2c866f9773 100644 --- a/arch/sh/kernel/process_32.c +++ b/arch/sh/kernel/process_32.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -34,8 +35,6 @@ #include #include -int ubc_usercnt = 0; - #ifdef CONFIG_32BIT static void watchdog_trigger_immediate(void) { @@ -148,16 +147,15 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) */ void exit_thread(void) { - if (current->thread.ubc_pc) { - current->thread.ubc_pc = 0; - ubc_usercnt -= 1; - } } void flush_thread(void) { -#if defined(CONFIG_SH_FPU) struct task_struct *tsk = current; + + flush_ptrace_hw_breakpoint(tsk); + +#if defined(CONFIG_SH_FPU) /* Forget lazy FPU state */ clear_fpu(tsk, task_pt_regs(tsk)); clear_used_math(); @@ -195,9 +193,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, { struct thread_info *ti = task_thread_info(p); struct pt_regs *childregs; -#if defined(CONFIG_SH_FPU) || defined(CONFIG_SH_DSP) struct task_struct *tsk = current; -#endif #if defined(CONFIG_SH_FPU) unlazy_fpu(tsk, regs); @@ -234,53 +230,11 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, p->thread.sp = (unsigned long) childregs; p->thread.pc = (unsigned long) ret_from_fork; - p->thread.ubc_pc = 0; + memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps)); return 0; } -/* Tracing by user break controller. */ -static void ubc_set_tracing(int asid, unsigned long pc) -{ -#if defined(CONFIG_CPU_SH4A) - unsigned long val; - - val = (UBC_CBR_ID_INST | UBC_CBR_RW_READ | UBC_CBR_CE); - val |= (UBC_CBR_AIE | UBC_CBR_AIV_SET(asid)); - - ctrl_outl(val, UBC_CBR0); - ctrl_outl(pc, UBC_CAR0); - ctrl_outl(0x0, UBC_CAMR0); - ctrl_outl(0x0, UBC_CBCR); - - val = (UBC_CRR_RES | UBC_CRR_PCB | UBC_CRR_BIE); - ctrl_outl(val, UBC_CRR0); - - /* Read UBC register that we wrote last, for checking update */ - val = ctrl_inl(UBC_CRR0); - -#else /* CONFIG_CPU_SH4A */ - ctrl_outl(pc, UBC_BARA); - -#ifdef CONFIG_MMU - ctrl_outb(asid, UBC_BASRA); -#endif - - ctrl_outl(0, UBC_BAMRA); - - if (current_cpu_data.type == CPU_SH7729 || - current_cpu_data.type == CPU_SH7710 || - current_cpu_data.type == CPU_SH7712 || - current_cpu_data.type == CPU_SH7203){ - ctrl_outw(BBR_INST | BBR_READ | BBR_CPU, UBC_BBRA); - ctrl_outl(BRCR_PCBA | BRCR_PCTE, UBC_BRCR); - } else { - ctrl_outw(BBR_INST | BBR_READ, UBC_BBRA); - ctrl_outw(BRCR_PCBA, UBC_BRCR); - } -#endif /* CONFIG_CPU_SH4A */ -} - /* * switch_to(x,y) should switch tasks from x to y. * @@ -302,25 +256,6 @@ __switch_to(struct task_struct *prev, struct task_struct *next) : "r" (task_thread_info(next))); #endif - /* If no tasks are using the UBC, we're done */ - if (ubc_usercnt == 0) - /* If no tasks are using the UBC, we're done */; - else if (next->thread.ubc_pc && next->mm) { - int asid = 0; -#ifdef CONFIG_MMU - asid |= cpu_asid(smp_processor_id(), next->mm); -#endif - ubc_set_tracing(asid, next->thread.ubc_pc); - } else { -#if defined(CONFIG_CPU_SH4A) - ctrl_outl(UBC_CBR_INIT, UBC_CBR0); - ctrl_outl(UBC_CRR_INIT, UBC_CRR0); -#else - ctrl_outw(0, UBC_BBRA); - ctrl_outw(0, UBC_BBRB); -#endif - } - return prev; } @@ -412,20 +347,3 @@ unsigned long get_wchan(struct task_struct *p) return pc; } - -asmlinkage void break_point_trap(void) -{ - /* Clear tracing. */ -#if defined(CONFIG_CPU_SH4A) - ctrl_outl(UBC_CBR_INIT, UBC_CBR0); - ctrl_outl(UBC_CRR_INIT, UBC_CRR0); -#else - ctrl_outw(0, UBC_BBRA); - ctrl_outw(0, UBC_BBRB); - ctrl_outl(0, UBC_BRCR); -#endif - current->thread.ubc_pc = 0; - ubc_usercnt -= 1; - - force_sig(SIGTRAP, current); -} diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c index 9be35f348093..bdb10446cbac 100644 --- a/arch/sh/kernel/ptrace_32.c +++ b/arch/sh/kernel/ptrace_32.c @@ -65,31 +65,12 @@ static inline int put_stack_long(struct task_struct *task, int offset, void user_enable_single_step(struct task_struct *child) { - /* Next scheduling will set up UBC */ - if (child->thread.ubc_pc == 0) - ubc_usercnt += 1; - - child->thread.ubc_pc = get_stack_long(child, - offsetof(struct pt_regs, pc)); - set_tsk_thread_flag(child, TIF_SINGLESTEP); } void user_disable_single_step(struct task_struct *child) { clear_tsk_thread_flag(child, TIF_SINGLESTEP); - - /* - * Ensure the UBC is not programmed at the next context switch. - * - * Normally this is not needed but there are sequences such as - * singlestep, signal delivery, and continue that leave the - * ubc_pc non-zero leading to spurious SIGTRAPs. - */ - if (child->thread.ubc_pc != 0) { - ubc_usercnt -= 1; - child->thread.ubc_pc = 0; - } } /* -- cgit v1.2.3 From b73c806341cfc7492ede6a2ce713cb579547d0ab Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Wed, 25 Nov 2009 22:00:08 +0000 Subject: sh: Abstract the number of page table levels Keep the dimensions of the page tables in a separate header file in preparation for allowing a three level page table structure. Signed-off-by: Matt Fleming Signed-off-by: Paul Mundt --- arch/sh/include/asm/pgalloc.h | 24 +++--------------------- arch/sh/include/asm/pgalloc_nopmd.h | 30 ++++++++++++++++++++++++++++++ arch/sh/include/asm/pgtable.h | 18 +----------------- arch/sh/include/asm/pgtable_nopmd.h | 22 ++++++++++++++++++++++ 4 files changed, 56 insertions(+), 38 deletions(-) create mode 100644 arch/sh/include/asm/pgalloc_nopmd.h create mode 100644 arch/sh/include/asm/pgtable_nopmd.h (limited to 'arch/sh') diff --git a/arch/sh/include/asm/pgalloc.h b/arch/sh/include/asm/pgalloc.h index 63ca37bd9a95..fe9f037ac5fd 100644 --- a/arch/sh/include/asm/pgalloc.h +++ b/arch/sh/include/asm/pgalloc.h @@ -4,9 +4,10 @@ #include #include -#define QUICK_PGD 0 /* We preserve special mappings over free */ #define QUICK_PT 1 /* Other page table pages that are zero on free */ +#include + static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte) { @@ -20,28 +21,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) { @@ -81,7 +63,7 @@ do { \ static inline void check_pgt_cache(void) { - quicklist_trim(QUICK_PGD, NULL, 25, 16); + __check_pgt_cache(); quicklist_trim(QUICK_PT, NULL, 25, 16); } diff --git a/arch/sh/include/asm/pgalloc_nopmd.h b/arch/sh/include/asm/pgalloc_nopmd.h new file mode 100644 index 000000000000..e4b344c37e74 --- /dev/null +++ b/arch/sh/include/asm/pgalloc_nopmd.h @@ -0,0 +1,30 @@ +#ifndef __ASM_SH_PGALLOC_NOPMD_H +#define __ASM_SH_PGALLOC_NOPMD_H + +#define QUICK_PGD 0 /* We preserve special mappings over free */ + +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)); +} + +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 void __check_pgt_cache(void) +{ + quicklist_trim(QUICK_PGD, NULL, 25, 16); +} + +#endif /* __ASM_SH_PGALLOC_NOPMD_H */ diff --git a/arch/sh/include/asm/pgtable.h b/arch/sh/include/asm/pgtable.h index ba3046e4f06f..9a0f66c1134c 100644 --- a/arch/sh/include/asm/pgtable.h +++ b/arch/sh/include/asm/pgtable.h @@ -12,7 +12,7 @@ #ifndef __ASM_SH_PGTABLE_H #define __ASM_SH_PGTABLE_H -#include +#include #include #ifndef __ASSEMBLY__ @@ -51,28 +51,12 @@ static inline unsigned long long neff_sign_extend(unsigned long val) #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 #define PHYS_ADDR_MASK29 0x1fffffff diff --git a/arch/sh/include/asm/pgtable_nopmd.h b/arch/sh/include/asm/pgtable_nopmd.h new file mode 100644 index 000000000000..f0b525b3cb4a --- /dev/null +++ b/arch/sh/include/asm/pgtable_nopmd.h @@ -0,0 +1,22 @@ +#ifndef __ASM_SH_PGTABLE_NOPMD_H +#define __ASM_SH_PGTABLE_NOPMD_H + +#include + +/* + * traditional two-level paging structure + */ + +/* 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_NOPMD_H */ -- cgit v1.2.3 From 5d9b4b19f118abfb75e352841f7bf74580d7e427 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Sun, 13 Dec 2009 14:38:50 +0000 Subject: sh: Definitions for 3-level page table layout If using 64-bit PTEs and 4K pages then each page table has 512 entries (as opposed to 1024 entries with 32-bit PTEs). Unlike MIPS, SH follows the convention that all structures in the page table (pgd_t, pmd_t, pgprot_t, etc) must be the same size. Therefore, 64-bit PTEs require 64-bit PGD entries, etc. Using 2-levels of page tables and 64-bit PTEs it is only possible to map 1GB of virtual address space. In order to map all 4GB of virtual address space we need to adopt a 3-level page table layout. This actually works out better for CONFIG_SUPERH32 because we only waste 2 PGD entries on the P1 and P2 areas (which are untranslated) instead of 256. Signed-off-by: Matt Fleming Signed-off-by: Paul Mundt --- arch/sh/include/asm/pgalloc.h | 4 +++ arch/sh/include/asm/pgalloc_pmd.h | 41 +++++++++++++++++++++++++++++ arch/sh/include/asm/pgtable.h | 4 +++ arch/sh/include/asm/pgtable_pmd.h | 55 +++++++++++++++++++++++++++++++++++++++ arch/sh/mm/Kconfig | 24 ++++++++++++++--- arch/sh/mm/fault_32.c | 3 +++ arch/sh/mm/init.c | 6 +++++ 7 files changed, 134 insertions(+), 3 deletions(-) create mode 100644 arch/sh/include/asm/pgalloc_pmd.h create mode 100644 arch/sh/include/asm/pgtable_pmd.h (limited to 'arch/sh') diff --git a/arch/sh/include/asm/pgalloc.h b/arch/sh/include/asm/pgalloc.h index fe9f037ac5fd..4ea27855c3b5 100644 --- a/arch/sh/include/asm/pgalloc.h +++ b/arch/sh/include/asm/pgalloc.h @@ -6,7 +6,11 @@ #define QUICK_PT 1 /* Other page table pages that are zero on free */ +#ifdef CONFIG_PGTABLE_LEVELS_3 +#include +#else #include +#endif static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte) diff --git a/arch/sh/include/asm/pgalloc_pmd.h b/arch/sh/include/asm/pgalloc_pmd.h new file mode 100644 index 000000000000..20f75cc4eb09 --- /dev/null +++ b/arch/sh/include/asm/pgalloc_pmd.h @@ -0,0 +1,41 @@ +#ifndef __ASM_SH_PGALLOC_PMD_H +#define __ASM_SH_PGALLOC_PMD_H + +static inline pgd_t *pgd_alloc(struct mm_struct *mm) +{ + pgd_t *pgd; + int i; + + pgd = kzalloc(sizeof(*pgd) * PTRS_PER_PGD, GFP_KERNEL | __GFP_REPEAT); + + for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) + pgd[i] = swapper_pg_dir[i]; + + return pgd; +} + +static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) +{ + kfree(pgd); +} + +static inline void __check_pgt_cache(void) +{ +} + +static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) +{ + set_pud(pud, __pud((unsigned long)pmd)); +} + +static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) +{ + return quicklist_alloc(QUICK_PT, GFP_KERNEL | __GFP_REPEAT, NULL); +} + +static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) +{ + quicklist_free(QUICK_PT, NULL, pmd); +} + +#endif /* __ASM_SH_PGALLOC_PMD_H */ diff --git a/arch/sh/include/asm/pgtable.h b/arch/sh/include/asm/pgtable.h index 9a0f66c1134c..9effcc3b0d10 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 +#ifdef CONFIG_PGTABLE_LEVELS_3 +#include +#else #include +#endif #include #ifndef __ASSEMBLY__ diff --git a/arch/sh/include/asm/pgtable_pmd.h b/arch/sh/include/asm/pgtable_pmd.h new file mode 100644 index 000000000000..78dc36e1c2dd --- /dev/null +++ b/arch/sh/include/asm/pgtable_pmd.h @@ -0,0 +1,55 @@ +#ifndef __ASM_SH_PGTABLE_PMD_H +#define __ASM_SH_PGTABLE_PMD_H + +#include + +/* + * Some cores need a 3-level page table layout, for example when using + * 64-bit PTEs and 4K pages. + */ + +#define PTE_MAGNITUDE 3 /* 64-bit PTEs on extended mode 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 - 3)) +#define PMD_SIZE (1UL << PMD_SHIFT) +#define PMD_MASK (~(PMD_SIZE-1)) + +#define PTRS_PER_PMD (PAGE_SIZE / sizeof(pmd_t)) + +#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_PMD_H */ diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index 0e7ba8e891cf..b3f6c1a30b22 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig @@ -189,6 +189,24 @@ config ARCH_MEMORY_PROBE def_bool y depends on MEMORY_HOTPLUG +choice + prompt "Page table layout" + default PGTABLE_LEVELS_3 if X2TLB + default PGTABLE_LEVELS_2 + +config PGTABLE_LEVELS_2 + bool "2 Levels" + help + This is the default page table layout for all SuperH CPUs. + +config PGTABLE_LEVELS_3 + bool "3 Levels" + depends on X2TLB + help + This enables a 3 level page table structure. + +endchoice + choice prompt "Kernel page size" default PAGE_SIZE_8KB if X2TLB @@ -196,13 +214,13 @@ choice config PAGE_SIZE_4KB bool "4kB" - depends on !MMU || !X2TLB + depends on !MMU || !X2TLB || PGTABLE_LEVELS_3 help This is the default page size used by all SuperH CPUs. config PAGE_SIZE_8KB bool "8kB" - depends on !MMU || X2TLB + depends on !MMU || X2TLB && !PGTABLE_LEVELS_3 help This enables 8kB pages as supported by SH-X2 and later MMUs. @@ -214,7 +232,7 @@ config PAGE_SIZE_16KB config PAGE_SIZE_64KB bool "64kB" - depends on !MMU || CPU_SH4 || CPU_SH5 + depends on !MMU || CPU_SH4 && !PGTABLE_LEVELS_3 || CPU_SH5 help This enables support for 64kB pages, possible on all SH-4 CPUs and later. diff --git a/arch/sh/mm/fault_32.c b/arch/sh/mm/fault_32.c index 47530104e0ad..28e22839c665 100644 --- a/arch/sh/mm/fault_32.c +++ b/arch/sh/mm/fault_32.c @@ -53,6 +53,9 @@ static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address) if (!pud_present(*pud_k)) return NULL; + if (!pud_present(*pud)) + set_pud(pud, *pud_k); + pmd = pmd_offset(pud, address); pmd_k = pmd_offset(pud_k, address); if (!pmd_present(*pmd_k)) diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 432acd07e76a..761910d142f8 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -120,7 +120,13 @@ void __init page_table_range_init(unsigned long start, unsigned long end, for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) { pud = (pud_t *)pgd; for ( ; (j < PTRS_PER_PUD) && (vaddr != end); pud++, j++) { +#ifdef __PAGETABLE_PMD_FOLDED pmd = (pmd_t *)pud; +#else + pmd = (pmd_t *)alloc_bootmem_low_pages(PAGE_SIZE); + pud_populate(&init_mm, pud, pmd); + pmd += k; +#endif for (; (k < PTRS_PER_PMD) && (vaddr != end); pmd++, k++) { if (pmd_none(*pmd)) { pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); -- cgit v1.2.3 From a28b460ec7968f430a2d6ea2809b249ee9fe1d28 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 21 Dec 2009 15:56:24 +0900 Subject: sh: Fix up hw-breakpoints build for API changes. The event callback handling has been removed in favour of going through a generic event handler to handle overflows. Follows the x86 change. Signed-off-by: Paul Mundt --- arch/sh/kernel/hw_breakpoint.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/kernel/hw_breakpoint.c b/arch/sh/kernel/hw_breakpoint.c index ff3cb3d7df8f..75b8c471120f 100644 --- a/arch/sh/kernel/hw_breakpoint.c +++ b/arch/sh/kernel/hw_breakpoint.c @@ -302,8 +302,7 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp, return ret; } - if (bp->callback) - ret = arch_store_info(bp); + ret = arch_store_info(bp); if (ret < 0) return ret; @@ -368,7 +367,7 @@ static int __kprobes hw_breakpoint_handler(struct die_args *args) break; } - (bp->callback)(bp, args->regs); + perf_bp_event(bp, args->regs); rcu_read_unlock(); } -- cgit v1.2.3 From 6c0ee6a4bba0e21eb0fb4de5bdac03c11b74242d Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 21 Dec 2009 17:35:00 +0900 Subject: sh: hw-breakpoint support requires perf events. This follows the x86 change to select perf events when hw_breakpoint support is enabled. This fixes up build issues where perf events can otherwise be disabled on their own. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/sh') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 185e9af251cf..fa76d6264dff 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -43,6 +43,7 @@ config SUPERH32 select HAVE_FUNCTION_GRAPH_TRACER select HAVE_ARCH_KGDB select HAVE_HW_BREAKPOINT if CPU_SH4A + select PERF_EVENTS if HAVE_HW_BREAKPOINT select ARCH_HIBERNATION_POSSIBLE if MMU config SUPERH64 -- cgit v1.2.3 From b74ab703b1326aafadb5604ff6200da62c61df49 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 22 Dec 2009 12:40:38 +0900 Subject: sh: Don't NOTIFY_STOP for non-UBC breakpoint traps. Presently the hw_breakpoint code is the primary notifier dispatch for breakpoint traps, although it's only UBC traps that are of particular interest there. This patches in a check to allow non-UBC generated breakpoints to pass through down the remainder of the notifier chain, giving things like kgdb a chance at getting notified. Signed-off-by: Paul Mundt --- arch/sh/kernel/hw_breakpoint.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/kernel/hw_breakpoint.c b/arch/sh/kernel/hw_breakpoint.c index 75b8c471120f..022d8ed66bd6 100644 --- a/arch/sh/kernel/hw_breakpoint.c +++ b/arch/sh/kernel/hw_breakpoint.c @@ -398,9 +398,18 @@ BUILD_TRAP_HANDLER(breakpoint) int __kprobes hw_breakpoint_exceptions_notify(struct notifier_block *unused, unsigned long val, void *data) { + struct die_args *args = data; + if (val != DIE_BREAKPOINT) return NOTIFY_DONE; + /* + * If the breakpoint hasn't been triggered by the UBC, it's + * probably from a debugger, so don't do anything more here. + */ + if (args->trapnr != 0x1e0) + return NOTIFY_DONE; + return hw_breakpoint_handler(data); } -- cgit v1.2.3 From 22648735405f73299b717bb5933767e9a9c335ca Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 22 Dec 2009 12:44:14 +0900 Subject: sh: kgdb: Rework breakpoint handling on top of notifier chain. This kills off kgdb's breakpoint handler and ties in to the notifier chain instead. Signed-off-by: Paul Mundt --- arch/sh/kernel/debugtraps.S | 1 - arch/sh/kernel/kgdb.c | 46 ++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 41 insertions(+), 6 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/kernel/debugtraps.S b/arch/sh/kernel/debugtraps.S index 591741383ee6..7a1b46fec0f4 100644 --- a/arch/sh/kernel/debugtraps.S +++ b/arch/sh/kernel/debugtraps.S @@ -13,7 +13,6 @@ #include #if !defined(CONFIG_KGDB) -#define breakpoint_trap_handler debug_trap_handler #define singlestep_trap_handler debug_trap_handler #endif diff --git a/arch/sh/kernel/kgdb.c b/arch/sh/kernel/kgdb.c index 3e532d0d4a5c..70c69659b846 100644 --- a/arch/sh/kernel/kgdb.c +++ b/arch/sh/kernel/kgdb.c @@ -1,7 +1,7 @@ /* * SuperH KGDB support * - * Copyright (C) 2008 Paul Mundt + * Copyright (C) 2008 - 2009 Paul Mundt * * Single stepping taken from the old stub by Henry Bell and Jeremy Siegel. * @@ -251,24 +251,60 @@ BUILD_TRAP_HANDLER(singlestep) local_irq_restore(flags); } +static int __kgdb_notify(struct die_args *args, unsigned long cmd) +{ + int ret; + + switch (cmd) { + case DIE_BREAKPOINT: + /* + * This means a user thread is single stepping + * a system call which should be ignored + */ + if (test_thread_flag(TIF_SINGLESTEP)) + return NOTIFY_DONE; + + ret = kgdb_handle_exception(args->trapnr & 0xff, args->signr, + args->err, args->regs); + if (ret) + return NOTIFY_DONE; + + break; + } -BUILD_TRAP_HANDLER(breakpoint) + return NOTIFY_STOP; +} + +static int +kgdb_notify(struct notifier_block *self, unsigned long cmd, void *ptr) { unsigned long flags; - TRAP_HANDLER_DECL; + int ret; local_irq_save(flags); - kgdb_handle_exception(vec >> 2, SIGTRAP, 0, regs); + ret = __kgdb_notify(ptr, cmd); local_irq_restore(flags); + + return ret; } +static struct notifier_block kgdb_notifier = { + .notifier_call = kgdb_notify, + + /* + * Lowest-prio notifier priority, we want to be notified last: + */ + .priority = -INT_MAX, +}; + int kgdb_arch_init(void) { - return 0; + return register_die_notifier(&kgdb_notifier); } void kgdb_arch_exit(void) { + unregister_die_notifier(&kgdb_notifier); } struct kgdb_arch arch_kgdb_ops = { -- cgit v1.2.3 From 34d0b5af50a063cded842716633501b38ff815fb Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 28 Dec 2009 17:53:47 +0900 Subject: sh: Convert ptrace to hw_breakpoint API. This is the initial step for converting singlestep handling via ptrace over to hw_breakpoints. Signed-off-by: Paul Mundt --- arch/sh/include/asm/ptrace.h | 6 +++++ arch/sh/kernel/hw_breakpoint.c | 15 ++++++++++-- arch/sh/kernel/ptrace_32.c | 53 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 71 insertions(+), 3 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/ptrace.h b/arch/sh/include/asm/ptrace.h index 1dc12cb44a2d..201d11ef211f 100644 --- a/arch/sh/include/asm/ptrace.h +++ b/arch/sh/include/asm/ptrace.h @@ -124,6 +124,12 @@ struct task_struct; extern void user_enable_single_step(struct task_struct *); extern void user_disable_single_step(struct task_struct *); +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) diff --git a/arch/sh/kernel/hw_breakpoint.c b/arch/sh/kernel/hw_breakpoint.c index 022d8ed66bd6..c515a3ecf562 100644 --- a/arch/sh/kernel/hw_breakpoint.c +++ b/arch/sh/kernel/hw_breakpoint.c @@ -20,6 +20,7 @@ #include #include #include +#include struct ubc_context { unsigned long pc; @@ -372,7 +373,7 @@ static int __kprobes hw_breakpoint_handler(struct die_args *args) rcu_read_unlock(); } - if (bp) { + if (bp && bp->overflow_handler != ptrace_triggered) { struct arch_hw_breakpoint *info = counter_arch_bp(bp); __raw_writel(UBC_CBR_CE | info->len | info->type, UBC_CBR0); @@ -387,9 +388,19 @@ static int __kprobes hw_breakpoint_handler(struct die_args *args) BUILD_TRAP_HANDLER(breakpoint) { unsigned long ex = lookup_exception_vector(); + siginfo_t info; + int err; TRAP_HANDLER_DECL; - notify_die(DIE_BREAKPOINT, "breakpoint", regs, 0, ex, SIGTRAP); + err = notify_die(DIE_BREAKPOINT, "breakpoint", regs, 0, ex, SIGTRAP); + if (err == NOTIFY_STOP) + return; + + /* Deliver the signal to userspace */ + info.si_signo = SIGTRAP; + info.si_errno = 0; + info.si_code = TRAP_HWBKPT; + force_sig_info(SIGTRAP, &info, current); } /* diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c index bdb10446cbac..8e094c4c7bb4 100644 --- a/arch/sh/kernel/ptrace_32.c +++ b/arch/sh/kernel/ptrace_32.c @@ -2,7 +2,7 @@ * SuperH process tracing * * Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka - * Copyright (C) 2002 - 2008 Paul Mundt + * Copyright (C) 2002 - 2009 Paul Mundt * * Audit support by Yuichi Nakamura * @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -63,9 +64,59 @@ static inline int put_stack_long(struct task_struct *task, int offset, return 0; } +void ptrace_triggered(struct perf_event *bp, int nmi, + struct perf_sample_data *data, struct pt_regs *regs) +{ + struct perf_event_attr attr; + + /* + * Disable the breakpoint request here since ptrace has defined a + * one-shot behaviour for breakpoint exceptions. + */ + attr = bp->attr; + attr.disabled = true; + modify_user_hw_breakpoint(bp, &attr); +} + +static int set_single_step(struct task_struct *tsk, unsigned long addr) +{ + struct thread_struct *thread = &tsk->thread; + struct perf_event *bp; + struct perf_event_attr attr; + + bp = thread->ptrace_bps[0]; + if (!bp) { + hw_breakpoint_init(&attr); + + attr.bp_addr = addr; + attr.bp_len = HW_BREAKPOINT_LEN_2; + attr.bp_type = HW_BREAKPOINT_R; + + bp = register_user_hw_breakpoint(&attr, ptrace_triggered, tsk); + if (IS_ERR(bp)) + return PTR_ERR(bp); + + thread->ptrace_bps[0] = bp; + } else { + int err; + + attr = bp->attr; + attr.bp_addr = addr; + err = modify_user_hw_breakpoint(bp, &attr); + if (unlikely(err)) + return err; + } + + return 0; +} + void user_enable_single_step(struct task_struct *child) { + unsigned long pc = get_stack_long(child, offsetof(struct pt_regs, pc)); + set_tsk_thread_flag(child, TIF_SINGLESTEP); + + set_single_step(child, pc); } void user_disable_single_step(struct task_struct *child) -- cgit v1.2.3 From e591a517230a97e93f5edd19e7bef7ec8d22ac2b Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Sun, 13 Dec 2009 22:18:09 +0000 Subject: sh: Remove unused functions Apply some TLC to the SH64 header files and remove some functions that are not used anymore. Signed-off-by: Matt Fleming --- arch/sh/include/asm/pgtable_64.h | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/pgtable_64.h b/arch/sh/include/asm/pgtable_64.h index 17cdbecc3adc..dd381588c695 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. */ @@ -202,12 +197,6 @@ static __inline__ void pmd_set(pmd_t *pmdp,pte_t *ptep) #define pgprot_noncached(x) __pgprot(((x).pgprot & ~(_PAGE_CACHABLE)) | _PAGE_DEVICE) #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. * -- cgit v1.2.3 From 3f5ab768164df9a44721660b96e0accb92eb2c24 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Thu, 24 Dec 2009 20:38:45 +0000 Subject: sh: Correct the PTRS_PER_PMD and PMD_SHIFT values The previous expressions were wrong which made free_pmd_range() explode when using anything other than 4KB pages (which is why 8KB and 64KB pages were disabled with the 3-level page table layout). The problem was that pmd_offset() was returning an index of non-zero when it should have been returning 0. This non-zero offset was used to calculate the address of the pmd table to free in free_pmd_range(), which ended up trying to free an object that was not aligned on a page boundary. Now 3-level page tables should work with 4KB, 8KB and 64KB pages. Signed-off-by: Matt Fleming --- arch/sh/include/asm/pgtable_pmd.h | 4 ++-- arch/sh/mm/Kconfig | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/pgtable_pmd.h b/arch/sh/include/asm/pgtable_pmd.h index 78dc36e1c2dd..42a180e534a8 100644 --- a/arch/sh/include/asm/pgtable_pmd.h +++ b/arch/sh/include/asm/pgtable_pmd.h @@ -17,11 +17,11 @@ #define USER_PTRS_PER_PGD 2 /* PMD bits */ -#define PMD_SHIFT (PAGE_SHIFT + (PAGE_SHIFT - 3)) +#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 (PAGE_SIZE / sizeof(pmd_t)) +#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)) diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index b3f6c1a30b22..1b4364871899 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig @@ -220,7 +220,7 @@ config PAGE_SIZE_4KB config PAGE_SIZE_8KB bool "8kB" - depends on !MMU || X2TLB && !PGTABLE_LEVELS_3 + depends on !MMU || X2TLB help This enables 8kB pages as supported by SH-X2 and later MMUs. @@ -232,7 +232,7 @@ config PAGE_SIZE_16KB config PAGE_SIZE_64KB bool "64kB" - depends on !MMU || CPU_SH4 && !PGTABLE_LEVELS_3 || CPU_SH5 + depends on !MMU || CPU_SH4 || CPU_SH5 help This enables support for 64kB pages, possible on all SH-4 CPUs and later. -- cgit v1.2.3 From b4c892762373c5e59c7e8db35f5f9a7658602bda Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Thu, 24 Dec 2009 22:17:35 +0000 Subject: sh: Optimise flush_dcache_page() on SH4 If the page is not mapped into any process's address space then aliases cannot exist in the cache. So reduce the amount of flushing we perform. Signed-off-by: Matt Fleming --- arch/sh/mm/cache-sh4.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c index 560ddb6bc8a7..a2301daeefa3 100644 --- a/arch/sh/mm/cache-sh4.c +++ b/arch/sh/mm/cache-sh4.c @@ -109,6 +109,7 @@ static inline void flush_cache_one(unsigned long start, unsigned long phys) static void sh4_flush_dcache_page(void *arg) { struct page *page = arg; + unsigned long addr = (unsigned long)page_address(page); #ifndef CONFIG_SMP struct address_space *mapping = page_mapping(page); @@ -116,16 +117,8 @@ static void sh4_flush_dcache_page(void *arg) set_bit(PG_dcache_dirty, &page->flags); else #endif - { - unsigned long phys = page_to_phys(page); - unsigned long addr = CACHE_OC_ADDRESS_ARRAY; - int i, n; - - /* Loop all the D-cache */ - n = boot_cpu_data.dcache.n_aliases; - for (i = 0; i < n; i++, addr += PAGE_SIZE) - flush_cache_one(addr, phys); - } + flush_cache_one(CACHE_OC_ADDRESS_ARRAY | + (addr & shm_align_mask), page_to_phys(page)); wmb(); } -- cgit v1.2.3 From 2a5eacca85d39d8b6dffae821d7d260f05584dc7 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Thu, 31 Dec 2009 12:19:24 +0000 Subject: sh: Move page table allocation out of line We also switched away from quicklists and instead moved to slab caches. After benchmarking both implementations the difference is negligible. The slab caches suit us better though because the size of a pgd table is just 4 entries when we're using a 3-level page table layout and quicklists always deal with pages. Signed-off-by: Matt Fleming --- arch/sh/include/asm/pgalloc.h | 10 ++++--- arch/sh/include/asm/pgalloc_nopmd.h | 30 ------------------- arch/sh/include/asm/pgalloc_pmd.h | 41 -------------------------- arch/sh/include/asm/pgtable.h | 4 +-- arch/sh/mm/Makefile | 2 +- arch/sh/mm/pgtable.c | 57 +++++++++++++++++++++++++++++++++++++ 6 files changed, 66 insertions(+), 78 deletions(-) delete mode 100644 arch/sh/include/asm/pgalloc_nopmd.h delete mode 100644 arch/sh/include/asm/pgalloc_pmd.h create mode 100644 arch/sh/mm/pgtable.c (limited to 'arch/sh') diff --git a/arch/sh/include/asm/pgalloc.h b/arch/sh/include/asm/pgalloc.h index 4ea27855c3b5..e106474996b2 100644 --- a/arch/sh/include/asm/pgalloc.h +++ b/arch/sh/include/asm/pgalloc.h @@ -6,10 +6,13 @@ #define QUICK_PT 1 /* 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); + #ifdef CONFIG_PGTABLE_LEVELS_3 -#include -#else -#include +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, @@ -67,7 +70,6 @@ do { \ static inline void check_pgt_cache(void) { - __check_pgt_cache(); quicklist_trim(QUICK_PT, NULL, 25, 16); } diff --git a/arch/sh/include/asm/pgalloc_nopmd.h b/arch/sh/include/asm/pgalloc_nopmd.h deleted file mode 100644 index e4b344c37e74..000000000000 --- a/arch/sh/include/asm/pgalloc_nopmd.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef __ASM_SH_PGALLOC_NOPMD_H -#define __ASM_SH_PGALLOC_NOPMD_H - -#define QUICK_PGD 0 /* We preserve special mappings over free */ - -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)); -} - -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 void __check_pgt_cache(void) -{ - quicklist_trim(QUICK_PGD, NULL, 25, 16); -} - -#endif /* __ASM_SH_PGALLOC_NOPMD_H */ diff --git a/arch/sh/include/asm/pgalloc_pmd.h b/arch/sh/include/asm/pgalloc_pmd.h deleted file mode 100644 index 20f75cc4eb09..000000000000 --- a/arch/sh/include/asm/pgalloc_pmd.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef __ASM_SH_PGALLOC_PMD_H -#define __ASM_SH_PGALLOC_PMD_H - -static inline pgd_t *pgd_alloc(struct mm_struct *mm) -{ - pgd_t *pgd; - int i; - - pgd = kzalloc(sizeof(*pgd) * PTRS_PER_PGD, GFP_KERNEL | __GFP_REPEAT); - - for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++) - pgd[i] = swapper_pg_dir[i]; - - return pgd; -} - -static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) -{ - kfree(pgd); -} - -static inline void __check_pgt_cache(void) -{ -} - -static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) -{ - set_pud(pud, __pud((unsigned long)pmd)); -} - -static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) -{ - return quicklist_alloc(QUICK_PT, GFP_KERNEL | __GFP_REPEAT, NULL); -} - -static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) -{ - quicklist_free(QUICK_PT, NULL, pmd); -} - -#endif /* __ASM_SH_PGALLOC_PMD_H */ diff --git a/arch/sh/include/asm/pgtable.h b/arch/sh/include/asm/pgtable.h index 9effcc3b0d10..78598ec33d0a 100644 --- a/arch/sh/include/asm/pgtable.h +++ b/arch/sh/include/asm/pgtable.h @@ -141,9 +141,9 @@ 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) +extern void pgtable_cache_init(void); struct vm_area_struct; diff --git a/arch/sh/mm/Makefile b/arch/sh/mm/Makefile index 8a70535fa7ce..dd5010c708e0 100644 --- a/arch/sh/mm/Makefile +++ b/arch/sh/mm/Makefile @@ -15,7 +15,7 @@ obj-y += $(cacheops-y) mmu-y := nommu.o extable_32.o mmu-$(CONFIG_MMU) := extable_$(BITS).o fault_$(BITS).o \ - ioremap_$(BITS).o kmap.o tlbflush_$(BITS).o + ioremap_$(BITS).o kmap.o pgtable.o tlbflush_$(BITS).o obj-y += $(mmu-y) obj-$(CONFIG_DEBUG_FS) += asids-debugfs.o diff --git a/arch/sh/mm/pgtable.c b/arch/sh/mm/pgtable.c new file mode 100644 index 000000000000..e1bc5483cc07 --- /dev/null +++ b/arch/sh/mm/pgtable.c @@ -0,0 +1,57 @@ +#include + +#define PGALLOC_GFP GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO + +static struct kmem_cache *pgd_cachep; + +#ifdef CONFIG_PGTABLE_LEVELS_3 +static struct kmem_cache *pmd_cachep; +#endif + +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)); +} + +void pgtable_cache_init(void) +{ + pgd_cachep = kmem_cache_create("pgd_cache", + PTRS_PER_PGD * (1< Date: Tue, 5 Jan 2010 12:35:00 +0900 Subject: sh: Drop down to a single quicklist. We previously had 2 quicklists, one for the PGD case and one for PTEs. Now that the PGD/PMD cases are handled through slab caches due to the multi-level configurability, only the PTE quicklist remains. As such, reduce NR_QUICK to its appropriate size and bump down the PTE quicklist index. Signed-off-by: Paul Mundt --- arch/sh/include/asm/pgalloc.h | 2 +- mm/Kconfig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/pgalloc.h b/arch/sh/include/asm/pgalloc.h index e106474996b2..f8982f4e0405 100644 --- a/arch/sh/include/asm/pgalloc.h +++ b/arch/sh/include/asm/pgalloc.h @@ -4,7 +4,7 @@ #include #include -#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); diff --git a/mm/Kconfig b/mm/Kconfig index 17b8947aa7da..d34c2b971032 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -195,7 +195,7 @@ config BOUNCE config NR_QUICK int depends on QUICKLIST - default "2" if SUPERH || AVR32 + default "2" if AVR32 default "1" config VIRT_TO_BUS -- cgit v1.2.3 From c4761815ab49feca904776dec464046bc7138d3a Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 5 Jan 2010 12:44:02 +0900 Subject: sh: Fix up breakpoint trap handler patching on SH-2A. SH-2A was referencing the old handler that no longer exists, fix it up. Signed-off-by: Paul Mundt --- arch/sh/kernel/traps_32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/sh') diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c index 86639beac3a2..706c1c18a2f2 100644 --- a/arch/sh/kernel/traps_32.c +++ b/arch/sh/kernel/traps_32.c @@ -956,7 +956,7 @@ void __init trap_init(void) #endif #ifdef TRAP_UBC - set_exception_table_vec(TRAP_UBC, break_point_trap); + set_exception_table_vec(TRAP_UBC, breakpoint_trap_handler); #endif /* Setup VBR for boot cpu */ -- cgit v1.2.3 From 4352fc1b12fae4c753a063a2f162ddf9277af774 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 5 Jan 2010 19:06:45 +0900 Subject: sh: Abstracted SH-4A UBC support on hw-breakpoint core. This is the next big chunk of hw_breakpoint support. This decouples the SH-4A support from the core and moves it out in to its own stub, following many of the conventions established with the perf events layering. In addition to extending SH-4A support to encapsulate the remainder of the UBC channels, clock framework support for handling the UBC interface clock is added as well, allowing for dynamic clock gating. This also fixes up a regression introduced by the SIGTRAP handling that broke the ksym_tracer, to the extent that the current support works well with all of the ksym_tracer/ptrace/kgdb. The kprobes singlestep code will follow in turn. With this in place, the remaining UBC variants (SH-2A and SH-4) can now be trivially plugged in. Signed-off-by: Paul Mundt --- arch/sh/include/asm/hw_breakpoint.h | 22 ++++- arch/sh/include/asm/processor_32.h | 4 +- arch/sh/kernel/cpu/sh4a/Makefile | 9 +- arch/sh/kernel/cpu/sh4a/ubc.c | 133 +++++++++++++++++++++++++++++ arch/sh/kernel/hw_breakpoint.c | 164 +++++++++++++++++++++--------------- 5 files changed, 254 insertions(+), 78 deletions(-) create mode 100644 arch/sh/kernel/cpu/sh4a/ubc.c (limited to 'arch/sh') diff --git a/arch/sh/include/asm/hw_breakpoint.h b/arch/sh/include/asm/hw_breakpoint.h index 0f4a00f60058..7295d6290249 100644 --- a/arch/sh/include/asm/hw_breakpoint.h +++ b/arch/sh/include/asm/hw_breakpoint.h @@ -3,7 +3,6 @@ #include #include -#include #ifdef __KERNEL__ #define __ARCH_HW_BREAKPOINT_H @@ -11,7 +10,6 @@ struct arch_hw_breakpoint { char *name; /* Contains name of the symbol to set bkpt */ unsigned long address; - unsigned long asid; u16 len; u16 type; }; @@ -27,13 +25,28 @@ enum { SH_BREAKPOINT_LEN_8 = (1 << 14), }; -/* Total number of available UBC channels */ -#define HBP_NUM 1 /* XXX */ +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 + +/* arch/sh/kernel/hw_breakpoint.c */ extern int arch_check_va_in_userspace(unsigned long va, u16 hbp_len); extern int arch_validate_hwbkpt_settings(struct perf_event *bp, struct task_struct *tsk); @@ -46,6 +59,7 @@ void hw_breakpoint_pmu_read(struct perf_event *bp); void hw_breakpoint_pmu_unthrottle(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; diff --git a/arch/sh/include/asm/processor_32.h b/arch/sh/include/asm/processor_32.h index d60b28271a05..259112cecbdf 100644 --- a/arch/sh/include/asm/processor_32.h +++ b/arch/sh/include/asm/processor_32.h @@ -14,7 +14,7 @@ #include #include #include -#include +#include /* * Default implementation of macro that returns current @@ -102,7 +102,7 @@ struct thread_struct { unsigned long pc; /* Save middle states of ptrace breakpoints */ - struct perf_event *ptrace_bps[NR_UBC_CHANNELS]; + struct perf_event *ptrace_bps[HBP_NUM]; /* floating point info */ union sh_fpu_union fpu; diff --git a/arch/sh/kernel/cpu/sh4a/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile index 33bab477d2e2..b144e8af89dc 100644 --- a/arch/sh/kernel/cpu/sh4a/Makefile +++ b/arch/sh/kernel/cpu/sh4a/Makefile @@ -41,7 +41,8 @@ pinmux-$(CONFIG_CPU_SUBTYPE_SH7757) := pinmux-sh7757.o pinmux-$(CONFIG_CPU_SUBTYPE_SH7785) := pinmux-sh7785.o pinmux-$(CONFIG_CPU_SUBTYPE_SH7786) := pinmux-sh7786.o -obj-y += $(clock-y) -obj-$(CONFIG_SMP) += $(smp-y) -obj-$(CONFIG_GENERIC_GPIO) += $(pinmux-y) -obj-$(CONFIG_PERF_EVENTS) += perf_event.o +obj-y += $(clock-y) +obj-$(CONFIG_SMP) += $(smp-y) +obj-$(CONFIG_GENERIC_GPIO) += $(pinmux-y) +obj-$(CONFIG_PERF_EVENTS) += perf_event.o +obj-$(CONFIG_HAVE_HW_BREAKPOINT) += ubc.o diff --git a/arch/sh/kernel/cpu/sh4a/ubc.c b/arch/sh/kernel/cpu/sh4a/ubc.c new file mode 100644 index 000000000000..efb2745bcb36 --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/ubc.c @@ -0,0 +1,133 @@ +/* + * arch/sh/kernel/cpu/sh4a/ubc.c + * + * On-chip UBC support for SH-4A CPUs. + * + * Copyright (C) 2009 - 2010 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. + */ +#include +#include +#include +#include +#include + +#define UBC_CBR(idx) (0xff200000 + (0x20 * idx)) +#define UBC_CRR(idx) (0xff200004 + (0x20 * idx)) +#define UBC_CAR(idx) (0xff200008 + (0x20 * idx)) +#define UBC_CAMR(idx) (0xff20000c + (0x20 * idx)) + +#define UBC_CCMFR 0xff200600 +#define UBC_CBCR 0xff200620 + +/* CRR */ +#define UBC_CRR_PCB (1 << 1) +#define UBC_CRR_BIE (1 << 0) + +/* CBR */ +#define UBC_CBR_CE (1 << 0) + +static struct sh_ubc sh4a_ubc; + +static void sh4a_ubc_enable(struct arch_hw_breakpoint *info, int idx) +{ + __raw_writel(UBC_CBR_CE | info->len | info->type, UBC_CBR(idx)); + __raw_writel(info->address, UBC_CAR(idx)); +} + +static void sh4a_ubc_disable(struct arch_hw_breakpoint *info, int idx) +{ + __raw_writel(0, UBC_CBR(idx)); + __raw_writel(0, UBC_CAR(idx)); +} + +static void sh4a_ubc_enable_all(unsigned long mask) +{ + int i; + + for (i = 0; i < sh4a_ubc.num_events; i++) + if (mask & (1 << i)) + __raw_writel(__raw_readl(UBC_CBR(i)) | UBC_CBR_CE, + UBC_CBR(i)); +} + +static void sh4a_ubc_disable_all(void) +{ + int i; + + for (i = 0; i < sh4a_ubc.num_events; i++) + __raw_writel(__raw_readl(UBC_CBR(i)) & ~UBC_CBR_CE, + UBC_CBR(i)); +} + +static unsigned long sh4a_ubc_active_mask(void) +{ + unsigned long active = 0; + int i; + + for (i = 0; i < sh4a_ubc.num_events; i++) + if (__raw_readl(UBC_CBR(i)) & UBC_CBR_CE) + active |= (1 << i); + + return active; +} + +static unsigned long sh4a_ubc_triggered_mask(void) +{ + return __raw_readl(UBC_CCMFR); +} + +static void sh4a_ubc_clear_triggered_mask(unsigned long mask) +{ + __raw_writel(__raw_readl(UBC_CCMFR) & ~mask, UBC_CCMFR); +} + +static struct sh_ubc sh4a_ubc = { + .name = "SH-4A", + .num_events = 2, + .trap_nr = 0x1e0, + .enable = sh4a_ubc_enable, + .disable = sh4a_ubc_disable, + .enable_all = sh4a_ubc_enable_all, + .disable_all = sh4a_ubc_disable_all, + .active_mask = sh4a_ubc_active_mask, + .triggered_mask = sh4a_ubc_triggered_mask, + .clear_triggered_mask = sh4a_ubc_clear_triggered_mask, +}; + +static int __init sh4a_ubc_init(void) +{ + struct clk *ubc_iclk = clk_get(NULL, "ubc0"); + int i; + + /* + * The UBC MSTP bit is optional, as not all platforms will have + * it. Just ignore it if we can't find it. + */ + if (IS_ERR(ubc_iclk)) + ubc_iclk = NULL; + + clk_enable(ubc_iclk); + + __raw_writel(0, UBC_CBCR); + + for (i = 0; i < sh4a_ubc.num_events; i++) { + __raw_writel(0, UBC_CAMR(i)); + __raw_writel(0, UBC_CBR(i)); + + __raw_writel(UBC_CRR_BIE | UBC_CRR_PCB, UBC_CRR(i)); + + /* dummy read for write posting */ + (void)__raw_readl(UBC_CRR(i)); + } + + clk_disable(ubc_iclk); + + sh4a_ubc.clk = ubc_iclk; + + return register_sh_ubc(&sh4a_ubc); +} +arch_initcall(sh4a_ubc_init); diff --git a/arch/sh/kernel/hw_breakpoint.c b/arch/sh/kernel/hw_breakpoint.c index c515a3ecf562..e2f1753d275c 100644 --- a/arch/sh/kernel/hw_breakpoint.c +++ b/arch/sh/kernel/hw_breakpoint.c @@ -3,7 +3,7 @@ * * Unified kernel/user-space hardware breakpoint facility for the on-chip UBC. * - * Copyright (C) 2009 Paul Mundt + * Copyright (C) 2009 - 2010 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 @@ -18,38 +18,24 @@ #include #include #include +#include #include #include #include -struct ubc_context { - unsigned long pc; - unsigned long state; -}; - -/* Per cpu ubc channel state */ -static DEFINE_PER_CPU(struct ubc_context, ubc_ctx[HBP_NUM]); - /* * Stores the breakpoints currently in use on each breakpoint address * register for each cpus */ static DEFINE_PER_CPU(struct perf_event *, bp_per_reg[HBP_NUM]); -static int __init ubc_init(void) -{ - __raw_writel(0, UBC_CAMR0); - __raw_writel(0, UBC_CBR0); - __raw_writel(0, UBC_CBCR); - - __raw_writel(UBC_CRR_BIE | UBC_CRR_PCB, UBC_CRR0); - - /* dummy read for write posting */ - (void)__raw_readl(UBC_CRR0); +/* + * A dummy placeholder for early accesses until the CPUs get a chance to + * register their UBCs later in the boot process. + */ +static struct sh_ubc ubc_dummy = { .num_events = 0 }; - return 0; -} -arch_initcall(ubc_init); +static struct sh_ubc *sh_ubc __read_mostly = &ubc_dummy; /* * Install a perf counter breakpoint. @@ -62,10 +48,9 @@ arch_initcall(ubc_init); int arch_install_hw_breakpoint(struct perf_event *bp) { struct arch_hw_breakpoint *info = counter_arch_bp(bp); - struct ubc_context *ubc_ctx; int i; - for (i = 0; i < HBP_NUM; i++) { + for (i = 0; i < sh_ubc->num_events; i++) { struct perf_event **slot = &__get_cpu_var(bp_per_reg[i]); if (!*slot) { @@ -74,16 +59,11 @@ int arch_install_hw_breakpoint(struct perf_event *bp) } } - if (WARN_ONCE(i == HBP_NUM, "Can't find any breakpoint slot")) + if (WARN_ONCE(i == sh_ubc->num_events, "Can't find any breakpoint slot")) return -EBUSY; - ubc_ctx = &__get_cpu_var(ubc_ctx[i]); - - ubc_ctx->pc = info->address; - ubc_ctx->state = info->len | info->type; - - __raw_writel(UBC_CBR_CE | ubc_ctx->state, UBC_CBR0); - __raw_writel(ubc_ctx->pc, UBC_CAR0); + clk_enable(sh_ubc->clk); + sh_ubc->enable(info, i); return 0; } @@ -100,10 +80,9 @@ int arch_install_hw_breakpoint(struct perf_event *bp) void arch_uninstall_hw_breakpoint(struct perf_event *bp) { struct arch_hw_breakpoint *info = counter_arch_bp(bp); - struct ubc_context *ubc_ctx; int i; - for (i = 0; i < HBP_NUM; i++) { + for (i = 0; i < sh_ubc->num_events; i++) { struct perf_event **slot = &__get_cpu_var(bp_per_reg[i]); if (*slot == bp) { @@ -112,15 +91,11 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp) } } - if (WARN_ONCE(i == HBP_NUM, "Can't find any breakpoint slot")) + if (WARN_ONCE(i == sh_ubc->num_events, "Can't find any breakpoint slot")) return; - ubc_ctx = &__get_cpu_var(ubc_ctx[i]); - ubc_ctx->pc = 0; - ubc_ctx->state &= ~(info->len | info->type); - - __raw_writel(ubc_ctx->pc, UBC_CBR0); - __raw_writel(ubc_ctx->state, UBC_CAR0); + sh_ubc->disable(info, i); + clk_disable(sh_ubc->clk); } static int get_hbp_len(u16 hbp_len) @@ -182,10 +157,8 @@ static int arch_store_info(struct perf_event *bp) */ if (info->name) info->address = (unsigned long)kallsyms_lookup_name(info->name); - if (info->address) { - info->asid = get_asid(); + if (info->address) return 0; - } return -EINVAL; } @@ -335,7 +308,7 @@ void flush_ptrace_hw_breakpoint(struct task_struct *tsk) int i; struct thread_struct *t = &tsk->thread; - for (i = 0; i < HBP_NUM; i++) { + for (i = 0; i < sh_ubc->num_events; i++) { unregister_hw_breakpoint(t->ptrace_bps[i]); t->ptrace_bps[i] = NULL; } @@ -345,13 +318,32 @@ static int __kprobes hw_breakpoint_handler(struct die_args *args) { int cpu, i, rc = NOTIFY_STOP; struct perf_event *bp; - unsigned long val; + unsigned int cmf, resume_mask; + + /* + * Do an early return if none of the channels triggered. + */ + cmf = sh_ubc->triggered_mask(); + if (unlikely(!cmf)) + return NOTIFY_DONE; + + /* + * By default, resume all of the active channels. + */ + resume_mask = sh_ubc->active_mask(); - val = __raw_readl(UBC_CBR0); - __raw_writel(val & ~UBC_CBR_CE, UBC_CBR0); + /* + * Disable breakpoints during exception handling. + */ + sh_ubc->disable_all(); cpu = get_cpu(); - for (i = 0; i < HBP_NUM; i++) { + for (i = 0; i < sh_ubc->num_events; i++) { + unsigned long event_mask = (1 << i); + + if (likely(!(cmf & event_mask))) + continue; + /* * The counter may be concurrently released but that can only * occur from a call_rcu() path. We can then safely fetch @@ -361,24 +353,52 @@ static int __kprobes hw_breakpoint_handler(struct die_args *args) rcu_read_lock(); bp = per_cpu(bp_per_reg[i], cpu); - if (bp) { + if (bp) rc = NOTIFY_DONE; - } else { + + /* + * Reset the condition match flag to denote completion of + * exception handling. + */ + sh_ubc->clear_triggered_mask(event_mask); + + /* + * bp can be NULL due to concurrent perf counter + * removing. + */ + if (!bp) { rcu_read_unlock(); break; } + /* + * Don't restore the channel if the breakpoint is from + * ptrace, as it always operates in one-shot mode. + */ + if (bp->overflow_handler == ptrace_triggered) + resume_mask &= ~(1 << i); + perf_bp_event(bp, args->regs); + /* Deliver the signal to userspace */ + if (arch_check_va_in_userspace(bp->attr.bp_addr, + bp->attr.bp_len)) { + siginfo_t info; + + info.si_signo = args->signr; + info.si_errno = notifier_to_errno(rc); + info.si_code = TRAP_HWBKPT; + + force_sig_info(args->signr, &info, current); + } + rcu_read_unlock(); } - if (bp && bp->overflow_handler != ptrace_triggered) { - struct arch_hw_breakpoint *info = counter_arch_bp(bp); + if (cmf == 0) + rc = NOTIFY_DONE; - __raw_writel(UBC_CBR_CE | info->len | info->type, UBC_CBR0); - __raw_writel(info->address, UBC_CAR0); - } + sh_ubc->enable_all(resume_mask); put_cpu(); @@ -388,19 +408,9 @@ static int __kprobes hw_breakpoint_handler(struct die_args *args) BUILD_TRAP_HANDLER(breakpoint) { unsigned long ex = lookup_exception_vector(); - siginfo_t info; - int err; TRAP_HANDLER_DECL; - err = notify_die(DIE_BREAKPOINT, "breakpoint", regs, 0, ex, SIGTRAP); - if (err == NOTIFY_STOP) - return; - - /* Deliver the signal to userspace */ - info.si_signo = SIGTRAP; - info.si_errno = 0; - info.si_code = TRAP_HWBKPT; - force_sig_info(SIGTRAP, &info, current); + notify_die(DIE_BREAKPOINT, "breakpoint", regs, 0, ex, SIGTRAP); } /* @@ -417,8 +427,12 @@ int __kprobes hw_breakpoint_exceptions_notify(struct notifier_block *unused, /* * If the breakpoint hasn't been triggered by the UBC, it's * probably from a debugger, so don't do anything more here. + * + * This also permits the UBC interface clock to remain off for + * non-UBC breakpoints, as we don't need to check the triggered + * or active channel masks. */ - if (args->trapnr != 0x1e0) + if (args->trapnr != sh_ubc->trap_nr) return NOTIFY_DONE; return hw_breakpoint_handler(data); @@ -433,3 +447,17 @@ void hw_breakpoint_pmu_unthrottle(struct perf_event *bp) { /* TODO */ } + +int register_sh_ubc(struct sh_ubc *ubc) +{ + /* Bail if it's already assigned */ + if (sh_ubc != &ubc_dummy) + return -EBUSY; + sh_ubc = ubc; + + pr_info("HW Breakpoints: %s UBC support registered\n", ubc->name); + + WARN_ON(ubc->num_events > HBP_NUM); + + return 0; +} -- cgit v1.2.3 From 7025bec9125b0a02edcaf22c2dce753bf2c95480 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 5 Jan 2010 19:16:35 +0900 Subject: sh: Kill off dead UBC headers. Nothing is using these now, so kill them all off. Signed-off-by: Paul Mundt --- arch/sh/include/asm/ubc.h | 70 --------------------------------------- arch/sh/include/cpu-sh2/cpu/ubc.h | 32 ------------------ arch/sh/include/cpu-sh3/cpu/ubc.h | 42 ----------------------- arch/sh/include/cpu-sh4/cpu/ubc.h | 64 ----------------------------------- arch/sh/kernel/cpu/init.c | 20 +++++------ arch/sh/kernel/process_32.c | 1 - 6 files changed, 8 insertions(+), 221 deletions(-) delete mode 100644 arch/sh/include/asm/ubc.h delete mode 100644 arch/sh/include/cpu-sh2/cpu/ubc.h delete mode 100644 arch/sh/include/cpu-sh3/cpu/ubc.h delete mode 100644 arch/sh/include/cpu-sh4/cpu/ubc.h (limited to 'arch/sh') diff --git a/arch/sh/include/asm/ubc.h b/arch/sh/include/asm/ubc.h deleted file mode 100644 index e3c2968b04d3..000000000000 --- a/arch/sh/include/asm/ubc.h +++ /dev/null @@ -1,70 +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 - -/* 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 - -/* - * All SH parts have 2 UBC channels. I defy any hardware designer to - * invalidate this assertion. - */ -#define NR_UBC_CHANNELS 2 - -#endif /* __KERNEL__ */ -#endif /* __ASM_SH_UBC_H */ diff --git a/arch/sh/include/cpu-sh2/cpu/ubc.h b/arch/sh/include/cpu-sh2/cpu/ubc.h deleted file mode 100644 index ba0e87f19c7a..000000000000 --- a/arch/sh/include/cpu-sh2/cpu/ubc.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * include/asm-sh/cpu-sh2/ubc.h - * - * 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 __ASM_CPU_SH2_UBC_H -#define __ASM_CPU_SH2_UBC_H - -#define UBC_BARA 0xffffff40 -#define UBC_BAMRA 0xffffff44 -#define UBC_BBRA 0xffffff48 -#define UBC_BARB 0xffffff60 -#define UBC_BAMRB 0xffffff64 -#define UBC_BBRB 0xffffff68 -#define UBC_BDRB 0xffffff70 -#define UBC_BDMRB 0xffffff74 -#define UBC_BRCR 0xffffff78 - -/* - * We don't have any ASID changes to make in the UBC on the SH-2. - * - * Make these purposely invalid to track misuse. - */ -#define UBC_BASRA 0x00000000 -#define UBC_BASRB 0x00000000 - -#endif /* __ASM_CPU_SH2_UBC_H */ - diff --git a/arch/sh/include/cpu-sh3/cpu/ubc.h b/arch/sh/include/cpu-sh3/cpu/ubc.h deleted file mode 100644 index 4e6381d5ff7a..000000000000 --- a/arch/sh/include/cpu-sh3/cpu/ubc.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * include/asm-sh/cpu-sh3/ubc.h - * - * Copyright (C) 1999 Niibe Yutaka - * 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 __ASM_CPU_SH3_UBC_H -#define __ASM_CPU_SH3_UBC_H - -#if defined(CONFIG_CPU_SUBTYPE_SH7710) || \ - defined(CONFIG_CPU_SUBTYPE_SH7720) || \ - defined(CONFIG_CPU_SUBTYPE_SH7721) -#define UBC_BARA 0xa4ffffb0 -#define UBC_BAMRA 0xa4ffffb4 -#define UBC_BBRA 0xa4ffffb8 -#define UBC_BASRA 0xffffffe4 -#define UBC_BARB 0xa4ffffa0 -#define UBC_BAMRB 0xa4ffffa4 -#define UBC_BBRB 0xa4ffffa8 -#define UBC_BASRB 0xffffffe8 -#define UBC_BDRB 0xa4ffff90 -#define UBC_BDMRB 0xa4ffff94 -#define UBC_BRCR 0xa4ffff98 -#else -#define UBC_BARA 0xffffffb0 -#define UBC_BAMRA 0xffffffb4 -#define UBC_BBRA 0xffffffb8 -#define UBC_BASRA 0xffffffe4 -#define UBC_BARB 0xffffffa0 -#define UBC_BAMRB 0xffffffa4 -#define UBC_BBRB 0xffffffa8 -#define UBC_BASRB 0xffffffe8 -#define UBC_BDRB 0xffffff90 -#define UBC_BDMRB 0xffffff94 -#define UBC_BRCR 0xffffff98 -#endif - -#endif /* __ASM_CPU_SH3_UBC_H */ diff --git a/arch/sh/include/cpu-sh4/cpu/ubc.h b/arch/sh/include/cpu-sh4/cpu/ubc.h deleted file mode 100644 index c86e17050935..000000000000 --- a/arch/sh/include/cpu-sh4/cpu/ubc.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * include/asm-sh/cpu-sh4/ubc.h - * - * Copyright (C) 1999 Niibe Yutaka - * Copyright (C) 2003 Paul Mundt - * Copyright (C) 2006 Lineo Solutions Inc. support SH4A UBC - * - * 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_CPU_SH4_UBC_H -#define __ASM_CPU_SH4_UBC_H - -#if defined(CONFIG_CPU_SH4A) -#define UBC_CBR0 0xff200000 -#define UBC_CRR0 0xff200004 -#define UBC_CAR0 0xff200008 -#define UBC_CAMR0 0xff20000c -#define UBC_CBR1 0xff200020 -#define UBC_CRR1 0xff200024 -#define UBC_CAR1 0xff200028 -#define UBC_CAMR1 0xff20002c -#define UBC_CDR1 0xff200030 -#define UBC_CDMR1 0xff200034 -#define UBC_CETR1 0xff200038 -#define UBC_CCMFR 0xff200600 -#define UBC_CBCR 0xff200620 - -/* CBR */ -#define UBC_CBR_AIE (0x01<<30) -#define UBC_CBR_ID_INST (0x01<<4) -#define UBC_CBR_RW_READ (0x01<<1) -#define UBC_CBR_CE (0x01) - -#define UBC_CBR_AIV_MASK (0x00FF0000) -#define UBC_CBR_AIV_SHIFT (16) -#define UBC_CBR_AIV_SET(asid) (((asid)< #include #include -#ifdef CONFIG_SUPERH32 -#include -#endif /* * Generic wrapper for command line arguments to disable on-chip @@ -252,20 +249,19 @@ static void __init dsp_init(void) /** * sh_cpu_init * - * This is our initial entry point for each CPU, and is invoked on the boot - * CPU prior to calling start_kernel(). For SMP, a combination of this and - * start_secondary() will bring up each processor to a ready state prior - * to hand forking the idle loop. + * This is our initial entry point for each CPU, and is invoked on the + * boot CPU prior to calling start_kernel(). For SMP, a combination of + * this and start_secondary() will bring up each processor to a ready + * state prior to hand forking the idle loop. * - * We do all of the basic processor init here, including setting up the - * caches, FPU, DSP, kicking the UBC, etc. By the time start_kernel() is - * hit (and subsequently platform_setup()) things like determining the - * CPU subtype and initial configuration will all be done. + * We do all of the basic processor init here, including setting up + * the caches, FPU, DSP, etc. By the time start_kernel() is hit (and + * subsequently platform_setup()) things like determining the CPU + * subtype and initial configuration will all be done. * * Each processor family is still responsible for doing its own probing * and cache configuration in detect_cpu_and_cache_system(). */ - asmlinkage void __init sh_cpu_init(void) { current_thread_info()->cpu = hard_smp_processor_id(); diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c index 7399d78fc8ed..b94f9d96ac95 100644 --- a/arch/sh/kernel/process_32.c +++ b/arch/sh/kernel/process_32.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3 From 9fae4fb3ce38cc657ff0aba570ae875aae2806d4 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 5 Jan 2010 19:30:18 +0900 Subject: sh: Reclaim TIF_DEBUG. This was used by the old hw-breakpoints API, but now there is nothing is using it anymore, so just kill it off. Signed-off-by: Paul Mundt --- arch/sh/include/asm/thread_info.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/thread_info.h b/arch/sh/include/asm/thread_info.h index e0856b205c4e..1f3d927e2265 100644 --- a/arch/sh/include/asm/thread_info.h +++ b/arch/sh/include/asm/thread_info.h @@ -118,7 +118,6 @@ extern void free_thread_info(struct thread_info *ti); #define TIF_SECCOMP 6 /* secure computing */ #define TIF_NOTIFY_RESUME 7 /* callback before returning to user */ #define TIF_SYSCALL_TRACEPOINT 8 /* for ftrace syscall instrumentation */ -#define TIF_DEBUG 9 /* uses UBC */ #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */ #define TIF_MEMDIE 18 #define TIF_FREEZE 19 /* Freezing for suspend */ @@ -131,7 +130,6 @@ extern void free_thread_info(struct thread_info *ti); #define _TIF_SECCOMP (1 << TIF_SECCOMP) #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) #define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) -#define _TIF_DEBUG (1 << TIF_DEBUG) #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) #define _TIF_FREEZE (1 << TIF_FREEZE) -- cgit v1.2.3 From 56d45b62ce622a003da972428fdbba2b42102efb Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 6 Jan 2010 14:45:14 +0900 Subject: sh: Fix up nommu build for out-of-line pgtable changes. pgtable_cache_init() has been moved out-of-line, so we also need a dummy definition for it on nommu to fix up the build. Signed-off-by: Paul Mundt --- arch/sh/mm/nommu.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/mm/nommu.c b/arch/sh/mm/nommu.c index ac16c05917ef..7694f50c9034 100644 --- a/arch/sh/mm/nommu.c +++ b/arch/sh/mm/nommu.c @@ -94,3 +94,7 @@ void __init page_table_range_init(unsigned long start, unsigned long end, void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot) { } + +void pgtable_cache_init(void) +{ +} -- cgit v1.2.3 From 6fbfe8d7cd7e71ceb281c5a1b9de6e5e0dfbf1c8 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 6 Jan 2010 15:46:53 +0900 Subject: sh: select HAVE_HW_BREAKPOINT for all SUPERH32 CPUs. All SH CPUs (with the exception of sh64) support the UBC, so select HW_BREAKPOINT support by default. This fixes up the build for non-SH4A targets. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/sh') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index fa76d6264dff..f971cb74dd62 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -42,7 +42,7 @@ config SUPERH32 select HAVE_FTRACE_NMI_ENTER if DYNAMIC_FTRACE select HAVE_FUNCTION_GRAPH_TRACER select HAVE_ARCH_KGDB - select HAVE_HW_BREAKPOINT if CPU_SH4A + select HAVE_HW_BREAKPOINT select PERF_EVENTS if HAVE_HW_BREAKPOINT select ARCH_HIBERNATION_POSSIBLE if MMU -- cgit v1.2.3 From 8c0b8139c87cfe8b95c6e763b4ca3190aa9b1ad0 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 8 Jan 2010 17:02:17 +0900 Subject: sh: consolidate atomic_cmpxchg()/atomic_add_unless() definitions. The LL/SC and IRQ versions were using generic stubs while the GRB version was just reimplementing what it already had for the standard cmpxchg() code. As we have optimized cmpxchg() implementations that are decoupled from the atomic code, simply falling back on the generic wrapper does the right thing. With this in place the GRB case is unaffected while the LL/SC case gets to use its optimized cmpxchg(). Signed-off-by: Paul Mundt --- arch/sh/include/asm/atomic-grb.h | 46 ------------------------ arch/sh/include/asm/atomic-llsc.h | 27 --------------- arch/sh/include/asm/atomic.h | 73 ++++++++++++++++----------------------- 3 files changed, 29 insertions(+), 117 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/atomic-grb.h b/arch/sh/include/asm/atomic-grb.h index 4c5b7dbfcedb..a273c88578fc 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 b040e1e08610..4b00b78e3f4f 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 b16388d71954..275a448ae8c2 100644 --- a/arch/sh/include/asm/atomic.h +++ b/arch/sh/include/asm/atomic.h @@ -25,58 +25,43 @@ #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) #define smp_mb__before_atomic_dec() smp_mb() #define smp_mb__after_atomic_dec() smp_mb() -- cgit v1.2.3 From 53e6d8e0060fe2bb9b11238f8250fdfbb0589425 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 12 Jan 2010 13:37:04 +0900 Subject: sh: mach-se: Convert SE7343 FPGA to dynamic IRQ allocation. This gets rid of the arbitrary set of vectors used by the SE7722 FPGA interrupt controller and switches over to a completely dynamic set. No assumptions regarding a contiguous range are made, and the platform resources themselves need to be filled in lazily. Signed-off-by: Paul Mundt --- arch/sh/boards/mach-se/7343/irq.c | 35 +++++++++++++---------- arch/sh/boards/mach-se/7343/setup.c | 16 +++++++---- arch/sh/include/mach-se/mach/se7343.h | 52 +++++++++++++++-------------------- 3 files changed, 53 insertions(+), 50 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/boards/mach-se/7343/irq.c b/arch/sh/boards/mach-se/7343/irq.c index 051c29d4eae0..c60fd13608d0 100644 --- a/arch/sh/boards/mach-se/7343/irq.c +++ b/arch/sh/boards/mach-se/7343/irq.c @@ -16,15 +16,17 @@ #include #include +unsigned int se7343_fpga_irq[SE7343_FPGA_IRQ_NR] = { 0, }; + static void disable_se7343_irq(unsigned int irq) { - unsigned int bit = irq - SE7343_FPGA_IRQ_BASE; + unsigned int bit = (unsigned int)get_irq_chip_data(irq); ctrl_outw(ctrl_inw(PA_CPLD_IMSK) | 1 << bit, PA_CPLD_IMSK); } static void enable_se7343_irq(unsigned int irq) { - unsigned int bit = irq - SE7343_FPGA_IRQ_BASE; + unsigned int bit = (unsigned int)get_irq_chip_data(irq); ctrl_outw(ctrl_inw(PA_CPLD_IMSK) & ~(1 << bit), PA_CPLD_IMSK); } @@ -38,18 +40,15 @@ static struct irq_chip se7343_irq_chip __read_mostly = { static void se7343_irq_demux(unsigned int irq, struct irq_desc *desc) { unsigned short intv = ctrl_inw(PA_CPLD_ST); - struct irq_desc *ext_desc; - unsigned int ext_irq = SE7343_FPGA_IRQ_BASE; + unsigned int ext_irq = 0; intv &= (1 << SE7343_FPGA_IRQ_NR) - 1; - while (intv) { - if (intv & 1) { - ext_desc = irq_desc + ext_irq; - handle_level_irq(ext_irq, ext_desc); - } - intv >>= 1; - ext_irq++; + for (; intv; intv >>= 1, ext_irq++) { + if (!(intv & 1)) + continue; + + generic_handle_irq(se7343_fpga_irq[ext_irq]); } } @@ -58,16 +57,24 @@ static void se7343_irq_demux(unsigned int irq, struct irq_desc *desc) */ void __init init_7343se_IRQ(void) { - int i; + int i, irq; ctrl_outw(0, PA_CPLD_IMSK); /* disable all irqs */ ctrl_outw(0x2000, 0xb03fffec); /* mrshpc irq enable */ - for (i = 0; i < SE7343_FPGA_IRQ_NR; i++) - set_irq_chip_and_handler_name(SE7343_FPGA_IRQ_BASE + i, + for (i = 0; i < SE7343_FPGA_IRQ_NR; i++) { + irq = create_irq(); + if (irq < 0) + return; + se7343_fpga_irq[i] = irq; + + set_irq_chip_and_handler_name(se7343_fpga_irq[i], &se7343_irq_chip, handle_level_irq, "level"); + set_irq_chip_data(se7343_fpga_irq[i], (void *)i); + } + set_irq_chained_handler(IRQ0_IRQ, se7343_irq_demux); set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW); set_irq_chained_handler(IRQ1_IRQ, se7343_irq_demux); diff --git a/arch/sh/boards/mach-se/7343/setup.c b/arch/sh/boards/mach-se/7343/setup.c index 4de56f35f419..292cc47d853f 100644 --- a/arch/sh/boards/mach-se/7343/setup.c +++ b/arch/sh/boards/mach-se/7343/setup.c @@ -82,7 +82,6 @@ static struct plat_serial8250_port serial_platform_data[] = { .mapbase = 0x16000000, .regshift = 1, .flags = ST16C2550C_FLAGS, - .irq = UARTA_IRQ, .uartclk = 7372800, }, [1] = { @@ -90,7 +89,6 @@ static struct plat_serial8250_port serial_platform_data[] = { .mapbase = 0x17000000, .regshift = 1, .flags = ST16C2550C_FLAGS, - .irq = UARTB_IRQ, .uartclk = 7372800, }, { }, @@ -121,7 +119,7 @@ static struct resource usb_resources[] = { .flags = IORESOURCE_MEM, }, [2] = { - .start = USB_IRQ, + /* Filled in later */ .flags = IORESOURCE_IRQ, }, }; @@ -138,8 +136,8 @@ static struct isp116x_platform_data usb_platform_data = { static struct platform_device usb_device = { .name = "isp116x-hcd", .id = -1, - .num_resources = ARRAY_SIZE(usb_resources), - .resource = usb_resources, + .num_resources = ARRAY_SIZE(usb_resources), + .resource = usb_resources, .dev = { .platform_data = &usb_platform_data, }, @@ -155,6 +153,13 @@ static struct platform_device *sh7343se_platform_devices[] __initdata = { static int __init sh7343se_devices_setup(void) { + /* Wire-up dynamic vectors */ + serial_platform_data[0].irq = se7343_fpga_irq[SE7343_FPGA_IRQ_UARTA]; + serial_platform_data[1].irq = se7343_fpga_irq[SE7343_FPGA_IRQ_UARTB]; + + usb_resources[2].start = usb_resources[2].end = + se7343_fpga_irq[SE7343_FPGA_IRQ_USB]; + return platform_add_devices(sh7343se_platform_devices, ARRAY_SIZE(sh7343se_platform_devices)); } @@ -179,6 +184,5 @@ static void __init sh7343se_setup(char **cmdline_p) static struct sh_machine_vector mv_7343se __initmv = { .mv_name = "SolutionEngine 7343", .mv_setup = sh7343se_setup, - .mv_nr_irqs = SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_NR, .mv_init_irq = init_7343se_IRQ, }; diff --git a/arch/sh/include/mach-se/mach/se7343.h b/arch/sh/include/mach-se/mach/se7343.h index 749914b400fb..8d8170d6cc43 100644 --- a/arch/sh/include/mach-se/mach/se7343.h +++ b/arch/sh/include/mach-se/mach/se7343.h @@ -94,26 +94,26 @@ #define PORT_DRVCR 0xA4050180 -#define PORT_PADR 0xA4050120 -#define PORT_PBDR 0xA4050122 -#define PORT_PCDR 0xA4050124 -#define PORT_PDDR 0xA4050126 -#define PORT_PEDR 0xA4050128 -#define PORT_PFDR 0xA405012A -#define PORT_PGDR 0xA405012C -#define PORT_PHDR 0xA405012E -#define PORT_PJDR 0xA4050130 -#define PORT_PKDR 0xA4050132 -#define PORT_PLDR 0xA4050134 -#define PORT_PMDR 0xA4050136 -#define PORT_PNDR 0xA4050138 -#define PORT_PQDR 0xA405013A -#define PORT_PRDR 0xA405013C -#define PORT_PTDR 0xA4050160 -#define PORT_PUDR 0xA4050162 -#define PORT_PVDR 0xA4050164 -#define PORT_PWDR 0xA4050166 -#define PORT_PYDR 0xA4050168 +#define PORT_PADR 0xA4050120 +#define PORT_PBDR 0xA4050122 +#define PORT_PCDR 0xA4050124 +#define PORT_PDDR 0xA4050126 +#define PORT_PEDR 0xA4050128 +#define PORT_PFDR 0xA405012A +#define PORT_PGDR 0xA405012C +#define PORT_PHDR 0xA405012E +#define PORT_PJDR 0xA4050130 +#define PORT_PKDR 0xA4050132 +#define PORT_PLDR 0xA4050134 +#define PORT_PMDR 0xA4050136 +#define PORT_PNDR 0xA4050138 +#define PORT_PQDR 0xA405013A +#define PORT_PRDR 0xA405013C +#define PORT_PTDR 0xA4050160 +#define PORT_PUDR 0xA4050162 +#define PORT_PVDR 0xA4050164 +#define PORT_PWDR 0xA4050166 +#define PORT_PYDR 0xA4050168 #define FPGA_IN 0xb1400000 #define FPGA_OUT 0xb1400002 @@ -133,18 +133,10 @@ #define SE7343_FPGA_IRQ_UARTB 11 #define SE7343_FPGA_IRQ_NR 12 -#define SE7343_FPGA_IRQ_BASE 120 - -#define MRSHPC_IRQ3 (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_MRSHPC3) -#define MRSHPC_IRQ2 (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_MRSHPC2) -#define MRSHPC_IRQ1 (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_MRSHPC1) -#define MRSHPC_IRQ0 (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_MRSHPC0) -#define SMC_IRQ (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_SMC) -#define USB_IRQ (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_USB) -#define UARTA_IRQ (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_UARTA) -#define UARTB_IRQ (SE7343_FPGA_IRQ_BASE + SE7343_FPGA_IRQ_UARTB) /* arch/sh/boards/se/7343/irq.c */ +extern unsigned int se7343_fpga_irq[]; + void init_7343se_IRQ(void); #endif /* __ASM_SH_HITACHI_SE7343_H */ -- cgit v1.2.3 From ee2760ea58d81fc00bcc2137232ed9bc28202aec Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 12 Jan 2010 13:48:27 +0900 Subject: sh: default to sparseirq. As SH has a very sparse IRQ map by default, all new CPUs and boards benefit from using sparseirq by default. Despite this, there are still a few stragglers (mostly due to using a fixed IRQ range for their FPGA IRQ mappings), and these still need to be converted over one by one. As these are now in the minority, and we do not want to encourage this sort of brain-damage in newer board ports, we force sparseirq on. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 2121fbb2ff4c..ae6c73689036 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -726,8 +726,9 @@ config GUSA_RB disabling interrupts around the atomic sequence. config SPARSE_IRQ - bool "Support sparse irq numbering" - depends on EXPERIMENTAL + def_bool y + depends on SUPERH32 && !SH_DREAMCAST && !SH_HIGHLANDER && \ + !SH_RTS7751R2D && !HD64461 && !SH_7724_SOLUTION_ENGINE help This enables support for sparse irqs. This is useful in general as most CPUs have a fairly sparse array of IRQ vectors, which -- cgit v1.2.3 From 191d0d24b632eb69767705acded5cbf7449ad457 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 12 Jan 2010 14:50:43 +0900 Subject: sh: Tidy up the sh bios VBR handling. This moves the VBR handling out of the main trap handling code and in to the sh-bios helper code. A couple of accessors are added in order to permit other kernel code to get at the VBR value for state save/restore paths. Signed-off-by: Paul Mundt --- arch/sh/include/asm/sh_bios.h | 14 ++++++++++++-- arch/sh/kernel/machine_kexec.c | 8 ++------ arch/sh/kernel/sh_bios.c | 37 +++++++++++++++++++++++++++++++++++++ arch/sh/kernel/traps_32.c | 29 ++++------------------------- 4 files changed, 55 insertions(+), 33 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/sh_bios.h b/arch/sh/include/asm/sh_bios.h index d9c96d7cf6c7..d8a67a17777c 100644 --- a/arch/sh/include/asm/sh_bios.h +++ b/arch/sh/include/asm/sh_bios.h @@ -1,13 +1,13 @@ #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); @@ -15,4 +15,14 @@ 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/kernel/machine_kexec.c b/arch/sh/kernel/machine_kexec.c index 76f280223ebd..f52d8ed69e12 100644 --- a/arch/sh/kernel/machine_kexec.c +++ b/arch/sh/kernel/machine_kexec.c @@ -21,6 +21,7 @@ #include #include #include +#include typedef void (*relocate_new_kernel_t)(unsigned long indirection_page, unsigned long reboot_code_buffer, @@ -28,7 +29,6 @@ typedef void (*relocate_new_kernel_t)(unsigned long indirection_page, extern const unsigned char relocate_new_kernel[]; extern const unsigned int relocate_new_kernel_size; -extern void *gdb_vbr_vector; extern void *vbr_base; void machine_shutdown(void) @@ -117,11 +117,7 @@ void machine_kexec(struct kimage *image) kexec_info(image); flush_cache_all(); -#if defined(CONFIG_SH_STANDARD_BIOS) - asm volatile("ldc %0, vbr" : - : "r" (((unsigned long) gdb_vbr_vector) - 0x100) - : "memory"); -#endif + sh_bios_vbr_reload(); /* now call it */ rnk = (relocate_new_kernel_t) reboot_code_buffer; diff --git a/arch/sh/kernel/sh_bios.c b/arch/sh/kernel/sh_bios.c index c852f7805728..2a5f2e0d505d 100644 --- a/arch/sh/kernel/sh_bios.c +++ b/arch/sh/kernel/sh_bios.c @@ -55,3 +55,40 @@ void sh_bios_shutdown(unsigned int how) { sh_bios_call(BIOS_CALL_SHUTDOWN, how, 0, 0, 0); } + +void *gdb_vbr_vector = NULL; + +/* + * Read the old value of the VBR register to initialise the vector + * through which debug and BIOS traps are delegated by the Linux trap + * handler. + */ +void sh_bios_vbr_init(void) +{ + unsigned long vbr; + + if (unlikely(gdb_vbr_vector)) + return; + + __asm__ __volatile__ ("stc vbr, %0" : "=r" (vbr)); + + gdb_vbr_vector = (void *)(vbr + 0x100); + printk(KERN_NOTICE "Setting GDB trap vector to %p\n", gdb_vbr_vector); +} + +/** + * sh_bios_vbr_reload - Re-load the system VBR from the BIOS vector. + * + * This can be used by save/restore code to reinitialize the system VBR + * from the fixed BIOS VBR. A no-op if no BIOS VBR is known. + */ +void sh_bios_vbr_reload(void) +{ + if (gdb_vbr_vector) + __asm__ __volatile__ ( + "ldc %0, vbr" + : + : "r" (((unsigned long) gdb_vbr_vector) - 0x100) + : "memory" + ); +} diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c index 86639beac3a2..efcbdfe52f52 100644 --- a/arch/sh/kernel/traps_32.c +++ b/arch/sh/kernel/traps_32.c @@ -31,6 +31,7 @@ #include #include #include +#include #ifdef CONFIG_CPU_SH2 # define TRAP_RESERVED_INST 4 @@ -876,35 +877,10 @@ asmlinkage void do_exception_error(unsigned long r4, unsigned long r5, die_if_kernel("exception", regs, ex); } -#if defined(CONFIG_SH_STANDARD_BIOS) -void *gdb_vbr_vector; - -static inline void __init gdb_vbr_init(void) -{ - register unsigned long vbr; - - /* - * Read the old value of the VBR register to initialise - * the vector through which debug and BIOS traps are - * delegated by the Linux trap handler. - */ - asm volatile("stc vbr, %0" : "=r" (vbr)); - - gdb_vbr_vector = (void *)(vbr + 0x100); - printk("Setting GDB trap vector to 0x%08lx\n", - (unsigned long)gdb_vbr_vector); -} -#endif - void __cpuinit per_cpu_trap_init(void) { extern void *vbr_base; -#ifdef CONFIG_SH_STANDARD_BIOS - if (raw_smp_processor_id() == 0) - gdb_vbr_init(); -#endif - /* NOTE: The VBR value should be at P1 (or P2, virtural "fixed" address space). It's definitely should not in physical address. */ @@ -959,6 +935,9 @@ void __init trap_init(void) set_exception_table_vec(TRAP_UBC, break_point_trap); #endif + /* Save off the BIOS VBR, if there is one */ + sh_bios_vbr_init(); + /* Setup VBR for boot cpu */ per_cpu_trap_init(); } -- cgit v1.2.3 From 65fedbbef8404be5e1dbd18bdad252616b49a24b Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 12 Jan 2010 15:22:26 +0900 Subject: sh64: Fix up early serial fixmap. This was conditionalized on CONFIG_EARLY_PRINTK, which has subsequently gone away. Now that the serial driver always supports the early console, make sure we always establish the mapping. Signed-off-by: Paul Mundt --- arch/sh/kernel/head_64.S | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/kernel/head_64.S b/arch/sh/kernel/head_64.S index 3ea765844c74..defd851abefa 100644 --- a/arch/sh/kernel/head_64.S +++ b/arch/sh/kernel/head_64.S @@ -220,7 +220,6 @@ clear_DTLB: add.l r22, r63, r22 /* Sign extend */ putcfg r21, 0, r22 /* Set MMUDR[0].PTEH */ -#ifdef CONFIG_EARLY_PRINTK /* * Setup a DTLB translation for SCIF phys. */ @@ -231,7 +230,6 @@ clear_DTLB: movi 0xfa03, r22 /* 0xfa030000, fixed SCIF virt */ shori 0x0003, r22 putcfg r21, 0, r22 /* PTEH last */ -#endif /* * Set cache behaviours. -- cgit v1.2.3 From b9303a79567d4a45b015dff7e71dd24923332d8d Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 12 Jan 2010 15:26:11 +0900 Subject: sh: Kill off more unused sh_bios callbacks. sh_bios_char_out() is not used by anything in-tree these days, so just get rid of it. Signed-off-by: Paul Mundt --- arch/sh/include/asm/sh_bios.h | 1 - arch/sh/kernel/sh_bios.c | 5 ----- 2 files changed, 6 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/sh_bios.h b/arch/sh/include/asm/sh_bios.h index d8a67a17777c..95714c28422b 100644 --- a/arch/sh/include/asm/sh_bios.h +++ b/arch/sh/include/asm/sh_bios.h @@ -9,7 +9,6 @@ * 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); diff --git a/arch/sh/kernel/sh_bios.c b/arch/sh/kernel/sh_bios.c index 2a5f2e0d505d..2a9c6d50d2c0 100644 --- a/arch/sh/kernel/sh_bios.c +++ b/arch/sh/kernel/sh_bios.c @@ -34,11 +34,6 @@ void sh_bios_console_write(const char *buf, unsigned int len) sh_bios_call(BIOS_CALL_CONSOLE_WRITE, (long)buf, (long)len, 0, 0); } -void sh_bios_char_out(char ch) -{ - sh_bios_call(BIOS_CALL_CHAR_OUT, ch, 0, 0, 0); -} - void sh_bios_gdb_detach(void) { sh_bios_call(BIOS_CALL_GDB_DETACH, 0, 0, 0, 0); -- cgit v1.2.3 From 776258df925acd0563f471ee4b3f19bbffb3c04f Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 12 Jan 2010 15:31:20 +0900 Subject: sh: Consolidate the sh_bios earlyprintk code. Now that the sh-sci earlyprintk is taken care of by the sh-sci driver directly, there's no longer any reason for having a split-out early_printk framework. sh_bios is the only other thing that uses it, so we just migrate the leftovers in to there. As it's possible to have multiple early_param()'s for the same string, there's not much point in having this split out anymore anyways, particularly since the sh_bios dependencies are still special-cased within sh-sci itself. Signed-off-by: Paul Mundt --- arch/sh/include/asm/setup.h | 1 - arch/sh/kernel/Makefile | 2 +- arch/sh/kernel/early_printk.c | 85 ------------------------------------------- arch/sh/kernel/sh_bios.c | 80 +++++++++++++++++++++++++++++++++++++++- 4 files changed, 79 insertions(+), 89 deletions(-) delete mode 100644 arch/sh/kernel/early_printk.c (limited to 'arch/sh') diff --git a/arch/sh/include/asm/setup.h b/arch/sh/include/asm/setup.h index ce3743599b27..4758325bb24a 100644 --- a/arch/sh/include/asm/setup.h +++ b/arch/sh/include/asm/setup.h @@ -18,7 +18,6 @@ /* ... */ #define COMMAND_LINE ((char *) (PARAM+0x100)) -int setup_early_printk(char *); void sh_mv_setup(void); #endif /* __KERNEL__ */ diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile index 0d587da1ef12..5bec10c8bd74 100644 --- a/arch/sh/kernel/Makefile +++ b/arch/sh/kernel/Makefile @@ -22,7 +22,7 @@ obj-y := debugtraps.o dma-nommu.o dumpstack.o \ obj-y += cpu/ obj-$(CONFIG_VSYSCALL) += vsyscall/ obj-$(CONFIG_SMP) += smp.o -obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o early_printk.o +obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o obj-$(CONFIG_KGDB) += kgdb.o obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o obj-$(CONFIG_MODULES) += sh_ksyms_$(BITS).o module.o diff --git a/arch/sh/kernel/early_printk.c b/arch/sh/kernel/early_printk.c deleted file mode 100644 index f8bb50c6e050..000000000000 --- a/arch/sh/kernel/early_printk.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * arch/sh/kernel/early_printk.c - * - * Copyright (C) 1999, 2000 Niibe Yutaka - * Copyright (C) 2002 M. R. Brown - * Copyright (C) 2004 - 2007 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. - */ -#include -#include -#include -#include -#include - -#include - -/* - * Print a string through the BIOS - */ -static void sh_console_write(struct console *co, const char *s, - unsigned count) -{ - sh_bios_console_write(s, count); -} - -/* - * Setup initial baud/bits/parity. We do two things here: - * - construct a cflag setting for the first rs_open() - * - initialize the serial port - * Return non-zero if we didn't find a serial port. - */ -static int __init sh_console_setup(struct console *co, char *options) -{ - int cflag = CREAD | HUPCL | CLOCAL; - - /* - * Now construct a cflag setting. - * TODO: this is a totally bogus cflag, as we have - * no idea what serial settings the BIOS is using, or - * even if its using the serial port at all. - */ - cflag |= B115200 | CS8 | /*no parity*/0; - - co->cflag = cflag; - - return 0; -} - -static struct console bios_console = { - .name = "bios", - .write = sh_console_write, - .setup = sh_console_setup, - .flags = CON_PRINTBUFFER, - .index = -1, -}; - -static struct console *early_console; - -static int __init setup_early_printk(char *buf) -{ - int keep_early = 0; - - if (!buf) - return 0; - - if (strstr(buf, "keep")) - keep_early = 1; - - if (!strncmp(buf, "bios", 4)) - early_console = &bios_console; - - if (likely(early_console)) { - if (keep_early) - early_console->flags &= ~CON_BOOT; - else - early_console->flags |= CON_BOOT; - register_console(early_console); - } - - return 0; -} -early_param("earlyprintk", setup_early_printk); diff --git a/arch/sh/kernel/sh_bios.c b/arch/sh/kernel/sh_bios.c index 2a9c6d50d2c0..29cd2526e5c4 100644 --- a/arch/sh/kernel/sh_bios.c +++ b/arch/sh/kernel/sh_bios.c @@ -1,17 +1,26 @@ /* - * linux/arch/sh/kernel/sh_bios.c * C interface for trapping into the standard LinuxSH BIOS. * * Copyright (C) 2000 Greg Banks, Mitch Davis + * Copyright (C) 1999, 2000 Niibe Yutaka + * Copyright (C) 2002 M. R. Brown + * Copyright (C) 2004 - 2010 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. */ #include +#include +#include +#include +#include +#include #include #define BIOS_CALL_CONSOLE_WRITE 0 #define BIOS_CALL_ETH_NODE_ADDR 10 #define BIOS_CALL_SHUTDOWN 11 -#define BIOS_CALL_CHAR_OUT 0x1f /* TODO: hack */ #define BIOS_CALL_GDB_DETACH 0xff static inline long sh_bios_call(long func, long arg0, long arg1, long arg2, @@ -87,3 +96,70 @@ void sh_bios_vbr_reload(void) : "memory" ); } + +/* + * Print a string through the BIOS + */ +static void sh_console_write(struct console *co, const char *s, + unsigned count) +{ + sh_bios_console_write(s, count); +} + +/* + * Setup initial baud/bits/parity. We do two things here: + * - construct a cflag setting for the first rs_open() + * - initialize the serial port + * Return non-zero if we didn't find a serial port. + */ +static int __init sh_console_setup(struct console *co, char *options) +{ + int cflag = CREAD | HUPCL | CLOCAL; + + /* + * Now construct a cflag setting. + * TODO: this is a totally bogus cflag, as we have + * no idea what serial settings the BIOS is using, or + * even if its using the serial port at all. + */ + cflag |= B115200 | CS8 | /*no parity*/0; + + co->cflag = cflag; + + return 0; +} + +static struct console bios_console = { + .name = "bios", + .write = sh_console_write, + .setup = sh_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, +}; + +static struct console *early_console; + +static int __init setup_early_printk(char *buf) +{ + int keep_early = 0; + + if (!buf) + return 0; + + if (strstr(buf, "keep")) + keep_early = 1; + + if (!strncmp(buf, "bios", 4)) + early_console = &bios_console; + + if (likely(early_console)) { + if (keep_early) + early_console->flags &= ~CON_BOOT; + else + early_console->flags |= CON_BOOT; + register_console(early_console); + } + + return 0; +} +early_param("earlyprintk", setup_early_printk); -- cgit v1.2.3 From a99eae5417a09e0be66bf574a9a79a2a7388c967 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 12 Jan 2010 16:12:25 +0900 Subject: sh: Split out the unaligned counters and user bits. This splits out the unaligned access counters and userspace bits in to their own generic interface, which will allow them to be wired up on sh64 too. Signed-off-by: Paul Mundt --- arch/sh/include/asm/alignment.h | 21 ++++++ arch/sh/kernel/traps_32.c | 151 +++++--------------------------------- arch/sh/mm/Makefile | 2 +- arch/sh/mm/alignment.c | 159 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 198 insertions(+), 135 deletions(-) create mode 100644 arch/sh/include/asm/alignment.h create mode 100644 arch/sh/mm/alignment.c (limited to 'arch/sh') diff --git a/arch/sh/include/asm/alignment.h b/arch/sh/include/asm/alignment.h new file mode 100644 index 000000000000..b12efecf5294 --- /dev/null +++ b/arch/sh/include/asm/alignment.h @@ -0,0 +1,21 @@ +#ifndef __ASM_SH_ALIGNMENT_H +#define __ASM_SH_ALIGNMENT_H + +#include + +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/kernel/traps_32.c b/arch/sh/kernel/traps_32.c index efcbdfe52f52..204def6ecb6a 100644 --- a/arch/sh/kernel/traps_32.c +++ b/arch/sh/kernel/traps_32.c @@ -24,11 +24,10 @@ #include #include #include -#include -#include #include +#include #include -#include +#include #include #include #include @@ -48,73 +47,6 @@ #define TRAP_ILLEGAL_SLOT_INST 13 #endif -static unsigned long se_user; -static unsigned long se_sys; -static unsigned long se_half; -static unsigned long se_word; -static unsigned long se_dword; -static unsigned long se_multi; -/* bitfield: 1: warn 2: fixup 4: signal -> combinations 2|4 && 1|2|4 are not - valid! */ -static int se_usermode = 3; -/* 0: no warning 1: print a warning message, disabled by default */ -static int se_kernmode_warn; - -#ifdef CONFIG_PROC_FS -static const char *se_usermode_action[] = { - "ignored", - "warn", - "fixup", - "fixup+warn", - "signal", - "signal+warn" -}; - -static int alignment_proc_show(struct seq_file *m, void *v) -{ - seq_printf(m, "User:\t\t%lu\n", se_user); - seq_printf(m, "System:\t\t%lu\n", se_sys); - seq_printf(m, "Half:\t\t%lu\n", se_half); - seq_printf(m, "Word:\t\t%lu\n", se_word); - seq_printf(m, "DWord:\t\t%lu\n", se_dword); - seq_printf(m, "Multi:\t\t%lu\n", se_multi); - seq_printf(m, "User faults:\t%i (%s)\n", se_usermode, - se_usermode_action[se_usermode]); - seq_printf(m, "Kernel faults:\t%i (fixup%s)\n", se_kernmode_warn, - se_kernmode_warn ? "+warn" : ""); - return 0; -} - -static int alignment_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, alignment_proc_show, NULL); -} - -static ssize_t alignment_proc_write(struct file *file, - const char __user *buffer, size_t count, loff_t *pos) -{ - int *data = PDE(file->f_path.dentry->d_inode)->data; - char mode; - - if (count > 0) { - if (get_user(mode, buffer)) - return -EFAULT; - if (mode >= '0' && mode <= '5') - *data = mode - '0'; - } - return count; -} - -static const struct file_operations alignment_proc_fops = { - .owner = THIS_MODULE, - .open = alignment_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .write = alignment_proc_write, -}; -#endif - static void dump_mem(const char *str, unsigned long bottom, unsigned long top) { unsigned long p; @@ -266,10 +198,10 @@ static int handle_unaligned_ins(insn_size_t instruction, struct pt_regs *regs, count = 1<<(instruction&3); switch (count) { - case 1: se_half += 1; break; - case 2: se_word += 1; break; - case 4: se_dword += 1; break; - case 8: se_multi += 1; break; /* ??? */ + case 1: inc_unaligned_byte_access(); break; + case 2: inc_unaligned_word_access(); break; + case 4: inc_unaligned_dword_access(); break; + case 8: inc_unaligned_multi_access(); break; } ret = -EFAULT; @@ -453,18 +385,8 @@ int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs, rm = regs->regs[index]; /* shout about fixups */ - if (!expected) { - if (user_mode(regs) && (se_usermode & 1) && printk_ratelimit()) - pr_notice("Fixing up unaligned userspace access " - "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n", - current->comm, task_pid_nr(current), - (void *)regs->pc, instruction); - else if (se_kernmode_warn && printk_ratelimit()) - pr_notice("Fixing up unaligned kernel access " - "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n", - current->comm, task_pid_nr(current), - (void *)regs->pc, instruction); - } + if (!expected) + unaligned_fixups_notify(current, instruction, regs); ret = -EFAULT; switch (instruction&0xF000) { @@ -617,10 +539,10 @@ asmlinkage void do_address_error(struct pt_regs *regs, if (user_mode(regs)) { int si_code = BUS_ADRERR; + unsigned int user_action; local_irq_enable(); - - se_user += 1; + inc_unaligned_user_access(); set_fs(USER_DS); if (copy_from_user(&instruction, (insn_size_t *)(regs->pc & ~1), @@ -631,16 +553,12 @@ asmlinkage void do_address_error(struct pt_regs *regs, set_fs(oldfs); /* shout about userspace fixups */ - if (se_usermode & 1) - printk(KERN_NOTICE "Unaligned userspace access " - "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n", - current->comm, current->pid, (void *)regs->pc, - instruction); + unaligned_fixups_notify(current, instruction, regs); - if (se_usermode & 2) + user_action = unaligned_user_action(); + if (user_action & UM_FIXUP) goto fixup; - - if (se_usermode & 4) + if (user_action & UM_SIGNAL) goto uspace_segv; else { /* ignore */ @@ -660,7 +578,7 @@ fixup: &user_mem_access, 0); set_fs(oldfs); - if (tmp==0) + if (tmp == 0) return; /* sorted */ uspace_segv: printk(KERN_NOTICE "Sending SIGBUS to \"%s\" due to unaligned " @@ -673,7 +591,7 @@ uspace_segv: info.si_addr = (void __user *)address; force_sig_info(SIGBUS, &info, current); } else { - se_sys += 1; + inc_unaligned_kernel_access(); if (regs->pc & 1) die("unaligned program counter", regs, error_code); @@ -688,11 +606,7 @@ uspace_segv: die("insn faulting in do_address_error", regs, 0); } - if (se_kernmode_warn) - printk(KERN_NOTICE "Unaligned kernel access " - "on behalf of \"%s\" pid=%d pc=0x%p ins=0x%04hx\n", - current->comm, current->pid, (void *)regs->pc, - instruction); + unaligned_fixups_notify(current, instruction, regs); handle_unaligned_access(instruction, regs, &user_mem_access, 0); @@ -964,34 +878,3 @@ void dump_stack(void) show_stack(NULL, NULL); } EXPORT_SYMBOL(dump_stack); - -#ifdef CONFIG_PROC_FS -/* - * This needs to be done after sysctl_init, otherwise sys/ will be - * overwritten. Actually, this shouldn't be in sys/ at all since - * it isn't a sysctl, and it doesn't contain sysctl information. - * We now locate it in /proc/cpu/alignment instead. - */ -static int __init alignment_init(void) -{ - struct proc_dir_entry *dir, *res; - - dir = proc_mkdir("cpu", NULL); - if (!dir) - return -ENOMEM; - - res = proc_create_data("alignment", S_IWUSR | S_IRUGO, dir, - &alignment_proc_fops, &se_usermode); - if (!res) - return -ENOMEM; - - res = proc_create_data("kernel_alignment", S_IWUSR | S_IRUGO, dir, - &alignment_proc_fops, &se_kernmode_warn); - if (!res) - return -ENOMEM; - - return 0; -} - -fs_initcall(alignment_init); -#endif diff --git a/arch/sh/mm/Makefile b/arch/sh/mm/Makefile index dd5010c708e0..9fa11d655044 100644 --- a/arch/sh/mm/Makefile +++ b/arch/sh/mm/Makefile @@ -2,7 +2,7 @@ # Makefile for the Linux SuperH-specific parts of the memory manager. # -obj-y := cache.o init.o consistent.o mmap.o +obj-y := alignment.o cache.o init.o consistent.o mmap.o cacheops-$(CONFIG_CPU_SH2) := cache-sh2.o cacheops-$(CONFIG_CPU_SH2A) := cache-sh2a.o diff --git a/arch/sh/mm/alignment.c b/arch/sh/mm/alignment.c new file mode 100644 index 000000000000..e615151eac3b --- /dev/null +++ b/arch/sh/mm/alignment.c @@ -0,0 +1,159 @@ +/* + * Alignment access counters and corresponding user-space interfaces. + * + * Copyright (C) 2009 ST Microelectronics + * Copyright (C) 2009 - 2010 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. + */ +#include +#include +#include +#include +#include +#include + +static unsigned long se_user; +static unsigned long se_sys; +static unsigned long se_half; +static unsigned long se_word; +static unsigned long se_dword; +static unsigned long se_multi; +/* bitfield: 1: warn 2: fixup 4: signal -> combinations 2|4 && 1|2|4 are not + valid! */ +static int se_usermode = UM_WARN | UM_FIXUP; +/* 0: no warning 1: print a warning message, disabled by default */ +static int se_kernmode_warn; + +void inc_unaligned_byte_access(void) +{ + se_half++; +} + +void inc_unaligned_word_access(void) +{ + se_word++; +} + +void inc_unaligned_dword_access(void) +{ + se_dword++; +} + +void inc_unaligned_multi_access(void) +{ + se_multi++; +} + +void inc_unaligned_user_access(void) +{ + se_user++; +} + +void inc_unaligned_kernel_access(void) +{ + se_sys++; +} + +unsigned int unaligned_user_action(void) +{ + return se_usermode; +} + +void unaligned_fixups_notify(struct task_struct *tsk, insn_size_t insn, + struct pt_regs *regs) +{ + if (user_mode(regs) && (se_usermode & UM_WARN) && printk_ratelimit()) + pr_notice("Fixing up unaligned userspace access " + "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n", + tsk->comm, task_pid_nr(tsk), + (void *)regs->pc, insn); + else if (se_kernmode_warn && printk_ratelimit()) + pr_notice("Fixing up unaligned kernel access " + "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n", + tsk->comm, task_pid_nr(tsk), + (void *)regs->pc, insn); +} + +static const char *se_usermode_action[] = { + "ignored", + "warn", + "fixup", + "fixup+warn", + "signal", + "signal+warn" +}; + +static int alignment_proc_show(struct seq_file *m, void *v) +{ + seq_printf(m, "User:\t\t%lu\n", se_user); + seq_printf(m, "System:\t\t%lu\n", se_sys); + seq_printf(m, "Half:\t\t%lu\n", se_half); + seq_printf(m, "Word:\t\t%lu\n", se_word); + seq_printf(m, "DWord:\t\t%lu\n", se_dword); + seq_printf(m, "Multi:\t\t%lu\n", se_multi); + seq_printf(m, "User faults:\t%i (%s)\n", se_usermode, + se_usermode_action[se_usermode]); + seq_printf(m, "Kernel faults:\t%i (fixup%s)\n", se_kernmode_warn, + se_kernmode_warn ? "+warn" : ""); + return 0; +} + +static int alignment_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, alignment_proc_show, NULL); +} + +static ssize_t alignment_proc_write(struct file *file, + const char __user *buffer, size_t count, loff_t *pos) +{ + int *data = PDE(file->f_path.dentry->d_inode)->data; + char mode; + + if (count > 0) { + if (get_user(mode, buffer)) + return -EFAULT; + if (mode >= '0' && mode <= '5') + *data = mode - '0'; + } + return count; +} + +static const struct file_operations alignment_proc_fops = { + .owner = THIS_MODULE, + .open = alignment_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = alignment_proc_write, +}; + +/* + * This needs to be done after sysctl_init, otherwise sys/ will be + * overwritten. Actually, this shouldn't be in sys/ at all since + * it isn't a sysctl, and it doesn't contain sysctl information. + * We now locate it in /proc/cpu/alignment instead. + */ +static int __init alignment_init(void) +{ + struct proc_dir_entry *dir, *res; + + dir = proc_mkdir("cpu", NULL); + if (!dir) + return -ENOMEM; + + res = proc_create_data("alignment", S_IWUSR | S_IRUGO, dir, + &alignment_proc_fops, &se_usermode); + if (!res) + return -ENOMEM; + + res = proc_create_data("kernel_alignment", S_IWUSR | S_IRUGO, dir, + &alignment_proc_fops, &se_kernmode_warn); + if (!res) + return -ENOMEM; + + return 0; +} +fs_initcall(alignment_init); -- cgit v1.2.3 From 94cd049522136c2f3bbe063d2e98b2b8d4286fd3 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 12 Jan 2010 18:42:52 +0900 Subject: sh: sh_bios detection. This adds some VBR sanity checks in the sh_bios code to ensure that the BIOS VBR is in range before blindly trapping in to it. This permits boards with varying boot loader configurations to always leave support for sh-bios enabled and it will just be disabled at run-time if not found. Signed-off-by: Paul Mundt --- arch/sh/kernel/sh_bios.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/kernel/sh_bios.c b/arch/sh/kernel/sh_bios.c index 29cd2526e5c4..47475cca068a 100644 --- a/arch/sh/kernel/sh_bios.c +++ b/arch/sh/kernel/sh_bios.c @@ -23,6 +23,8 @@ #define BIOS_CALL_SHUTDOWN 11 #define BIOS_CALL_GDB_DETACH 0xff +void *gdb_vbr_vector = NULL; + static inline long sh_bios_call(long func, long arg0, long arg1, long arg2, long arg3) { @@ -32,6 +34,9 @@ static inline long sh_bios_call(long func, long arg0, long arg1, long arg2, register long r6 __asm__("r6") = arg2; register long r7 __asm__("r7") = arg3; + if (!gdb_vbr_vector) + return -ENOSYS; + __asm__ __volatile__("trapa #0x3f":"=z"(r0) :"0"(r0), "r"(r4), "r"(r5), "r"(r6), "r"(r7) :"memory"); @@ -60,8 +65,6 @@ void sh_bios_shutdown(unsigned int how) sh_bios_call(BIOS_CALL_SHUTDOWN, how, 0, 0, 0); } -void *gdb_vbr_vector = NULL; - /* * Read the old value of the VBR register to initialise the vector * through which debug and BIOS traps are delegated by the Linux trap @@ -76,8 +79,12 @@ void sh_bios_vbr_init(void) __asm__ __volatile__ ("stc vbr, %0" : "=r" (vbr)); - gdb_vbr_vector = (void *)(vbr + 0x100); - printk(KERN_NOTICE "Setting GDB trap vector to %p\n", gdb_vbr_vector); + if (vbr) { + gdb_vbr_vector = (void *)(vbr + 0x100); + printk(KERN_NOTICE "Setting GDB trap vector to %p\n", + gdb_vbr_vector); + } else + printk(KERN_NOTICE "SH-BIOS not detected\n"); } /** -- cgit v1.2.3 From 70e068eef97d05c97c3512f82352f39fdadfa8cb Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 12 Jan 2010 18:52:00 +0900 Subject: sh: Move start_thread() out of line. start_thread() will become a bit heavier with the xstate freeing to be added in, so move it out-of-line in preparation. Signed-off-by: Paul Mundt --- arch/sh/include/asm/processor_32.h | 13 ++----------- arch/sh/kernel/process_32.c | 12 ++++++++++++ 2 files changed, 14 insertions(+), 11 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/processor_32.h b/arch/sh/include/asm/processor_32.h index 1f3d6fab660c..50b8c9c3fa4c 100644 --- a/arch/sh/include/asm/processor_32.h +++ b/arch/sh/include/asm/processor_32.h @@ -119,19 +119,10 @@ extern int ubc_usercnt; .sp = sizeof(init_stack) + (long) &init_stack, \ } -/* - * 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 *); diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c index d8af889366a4..c4361402ec5e 100644 --- a/arch/sh/kernel/process_32.c +++ b/arch/sh/kernel/process_32.c @@ -147,6 +147,18 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) } EXPORT_SYMBOL(kernel_thread); +void start_thread(struct pt_regs *regs, unsigned long new_pc, + unsigned long new_sp) +{ + set_fs(USER_DS); + + regs->pr = 0; + regs->sr = SR_FD; + regs->pc = new_pc; + regs->regs[15] = new_sp; +} +EXPORT_SYMBOL(start_thread); + /* * Free current thread data structures etc.. */ -- cgit v1.2.3 From cbf6b1ba7ae12b3f7cb6b0d060b88d44649f9eda Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 12 Jan 2010 19:01:11 +0900 Subject: sh: Always provide thread_info allocators. Presently the thread_info allocators are special cased, depending on THREAD_SHIFT < PAGE_SHIFT. This provides a sensible definition for them regardless of configuration, in preparation for extended CPU state. Signed-off-by: Paul Mundt --- arch/sh/include/asm/thread_info.h | 6 ++--- arch/sh/kernel/Makefile | 4 ++-- arch/sh/kernel/process.c | 47 +++++++++++++++++++++++++++++++++++++++ arch/sh/mm/init.c | 29 ------------------------ 4 files changed, 51 insertions(+), 35 deletions(-) create mode 100644 arch/sh/kernel/process.c (limited to 'arch/sh') diff --git a/arch/sh/include/asm/thread_info.h b/arch/sh/include/asm/thread_info.h index 1f3d927e2265..2c5b48edeab9 100644 --- a/arch/sh/include/asm/thread_info.h +++ b/arch/sh/include/asm/thread_info.h @@ -93,14 +93,12 @@ 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 */ +#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR #endif /* __ASSEMBLY__ */ diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile index 5bec10c8bd74..379053c008f7 100644 --- a/arch/sh/kernel/Makefile +++ b/arch/sh/kernel/Makefile @@ -13,8 +13,8 @@ CFLAGS_REMOVE_return_address.o = -pg obj-y := debugtraps.o dma-nommu.o dumpstack.o \ idle.o io.o io_generic.o irq.o \ - irq_$(BITS).o machvec.o nmi_debug.o process_$(BITS).o \ - ptrace_$(BITS).o return_address.o \ + irq_$(BITS).o machvec.o nmi_debug.o process.o \ + process_$(BITS).o ptrace_$(BITS).o return_address.o \ setup.o signal_$(BITS).o sys_sh.o sys_sh$(BITS).o \ syscalls_$(BITS).o time.o topology.o traps.o \ traps_$(BITS).o unwinder.o diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c new file mode 100644 index 000000000000..b2bda83baeef --- /dev/null +++ b/arch/sh/kernel/process.c @@ -0,0 +1,47 @@ +#include +#include +#include + +#if THREAD_SHIFT < PAGE_SHIFT +static struct kmem_cache *thread_info_cache; + +struct thread_info *alloc_thread_info(struct task_struct *tsk) +{ + struct thread_info *ti; + + ti = kmem_cache_alloc(thread_info_cache, GFP_KERNEL); + if (unlikely(ti == NULL)) + return NULL; +#ifdef CONFIG_DEBUG_STACK_USAGE + memset(ti, 0, THREAD_SIZE); +#endif + return ti; +} + +void free_thread_info(struct thread_info *ti) +{ + kmem_cache_free(thread_info_cache, ti); +} + +void thread_info_cache_init(void) +{ + thread_info_cache = kmem_cache_create("thread_info", THREAD_SIZE, + THREAD_SIZE, 0, NULL); + BUG_ON(thread_info_cache == NULL); +} +#else +struct thread_info *alloc_thread_info(struct task_struct *tsk) +{ +#ifdef CONFIG_DEBUG_STACK_USAGE + gfp_t mask = GFP_KERNEL | __GFP_ZERO; +#else + gfp_t mask = GFP_KERNEL; +#endif + return (struct thread_info *)__get_free_pages(mask, THREAD_SIZE_ORDER); +} + +void free_thread_info(struct thread_info *ti) +{ + free_pages((unsigned long)ti, THREAD_SIZE_ORDER); +} +#endif /* THREAD_SHIFT < PAGE_SHIFT */ diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 761910d142f8..d5fb014279ad 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -283,35 +283,6 @@ void free_initrd_mem(unsigned long start, unsigned long end) } #endif -#if THREAD_SHIFT < PAGE_SHIFT -static struct kmem_cache *thread_info_cache; - -struct thread_info *alloc_thread_info(struct task_struct *tsk) -{ - struct thread_info *ti; - - ti = kmem_cache_alloc(thread_info_cache, GFP_KERNEL); - if (unlikely(ti == NULL)) - return NULL; -#ifdef CONFIG_DEBUG_STACK_USAGE - memset(ti, 0, THREAD_SIZE); -#endif - return ti; -} - -void free_thread_info(struct thread_info *ti) -{ - kmem_cache_free(thread_info_cache, ti); -} - -void thread_info_cache_init(void) -{ - thread_info_cache = kmem_cache_create("thread_info", THREAD_SIZE, - THREAD_SIZE, 0, NULL); - BUG_ON(thread_info_cache == NULL); -} -#endif /* THREAD_SHIFT < PAGE_SHIFT */ - #ifdef CONFIG_MEMORY_HOTPLUG int arch_add_memory(int nid, u64 start, u64 size) { -- cgit v1.2.3 From a3705799e2cc5fb69d88ad6a7f317a8f5597f18d Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 12 Jan 2010 19:10:06 +0900 Subject: sh: Use SLAB_PANIC for thread_info slab cache. Presently this has a BUG_ON() for failure cases, as powerpc does. Switch this over to a SLAB_PANIC instead. Signed-off-by: Paul Mundt --- arch/sh/kernel/process.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c index b2bda83baeef..077e06e1a889 100644 --- a/arch/sh/kernel/process.c +++ b/arch/sh/kernel/process.c @@ -26,8 +26,7 @@ void free_thread_info(struct thread_info *ti) void thread_info_cache_init(void) { thread_info_cache = kmem_cache_create("thread_info", THREAD_SIZE, - THREAD_SIZE, 0, NULL); - BUG_ON(thread_info_cache == NULL); + THREAD_SIZE, SLAB_PANIC, NULL); } #else struct thread_info *alloc_thread_info(struct task_struct *tsk) -- cgit v1.2.3 From 0ea820cf9bf58f735ed40ec67947159c4f170012 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 13 Jan 2010 12:51:40 +0900 Subject: sh: Move over to dynamically allocated FPU context. This follows the x86 xstate changes and implements a task_xstate slab cache that is dynamically sized to match one of hard FP/soft FP/FPU-less. This also tidies up and consolidates some of the SH-2A/SH-4 FPU fragmentation. Now fpu state restorers are commonly defined, with the init_fpu()/fpu_init() mess reworked to follow the x86 convention. The fpu_init() register initialization has been replaced by xstate setup followed by writing out to hardware via the standard restore path. As init_fpu() now performs a slab allocation a secondary lighterweight restorer is also introduced for the context switch. In the future the DSP state will be rolled in here, too. More work remains for math emulation and the SH-5 FPU, which presently uses its own special (UP-only) interfaces. Signed-off-by: Paul Mundt --- arch/sh/include/asm/fpu.h | 35 +++----- arch/sh/include/asm/processor_32.h | 16 ++-- arch/sh/include/asm/thread_info.h | 4 + arch/sh/kernel/cpu/Makefile | 2 + arch/sh/kernel/cpu/fpu.c | 82 +++++++++++++++++++ arch/sh/kernel/cpu/init.c | 80 +++++++++++-------- arch/sh/kernel/cpu/sh2a/fpu.c | 111 ++++++-------------------- arch/sh/kernel/cpu/sh4/fpu.c | 159 +++++++++---------------------------- arch/sh/kernel/process.c | 54 +++++++++++++ arch/sh/kernel/process_32.c | 6 +- arch/sh/kernel/ptrace_32.c | 12 +-- arch/sh/kernel/signal_32.c | 4 +- arch/sh/math-emu/math.c | 12 +-- 13 files changed, 292 insertions(+), 285 deletions(-) create mode 100644 arch/sh/kernel/cpu/fpu.c (limited to 'arch/sh') diff --git a/arch/sh/include/asm/fpu.h b/arch/sh/include/asm/fpu.h index fb6bbb9b1cc8..06c4281aab65 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 -#include + +struct task_struct; #ifdef CONFIG_SH_FPU static inline void release_fpu(struct pt_regs *regs) @@ -16,22 +16,23 @@ static inline void grab_fpu(struct pt_regs *regs) regs->sr &= ~SR_FD; } -struct task_struct; - extern void save_fpu(struct task_struct *__tsk); -void fpu_state_restore(struct pt_regs *regs); +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 save_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 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, @@ -65,18 +66,6 @@ static inline void clear_fpu(struct task_struct *tsk, struct pt_regs *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/processor_32.h b/arch/sh/include/asm/processor_32.h index 50b8c9c3fa4c..a359898206e8 100644 --- a/arch/sh/include/asm/processor_32.h +++ b/arch/sh/include/asm/processor_32.h @@ -90,11 +90,15 @@ 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; }; +extern unsigned int xstate_size; +extern void free_thread_xstate(struct task_struct *); +extern struct kmem_cache *task_xstate_cachep; + struct thread_struct { /* Saved registers when thread is descheduled */ unsigned long sp; @@ -103,13 +107,13 @@ struct thread_struct { /* Hardware debugging registers */ unsigned long ubc_pc; - /* floating point info */ - union sh_fpu_union fpu; - #ifdef CONFIG_SH_DSP /* Dsp status information */ struct sh_dsp_struct dsp_status; #endif + + /* Extended processor state */ + union thread_xstate *xstate; }; /* Count of active tasks with UBC settings */ diff --git a/arch/sh/include/asm/thread_info.h b/arch/sh/include/asm/thread_info.h index 2c5b48edeab9..55a36fef6875 100644 --- a/arch/sh/include/asm/thread_info.h +++ b/arch/sh/include/asm/thread_info.h @@ -97,6 +97,10 @@ static inline struct thread_info *current_thread_info(void) extern struct thread_info *alloc_thread_info(struct task_struct *tsk); extern void free_thread_info(struct thread_info *ti); +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 diff --git a/arch/sh/kernel/cpu/Makefile b/arch/sh/kernel/cpu/Makefile index d97c803719ec..0e48bc61c272 100644 --- a/arch/sh/kernel/cpu/Makefile +++ b/arch/sh/kernel/cpu/Makefile @@ -17,5 +17,7 @@ obj-$(CONFIG_ARCH_SHMOBILE) += shmobile/ obj-$(CONFIG_SH_ADC) += adc.o obj-$(CONFIG_SH_CLK_CPG) += clock-cpg.o +obj-$(CONFIG_SH_FPU) += fpu.o +obj-$(CONFIG_SH_FPU_EMU) += fpu.o obj-y += irq/ init.o clock.o hwblk.o diff --git a/arch/sh/kernel/cpu/fpu.c b/arch/sh/kernel/cpu/fpu.c new file mode 100644 index 000000000000..c23e6727002a --- /dev/null +++ b/arch/sh/kernel/cpu/fpu.c @@ -0,0 +1,82 @@ +#include +#include +#include + +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; + } + + /* + * Memory allocation at the first usage of the FPU and other state. + */ + if (!tsk->thread.xstate) { + tsk->thread.xstate = kmem_cache_alloc(task_xstate_cachep, + GFP_KERNEL); + if (!tsk->thread.xstate) + return -ENOMEM; + } + + if (boot_cpu_data.flags & CPU_HAS_FPU) { + struct sh_fpu_hard_struct *fp = &tsk->thread.xstate->hardfpu; + memset(fp, 0, xstate_size); + fp->fpscr = FPSCR_INIT; + } else { + struct sh_fpu_soft_struct *fp = &tsk->thread.xstate->softfpu; + memset(fp, 0, xstate_size); + fp->fpscr = FPSCR_INIT; + } + + set_stopped_child_used_math(tsk); + return 0; +} + +#ifdef CONFIG_SH_FPU +void __fpu_state_restore(void) +{ + struct task_struct *tsk = current; + + restore_fpu(tsk); + + task_thread_info(tsk)->status |= TS_USEDFPU; + tsk->fpu_counter++; +} + +void fpu_state_restore(struct pt_regs *regs) +{ + struct task_struct *tsk = current; + + if (unlikely(!user_mode(regs))) { + printk(KERN_ERR "BUG: FPU is used in kernel mode.\n"); + BUG(); + return; + } + + if (!tsk_used_math(tsk)) { + /* + * does a slab alloc which can sleep + */ + if (init_fpu(tsk)) { + /* + * ran out of memory! + */ + do_group_exit(SIGKILL); + return; + } + } + + grab_fpu(regs); + + __fpu_state_restore(); +} + +BUILD_TRAP_HANDLER(fpu_state_restore) +{ + TRAP_HANDLER_DECL; + + fpu_state_restore(regs); +} +#endif /* CONFIG_SH_FPU */ diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c index 89b4b76c0d76..2e23422280a7 100644 --- a/arch/sh/kernel/cpu/init.c +++ b/arch/sh/kernel/cpu/init.c @@ -28,18 +28,30 @@ #include #endif +#ifdef CONFIG_SH_FPU +#define cpu_has_fpu 1 +#else +#define cpu_has_fpu 0 +#endif + +#ifdef CONFIG_SH_DSP +#define cpu_has_dsp 1 +#else +#define cpu_has_dsp 0 +#endif + /* * Generic wrapper for command line arguments to disable on-chip * peripherals (nofpu, nodsp, and so forth). */ -#define onchip_setup(x) \ -static int x##_disabled __initdata = 0; \ - \ -static int __init x##_setup(char *opts) \ -{ \ - x##_disabled = 1; \ - return 1; \ -} \ +#define onchip_setup(x) \ +static int x##_disabled __initdata = !cpu_has_##x; \ + \ +static int __init x##_setup(char *opts) \ +{ \ + x##_disabled = 1; \ + return 1; \ +} \ __setup("no" __stringify(x), x##_setup); onchip_setup(fpu); @@ -207,6 +219,18 @@ static void detect_cache_shape(void) l2_cache_shape = -1; /* No S-cache */ } +static void __init fpu_init(void) +{ + /* Disable the FPU */ + if (fpu_disabled && (current_cpu_data.flags & CPU_HAS_FPU)) { + printk("FPU Disabled\n"); + current_cpu_data.flags &= ~CPU_HAS_FPU; + } + + disable_fpu(); + clear_used_math(); +} + #ifdef CONFIG_SH_DSP static void __init release_dsp(void) { @@ -244,9 +268,17 @@ static void __init dsp_init(void) if (sr & SR_DSP) current_cpu_data.flags |= CPU_HAS_DSP; + /* Disable the DSP */ + if (dsp_disabled && (current_cpu_data.flags & CPU_HAS_DSP)) { + printk("DSP Disabled\n"); + current_cpu_data.flags &= ~CPU_HAS_DSP; + } + /* Now that we've determined the DSP status, clear the DSP bit. */ release_dsp(); } +#else +static inline void __init dsp_init(void) { } #endif /* CONFIG_SH_DSP */ /** @@ -302,18 +334,8 @@ asmlinkage void __init sh_cpu_init(void) detect_cache_shape(); } - /* Disable the FPU */ - if (fpu_disabled) { - printk("FPU Disabled\n"); - current_cpu_data.flags &= ~CPU_HAS_FPU; - } - - /* FPU initialization */ - disable_fpu(); - if ((current_cpu_data.flags & CPU_HAS_FPU)) { - current_thread_info()->status &= ~TS_USEDFPU; - clear_used_math(); - } + fpu_init(); + dsp_init(); /* * Initialize the per-CPU ASID cache very early, since the @@ -321,18 +343,12 @@ asmlinkage void __init sh_cpu_init(void) */ current_cpu_data.asid_cache = NO_CONTEXT; -#ifdef CONFIG_SH_DSP - /* Probe for DSP */ - dsp_init(); - - /* Disable the DSP */ - if (dsp_disabled) { - printk("DSP Disabled\n"); - current_cpu_data.flags &= ~CPU_HAS_DSP; - release_dsp(); - } -#endif - speculative_execution_init(); expmask_init(); + + /* + * Boot processor to setup the FP and extended state context info. + */ + if (raw_smp_processor_id() == 0) + init_thread_xstate(); } diff --git a/arch/sh/kernel/cpu/sh2a/fpu.c b/arch/sh/kernel/cpu/sh2a/fpu.c index d395ce5740e7..488d24e0cdf0 100644 --- a/arch/sh/kernel/cpu/sh2a/fpu.c +++ b/arch/sh/kernel/cpu/sh2a/fpu.c @@ -26,8 +26,7 @@ /* * Save FPU registers onto task structure. */ -void -save_fpu(struct task_struct *tsk) +void save_fpu(struct task_struct *tsk) { unsigned long dummy; @@ -52,7 +51,7 @@ save_fpu(struct task_struct *tsk) "fmov.s fr0, @-%0\n\t" "lds %3, fpscr\n\t" : "=r" (dummy) - : "0" ((char *)(&tsk->thread.fpu.hard.status)), + : "0" ((char *)(&tsk->thread.xstate->hardfpu.status)), "r" (FPSCR_RCHG), "r" (FPSCR_INIT) : "memory"); @@ -60,8 +59,7 @@ save_fpu(struct task_struct *tsk) disable_fpu(); } -static void -restore_fpu(struct task_struct *tsk) +void restore_fpu(struct task_struct *tsk) { unsigned long dummy; @@ -85,44 +83,11 @@ restore_fpu(struct task_struct *tsk) "lds.l @%0+, fpscr\n\t" "lds.l @%0+, fpul\n\t" : "=r" (dummy) - : "0" (&tsk->thread.fpu), "r" (FPSCR_RCHG) + : "0" (tsk->thread.xstate), "r" (FPSCR_RCHG) : "memory"); disable_fpu(); } -/* - * Load the FPU with signalling NANS. This bit pattern we're using - * has the property that no matter wether considered as single or as - * double precission represents signaling NANS. - */ - -static void -fpu_init(void) -{ - enable_fpu(); - asm volatile("lds %0, fpul\n\t" - "fsts fpul, fr0\n\t" - "fsts fpul, fr1\n\t" - "fsts fpul, fr2\n\t" - "fsts fpul, fr3\n\t" - "fsts fpul, fr4\n\t" - "fsts fpul, fr5\n\t" - "fsts fpul, fr6\n\t" - "fsts fpul, fr7\n\t" - "fsts fpul, fr8\n\t" - "fsts fpul, fr9\n\t" - "fsts fpul, fr10\n\t" - "fsts fpul, fr11\n\t" - "fsts fpul, fr12\n\t" - "fsts fpul, fr13\n\t" - "fsts fpul, fr14\n\t" - "fsts fpul, fr15\n\t" - "lds %2, fpscr\n\t" - : /* no output */ - : "r" (0), "r" (FPSCR_RCHG), "r" (FPSCR_INIT)); - disable_fpu(); -} - /* * Emulate arithmetic ops on denormalized number for some FPU insns. */ @@ -490,9 +455,9 @@ ieee_fpe_handler (struct pt_regs *regs) if ((finsn & 0xf1ff) == 0xf0ad) { /* fcnvsd */ struct task_struct *tsk = current; - if ((tsk->thread.fpu.hard.fpscr & FPSCR_FPU_ERROR)) { + if ((tsk->thread.xstate->hardfpu.fpscr & FPSCR_FPU_ERROR)) { /* FPU error */ - denormal_to_double (&tsk->thread.fpu.hard, + denormal_to_double (&tsk->thread.xstate->hardfpu, (finsn >> 8) & 0xf); } else return 0; @@ -507,9 +472,9 @@ ieee_fpe_handler (struct pt_regs *regs) n = (finsn >> 8) & 0xf; m = (finsn >> 4) & 0xf; - hx = tsk->thread.fpu.hard.fp_regs[n]; - hy = tsk->thread.fpu.hard.fp_regs[m]; - fpscr = tsk->thread.fpu.hard.fpscr; + hx = tsk->thread.xstate->hardfpu.fp_regs[n]; + hy = tsk->thread.xstate->hardfpu.fp_regs[m]; + fpscr = tsk->thread.xstate->hardfpu.fpscr; prec = fpscr & (1 << 19); if ((fpscr & FPSCR_FPU_ERROR) @@ -519,15 +484,15 @@ ieee_fpe_handler (struct pt_regs *regs) /* FPU error because of denormal */ llx = ((long long) hx << 32) - | tsk->thread.fpu.hard.fp_regs[n+1]; + | tsk->thread.xstate->hardfpu.fp_regs[n+1]; lly = ((long long) hy << 32) - | tsk->thread.fpu.hard.fp_regs[m+1]; + | tsk->thread.xstate->hardfpu.fp_regs[m+1]; if ((hx & 0x7fffffff) >= 0x00100000) llx = denormal_muld(lly, llx); else llx = denormal_muld(llx, lly); - tsk->thread.fpu.hard.fp_regs[n] = llx >> 32; - tsk->thread.fpu.hard.fp_regs[n+1] = llx & 0xffffffff; + tsk->thread.xstate->hardfpu.fp_regs[n] = llx >> 32; + tsk->thread.xstate->hardfpu.fp_regs[n+1] = llx & 0xffffffff; } else if ((fpscr & FPSCR_FPU_ERROR) && (!prec && ((hx & 0x7fffffff) < 0x00800000 || (hy & 0x7fffffff) < 0x00800000))) { @@ -536,7 +501,7 @@ ieee_fpe_handler (struct pt_regs *regs) hx = denormal_mulf(hy, hx); else hx = denormal_mulf(hx, hy); - tsk->thread.fpu.hard.fp_regs[n] = hx; + tsk->thread.xstate->hardfpu.fp_regs[n] = hx; } else return 0; @@ -550,9 +515,9 @@ ieee_fpe_handler (struct pt_regs *regs) n = (finsn >> 8) & 0xf; m = (finsn >> 4) & 0xf; - hx = tsk->thread.fpu.hard.fp_regs[n]; - hy = tsk->thread.fpu.hard.fp_regs[m]; - fpscr = tsk->thread.fpu.hard.fpscr; + hx = tsk->thread.xstate->hardfpu.fp_regs[n]; + hy = tsk->thread.xstate->hardfpu.fp_regs[m]; + fpscr = tsk->thread.xstate->hardfpu.fpscr; prec = fpscr & (1 << 19); if ((fpscr & FPSCR_FPU_ERROR) @@ -562,15 +527,15 @@ ieee_fpe_handler (struct pt_regs *regs) /* FPU error because of denormal */ llx = ((long long) hx << 32) - | tsk->thread.fpu.hard.fp_regs[n+1]; + | tsk->thread.xstate->hardfpu.fp_regs[n+1]; lly = ((long long) hy << 32) - | tsk->thread.fpu.hard.fp_regs[m+1]; + | tsk->thread.xstate->hardfpu.fp_regs[m+1]; if ((finsn & 0xf00f) == 0xf000) llx = denormal_addd(llx, lly); else llx = denormal_addd(llx, lly ^ (1LL << 63)); - tsk->thread.fpu.hard.fp_regs[n] = llx >> 32; - tsk->thread.fpu.hard.fp_regs[n+1] = llx & 0xffffffff; + tsk->thread.xstate->hardfpu.fp_regs[n] = llx >> 32; + tsk->thread.xstate->hardfpu.fp_regs[n+1] = llx & 0xffffffff; } else if ((fpscr & FPSCR_FPU_ERROR) && (!prec && ((hx & 0x7fffffff) < 0x00800000 || (hy & 0x7fffffff) < 0x00800000))) { @@ -579,7 +544,7 @@ ieee_fpe_handler (struct pt_regs *regs) hx = denormal_addf(hx, hy); else hx = denormal_addf(hx, hy ^ 0x80000000); - tsk->thread.fpu.hard.fp_regs[n] = hx; + tsk->thread.xstate->hardfpu.fp_regs[n] = hx; } else return 0; @@ -597,7 +562,7 @@ BUILD_TRAP_HANDLER(fpu_error) __unlazy_fpu(tsk, regs); if (ieee_fpe_handler(regs)) { - tsk->thread.fpu.hard.fpscr &= + tsk->thread.xstate->hardfpu.fpscr &= ~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK); grab_fpu(regs); restore_fpu(tsk); @@ -607,33 +572,3 @@ BUILD_TRAP_HANDLER(fpu_error) force_sig(SIGFPE, tsk); } - -void fpu_state_restore(struct pt_regs *regs) -{ - struct task_struct *tsk = current; - - grab_fpu(regs); - if (unlikely(!user_mode(regs))) { - printk(KERN_ERR "BUG: FPU is used in kernel mode.\n"); - BUG(); - return; - } - - if (likely(used_math())) { - /* Using the FPU again. */ - restore_fpu(tsk); - } else { - /* First time FPU user. */ - fpu_init(); - set_used_math(); - } - task_thread_info(tsk)->status |= TS_USEDFPU; - tsk->fpu_counter++; -} - -BUILD_TRAP_HANDLER(fpu_state_restore) -{ - TRAP_HANDLER_DECL; - - fpu_state_restore(regs); -} diff --git a/arch/sh/kernel/cpu/sh4/fpu.c b/arch/sh/kernel/cpu/sh4/fpu.c index e97857aec8a0..447482d7f65e 100644 --- a/arch/sh/kernel/cpu/sh4/fpu.c +++ b/arch/sh/kernel/cpu/sh4/fpu.c @@ -85,14 +85,14 @@ void save_fpu(struct task_struct *tsk) "fmov.s fr1, @-%0\n\t" "fmov.s fr0, @-%0\n\t" "lds %3, fpscr\n\t":"=r" (dummy) - :"0"((char *)(&tsk->thread.fpu.hard.status)), + :"0"((char *)(&tsk->thread.xstate->hardfpu.status)), "r"(FPSCR_RCHG), "r"(FPSCR_INIT) :"memory"); disable_fpu(); } -static void restore_fpu(struct task_struct *tsk) +void restore_fpu(struct task_struct *tsk) { unsigned long dummy; @@ -135,62 +135,11 @@ static void restore_fpu(struct task_struct *tsk) "lds.l @%0+, fpscr\n\t" "lds.l @%0+, fpul\n\t" :"=r" (dummy) - :"0"(&tsk->thread.fpu), "r"(FPSCR_RCHG) + :"0" (tsk->thread.xstate), "r" (FPSCR_RCHG) :"memory"); disable_fpu(); } -/* - * Load the FPU with signalling NANS. This bit pattern we're using - * has the property that no matter wether considered as single or as - * double precision represents signaling NANS. - */ - -static void fpu_init(void) -{ - enable_fpu(); - asm volatile ( "lds %0, fpul\n\t" - "lds %1, fpscr\n\t" - "fsts fpul, fr0\n\t" - "fsts fpul, fr1\n\t" - "fsts fpul, fr2\n\t" - "fsts fpul, fr3\n\t" - "fsts fpul, fr4\n\t" - "fsts fpul, fr5\n\t" - "fsts fpul, fr6\n\t" - "fsts fpul, fr7\n\t" - "fsts fpul, fr8\n\t" - "fsts fpul, fr9\n\t" - "fsts fpul, fr10\n\t" - "fsts fpul, fr11\n\t" - "fsts fpul, fr12\n\t" - "fsts fpul, fr13\n\t" - "fsts fpul, fr14\n\t" - "fsts fpul, fr15\n\t" - "frchg\n\t" - "fsts fpul, fr0\n\t" - "fsts fpul, fr1\n\t" - "fsts fpul, fr2\n\t" - "fsts fpul, fr3\n\t" - "fsts fpul, fr4\n\t" - "fsts fpul, fr5\n\t" - "fsts fpul, fr6\n\t" - "fsts fpul, fr7\n\t" - "fsts fpul, fr8\n\t" - "fsts fpul, fr9\n\t" - "fsts fpul, fr10\n\t" - "fsts fpul, fr11\n\t" - "fsts fpul, fr12\n\t" - "fsts fpul, fr13\n\t" - "fsts fpul, fr14\n\t" - "fsts fpul, fr15\n\t" - "frchg\n\t" - "lds %2, fpscr\n\t" - : /* no output */ - :"r" (0), "r"(FPSCR_RCHG), "r"(FPSCR_INIT)); - disable_fpu(); -} - /** * denormal_to_double - Given denormalized float number, * store double float @@ -282,9 +231,9 @@ static int ieee_fpe_handler(struct pt_regs *regs) /* fcnvsd */ struct task_struct *tsk = current; - if ((tsk->thread.fpu.hard.fpscr & FPSCR_CAUSE_ERROR)) + if ((tsk->thread.xstate->hardfpu.fpscr & FPSCR_CAUSE_ERROR)) /* FPU error */ - denormal_to_double(&tsk->thread.fpu.hard, + denormal_to_double(&tsk->thread.xstate->hardfpu, (finsn >> 8) & 0xf); else return 0; @@ -300,9 +249,9 @@ static int ieee_fpe_handler(struct pt_regs *regs) n = (finsn >> 8) & 0xf; m = (finsn >> 4) & 0xf; - hx = tsk->thread.fpu.hard.fp_regs[n]; - hy = tsk->thread.fpu.hard.fp_regs[m]; - fpscr = tsk->thread.fpu.hard.fpscr; + hx = tsk->thread.xstate->hardfpu.fp_regs[n]; + hy = tsk->thread.xstate->hardfpu.fp_regs[m]; + fpscr = tsk->thread.xstate->hardfpu.fpscr; prec = fpscr & FPSCR_DBL_PRECISION; if ((fpscr & FPSCR_CAUSE_ERROR) @@ -312,18 +261,18 @@ static int ieee_fpe_handler(struct pt_regs *regs) /* FPU error because of denormal (doubles) */ llx = ((long long)hx << 32) - | tsk->thread.fpu.hard.fp_regs[n + 1]; + | tsk->thread.xstate->hardfpu.fp_regs[n + 1]; lly = ((long long)hy << 32) - | tsk->thread.fpu.hard.fp_regs[m + 1]; + | tsk->thread.xstate->hardfpu.fp_regs[m + 1]; llx = float64_mul(llx, lly); - tsk->thread.fpu.hard.fp_regs[n] = llx >> 32; - tsk->thread.fpu.hard.fp_regs[n + 1] = llx & 0xffffffff; + tsk->thread.xstate->hardfpu.fp_regs[n] = llx >> 32; + tsk->thread.xstate->hardfpu.fp_regs[n + 1] = llx & 0xffffffff; } else if ((fpscr & FPSCR_CAUSE_ERROR) && (!prec && ((hx & 0x7fffffff) < 0x00800000 || (hy & 0x7fffffff) < 0x00800000))) { /* FPU error because of denormal (floats) */ hx = float32_mul(hx, hy); - tsk->thread.fpu.hard.fp_regs[n] = hx; + tsk->thread.xstate->hardfpu.fp_regs[n] = hx; } else return 0; @@ -338,9 +287,9 @@ static int ieee_fpe_handler(struct pt_regs *regs) n = (finsn >> 8) & 0xf; m = (finsn >> 4) & 0xf; - hx = tsk->thread.fpu.hard.fp_regs[n]; - hy = tsk->thread.fpu.hard.fp_regs[m]; - fpscr = tsk->thread.fpu.hard.fpscr; + hx = tsk->thread.xstate->hardfpu.fp_regs[n]; + hy = tsk->thread.xstate->hardfpu.fp_regs[m]; + fpscr = tsk->thread.xstate->hardfpu.fpscr; prec = fpscr & FPSCR_DBL_PRECISION; if ((fpscr & FPSCR_CAUSE_ERROR) @@ -350,15 +299,15 @@ static int ieee_fpe_handler(struct pt_regs *regs) /* FPU error because of denormal (doubles) */ llx = ((long long)hx << 32) - | tsk->thread.fpu.hard.fp_regs[n + 1]; + | tsk->thread.xstate->hardfpu.fp_regs[n + 1]; lly = ((long long)hy << 32) - | tsk->thread.fpu.hard.fp_regs[m + 1]; + | tsk->thread.xstate->hardfpu.fp_regs[m + 1]; if ((finsn & 0xf00f) == 0xf000) llx = float64_add(llx, lly); else llx = float64_sub(llx, lly); - tsk->thread.fpu.hard.fp_regs[n] = llx >> 32; - tsk->thread.fpu.hard.fp_regs[n + 1] = llx & 0xffffffff; + tsk->thread.xstate->hardfpu.fp_regs[n] = llx >> 32; + tsk->thread.xstate->hardfpu.fp_regs[n + 1] = llx & 0xffffffff; } else if ((fpscr & FPSCR_CAUSE_ERROR) && (!prec && ((hx & 0x7fffffff) < 0x00800000 || (hy & 0x7fffffff) < 0x00800000))) { @@ -367,7 +316,7 @@ static int ieee_fpe_handler(struct pt_regs *regs) hx = float32_add(hx, hy); else hx = float32_sub(hx, hy); - tsk->thread.fpu.hard.fp_regs[n] = hx; + tsk->thread.xstate->hardfpu.fp_regs[n] = hx; } else return 0; @@ -382,9 +331,9 @@ static int ieee_fpe_handler(struct pt_regs *regs) n = (finsn >> 8) & 0xf; m = (finsn >> 4) & 0xf; - hx = tsk->thread.fpu.hard.fp_regs[n]; - hy = tsk->thread.fpu.hard.fp_regs[m]; - fpscr = tsk->thread.fpu.hard.fpscr; + hx = tsk->thread.xstate->hardfpu.fp_regs[n]; + hy = tsk->thread.xstate->hardfpu.fp_regs[m]; + fpscr = tsk->thread.xstate->hardfpu.fpscr; prec = fpscr & FPSCR_DBL_PRECISION; if ((fpscr & FPSCR_CAUSE_ERROR) @@ -394,20 +343,20 @@ static int ieee_fpe_handler(struct pt_regs *regs) /* FPU error because of denormal (doubles) */ llx = ((long long)hx << 32) - | tsk->thread.fpu.hard.fp_regs[n + 1]; + | tsk->thread.xstate->hardfpu.fp_regs[n + 1]; lly = ((long long)hy << 32) - | tsk->thread.fpu.hard.fp_regs[m + 1]; + | tsk->thread.xstate->hardfpu.fp_regs[m + 1]; llx = float64_div(llx, lly); - tsk->thread.fpu.hard.fp_regs[n] = llx >> 32; - tsk->thread.fpu.hard.fp_regs[n + 1] = llx & 0xffffffff; + tsk->thread.xstate->hardfpu.fp_regs[n] = llx >> 32; + tsk->thread.xstate->hardfpu.fp_regs[n + 1] = llx & 0xffffffff; } else if ((fpscr & FPSCR_CAUSE_ERROR) && (!prec && ((hx & 0x7fffffff) < 0x00800000 || (hy & 0x7fffffff) < 0x00800000))) { /* FPU error because of denormal (floats) */ hx = float32_div(hx, hy); - tsk->thread.fpu.hard.fp_regs[n] = hx; + tsk->thread.xstate->hardfpu.fp_regs[n] = hx; } else return 0; @@ -420,17 +369,17 @@ static int ieee_fpe_handler(struct pt_regs *regs) unsigned int hx; m = (finsn >> 8) & 0x7; - hx = tsk->thread.fpu.hard.fp_regs[m]; + hx = tsk->thread.xstate->hardfpu.fp_regs[m]; - if ((tsk->thread.fpu.hard.fpscr & FPSCR_CAUSE_ERROR) + if ((tsk->thread.xstate->hardfpu.fpscr & FPSCR_CAUSE_ERROR) && ((hx & 0x7fffffff) < 0x00100000)) { /* subnormal double to float conversion */ long long llx; - llx = ((long long)tsk->thread.fpu.hard.fp_regs[m] << 32) - | tsk->thread.fpu.hard.fp_regs[m + 1]; + llx = ((long long)tsk->thread.xstate->hardfpu.fp_regs[m] << 32) + | tsk->thread.xstate->hardfpu.fp_regs[m + 1]; - tsk->thread.fpu.hard.fpul = float64_to_float32(llx); + tsk->thread.xstate->hardfpu.fpul = float64_to_float32(llx); } else return 0; @@ -449,7 +398,7 @@ void float_raise(unsigned int flags) int float_rounding_mode(void) { struct task_struct *tsk = current; - int roundingMode = FPSCR_ROUNDING_MODE(tsk->thread.fpu.hard.fpscr); + int roundingMode = FPSCR_ROUNDING_MODE(tsk->thread.xstate->hardfpu.fpscr); return roundingMode; } @@ -461,16 +410,16 @@ BUILD_TRAP_HANDLER(fpu_error) __unlazy_fpu(tsk, regs); fpu_exception_flags = 0; if (ieee_fpe_handler(regs)) { - tsk->thread.fpu.hard.fpscr &= + tsk->thread.xstate->hardfpu.fpscr &= ~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK); - tsk->thread.fpu.hard.fpscr |= fpu_exception_flags; + tsk->thread.xstate->hardfpu.fpscr |= fpu_exception_flags; /* Set the FPSCR flag as well as cause bits - simply * replicate the cause */ - tsk->thread.fpu.hard.fpscr |= (fpu_exception_flags >> 10); + tsk->thread.xstate->hardfpu.fpscr |= (fpu_exception_flags >> 10); grab_fpu(regs); restore_fpu(tsk); task_thread_info(tsk)->status |= TS_USEDFPU; - if ((((tsk->thread.fpu.hard.fpscr & FPSCR_ENABLE_MASK) >> 7) & + if ((((tsk->thread.xstate->hardfpu.fpscr & FPSCR_ENABLE_MASK) >> 7) & (fpu_exception_flags >> 2)) == 0) { return; } @@ -478,33 +427,3 @@ BUILD_TRAP_HANDLER(fpu_error) force_sig(SIGFPE, tsk); } - -void fpu_state_restore(struct pt_regs *regs) -{ - struct task_struct *tsk = current; - - grab_fpu(regs); - if (unlikely(!user_mode(regs))) { - printk(KERN_ERR "BUG: FPU is used in kernel mode.\n"); - BUG(); - return; - } - - if (likely(used_math())) { - /* Using the FPU again. */ - restore_fpu(tsk); - } else { - /* First time FPU user. */ - fpu_init(); - set_used_math(); - } - task_thread_info(tsk)->status |= TS_USEDFPU; - tsk->fpu_counter++; -} - -BUILD_TRAP_HANDLER(fpu_state_restore) -{ - TRAP_HANDLER_DECL; - - fpu_state_restore(regs); -} diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c index 077e06e1a889..81add9b9ea6e 100644 --- a/arch/sh/kernel/process.c +++ b/arch/sh/kernel/process.c @@ -2,6 +2,32 @@ #include #include +struct kmem_cache *task_xstate_cachep = NULL; +unsigned int xstate_size; + +int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) +{ + *dst = *src; + + if (src->thread.xstate) { + dst->thread.xstate = kmem_cache_alloc(task_xstate_cachep, + GFP_KERNEL); + if (!dst->thread.xstate) + return -ENOMEM; + memcpy(dst->thread.xstate, src->thread.xstate, xstate_size); + } + + return 0; +} + +void free_thread_xstate(struct task_struct *tsk) +{ + if (tsk->thread.xstate) { + kmem_cache_free(task_xstate_cachep, tsk->thread.xstate); + tsk->thread.xstate = NULL; + } +} + #if THREAD_SHIFT < PAGE_SHIFT static struct kmem_cache *thread_info_cache; @@ -20,6 +46,7 @@ struct thread_info *alloc_thread_info(struct task_struct *tsk) void free_thread_info(struct thread_info *ti) { + free_thread_xstate(ti->task); kmem_cache_free(thread_info_cache, ti); } @@ -41,6 +68,33 @@ struct thread_info *alloc_thread_info(struct task_struct *tsk) void free_thread_info(struct thread_info *ti) { + free_thread_xstate(ti->task); free_pages((unsigned long)ti, THREAD_SIZE_ORDER); } #endif /* THREAD_SHIFT < PAGE_SHIFT */ + +void arch_task_cache_init(void) +{ + if (!xstate_size) + return; + + task_xstate_cachep = kmem_cache_create("task_xstate", xstate_size, + __alignof__(union thread_xstate), + SLAB_PANIC | SLAB_NOTRACK, NULL); +} + +#ifdef CONFIG_SH_FPU_EMU +# define HAVE_SOFTFP 1 +#else +# define HAVE_SOFTFP 0 +#endif + +void init_thread_xstate(void) +{ + if (boot_cpu_data.flags & CPU_HAS_FPU) + xstate_size = sizeof(struct sh_fpu_hard_struct); + else if (HAVE_SOFTFP) + xstate_size = sizeof(struct sh_fpu_soft_struct); + else + xstate_size = 0; +} diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c index c4361402ec5e..03de6573aa76 100644 --- a/arch/sh/kernel/process_32.c +++ b/arch/sh/kernel/process_32.c @@ -156,6 +156,8 @@ void start_thread(struct pt_regs *regs, unsigned long new_pc, regs->sr = SR_FD; regs->pc = new_pc; regs->regs[15] = new_sp; + + free_thread_xstate(current); } EXPORT_SYMBOL(start_thread); @@ -316,7 +318,7 @@ __switch_to(struct task_struct *prev, struct task_struct *next) /* we're going to use this soon, after a few expensive things */ if (next->fpu_counter > 5) - prefetch(&next_t->fpu.hard); + prefetch(next_t->xstate); #ifdef CONFIG_MMU /* @@ -353,7 +355,7 @@ __switch_to(struct task_struct *prev, struct task_struct *next) * chances of needing FPU soon are obviously high now */ if (next->fpu_counter > 5) - fpu_state_restore(task_pt_regs(next)); + __fpu_state_restore(); return prev; } diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c index 9be35f348093..be9b5dcb4021 100644 --- a/arch/sh/kernel/ptrace_32.c +++ b/arch/sh/kernel/ptrace_32.c @@ -163,10 +163,10 @@ int fpregs_get(struct task_struct *target, if ((boot_cpu_data.flags & CPU_HAS_FPU)) return user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.fpu.hard, 0, -1); + &target->thread.xstate->hardfpu, 0, -1); return user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.fpu.soft, 0, -1); + &target->thread.xstate->softfpu, 0, -1); } static int fpregs_set(struct task_struct *target, @@ -184,10 +184,10 @@ static int fpregs_set(struct task_struct *target, if ((boot_cpu_data.flags & CPU_HAS_FPU)) return user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.fpu.hard, 0, -1); + &target->thread.xstate->hardfpu, 0, -1); return user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.fpu.soft, 0, -1); + &target->thread.xstate->softfpu, 0, -1); } static int fpregs_active(struct task_struct *target, @@ -333,7 +333,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) else tmp = 0; } else - tmp = ((long *)&child->thread.fpu) + tmp = ((long *)child->thread.xstate) [(addr - (long)&dummy->fpu) >> 2]; } else if (addr == (long) &dummy->u_fpvalid) tmp = !!tsk_used_math(child); @@ -362,7 +362,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) else if (addr >= (long) &dummy->fpu && addr < (long) &dummy->u_fpvalid) { set_stopped_child_used_math(child); - ((long *)&child->thread.fpu) + ((long *)child->thread.xstate) [(addr - (long)&dummy->fpu) >> 2] = data; ret = 0; } else if (addr == (long) &dummy->u_fpvalid) { diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c index 12815ce01ecd..6a7cce79eb4e 100644 --- a/arch/sh/kernel/signal_32.c +++ b/arch/sh/kernel/signal_32.c @@ -150,7 +150,7 @@ static inline int restore_sigcontext_fpu(struct sigcontext __user *sc) return 0; set_used_math(); - return __copy_from_user(&tsk->thread.fpu.hard, &sc->sc_fpregs[0], + return __copy_from_user(&tsk->thread.xstate->hardfpu, &sc->sc_fpregs[0], sizeof(long)*(16*2+2)); } @@ -175,7 +175,7 @@ static inline int save_sigcontext_fpu(struct sigcontext __user *sc, clear_used_math(); unlazy_fpu(tsk, regs); - return __copy_to_user(&sc->sc_fpregs[0], &tsk->thread.fpu.hard, + return __copy_to_user(&sc->sc_fpregs[0], &tsk->thread.xstate->hardfpu, sizeof(long)*(16*2+2)); } #endif /* CONFIG_SH_FPU */ diff --git a/arch/sh/math-emu/math.c b/arch/sh/math-emu/math.c index d6c15cae0912..1fcdb1220975 100644 --- a/arch/sh/math-emu/math.c +++ b/arch/sh/math-emu/math.c @@ -471,10 +471,10 @@ static int fpu_emulate(u16 code, struct sh_fpu_soft_struct *fregs, struct pt_reg * denormal_to_double - Given denormalized float number, * store double float * - * @fpu: Pointer to sh_fpu_hard structure + * @fpu: Pointer to sh_fpu_soft structure * @n: Index to FP register */ -static void denormal_to_double(struct sh_fpu_hard_struct *fpu, int n) +static void denormal_to_double(struct sh_fpu_soft_struct *fpu, int n) { unsigned long du, dl; unsigned long x = fpu->fpul; @@ -552,11 +552,11 @@ static int ieee_fpe_handler(struct pt_regs *regs) if ((finsn & 0xf1ff) == 0xf0ad) { /* fcnvsd */ struct task_struct *tsk = current; - if ((tsk->thread.fpu.hard.fpscr & (1 << 17))) { + if ((tsk->thread.xstate->softfpu.fpscr & (1 << 17))) { /* FPU error */ - denormal_to_double (&tsk->thread.fpu.hard, + denormal_to_double (&tsk->thread.xstate->softfpu, (finsn >> 8) & 0xf); - tsk->thread.fpu.hard.fpscr &= + tsk->thread.xstate->softfpu.fpscr &= ~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK); task_thread_info(tsk)->status |= TS_USEDFPU; } else { @@ -617,7 +617,7 @@ static void fpu_init(struct sh_fpu_soft_struct *fpu) int do_fpu_inst(unsigned short inst, struct pt_regs *regs) { struct task_struct *tsk = current; - struct sh_fpu_soft_struct *fpu = &(tsk->thread.fpu.soft); + struct sh_fpu_soft_struct *fpu = &(tsk->thread.xstate->softfpu); if (!(task_thread_info(tsk)->status & TS_USEDFPU)) { /* initialize once. */ -- cgit v1.2.3 From 6430a5987f8bb9a7c5187b343956aa8ef404d571 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Wed, 13 Jan 2010 12:59:24 +0900 Subject: sh: Don't perform an icbi on a P2 address The legacy P2 area may not always be mapped (for example when using PMB). So perform an icbi on an address that we know will always be mapped. Signed-off-by: Matt Fleming Signed-off-by: Paul Mundt --- arch/sh/include/asm/system.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/system.h b/arch/sh/include/asm/system.h index c15415b4b169..b74d2532cc27 100644 --- a/arch/sh/include/asm/system.h +++ b/arch/sh/include/asm/system.h @@ -32,7 +32,7 @@ #define mb() __asm__ __volatile__ ("synco": : :"memory") #define rmb() mb() #define wmb() __asm__ __volatile__ ("synco": : :"memory") -#define ctrl_barrier() __icbi(0xa8000000) +#define ctrl_barrier() __icbi(PAGE_OFFSET) #define read_barrier_depends() do { } while(0) #else #define mb() __asm__ __volatile__ ("": : :"memory") -- cgit v1.2.3 From c7b16efb7d0c7fce218b2cdafa2432c5fbf57314 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 13 Jan 2010 13:29:19 +0900 Subject: sh: Add support for LZO-compressed kernels. Plugs in LZO along with the others. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 1 + arch/sh/Makefile | 5 +++-- arch/sh/boot/Makefile | 21 +++++++++++++++------ arch/sh/boot/compressed/Makefile | 3 +++ arch/sh/boot/compressed/misc.c | 4 ++++ 5 files changed, 26 insertions(+), 8 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 4eaf3401a15e..5ac0115c9e20 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -22,6 +22,7 @@ config SUPERH select HAVE_KERNEL_GZIP select HAVE_KERNEL_BZIP2 select HAVE_KERNEL_LZMA + select HAVE_KERNEL_LZO select HAVE_SYSCALL_TRACEPOINTS select RTC_LIB select GENERIC_ATOMIC64 diff --git a/arch/sh/Makefile b/arch/sh/Makefile index db91925c79d1..fd57676115e6 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -203,8 +203,8 @@ endif libs-$(CONFIG_SUPERH32) := arch/sh/lib/ $(libs-y) libs-$(CONFIG_SUPERH64) := arch/sh/lib64/ $(libs-y) -BOOT_TARGETS = uImage uImage.bz2 uImage.gz uImage.lzma uImage.srec uImage.bin \ - zImage vmlinux.srec romImage +BOOT_TARGETS = uImage uImage.bz2 uImage.gz uImage.lzma uImage.lzo \ + uImage.srec uImage.bin zImage vmlinux.srec romImage PHONY += $(BOOT_TARGETS) all: $(KBUILD_IMAGE) @@ -231,4 +231,5 @@ define archhelp @echo '* uImage.gz - Kernel-only image for U-Boot (gzip)' @echo ' uImage.bz2 - Kernel-only image for U-Boot (bzip2)' @echo ' uImage.lzma - Kernel-only image for U-Boot (lzma)' + @echo ' uImage.lzo - Kernel-only image for U-Boot (lzo)' endef diff --git a/arch/sh/boot/Makefile b/arch/sh/boot/Makefile index cb8cf5572e79..743ce0c8d98d 100644 --- a/arch/sh/boot/Makefile +++ b/arch/sh/boot/Makefile @@ -21,12 +21,15 @@ CONFIG_ZERO_PAGE_OFFSET ?= 0x00001000 CONFIG_ENTRY_OFFSET ?= 0x00001000 suffix-y := bin -suffix-$(CONFIG_KERNEL_GZIP) := gz -suffix-$(CONFIG_KERNEL_BZIP2) := bz2 -suffix-$(CONFIG_KERNEL_LZMA) := lzma - -targets := zImage vmlinux.srec romImage uImage uImage.srec uImage.gz uImage.bz2 uImage.lzma uImage.bin -extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma +suffix-$(CONFIG_KERNEL_GZIP) := gz +suffix-$(CONFIG_KERNEL_BZIP2) := bz2 +suffix-$(CONFIG_KERNEL_LZMA) := lzma +suffix-$(CONFIG_KERNEL_LZO) := lzo + +targets := zImage vmlinux.srec romImage uImage uImage.srec uImage.gz \ + uImage.bz2 uImage.lzma uImage.lzo uImage.bin +extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma \ + vmlinux.bin.lzo subdir- := compressed romimage $(obj)/zImage: $(obj)/compressed/vmlinux FORCE @@ -80,6 +83,9 @@ $(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE $(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE $(call if_changed,lzma) +$(obj)/vmlinux.bin.lzo: $(obj)/vmlinux.bin FORCE + $(call if_changed,lzo) + $(obj)/uImage.bz2: $(obj)/vmlinux.bin.bz2 $(call if_changed,uimage,bzip2) @@ -89,6 +95,9 @@ $(obj)/uImage.gz: $(obj)/vmlinux.bin.gz $(obj)/uImage.lzma: $(obj)/vmlinux.bin.lzma $(call if_changed,uimage,lzma) +$(obj)/uImage.lzo: $(obj)/vmlinux.bin.lzo + $(call if_changed,uimage,lzo) + $(obj)/uImage.bin: $(obj)/vmlinux.bin $(call if_changed,uimage,none) diff --git a/arch/sh/boot/compressed/Makefile b/arch/sh/boot/compressed/Makefile index 6182eca5180a..6b95a2a48267 100644 --- a/arch/sh/boot/compressed/Makefile +++ b/arch/sh/boot/compressed/Makefile @@ -6,6 +6,7 @@ targets := vmlinux vmlinux.bin vmlinux.bin.gz \ vmlinux.bin.bz2 vmlinux.bin.lzma \ + vmlinux.bin.lzo \ head_$(BITS).o misc.o piggy.o OBJECTS = $(obj)/head_$(BITS).o $(obj)/misc.o $(obj)/cache.o @@ -47,6 +48,8 @@ $(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y) FORCE $(call if_changed,bzip2) $(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y) FORCE $(call if_changed,lzma) +$(obj)/vmlinux.bin.lzo: $(vmlinux.bin.all-y) FORCE + $(call if_changed,lzo) OBJCOPYFLAGS += -R .empty_zero_page diff --git a/arch/sh/boot/compressed/misc.c b/arch/sh/boot/compressed/misc.c index b51b1fc4baae..4b319e9e4f88 100644 --- a/arch/sh/boot/compressed/misc.c +++ b/arch/sh/boot/compressed/misc.c @@ -62,6 +62,10 @@ static unsigned long free_mem_end_ptr; #include "../../../../lib/decompress_unlzma.c" #endif +#ifdef CONFIG_KERNEL_LZO +#include "../../../../lib/decompress_unlzo.c" +#endif + #ifdef CONFIG_SH_STANDARD_BIOS size_t strlen(const char *s) { -- cgit v1.2.3 From eca50f14b88315bd31183a17c89e53534f2ed2fa Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 13 Jan 2010 16:28:47 +0900 Subject: sh: Add a vmlinux.bin target. This makes vmlinux.bin generation an explicit make target, as opposed to just a dependency for some of the other targets. Signed-off-by: Paul Mundt --- arch/sh/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'arch/sh') diff --git a/arch/sh/Makefile b/arch/sh/Makefile index fd57676115e6..f7d5f42b00a7 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -204,7 +204,8 @@ libs-$(CONFIG_SUPERH32) := arch/sh/lib/ $(libs-y) libs-$(CONFIG_SUPERH64) := arch/sh/lib64/ $(libs-y) BOOT_TARGETS = uImage uImage.bz2 uImage.gz uImage.lzma uImage.lzo \ - uImage.srec uImage.bin zImage vmlinux.srec romImage + uImage.srec uImage.bin zImage vmlinux.bin vmlinux.srec \ + romImage PHONY += $(BOOT_TARGETS) all: $(KBUILD_IMAGE) @@ -225,6 +226,7 @@ define archhelp @echo ' zImage - Compressed kernel image' @echo ' romImage - Compressed ROM image, if supported' @echo ' vmlinux.srec - Create an ELF S-record' + @echo ' vmlinux.bin - Create an uncompressed binary image' @echo '* uImage - Alias to bootable U-Boot image' @echo ' uImage.srec - Create an S-record for U-Boot' @echo ' uImage.bin - Kernel-only image for U-Boot (bin)' -- cgit v1.2.3 From 7f33306ee57bce9c79825e89c457a91025aa5aad Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Wed, 13 Jan 2010 16:35:58 +0900 Subject: sh: PVR detection for 2nd cut SH7786. The mass produced cuts use an updated PVR value, add them to the list. Signed-off-by: Matt Fleming Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4/probe.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/sh') diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c index d36f0c45f55f..75189c4691da 100644 --- a/arch/sh/kernel/cpu/sh4/probe.c +++ b/arch/sh/kernel/cpu/sh4/probe.c @@ -124,6 +124,7 @@ int __init detect_cpu_and_cache_system(void) boot_cpu_data.type = CPU_SH7785; break; case 0x4004: + case 0x4005: boot_cpu_data.type = CPU_SH7786; boot_cpu_data.flags |= CPU_HAS_PTEAEX | CPU_HAS_L2_CACHE; break; -- cgit v1.2.3 From a0ab36689a36e583b6e736f1c99ac8c9aebdad59 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 13 Jan 2010 18:31:48 +0900 Subject: sh: fixed PMB mode refactoring. This introduces some much overdue chainsawing of the fixed PMB support. fixed PMB was introduced initially to work around the fact that dynamic PMB mode was relatively broken, though they were never intended to converge. The main areas where there are differences are whether the system is booted in 29-bit mode or 32-bit mode, and whether legacy mappings are to be preserved. Any system booting in true 32-bit mode will not care about legacy mappings, so these are roughly decoupled. Regardless of the entry point, PMB and 32BIT are directly related as far as the kernel is concerned, so we also switch back to having one select the other. With legacy mappings iterated through and applied in the initialization path it's now possible to finally merge the two implementations and permit dynamic remapping overtop of remaining entries regardless of whether boot mappings are crafted by hand or inherited from the boot loader. Signed-off-by: Paul Mundt --- arch/sh/boot/Makefile | 9 +--- arch/sh/include/asm/addrspace.h | 4 +- arch/sh/include/asm/io.h | 27 ++++++---- arch/sh/include/asm/mmu.h | 18 +++++++ arch/sh/include/asm/page.h | 2 +- arch/sh/kernel/head_32.S | 4 +- arch/sh/kernel/setup.c | 3 -- arch/sh/kernel/vmlinux.lds.S | 15 +++--- arch/sh/mm/Kconfig | 24 ++------- arch/sh/mm/Makefile | 2 +- arch/sh/mm/pmb.c | 106 +++++++++++++++++++++++----------------- 11 files changed, 117 insertions(+), 97 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/boot/Makefile b/arch/sh/boot/Makefile index 743ce0c8d98d..1ce63624c9b9 100644 --- a/arch/sh/boot/Makefile +++ b/arch/sh/boot/Makefile @@ -46,15 +46,8 @@ $(obj)/romImage: $(obj)/romimage/vmlinux FORCE $(obj)/romimage/vmlinux: $(obj)/zImage FORCE $(Q)$(MAKE) $(build)=$(obj)/romimage $@ -KERNEL_MEMORY := 0x00000000 -ifeq ($(CONFIG_PMB_FIXED),y) -KERNEL_MEMORY := $(shell /bin/bash -c 'printf "0x%08x" \ +KERNEL_MEMORY := $(shell /bin/bash -c 'printf "0x%08x" \ $$[$(CONFIG_MEMORY_START) & 0x1fffffff]') -endif -ifeq ($(CONFIG_29BIT),y) -KERNEL_MEMORY := $(shell /bin/bash -c 'printf "0x%08x" \ - $$[$(CONFIG_MEMORY_START)]') -endif KERNEL_LOAD := $(shell /bin/bash -c 'printf "0x%08x" \ $$[$(CONFIG_PAGE_OFFSET) + \ diff --git a/arch/sh/include/asm/addrspace.h b/arch/sh/include/asm/addrspace.h index 99d6b3ecbe22..bcd7d4d78f6b 100644 --- a/arch/sh/include/asm/addrspace.h +++ b/arch/sh/include/asm/addrspace.h @@ -28,7 +28,7 @@ /* Returns the privileged segment base of a given address */ #define PXSEG(a) (((unsigned long)(a)) & 0xe0000000) -#if defined(CONFIG_29BIT) || defined(CONFIG_PMB_FIXED) +#ifdef CONFIG_29BIT /* * Map an address to a certain privileged segment */ @@ -40,7 +40,7 @@ ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | P3SEG)) #define P4SEGADDR(a) \ ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | P4SEG)) -#endif /* 29BIT || PMB_FIXED */ +#endif /* 29BIT */ #endif /* P1SEG */ /* Check if an address can be reached in 29 bits */ diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h index 026dd659a640..f4314d8b05b8 100644 --- a/arch/sh/include/asm/io.h +++ b/arch/sh/include/asm/io.h @@ -244,18 +244,11 @@ __ioremap(unsigned long offset, unsigned long size, unsigned long flags) } static inline void __iomem * -__ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags) +__ioremap_29bit(unsigned long offset, unsigned long size, unsigned long flags) { -#if defined(CONFIG_SUPERH32) && !defined(CONFIG_PMB_FIXED) && !defined(CONFIG_PMB) +#ifdef CONFIG_29BIT unsigned long last_addr = offset + size - 1; -#endif - void __iomem *ret; - ret = __ioremap_trapped(offset, size); - if (ret) - return ret; - -#if defined(CONFIG_SUPERH32) && !defined(CONFIG_PMB_FIXED) && !defined(CONFIG_PMB) /* * For P1 and P2 space this is trivial, as everything is already * mapped. Uncached access for P1 addresses are done through P2. @@ -274,6 +267,22 @@ __ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags) return (void __iomem *)P4SEGADDR(offset); #endif + return NULL; +} + +static inline void __iomem * +__ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags) +{ + void __iomem *ret; + + ret = __ioremap_trapped(offset, size); + if (ret) + return ret; + + ret = __ioremap_29bit(offset, size, flags); + if (ret) + return ret; + return __ioremap(offset, size, flags); } #else diff --git a/arch/sh/include/asm/mmu.h b/arch/sh/include/asm/mmu.h index c7426ad9926e..4b0882bf5183 100644 --- a/arch/sh/include/asm/mmu.h +++ b/arch/sh/include/asm/mmu.h @@ -65,11 +65,29 @@ struct pmb_entry { struct pmb_entry *link; }; +#ifdef CONFIG_PMB /* arch/sh/mm/pmb.c */ long pmb_remap(unsigned long virt, unsigned long phys, unsigned long size, unsigned long flags); void pmb_unmap(unsigned long addr); int pmb_init(void); +#else +static inline long pmb_remap(unsigned long virt, unsigned long phys, + unsigned long size, unsigned long flags) +{ + return -EINVAL +} + +static inline void pmb_unmap(unsigned long addr) +{ +} + +static inline int pmb_init(void) +{ + return -ENODEV; +} +#endif /* CONFIG_PMB */ + #endif /* __ASSEMBLY__ */ #endif /* __MMU_H */ diff --git a/arch/sh/include/asm/page.h b/arch/sh/include/asm/page.h index 81bffc0d6860..a86c0f1d05d4 100644 --- a/arch/sh/include/asm/page.h +++ b/arch/sh/include/asm/page.h @@ -127,7 +127,7 @@ 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) +#if defined(CONFIG_PMB_LEGACY) /* phys = virt - PAGE_OFFSET - (__MEMORY_START & 0xe0000000) */ #define PMB_OFFSET (PAGE_OFFSET - PXSEG(__MEMORY_START)) #define __pa(x) ((unsigned long)(x) - PMB_OFFSET) diff --git a/arch/sh/kernel/head_32.S b/arch/sh/kernel/head_32.S index 1151ecdffa71..e5d421db4c83 100644 --- a/arch/sh/kernel/head_32.S +++ b/arch/sh/kernel/head_32.S @@ -13,6 +13,8 @@ #include #include #include +#include +#include #ifdef CONFIG_CPU_SH4A #define SYNCO() synco @@ -33,7 +35,7 @@ ENTRY(empty_zero_page) .long 1 /* LOADER_TYPE */ .long 0x00000000 /* INITRD_START */ .long 0x00000000 /* INITRD_SIZE */ -#if defined(CONFIG_32BIT) && defined(CONFIG_PMB_FIXED) +#ifdef CONFIG_32BIT .long 0x53453f00 + 32 /* "SE?" = 32 bit */ #else .long 0x53453f00 + 29 /* "SE?" = 29 bit */ diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 8b0e69792cf4..f79ebe32a24a 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -455,10 +455,7 @@ void __init setup_arch(char **cmdline_p) sh_mv.mv_setup(cmdline_p); paging_init(); - -#ifdef CONFIG_PMB_ENABLE pmb_init(); -#endif #ifdef CONFIG_SMP plat_smp_setup(); diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S index a1e4ec24f1f5..9e5a5878eeae 100644 --- a/arch/sh/kernel/vmlinux.lds.S +++ b/arch/sh/kernel/vmlinux.lds.S @@ -14,17 +14,16 @@ OUTPUT_ARCH(sh) #include #include +#if defined(CONFIG_32BIT) && !defined(CONFIG_PMB_LEGACY) +#define MEMORY_OFFSET 0 +#else +#define MEMORY_OFFSET (CONFIG_MEMORY_START & 0x1fffffff) +#endif + ENTRY(_start) SECTIONS { -#ifdef CONFIG_PMB_FIXED - . = CONFIG_PAGE_OFFSET + (CONFIG_MEMORY_START & 0x1fffffff) + - CONFIG_ZERO_PAGE_OFFSET; -#elif defined(CONFIG_32BIT) - . = CONFIG_PAGE_OFFSET + CONFIG_ZERO_PAGE_OFFSET; -#else - . = CONFIG_PAGE_OFFSET + CONFIG_MEMORY_START + CONFIG_ZERO_PAGE_OFFSET; -#endif + . = CONFIG_PAGE_OFFSET + MEMORY_OFFSET + CONFIG_ZERO_PAGE_OFFSET; _text = .; /* Text and read-only data */ diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index 358c860aeb9b..860cd24b4205 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig @@ -80,30 +80,18 @@ config 32BIT bool default y if CPU_SH5 -config PMB_ENABLE - bool "Support 32-bit physical addressing through PMB" - depends on MMU && EXPERIMENTAL && CPU_SH4A && !CPU_SH4AL_DSP - help - If you say Y here, physical addressing will be extended to - 32-bits through the SH-4A PMB. If this is not set, legacy - 29-bit physical addressing will be used. - -choice - prompt "PMB handling type" - depends on PMB_ENABLE - default PMB_FIXED - config PMB - bool "PMB" + bool "Support 32-bit physical addressing through PMB" depends on MMU && EXPERIMENTAL && CPU_SH4A && !CPU_SH4AL_DSP + select 32BIT help If you say Y here, physical addressing will be extended to 32-bits through the SH-4A PMB. If this is not set, legacy 29-bit physical addressing will be used. -config PMB_FIXED - bool "fixed PMB" - depends on MMU && EXPERIMENTAL && CPU_SH4A && !CPU_SH4AL_DSP +config PMB_LEGACY + bool "Support legacy boot mappings for PMB" + depends on PMB select 32BIT help If this option is enabled, fixed PMB mappings are inherited @@ -111,8 +99,6 @@ config PMB_FIXED management. This is the closest to legacy 29-bit physical mode, and allows systems to support up to 512MiB of system memory. -endchoice - config X2TLB bool "Enable extended TLB mode" depends on (CPU_SHX2 || CPU_SHX3) && MMU && EXPERIMENTAL diff --git a/arch/sh/mm/Makefile b/arch/sh/mm/Makefile index 9fa11d655044..edde8bdd681d 100644 --- a/arch/sh/mm/Makefile +++ b/arch/sh/mm/Makefile @@ -33,7 +33,7 @@ obj-y += $(tlb-y) endif obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o -obj-$(CONFIG_PMB_ENABLE) += pmb.o +obj-$(CONFIG_PMB) += pmb.o obj-$(CONFIG_NUMA) += numa.o # Special flags for fault_64.o. This puts restrictions on the number of diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c index 280f6a166035..8f7dbf183fb0 100644 --- a/arch/sh/mm/pmb.c +++ b/arch/sh/mm/pmb.c @@ -3,7 +3,7 @@ * * Privileged Space Mapping Buffer (PMB) Support. * - * Copyright (C) 2005, 2006, 2007 Paul Mundt + * Copyright (C) 2005 - 2010 Paul Mundt * * P1/P2 Section mapping definitions from map32.h, which was: * @@ -279,51 +279,12 @@ static void __pmb_unmap(struct pmb_entry *pmbe) } while (pmbe); } -#ifdef CONFIG_PMB -int __uses_jump_to_uncached pmb_init(void) -{ - unsigned int i; - long size, ret; - - jump_to_uncached(); - - /* - * Insert PMB entries for the P1 and P2 areas so that, after - * we've switched the MMU to 32-bit mode, the semantics of P1 - * and P2 are the same as in 29-bit mode, e.g. - * - * P1 - provides a cached window onto physical memory - * P2 - provides an uncached window onto physical memory - */ - size = __MEMORY_START + __MEMORY_SIZE; - - ret = pmb_remap(P1SEG, 0x00000000, size, PMB_C); - BUG_ON(ret != size); - - ret = pmb_remap(P2SEG, 0x00000000, size, PMB_WT | PMB_UB); - BUG_ON(ret != size); - - ctrl_outl(0, PMB_IRMCR); - - /* PMB.SE and UB[7] */ - ctrl_outl(PASCR_SE | (1 << 7), PMB_PASCR); - - /* Flush out the TLB */ - i = ctrl_inl(MMUCR); - i |= MMUCR_TI; - ctrl_outl(i, MMUCR); - - back_to_cached(); - - return 0; -} -#else -int __uses_jump_to_uncached pmb_init(void) +#ifdef CONFIG_PMB_LEGACY +static int pmb_apply_legacy_mappings(void) { int i; unsigned long addr, data; - - jump_to_uncached(); + unsigned int applied = 0; for (i = 0; i < PMB_ENTRY_MAX; i++) { struct pmb_entry *pmbe; @@ -357,13 +318,69 @@ int __uses_jump_to_uncached pmb_init(void) pmbe = pmb_alloc(vpn, ppn, flags, i); WARN_ON(IS_ERR(pmbe)); + + applied++; + } + + return (applied == 0); +} +#else +static inline int pmb_apply_legacy_mappings(void) +{ + return 1; +} +#endif + +int __uses_jump_to_uncached pmb_init(void) +{ + unsigned int i; + unsigned long size, ret; + + jump_to_uncached(); + + /* + * Attempt to apply the legacy boot mappings if configured. If + * this is successful then we simply carry on with those and + * don't bother establishing additional memory mappings. Dynamic + * device mappings through pmb_remap() can still be bolted on + * after this. + */ + ret = pmb_apply_legacy_mappings(); + if (ret == 0) { + back_to_cached(); + return 0; } + /* + * Insert PMB entries for the P1 and P2 areas so that, after + * we've switched the MMU to 32-bit mode, the semantics of P1 + * and P2 are the same as in 29-bit mode, e.g. + * + * P1 - provides a cached window onto physical memory + * P2 - provides an uncached window onto physical memory + */ + size = (unsigned long)__MEMORY_START + __MEMORY_SIZE; + + ret = pmb_remap(P1SEG, 0x00000000, size, PMB_C); + BUG_ON(ret != size); + + ret = pmb_remap(P2SEG, 0x00000000, size, PMB_WT | PMB_UB); + BUG_ON(ret != size); + + ctrl_outl(0, PMB_IRMCR); + + /* PMB.SE and UB[7] */ + ctrl_outl(PASCR_SE | (1 << 7), PMB_PASCR); + + /* Flush out the TLB */ + i = ctrl_inl(MMUCR); + i |= MMUCR_TI; + ctrl_outl(i, MMUCR); + back_to_cached(); return 0; } -#endif /* CONFIG_PMB */ static int pmb_seq_show(struct seq_file *file, void *iter) { @@ -462,6 +479,5 @@ static int __init pmb_sysdev_init(void) { return sysdev_driver_register(&cpu_sysdev_class, &pmb_sysdev_driver); } - subsys_initcall(pmb_sysdev_init); #endif -- cgit v1.2.3 From 88f73d22853cb080432e91d68759323477a8b835 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 13 Jan 2010 18:37:19 +0900 Subject: sh: Fix up L2 cache comment typo. Valid sizes include 256kB, not 258kB. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4/probe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/sh') diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c index 75189c4691da..21371f8cf010 100644 --- a/arch/sh/kernel/cpu/sh4/probe.c +++ b/arch/sh/kernel/cpu/sh4/probe.c @@ -228,7 +228,7 @@ int __init detect_cpu_and_cache_system(void) * Size calculation is much more sensible * than it is for the L1. * - * Sizes are 128KB, 258KB, 512KB, and 1MB. + * Sizes are 128KB, 256KB, 512KB, and 1MB. */ size = (cvr & 0xf) << 17; -- cgit v1.2.3 From 206582c3161f165f5bf49ececa962c5f95fdf0a3 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 13 Jan 2010 18:45:12 +0900 Subject: sh: Make all PxSEGADDR() calls fatal for non-legacy configs. This stubs out all of the PxSEGADDR() wrappers for non-legacy code. 29-bit will continue to work with these, while 32-bit code will now blow up on compile rather than at runtime. The vast majority of the in-tree offenders are gone, with the only remaining culprits being unable to support 32-bit mode. Hopefully this will prevent anyone from ever using these again. Signed-off-by: Paul Mundt --- arch/sh/include/asm/addrspace.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/addrspace.h b/arch/sh/include/asm/addrspace.h index bcd7d4d78f6b..268efd62ed21 100644 --- a/arch/sh/include/asm/addrspace.h +++ b/arch/sh/include/asm/addrspace.h @@ -40,7 +40,15 @@ ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | P3SEG)) #define P4SEGADDR(a) \ ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | P4SEG)) -#endif /* 29BIT */ +#else +/* + * These will never work in 32-bit, don't even bother. + */ +#define P1SEGADDR(a) __futile_remapping_attempt +#define P2SEGADDR(a) __futile_remapping_attempt +#define P3SEGADDR(a) __futile_remapping_attempt +#define P4SEGADDR(a) __futile_remapping_attempt +#endif #endif /* P1SEG */ /* Check if an address can be reached in 29 bits */ -- cgit v1.2.3 From 782bb5a532f883540bf403afb19f735a4eefd95b Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 13 Jan 2010 19:11:14 +0900 Subject: sh: default to extended TLB support. All SH-X2 and SH-X3 parts support an extended TLB mode, which has been left as experimental since support was originally merged. Now that it's had some time to stabilize and get some exposure to various platforms, we can drop it as an option and default enable it across the board. This is also good future proofing for newer parts that will drop support for the legacy TLB mode completely. This will also force 3-level page tables for all newer parts, which is necessary both for the varying page sizes and larger memories. Signed-off-by: Paul Mundt --- arch/sh/include/asm/pgalloc.h | 2 +- arch/sh/include/asm/pgtable.h | 2 +- arch/sh/include/asm/pgtable_nopmd.h | 11 ++++++----- arch/sh/include/asm/pgtable_pmd.h | 5 +++-- arch/sh/mm/Kconfig | 29 ++--------------------------- arch/sh/mm/pgtable.c | 9 ++++----- 6 files changed, 17 insertions(+), 41 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/pgalloc.h b/arch/sh/include/asm/pgalloc.h index f8982f4e0405..8c00785c60d5 100644 --- a/arch/sh/include/asm/pgalloc.h +++ b/arch/sh/include/asm/pgalloc.h @@ -9,7 +9,7 @@ extern pgd_t *pgd_alloc(struct mm_struct *); extern void pgd_free(struct mm_struct *mm, pgd_t *pgd); -#ifdef CONFIG_PGTABLE_LEVELS_3 +#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); diff --git a/arch/sh/include/asm/pgtable.h b/arch/sh/include/asm/pgtable.h index 78598ec33d0a..856ece07d31b 100644 --- a/arch/sh/include/asm/pgtable.h +++ b/arch/sh/include/asm/pgtable.h @@ -12,7 +12,7 @@ #ifndef __ASM_SH_PGTABLE_H #define __ASM_SH_PGTABLE_H -#ifdef CONFIG_PGTABLE_LEVELS_3 +#ifdef CONFIG_X2TLB #include #else #include diff --git a/arch/sh/include/asm/pgtable_nopmd.h b/arch/sh/include/asm/pgtable_nopmd.h index f0b525b3cb4a..b8355e4057cf 100644 --- a/arch/sh/include/asm/pgtable_nopmd.h +++ b/arch/sh/include/asm/pgtable_nopmd.h @@ -6,17 +6,18 @@ /* * traditional two-level paging structure */ +#define PAGETABLE_LEVELS 2 /* PTE bits */ -#define PTE_MAGNITUDE 2 /* 32-bit PTEs */ +#define PTE_MAGNITUDE 2 /* 32-bit PTEs */ -#define PTE_SHIFT PAGE_SHIFT -#define PTE_BITS (PTE_SHIFT - PTE_MAGNITUDE) +#define PTE_SHIFT PAGE_SHIFT +#define PTE_BITS (PTE_SHIFT - PTE_MAGNITUDE) /* PGD bits */ -#define PGDIR_SHIFT (PTE_SHIFT + PTE_BITS) +#define PGDIR_SHIFT (PTE_SHIFT + PTE_BITS) -#define PTRS_PER_PGD (PAGE_SIZE / (1 << PTE_MAGNITUDE)) +#define PTRS_PER_PGD (PAGE_SIZE / (1 << PTE_MAGNITUDE)) #define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE) #endif /* __ASM_SH_PGTABLE_NOPMD_H */ diff --git a/arch/sh/include/asm/pgtable_pmd.h b/arch/sh/include/asm/pgtable_pmd.h index 42a180e534a8..587b05e1d04f 100644 --- a/arch/sh/include/asm/pgtable_pmd.h +++ b/arch/sh/include/asm/pgtable_pmd.h @@ -7,11 +7,12 @@ * 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 extended mode SH-X2 TLB */ +#define PTE_MAGNITUDE 3 /* 64-bit PTEs on SH-X2 TLB */ /* PGD bits */ -#define PGDIR_SHIFT 30 +#define PGDIR_SHIFT 30 #define PTRS_PER_PGD 4 #define USER_PTRS_PER_PGD 2 diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index 860cd24b4205..7a4ebc8cbadd 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig @@ -100,13 +100,8 @@ config PMB_LEGACY and allows systems to support up to 512MiB of system memory. config X2TLB - bool "Enable extended TLB mode" - depends on (CPU_SHX2 || CPU_SHX3) && MMU && EXPERIMENTAL - help - Selecting this option will enable the extended mode of the SH-X2 - TLB. For legacy SH-X behaviour and interoperability, say N. For - all of the fun new features and a willingless to submit bug reports, - say Y. + def_bool y + depends on (CPU_SHX2 || CPU_SHX3) && MMU config VSYSCALL bool "Support vsyscall page" @@ -174,32 +169,12 @@ config ARCH_MEMORY_PROBE def_bool y depends on MEMORY_HOTPLUG -choice - prompt "Page table layout" - default PGTABLE_LEVELS_3 if X2TLB - default PGTABLE_LEVELS_2 - -config PGTABLE_LEVELS_2 - bool "2 Levels" - help - This is the default page table layout for all SuperH CPUs. - -config PGTABLE_LEVELS_3 - bool "3 Levels" - depends on X2TLB - help - This enables a 3 level page table structure. - -endchoice - choice prompt "Kernel page size" - default PAGE_SIZE_8KB if X2TLB default PAGE_SIZE_4KB config PAGE_SIZE_4KB bool "4kB" - depends on !MMU || !X2TLB || PGTABLE_LEVELS_3 help This is the default page size used by all SuperH CPUs. diff --git a/arch/sh/mm/pgtable.c b/arch/sh/mm/pgtable.c index e1bc5483cc07..6f21fb1d8726 100644 --- a/arch/sh/mm/pgtable.c +++ b/arch/sh/mm/pgtable.c @@ -3,8 +3,7 @@ #define PGALLOC_GFP GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO static struct kmem_cache *pgd_cachep; - -#ifdef CONFIG_PGTABLE_LEVELS_3 +#if PAGETABLE_LEVELS > 2 static struct kmem_cache *pmd_cachep; #endif @@ -22,7 +21,7 @@ void pgtable_cache_init(void) pgd_cachep = kmem_cache_create("pgd_cache", PTRS_PER_PGD * (1< 2 pmd_cachep = kmem_cache_create("pmd_cache", PTRS_PER_PMD * (1< 2 void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) { set_pud(pud, __pud((unsigned long)pmd)); @@ -54,4 +53,4 @@ void pmd_free(struct mm_struct *mm, pmd_t *pmd) { kmem_cache_free(pmd_cachep, pmd); } -#endif /* CONFIG_PGTABLE_LEVELS_3 */ +#endif /* PAGETABLE_LEVELS > 2 */ -- cgit v1.2.3 From e44d6c4010a4c84369013932eea4721d16cbc08d Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 13 Jan 2010 19:18:39 +0900 Subject: sh: Rename split-level pgtable headers. These were originally named _nopmd and _pmd to follow their asm-generic counterparts, but we rename them to -2level and -3level for general consistency. Signed-off-by: Paul Mundt --- arch/sh/include/asm/pgtable-2level.h | 23 +++++++++++++++ arch/sh/include/asm/pgtable-3level.h | 56 ++++++++++++++++++++++++++++++++++++ arch/sh/include/asm/pgtable.h | 4 +-- arch/sh/include/asm/pgtable_nopmd.h | 23 --------------- arch/sh/include/asm/pgtable_pmd.h | 56 ------------------------------------ 5 files changed, 81 insertions(+), 81 deletions(-) create mode 100644 arch/sh/include/asm/pgtable-2level.h create mode 100644 arch/sh/include/asm/pgtable-3level.h delete mode 100644 arch/sh/include/asm/pgtable_nopmd.h delete mode 100644 arch/sh/include/asm/pgtable_pmd.h (limited to 'arch/sh') diff --git a/arch/sh/include/asm/pgtable-2level.h b/arch/sh/include/asm/pgtable-2level.h new file mode 100644 index 000000000000..19bd89db17e7 --- /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 + +/* + * 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 000000000000..249a985d9648 --- /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 + +/* + * 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 856ece07d31b..aab76528abb9 100644 --- a/arch/sh/include/asm/pgtable.h +++ b/arch/sh/include/asm/pgtable.h @@ -13,9 +13,9 @@ #define __ASM_SH_PGTABLE_H #ifdef CONFIG_X2TLB -#include +#include #else -#include +#include #endif #include diff --git a/arch/sh/include/asm/pgtable_nopmd.h b/arch/sh/include/asm/pgtable_nopmd.h deleted file mode 100644 index b8355e4057cf..000000000000 --- a/arch/sh/include/asm/pgtable_nopmd.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef __ASM_SH_PGTABLE_NOPMD_H -#define __ASM_SH_PGTABLE_NOPMD_H - -#include - -/* - * 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_NOPMD_H */ diff --git a/arch/sh/include/asm/pgtable_pmd.h b/arch/sh/include/asm/pgtable_pmd.h deleted file mode 100644 index 587b05e1d04f..000000000000 --- a/arch/sh/include/asm/pgtable_pmd.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef __ASM_SH_PGTABLE_PMD_H -#define __ASM_SH_PGTABLE_PMD_H - -#include - -/* - * 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_PMD_H */ -- cgit v1.2.3 From 02bf6cc72cc2a6258411ddf1649f33a65fc9a06e Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 14 Jan 2010 20:58:58 +0900 Subject: sh: Preliminary SDK7786 board support. This stubs in some preliminary board support for the RTE SDK7786. This is quite stunted at the moment, and primarily builds on top of the system FPGA. FPGA IRQs are handled via CPU IRL masking for simplicity, with initial peripheral support restricted to the debug ethernet. Signed-off-by: Matt Fleming Signed-off-by: Paul Mundt --- arch/sh/Makefile | 2 + arch/sh/boards/Kconfig | 7 + arch/sh/boards/mach-sdk7786/Makefile | 1 + arch/sh/boards/mach-sdk7786/setup.c | 219 ++++++ arch/sh/configs/sdk7786_defconfig | 1440 ++++++++++++++++++++++++++++++++++ arch/sh/tools/mach-types | 1 + 6 files changed, 1670 insertions(+) create mode 100644 arch/sh/boards/mach-sdk7786/Makefile create mode 100644 arch/sh/boards/mach-sdk7786/setup.c create mode 100644 arch/sh/configs/sdk7786_defconfig (limited to 'arch/sh') diff --git a/arch/sh/Makefile b/arch/sh/Makefile index f7d5f42b00a7..30c80fd29058 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -83,6 +83,7 @@ defaultimage-$(CONFIG_SH_AP325RXA) := uImage defaultimage-$(CONFIG_SH_7724_SOLUTION_ENGINE) := uImage defaultimage-$(CONFIG_SH_7206_SOLUTION_ENGINE) := vmlinux defaultimage-$(CONFIG_SH_7619_SOLUTION_ENGINE) := vmlinux +defaultimage-$(CONFIG_SH_SDK7786) := vmlinux.bin # Set some sensible Kbuild defaults KBUILD_IMAGE := $(defaultimage-y) @@ -143,6 +144,7 @@ machdir-$(CONFIG_SH_AP325RXA) += mach-ap325rxa machdir-$(CONFIG_SH_KFR2R09) += mach-kfr2r09 machdir-$(CONFIG_SH_ECOVEC) += mach-ecovec24 machdir-$(CONFIG_SH_SDK7780) += mach-sdk7780 +machdir-$(CONFIG_SH_SDK7786) += mach-sdk7786 machdir-$(CONFIG_SH_X3PROTO) += mach-x3proto machdir-$(CONFIG_SH_SH7763RDP) += mach-sh7763rdp machdir-$(CONFIG_SH_SH4202_MICRODEV) += mach-microdev diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig index aedd9deb5de2..c0a1992bb256 100644 --- a/arch/sh/boards/Kconfig +++ b/arch/sh/boards/Kconfig @@ -150,6 +150,13 @@ config SH_SDK7780 Select SDK7780 if configuring for a Renesas SH7780 SDK7780R3 evaluation board. +config SH_SDK7786 + bool "SDK7786" + depends on CPU_SUBTYPE_SH7786 + help + Select SDK7786 if configuring for a Renesas Technology Europe + SH7786-65nm board. + config SH_HIGHLANDER bool "Highlander" depends on CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785 diff --git a/arch/sh/boards/mach-sdk7786/Makefile b/arch/sh/boards/mach-sdk7786/Makefile new file mode 100644 index 000000000000..f663768429f0 --- /dev/null +++ b/arch/sh/boards/mach-sdk7786/Makefile @@ -0,0 +1 @@ +obj-y := setup.o diff --git a/arch/sh/boards/mach-sdk7786/setup.c b/arch/sh/boards/mach-sdk7786/setup.c new file mode 100644 index 000000000000..b460dcc785c1 --- /dev/null +++ b/arch/sh/boards/mach-sdk7786/setup.c @@ -0,0 +1,219 @@ +/* + * Renesas Technology Europe SDK7786 Support. + * + * Copyright (C) 2010 Matt Fleming + * Copyright (C) 2010 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. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +static struct resource smsc911x_resources[] = { + [0] = { + .name = "smsc911x-memory", + .start = 0x07ffff00, + .end = 0x07ffff00 + SZ_256 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .name = "smsc911x-irq", + .start = evt2irq(0x2c0), + .end = evt2irq(0x2c0), + .flags = IORESOURCE_IRQ, + }, +}; + +static struct smsc911x_platform_config smsc911x_config = { + .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, + .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN, + .flags = SMSC911X_USE_32BIT, + .phy_interface = PHY_INTERFACE_MODE_MII, +}; + +static struct platform_device smsc911x_device = { + .name = "smsc911x", + .id = -1, + .num_resources = ARRAY_SIZE(smsc911x_resources), + .resource = smsc911x_resources, + .dev = { + .platform_data = &smsc911x_config, + }, +}; + +static struct resource smbus_fpga_resource = { + .start = 0x07fff9e0, + .end = 0x07fff9e0 + SZ_32 - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device smbus_fpga_device = { + .name = "i2c-sdk7786", + .id = 0, + .num_resources = 1, + .resource = &smbus_fpga_resource, +}; + +static struct resource smbus_pcie_resource = { + .start = 0x07fffc30, + .end = 0x07fffc30 + SZ_32 - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device smbus_pcie_device = { + .name = "i2c-sdk7786", + .id = 1, + .num_resources = 1, + .resource = &smbus_pcie_resource, +}; + +static struct i2c_board_info __initdata sdk7786_i2c_devices[] = { + { + I2C_BOARD_INFO("max6900", 0x68), + }, +}; + +static struct platform_device *sh7786_devices[] __initdata = { + &smsc911x_device, + &smbus_fpga_device, + &smbus_pcie_device, +}; + +#define SBCR_REGS_BASE 0x07fff990 + +#define SCBR_I2CMEN (1 << 0) /* FPGA I2C master enable */ +#define SCBR_I2CCEN (1 << 1) /* CPU I2C master enable */ + +static int sdk7786_i2c_setup(void) +{ + void __iomem *sbcr; + unsigned int tmp; + + sbcr = ioremap_nocache(SBCR_REGS_BASE, SZ_16); + + /* + * Hand over I2C control to the FPGA. + */ + tmp = ioread16(sbcr); + tmp &= ~SCBR_I2CCEN; + tmp |= SCBR_I2CMEN; + iowrite16(tmp, sbcr); + + iounmap(sbcr); + + return i2c_register_board_info(0, sdk7786_i2c_devices, + ARRAY_SIZE(sdk7786_i2c_devices)); +} + +static int __init sdk7786_devices_setup(void) +{ + int ret; + + ret = platform_add_devices(sh7786_devices, ARRAY_SIZE(sh7786_devices)); + if (unlikely(ret != 0)) + return ret; + + return sdk7786_i2c_setup(); +} +__initcall(sdk7786_devices_setup); + +#define FPGA_REGS_BASE 0x07fff800 +#define FPGA_REGS_SIZE 1152 + +#define INTASR 0x010 +#define INTAMR 0x020 +#define INTBSR 0x090 +#define INTBMR 0x0a0 +#define INTMSR 0x130 + +#define IASELR1 0x210 +#define IASELR2 0x220 +#define IASELR3 0x230 +#define IASELR4 0x240 +#define IASELR5 0x250 +#define IASELR6 0x260 +#define IASELR7 0x270 +#define IASELR8 0x280 +#define IASELR9 0x290 +#define IASELR10 0x2a0 +#define IASELR11 0x2b0 +#define IASELR12 0x2c0 +#define IASELR13 0x2d0 +#define IASELR14 0x2e0 +#define IASELR15 0x2f0 + +static void __iomem *fpga_regs; + +static u16 fpga_read_reg(unsigned int reg) +{ + return __raw_readw(fpga_regs + reg); +} + +static void fpga_write_reg(u16 val, unsigned int reg) +{ + __raw_writew(val, fpga_regs + reg); +} + +enum { + ATA_IRQ_BIT = 1, + SPI_BUSY_BIT = 2, + LIRQ5_BIT = 3, + LIRQ6_BIT = 4, + LIRQ7_BIT = 5, + LIRQ8_BIT = 6, + KEY_IRQ_BIT = 7, + PEN_IRQ_BIT = 8, + ETH_IRQ_BIT = 9, + RTC_ALARM_BIT = 10, + CRYSTAL_FAIL_BIT = 12, + ETH_PME_BIT = 14, +}; + +static void __init init_sdk7786_IRQ(void) +{ + unsigned int tmp; + + fpga_regs = ioremap_nocache(FPGA_REGS_BASE, FPGA_REGS_SIZE); + if (!fpga_regs) { + printk(KERN_ERR "Couldn't map FPGA registers\n"); + return; + } + + /* Enable priority encoding for all IRLs */ + fpga_write_reg(fpga_read_reg(INTMSR) | 0x0303, INTMSR); + + /* Clear FPGA interrupt status registers */ + fpga_write_reg(0x0000, INTASR); + fpga_write_reg(0x0000, INTBSR); + + /* Unmask FPGA interrupts */ + tmp = fpga_read_reg(INTAMR); + tmp &= ~(1 << ETH_IRQ_BIT); + fpga_write_reg(tmp, INTAMR); + + plat_irq_setup_pins(IRQ_MODE_IRL7654_MASK); + plat_irq_setup_pins(IRQ_MODE_IRL3210_MASK); +} + +/* Initialize the board */ +static void __init sdk7786_setup(char **cmdline_p) +{ + printk(KERN_INFO "Renesas Technology Corp. SDK7786 support.\n"); +} + +/* + * The Machine Vector + */ +static struct sh_machine_vector mv_sdk7786 __initmv = { + .mv_name = "SDK7786", + .mv_setup = sdk7786_setup, + .mv_init_irq = init_sdk7786_IRQ, +}; diff --git a/arch/sh/configs/sdk7786_defconfig b/arch/sh/configs/sdk7786_defconfig new file mode 100644 index 000000000000..1721d2c5c7e8 --- /dev/null +++ b/arch/sh/configs/sdk7786_defconfig @@ -0,0 +1,1440 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.33-rc3 +# Thu Jan 14 20:37:44 2010 +# +CONFIG_SUPERH=y +CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set +CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_IRQ_PER_CPU=y +# CONFIG_GENERIC_GPIO is not set +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +# CONFIG_ARCH_SUSPEND_POSSIBLE is not set +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_SYS_SUPPORTS_HUGETLBFS=y +CONFIG_SYS_SUPPORTS_SMP=y +CONFIG_SYS_SUPPORTS_NUMA=y +CONFIG_SYS_SUPPORTS_TMU=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_NO_VIRT_TO_BUS=y +CONFIG_ARCH_HAS_DEFAULT_IDLE=y +CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_DMA_COHERENT=y +# CONFIG_DMA_NONCOHERENT is not set +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_BZIP2=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_LZO is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set +CONFIG_RCU_TRACE=y +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +CONFIG_TREE_RCU_TRACE=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_GROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_RT_GROUP_SCHED=y +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set +CONFIG_CGROUPS=y +# CONFIG_CGROUP_DEBUG is not set +CONFIG_CGROUP_NS=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_DEVICE=y +# CONFIG_CPUSETS is not set +CONFIG_CGROUP_CPUACCT=y +CONFIG_RESOURCE_COUNTERS=y +CONFIG_CGROUP_MEM_RES_CTLR=y +# CONFIG_CGROUP_MEM_RES_CTLR_SWAP is not set +CONFIG_MM_OWNER=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set +# CONFIG_RELAY is not set +CONFIG_NAMESPACES=y +CONFIG_UTS_NS=y +CONFIG_IPC_NS=y +CONFIG_USER_NS=y +CONFIG_PID_NS=y +CONFIG_NET_NS=y +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y + +# +# Kernel Performance Events And Counters +# +CONFIG_PERF_EVENTS=y +CONFIG_EVENT_PROFILE=y +# CONFIG_PERF_COUNTERS is not set +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set +CONFIG_VM_EVENT_COUNTERS=y +# CONFIG_COMPAT_BRK is not set +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_PROFILING=y +CONFIG_TRACEPOINTS=y +# CONFIG_OPROFILE is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_IOREMAP_PROT=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +# CONFIG_SLOW_WORK is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_BLOCK=y +# CONFIG_LBDAF is not set +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set +CONFIG_BLK_CGROUP=y +# CONFIG_DEBUG_BLK_CGROUP is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_CFQ_GROUP_IOSCHED=y +# CONFIG_DEBUG_CFQ_IOSCHED is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +# CONFIG_MUTEX_SPIN_ON_OWNER is not set +CONFIG_FREEZER=y + +# +# System type +# +CONFIG_CPU_SH4=y +CONFIG_CPU_SH4A=y +CONFIG_CPU_SHX3=y +# CONFIG_CPU_SUBTYPE_SH7619 is not set +# CONFIG_CPU_SUBTYPE_SH7201 is not set +# CONFIG_CPU_SUBTYPE_SH7203 is not set +# CONFIG_CPU_SUBTYPE_SH7206 is not set +# CONFIG_CPU_SUBTYPE_SH7263 is not set +# CONFIG_CPU_SUBTYPE_MXG is not set +# CONFIG_CPU_SUBTYPE_SH7705 is not set +# CONFIG_CPU_SUBTYPE_SH7706 is not set +# CONFIG_CPU_SUBTYPE_SH7707 is not set +# CONFIG_CPU_SUBTYPE_SH7708 is not set +# CONFIG_CPU_SUBTYPE_SH7709 is not set +# CONFIG_CPU_SUBTYPE_SH7710 is not set +# CONFIG_CPU_SUBTYPE_SH7712 is not set +# CONFIG_CPU_SUBTYPE_SH7720 is not set +# CONFIG_CPU_SUBTYPE_SH7721 is not set +# CONFIG_CPU_SUBTYPE_SH7750 is not set +# CONFIG_CPU_SUBTYPE_SH7091 is not set +# CONFIG_CPU_SUBTYPE_SH7750R is not set +# CONFIG_CPU_SUBTYPE_SH7750S is not set +# CONFIG_CPU_SUBTYPE_SH7751 is not set +# CONFIG_CPU_SUBTYPE_SH7751R is not set +# CONFIG_CPU_SUBTYPE_SH7760 is not set +# CONFIG_CPU_SUBTYPE_SH4_202 is not set +# CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set +# CONFIG_CPU_SUBTYPE_SH7757 is not set +# CONFIG_CPU_SUBTYPE_SH7763 is not set +# CONFIG_CPU_SUBTYPE_SH7770 is not set +# CONFIG_CPU_SUBTYPE_SH7780 is not set +# CONFIG_CPU_SUBTYPE_SH7785 is not set +CONFIG_CPU_SUBTYPE_SH7786=y +# CONFIG_CPU_SUBTYPE_SHX3 is not set +# CONFIG_CPU_SUBTYPE_SH7343 is not set +# CONFIG_CPU_SUBTYPE_SH7722 is not set +# CONFIG_CPU_SUBTYPE_SH7366 is not set + +# +# Memory management options +# +CONFIG_QUICKLIST=y +CONFIG_MMU=y +CONFIG_PAGE_OFFSET=0x80000000 +CONFIG_FORCE_MAX_ZONEORDER=11 +CONFIG_MEMORY_START=0x60000000 +CONFIG_MEMORY_SIZE=0x08000000 +# CONFIG_29BIT is not set +CONFIG_32BIT=y +CONFIG_PMB=y +# CONFIG_PMB_LEGACY is not set +CONFIG_X2TLB=y +CONFIG_VSYSCALL=y +# CONFIG_NUMA is not set +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_DEFAULT=y +CONFIG_MAX_ACTIVE_REGIONS=1 +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y +CONFIG_ARCH_MEMORY_PROBE=y +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +# CONFIG_HUGETLB_PAGE_SIZE_64K is not set +# CONFIG_HUGETLB_PAGE_SIZE_256K is not set +CONFIG_HUGETLB_PAGE_SIZE_1MB=y +# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set +# CONFIG_HUGETLB_PAGE_SIZE_64MB is not set +# CONFIG_HUGETLB_PAGE_SIZE_512MB is not set +CONFIG_SELECT_MEMORY_MODEL=y +# CONFIG_FLATMEM_MANUAL is not set +# CONFIG_DISCONTIGMEM_MANUAL is not set +CONFIG_SPARSEMEM_MANUAL=y +CONFIG_SPARSEMEM=y +CONFIG_HAVE_MEMORY_PRESENT=y +CONFIG_SPARSEMEM_STATIC=y +CONFIG_MEMORY_HOTPLUG=y +CONFIG_MEMORY_HOTPLUG_SPARSE=y +CONFIG_MEMORY_HOTREMOVE=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_MIGRATION=y +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_NR_QUICK=1 +CONFIG_KSM=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 + +# +# Cache configuration +# +CONFIG_CACHE_WRITEBACK=y +# CONFIG_CACHE_WRITETHROUGH is not set +# CONFIG_CACHE_OFF is not set + +# +# Processor features +# +CONFIG_CPU_LITTLE_ENDIAN=y +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_SH_FPU=y +CONFIG_SH_STORE_QUEUES=y +CONFIG_CPU_HAS_INTEVT=y +CONFIG_CPU_HAS_SR_RB=y +CONFIG_CPU_HAS_PTEAEX=y +CONFIG_CPU_HAS_FPU=y + +# +# Board support +# +CONFIG_SH_SDK7786=y +# CONFIG_SH_URQUELL is not set + +# +# Timer and clock configuration +# +CONFIG_SH_TIMER_TMU=y +CONFIG_SH_PCLK_FREQ=50000000 +CONFIG_SH_CLK_CPG=y +CONFIG_SH_CLK_CPG_LEGACY=y +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_USERSPACE=m +CONFIG_CPU_FREQ_GOV_ONDEMAND=m +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m +CONFIG_SH_CPU_FREQ=y + +# +# DMA support +# +# CONFIG_SH_DMA is not set + +# +# Companion Chips +# + +# +# Additional SuperH Device Drivers +# +CONFIG_HEARTBEAT=y +# CONFIG_PUSH_SWITCH is not set + +# +# Kernel features +# +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +CONFIG_SCHED_HRTICK=y +CONFIG_KEXEC=y +# CONFIG_CRASH_DUMP is not set +CONFIG_SECCOMP=y +# CONFIG_SMP is not set +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_GUSA=y +CONFIG_SPARSE_IRQ=y + +# +# Boot options +# +CONFIG_ZERO_PAGE_OFFSET=0x00001000 +CONFIG_BOOT_LINK_OFFSET=0x00800000 +CONFIG_ENTRY_OFFSET=0x00001000 +CONFIG_CMDLINE_OVERWRITE=y +# CONFIG_CMDLINE_EXTEND is not set +CONFIG_CMDLINE="console=ttySC1,115200 earlyprintk=sh-sci.1,115200 root=/dev/nfs ip=dhcp" + +# +# Bus options +# +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_HAVE_AOUT is not set +CONFIG_BINFMT_MISC=y + +# +# Power management options (EXPERIMENTAL) +# +# CONFIG_PM is not set +# CONFIG_CPU_IDLE is not set +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +CONFIG_NET_KEY=y +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NET_DROP_MONITOR is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +CONFIG_WIRELESS=y +# CONFIG_CFG80211 is not set +# CONFIG_LIB80211 is not set + +# +# CFG80211 needs to be enabled for MAC80211 +# +# CONFIG_WIMAX is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_DEVTMPFS is not set +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +# CONFIG_MTD is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_BLK_DEV_HD is not set +CONFIG_MISC_DEVICES=y +# CONFIG_AD525X_DPOT is not set +# CONFIG_ICS932S401 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_ISL29003 is not set +# CONFIG_DS1682 is not set +# CONFIG_TI_DAC7512 is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +CONFIG_ATA=y +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_ATA_VERBOSE_ERROR=y +CONFIG_SATA_PMP=y +CONFIG_ATA_SFF=y +# CONFIG_SATA_MV is not set +CONFIG_PATA_PLATFORM=y +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_FIXED_PHY is not set +CONFIG_MDIO_BITBANG=y +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 is not set +# CONFIG_STNIC is not set +CONFIG_SMC91X=y +# CONFIG_ENC28J60 is not set +# CONFIG_ETHOC is not set +# CONFIG_SMC911X is not set +CONFIG_SMSC911X=y +# CONFIG_DNET is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_B44 is not set +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set +CONFIG_WLAN=y +# CONFIG_USB_ZD1201 is not set +# CONFIG_HOSTAP is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_MAX3100 is not set +CONFIG_SERIAL_SH_SCI=y +CONFIG_SERIAL_SH_SCI_NR_UARTS=6 +CONFIG_SERIAL_SH_SCI_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +# CONFIG_I2C_COMPAT is not set +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_HELPER_AUTO=y + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_DESIGNWARE is not set +# CONFIG_I2C_OCORES is not set +CONFIG_I2C_SDK7786=y +# CONFIG_I2C_SH_MOBILE is not set +# CONFIG_I2C_SIMTEC is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_STUB is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_TSL2550 is not set +CONFIG_I2C_DEBUG_CORE=y +CONFIG_I2C_DEBUG_ALGO=y +CONFIG_I2C_DEBUG_BUS=y +CONFIG_I2C_DEBUG_CHIP=y +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_SH_MSIOF is not set +# CONFIG_SPI_SH_SCI is not set +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_DESIGNWARE is not set + +# +# SPI Protocol Masters +# +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set + +# +# PPS support +# +# CONFIG_PPS is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_SH_WDT is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SH_MOBILE_SDHI is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13783 is not set +# CONFIG_AB3100_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_MFD_88PM8607 is not set +# CONFIG_AB4500_CORE is not set +# CONFIG_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +CONFIG_VIDEO_OUTPUT_CONTROL=m +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_SOUND is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_ARCH_HAS_EHCI is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +CONFIG_USB_MON=y +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +# CONFIG_USB_OHCI_HCD is not set +# CONFIG_USB_SL811_HCD is not set +CONFIG_USB_R8A66597_HCD=m +# CONFIG_USB_HWA_HCD is not set +# CONFIG_USB_GADGET_MUSB_HDRC is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB port drivers +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_VST is not set +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_VBUS_DRAW=2 +CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA25X is not set +# CONFIG_USB_GADGET_R8A66597 is not set +# CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_S3C_HSOTG is not set +# CONFIG_USB_GADGET_IMX is not set +# CONFIG_USB_GADGET_S3C2410 is not set +CONFIG_USB_GADGET_M66592=y +CONFIG_USB_M66592=y +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_FSL_QE is not set +# CONFIG_USB_GADGET_CI13XXX is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LANGWELL is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_ZERO is not set +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_FILE_STORAGE is not set +# CONFIG_USB_MASS_STORAGE is not set +# CONFIG_USB_G_SERIAL is not set +# CONFIG_USB_MIDI_GADGET is not set +# CONFIG_USB_G_PRINTER is not set +# CONFIG_USB_CDC_COMPOSITE is not set +# CONFIG_USB_G_MULTI is not set + +# +# OTG and related infrastructure +# +# CONFIG_NOP_USB_XCEIV is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +CONFIG_RTC_DRV_MAX6900=y +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +CONFIG_RTC_DRV_SH=y +# CONFIG_RTC_DRV_GENERIC is not set +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +CONFIG_UIO=m +# CONFIG_UIO_PDRV is not set +# CONFIG_UIO_PDRV_GENIRQ is not set +# CONFIG_UIO_SMX is not set +# CONFIG_UIO_SERCOS3 is not set + +# +# TI VLYNQ +# +# CONFIG_STAGING is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT4_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set +# CONFIG_DLM is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_PRINTK_TIME=y +CONFIG_ENABLE_WARN_DEPRECATED=y +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_DEBUG_SHIRQ=y +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_SLAB is not set +CONFIG_DEBUG_PREEMPT=y +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +CONFIG_STACKTRACE=y +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +CONFIG_DEBUG_VM=y +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set +CONFIG_FRAME_POINTER=y +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set +# CONFIG_PAGE_POISONING is not set +CONFIG_NOP_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y +CONFIG_RING_BUFFER=y +CONFIG_EVENT_TRACING=y +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_TRACING=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_PREEMPT_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_ENABLE_DEFAULT_TRACERS is not set +# CONFIG_FTRACE_SYSCALLS is not set +# CONFIG_BOOT_TRACER is not set +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +CONFIG_KSYM_TRACER=y +# CONFIG_PROFILE_KSYM_TRACER is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_RING_BUFFER_BENCHMARK is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_DMA_API_DEBUG is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_SH_STANDARD_BIOS is not set +# CONFIG_STACK_DEBUG is not set +CONFIG_DEBUG_STACK_USAGE=y +# CONFIG_4KSTACKS is not set +CONFIG_DUMP_CODE=y +CONFIG_DWARF_UNWINDER=y +# CONFIG_SH_NO_BSS_INIT is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_DEFAULT_SECURITY_SELINUX is not set +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +# CONFIG_CRYPTO_MANAGER is not set +# CONFIG_CRYPTO_MANAGER2 is not set +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +# CONFIG_CRYPTO_CBC is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +# CONFIG_CRYPTO_ECB is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_GHASH is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_HW=y +CONFIG_BINARY_PRINTF=y + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_HAVE_LMB=y +CONFIG_NLATTR=y +CONFIG_GENERIC_ATOMIC64=y diff --git a/arch/sh/tools/mach-types b/arch/sh/tools/mach-types index 6639b25d8d57..b25aa554ee5e 100644 --- a/arch/sh/tools/mach-types +++ b/arch/sh/tools/mach-types @@ -32,6 +32,7 @@ DREAMCAST SH_DREAMCAST SNAPGEAR SH_SECUREEDGE5410 EDOSK7705 SH_EDOSK7705 EDOSK7760 SH_EDOSK7760 +SDK7786 SH_SDK7786 SH4202_MICRODEV SH_SH4202_MICRODEV SH03 SH_SH03 LANDISK SH_LANDISK -- cgit v1.2.3 From 46c4e5daea3d5df06e27bf5a49a0c42274db6725 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Fri, 15 Jan 2010 08:00:45 +0900 Subject: sh: Fix CONFIG_PMB=n build. The last commit introduced the following breakage arch/sh/include/asm/mmu.h: In function 'pmb_remap': arch/sh/include/asm/mmu.h:79: error: expected ';' before '}' token and... arch/sh/include/asm/mmu.h:78: error: 'EINVAL' undeclared (first use in this function) arch/sh/include/asm/mmu.h:78: error: (Each undeclared identifier is reported only once arch/sh/include/asm/mmu.h:78: error: for each function it appears in.) arch/sh/include/asm/mmu.h: In function 'pmb_init': arch/sh/include/asm/mmu.h:87: error: 'ENODEV' undeclared (first use in this function) Signed-off-by: Matt Fleming Signed-off-by: Paul Mundt --- arch/sh/include/asm/mmu.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/mmu.h b/arch/sh/include/asm/mmu.h index 4b0882bf5183..e5e8f48830ef 100644 --- a/arch/sh/include/asm/mmu.h +++ b/arch/sh/include/asm/mmu.h @@ -30,6 +30,7 @@ #define PMB_NO_ENTRY (-1) #ifndef __ASSEMBLY__ +#include /* Default "unsigned long" context */ typedef unsigned long mm_context_id_t[NR_CPUS]; @@ -75,7 +76,7 @@ int pmb_init(void); static inline long pmb_remap(unsigned long virt, unsigned long phys, unsigned long size, unsigned long flags) { - return -EINVAL + return -EINVAL; } static inline void pmb_unmap(unsigned long addr) -- cgit v1.2.3 From 10ab92d8c336c25af1fce46113ed85856e02e95d Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 15 Jan 2010 12:08:31 +0900 Subject: sh: heartbeat: Support access size specification via resource flags. This permits the resource access size to be handed off through the resource flags, which saves platforms from having to establish platform data only to specify the register width. Signed-off-by: Paul Mundt --- arch/sh/drivers/heartbeat.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/drivers/heartbeat.c b/arch/sh/drivers/heartbeat.c index a9339a6174fc..2acbc793032d 100644 --- a/arch/sh/drivers/heartbeat.c +++ b/arch/sh/drivers/heartbeat.c @@ -1,7 +1,7 @@ /* * Generic heartbeat driver for regular LED banks * - * Copyright (C) 2007 Paul Mundt + * Copyright (C) 2007 - 2010 Paul Mundt * * Most SH reference boards include a number of individual LEDs that can * be independently controlled (either via a pre-defined hardware @@ -27,7 +27,7 @@ #include #define DRV_NAME "heartbeat" -#define DRV_VERSION "0.1.1" +#define DRV_VERSION "0.1.2" static unsigned char default_bit_pos[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; @@ -98,7 +98,7 @@ static int heartbeat_drv_probe(struct platform_device *pdev) return -ENOMEM; } - hd->base = ioremap_nocache(res->start, res->end - res->start + 1); + hd->base = ioremap_nocache(res->start, resource_size(res)); if (unlikely(!hd->base)) { dev_err(&pdev->dev, "ioremap failed\n"); @@ -117,8 +117,20 @@ static int heartbeat_drv_probe(struct platform_device *pdev) for (i = 0; i < hd->nr_bits; i++) hd->mask |= (1 << hd->bit_pos[i]); - if (!hd->regsize) - hd->regsize = 8; /* default access size */ + if (!hd->regsize) { + switch (res->flags & IORESOURCE_MEM_TYPE_MASK) { + case IORESOURCE_MEM_32BIT: + hd->regsize = 32; + break; + case IORESOURCE_MEM_16BIT: + hd->regsize = 16; + break; + case IORESOURCE_MEM_8BIT: + default: + hd->regsize = 8; + break; + } + } setup_timer(&hd->timer, heartbeat_timer, (unsigned long)hd); platform_set_drvdata(pdev, hd); -- cgit v1.2.3 From 2267c7875b3a3a41b7a8cc9659d75ec934c98ffd Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 15 Jan 2010 12:11:30 +0900 Subject: sh: mach-sdk7786: heartbeat support. Hand off the user LEDs to the heartbeat driver. Signed-off-by: Paul Mundt --- arch/sh/boards/mach-sdk7786/setup.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/boards/mach-sdk7786/setup.c b/arch/sh/boards/mach-sdk7786/setup.c index b460dcc785c1..f2d4b75bf31c 100644 --- a/arch/sh/boards/mach-sdk7786/setup.c +++ b/arch/sh/boards/mach-sdk7786/setup.c @@ -15,8 +15,22 @@ #include #include #include +#include #include +static struct resource heartbeat_resource = { + .start = 0x07fff8b0, + .end = 0x07fff8b0 + sizeof(u16) - 1, + .flags = IORESOURCE_MEM | IORESOURCE_MEM_16BIT, +}; + +static struct platform_device heartbeat_device = { + .name = "heartbeat", + .id = -1, + .num_resources = 1, + .resource = &heartbeat_resource, +}; + static struct resource smsc911x_resources[] = { [0] = { .name = "smsc911x-memory", @@ -82,6 +96,7 @@ static struct i2c_board_info __initdata sdk7786_i2c_devices[] = { }; static struct platform_device *sh7786_devices[] __initdata = { + &heartbeat_device, &smsc911x_device, &smbus_fpga_device, &smbus_pcie_device, -- cgit v1.2.3 From a09d2831b3457a92a58d67bddfed370516acfe28 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 15 Jan 2010 12:24:34 +0900 Subject: sh: heartbeat: Update boards for access size hinting. This updates the existing boards that specify the register width through platform data to use the resource flags instead. This eliminates platform data completely in most cases, and permits further improvement in the heartbeat driver as well as shrinking the overall private data size. Signed-off-by: Paul Mundt --- arch/sh/boards/board-polaris.c | 15 ++++++--------- arch/sh/boards/board-sh7785lcr.c | 21 ++++++--------------- arch/sh/boards/board-urquell.c | 21 ++++++--------------- arch/sh/boards/mach-ecovec24/setup.c | 16 +++++++--------- arch/sh/boards/mach-sdk7780/setup.c | 23 +++++++---------------- arch/sh/boards/mach-se/7206/setup.c | 15 ++++++--------- arch/sh/boards/mach-se/7343/setup.c | 21 ++++++--------------- arch/sh/boards/mach-se/770x/setup.c | 15 ++++++--------- arch/sh/boards/mach-se/7721/setup.c | 15 ++++++--------- arch/sh/boards/mach-se/7722/setup.c | 21 ++++++--------------- arch/sh/boards/mach-se/7724/setup.c | 21 ++++++--------------- arch/sh/boards/mach-se/7780/setup.c | 21 ++++++--------------- 12 files changed, 74 insertions(+), 151 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/boards/board-polaris.c b/arch/sh/boards/board-polaris.c index 62607eb51004..5bc126900ce3 100644 --- a/arch/sh/boards/board-polaris.c +++ b/arch/sh/boards/board-polaris.c @@ -59,15 +59,12 @@ static unsigned char heartbeat_bit_pos[] = { 0, 1, 2, 3 }; static struct heartbeat_data heartbeat_data = { .bit_pos = heartbeat_bit_pos, .nr_bits = ARRAY_SIZE(heartbeat_bit_pos), - .regsize = 8, }; -static struct resource heartbeat_resources[] = { - [0] = { - .start = PORT_PCDR, - .end = PORT_PCDR, - .flags = IORESOURCE_MEM, - }, +static struct resource heartbeat_resource = { + .start = PORT_PCDR, + .end = PORT_PCDR, + .flags = IORESOURCE_MEM | IORESOURCE_MEM_8BIT, }; static struct platform_device heartbeat_device = { @@ -76,8 +73,8 @@ static struct platform_device heartbeat_device = { .dev = { .platform_data = &heartbeat_data, }, - .num_resources = ARRAY_SIZE(heartbeat_resources), - .resource = heartbeat_resources, + .num_resources = 1, + .resource = &heartbeat_resource, }; static struct platform_device *polaris_devices[] __initdata = { diff --git a/arch/sh/boards/board-sh7785lcr.c b/arch/sh/boards/board-sh7785lcr.c index e5a8a2fde39c..7eea90db6cea 100644 --- a/arch/sh/boards/board-sh7785lcr.c +++ b/arch/sh/boards/board-sh7785lcr.c @@ -32,26 +32,17 @@ * NOTE: This board has 2 physical memory maps. * Please look at include/asm-sh/sh7785lcr.h or hardware manual. */ -static struct resource heartbeat_resources[] = { - [0] = { - .start = PLD_LEDCR, - .end = PLD_LEDCR, - .flags = IORESOURCE_MEM, - }, -}; - -static struct heartbeat_data heartbeat_data = { - .regsize = 8, +static struct resource heartbeat_resource = { + .start = PLD_LEDCR, + .end = PLD_LEDCR, + .flags = IORESOURCE_MEM | IORESOURCE_MEM_8BIT, }; static struct platform_device heartbeat_device = { .name = "heartbeat", .id = -1, - .dev = { - .platform_data = &heartbeat_data, - }, - .num_resources = ARRAY_SIZE(heartbeat_resources), - .resource = heartbeat_resources, + .num_resources = 1, + .resource = &heartbeat_resource, }; static struct mtd_partition nor_flash_partitions[] = { diff --git a/arch/sh/boards/board-urquell.c b/arch/sh/boards/board-urquell.c index 36b8bac9b124..268f09e46568 100644 --- a/arch/sh/boards/board-urquell.c +++ b/arch/sh/boards/board-urquell.c @@ -50,26 +50,17 @@ */ /* HeartBeat */ -static struct resource heartbeat_resources[] = { - [0] = { - .start = BOARDREG(SLEDR), - .end = BOARDREG(SLEDR), - .flags = IORESOURCE_MEM, - }, -}; - -static struct heartbeat_data heartbeat_data = { - .regsize = 16, +static struct resource heartbeat_resource = { + .start = BOARDREG(SLEDR), + .end = BOARDREG(SLEDR), + .flags = IORESOURCE_MEM | IORESOURCE_MEM_16BIT, }; static struct platform_device heartbeat_device = { .name = "heartbeat", .id = -1, - .dev = { - .platform_data = &heartbeat_data, - }, - .num_resources = ARRAY_SIZE(heartbeat_resources), - .resource = heartbeat_resources, + .num_resources = 1 + .resource = &heartbeat_resource, }; /* LAN91C111 */ diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index 6a8861b39f05..a6b223332d15 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c @@ -64,18 +64,16 @@ /* Heartbeat */ static unsigned char led_pos[] = { 0, 1, 2, 3 }; + static struct heartbeat_data heartbeat_data = { - .regsize = 8, .nr_bits = 4, .bit_pos = led_pos, }; -static struct resource heartbeat_resources[] = { - [0] = { - .start = 0xA405012C, /* PTG */ - .end = 0xA405012E - 1, - .flags = IORESOURCE_MEM, - }, +static struct resource heartbeat_resource = { + .start = 0xA405012C, /* PTG */ + .end = 0xA405012E - 1, + .flags = IORESOURCE_MEM | IORESOURCE_MEM_8BIT, }; static struct platform_device heartbeat_device = { @@ -84,8 +82,8 @@ static struct platform_device heartbeat_device = { .dev = { .platform_data = &heartbeat_data, }, - .num_resources = ARRAY_SIZE(heartbeat_resources), - .resource = heartbeat_resources, + .num_resources = 1, + .resource = &heartbeat_resource, }; /* MTD */ diff --git a/arch/sh/boards/mach-sdk7780/setup.c b/arch/sh/boards/mach-sdk7780/setup.c index aad94a78dc70..1d04657e992d 100644 --- a/arch/sh/boards/mach-sdk7780/setup.c +++ b/arch/sh/boards/mach-sdk7780/setup.c @@ -20,27 +20,18 @@ #define GPIO_PECR 0xFFEA0008 -//* Heartbeat */ -static struct heartbeat_data heartbeat_data = { - .regsize = 16, -}; - -static struct resource heartbeat_resources[] = { - [0] = { - .start = PA_LED, - .end = PA_LED, - .flags = IORESOURCE_MEM, - }, +/* Heartbeat */ +static struct resource heartbeat_resource = { + .start = PA_LED, + .end = PA_LED, + .flags = IORESOURCE_MEM | IORESOURCE_MEM_16BIT, }; static struct platform_device heartbeat_device = { .name = "heartbeat", .id = -1, - .dev = { - .platform_data = &heartbeat_data, - }, - .num_resources = ARRAY_SIZE(heartbeat_resources), - .resource = heartbeat_resources, + .num_resources = 1 + .resource = &heartbeat_resource, }; /* SMC91x */ diff --git a/arch/sh/boards/mach-se/7206/setup.c b/arch/sh/boards/mach-se/7206/setup.c index f5466384972e..8f5c65d43d1d 100644 --- a/arch/sh/boards/mach-se/7206/setup.c +++ b/arch/sh/boards/mach-se/7206/setup.c @@ -50,15 +50,12 @@ static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 }; static struct heartbeat_data heartbeat_data = { .bit_pos = heartbeat_bit_pos, .nr_bits = ARRAY_SIZE(heartbeat_bit_pos), - .regsize = 32, }; -static struct resource heartbeat_resources[] = { - [0] = { - .start = PA_LED, - .end = PA_LED, - .flags = IORESOURCE_MEM, - }, +static struct resource heartbeat_resource = { + .start = PA_LED, + .end = PA_LED, + .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT, }; static struct platform_device heartbeat_device = { @@ -67,8 +64,8 @@ static struct platform_device heartbeat_device = { .dev = { .platform_data = &heartbeat_data, }, - .num_resources = ARRAY_SIZE(heartbeat_resources), - .resource = heartbeat_resources, + .num_resources = 1, + .resource = &heartbeat_resource, }; static struct platform_device *se7206_devices[] __initdata = { diff --git a/arch/sh/boards/mach-se/7343/setup.c b/arch/sh/boards/mach-se/7343/setup.c index 292cc47d853f..3412bb2973ae 100644 --- a/arch/sh/boards/mach-se/7343/setup.c +++ b/arch/sh/boards/mach-se/7343/setup.c @@ -11,26 +11,17 @@ #include #include -static struct resource heartbeat_resources[] = { - [0] = { - .start = PA_LED, - .end = PA_LED, - .flags = IORESOURCE_MEM, - }, -}; - -static struct heartbeat_data heartbeat_data = { - .regsize = 16, +static struct resource heartbeat_resource = { + .start = PA_LED, + .end = PA_LED, + .flags = IORESOURCE_MEM | IORESOURCE_MEM_16BIT, }; static struct platform_device heartbeat_device = { .name = "heartbeat", .id = -1, - .dev = { - .platform_data = &heartbeat_data, - }, - .num_resources = ARRAY_SIZE(heartbeat_resources), - .resource = heartbeat_resources, + .num_resources = 1, + .resource = &heartbeat_resource, }; static struct mtd_partition nor_flash_partitions[] = { diff --git a/arch/sh/boards/mach-se/770x/setup.c b/arch/sh/boards/mach-se/770x/setup.c index 527eb6b12610..66d39d1b0901 100644 --- a/arch/sh/boards/mach-se/770x/setup.c +++ b/arch/sh/boards/mach-se/770x/setup.c @@ -93,15 +93,12 @@ static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 }; static struct heartbeat_data heartbeat_data = { .bit_pos = heartbeat_bit_pos, .nr_bits = ARRAY_SIZE(heartbeat_bit_pos), - .regsize = 16, }; -static struct resource heartbeat_resources[] = { - [0] = { - .start = PA_LED, - .end = PA_LED, - .flags = IORESOURCE_MEM, - }, +static struct resource heartbeat_resource = { + .start = PA_LED, + .end = PA_LED, + .flags = IORESOURCE_MEM | IORESOURCE_MEM_16BIT, }; static struct platform_device heartbeat_device = { @@ -110,8 +107,8 @@ static struct platform_device heartbeat_device = { .dev = { .platform_data = &heartbeat_data, }, - .num_resources = ARRAY_SIZE(heartbeat_resources), - .resource = heartbeat_resources, + .num_resources = 1, + .resource = &heartbeat_resource, }; #if defined(CONFIG_CPU_SUBTYPE_SH7710) ||\ diff --git a/arch/sh/boards/mach-se/7721/setup.c b/arch/sh/boards/mach-se/7721/setup.c index 55af4c36b43a..460da53b4961 100644 --- a/arch/sh/boards/mach-se/7721/setup.c +++ b/arch/sh/boards/mach-se/7721/setup.c @@ -23,15 +23,12 @@ static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 }; static struct heartbeat_data heartbeat_data = { .bit_pos = heartbeat_bit_pos, .nr_bits = ARRAY_SIZE(heartbeat_bit_pos), - .regsize = 16, }; -static struct resource heartbeat_resources[] = { - [0] = { - .start = PA_LED, - .end = PA_LED, - .flags = IORESOURCE_MEM, - }, +static struct resource heartbeat_resource = { + .start = PA_LED, + .end = PA_LED, + .flags = IORESOURCE_MEM | IORESOURCE_MEM_16BIT, }; static struct platform_device heartbeat_device = { @@ -40,8 +37,8 @@ static struct platform_device heartbeat_device = { .dev = { .platform_data = &heartbeat_data, }, - .num_resources = ARRAY_SIZE(heartbeat_resources), - .resource = heartbeat_resources, + .num_resources = 1, + .resource = &heartbeat_resource, }; static struct resource cf_ide_resources[] = { diff --git a/arch/sh/boards/mach-se/7722/setup.c b/arch/sh/boards/mach-se/7722/setup.c index b1cb9425b600..93675418171d 100644 --- a/arch/sh/boards/mach-se/7722/setup.c +++ b/arch/sh/boards/mach-se/7722/setup.c @@ -25,26 +25,17 @@ #include /* Heartbeat */ -static struct heartbeat_data heartbeat_data = { - .regsize = 16, -}; - -static struct resource heartbeat_resources[] = { - [0] = { - .start = PA_LED, - .end = PA_LED, - .flags = IORESOURCE_MEM, - }, +static struct resource heartbeat_resource = { + .start = PA_LED, + .end = PA_LED, + .flags = IORESOURCE_MEM | IORESOURCE_MEM_16BIT, }; static struct platform_device heartbeat_device = { .name = "heartbeat", .id = -1, - .dev = { - .platform_data = &heartbeat_data, - }, - .num_resources = ARRAY_SIZE(heartbeat_resources), - .resource = heartbeat_resources, + .num_resources = 1, + .resource = &heartbeat_resource, }; /* SMC91x */ diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c index 5d0f70b46c97..cbfba783ee49 100644 --- a/arch/sh/boards/mach-se/7724/setup.c +++ b/arch/sh/boards/mach-se/7724/setup.c @@ -53,26 +53,17 @@ */ /* Heartbeat */ -static struct heartbeat_data heartbeat_data = { - .regsize = 16, -}; - -static struct resource heartbeat_resources[] = { - [0] = { - .start = PA_LED, - .end = PA_LED, - .flags = IORESOURCE_MEM, - }, +static struct resource heartbeat_resource = { + .start = PA_LED, + .end = PA_LED, + .flags = IORESOURCE_MEM | IORESOURCE_MEM_16BIT, }; static struct platform_device heartbeat_device = { .name = "heartbeat", .id = -1, - .dev = { - .platform_data = &heartbeat_data, - }, - .num_resources = ARRAY_SIZE(heartbeat_resources), - .resource = heartbeat_resources, + .num_resources = 1, + .resource = &heartbeat_resource, }; /* LAN91C111 */ diff --git a/arch/sh/boards/mach-se/7780/setup.c b/arch/sh/boards/mach-se/7780/setup.c index 1d3a867e94e3..f7bfb3f83692 100644 --- a/arch/sh/boards/mach-se/7780/setup.c +++ b/arch/sh/boards/mach-se/7780/setup.c @@ -17,26 +17,17 @@ #include /* Heartbeat */ -static struct heartbeat_data heartbeat_data = { - .regsize = 16, -}; - -static struct resource heartbeat_resources[] = { - [0] = { - .start = PA_LED, - .end = PA_LED, - .flags = IORESOURCE_MEM, - }, +static struct resource heartbeat_resource = { + .start = PA_LED, + .end = PA_LED, + .flags = IORESOURCE_MEM | IORESOURCE_MEM_16BIT, }; static struct platform_device heartbeat_device = { .name = "heartbeat", .id = -1, - .dev = { - .platform_data = &heartbeat_data, - }, - .num_resources = ARRAY_SIZE(heartbeat_resources), - .resource = heartbeat_resources, + .num_resources = 1, + .resource = &heartbeat_resource, }; /* SMC91x */ -- cgit v1.2.3 From a6198a238baceae9d4e0ce3915f6d239c89b5c08 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 15 Jan 2010 14:21:37 +0900 Subject: sh: Guard against early IPIs in flush_cache_all(). flush_cache_all() gets called in to when we do some early ioremapping. Unfortunately on SDK7786 the interrupt controller itself requires ioremapping, leading to a bit of a chicken and egg scenario. For now, don't bother with IPI crosscalls if there aren't any other CPUs online. Signed-off-by: Paul Mundt --- arch/sh/mm/cache.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/mm/cache.c b/arch/sh/mm/cache.c index b8607fa7ae12..0f4095d7ac8b 100644 --- a/arch/sh/mm/cache.c +++ b/arch/sh/mm/cache.c @@ -2,7 +2,7 @@ * arch/sh/mm/cache.c * * Copyright (C) 1999, 2000, 2002 Niibe Yutaka - * Copyright (C) 2002 - 2009 Paul Mundt + * Copyright (C) 2002 - 2010 Paul Mundt * * Released under the terms of the GNU GPL v2.0. */ @@ -41,8 +41,17 @@ static inline void cacheop_on_each_cpu(void (*func) (void *info), void *info, int wait) { preempt_disable(); - smp_call_function(func, info, wait); + + /* + * It's possible that this gets called early on when IRQs are + * still disabled due to ioremapping by the boot CPU, so don't + * even attempt IPIs unless there are other CPUs online. + */ + if (num_online_cpus() > 1) + smp_call_function(func, info, wait); + func(info); + preempt_enable(); } -- cgit v1.2.3 From f0cb77372c3cf8c0cb17bbfb30a62506ea119286 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 15 Jan 2010 15:13:48 +0900 Subject: sh: Fix up the secondary CPU entry point for 32bit mode. Presently the secondary CPU entry point is only aimed at 29bit phys mode, causing it to point to a stray virtual address in 32bit mode. Fix it up after consulting with our shiny new __in_29bit_mode(). Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/smp-shx3.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'arch/sh') diff --git a/arch/sh/kernel/cpu/sh4a/smp-shx3.c b/arch/sh/kernel/cpu/sh4a/smp-shx3.c index 5863e0c4d02f..11bf4c1e25c0 100644 --- a/arch/sh/kernel/cpu/sh4a/smp-shx3.c +++ b/arch/sh/kernel/cpu/sh4a/smp-shx3.c @@ -78,7 +78,10 @@ void __init plat_prepare_cpus(unsigned int max_cpus) void plat_start_cpu(unsigned int cpu, unsigned long entry_point) { - __raw_writel(entry_point, RESET_REG(cpu)); + if (__in_29bit_mode()) + __raw_writel(entry_point, RESET_REG(cpu)); + else + __raw_writel(virt_to_phys(entry_point), RESET_REG(cpu)); if (!(__raw_readl(STBCR_REG(cpu)) & STBCR_MSTP)) __raw_writel(STBCR_MSTP, STBCR_REG(cpu)); -- cgit v1.2.3 From 6f832e8aab8c4c6d28629e970e4a85e74a8d0be6 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 15 Jan 2010 16:31:04 +0900 Subject: sh: mach-sdk7786: mode pins support. This wires up the mode pins support on the SDK7786. The pins are standard SH7786 pins, and all are fixed in software. Needed for the clock framework, PCIe, and so forth. Signed-off-by: Paul Mundt --- arch/sh/boards/mach-sdk7786/setup.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/boards/mach-sdk7786/setup.c b/arch/sh/boards/mach-sdk7786/setup.c index f2d4b75bf31c..c38c6cc293b5 100644 --- a/arch/sh/boards/mach-sdk7786/setup.c +++ b/arch/sh/boards/mach-sdk7786/setup.c @@ -218,6 +218,23 @@ static void __init init_sdk7786_IRQ(void) plat_irq_setup_pins(IRQ_MODE_IRL3210_MASK); } +#define MODSWR_REGS 0x07fff830 + +static int sdk7786_mode_pins(void) +{ + void __iomem *modswr; + int pin_states; + + modswr = ioremap_nocache(MODSWR_REGS, SZ_16); + if (!modswr) + return -ENXIO; + + pin_states = ioread16(modswr); + iounmap(modswr); + + return pin_states; +} + /* Initialize the board */ static void __init sdk7786_setup(char **cmdline_p) { @@ -230,5 +247,6 @@ static void __init sdk7786_setup(char **cmdline_p) static struct sh_machine_vector mv_sdk7786 __initmv = { .mv_name = "SDK7786", .mv_setup = sdk7786_setup, + .mv_mode_pins = sdk7786_mode_pins, .mv_init_irq = init_sdk7786_IRQ, }; -- cgit v1.2.3 From 7dcaa8e8e67b2cfbe0097c9bb52e23aed5443b8b Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 15 Jan 2010 19:13:56 +0900 Subject: sh: Generalize SH7786 PCIe support. Previously this was only built in for Urquell boards, but the same approach can be used on SDK7786 now that the mode pin reading is supported, so make it generic to SH7786. Signed-off-by: Paul Mundt --- arch/sh/boards/Kconfig | 1 + arch/sh/drivers/pci/Makefile | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig index c0a1992bb256..938e87d51482 100644 --- a/arch/sh/boards/Kconfig +++ b/arch/sh/boards/Kconfig @@ -153,6 +153,7 @@ config SH_SDK7780 config SH_SDK7786 bool "SDK7786" depends on CPU_SUBTYPE_SH7786 + select SYS_SUPPORTS_PCI help Select SDK7786 if configuring for a Renesas Technology Europe SH7786-65nm board. diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile index 08af1f459756..2c458b602beb 100644 --- a/arch/sh/drivers/pci/Makefile +++ b/arch/sh/drivers/pci/Makefile @@ -8,7 +8,7 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7751R) += pci-sh7751.o ops-sh4.o obj-$(CONFIG_CPU_SUBTYPE_SH7763) += pci-sh7780.o ops-sh4.o obj-$(CONFIG_CPU_SUBTYPE_SH7780) += pci-sh7780.o ops-sh4.o obj-$(CONFIG_CPU_SUBTYPE_SH7785) += pci-sh7780.o ops-sh4.o -obj-$(CONFIG_CPU_SUBTYPE_SH7786) += ops-sh7786.o +obj-$(CONFIG_CPU_SUBTYPE_SH7786) += pcie-sh7786.o ops-sh7786.o obj-$(CONFIG_CPU_SH5) += pci-sh5.o ops-sh5.o obj-$(CONFIG_SH_DREAMCAST) += ops-dreamcast.o fixups-dreamcast.o \ @@ -25,4 +25,3 @@ obj-$(CONFIG_SH_TITAN) += fixups-titan.o obj-$(CONFIG_SH_LANDISK) += fixups-landisk.o obj-$(CONFIG_SH_LBOX_RE2) += fixups-rts7751r2d.o obj-$(CONFIG_SH_CAYMAN) += fixups-cayman.o -obj-$(CONFIG_SH_URQUELL) += pcie-sh7786.o -- cgit v1.2.3 From 8eda55142080f0373b1f0268fe6d6807f193e713 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Tue, 17 Nov 2009 21:05:31 +0000 Subject: sh: New extended page flag to wire/unwire TLB entries Provide a new extended page flag, _PAGE_WIRED and an SH4 implementation for wiring TLB entries and use it in the fixmap code path so that we can wire the fixmap TLB entry. Signed-off-by: Matt Fleming --- arch/sh/include/asm/pgtable_32.h | 4 ++ arch/sh/include/asm/tlb.h | 16 ++++++++ arch/sh/include/cpu-sh4/cpu/mmu_context.h | 4 ++ arch/sh/mm/tlb-pteaex.c | 66 +++++++++++++++++++++++++++++++ arch/sh/mm/tlb-sh4.c | 66 +++++++++++++++++++++++++++++++ 5 files changed, 156 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/pgtable_32.h b/arch/sh/include/asm/pgtable_32.h index 5003ee86f67b..c573d45f1286 100644 --- a/arch/sh/include/asm/pgtable_32.h +++ b/arch/sh/include/asm/pgtable_32.h @@ -71,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) @@ -164,6 +166,8 @@ static inline unsigned long copy_ptea_attributes(unsigned long x) (PTE_MASK | _PAGE_ACCESSED | _PAGE_CACHABLE | \ _PAGE_DIRTY | _PAGE_SPECIAL) +#define _PAGE_WIRED (_PAGE_EXT(_PAGE_EXT_WIRED)) + #ifndef __ASSEMBLY__ #if defined(CONFIG_X2TLB) /* SH-X2 TLB */ diff --git a/arch/sh/include/asm/tlb.h b/arch/sh/include/asm/tlb.h index da8fe7ab8728..3ed2f7a05416 100644 --- a/arch/sh/include/asm/tlb.h +++ b/arch/sh/include/asm/tlb.h @@ -97,6 +97,22 @@ tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vma) #define tlb_migrate_finish(mm) do { } while (0) +#ifdef CONFIG_CPU_SH4 +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 /* CONFIG_CPU_SH4 */ + #else /* CONFIG_MMU */ #define tlb_start_vma(tlb, vma) do { } while (0) diff --git a/arch/sh/include/cpu-sh4/cpu/mmu_context.h b/arch/sh/include/cpu-sh4/cpu/mmu_context.h index 3ce7ef6c2978..03ea75c5315d 100644 --- a/arch/sh/include/cpu-sh4/cpu/mmu_context.h +++ b/arch/sh/include/cpu-sh4/cpu/mmu_context.h @@ -25,6 +25,10 @@ #define MMUCR_TI (1<<2) +#define MMUCR_URB 0x00FC0000 +#define MMUCR_URB_SHIFT 18 +#define MMUCR_URB_NENTRIES 64 + #if defined(CONFIG_32BIT) && defined(CONFIG_CPU_SUBTYPE_ST40) #define MMUCR_SE (1 << 4) #else diff --git a/arch/sh/mm/tlb-pteaex.c b/arch/sh/mm/tlb-pteaex.c index 409b7c2b4b9d..88c8bb05e16d 100644 --- a/arch/sh/mm/tlb-pteaex.c +++ b/arch/sh/mm/tlb-pteaex.c @@ -76,3 +76,69 @@ void __uses_jump_to_uncached local_flush_tlb_one(unsigned long asid, __raw_writel(asid, MMU_UTLB_ADDRESS_ARRAY2 | MMU_PAGE_ASSOC_BIT); back_to_cached(); } + +/* + * Load the entry for 'addr' into the TLB and wire the entry. + */ +void tlb_wire_entry(struct vm_area_struct *vma, unsigned long addr, pte_t pte) +{ + unsigned long status, flags; + int urb; + + local_irq_save(flags); + + /* Load the entry into the TLB */ + __update_tlb(vma, addr, pte); + + /* ... and wire it up. */ + status = ctrl_inl(MMUCR); + urb = (status & MMUCR_URB) >> MMUCR_URB_SHIFT; + status &= ~MMUCR_URB; + + /* + * Make sure we're not trying to wire the last TLB entry slot. + */ + BUG_ON(!--urb); + + urb = urb % MMUCR_URB_NENTRIES; + + status |= (urb << MMUCR_URB_SHIFT); + ctrl_outl(status, MMUCR); + ctrl_barrier(); + + local_irq_restore(flags); +} + +/* + * Unwire the last wired TLB entry. + * + * It should also be noted that it is not possible to wire and unwire + * TLB entries in an arbitrary order. If you wire TLB entry N, followed + * by entry N+1, you must unwire entry N+1 first, then entry N. In this + * respect, it works like a stack or LIFO queue. + */ +void tlb_unwire_entry(void) +{ + unsigned long status, flags; + int urb; + + local_irq_save(flags); + + status = ctrl_inl(MMUCR); + urb = (status & MMUCR_URB) >> MMUCR_URB_SHIFT; + status &= ~MMUCR_URB; + + /* + * Make sure we're not trying to unwire a TLB entry when none + * have been wired. + */ + BUG_ON(urb++ == MMUCR_URB_NENTRIES); + + urb = urb % MMUCR_URB_NENTRIES; + + status |= (urb << MMUCR_URB_SHIFT); + ctrl_outl(status, MMUCR); + ctrl_barrier(); + + local_irq_restore(flags); +} diff --git a/arch/sh/mm/tlb-sh4.c b/arch/sh/mm/tlb-sh4.c index 8cf550e2570f..4c6234743318 100644 --- a/arch/sh/mm/tlb-sh4.c +++ b/arch/sh/mm/tlb-sh4.c @@ -81,3 +81,69 @@ void __uses_jump_to_uncached local_flush_tlb_one(unsigned long asid, ctrl_outl(data, addr); back_to_cached(); } + +/* + * Load the entry for 'addr' into the TLB and wire the entry. + */ +void tlb_wire_entry(struct vm_area_struct *vma, unsigned long addr, pte_t pte) +{ + unsigned long status, flags; + int urb; + + local_irq_save(flags); + + /* Load the entry into the TLB */ + __update_tlb(vma, addr, pte); + + /* ... and wire it up. */ + status = ctrl_inl(MMUCR); + urb = (status & MMUCR_URB) >> MMUCR_URB_SHIFT; + status &= ~MMUCR_URB; + + /* + * Make sure we're not trying to wire the last TLB entry slot. + */ + BUG_ON(!--urb); + + urb = urb % MMUCR_URB_NENTRIES; + + status |= (urb << MMUCR_URB_SHIFT); + ctrl_outl(status, MMUCR); + ctrl_barrier(); + + local_irq_restore(flags); +} + +/* + * Unwire the last wired TLB entry. + * + * It should also be noted that it is not possible to wire and unwire + * TLB entries in an arbitrary order. If you wire TLB entry N, followed + * by entry N+1, you must unwire entry N+1 first, then entry N. In this + * respect, it works like a stack or LIFO queue. + */ +void tlb_unwire_entry(void) +{ + unsigned long status, flags; + int urb; + + local_irq_save(flags); + + status = ctrl_inl(MMUCR); + urb = (status & MMUCR_URB) >> MMUCR_URB_SHIFT; + status &= ~MMUCR_URB; + + /* + * Make sure we're not trying to unwire a TLB entry when none + * have been wired. + */ + BUG_ON(urb++ == MMUCR_URB_NENTRIES); + + urb = urb % MMUCR_URB_NENTRIES; + + status |= (urb << MMUCR_URB_SHIFT); + ctrl_outl(status, MMUCR); + ctrl_barrier(); + + local_irq_restore(flags); +} -- cgit v1.2.3 From 24ef7fc4dcc57afa0c33166c25bfe7676ffd4296 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Thu, 19 Nov 2009 21:11:05 +0000 Subject: sh: Acquire some more page flags for SH-5. We need some more page flags to hook up _PAGE_WIRED (and eventually other things). So use the unused PTE bits above the PPN field as no implementations use these for anything currently. Now that we have _PAGE_WIRED let's provide the SH-5 functions for wiring up TLB entries. Signed-off-by: Matt Fleming --- arch/sh/include/asm/page.h | 2 +- arch/sh/include/asm/pgtable_64.h | 15 ++++++++++++++- arch/sh/include/asm/tlb.h | 41 ++++++++++++++++++++++++++++++++++++++++ arch/sh/mm/tlbflush_64.c | 2 +- 4 files changed, 57 insertions(+), 3 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/page.h b/arch/sh/include/asm/page.h index a86c0f1d05d4..61e58105adc3 100644 --- a/arch/sh/include/asm/page.h +++ b/arch/sh/include/asm/page.h @@ -88,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) } ) diff --git a/arch/sh/include/asm/pgtable_64.h b/arch/sh/include/asm/pgtable_64.h index dd381588c695..0ee46776dad6 100644 --- a/arch/sh/include/asm/pgtable_64.h +++ b/arch/sh/include/asm/pgtable_64.h @@ -123,8 +123,21 @@ static __inline__ void set_pte(pte_t *pteptr, pte_t pteval) #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_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 diff --git a/arch/sh/include/asm/tlb.h b/arch/sh/include/asm/tlb.h index 3ed2f7a05416..dfc8fcd8ee50 100644 --- a/arch/sh/include/asm/tlb.h +++ b/arch/sh/include/asm/tlb.h @@ -11,6 +11,7 @@ #ifdef CONFIG_MMU #include #include +#include /* * TLB handling. This allows us to remove pages from the page @@ -100,6 +101,46 @@ tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vma) #ifdef CONFIG_CPU_SH4 extern void tlb_wire_entry(struct vm_area_struct *, unsigned long, pte_t); extern void tlb_unwire_entry(void); +#elif defined(CONFIG_SUPERH64) +static int dtlb_entry; +static unsigned long long dtlb_entries[64]; + +static inline void tlb_wire_entry(struct vm_area_struct *vma, + unsigned long addr, pte_t pte) +{ + unsigned long long entry; + unsigned long paddr, flags; + + BUG_ON(dtlb_entry == 64); + + local_irq_save(flags); + + entry = sh64_get_wired_dtlb_entry(); + dtlb_entries[dtlb_entry++] = entry; + + paddr = pte_val(pte) & _PAGE_FLAGS_HARDWARE_MASK; + paddr &= ~PAGE_MASK; + + sh64_setup_tlb_slot(entry, addr, get_asid(), paddr); + + local_irq_restore(flags); +} + +static inline void tlb_unwire_entry(void) +{ + unsigned long long entry; + unsigned long flags; + + BUG_ON(!dtlb_entry); + + local_irq_save(flags); + entry = dtlb_entries[dtlb_entry--]; + + sh64_teardown_tlb_slot(entry); + sh64_put_wired_dtlb_entry(entry); + + local_irq_restore(flags); +} #else static inline void tlb_wire_entry(struct vm_area_struct *vma , unsigned long addr, pte_t pte) diff --git a/arch/sh/mm/tlbflush_64.c b/arch/sh/mm/tlbflush_64.c index de0b0e881823..706da1d3a67a 100644 --- a/arch/sh/mm/tlbflush_64.c +++ b/arch/sh/mm/tlbflush_64.c @@ -36,7 +36,7 @@ extern void die(const char *,struct pt_regs *,long); static inline void print_prots(pgprot_t prot) { - printk("prot is 0x%08lx\n",pgprot_val(prot)); + printk("prot is 0x%016llx\n",pgprot_val(prot)); printk("%s %s %s %s %s\n",PPROT(_PAGE_SHARED),PPROT(_PAGE_READ), PPROT(_PAGE_EXECUTE),PPROT(_PAGE_WRITE),PPROT(_PAGE_USER)); -- cgit v1.2.3 From 07cad4dc1bfdaefd20c6329e9d8179ad1c600e92 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Tue, 17 Nov 2009 22:03:41 +0000 Subject: sh: Generalise the pte handling code for the fixmap path Generalise the code for setting and clearing pte's and allow TLB entries to be pinned and unpinned if the _PAGE_WIRED flag is present. Signed-off-by: Matt Fleming --- arch/sh/include/asm/fixmap.h | 1 + arch/sh/mm/init.c | 44 ++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 41 insertions(+), 4 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/fixmap.h b/arch/sh/include/asm/fixmap.h index 5ac1e40a511c..1566d3361ca4 100644 --- a/arch/sh/include/asm/fixmap.h +++ b/arch/sh/include/asm/fixmap.h @@ -65,6 +65,7 @@ enum 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/mm/init.c b/arch/sh/mm/init.c index d5fb014279ad..30a9b530d456 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -39,7 +39,7 @@ unsigned long cached_to_uncached = P2SEG - P1SEG; #endif #ifdef CONFIG_MMU -static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot) +static pte_t *__get_pte_phys(unsigned long addr) { pgd_t *pgd; pud_t *pud; @@ -49,22 +49,30 @@ static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot) pgd = pgd_offset_k(addr); if (pgd_none(*pgd)) { pgd_ERROR(*pgd); - return; + return NULL; } pud = pud_alloc(NULL, pgd, addr); if (unlikely(!pud)) { pud_ERROR(*pud); - return; + return NULL; } pmd = pmd_alloc(NULL, pud, addr); if (unlikely(!pmd)) { pmd_ERROR(*pmd); - return; + return NULL; } pte = pte_offset_kernel(pmd, addr); + return pte; +} + +static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot) +{ + pte_t *pte; + + pte = __get_pte_phys(addr); if (!pte_none(*pte)) { pte_ERROR(*pte); return; @@ -72,6 +80,22 @@ static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot) set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, prot)); local_flush_tlb_one(get_asid(), addr); + + if (pgprot_val(prot) & _PAGE_WIRED) + tlb_wire_entry(NULL, addr, *pte); +} + +static void clear_pte_phys(unsigned long addr, pgprot_t prot) +{ + pte_t *pte; + + pte = __get_pte_phys(addr); + + if (pgprot_val(prot) & _PAGE_WIRED) + tlb_unwire_entry(); + + set_pte(pte, pfn_pte(0, __pgprot(0))); + local_flush_tlb_one(get_asid(), addr); } /* @@ -101,6 +125,18 @@ void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot) set_pte_phys(address, phys, prot); } +void __clear_fixmap(enum fixed_addresses idx, pgprot_t prot) +{ + unsigned long address = __fix_to_virt(idx); + + if (idx >= __end_of_fixed_addresses) { + BUG(); + return; + } + + clear_pte_phys(address, prot); +} + void __init page_table_range_init(unsigned long start, unsigned long end, pgd_t *pgd_base) { -- cgit v1.2.3 From 4d35b93a66e9b87df20784fcf130d2e8760be53f Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Thu, 5 Nov 2009 07:54:17 +0000 Subject: sh: Add fixed ioremap support Some devices need to be ioremap'd and accessed very early in the boot process. It is not possible to use the standard ioremap() function in this case because that requires kmalloc()'ing some virtual address space and kmalloc() may not be available so early in boot. This patch provides fixmap mappings that allow physical address ranges to be remapped into the kernel address space during the early boot stages. Signed-off-by: Matt Fleming --- arch/sh/include/asm/fixmap.h | 8 +++ arch/sh/include/asm/io.h | 6 ++ arch/sh/kernel/setup.c | 7 ++- arch/sh/mm/Kconfig | 4 ++ arch/sh/mm/Makefile | 1 + arch/sh/mm/ioremap_fixed.c | 144 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 167 insertions(+), 3 deletions(-) create mode 100644 arch/sh/mm/ioremap_fixed.c (limited to 'arch/sh') diff --git a/arch/sh/include/asm/fixmap.h b/arch/sh/include/asm/fixmap.h index 1566d3361ca4..38a1de866873 100644 --- a/arch/sh/include/asm/fixmap.h +++ b/arch/sh/include/asm/fixmap.h @@ -60,6 +60,14 @@ enum fixed_addresses { FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */ FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1, #endif + /* + * 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, __end_of_fixed_addresses }; diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h index f4314d8b05b8..bee5965e0a82 100644 --- a/arch/sh/include/asm/io.h +++ b/arch/sh/include/asm/io.h @@ -237,6 +237,12 @@ void __iomem *__ioremap_caller(unsigned long offset, unsigned long size, unsigned long flags, void *caller); void __iounmap(void __iomem *addr); +#ifdef CONFIG_IOREMAP_FIXED +extern void __iomem *ioremap_fixed(resource_size_t, unsigned long, pgprot_t); +extern void iounmap_fixed(void __iomem *); +extern void ioremap_fixed_init(void); +#endif + static inline void __iomem * __ioremap(unsigned long offset, unsigned long size, unsigned long flags) { diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index f79ebe32a24a..e187750dd319 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -449,14 +449,15 @@ void __init setup_arch(char **cmdline_p) #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; #endif + paging_init(); + pmb_init(); + + ioremap_fixed_init(); /* Perform the machine specific initialisation */ if (likely(sh_mv.mv_setup)) sh_mv.mv_setup(cmdline_p); - paging_init(); - pmb_init(); - #ifdef CONFIG_SMP plat_smp_setup(); #endif diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index 7a4ebc8cbadd..b89075256b70 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig @@ -169,6 +169,10 @@ config ARCH_MEMORY_PROBE def_bool y depends on MEMORY_HOTPLUG +config IOREMAP_FIXED + def_bool y + depends on X2TLB || SUPERH64 + choice prompt "Kernel page size" default PAGE_SIZE_4KB diff --git a/arch/sh/mm/Makefile b/arch/sh/mm/Makefile index edde8bdd681d..89ba56c20ade 100644 --- a/arch/sh/mm/Makefile +++ b/arch/sh/mm/Makefile @@ -35,6 +35,7 @@ endif obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o obj-$(CONFIG_PMB) += pmb.o obj-$(CONFIG_NUMA) += numa.o +obj-$(CONFIG_IOREMAP_FIXED) += ioremap_fixed.o # Special flags for fault_64.o. This puts restrictions on the number of # caller-save registers that the compiler can target when building this file. diff --git a/arch/sh/mm/ioremap_fixed.c b/arch/sh/mm/ioremap_fixed.c new file mode 100644 index 000000000000..3a9d3d88fe8d --- /dev/null +++ b/arch/sh/mm/ioremap_fixed.c @@ -0,0 +1,144 @@ +/* + * Re-map IO memory to kernel address space so that we can access it. + * + * These functions should only be used when it is necessary to map a + * physical address space into the kernel address space before ioremap() + * can be used, e.g. early in boot before paging_init(). + * + * Copyright (C) 2009 Matt Fleming + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct ioremap_map { + void __iomem *addr; + unsigned long size; + unsigned long fixmap_addr; +}; + +static struct ioremap_map ioremap_maps[FIX_N_IOREMAPS]; + +void __init ioremap_fixed_init(void) +{ + struct ioremap_map *map; + int i; + + for (i = 0; i < FIX_N_IOREMAPS; i++) { + map = &ioremap_maps[i]; + map->fixmap_addr = __fix_to_virt(FIX_IOREMAP_BEGIN + i); + } +} + +void __init __iomem * +ioremap_fixed(resource_size_t phys_addr, unsigned long size, pgprot_t prot) +{ + enum fixed_addresses idx0, idx; + resource_size_t last_addr; + struct ioremap_map *map; + unsigned long offset; + unsigned int nrpages; + int i, slot; + + slot = -1; + for (i = 0; i < FIX_N_IOREMAPS; i++) { + map = &ioremap_maps[i]; + if (!map->addr) { + map->size = size; + slot = i; + break; + } + } + + if (slot < 0) + return NULL; + + /* Don't allow wraparound or zero size */ + last_addr = phys_addr + size - 1; + if (!size || last_addr < phys_addr) + return NULL; + + /* + * Fixmap mappings have to be page-aligned + */ + offset = phys_addr & ~PAGE_MASK; + phys_addr &= PAGE_MASK; + size = PAGE_ALIGN(last_addr + 1) - phys_addr; + + /* + * Mappings have to fit in the FIX_IOREMAP area. + */ + nrpages = size >> PAGE_SHIFT; + if (nrpages > FIX_N_IOREMAPS) + return NULL; + + /* + * Ok, go for it.. + */ + idx0 = FIX_IOREMAP_BEGIN + slot; + idx = idx0; + while (nrpages > 0) { + pgprot_val(prot) |= _PAGE_WIRED; + __set_fixmap(idx, phys_addr, prot); + phys_addr += PAGE_SIZE; + idx++; + --nrpages; + } + + map->addr = (void __iomem *)(offset + map->fixmap_addr); + return map->addr; +} + +void __init iounmap_fixed(void __iomem *addr) +{ + enum fixed_addresses idx; + unsigned long virt_addr; + struct ioremap_map *map; + unsigned long offset; + unsigned int nrpages; + int i, slot; + pgprot_t prot; + + slot = -1; + for (i = 0; i < FIX_N_IOREMAPS; i++) { + map = &ioremap_maps[i]; + if (map->addr == addr) { + slot = i; + break; + } + } + + if (slot < 0) + return; + + virt_addr = (unsigned long)addr; + + offset = virt_addr & ~PAGE_MASK; + nrpages = PAGE_ALIGN(offset + map->size - 1) >> PAGE_SHIFT; + + pgprot_val(prot) = _PAGE_WIRED; + + idx = FIX_IOREMAP_BEGIN + slot + nrpages; + while (nrpages > 0) { + __clear_fixmap(idx, prot); + --idx; + --nrpages; + } + + map->size = 0; + map->addr = NULL; +} -- cgit v1.2.3 From 6f82b6ebb1dcc0c3c23820a70a5d79a60c4f5e84 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Thu, 5 Nov 2009 08:01:10 +0000 Subject: sh: Use ioremap_fixmed to map the SM501 DRAM config register We need to write to the DRAM config register very early and at such an early stage ioremap() is not available. So use ioremap_fixed() to map the register. The reason that we are avoiding using the legacy P2 mapping is that there will come a day when the legacy P2 mappings no longer exist. Signed-off-by: Matt Fleming --- arch/sh/boards/board-sh7785lcr.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/boards/board-sh7785lcr.c b/arch/sh/boards/board-sh7785lcr.c index 7eea90db6cea..511de38d2046 100644 --- a/arch/sh/boards/board-sh7785lcr.c +++ b/arch/sh/boards/board-sh7785lcr.c @@ -332,8 +332,15 @@ static void __init sh7785lcr_setup(char **cmdline_p) pm_power_off = sh7785lcr_power_off; /* sm501 DRAM configuration */ - sm501_reg = (void __iomem *)0xb3e00000 + SM501_DRAM_CONTROL; - writel(0x000307c2, sm501_reg); + sm501_reg = ioremap_fixed(SM107_REG_ADDR, SM501_DRAM_CONTROL, + PAGE_KERNEL); + if (!sm501_reg) { + printk(KERN_ERR "%s: ioremap error.\n", __func__); + return; + } + + writel(0x000307c2, sm501_reg + SM501_DRAM_CONTROL); + iounmap_fixed(sm501_reg); } /* Return the board specific boot mode pin configuration */ -- cgit v1.2.3 From 597fe76ec36e782aa45b8dac5e12e4dbb0588967 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Thu, 5 Nov 2009 20:49:05 +0000 Subject: sh: Use ioremap_fixed() to implement SH-5 ioremap() Use the fixmap-based memory mapping implementation for SH-5's ioremap() functions and delete the old static allocator that was borrowed from sparc. Signed-off-by: Matt Fleming --- arch/sh/mm/ioremap_64.c | 287 +----------------------------------------------- 1 file changed, 4 insertions(+), 283 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/mm/ioremap_64.c b/arch/sh/mm/ioremap_64.c index ef434657d428..fb0aa457c71e 100644 --- a/arch/sh/mm/ioremap_64.c +++ b/arch/sh/mm/ioremap_64.c @@ -28,299 +28,20 @@ #include #include -static struct resource shmedia_iomap = { - .name = "shmedia_iomap", - .start = IOBASE_VADDR + PAGE_SIZE, - .end = IOBASE_END - 1, -}; - -static void shmedia_mapioaddr(unsigned long pa, unsigned long va, - unsigned long flags); -static void shmedia_unmapioaddr(unsigned long vaddr); -static void __iomem *shmedia_ioremap(struct resource *res, u32 pa, - int sz, unsigned long flags); - -/* - * We have the same problem as the SPARC, so lets have the same comment: - * Our mini-allocator... - * Boy this is gross! We need it because we must map I/O for - * timers and interrupt controller before the kmalloc is available. - */ - -#define XNMLN 15 -#define XNRES 10 - -struct xresource { - struct resource xres; /* Must be first */ - int xflag; /* 1 == used */ - char xname[XNMLN+1]; -}; - -static struct xresource xresv[XNRES]; - -static struct xresource *xres_alloc(void) -{ - struct xresource *xrp; - int n; - - xrp = xresv; - for (n = 0; n < XNRES; n++) { - if (xrp->xflag == 0) { - xrp->xflag = 1; - return xrp; - } - xrp++; - } - return NULL; -} - -static void xres_free(struct xresource *xrp) -{ - xrp->xflag = 0; -} - -static struct resource *shmedia_find_resource(struct resource *root, - unsigned long vaddr) -{ - struct resource *res; - - for (res = root->child; res; res = res->sibling) - if (res->start <= vaddr && res->end >= vaddr) - return res; - - return NULL; -} - -static void __iomem *shmedia_alloc_io(unsigned long phys, unsigned long size, - const char *name, unsigned long flags) -{ - struct xresource *xres; - struct resource *res; - char *tack; - int tlen; - - if (name == NULL) - name = "???"; - - xres = xres_alloc(); - if (xres != 0) { - tack = xres->xname; - res = &xres->xres; - } else { - printk_once(KERN_NOTICE "%s: done with statics, " - "switching to kmalloc\n", __func__); - tlen = strlen(name); - tack = kmalloc(sizeof(struct resource) + tlen + 1, GFP_KERNEL); - if (!tack) - return NULL; - memset(tack, 0, sizeof(struct resource)); - res = (struct resource *) tack; - tack += sizeof(struct resource); - } - - strncpy(tack, name, XNMLN); - tack[XNMLN] = 0; - res->name = tack; - - return shmedia_ioremap(res, phys, size, flags); -} - -static void __iomem *shmedia_ioremap(struct resource *res, u32 pa, int sz, - unsigned long flags) -{ - unsigned long offset = ((unsigned long) pa) & (~PAGE_MASK); - unsigned long round_sz = (offset + sz + PAGE_SIZE-1) & PAGE_MASK; - unsigned long va; - unsigned int psz; - - if (allocate_resource(&shmedia_iomap, res, round_sz, - shmedia_iomap.start, shmedia_iomap.end, - PAGE_SIZE, NULL, NULL) != 0) { - panic("alloc_io_res(%s): cannot occupy\n", - (res->name != NULL) ? res->name : "???"); - } - - va = res->start; - pa &= PAGE_MASK; - - psz = (res->end - res->start + (PAGE_SIZE - 1)) / PAGE_SIZE; - - for (psz = res->end - res->start + 1; psz != 0; psz -= PAGE_SIZE) { - shmedia_mapioaddr(pa, va, flags); - va += PAGE_SIZE; - pa += PAGE_SIZE; - } - - return (void __iomem *)(unsigned long)(res->start + offset); -} - -static void shmedia_free_io(struct resource *res) -{ - unsigned long len = res->end - res->start + 1; - - BUG_ON((len & (PAGE_SIZE - 1)) != 0); - - while (len) { - len -= PAGE_SIZE; - shmedia_unmapioaddr(res->start + len); - } - - release_resource(res); -} - -static __init_refok void *sh64_get_page(void) -{ - void *page; - - if (slab_is_available()) - page = (void *)get_zeroed_page(GFP_KERNEL); - else - page = alloc_bootmem_pages(PAGE_SIZE); - - if (!page || ((unsigned long)page & ~PAGE_MASK)) - panic("sh64_get_page: Out of memory already?\n"); - - return page; -} - -static void shmedia_mapioaddr(unsigned long pa, unsigned long va, - unsigned long flags) +void __iomem *__ioremap_caller(unsigned long offset, unsigned long size, + unsigned long flags, void *caller) { - pgd_t *pgdp; - pud_t *pudp; - pmd_t *pmdp; - pte_t *ptep, pte; pgprot_t prot; - pr_debug("shmedia_mapiopage pa %08lx va %08lx\n", pa, va); - - if (!flags) - flags = 1; /* 1 = CB0-1 device */ - - pgdp = pgd_offset_k(va); - if (pgd_none(*pgdp) || !pgd_present(*pgdp)) { - pudp = (pud_t *)sh64_get_page(); - set_pgd(pgdp, __pgd((unsigned long)pudp | _KERNPG_TABLE)); - } - - pudp = pud_offset(pgdp, va); - if (pud_none(*pudp) || !pud_present(*pudp)) { - pmdp = (pmd_t *)sh64_get_page(); - set_pud(pudp, __pud((unsigned long)pmdp | _KERNPG_TABLE)); - } - - pmdp = pmd_offset(pudp, va); - if (pmd_none(*pmdp) || !pmd_present(*pmdp)) { - ptep = (pte_t *)sh64_get_page(); - set_pmd(pmdp, __pmd((unsigned long)ptep + _PAGE_TABLE)); - } - prot = __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_SHARED | flags); - pte = pfn_pte(pa >> PAGE_SHIFT, prot); - ptep = pte_offset_kernel(pmdp, va); - - if (!pte_none(*ptep) && - pte_val(*ptep) != pte_val(pte)) - pte_ERROR(*ptep); - - set_pte(ptep, pte); - - flush_tlb_kernel_range(va, PAGE_SIZE); -} - -static void shmedia_unmapioaddr(unsigned long vaddr) -{ - pgd_t *pgdp; - pud_t *pudp; - pmd_t *pmdp; - pte_t *ptep; - - pgdp = pgd_offset_k(vaddr); - if (pgd_none(*pgdp) || pgd_bad(*pgdp)) - return; - - pudp = pud_offset(pgdp, vaddr); - if (pud_none(*pudp) || pud_bad(*pudp)) - return; - - pmdp = pmd_offset(pudp, vaddr); - if (pmd_none(*pmdp) || pmd_bad(*pmdp)) - return; - - ptep = pte_offset_kernel(pmdp, vaddr); - - if (pte_none(*ptep) || !pte_present(*ptep)) - return; - - clear_page((void *)ptep); - pte_clear(&init_mm, vaddr, ptep); -} - -void __iomem *__ioremap_caller(unsigned long offset, unsigned long size, - unsigned long flags, void *caller) -{ - char name[14]; - - sprintf(name, "phys_%08x", (u32)offset); - return shmedia_alloc_io(offset, size, name, flags); + return ioremap_fixed(offset, size, prot); } EXPORT_SYMBOL(__ioremap_caller); void __iounmap(void __iomem *virtual) { - unsigned long vaddr = (unsigned long)virtual & PAGE_MASK; - struct resource *res; - unsigned int psz; - - res = shmedia_find_resource(&shmedia_iomap, vaddr); - if (!res) { - printk(KERN_ERR "%s: Failed to free 0x%08lx\n", - __func__, vaddr); - return; - } - - psz = (res->end - res->start + (PAGE_SIZE - 1)) / PAGE_SIZE; - - shmedia_free_io(res); - - if ((char *)res >= (char *)xresv && - (char *)res < (char *)&xresv[XNRES]) { - xres_free((struct xresource *)res); - } else { - kfree(res); - } + iounmap_fixed(virtual); } EXPORT_SYMBOL(__iounmap); - -static int -ioremap_proc_info(char *buf, char **start, off_t fpos, int length, int *eof, - void *data) -{ - char *p = buf, *e = buf + length; - struct resource *r; - const char *nm; - - for (r = ((struct resource *)data)->child; r != NULL; r = r->sibling) { - if (p + 32 >= e) /* Better than nothing */ - break; - nm = r->name; - if (nm == NULL) - nm = "???"; - - p += sprintf(p, "%08lx-%08lx: %s\n", - (unsigned long)r->start, - (unsigned long)r->end, nm); - } - - return p-buf; -} - -static int __init register_proc_onchip(void) -{ - create_proc_read_entry("io_map", 0, 0, ioremap_proc_info, - &shmedia_iomap); - return 0; -} -late_initcall(register_proc_onchip); -- cgit v1.2.3 From 78bf04fc96f509474c6b443b515d6b79bb7bf584 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Sun, 17 Jan 2010 01:45:26 +0900 Subject: sh: Tidy up non-translatable checks in iounmap path. This tidies up the iounmap path with consolidated checks for nontranslatable mappings. This is in preparation of unifying the implementations. Signed-off-by: Paul Mundt --- arch/sh/mm/ioremap_32.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/mm/ioremap_32.c b/arch/sh/mm/ioremap_32.c index 2141befb4f91..c80a8166fbb0 100644 --- a/arch/sh/mm/ioremap_32.c +++ b/arch/sh/mm/ioremap_32.c @@ -105,15 +105,35 @@ void __iomem *__ioremap_caller(unsigned long phys_addr, unsigned long size, } EXPORT_SYMBOL(__ioremap_caller); +/* + * Simple checks for non-translatable mappings. + */ +static inline int iomapping_nontranslatable(unsigned long offset) +{ +#ifdef CONFIG_29BIT + /* + * In 29-bit mode this includes the fixed P1/P2 areas, as well as + * parts of P3. + */ + if (PXSEG(offset) < P3SEG || offset >= P3_ADDR_MAX) + return 1; +#endif + + if (is_pci_memory_fixed_range(offset, 0)) + return 1; + + return 0; +} + void __iounmap(void __iomem *addr) { unsigned long vaddr = (unsigned long __force)addr; - unsigned long seg = PXSEG(vaddr); struct vm_struct *p; - if (seg < P3SEG || vaddr >= P3_ADDR_MAX) - return; - if (is_pci_memory_fixed_range(vaddr, 0)) + /* + * Nothing to do if there is no translatable mapping. + */ + if (iomapping_nontranslatable(vaddr)) return; #ifdef CONFIG_PMB -- cgit v1.2.3 From 3d467676abf5f01f5ee99056273a58486968e252 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Mon, 18 Jan 2010 19:33:10 +0900 Subject: sh: Setup early PMB mappings. More and more boards are going to start shipping that boot with the MMU in 32BIT mode by default. Previously we relied on the bootloader to setup PMB mappings for use by the kernel but we also need to cater for boards whose bootloaders don't set them up. If CONFIG_PMB_LEGACY is not enabled we have full control over our PMB mappings and can compress our address space. Usually, the distance between the the cached and uncached mappings of RAM is always 512MB, however we can compress the distance to be the amount of RAM on the board. pmb_init() now becomes much simpler. It no longer has to calculate any mappings, it just has to synchronise the software PMB table with the hardware. Tested on SDK7786 and SH7785LCR. Signed-off-by: Matt Fleming Signed-off-by: Paul Mundt --- arch/sh/kernel/head_32.S | 241 +++++++++++++++++++++++++++++++++++++++++++++++ arch/sh/mm/pmb.c | 156 ++++++++++++++++++++---------- 2 files changed, 346 insertions(+), 51 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/kernel/head_32.S b/arch/sh/kernel/head_32.S index e5d421db4c83..8ee31a0b973e 100644 --- a/arch/sh/kernel/head_32.S +++ b/arch/sh/kernel/head_32.S @@ -3,6 +3,7 @@ * arch/sh/kernel/head.S * * Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima + * Copyright (C) 2010 Matt Fleming * * 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 @@ -84,6 +85,236 @@ ENTRY(_stext) ldc r0, r7_bank ! ... and initial thread_info #endif +#if defined(CONFIG_PMB) && !defined(CONFIG_PMB_LEGACY) + /* + * Reconfigure the initial PMB mappings setup by the hardware. + * + * When we boot in 32-bit MMU mode there are 2 PMB entries already + * setup for us. + * + * Entry VPN PPN V SZ C UB WT + * --------------------------------------------------------------- + * 0 0x80000000 0x00000000 1 512MB 1 0 1 + * 1 0xA0000000 0x00000000 1 512MB 0 0 0 + * + * But we reprogram them here because we want complete control over + * our address space and the initial mappings may not map PAGE_OFFSET + * to __MEMORY_START (or even map all of our RAM). + * + * Once we've setup cached and uncached mappings for all of RAM we + * clear the rest of the PMB entries. + * + * This clearing also deals with the fact that PMB entries can persist + * across reboots. The PMB could have been left in any state when the + * reboot occurred, so to be safe we clear all entries and start with + * with a clean slate. + */ + + mov.l .LMMUCR, r1 /* Flush the TLB */ + mov.l @r1, r0 + or #MMUCR_TI, r0 + mov.l r0, @r1 + + mov.l .LMEMORY_SIZE, r5 + mov r5, r7 + + mov #PMB_E_SHIFT, r0 + mov #0x1, r4 + shld r0, r4 + + mov.l .LFIRST_DATA_ENTRY, r0 + mov.l .LPMB_DATA, r1 + mov.l .LFIRST_ADDR_ENTRY, r2 + mov.l .LPMB_ADDR, r3 + + mov #0, r10 + + /* + * r0 = PMB_DATA data field + * r1 = PMB_DATA address field + * r2 = PMB_ADDR data field + * r3 = PMB_ADDR address field + * r4 = PMB_E_SHIFT + * r5 = remaining amount of RAM to map + * r6 = PMB mapping size we're trying to use + * r7 = cached_to_uncached + * r8 = scratch register + * r9 = scratch register + * r10 = number of PMB entries we've setup + */ +.L512: + mov #(512 >> 4), r6 + shll16 r6 + shll8 r6 + + cmp/hi r5, r6 + bt .L128 + + mov #(PMB_SZ_512M >> 2), r9 + shll2 r9 + + /* + * Cached mapping + */ + mov #PMB_C, r8 + or r0, r8 + or r9, r8 + mov.l r8, @r1 + mov.l r2, @r3 + + add r4, r1 /* Increment to the next PMB_DATA entry */ + add r4, r3 /* Increment to the next PMB_ADDR entry */ + + add #1, r10 /* Increment number of PMB entries */ + + /* + * Uncached mapping + */ + mov #(PMB_UB >> 8), r8 + shll8 r8 + + or r0, r8 + or r9, r8 + mov.l r8, @r1 + mov r2, r8 + add r7, r8 + mov.l r8, @r3 + + add r4, r1 /* Increment to the next PMB_DATA entry */ + add r4, r3 /* Increment to the next PMB_ADDR entry */ + + add #1, r10 /* Increment number of PMB entries */ + + sub r6, r5 + add r6, r0 + add r6, r2 + + bra .L512 + +.L128: + mov #(128 >> 4), r6 + shll16 r6 + shll8 r6 + + cmp/hi r5, r6 + bt .L64 + + mov #(PMB_SZ_128M >> 2), r9 + shll2 r9 + + /* + * Cached mapping + */ + mov #PMB_C, r8 + or r0, r8 + or r9, r8 + mov.l r8, @r1 + mov.l r2, @r3 + + add r4, r1 /* Increment to the next PMB_DATA entry */ + add r4, r3 /* Increment to the next PMB_ADDR entry */ + + add #1, r10 /* Increment number of PMB entries */ + + /* + * Uncached mapping + */ + mov #(PMB_UB >> 8), r8 + shll8 r8 + + or r0, r8 + or r9, r8 + mov.l r8, @r1 + mov r2, r8 + add r7, r8 + mov.l r8, @r3 + + add r4, r1 /* Increment to the next PMB_DATA entry */ + add r4, r3 /* Increment to the next PMB_ADDR entry */ + + add #1, r10 /* Increment number of PMB entries */ + + sub r6, r5 + add r6, r0 + add r6, r2 + + bra .L128 + +.L64: + mov #(64 >> 4), r6 + shll16 r6 + shll8 r6 + + cmp/hi r5, r6 + bt .Ldone + + mov #(PMB_SZ_64M >> 2), r9 + shll2 r9 + + /* + * Cached mapping + */ + mov #PMB_C, r8 + or r0, r8 + or r9, r8 + mov.l r8, @r1 + mov.l r2, @r3 + + add r4, r1 /* Increment to the next PMB_DATA entry */ + add r4, r3 /* Increment to the next PMB_ADDR entry */ + + add #1, r10 /* Increment number of PMB entries */ + + /* + * Uncached mapping + */ + mov #(PMB_UB >> 8), r8 + shll8 r8 + + or r0, r8 + or r9, r8 + mov.l r8, @r1 + mov r2, r8 + add r7, r8 + mov.l r8, @r3 + + add r4, r1 /* Increment to the next PMB_DATA entry */ + add r4, r3 /* Increment to the next PMB_ADDR entry */ + + add #1, r10 /* Increment number of PMB entries */ + + sub r6, r5 + add r6, r0 + add r6, r2 + + bra .L64 + +.Ldone: + /* Update cached_to_uncached */ + mov.l .Lcached_to_uncached, r0 + mov.l r7, @r0 + + /* + * Clear the remaining PMB entries. + * + * r3 = entry to begin clearing from + * r10 = number of entries we've setup so far + */ + mov #0, r1 + mov #PMB_ENTRY_MAX, r0 + +.Lagain: + mov.l r1, @r3 /* Clear PMB_ADDR entry */ + add #1, r10 /* Increment the loop counter */ + cmp/eq r0, r10 + bf/s .Lagain + add r4, r3 /* Increment to the next PMB_ADDR entry */ + + mov.l 6f, r0 + icbi @r0 + +#endif /* !CONFIG_PMB_LEGACY */ + #ifndef CONFIG_SH_NO_BSS_INIT /* * Don't clear BSS if running on slow platforms such as an RTL simulation, @@ -133,3 +364,13 @@ ENTRY(stack_start) 5: .long start_kernel 6: .long sh_cpu_init 7: .long init_thread_union + +#if defined(CONFIG_PMB) && !defined(CONFIG_PMB_LEGACY) +.LPMB_ADDR: .long PMB_ADDR +.LPMB_DATA: .long PMB_DATA +.LFIRST_ADDR_ENTRY: .long PAGE_OFFSET | PMB_V +.LFIRST_DATA_ENTRY: .long __MEMORY_START | PMB_V +.LMMUCR: .long MMUCR +.Lcached_to_uncached: .long cached_to_uncached +.LMEMORY_SIZE: .long __MEMORY_SIZE +#endif diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c index 8f7dbf183fb0..b796b6c021b4 100644 --- a/arch/sh/mm/pmb.c +++ b/arch/sh/mm/pmb.c @@ -3,11 +3,8 @@ * * Privileged Space Mapping Buffer (PMB) Support. * - * Copyright (C) 2005 - 2010 Paul Mundt - * - * P1/P2 Section mapping definitions from map32.h, which was: - * - * Copyright 2003 (c) Lineo Solutions,Inc. + * Copyright (C) 2005 - 2010 Paul Mundt + * Copyright (C) 2010 Matt Fleming * * 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 @@ -280,46 +277,82 @@ static void __pmb_unmap(struct pmb_entry *pmbe) } #ifdef CONFIG_PMB_LEGACY +static inline unsigned int pmb_ppn_in_range(unsigned long ppn) +{ + return ppn >= __MEMORY_START && ppn < __MEMORY_START + __MEMORY_SIZE; +} + static int pmb_apply_legacy_mappings(void) { - int i; - unsigned long addr, data; unsigned int applied = 0; + int i; - for (i = 0; i < PMB_ENTRY_MAX; i++) { - struct pmb_entry *pmbe; - unsigned long vpn, ppn, flags; - - addr = PMB_DATA + (i << PMB_E_SHIFT); - data = ctrl_inl(addr); - if (!(data & PMB_V)) - continue; + pr_info("PMB: Preserving legacy mappings:\n"); - if (data & PMB_C) { -#if defined(CONFIG_CACHE_WRITETHROUGH) - data |= PMB_WT; -#elif defined(CONFIG_CACHE_WRITEBACK) - data &= ~PMB_WT; -#else - data &= ~(PMB_C | PMB_WT); -#endif - } - ctrl_outl(data, addr); - - ppn = data & PMB_PFN_MASK; + /* + * The following entries are setup by the bootloader. + * + * Entry VPN PPN V SZ C UB + * -------------------------------------------------------- + * 0 0xA0000000 0x00000000 1 64MB 0 0 + * 1 0xA4000000 0x04000000 1 16MB 0 0 + * 2 0xA6000000 0x08000000 1 16MB 0 0 + * 9 0x88000000 0x48000000 1 128MB 1 1 + * 10 0x90000000 0x50000000 1 128MB 1 1 + * 11 0x98000000 0x58000000 1 128MB 1 1 + * 13 0xA8000000 0x48000000 1 128MB 0 0 + * 14 0xB0000000 0x50000000 1 128MB 0 0 + * 15 0xB8000000 0x58000000 1 128MB 0 0 + * + * The only entries the we need are the ones that map the kernel + * at the cached and uncached addresses. + */ + for (i = 0; i < PMB_ENTRY_MAX; i++) { + unsigned long addr, data; + unsigned long addr_val, data_val; + unsigned long ppn, vpn; - flags = data & (PMB_C | PMB_WT | PMB_UB); - flags |= data & PMB_SZ_MASK; + addr = mk_pmb_addr(i); + data = mk_pmb_data(i); - addr = PMB_ADDR + (i << PMB_E_SHIFT); - data = ctrl_inl(addr); + addr_val = __raw_readl(addr); + data_val = __raw_readl(data); - vpn = data & PMB_PFN_MASK; + /* + * Skip over any bogus entries + */ + if (!(data_val & PMB_V) || !(addr_val & PMB_V)) + continue; - pmbe = pmb_alloc(vpn, ppn, flags, i); - WARN_ON(IS_ERR(pmbe)); + ppn = data_val & PMB_PFN_MASK; + vpn = addr_val & PMB_PFN_MASK; - applied++; + /* + * Only preserve in-range mappings. + */ + if (pmb_ppn_in_range(ppn)) { + unsigned int size; + char *sz_str = NULL; + + size = data_val & PMB_SZ_MASK; + + sz_str = (size == PMB_SZ_16M) ? " 16MB": + (size == PMB_SZ_64M) ? " 64MB": + (size == PMB_SZ_128M) ? "128MB": + "512MB"; + + pr_info("\t0x%08lx -> 0x%08lx [ %s %scached ]\n", + vpn >> PAGE_SHIFT, ppn >> PAGE_SHIFT, sz_str, + (data_val & PMB_C) ? "" : "un"); + + applied++; + } else { + /* + * Invalidate anything out of bounds. + */ + __raw_writel(addr_val & ~PMB_V, addr); + __raw_writel(data_val & ~PMB_V, data); + } } return (applied == 0); @@ -333,8 +366,9 @@ static inline int pmb_apply_legacy_mappings(void) int __uses_jump_to_uncached pmb_init(void) { - unsigned int i; - unsigned long size, ret; + int i; + unsigned long addr, data; + unsigned long ret; jump_to_uncached(); @@ -352,25 +386,45 @@ int __uses_jump_to_uncached pmb_init(void) } /* - * Insert PMB entries for the P1 and P2 areas so that, after - * we've switched the MMU to 32-bit mode, the semantics of P1 - * and P2 are the same as in 29-bit mode, e.g. - * - * P1 - provides a cached window onto physical memory - * P2 - provides an uncached window onto physical memory + * Sync our software copy of the PMB mappings with those in + * hardware. The mappings in the hardware PMB were either set up + * by the bootloader or very early on by the kernel. */ - size = (unsigned long)__MEMORY_START + __MEMORY_SIZE; + for (i = 0; i < PMB_ENTRY_MAX; i++) { + struct pmb_entry *pmbe; + unsigned long vpn, ppn, flags; - ret = pmb_remap(P1SEG, 0x00000000, size, PMB_C); - BUG_ON(ret != size); + addr = PMB_DATA + (i << PMB_E_SHIFT); + data = ctrl_inl(addr); + if (!(data & PMB_V)) + continue; - ret = pmb_remap(P2SEG, 0x00000000, size, PMB_WT | PMB_UB); - BUG_ON(ret != size); + if (data & PMB_C) { +#if defined(CONFIG_CACHE_WRITETHROUGH) + data |= PMB_WT; +#elif defined(CONFIG_CACHE_WRITEBACK) + data &= ~PMB_WT; +#else + data &= ~(PMB_C | PMB_WT); +#endif + } + ctrl_outl(data, addr); - ctrl_outl(0, PMB_IRMCR); + ppn = data & PMB_PFN_MASK; + + flags = data & (PMB_C | PMB_WT | PMB_UB); + flags |= data & PMB_SZ_MASK; - /* PMB.SE and UB[7] */ - ctrl_outl(PASCR_SE | (1 << 7), PMB_PASCR); + addr = PMB_ADDR + (i << PMB_E_SHIFT); + data = ctrl_inl(addr); + + vpn = data & PMB_PFN_MASK; + + pmbe = pmb_alloc(vpn, ppn, flags, i); + WARN_ON(IS_ERR(pmbe)); + } + + ctrl_outl(0, PMB_IRMCR); /* Flush out the TLB */ i = ctrl_inl(MMUCR); -- cgit v1.2.3 From 4291b730cd0f0cf98a90d946b6cabbd804397350 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 18 Jan 2010 20:39:49 +0900 Subject: sh: Need IRQs enabled for init_fpu(). This tosses in a local_irq_enable()/disable() pair around the init_fpu() callsite in the FPU state restore exception handler. Fixes up a slab BUG triggered by making a slab cache allocation that can sleep whilst irqs_disabled(). This follows the behaviour undertaken by the x86 implementation. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/fpu.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/kernel/cpu/fpu.c b/arch/sh/kernel/cpu/fpu.c index c23e6727002a..f059ed62cf57 100644 --- a/arch/sh/kernel/cpu/fpu.c +++ b/arch/sh/kernel/cpu/fpu.c @@ -56,6 +56,7 @@ void fpu_state_restore(struct pt_regs *regs) } if (!tsk_used_math(tsk)) { + local_irq_enable(); /* * does a slab alloc which can sleep */ @@ -66,6 +67,7 @@ void fpu_state_restore(struct pt_regs *regs) do_group_exit(SIGKILL); return; } + local_irq_disable(); } grab_fpu(regs); -- cgit v1.2.3 From d9b9487af79955a8e8fcddc963f56697e020cfed Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 18 Jan 2010 21:08:32 +0900 Subject: sh: Handle early ioremaps through fixed mappings. This adds in a mem_init_done to work out when a standard ioremap() is possible, falling back to the fixmap based ioremap otherwise. Signed-off-by: Paul Mundt --- arch/sh/include/asm/processor.h | 3 +++ arch/sh/mm/init.c | 4 ++++ arch/sh/mm/ioremap_32.c | 12 +++++++++--- 3 files changed, 16 insertions(+), 3 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/processor.h b/arch/sh/include/asm/processor.h index 017e0c1807b2..a522e5d8f44f 100644 --- a/arch/sh/include/asm/processor.h +++ b/arch/sh/include/asm/processor.h @@ -101,6 +101,9 @@ struct seq_operations; extern struct pt_regs fake_swapper_regs; +/* 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; diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 30a9b530d456..fe578a286fdd 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -237,6 +237,8 @@ static void __init iommu_init(void) no_iommu_init(); } +unsigned int mem_init_done = 0; + void __init mem_init(void) { int codesize, datasize, initsize; @@ -287,6 +289,8 @@ void __init mem_init(void) /* Initialize the vDSO */ vsyscall_init(); + + mem_init_done = 1; } void free_initmem(void) diff --git a/arch/sh/mm/ioremap_32.c b/arch/sh/mm/ioremap_32.c index c80a8166fbb0..24f6ba6bff71 100644 --- a/arch/sh/mm/ioremap_32.c +++ b/arch/sh/mm/ioremap_32.c @@ -1,13 +1,13 @@ /* * arch/sh/mm/ioremap.c * + * (C) Copyright 1995 1996 Linus Torvalds + * (C) Copyright 2005 - 2010 Paul Mundt + * * Re-map IO memory to kernel address space so that we can access it. * This is needed for high PCI addresses that aren't mapped in the * 640k-1MB IO memory area on PC's * - * (C) Copyright 1995 1996 Linus Torvalds - * (C) Copyright 2005, 2006 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. @@ -64,6 +64,12 @@ void __iomem *__ioremap_caller(unsigned long phys_addr, unsigned long size, phys_addr &= PAGE_MASK; size = PAGE_ALIGN(last_addr+1) - phys_addr; + /* + * If we can't yet use the regular approach, go the fixmap route. + */ + if (!mem_init_done) + return ioremap_fixed(phys_addr, size, __pgprot(flags)); + /* * Ok, go for it.. */ -- cgit v1.2.3 From edf711b66f2a8a9629aa253ad8b3a5a03b5d7af5 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 18 Jan 2010 21:20:13 +0900 Subject: sh: Fixup the IOREMAP_FIXED=n build. Presently the fixed ioremap API is only defined when CONFIG_IOREMAP_FIXED is set. As we want to call in to it unconditionally, provide a stubbed out interface. Signed-off-by: Paul Mundt --- arch/sh/include/asm/io.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h index bee5965e0a82..9aa9438c66c3 100644 --- a/arch/sh/include/asm/io.h +++ b/arch/sh/include/asm/io.h @@ -241,6 +241,15 @@ void __iounmap(void __iomem *addr); extern void __iomem *ioremap_fixed(resource_size_t, unsigned long, pgprot_t); extern void iounmap_fixed(void __iomem *); extern void ioremap_fixed_init(void); +#else +static inline void __iomem * +ioremap_fixed(resource_size t phys_addr, unsigned long size, pgprot_t prot) +{ + BUG(); +} + +static inline void ioremap_fixed_init(void) { } +static inline void iounmap_fixed(void __iomem *addr) { } #endif static inline void __iomem * -- cgit v1.2.3 From 0b59e38ffaf7b201ff6afe5b736365d16848c7e3 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 18 Jan 2010 21:21:32 +0900 Subject: sh: Merge _32/_64 ioremap implementations. There is nothing of interest in the _64 version anymore, so the _32 one can be renamed and used unconditionally. Signed-off-by: Paul Mundt --- arch/sh/mm/Makefile | 2 +- arch/sh/mm/ioremap.c | 171 ++++++++++++++++++++++++++++++++++++++++++++++++ arch/sh/mm/ioremap_32.c | 171 ------------------------------------------------ arch/sh/mm/ioremap_64.c | 47 ------------- 4 files changed, 172 insertions(+), 219 deletions(-) create mode 100644 arch/sh/mm/ioremap.c delete mode 100644 arch/sh/mm/ioremap_32.c delete mode 100644 arch/sh/mm/ioremap_64.c (limited to 'arch/sh') diff --git a/arch/sh/mm/Makefile b/arch/sh/mm/Makefile index 89ba56c20ade..0027cdea2c20 100644 --- a/arch/sh/mm/Makefile +++ b/arch/sh/mm/Makefile @@ -15,7 +15,7 @@ obj-y += $(cacheops-y) mmu-y := nommu.o extable_32.o mmu-$(CONFIG_MMU) := extable_$(BITS).o fault_$(BITS).o \ - ioremap_$(BITS).o kmap.o pgtable.o tlbflush_$(BITS).o + ioremap.o kmap.o pgtable.o tlbflush_$(BITS).o obj-y += $(mmu-y) obj-$(CONFIG_DEBUG_FS) += asids-debugfs.o diff --git a/arch/sh/mm/ioremap.c b/arch/sh/mm/ioremap.c new file mode 100644 index 000000000000..24f6ba6bff71 --- /dev/null +++ b/arch/sh/mm/ioremap.c @@ -0,0 +1,171 @@ +/* + * arch/sh/mm/ioremap.c + * + * (C) Copyright 1995 1996 Linus Torvalds + * (C) Copyright 2005 - 2010 Paul Mundt + * + * Re-map IO memory to kernel address space so that we can access it. + * This is needed for high PCI addresses that aren't mapped in the + * 640k-1MB IO memory area on PC's + * + * 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. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Remap an arbitrary physical address space into the kernel virtual + * address space. Needed when the kernel wants to access high addresses + * directly. + * + * NOTE! We need to allow non-page-aligned mappings too: we will obviously + * have to convert them into an offset in a page-aligned mapping, but the + * caller shouldn't need to know that small detail. + */ +void __iomem *__ioremap_caller(unsigned long phys_addr, unsigned long size, + unsigned long flags, void *caller) +{ + struct vm_struct *area; + unsigned long offset, last_addr, addr, orig_addr; + pgprot_t pgprot; + + /* Don't allow wraparound or zero size */ + last_addr = phys_addr + size - 1; + if (!size || last_addr < phys_addr) + return NULL; + + /* + * If we're in the fixed PCI memory range, mapping through page + * tables is not only pointless, but also fundamentally broken. + * Just return the physical address instead. + * + * For boards that map a small PCI memory aperture somewhere in + * P1/P2 space, ioremap() will already do the right thing, + * and we'll never get this far. + */ + if (is_pci_memory_fixed_range(phys_addr, size)) + return (void __iomem *)phys_addr; + + /* + * Mappings have to be page-aligned + */ + offset = phys_addr & ~PAGE_MASK; + phys_addr &= PAGE_MASK; + size = PAGE_ALIGN(last_addr+1) - phys_addr; + + /* + * If we can't yet use the regular approach, go the fixmap route. + */ + if (!mem_init_done) + return ioremap_fixed(phys_addr, size, __pgprot(flags)); + + /* + * Ok, go for it.. + */ + area = get_vm_area_caller(size, VM_IOREMAP, caller); + if (!area) + return NULL; + area->phys_addr = phys_addr; + orig_addr = addr = (unsigned long)area->addr; + +#ifdef CONFIG_PMB + /* + * First try to remap through the PMB once a valid VMA has been + * established. Smaller allocations (or the rest of the size + * remaining after a PMB mapping due to the size not being + * perfectly aligned on a PMB size boundary) are then mapped + * through the UTLB using conventional page tables. + * + * PMB entries are all pre-faulted. + */ + if (unlikely(phys_addr >= P1SEG)) { + unsigned long mapped = pmb_remap(addr, phys_addr, size, flags); + + if (likely(mapped)) { + addr += mapped; + phys_addr += mapped; + size -= mapped; + } + } +#endif + + pgprot = __pgprot(pgprot_val(PAGE_KERNEL_NOCACHE) | flags); + if (likely(size)) + if (ioremap_page_range(addr, addr + size, phys_addr, pgprot)) { + vunmap((void *)orig_addr); + return NULL; + } + + return (void __iomem *)(offset + (char *)orig_addr); +} +EXPORT_SYMBOL(__ioremap_caller); + +/* + * Simple checks for non-translatable mappings. + */ +static inline int iomapping_nontranslatable(unsigned long offset) +{ +#ifdef CONFIG_29BIT + /* + * In 29-bit mode this includes the fixed P1/P2 areas, as well as + * parts of P3. + */ + if (PXSEG(offset) < P3SEG || offset >= P3_ADDR_MAX) + return 1; +#endif + + if (is_pci_memory_fixed_range(offset, 0)) + return 1; + + return 0; +} + +void __iounmap(void __iomem *addr) +{ + unsigned long vaddr = (unsigned long __force)addr; + struct vm_struct *p; + + /* + * Nothing to do if there is no translatable mapping. + */ + if (iomapping_nontranslatable(vaddr)) + return; + +#ifdef CONFIG_PMB + /* + * Purge any PMB entries that may have been established for this + * mapping, then proceed with conventional VMA teardown. + * + * XXX: Note that due to the way that remove_vm_area() does + * matching of the resultant VMA, we aren't able to fast-forward + * the address past the PMB space until the end of the VMA where + * the page tables reside. As such, unmap_vm_area() will be + * forced to linearly scan over the area until it finds the page + * tables where PTEs that need to be unmapped actually reside, + * which is far from optimal. Perhaps we need to use a separate + * VMA for the PMB mappings? + * -- PFM. + */ + pmb_unmap(vaddr); +#endif + + p = remove_vm_area((void *)(vaddr & PAGE_MASK)); + if (!p) { + printk(KERN_ERR "%s: bad address %p\n", __func__, addr); + return; + } + + kfree(p); +} +EXPORT_SYMBOL(__iounmap); diff --git a/arch/sh/mm/ioremap_32.c b/arch/sh/mm/ioremap_32.c deleted file mode 100644 index 24f6ba6bff71..000000000000 --- a/arch/sh/mm/ioremap_32.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * arch/sh/mm/ioremap.c - * - * (C) Copyright 1995 1996 Linus Torvalds - * (C) Copyright 2005 - 2010 Paul Mundt - * - * Re-map IO memory to kernel address space so that we can access it. - * This is needed for high PCI addresses that aren't mapped in the - * 640k-1MB IO memory area on PC's - * - * 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. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Remap an arbitrary physical address space into the kernel virtual - * address space. Needed when the kernel wants to access high addresses - * directly. - * - * NOTE! We need to allow non-page-aligned mappings too: we will obviously - * have to convert them into an offset in a page-aligned mapping, but the - * caller shouldn't need to know that small detail. - */ -void __iomem *__ioremap_caller(unsigned long phys_addr, unsigned long size, - unsigned long flags, void *caller) -{ - struct vm_struct *area; - unsigned long offset, last_addr, addr, orig_addr; - pgprot_t pgprot; - - /* Don't allow wraparound or zero size */ - last_addr = phys_addr + size - 1; - if (!size || last_addr < phys_addr) - return NULL; - - /* - * If we're in the fixed PCI memory range, mapping through page - * tables is not only pointless, but also fundamentally broken. - * Just return the physical address instead. - * - * For boards that map a small PCI memory aperture somewhere in - * P1/P2 space, ioremap() will already do the right thing, - * and we'll never get this far. - */ - if (is_pci_memory_fixed_range(phys_addr, size)) - return (void __iomem *)phys_addr; - - /* - * Mappings have to be page-aligned - */ - offset = phys_addr & ~PAGE_MASK; - phys_addr &= PAGE_MASK; - size = PAGE_ALIGN(last_addr+1) - phys_addr; - - /* - * If we can't yet use the regular approach, go the fixmap route. - */ - if (!mem_init_done) - return ioremap_fixed(phys_addr, size, __pgprot(flags)); - - /* - * Ok, go for it.. - */ - area = get_vm_area_caller(size, VM_IOREMAP, caller); - if (!area) - return NULL; - area->phys_addr = phys_addr; - orig_addr = addr = (unsigned long)area->addr; - -#ifdef CONFIG_PMB - /* - * First try to remap through the PMB once a valid VMA has been - * established. Smaller allocations (or the rest of the size - * remaining after a PMB mapping due to the size not being - * perfectly aligned on a PMB size boundary) are then mapped - * through the UTLB using conventional page tables. - * - * PMB entries are all pre-faulted. - */ - if (unlikely(phys_addr >= P1SEG)) { - unsigned long mapped = pmb_remap(addr, phys_addr, size, flags); - - if (likely(mapped)) { - addr += mapped; - phys_addr += mapped; - size -= mapped; - } - } -#endif - - pgprot = __pgprot(pgprot_val(PAGE_KERNEL_NOCACHE) | flags); - if (likely(size)) - if (ioremap_page_range(addr, addr + size, phys_addr, pgprot)) { - vunmap((void *)orig_addr); - return NULL; - } - - return (void __iomem *)(offset + (char *)orig_addr); -} -EXPORT_SYMBOL(__ioremap_caller); - -/* - * Simple checks for non-translatable mappings. - */ -static inline int iomapping_nontranslatable(unsigned long offset) -{ -#ifdef CONFIG_29BIT - /* - * In 29-bit mode this includes the fixed P1/P2 areas, as well as - * parts of P3. - */ - if (PXSEG(offset) < P3SEG || offset >= P3_ADDR_MAX) - return 1; -#endif - - if (is_pci_memory_fixed_range(offset, 0)) - return 1; - - return 0; -} - -void __iounmap(void __iomem *addr) -{ - unsigned long vaddr = (unsigned long __force)addr; - struct vm_struct *p; - - /* - * Nothing to do if there is no translatable mapping. - */ - if (iomapping_nontranslatable(vaddr)) - return; - -#ifdef CONFIG_PMB - /* - * Purge any PMB entries that may have been established for this - * mapping, then proceed with conventional VMA teardown. - * - * XXX: Note that due to the way that remove_vm_area() does - * matching of the resultant VMA, we aren't able to fast-forward - * the address past the PMB space until the end of the VMA where - * the page tables reside. As such, unmap_vm_area() will be - * forced to linearly scan over the area until it finds the page - * tables where PTEs that need to be unmapped actually reside, - * which is far from optimal. Perhaps we need to use a separate - * VMA for the PMB mappings? - * -- PFM. - */ - pmb_unmap(vaddr); -#endif - - p = remove_vm_area((void *)(vaddr & PAGE_MASK)); - if (!p) { - printk(KERN_ERR "%s: bad address %p\n", __func__, addr); - return; - } - - kfree(p); -} -EXPORT_SYMBOL(__iounmap); diff --git a/arch/sh/mm/ioremap_64.c b/arch/sh/mm/ioremap_64.c deleted file mode 100644 index fb0aa457c71e..000000000000 --- a/arch/sh/mm/ioremap_64.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * arch/sh/mm/ioremap_64.c - * - * Copyright (C) 2000, 2001 Paolo Alberelli - * Copyright (C) 2003 - 2007 Paul Mundt - * - * Mostly derived from arch/sh/mm/ioremap.c which, in turn is mostly - * derived from arch/i386/mm/ioremap.c . - * - * (C) Copyright 1995 1996 Linus Torvalds - * - * 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. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void __iomem *__ioremap_caller(unsigned long offset, unsigned long size, - unsigned long flags, void *caller) -{ - pgprot_t prot; - - prot = __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | - _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_SHARED | flags); - - return ioremap_fixed(offset, size, prot); -} -EXPORT_SYMBOL(__ioremap_caller); - -void __iounmap(void __iomem *virtual) -{ - iounmap_fixed(virtual); -} -EXPORT_SYMBOL(__iounmap); -- cgit v1.2.3 From 4f744affc345f8b158615e0cdd01d1f4985837c3 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 18 Jan 2010 21:30:29 +0900 Subject: sh: Make iounmap_fixed() return success/failure for iounmap() path. This converts iounmap_fixed() to return success/error if it handled the unmap request or not. At the same time, drop the __init label, as this can be called in to later. Signed-off-by: Paul Mundt --- arch/sh/include/asm/io.h | 5 +++-- arch/sh/mm/ioremap_fixed.c | 9 +++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h index 9aa9438c66c3..6a0dd8c1e0a9 100644 --- a/arch/sh/include/asm/io.h +++ b/arch/sh/include/asm/io.h @@ -22,6 +22,7 @@ * 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 #include #include #include @@ -239,7 +240,7 @@ void __iounmap(void __iomem *addr); #ifdef CONFIG_IOREMAP_FIXED extern void __iomem *ioremap_fixed(resource_size_t, unsigned long, pgprot_t); -extern void iounmap_fixed(void __iomem *); +extern int iounmap_fixed(void __iomem *); extern void ioremap_fixed_init(void); #else static inline void __iomem * @@ -249,7 +250,7 @@ ioremap_fixed(resource_size t phys_addr, unsigned long size, pgprot_t prot) } static inline void ioremap_fixed_init(void) { } -static inline void iounmap_fixed(void __iomem *addr) { } +static inline int iounmap_fixed(void __iomem *addr) { return -EINVAL; } #endif static inline void __iomem * diff --git a/arch/sh/mm/ioremap_fixed.c b/arch/sh/mm/ioremap_fixed.c index 3a9d3d88fe8d..425f6c6bf250 100644 --- a/arch/sh/mm/ioremap_fixed.c +++ b/arch/sh/mm/ioremap_fixed.c @@ -103,7 +103,7 @@ ioremap_fixed(resource_size_t phys_addr, unsigned long size, pgprot_t prot) return map->addr; } -void __init iounmap_fixed(void __iomem *addr) +int iounmap_fixed(void __iomem *addr) { enum fixed_addresses idx; unsigned long virt_addr; @@ -122,8 +122,11 @@ void __init iounmap_fixed(void __iomem *addr) } } + /* + * If we don't match, it's not for us. + */ if (slot < 0) - return; + return -EINVAL; virt_addr = (unsigned long)addr; @@ -141,4 +144,6 @@ void __init iounmap_fixed(void __iomem *addr) map->size = 0; map->addr = NULL; + + return 0; } -- cgit v1.2.3 From 12b6b01cb47dc3eefbef866592193661dad7afb9 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 18 Jan 2010 21:33:08 +0900 Subject: sh: Handle unmapping of fixed slots transparently in iounmap(). iounmap() should balance whatever is done by ioremap(). Presently ioremap() can do any of fixed mappings, PMB mappings, or page table mappings. Presently only the latter two are handled through the standard unmap path, so tie in the fixed unmapping, too. Signed-off-by: Paul Mundt --- arch/sh/mm/ioremap.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/mm/ioremap.c b/arch/sh/mm/ioremap.c index 24f6ba6bff71..e8b65f645aed 100644 --- a/arch/sh/mm/ioremap.c +++ b/arch/sh/mm/ioremap.c @@ -142,6 +142,12 @@ void __iounmap(void __iomem *addr) if (iomapping_nontranslatable(vaddr)) return; + /* + * There's no VMA if it's from an early fixed mapping. + */ + if (iounmap_fixed(addr) == 0) + return; + #ifdef CONFIG_PMB /* * Purge any PMB entries that may have been established for this -- cgit v1.2.3 From af1415314a4190b8ea06e53808d392fcf91555af Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 18 Jan 2010 21:45:00 +0900 Subject: sh: Flag __ioremap_caller() __init_refok. The mem_init_done test makes sure that this path is only entered in __init cases, so leaving ioremap_fixed() as __init and flagging the caller __init_refok is sufficient. Signed-off-by: Paul Mundt --- arch/sh/mm/ioremap.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/mm/ioremap.c b/arch/sh/mm/ioremap.c index e8b65f645aed..a130b2278e92 100644 --- a/arch/sh/mm/ioremap.c +++ b/arch/sh/mm/ioremap.c @@ -33,8 +33,9 @@ * have to convert them into an offset in a page-aligned mapping, but the * caller shouldn't need to know that small detail. */ -void __iomem *__ioremap_caller(unsigned long phys_addr, unsigned long size, - unsigned long flags, void *caller) +void __iomem * __init_refok +__ioremap_caller(unsigned long phys_addr, unsigned long size, + unsigned long flags, void *caller) { struct vm_struct *area; unsigned long offset, last_addr, addr, orig_addr; -- cgit v1.2.3 From d57d64080ddc0ff13fcffc898b6251074a482ba1 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 19 Jan 2010 13:34:38 +0900 Subject: sh: Prevent 64-bit pgprot clobbering across ioremap implementations. Presently 'flags' gets passed around a lot between the various ioremap helpers and implementations, which is only 32-bits. In the X2TLB case we use 64-bit pgprots which presently results in the upper 32bits being chopped off (which handily include our read/write/exec permissions). As such, we convert everything internally to using pgprot_t directly and simply convert over with pgprot_val() where needed. With this in place, transparent fixmap utilization for early ioremap works as expected. Signed-off-by: Paul Mundt --- arch/sh/boards/board-sh7785lcr.c | 6 ++--- arch/sh/boards/mach-landisk/setup.c | 2 +- arch/sh/boards/mach-lboxre2/setup.c | 2 +- arch/sh/boards/mach-sh03/setup.c | 2 +- arch/sh/include/asm/io.h | 53 ++++++++++++++++++++++--------------- arch/sh/mm/ioremap.c | 9 +++---- 6 files changed, 41 insertions(+), 33 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/boards/board-sh7785lcr.c b/arch/sh/boards/board-sh7785lcr.c index 511de38d2046..fe7e686c94ac 100644 --- a/arch/sh/boards/board-sh7785lcr.c +++ b/arch/sh/boards/board-sh7785lcr.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -332,15 +333,14 @@ static void __init sh7785lcr_setup(char **cmdline_p) pm_power_off = sh7785lcr_power_off; /* sm501 DRAM configuration */ - sm501_reg = ioremap_fixed(SM107_REG_ADDR, SM501_DRAM_CONTROL, - PAGE_KERNEL); + sm501_reg = ioremap_nocache(SM107_REG_ADDR, SM501_DRAM_CONTROL); if (!sm501_reg) { printk(KERN_ERR "%s: ioremap error.\n", __func__); return; } writel(0x000307c2, sm501_reg + SM501_DRAM_CONTROL); - iounmap_fixed(sm501_reg); + iounmap(sm501_reg); } /* Return the board specific boot mode pin configuration */ diff --git a/arch/sh/boards/mach-landisk/setup.c b/arch/sh/boards/mach-landisk/setup.c index db22ea2e6d49..59816355d199 100644 --- a/arch/sh/boards/mach-landisk/setup.c +++ b/arch/sh/boards/mach-landisk/setup.c @@ -63,7 +63,7 @@ static int __init landisk_devices_setup(void) /* open I/O area window */ paddrbase = virt_to_phys((void *)PA_AREA5_IO); prot = PAGE_KERNEL_PCC(1, _PAGE_PCC_IO16); - cf_ide_base = p3_ioremap(paddrbase, PAGE_SIZE, prot.pgprot); + cf_ide_base = p3_ioremap(paddrbase, PAGE_SIZE, prot); if (!cf_ide_base) { printk("allocate_cf_area : can't open CF I/O window!\n"); return -ENOMEM; diff --git a/arch/sh/boards/mach-lboxre2/setup.c b/arch/sh/boards/mach-lboxre2/setup.c index 2b0b5818e1e4..408dd5df7d45 100644 --- a/arch/sh/boards/mach-lboxre2/setup.c +++ b/arch/sh/boards/mach-lboxre2/setup.c @@ -57,7 +57,7 @@ static int __init lboxre2_devices_setup(void) paddrbase = virt_to_phys((void*)PA_AREA5_IO); psize = PAGE_SIZE; prot = PAGE_KERNEL_PCC( 1 , _PAGE_PCC_IO16); - cf0_io_base = (u32)p3_ioremap(paddrbase, psize, prot.pgprot); + cf0_io_base = (u32)p3_ioremap(paddrbase, psize, prot); if (!cf0_io_base) { printk(KERN_ERR "%s : can't open CF I/O window!\n" , __func__ ); return -ENOMEM; diff --git a/arch/sh/boards/mach-sh03/setup.c b/arch/sh/boards/mach-sh03/setup.c index 74cfb4b8b03d..f14ba0fa950b 100644 --- a/arch/sh/boards/mach-sh03/setup.c +++ b/arch/sh/boards/mach-sh03/setup.c @@ -82,7 +82,7 @@ static int __init sh03_devices_setup(void) /* open I/O area window */ paddrbase = virt_to_phys((void *)PA_AREA5_IO); prot = PAGE_KERNEL_PCC(1, _PAGE_PCC_IO16); - cf_ide_base = p3_ioremap(paddrbase, PAGE_SIZE, prot.pgprot); + cf_ide_base = p3_ioremap(paddrbase, PAGE_SIZE, prot); if (!cf_ide_base) { printk("allocate_cf_area : can't open CF I/O window!\n"); return -ENOMEM; diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h index 6a0dd8c1e0a9..13696dfccc16 100644 --- a/arch/sh/include/asm/io.h +++ b/arch/sh/include/asm/io.h @@ -235,7 +235,7 @@ unsigned long long poke_real_address_q(unsigned long long addr, */ #ifdef CONFIG_MMU void __iomem *__ioremap_caller(unsigned long offset, unsigned long size, - unsigned long flags, void *caller); + pgprot_t prot, void *caller); void __iounmap(void __iomem *addr); #ifdef CONFIG_IOREMAP_FIXED @@ -254,13 +254,13 @@ static inline int iounmap_fixed(void __iomem *addr) { return -EINVAL; } #endif static inline void __iomem * -__ioremap(unsigned long offset, unsigned long size, unsigned long flags) +__ioremap(unsigned long offset, unsigned long size, pgprot_t prot) { - return __ioremap_caller(offset, size, flags, __builtin_return_address(0)); + return __ioremap_caller(offset, size, prot, __builtin_return_address(0)); } static inline void __iomem * -__ioremap_29bit(unsigned long offset, unsigned long size, unsigned long flags) +__ioremap_29bit(unsigned long offset, unsigned long size, pgprot_t prot) { #ifdef CONFIG_29BIT unsigned long last_addr = offset + size - 1; @@ -272,7 +272,7 @@ __ioremap_29bit(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); @@ -287,7 +287,7 @@ __ioremap_29bit(unsigned long offset, unsigned long size, unsigned long flags) } static inline void __iomem * -__ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags) +__ioremap_mode(unsigned long offset, unsigned long size, pgprot_t prot) { void __iomem *ret; @@ -295,30 +295,39 @@ __ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags) if (ret) return ret; - ret = __ioremap_29bit(offset, size, flags); + ret = __ioremap_29bit(offset, size, prot); if (ret) return ret; - return __ioremap(offset, size, flags); + return __ioremap(offset, size, prot); } #else -#define __ioremap(offset, size, flags) ((void __iomem *)(offset)) -#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)) +static inline void __iomem * +ioremap(unsigned long offset, unsigned long size) +{ + return __ioremap_mode(offset, size, PAGE_KERNEL_NOCACHE); +} + +static inline void __iomem * +ioremap_cache(unsigned long offset, unsigned long size) +{ + return __ioremap_mode(offset, size, PAGE_KERNEL); +} + +static inline void __iomem * +ioremap_prot(resource_size_t offset, unsigned long size, unsigned long flags) +{ + return __ioremap_mode(offset, size, __pgprot(flags)); +} + +#define ioremap_nocache ioremap +#define p3_ioremap __ioremap +#define iounmap __iounmap #define maybebadio(port) \ printk(KERN_ERR "bad PC-like io %s:%u for port 0x%lx at 0x%08x\n", \ diff --git a/arch/sh/mm/ioremap.c b/arch/sh/mm/ioremap.c index a130b2278e92..85b420d00622 100644 --- a/arch/sh/mm/ioremap.c +++ b/arch/sh/mm/ioremap.c @@ -35,11 +35,10 @@ */ void __iomem * __init_refok __ioremap_caller(unsigned long phys_addr, unsigned long size, - unsigned long flags, void *caller) + pgprot_t pgprot, void *caller) { struct vm_struct *area; unsigned long offset, last_addr, addr, orig_addr; - pgprot_t pgprot; /* Don't allow wraparound or zero size */ last_addr = phys_addr + size - 1; @@ -69,7 +68,7 @@ __ioremap_caller(unsigned long phys_addr, unsigned long size, * If we can't yet use the regular approach, go the fixmap route. */ if (!mem_init_done) - return ioremap_fixed(phys_addr, size, __pgprot(flags)); + return ioremap_fixed(phys_addr, size, pgprot); /* * Ok, go for it.. @@ -91,8 +90,9 @@ __ioremap_caller(unsigned long phys_addr, unsigned long size, * PMB entries are all pre-faulted. */ if (unlikely(phys_addr >= P1SEG)) { - unsigned long mapped = pmb_remap(addr, phys_addr, size, flags); + unsigned long mapped; + mapped = pmb_remap(addr, phys_addr, size, pgprot_val(pgprot)); if (likely(mapped)) { addr += mapped; phys_addr += mapped; @@ -101,7 +101,6 @@ __ioremap_caller(unsigned long phys_addr, unsigned long size, } #endif - pgprot = __pgprot(pgprot_val(PAGE_KERNEL_NOCACHE) | flags); if (likely(size)) if (ioremap_page_range(addr, addr + size, phys_addr, pgprot)) { vunmap((void *)orig_addr); -- cgit v1.2.3 From acf2c9685fb8295cb62a623d7358a1cfde8b07ea Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 19 Jan 2010 13:49:19 +0900 Subject: sh: Kill off duplicate address alignment in ioremap_fixed(). This is already taken care of in the top-level ioremap, and now that no one should be calling ioremap_fixed() directly we can simply throw the mapping displacement in as an additional argument. Signed-off-by: Paul Mundt --- arch/sh/include/asm/io.h | 6 ++++-- arch/sh/mm/ioremap.c | 2 +- arch/sh/mm/ioremap_fixed.c | 22 +++------------------- 3 files changed, 8 insertions(+), 22 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h index 13696dfccc16..70269813cef1 100644 --- a/arch/sh/include/asm/io.h +++ b/arch/sh/include/asm/io.h @@ -239,12 +239,14 @@ void __iomem *__ioremap_caller(unsigned long offset, unsigned long size, void __iounmap(void __iomem *addr); #ifdef CONFIG_IOREMAP_FIXED -extern void __iomem *ioremap_fixed(resource_size_t, unsigned long, pgprot_t); +extern void __iomem *ioremap_fixed(resource_size_t, unsigned long, + unsigned long, pgprot_t); extern int iounmap_fixed(void __iomem *); extern void ioremap_fixed_init(void); #else static inline void __iomem * -ioremap_fixed(resource_size t phys_addr, unsigned long size, pgprot_t prot) +ioremap_fixed(resource_size t phys_addr, unsigned long offset, + unsigned long size, pgprot_t prot) { BUG(); } diff --git a/arch/sh/mm/ioremap.c b/arch/sh/mm/ioremap.c index 85b420d00622..bb03308e8408 100644 --- a/arch/sh/mm/ioremap.c +++ b/arch/sh/mm/ioremap.c @@ -68,7 +68,7 @@ __ioremap_caller(unsigned long phys_addr, unsigned long size, * If we can't yet use the regular approach, go the fixmap route. */ if (!mem_init_done) - return ioremap_fixed(phys_addr, size, pgprot); + return ioremap_fixed(phys_addr, offset, size, pgprot); /* * Ok, go for it.. diff --git a/arch/sh/mm/ioremap_fixed.c b/arch/sh/mm/ioremap_fixed.c index 425f6c6bf250..551b513e8fce 100644 --- a/arch/sh/mm/ioremap_fixed.c +++ b/arch/sh/mm/ioremap_fixed.c @@ -45,12 +45,11 @@ void __init ioremap_fixed_init(void) } void __init __iomem * -ioremap_fixed(resource_size_t phys_addr, unsigned long size, pgprot_t prot) +ioremap_fixed(resource_size_t phys_addr, unsigned long offset, + unsigned long size, pgprot_t prot) { enum fixed_addresses idx0, idx; - resource_size_t last_addr; struct ioremap_map *map; - unsigned long offset; unsigned int nrpages; int i, slot; @@ -67,18 +66,6 @@ ioremap_fixed(resource_size_t phys_addr, unsigned long size, pgprot_t prot) if (slot < 0) return NULL; - /* Don't allow wraparound or zero size */ - last_addr = phys_addr + size - 1; - if (!size || last_addr < phys_addr) - return NULL; - - /* - * Fixmap mappings have to be page-aligned - */ - offset = phys_addr & ~PAGE_MASK; - phys_addr &= PAGE_MASK; - size = PAGE_ALIGN(last_addr + 1) - phys_addr; - /* * Mappings have to fit in the FIX_IOREMAP area. */ @@ -111,7 +98,6 @@ int iounmap_fixed(void __iomem *addr) unsigned long offset; unsigned int nrpages; int i, slot; - pgprot_t prot; slot = -1; for (i = 0; i < FIX_N_IOREMAPS; i++) { @@ -133,11 +119,9 @@ int iounmap_fixed(void __iomem *addr) offset = virt_addr & ~PAGE_MASK; nrpages = PAGE_ALIGN(offset + map->size - 1) >> PAGE_SHIFT; - pgprot_val(prot) = _PAGE_WIRED; - idx = FIX_IOREMAP_BEGIN + slot + nrpages; while (nrpages > 0) { - __clear_fixmap(idx, prot); + __clear_fixmap(idx, __pgprot(_PAGE_WIRED)); --idx; --nrpages; } -- cgit v1.2.3 From f33609344acfdde1c1acedf6de3efe6b80af93a6 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 19 Jan 2010 13:55:41 +0900 Subject: sh: Convert p3_ioremap() users to ioremap_prot(). This kills off the ancient p3_ioremap(), converting over to the more generic ioremap_prot() instead. Signed-off-by: Paul Mundt --- arch/sh/boards/mach-landisk/setup.c | 2 +- arch/sh/boards/mach-lboxre2/setup.c | 4 ++-- arch/sh/boards/mach-sh03/setup.c | 2 +- arch/sh/include/asm/io.h | 1 - 4 files changed, 4 insertions(+), 5 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/boards/mach-landisk/setup.c b/arch/sh/boards/mach-landisk/setup.c index 59816355d199..2d09d4d34f87 100644 --- a/arch/sh/boards/mach-landisk/setup.c +++ b/arch/sh/boards/mach-landisk/setup.c @@ -63,7 +63,7 @@ static int __init landisk_devices_setup(void) /* open I/O area window */ paddrbase = virt_to_phys((void *)PA_AREA5_IO); prot = PAGE_KERNEL_PCC(1, _PAGE_PCC_IO16); - cf_ide_base = p3_ioremap(paddrbase, PAGE_SIZE, prot); + cf_ide_base = ioremap_prot(paddrbase, PAGE_SIZE, pgprot_val(prot)); if (!cf_ide_base) { printk("allocate_cf_area : can't open CF I/O window!\n"); return -ENOMEM; diff --git a/arch/sh/boards/mach-lboxre2/setup.c b/arch/sh/boards/mach-lboxre2/setup.c index 408dd5df7d45..79b4e0d77b71 100644 --- a/arch/sh/boards/mach-lboxre2/setup.c +++ b/arch/sh/boards/mach-lboxre2/setup.c @@ -56,8 +56,8 @@ static int __init lboxre2_devices_setup(void) /* open I/O area window */ paddrbase = virt_to_phys((void*)PA_AREA5_IO); psize = PAGE_SIZE; - prot = PAGE_KERNEL_PCC( 1 , _PAGE_PCC_IO16); - cf0_io_base = (u32)p3_ioremap(paddrbase, psize, prot); + prot = PAGE_KERNEL_PCC(1, _PAGE_PCC_IO16); + cf0_io_base = (u32)ioremap_prot(paddrbase, psize, pgprot_val(prot)); if (!cf0_io_base) { printk(KERN_ERR "%s : can't open CF I/O window!\n" , __func__ ); return -ENOMEM; diff --git a/arch/sh/boards/mach-sh03/setup.c b/arch/sh/boards/mach-sh03/setup.c index f14ba0fa950b..af4a0c012a96 100644 --- a/arch/sh/boards/mach-sh03/setup.c +++ b/arch/sh/boards/mach-sh03/setup.c @@ -82,7 +82,7 @@ static int __init sh03_devices_setup(void) /* open I/O area window */ paddrbase = virt_to_phys((void *)PA_AREA5_IO); prot = PAGE_KERNEL_PCC(1, _PAGE_PCC_IO16); - cf_ide_base = p3_ioremap(paddrbase, PAGE_SIZE, prot); + cf_ide_base = ioremap_prot(paddrbase, PAGE_SIZE, pgprot_val(prot)); if (!cf_ide_base) { printk("allocate_cf_area : can't open CF I/O window!\n"); return -ENOMEM; diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h index 70269813cef1..c32a55601d01 100644 --- a/arch/sh/include/asm/io.h +++ b/arch/sh/include/asm/io.h @@ -328,7 +328,6 @@ ioremap_prot(resource_size_t offset, unsigned long size, unsigned long flags) } #define ioremap_nocache ioremap -#define p3_ioremap __ioremap #define iounmap __iounmap #define maybebadio(port) \ -- cgit v1.2.3 From 6d63e73d520b690e4378cef3003eb5f01f7d128c Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 19 Jan 2010 14:00:14 +0900 Subject: sh: Limit ioremap_prot() to 32bit pgprot parts. Presently ioremap_prot() uses an unsigned long to pass the pgprot value around. This results in the upper half of the pgprot being chomped when using 64-bit pgprots on a 32-bit ABI (X2TLB and SH-5). As the only users of ioremap_prot() are presently legacy parts, this doesn't cause too much of an issue. In the future when the interface is converted to use pgprot_t directly this can be re-enabled for the other parts, too. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 2 +- arch/sh/include/asm/io.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'arch/sh') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 5ac0115c9e20..8d0eabbf7460 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -13,7 +13,6 @@ config SUPERH select HAVE_LMB select HAVE_OPROFILE select HAVE_GENERIC_DMA_COHERENT - select HAVE_IOREMAP_PROT if MMU select HAVE_ARCH_TRACEHOOK select HAVE_DMA_API_DEBUG select HAVE_DMA_ATTRS @@ -36,6 +35,7 @@ config SUPERH32 def_bool ARCH = "sh" select HAVE_KPROBES select HAVE_KRETPROBES + select HAVE_IOREMAP_PROT if MMU && !X2TLB select HAVE_FUNCTION_TRACER select HAVE_FTRACE_MCOUNT_RECORD select HAVE_DYNAMIC_FTRACE diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h index c32a55601d01..4bad72a1b39e 100644 --- a/arch/sh/include/asm/io.h +++ b/arch/sh/include/asm/io.h @@ -321,11 +321,13 @@ ioremap_cache(unsigned long offset, unsigned long size) return __ioremap_mode(offset, size, PAGE_KERNEL); } +#ifdef CONFIG_HAVE_IOREMAP_PROT static inline void __iomem * ioremap_prot(resource_size_t offset, unsigned long size, unsigned long flags) { return __ioremap_mode(offset, size, __pgprot(flags)); } +#endif #define ioremap_nocache ioremap #define iounmap __iounmap -- cgit v1.2.3 From 046581f9623b53f551a93864bb74e15ad2514f0c Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 19 Jan 2010 14:23:39 +0900 Subject: sh: Provide a dummy _PAGE_WIRED flag for non-X2TLB parts. This provides a dummy value for legacy parts which permits the entry wiring to be open-coded. The compiler takes care of optimizing the entry wiring away in these cases. Signed-off-by: Paul Mundt --- arch/sh/include/asm/pgtable_32.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/pgtable_32.h b/arch/sh/include/asm/pgtable_32.h index c573d45f1286..e172d696e52b 100644 --- a/arch/sh/include/asm/pgtable_32.h +++ b/arch/sh/include/asm/pgtable_32.h @@ -143,12 +143,14 @@ static inline unsigned long copy_ptea_attributes(unsigned long x) # 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 /* @@ -166,8 +168,6 @@ static inline unsigned long copy_ptea_attributes(unsigned long x) (PTE_MASK | _PAGE_ACCESSED | _PAGE_CACHABLE | \ _PAGE_DIRTY | _PAGE_SPECIAL) -#define _PAGE_WIRED (_PAGE_EXT(_PAGE_EXT_WIRED)) - #ifndef __ASSEMBLY__ #if defined(CONFIG_X2TLB) /* SH-X2 TLB */ -- cgit v1.2.3 From bb29c677b366fdf4f6522cd82228a32567aa98c7 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 19 Jan 2010 15:20:35 +0900 Subject: sh: Split out MMUCR.URB based entry wiring in to shared helper. Presently this is duplicated between tlb-sh4 and tlb-pteaex. Split the helpers out in to a generic tlb-urb that can be used by any parts equipped with MMUCR.URB. At the same time, move the SH-5 code out-of-line, as we require single global state for DTLB entry wiring. Signed-off-by: Paul Mundt --- arch/sh/include/asm/tlb.h | 44 ++----------------------- arch/sh/mm/Makefile | 4 +-- arch/sh/mm/tlb-pteaex.c | 66 -------------------------------------- arch/sh/mm/tlb-sh4.c | 66 -------------------------------------- arch/sh/mm/tlb-sh5.c | 39 +++++++++++++++++++++++ arch/sh/mm/tlb-urb.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 124 insertions(+), 176 deletions(-) create mode 100644 arch/sh/mm/tlb-urb.c (limited to 'arch/sh') diff --git a/arch/sh/include/asm/tlb.h b/arch/sh/include/asm/tlb.h index dfc8fcd8ee50..75abb38dffd5 100644 --- a/arch/sh/include/asm/tlb.h +++ b/arch/sh/include/asm/tlb.h @@ -98,49 +98,9 @@ tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vma) #define tlb_migrate_finish(mm) do { } while (0) -#ifdef CONFIG_CPU_SH4 +#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); -#elif defined(CONFIG_SUPERH64) -static int dtlb_entry; -static unsigned long long dtlb_entries[64]; - -static inline void tlb_wire_entry(struct vm_area_struct *vma, - unsigned long addr, pte_t pte) -{ - unsigned long long entry; - unsigned long paddr, flags; - - BUG_ON(dtlb_entry == 64); - - local_irq_save(flags); - - entry = sh64_get_wired_dtlb_entry(); - dtlb_entries[dtlb_entry++] = entry; - - paddr = pte_val(pte) & _PAGE_FLAGS_HARDWARE_MASK; - paddr &= ~PAGE_MASK; - - sh64_setup_tlb_slot(entry, addr, get_asid(), paddr); - - local_irq_restore(flags); -} - -static inline void tlb_unwire_entry(void) -{ - unsigned long long entry; - unsigned long flags; - - BUG_ON(!dtlb_entry); - - local_irq_save(flags); - entry = dtlb_entries[dtlb_entry--]; - - sh64_teardown_tlb_slot(entry); - sh64_put_wired_dtlb_entry(entry); - - local_irq_restore(flags); -} #else static inline void tlb_wire_entry(struct vm_area_struct *vma , unsigned long addr, pte_t pte) @@ -152,7 +112,7 @@ static inline void tlb_unwire_entry(void) { BUG(); } -#endif /* CONFIG_CPU_SH4 */ +#endif #else /* CONFIG_MMU */ diff --git a/arch/sh/mm/Makefile b/arch/sh/mm/Makefile index 0027cdea2c20..de714cbd961a 100644 --- a/arch/sh/mm/Makefile +++ b/arch/sh/mm/Makefile @@ -26,9 +26,9 @@ endif ifdef CONFIG_MMU tlb-$(CONFIG_CPU_SH3) := tlb-sh3.o -tlb-$(CONFIG_CPU_SH4) := tlb-sh4.o +tlb-$(CONFIG_CPU_SH4) := tlb-sh4.o tlb-urb.o tlb-$(CONFIG_CPU_SH5) := tlb-sh5.o -tlb-$(CONFIG_CPU_HAS_PTEAEX) := tlb-pteaex.o +tlb-$(CONFIG_CPU_HAS_PTEAEX) := tlb-pteaex.o tlb-urb.o obj-y += $(tlb-y) endif diff --git a/arch/sh/mm/tlb-pteaex.c b/arch/sh/mm/tlb-pteaex.c index 88c8bb05e16d..409b7c2b4b9d 100644 --- a/arch/sh/mm/tlb-pteaex.c +++ b/arch/sh/mm/tlb-pteaex.c @@ -76,69 +76,3 @@ void __uses_jump_to_uncached local_flush_tlb_one(unsigned long asid, __raw_writel(asid, MMU_UTLB_ADDRESS_ARRAY2 | MMU_PAGE_ASSOC_BIT); back_to_cached(); } - -/* - * Load the entry for 'addr' into the TLB and wire the entry. - */ -void tlb_wire_entry(struct vm_area_struct *vma, unsigned long addr, pte_t pte) -{ - unsigned long status, flags; - int urb; - - local_irq_save(flags); - - /* Load the entry into the TLB */ - __update_tlb(vma, addr, pte); - - /* ... and wire it up. */ - status = ctrl_inl(MMUCR); - urb = (status & MMUCR_URB) >> MMUCR_URB_SHIFT; - status &= ~MMUCR_URB; - - /* - * Make sure we're not trying to wire the last TLB entry slot. - */ - BUG_ON(!--urb); - - urb = urb % MMUCR_URB_NENTRIES; - - status |= (urb << MMUCR_URB_SHIFT); - ctrl_outl(status, MMUCR); - ctrl_barrier(); - - local_irq_restore(flags); -} - -/* - * Unwire the last wired TLB entry. - * - * It should also be noted that it is not possible to wire and unwire - * TLB entries in an arbitrary order. If you wire TLB entry N, followed - * by entry N+1, you must unwire entry N+1 first, then entry N. In this - * respect, it works like a stack or LIFO queue. - */ -void tlb_unwire_entry(void) -{ - unsigned long status, flags; - int urb; - - local_irq_save(flags); - - status = ctrl_inl(MMUCR); - urb = (status & MMUCR_URB) >> MMUCR_URB_SHIFT; - status &= ~MMUCR_URB; - - /* - * Make sure we're not trying to unwire a TLB entry when none - * have been wired. - */ - BUG_ON(urb++ == MMUCR_URB_NENTRIES); - - urb = urb % MMUCR_URB_NENTRIES; - - status |= (urb << MMUCR_URB_SHIFT); - ctrl_outl(status, MMUCR); - ctrl_barrier(); - - local_irq_restore(flags); -} diff --git a/arch/sh/mm/tlb-sh4.c b/arch/sh/mm/tlb-sh4.c index 4c6234743318..8cf550e2570f 100644 --- a/arch/sh/mm/tlb-sh4.c +++ b/arch/sh/mm/tlb-sh4.c @@ -81,69 +81,3 @@ void __uses_jump_to_uncached local_flush_tlb_one(unsigned long asid, ctrl_outl(data, addr); back_to_cached(); } - -/* - * Load the entry for 'addr' into the TLB and wire the entry. - */ -void tlb_wire_entry(struct vm_area_struct *vma, unsigned long addr, pte_t pte) -{ - unsigned long status, flags; - int urb; - - local_irq_save(flags); - - /* Load the entry into the TLB */ - __update_tlb(vma, addr, pte); - - /* ... and wire it up. */ - status = ctrl_inl(MMUCR); - urb = (status & MMUCR_URB) >> MMUCR_URB_SHIFT; - status &= ~MMUCR_URB; - - /* - * Make sure we're not trying to wire the last TLB entry slot. - */ - BUG_ON(!--urb); - - urb = urb % MMUCR_URB_NENTRIES; - - status |= (urb << MMUCR_URB_SHIFT); - ctrl_outl(status, MMUCR); - ctrl_barrier(); - - local_irq_restore(flags); -} - -/* - * Unwire the last wired TLB entry. - * - * It should also be noted that it is not possible to wire and unwire - * TLB entries in an arbitrary order. If you wire TLB entry N, followed - * by entry N+1, you must unwire entry N+1 first, then entry N. In this - * respect, it works like a stack or LIFO queue. - */ -void tlb_unwire_entry(void) -{ - unsigned long status, flags; - int urb; - - local_irq_save(flags); - - status = ctrl_inl(MMUCR); - urb = (status & MMUCR_URB) >> MMUCR_URB_SHIFT; - status &= ~MMUCR_URB; - - /* - * Make sure we're not trying to unwire a TLB entry when none - * have been wired. - */ - BUG_ON(urb++ == MMUCR_URB_NENTRIES); - - urb = urb % MMUCR_URB_NENTRIES; - - status |= (urb << MMUCR_URB_SHIFT); - ctrl_outl(status, MMUCR); - ctrl_barrier(); - - local_irq_restore(flags); -} diff --git a/arch/sh/mm/tlb-sh5.c b/arch/sh/mm/tlb-sh5.c index fdb64e41ec50..f27dbe1c1599 100644 --- a/arch/sh/mm/tlb-sh5.c +++ b/arch/sh/mm/tlb-sh5.c @@ -143,3 +143,42 @@ void sh64_setup_tlb_slot(unsigned long long config_addr, unsigned long eaddr, */ void sh64_teardown_tlb_slot(unsigned long long config_addr) __attribute__ ((alias("__flush_tlb_slot"))); + +static int dtlb_entry; +static unsigned long long dtlb_entries[64]; + +void tlb_wire_entry(struct vm_area_struct *vma, unsigned long addr, pte_t pte) +{ + unsigned long long entry; + unsigned long paddr, flags; + + BUG_ON(dtlb_entry == ARRAY_SIZE(dtlb_entries)); + + local_irq_save(flags); + + entry = sh64_get_wired_dtlb_entry(); + dtlb_entries[dtlb_entry++] = entry; + + paddr = pte_val(pte) & _PAGE_FLAGS_HARDWARE_MASK; + paddr &= ~PAGE_MASK; + + sh64_setup_tlb_slot(entry, addr, get_asid(), paddr); + + local_irq_restore(flags); +} + +void tlb_unwire_entry(void) +{ + unsigned long long entry; + unsigned long flags; + + BUG_ON(!dtlb_entry); + + local_irq_save(flags); + entry = dtlb_entries[dtlb_entry--]; + + sh64_teardown_tlb_slot(entry); + sh64_put_wired_dtlb_entry(entry); + + local_irq_restore(flags); +} diff --git a/arch/sh/mm/tlb-urb.c b/arch/sh/mm/tlb-urb.c new file mode 100644 index 000000000000..bb5b9098956d --- /dev/null +++ b/arch/sh/mm/tlb-urb.c @@ -0,0 +1,81 @@ +/* + * arch/sh/mm/tlb-urb.c + * + * TLB entry wiring helpers for URB-equipped parts. + * + * Copyright (C) 2010 Matt Fleming + * + * 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. + */ +#include +#include +#include +#include + +/* + * Load the entry for 'addr' into the TLB and wire the entry. + */ +void tlb_wire_entry(struct vm_area_struct *vma, unsigned long addr, pte_t pte) +{ + unsigned long status, flags; + int urb; + + local_irq_save(flags); + + /* Load the entry into the TLB */ + __update_tlb(vma, addr, pte); + + /* ... and wire it up. */ + status = __raw_readl(MMUCR); + urb = (status & MMUCR_URB) >> MMUCR_URB_SHIFT; + status &= ~MMUCR_URB; + + /* + * Make sure we're not trying to wire the last TLB entry slot. + */ + BUG_ON(!--urb); + + urb = urb % MMUCR_URB_NENTRIES; + + status |= (urb << MMUCR_URB_SHIFT); + __raw_writel(status, MMUCR); + ctrl_barrier(); + + local_irq_restore(flags); +} + +/* + * Unwire the last wired TLB entry. + * + * It should also be noted that it is not possible to wire and unwire + * TLB entries in an arbitrary order. If you wire TLB entry N, followed + * by entry N+1, you must unwire entry N+1 first, then entry N. In this + * respect, it works like a stack or LIFO queue. + */ +void tlb_unwire_entry(void) +{ + unsigned long status, flags; + int urb; + + local_irq_save(flags); + + status = __raw_readl(MMUCR); + urb = (status & MMUCR_URB) >> MMUCR_URB_SHIFT; + status &= ~MMUCR_URB; + + /* + * Make sure we're not trying to unwire a TLB entry when none + * have been wired. + */ + BUG_ON(urb++ == MMUCR_URB_NENTRIES); + + urb = urb % MMUCR_URB_NENTRIES; + + status |= (urb << MMUCR_URB_SHIFT); + __raw_writel(status, MMUCR); + ctrl_barrier(); + + local_irq_restore(flags); +} -- cgit v1.2.3 From cb6d04468d16de5a6161167ec7e76a43be540a80 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 19 Jan 2010 15:22:52 +0900 Subject: sh: Kill off now bogus fixmap/page wiring documentation. The plans for _PAGE_WIRED were detailed in a comment with the fixmap code, but as it's now all taken care of, we no longer have any reason for keeping it around, particularly since it's no longer accurate. Kill it off. Signed-off-by: Paul Mundt --- arch/sh/mm/init.c | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index fe578a286fdd..32ebd1592e63 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -98,21 +98,6 @@ static void clear_pte_phys(unsigned long addr, pgprot_t prot) local_flush_tlb_one(get_asid(), addr); } -/* - * As a performance optimization, other platforms preserve the fixmap mapping - * across a context switch, we don't presently do this, but this could be done - * in a similar fashion as to the wired TLB interface that sh64 uses (by way - * of the memory mapped UTLB configuration) -- this unfortunately forces us to - * give up a TLB entry for each mapping we want to preserve. While this may be - * viable for a small number of fixmaps, it's not particularly useful for - * everything and needs to be carefully evaluated. (ie, we may want this for - * the vsyscall page). - * - * XXX: Perhaps add a _PAGE_WIRED flag or something similar that we can pass - * in at __set_fixmap() time to determine the appropriate behavior to follow. - * - * -- PFM. - */ void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot) { unsigned long address = __fix_to_virt(idx); -- cgit v1.2.3 From 3ef2932b8c1fc89408ef1fd4b1e1c2caabc7f07d Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 19 Jan 2010 15:40:03 +0900 Subject: sh64: Fix up the build for the thread_xstate changes. This updates the sh64 processor info with the sh32 changes in order to tie in to the generic task_xstate management code. Signed-off-by: Paul Mundt --- arch/sh/include/asm/processor.h | 6 ++++++ arch/sh/include/asm/processor_32.h | 4 ---- arch/sh/include/asm/processor_64.h | 18 +++++++++--------- arch/sh/kernel/cpu/sh5/fpu.c | 12 ++++++------ arch/sh/kernel/process_64.c | 2 +- arch/sh/kernel/ptrace_64.c | 10 +++++----- arch/sh/kernel/signal_64.c | 4 ++-- arch/sh/kernel/traps_64.c | 28 ++++++++++++++-------------- 8 files changed, 43 insertions(+), 41 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/processor.h b/arch/sh/include/asm/processor.h index a522e5d8f44f..87a8d1ef64e4 100644 --- a/arch/sh/include/asm/processor.h +++ b/arch/sh/include/asm/processor.h @@ -98,9 +98,15 @@ extern struct sh_cpuinfo cpu_data[]; /* Forward decl */ struct seq_operations; +struct task_struct; extern struct pt_regs fake_swapper_regs; +/* 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/init.c */ extern unsigned int mem_init_done; diff --git a/arch/sh/include/asm/processor_32.h b/arch/sh/include/asm/processor_32.h index 5fd83125fb89..488f0a906a41 100644 --- a/arch/sh/include/asm/processor_32.h +++ b/arch/sh/include/asm/processor_32.h @@ -96,10 +96,6 @@ union thread_xstate { struct sh_fpu_soft_struct softfpu; }; -extern unsigned int xstate_size; -extern void free_thread_xstate(struct task_struct *); -extern struct kmem_cache *task_xstate_cachep; - struct thread_struct { /* Saved registers when thread is descheduled */ unsigned long sp; diff --git a/arch/sh/include/asm/processor_64.h b/arch/sh/include/asm/processor_64.h index 5727d31b0ccf..7b1560f03d14 100644 --- a/arch/sh/include/asm/processor_64.h +++ b/arch/sh/include/asm/processor_64.h @@ -87,20 +87,21 @@ 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; }; @@ -122,7 +123,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 +138,6 @@ struct thread_struct { .trap_no = 0, \ .error_code = 0, \ .address = 0, \ - .fpu = { { { 0, } }, } \ } /* diff --git a/arch/sh/kernel/cpu/sh5/fpu.c b/arch/sh/kernel/cpu/sh5/fpu.c index 4648ccee6c4d..92df285fbe4b 100644 --- a/arch/sh/kernel/cpu/sh5/fpu.c +++ b/arch/sh/kernel/cpu/sh5/fpu.c @@ -27,8 +27,8 @@ #define sNAN64 0xFFFFFFFFFFFFFFFFULL #define sNAN32 0xFFFFFFFFUL -static union sh_fpu_union init_fpuregs = { - .hard = { +static union thread_xstate init_fpuregs = { + .hardfpu = { .fp_regs = { [0 ... 63] = sNAN32 }, .fpscr = FPSCR_INIT } @@ -72,7 +72,7 @@ void save_fpu(struct task_struct *tsk) "fgetscr fr63\n\t" "fst.s %0, (32*8), fr63\n\t" : /* no output */ - : "r" (&tsk->thread.fpu.hard) + : "r" (&tsk->thread.xstate->hardfpu) : "memory"); } @@ -121,7 +121,7 @@ fpload(struct sh_fpu_hard_struct *fpregs) void fpinit(struct sh_fpu_hard_struct *fpregs) { - *fpregs = init_fpuregs.hard; + *fpregs = init_fpuregs.hardfpu; } asmlinkage void @@ -157,10 +157,10 @@ do_fpu_state_restore(unsigned long ex, struct pt_regs *regs) last_task_used_math = current; if (used_math()) { - fpload(¤t->thread.fpu.hard); + fpload(¤t->thread.xstate->hardfpu); } else { /* First time FPU user. */ - fpload(&init_fpuregs.hard); + fpload(&init_fpuregs.hardfpu); set_used_math(); } disable_fpu(); diff --git a/arch/sh/kernel/process_64.c b/arch/sh/kernel/process_64.c index 31f80c61b031..c9554a70bd0e 100644 --- a/arch/sh/kernel/process_64.c +++ b/arch/sh/kernel/process_64.c @@ -410,7 +410,7 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) regs->sr |= SR_FD; } - memcpy(fpu, &tsk->thread.fpu.hard, sizeof(*fpu)); + memcpy(fpu, &tsk->thread.xstate->hardfpu, sizeof(*fpu)); } return fpvalid; diff --git a/arch/sh/kernel/ptrace_64.c b/arch/sh/kernel/ptrace_64.c index 873ebdc4f98e..67fbcee89e7e 100644 --- a/arch/sh/kernel/ptrace_64.c +++ b/arch/sh/kernel/ptrace_64.c @@ -88,7 +88,7 @@ get_fpu_long(struct task_struct *task, unsigned long addr) regs->sr |= SR_FD; } - tmp = ((long *)&task->thread.fpu)[addr / sizeof(unsigned long)]; + tmp = ((long *)task->thread.xstate)[addr / sizeof(unsigned long)]; return tmp; } @@ -114,7 +114,7 @@ put_fpu_long(struct task_struct *task, unsigned long addr, unsigned long data) regs = (struct pt_regs*)((unsigned char *)task + THREAD_SIZE) - 1; if (!tsk_used_math(task)) { - fpinit(&task->thread.fpu.hard); + fpinit(&task->thread.xstate->hardfpu); set_stopped_child_used_math(task); } else if (last_task_used_math == task) { enable_fpu(); @@ -124,7 +124,7 @@ put_fpu_long(struct task_struct *task, unsigned long addr, unsigned long data) regs->sr |= SR_FD; } - ((long *)&task->thread.fpu)[addr / sizeof(unsigned long)] = data; + ((long *)task->thread.xstate)[addr / sizeof(unsigned long)] = data; return 0; } @@ -222,7 +222,7 @@ int fpregs_get(struct task_struct *target, return ret; return user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.fpu.hard, 0, -1); + &target->thread.xstate->hardfpu, 0, -1); } static int fpregs_set(struct task_struct *target, @@ -239,7 +239,7 @@ static int fpregs_set(struct task_struct *target, set_stopped_child_used_math(target); return user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.fpu.hard, 0, -1); + &target->thread.xstate->hardfpu, 0, -1); } static int fpregs_active(struct task_struct *target, diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c index ce76dbdef294..4733bfc59d39 100644 --- a/arch/sh/kernel/signal_64.c +++ b/arch/sh/kernel/signal_64.c @@ -295,7 +295,7 @@ restore_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc) regs->sr |= SR_FD; } - err |= __copy_from_user(¤t->thread.fpu.hard, &sc->sc_fpregs[0], + err |= __copy_from_user(¤t->thread.xstate->hardfpu, &sc->sc_fpregs[0], (sizeof(long long) * 32) + (sizeof(int) * 1)); return err; @@ -320,7 +320,7 @@ setup_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc) regs->sr |= SR_FD; } - err |= __copy_to_user(&sc->sc_fpregs[0], ¤t->thread.fpu.hard, + err |= __copy_to_user(&sc->sc_fpregs[0], ¤t->thread.xstate->hardfpu, (sizeof(long long) * 32) + (sizeof(int) * 1)); clear_used_math(); diff --git a/arch/sh/kernel/traps_64.c b/arch/sh/kernel/traps_64.c index d86f5315a0c1..e3f92eb05ffd 100644 --- a/arch/sh/kernel/traps_64.c +++ b/arch/sh/kernel/traps_64.c @@ -611,19 +611,19 @@ static int misaligned_fpu_load(struct pt_regs *regs, switch (width_shift) { case 2: - current->thread.fpu.hard.fp_regs[destreg] = buflo; + current->thread.xstate->hardfpu.fp_regs[destreg] = buflo; break; case 3: if (do_paired_load) { - current->thread.fpu.hard.fp_regs[destreg] = buflo; - current->thread.fpu.hard.fp_regs[destreg+1] = bufhi; + current->thread.xstate->hardfpu.fp_regs[destreg] = buflo; + current->thread.xstate->hardfpu.fp_regs[destreg+1] = bufhi; } else { #if defined(CONFIG_CPU_LITTLE_ENDIAN) - current->thread.fpu.hard.fp_regs[destreg] = bufhi; - current->thread.fpu.hard.fp_regs[destreg+1] = buflo; + current->thread.xstate->hardfpu.fp_regs[destreg] = bufhi; + current->thread.xstate->hardfpu.fp_regs[destreg+1] = buflo; #else - current->thread.fpu.hard.fp_regs[destreg] = buflo; - current->thread.fpu.hard.fp_regs[destreg+1] = bufhi; + current->thread.xstate->hardfpu.fp_regs[destreg] = buflo; + current->thread.xstate->hardfpu.fp_regs[destreg+1] = bufhi; #endif } break; @@ -681,19 +681,19 @@ static int misaligned_fpu_store(struct pt_regs *regs, switch (width_shift) { case 2: - buflo = current->thread.fpu.hard.fp_regs[srcreg]; + buflo = current->thread.xstate->hardfpu.fp_regs[srcreg]; break; case 3: if (do_paired_load) { - buflo = current->thread.fpu.hard.fp_regs[srcreg]; - bufhi = current->thread.fpu.hard.fp_regs[srcreg+1]; + buflo = current->thread.xstate->hardfpu.fp_regs[srcreg]; + bufhi = current->thread.xstate->hardfpu.fp_regs[srcreg+1]; } else { #if defined(CONFIG_CPU_LITTLE_ENDIAN) - bufhi = current->thread.fpu.hard.fp_regs[srcreg]; - buflo = current->thread.fpu.hard.fp_regs[srcreg+1]; + bufhi = current->thread.xstate->hardfpu.fp_regs[srcreg]; + buflo = current->thread.xstate->hardfpu.fp_regs[srcreg+1]; #else - buflo = current->thread.fpu.hard.fp_regs[srcreg]; - bufhi = current->thread.fpu.hard.fp_regs[srcreg+1]; + buflo = current->thread.xstate->hardfpu.fp_regs[srcreg]; + bufhi = current->thread.xstate->hardfpu.fp_regs[srcreg+1]; #endif } break; -- cgit v1.2.3 From 88ea1a445a84fcfbedb810c01e84d6711352bd82 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 19 Jan 2010 15:41:50 +0900 Subject: sh64: Fix up PC casting in unaligned fixup notifier with 32bit ABI. Presently the build bails with the following: CC arch/sh/mm/alignment.o cc1: warnings being treated as errors arch/sh/mm/alignment.c: In function 'unaligned_fixups_notify': arch/sh/mm/alignment.c:69: warning: cast to pointer from integer of different size arch/sh/mm/alignment.c:74: warning: cast to pointer from integer of different size make[2]: *** [arch/sh/mm/alignment.o] Error 1 This is due to the fact that regs->pc is always 64-bit, while the pointer size depends on the ABI. Wrapping through instruction_pointer() takes care of the appropriate casting for both configurations. Signed-off-by: Paul Mundt --- arch/sh/mm/alignment.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/mm/alignment.c b/arch/sh/mm/alignment.c index e615151eac3b..2da808802a4c 100644 --- a/arch/sh/mm/alignment.c +++ b/arch/sh/mm/alignment.c @@ -69,12 +69,12 @@ void unaligned_fixups_notify(struct task_struct *tsk, insn_size_t insn, pr_notice("Fixing up unaligned userspace access " "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n", tsk->comm, task_pid_nr(tsk), - (void *)regs->pc, insn); + (void *)instruction_pointer(regs), insn); else if (se_kernmode_warn && printk_ratelimit()) pr_notice("Fixing up unaligned kernel access " "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n", tsk->comm, task_pid_nr(tsk), - (void *)regs->pc, insn); + (void *)instruction_pointer(regs), insn); } static const char *se_usermode_action[] = { -- cgit v1.2.3 From d6db8888c8957fbdcd611e1321a6f6a0d6fb7e15 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 19 Jan 2010 15:55:27 +0900 Subject: sh64: Use the shared FPU state restorer. This kills off the sh64-specific state restorer and switches over to the generic one. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh5/entry.S | 4 +-- arch/sh/kernel/cpu/sh5/fpu.c | 63 ++++-------------------------------------- arch/sh/kernel/ptrace_64.c | 3 +- 3 files changed, 8 insertions(+), 62 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/kernel/cpu/sh5/entry.S b/arch/sh/kernel/cpu/sh5/entry.S index 8f13f73cb2cb..36d031c700bb 100644 --- a/arch/sh/kernel/cpu/sh5/entry.S +++ b/arch/sh/kernel/cpu/sh5/entry.S @@ -1124,7 +1124,7 @@ fpu_error_or_IRQA: pta its_IRQ, tr0 beqi/l r4, EVENT_INTERRUPT, tr0 #ifdef CONFIG_SH_FPU - movi do_fpu_state_restore, r6 + movi fpu_state_restore_trap_handler, r6 #else movi do_exception_error, r6 #endif @@ -1135,7 +1135,7 @@ fpu_error_or_IRQB: pta its_IRQ, tr0 beqi/l r4, EVENT_INTERRUPT, tr0 #ifdef CONFIG_SH_FPU - movi do_fpu_state_restore, r6 + movi fpu_state_restore_trap_handler, r6 #else movi do_exception_error, r6 #endif diff --git a/arch/sh/kernel/cpu/sh5/fpu.c b/arch/sh/kernel/cpu/sh5/fpu.c index 92df285fbe4b..4b3bb35e99f3 100644 --- a/arch/sh/kernel/cpu/sh5/fpu.c +++ b/arch/sh/kernel/cpu/sh5/fpu.c @@ -15,24 +15,6 @@ #include #include #include -#include -#include -#include - -/* - * Initially load the FPU with signalling NANS. This bit pattern - * has the property that no matter whether considered as single or as - * double precision, it still represents a signalling NAN. - */ -#define sNAN64 0xFFFFFFFFFFFFFFFFULL -#define sNAN32 0xFFFFFFFFUL - -static union thread_xstate init_fpuregs = { - .hardfpu = { - .fp_regs = { [0 ... 63] = sNAN32 }, - .fpscr = FPSCR_INIT - } -}; void save_fpu(struct task_struct *tsk) { @@ -76,8 +58,7 @@ void save_fpu(struct task_struct *tsk) : "memory"); } -static inline void -fpload(struct sh_fpu_hard_struct *fpregs) +void restore_fpu(struct task_struct *tsk) { asm volatile("fld.p %0, (0*8), fp0\n\t" "fld.p %0, (1*8), fp2\n\t" @@ -116,16 +97,11 @@ fpload(struct sh_fpu_hard_struct *fpregs) "fld.p %0, (31*8), fp62\n\t" : /* no output */ - : "r" (fpregs) ); -} - -void fpinit(struct sh_fpu_hard_struct *fpregs) -{ - *fpregs = init_fpuregs.hardfpu; + : "r" (&tsk->thread.xstate->hardfpu) + : "memory"); } -asmlinkage void -do_fpu_error(unsigned long ex, struct pt_regs *regs) +asmlinkage void do_fpu_error(unsigned long ex, struct pt_regs *regs) { struct task_struct *tsk = current; @@ -133,35 +109,6 @@ do_fpu_error(unsigned long ex, struct pt_regs *regs) tsk->thread.trap_no = 11; tsk->thread.error_code = 0; - force_sig(SIGFPE, tsk); -} - - -asmlinkage void -do_fpu_state_restore(unsigned long ex, struct pt_regs *regs) -{ - void die(const char *str, struct pt_regs *regs, long err); - - if (! user_mode(regs)) - die("FPU used in kernel", regs, ex); - regs->sr &= ~SR_FD; - - if (last_task_used_math == current) - return; - - enable_fpu(); - if (last_task_used_math != NULL) - /* Other processes fpu state, save away */ - save_fpu(last_task_used_math); - - last_task_used_math = current; - if (used_math()) { - fpload(¤t->thread.xstate->hardfpu); - } else { - /* First time FPU user. */ - fpload(&init_fpuregs.hardfpu); - set_used_math(); - } - disable_fpu(); + force_sig(SIGFPE, tsk); } diff --git a/arch/sh/kernel/ptrace_64.c b/arch/sh/kernel/ptrace_64.c index 67fbcee89e7e..23fbd92a74e7 100644 --- a/arch/sh/kernel/ptrace_64.c +++ b/arch/sh/kernel/ptrace_64.c @@ -114,8 +114,7 @@ put_fpu_long(struct task_struct *task, unsigned long addr, unsigned long data) regs = (struct pt_regs*)((unsigned char *)task + THREAD_SIZE) - 1; if (!tsk_used_math(task)) { - fpinit(&task->thread.xstate->hardfpu); - set_stopped_child_used_math(task); + init_fpu(task); } else if (last_task_used_math == task) { enable_fpu(); save_fpu(task); -- cgit v1.2.3 From a4ae2b2b18d1766768987dc5de42dfa3c2a6d9f7 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 19 Jan 2010 15:58:27 +0900 Subject: sh64: Fixup build breakage from breakpoint handler rename. The breakpoint handler was renamed on sh32, but sh64 was overlooked in the conversion. Fix it up now. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh5/entry.S | 2 +- arch/sh/kernel/ptrace_64.c | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/kernel/cpu/sh5/entry.S b/arch/sh/kernel/cpu/sh5/entry.S index 36d031c700bb..6b80295dd7a4 100644 --- a/arch/sh/kernel/cpu/sh5/entry.S +++ b/arch/sh/kernel/cpu/sh5/entry.S @@ -187,7 +187,7 @@ trap_jtable: .rept 6 .long do_exception_error /* 0x880 - 0x920 */ .endr - .long do_software_break_point /* 0x940 */ + .long breakpoint_trap_handler /* 0x940 */ .long do_exception_error /* 0x960 */ .long do_single_step /* 0x980 */ diff --git a/arch/sh/kernel/ptrace_64.c b/arch/sh/kernel/ptrace_64.c index 23fbd92a74e7..2f6140e95ec5 100644 --- a/arch/sh/kernel/ptrace_64.c +++ b/arch/sh/kernel/ptrace_64.c @@ -478,9 +478,10 @@ asmlinkage void do_single_step(unsigned long long vec, struct pt_regs *regs) } /* Called with interrupts disabled */ -asmlinkage void do_software_break_point(unsigned long long vec, - struct pt_regs *regs) +BUILD_TRAP_HANDLER(breakpoint) { + TRAP_HANDLER_DECL; + /* We need to forward step the PC, to counteract the backstep done in signal.c. */ local_irq_enable(); -- cgit v1.2.3 From 43a1839cb1e0e0ed08b8ace0adb3716865fd0c4c Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 19 Jan 2010 19:37:14 +0900 Subject: sh: SH7786 clock framework rewrite. This rewrites the SH7786 clock framework support completely. It's reworked to provide all of the DIV4 and MSTP function clocks. This brings it in line with the current clock framework code and lets us drop SH7786 from the list of CPUs that require legacy CPG handling. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 6 +- arch/sh/kernel/cpu/sh4a/clock-sh7786.c | 184 ++++++++++++++++----------------- 2 files changed, 91 insertions(+), 99 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 8d0eabbf7460..352879c1b86b 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -551,8 +551,7 @@ config SH_PCLK_FREQ CPU_SUBTYPE_SH7203 || \ CPU_SUBTYPE_SH7206 || \ CPU_SUBTYPE_SH7263 || \ - CPU_SUBTYPE_MXG || \ - CPU_SUBTYPE_SH7786 + CPU_SUBTYPE_MXG default "60000000" if CPU_SUBTYPE_SH7751 || CPU_SUBTYPE_SH7751R default "66000000" if CPU_SUBTYPE_SH4_202 default "50000000" @@ -566,7 +565,8 @@ config SH_CLK_CPG config SH_CLK_CPG_LEGACY depends on SH_CLK_CPG - def_bool y if !CPU_SUBTYPE_SH7785 && !ARCH_SHMOBILE + def_bool y if !CPU_SUBTYPE_SH7785 && !ARCH_SHMOBILE && \ + !CPU_SUBTYPE_SH7786 config SH_CLK_MD int "CPU Mode Pin Setting" diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c index a0e8869071ac..494c636012bb 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c @@ -3,11 +3,7 @@ * * SH7786 support for the clock framework * - * Copyright (C) 2008, 2009 Renesas Solutions Corp. - * Kuninori Morimoto - * - * Based on SH7785 - * Copyright (C) 2007 Paul Mundt + * Copyright (C) 2010 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 @@ -15,127 +11,123 @@ */ #include #include +#include +#include #include #include -#include - -static int ifc_divisors[] = { 1, 2, 4, 1 }; -static int sfc_divisors[] = { 1, 1, 4, 1 }; -static int bfc_divisors[] = { 1, 1, 1, 1, 1, 12, 16, 1, - 24, 32, 1, 1, 1, 1, 1, 1 }; -static int mfc_divisors[] = { 1, 1, 4, 1 }; -static int pfc_divisors[] = { 1, 1, 1, 1, 1, 1, 16, 1, - 24, 32, 1, 48, 1, 1, 1, 1 }; - -static void master_clk_init(struct clk *clk) -{ - clk->rate *= pfc_divisors[ctrl_inl(FRQMR1) & 0x000f]; -} -static struct clk_ops sh7786_master_clk_ops = { - .init = master_clk_init, +/* + * Default rate for the root input clock, reset this with clk_set_rate() + * from the platform code. + */ +static struct clk extal_clk = { + .name = "extal", + .id = -1, + .rate = 33333333, }; -static unsigned long module_clk_recalc(struct clk *clk) +static unsigned long pll_recalc(struct clk *clk) { - int idx = (ctrl_inl(FRQMR1) & 0x000f); - return clk->parent->rate / pfc_divisors[idx]; -} + int multiplier; -static struct clk_ops sh7786_module_clk_ops = { - .recalc = module_clk_recalc, -}; + /* + * Clock modes 0, 1, and 2 use an x64 multiplier against PLL1, + * while modes 3, 4, and 5 use an x32. + */ + multiplier = (sh_mv.mv_mode_pins() & 0xf) < 3 ? 64 : 32; -static unsigned long bus_clk_recalc(struct clk *clk) -{ - int idx = ((ctrl_inl(FRQMR1) >> 16) & 0x000f); - return clk->parent->rate / bfc_divisors[idx]; + return clk->parent->rate * multiplier; } -static struct clk_ops sh7786_bus_clk_ops = { - .recalc = bus_clk_recalc, +static struct clk_ops pll_clk_ops = { + .recalc = pll_recalc, }; -static unsigned long cpu_clk_recalc(struct clk *clk) -{ - int idx = ((ctrl_inl(FRQMR1) >> 28) & 0x0003); - return clk->parent->rate / ifc_divisors[idx]; -} - -static struct clk_ops sh7786_cpu_clk_ops = { - .recalc = cpu_clk_recalc, +static struct clk pll_clk = { + .name = "pll_clk", + .id = -1, + .ops = &pll_clk_ops, + .parent = &extal_clk, + .flags = CLK_ENABLE_ON_INIT, }; -static struct clk_ops *sh7786_clk_ops[] = { - &sh7786_master_clk_ops, - &sh7786_module_clk_ops, - &sh7786_bus_clk_ops, - &sh7786_cpu_clk_ops, +static struct clk *clks[] = { + &extal_clk, + &pll_clk, }; -void __init arch_init_clk_ops(struct clk_ops **ops, int idx) -{ - if (idx < ARRAY_SIZE(sh7786_clk_ops)) - *ops = sh7786_clk_ops[idx]; -} - -static unsigned long shyway_clk_recalc(struct clk *clk) -{ - int idx = ((ctrl_inl(FRQMR1) >> 20) & 0x0003); - return clk->parent->rate / sfc_divisors[idx]; -} +static unsigned int div2[] = { 1, 2, 4, 6, 8, 12, 16, 18, + 24, 32, 36, 48 }; -static struct clk_ops sh7786_shyway_clk_ops = { - .recalc = shyway_clk_recalc, +static struct clk_div_mult_table div4_table = { + .divisors = div2, + .nr_divisors = ARRAY_SIZE(div2), }; -static struct clk sh7786_shyway_clk = { - .name = "shyway_clk", - .flags = CLK_ENABLE_ON_INIT, - .ops = &sh7786_shyway_clk_ops, -}; +enum { DIV4_I, DIV4_SH, DIV4_B, DIV4_DDR, DIV4_DU, DIV4_P, DIV4_NR }; -static unsigned long ddr_clk_recalc(struct clk *clk) -{ - int idx = ((ctrl_inl(FRQMR1) >> 12) & 0x0003); - return clk->parent->rate / mfc_divisors[idx]; -} +#define DIV4(_str, _bit, _mask, _flags) \ + SH_CLK_DIV4(_str, &pll_clk, FRQMR1, _bit, _mask, _flags) -static struct clk_ops sh7786_ddr_clk_ops = { - .recalc = ddr_clk_recalc, +struct clk div4_clks[DIV4_NR] = { + [DIV4_P] = DIV4("peripheral_clk", 0, 0x0b40, 0), + [DIV4_DU] = DIV4("du_clk", 4, 0x0010, 0), + [DIV4_DDR] = DIV4("ddr_clk", 12, 0x0002, CLK_ENABLE_ON_INIT), + [DIV4_B] = DIV4("bus_clk", 16, 0x0360, CLK_ENABLE_ON_INIT), + [DIV4_SH] = DIV4("shyway_clk", 20, 0x0002, CLK_ENABLE_ON_INIT), + [DIV4_I] = DIV4("cpu_clk", 28, 0x0006, CLK_ENABLE_ON_INIT), }; -static struct clk sh7786_ddr_clk = { - .name = "ddr_clk", - .flags = CLK_ENABLE_ON_INIT, - .ops = &sh7786_ddr_clk_ops, -}; - -/* - * Additional SH7786-specific on-chip clocks that aren't already part of the - * clock framework - */ -static struct clk *sh7786_onchip_clocks[] = { - &sh7786_shyway_clk, - &sh7786_ddr_clk, +#define MSTPCR0 0xffc40030 +#define MSTPCR1 0xffc40034 + +static struct clk mstp_clks[] = { + /* MSTPCR0 */ + SH_CLK_MSTP32("scif_fck", 5, &div4_clks[DIV4_P], MSTPCR0, 29, 0), + SH_CLK_MSTP32("scif_fck", 4, &div4_clks[DIV4_P], MSTPCR0, 28, 0), + SH_CLK_MSTP32("scif_fck", 3, &div4_clks[DIV4_P], MSTPCR0, 27, 0), + SH_CLK_MSTP32("scif_fck", 2, &div4_clks[DIV4_P], MSTPCR0, 26, 0), + SH_CLK_MSTP32("scif_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 25, 0), + SH_CLK_MSTP32("scif_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 24, 0), + SH_CLK_MSTP32("ssi_fck", 3, &div4_clks[DIV4_P], MSTPCR0, 23, 0), + SH_CLK_MSTP32("ssi_fck", 2, &div4_clks[DIV4_P], MSTPCR0, 22, 0), + SH_CLK_MSTP32("ssi_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 21, 0), + SH_CLK_MSTP32("ssi_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 20, 0), + SH_CLK_MSTP32("hac_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 17, 0), + SH_CLK_MSTP32("hac_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 16, 0), + SH_CLK_MSTP32("i2c_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 15, 0), + SH_CLK_MSTP32("i2c_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 14, 0), + SH_CLK_MSTP32("tmu9_11_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 11, 0), + SH_CLK_MSTP32("tmu678_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 10, 0), + SH_CLK_MSTP32("tmu345_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 9, 0), + SH_CLK_MSTP32("tmu012_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 8, 0), + SH_CLK_MSTP32("sdif_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 5, 0), + SH_CLK_MSTP32("sdif_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 4, 0), + SH_CLK_MSTP32("hspi_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 2, 0), + + /* MSTPCR1 */ + SH_CLK_MSTP32("usb_fck", -1, NULL, MSTPCR1, 12, 0), + SH_CLK_MSTP32("pcie_fck", 2, NULL, MSTPCR1, 10, 0), + SH_CLK_MSTP32("pcie_fck", 1, NULL, MSTPCR1, 9, 0), + SH_CLK_MSTP32("pcie_fck", 0, NULL, MSTPCR1, 8, 0), + SH_CLK_MSTP32("dmac_11_6_fck", -1, NULL, MSTPCR1, 5, 0), + SH_CLK_MSTP32("dmac_5_0_fck", -1, NULL, MSTPCR1, 4, 0), + SH_CLK_MSTP32("du_fck", -1, NULL, MSTPCR1, 3, 0), + SH_CLK_MSTP32("ether_fck", -1, NULL, MSTPCR1, 2, 0), }; int __init arch_clk_init(void) { - struct clk *clk; int i, ret = 0; - cpg_clk_init(); - - clk = clk_get(NULL, "master_clk"); - for (i = 0; i < ARRAY_SIZE(sh7786_onchip_clocks); i++) { - struct clk *clkp = sh7786_onchip_clocks[i]; - - clkp->parent = clk; - ret |= clk_register(clkp); - } + for (i = 0; i < ARRAY_SIZE(clks); i++) + ret |= clk_register(clks[i]); - clk_put(clk); + if (!ret) + ret = sh_clk_div4_register(div4_clks, ARRAY_SIZE(div4_clks), + &div4_table); + if (!ret) + ret = sh_clk_mstp32_register(mstp_clks, ARRAY_SIZE(mstp_clks)); return ret; } -- cgit v1.2.3 From c8098218271d19e7123d8b9137b9a4b87e5ffec0 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 19 Jan 2010 19:38:36 +0900 Subject: sh: mach-sdk7786: Detect/configure/propagate EXTAL. This uses the mode pins exposed through the FPGA to work out whether we're driven from EXTAL or not and does the appropriate setup and propagation through the clock framework. This will also -EINVAL out for anyone adding in their own oscillators, forcing proper configuration with the clock framework instead of proceeding on with bogus clock values. Signed-off-by: Paul Mundt --- arch/sh/boards/mach-sdk7786/setup.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/boards/mach-sdk7786/setup.c b/arch/sh/boards/mach-sdk7786/setup.c index c38c6cc293b5..0e4b1c39742c 100644 --- a/arch/sh/boards/mach-sdk7786/setup.c +++ b/arch/sh/boards/mach-sdk7786/setup.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -235,6 +236,27 @@ static int sdk7786_mode_pins(void) return pin_states; } +static int sdk7786_clk_init(void) +{ + struct clk *clk; + int ret; + + /* + * Only handle the EXTAL case, anyone interfacing a crystal + * resonator will need to provide their own input clock. + */ + if (test_mode_pin(MODE_PIN9)) + return -EINVAL; + + clk = clk_get(NULL, "extal"); + if (!clk || IS_ERR(clk)) + return PTR_ERR(clk); + ret = clk_set_rate(clk, 33333333); + clk_put(clk); + + return ret; +} + /* Initialize the board */ static void __init sdk7786_setup(char **cmdline_p) { @@ -248,5 +270,6 @@ static struct sh_machine_vector mv_sdk7786 __initmv = { .mv_name = "SDK7786", .mv_setup = sdk7786_setup, .mv_mode_pins = sdk7786_mode_pins, + .mv_clk_init = sdk7786_clk_init, .mv_init_irq = init_sdk7786_IRQ, }; -- cgit v1.2.3 From dea3cf1c3935047a5b0d21b21d26718e09135f97 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 19 Jan 2010 20:09:28 +0900 Subject: sh: urquell: Handle EXTAL configuration here, too. urquell happens to use the same mode pins and EXTAL configuration as SDK7786, so just copy it over. Signed-off-by: Paul Mundt --- arch/sh/boards/board-urquell.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'arch/sh') diff --git a/arch/sh/boards/board-urquell.c b/arch/sh/boards/board-urquell.c index 268f09e46568..8aeac64810dc 100644 --- a/arch/sh/boards/board-urquell.c +++ b/arch/sh/boards/board-urquell.c @@ -2,7 +2,7 @@ * Renesas Technology Corp. SH7786 Urquell Support. * * Copyright (C) 2008 Kuninori Morimoto - * Copyright (C) 2009 Paul Mundt + * Copyright (C) 2009, 2010 Paul Mundt * * Based on board-sh7785lcr.c * Copyright (C) 2008 Yoshihiro Shimoda @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -175,6 +176,27 @@ static int urquell_mode_pins(void) return __raw_readw(UBOARDREG(MDSWMR)); } +static int urquell_clk_init(void) +{ + struct clk *clk; + int ret; + + /* + * Only handle the EXTAL case, anyone interfacing a crystal + * resonator will need to provide their own input clock. + */ + if (test_mode_pin(MODE_PIN9)) + return -EINVAL; + + clk = clk_get(NULL, "extal"); + if (!clk || IS_ERR(clk)) + return PTR_ERR(clk); + ret = clk_set_rate(clk, 33333333); + clk_put(clk); + + return ret; +} + /* Initialize the board */ static void __init urquell_setup(char **cmdline_p) { @@ -191,4 +213,5 @@ static struct sh_machine_vector mv_urquell __initmv = { .mv_setup = urquell_setup, .mv_init_irq = urquell_init_irq, .mv_mode_pins = urquell_mode_pins, + .mv_clk_init = urquell_clk_init, }; -- cgit v1.2.3 From 14965f16b4bb8f3e51b09c1d8f61b8e98f9d12db Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 19 Jan 2010 20:10:33 +0900 Subject: sh: Fix up sdk7780 and urquell builds. These two got broken in the heartbeat private data conversion, fix them up. Signed-off-by: Paul Mundt --- arch/sh/boards/board-urquell.c | 2 +- arch/sh/boards/mach-sdk7780/setup.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/boards/board-urquell.c b/arch/sh/boards/board-urquell.c index 8aeac64810dc..a9bd6e3ee10b 100644 --- a/arch/sh/boards/board-urquell.c +++ b/arch/sh/boards/board-urquell.c @@ -60,7 +60,7 @@ static struct resource heartbeat_resource = { static struct platform_device heartbeat_device = { .name = "heartbeat", .id = -1, - .num_resources = 1 + .num_resources = 1, .resource = &heartbeat_resource, }; diff --git a/arch/sh/boards/mach-sdk7780/setup.c b/arch/sh/boards/mach-sdk7780/setup.c index 1d04657e992d..b887373a2599 100644 --- a/arch/sh/boards/mach-sdk7780/setup.c +++ b/arch/sh/boards/mach-sdk7780/setup.c @@ -30,7 +30,7 @@ static struct resource heartbeat_resource = { static struct platform_device heartbeat_device = { .name = "heartbeat", .id = -1, - .num_resources = 1 + .num_resources = 1, .resource = &heartbeat_resource, }; -- cgit v1.2.3 From 31c3af503eb75488aafb7a3d292b9e00962f2cee Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Tue, 19 Jan 2010 11:14:31 +0000 Subject: sh: support SIU sourcing from external clock on sh7722 Implement .set_rate() for all SH "div4 clocks," .enable(), .disable(), and .set_parent() for those, that support them. This allows, among other uses, reparenting of SIU clocks to the external source, and enabling and disabling of the IrDA clock on sh7722. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Paul Mundt --- arch/sh/include/asm/clock.h | 4 ++ arch/sh/kernel/cpu/clock-cpg.c | 94 ++++++++++++++++++++++++++++++++-- arch/sh/kernel/cpu/sh4a/clock-sh7722.c | 25 +++++++-- 3 files changed, 116 insertions(+), 7 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/clock.h b/arch/sh/include/asm/clock.h index 9fe7d7f8af40..501d0b076283 100644 --- a/arch/sh/include/asm/clock.h +++ b/arch/sh/include/asm/clock.h @@ -148,6 +148,10 @@ int sh_clk_mstp32_register(struct clk *clks, int nr); int sh_clk_div4_register(struct clk *clks, int nr, struct clk_div_mult_table *table); +int sh_clk_div4_enable_register(struct clk *clks, int nr, + struct clk_div_mult_table *table); +int sh_clk_div4_reparent_register(struct clk *clks, int nr, + struct clk_div_mult_table *table); #define SH_CLK_DIV6(_name, _parent, _reg, _flags) \ { \ diff --git a/arch/sh/kernel/cpu/clock-cpg.c b/arch/sh/kernel/cpu/clock-cpg.c index 6dfe2cced3fc..2827abb5d2ab 100644 --- a/arch/sh/kernel/cpu/clock-cpg.c +++ b/arch/sh/kernel/cpu/clock-cpg.c @@ -160,13 +160,81 @@ static unsigned long sh_clk_div4_recalc(struct clk *clk) return clk->freq_table[idx].frequency; } +static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent) +{ + struct clk_div_mult_table *table = clk->priv; + u32 value; + int ret; + + if (!strcmp("pll_clk", parent->name)) + value = __raw_readl(clk->enable_reg) & ~(1 << 7); + else + value = __raw_readl(clk->enable_reg) | (1 << 7); + + ret = clk_reparent(clk, parent); + if (ret < 0) + return ret; + + __raw_writel(value, clk->enable_reg); + + /* Rebiuld the frequency table */ + clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, + table, &clk->arch_flags); + + return 0; +} + +static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate, int algo_id) +{ + unsigned long value; + int idx = clk_rate_table_find(clk, clk->freq_table, rate); + if (idx < 0) + return idx; + + value = __raw_readl(clk->enable_reg); + value &= ~0xf; + value |= idx; + __raw_writel(value, clk->enable_reg); + + return 0; +} + +static int sh_clk_div4_enable(struct clk *clk) +{ + __raw_writel(__raw_readl(clk->enable_reg) & ~(1 << 8), clk->enable_reg); + return 0; +} + +static void sh_clk_div4_disable(struct clk *clk) +{ + __raw_writel(__raw_readl(clk->enable_reg) | (1 << 8), clk->enable_reg); +} + static struct clk_ops sh_clk_div4_clk_ops = { .recalc = sh_clk_div4_recalc, + .set_rate = sh_clk_div4_set_rate, .round_rate = sh_clk_div_round_rate, }; -int __init sh_clk_div4_register(struct clk *clks, int nr, - struct clk_div_mult_table *table) +static struct clk_ops sh_clk_div4_enable_clk_ops = { + .recalc = sh_clk_div4_recalc, + .set_rate = sh_clk_div4_set_rate, + .round_rate = sh_clk_div_round_rate, + .enable = sh_clk_div4_enable, + .disable = sh_clk_div4_disable, +}; + +static struct clk_ops sh_clk_div4_reparent_clk_ops = { + .recalc = sh_clk_div4_recalc, + .set_rate = sh_clk_div4_set_rate, + .round_rate = sh_clk_div_round_rate, + .enable = sh_clk_div4_enable, + .disable = sh_clk_div4_disable, + .set_parent = sh_clk_div4_set_parent, +}; + +static int __init sh_clk_div4_register_ops(struct clk *clks, int nr, + struct clk_div_mult_table *table, struct clk_ops *ops) { struct clk *clkp; void *freq_table; @@ -185,7 +253,7 @@ int __init sh_clk_div4_register(struct clk *clks, int nr, for (k = 0; !ret && (k < nr); k++) { clkp = clks + k; - clkp->ops = &sh_clk_div4_clk_ops; + clkp->ops = ops; clkp->id = -1; clkp->priv = table; @@ -198,6 +266,26 @@ int __init sh_clk_div4_register(struct clk *clks, int nr, return ret; } +int __init sh_clk_div4_register(struct clk *clks, int nr, + struct clk_div_mult_table *table) +{ + return sh_clk_div4_register_ops(clks, nr, table, &sh_clk_div4_clk_ops); +} + +int __init sh_clk_div4_enable_register(struct clk *clks, int nr, + struct clk_div_mult_table *table) +{ + return sh_clk_div4_register_ops(clks, nr, table, + &sh_clk_div4_enable_clk_ops); +} + +int __init sh_clk_div4_reparent_register(struct clk *clks, int nr, + struct clk_div_mult_table *table) +{ + return sh_clk_div4_register_ops(clks, nr, table, + &sh_clk_div4_reparent_clk_ops); +} + #ifdef CONFIG_SH_CLK_CPG_LEGACY static struct clk master_clk = { .name = "master_clk", diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c index ea38b554dc05..860ee2bf4bf0 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c @@ -117,12 +117,11 @@ static struct clk_div_mult_table div4_table = { .nr_multipliers = ARRAY_SIZE(multipliers), }; -enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P, - DIV4_SIUA, DIV4_SIUB, DIV4_IRDA, DIV4_NR }; - #define DIV4(_str, _reg, _bit, _mask, _flags) \ SH_CLK_DIV4(_str, &pll_clk, _reg, _bit, _mask, _flags) +enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P, DIV4_NR }; + struct clk div4_clks[DIV4_NR] = { [DIV4_I] = DIV4("cpu_clk", FRQCR, 20, 0x1fef, CLK_ENABLE_ON_INIT), [DIV4_U] = DIV4("umem_clk", FRQCR, 16, 0x1fff, CLK_ENABLE_ON_INIT), @@ -130,9 +129,19 @@ struct clk div4_clks[DIV4_NR] = { [DIV4_B] = DIV4("bus_clk", FRQCR, 8, 0x1fff, CLK_ENABLE_ON_INIT), [DIV4_B3] = DIV4("b3_clk", FRQCR, 4, 0x1fff, CLK_ENABLE_ON_INIT), [DIV4_P] = DIV4("peripheral_clk", FRQCR, 0, 0x1fff, 0), +}; + +enum { DIV4_IRDA, DIV4_ENABLE_NR }; + +struct clk div4_enable_clks[DIV4_ENABLE_NR] = { + [DIV4_IRDA] = DIV4("irda_clk", IRDACLKCR, 0, 0x1fff, 0), +}; + +enum { DIV4_SIUA, DIV4_SIUB, DIV4_REPARENT_NR }; + +struct clk div4_reparent_clks[DIV4_REPARENT_NR] = { [DIV4_SIUA] = DIV4("siua_clk", SCLKACR, 0, 0x1fff, 0), [DIV4_SIUB] = DIV4("siub_clk", SCLKBCR, 0, 0x1fff, 0), - [DIV4_IRDA] = DIV4("irda_clk", IRDACLKCR, 0, 0x1fff, 0), }; struct clk div6_clks[] = { @@ -188,6 +197,14 @@ int __init arch_clk_init(void) if (!ret) ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table); + if (!ret) + ret = sh_clk_div4_enable_register(div4_enable_clks, + DIV4_ENABLE_NR, &div4_table); + + if (!ret) + ret = sh_clk_div4_reparent_register(div4_reparent_clks, + DIV4_REPARENT_NR, &div4_table); + if (!ret) ret = sh_clk_div6_register(div6_clks, ARRAY_SIZE(div6_clks)); -- cgit v1.2.3 From 70911b861bfbba1851cbb3497635030f34703c7a Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 20 Jan 2010 02:45:05 +0900 Subject: sh: Shut up noisy IOREMAP_FIXED=n build. The ioremap_fixed() stub neglected to provide a return value, resulting in a fairly noisy build. Signed-off-by: Paul Mundt --- arch/sh/include/asm/io.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h index 4bad72a1b39e..e4f563f472eb 100644 --- a/arch/sh/include/asm/io.h +++ b/arch/sh/include/asm/io.h @@ -245,10 +245,11 @@ extern int iounmap_fixed(void __iomem *); extern void ioremap_fixed_init(void); #else static inline void __iomem * -ioremap_fixed(resource_size t phys_addr, unsigned long offset, +ioremap_fixed(resource_size_t phys_addr, unsigned long offset, unsigned long size, pgprot_t prot) { BUG(); + return NULL; } static inline void ioremap_fixed_init(void) { } -- cgit v1.2.3 From bdc27300f5718626a3817e6478e339f6cca6b994 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 20 Jan 2010 03:38:56 +0900 Subject: sh: Handle SH-4 FPU variants with broken CVR values. Usually we can look to the CVR to work out whether we have an FPU or not. Unfortunately not all parts comply with this, so just set the flag manually for all SH-4 parts and clear it on the only SH-4 that doesn't have one (SH4-501). Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4/probe.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c index 21371f8cf010..cc02b3145cca 100644 --- a/arch/sh/kernel/cpu/sh4/probe.c +++ b/arch/sh/kernel/cpu/sh4/probe.c @@ -71,11 +71,11 @@ int __init detect_cpu_and_cache_system(void) boot_cpu_data.dcache.ways = 4; } else { /* And some SH-4 defaults.. */ - boot_cpu_data.flags |= CPU_HAS_PTEA; + boot_cpu_data.flags |= CPU_HAS_PTEA | CPU_HAS_FPU; boot_cpu_data.family = CPU_FAMILY_SH4; } - /* FPU detection works for everyone */ + /* FPU detection works for almost everyone */ if ((cvr & 0x20000000)) boot_cpu_data.flags |= CPU_HAS_FPU; @@ -161,6 +161,7 @@ int __init detect_cpu_and_cache_system(void) break; case 0x700: boot_cpu_data.type = CPU_SH4_501; + boot_cpu_data.flags &= ~CPU_HAS_FPU; boot_cpu_data.icache.ways = 2; boot_cpu_data.dcache.ways = 2; break; -- cgit v1.2.3 From efd590d57a5edddabaaf4cfaf532c0f674193b81 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 20 Jan 2010 15:08:36 +0900 Subject: sh: mach-sdk7786: FPGA updates. This does a bit of refactoring of the FPGA management code. The primary FPGA initialization is moved out to its own file in preparation for implementing some of the more complex capabilities, a complete set of register definitions is provided, and all of the existing users in the board code are moved over to use the new interface instead of setting up overlapping mappings. This also corrects the FPGA size, which previously was chomped off at the SDIF control register. Signed-off-by: Paul Mundt --- arch/sh/boards/mach-sdk7786/Makefile | 2 +- arch/sh/boards/mach-sdk7786/fpga.c | 37 ++++++++++ arch/sh/boards/mach-sdk7786/setup.c | 78 +++------------------ arch/sh/include/mach-sdk7786/mach/fpga.h | 112 +++++++++++++++++++++++++++++++ 4 files changed, 159 insertions(+), 70 deletions(-) create mode 100644 arch/sh/boards/mach-sdk7786/fpga.c create mode 100644 arch/sh/include/mach-sdk7786/mach/fpga.h (limited to 'arch/sh') diff --git a/arch/sh/boards/mach-sdk7786/Makefile b/arch/sh/boards/mach-sdk7786/Makefile index f663768429f0..50c8065deaa0 100644 --- a/arch/sh/boards/mach-sdk7786/Makefile +++ b/arch/sh/boards/mach-sdk7786/Makefile @@ -1 +1 @@ -obj-y := setup.o +obj-y := setup.o fpga.o diff --git a/arch/sh/boards/mach-sdk7786/fpga.c b/arch/sh/boards/mach-sdk7786/fpga.c new file mode 100644 index 000000000000..99f903c8b238 --- /dev/null +++ b/arch/sh/boards/mach-sdk7786/fpga.c @@ -0,0 +1,37 @@ +/* + * SDK7786 FPGA Support. + * + * Copyright (C) 2010 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. + */ +#include +#include +#include +#include + +#define FPGA_REGS_BASE 0x07fff800 +#define FPGA_REGS_SIZE 0x490 + +void __iomem *sdk7786_fpga_base; + +void __init sdk7786_fpga_init(void) +{ + u16 version, date; + + sdk7786_fpga_base = ioremap_nocache(FPGA_REGS_BASE, FPGA_REGS_SIZE); + if (unlikely(!sdk7786_fpga_base)) { + panic("FPGA remapping failed.\n"); + return; + } + + version = fpga_read_reg(FPGAVR); + date = fpga_read_reg(FPGADR); + + pr_info("\tFPGA version:\t%d.%d (built on %d/%d/%d)\n", + bcd2bin(version >> 8) & 0xf, bcd2bin(version & 0xf), + ((date >> 12) & 0xf) + 2000, + (date >> 8) & 0xf, bcd2bin(date & 0xff)); +} diff --git a/arch/sh/boards/mach-sdk7786/setup.c b/arch/sh/boards/mach-sdk7786/setup.c index 0e4b1c39742c..8dbbdea9c983 100644 --- a/arch/sh/boards/mach-sdk7786/setup.c +++ b/arch/sh/boards/mach-sdk7786/setup.c @@ -18,6 +18,7 @@ #include #include #include +#include static struct resource heartbeat_resource = { .start = 0x07fff8b0, @@ -103,27 +104,17 @@ static struct platform_device *sh7786_devices[] __initdata = { &smbus_pcie_device, }; -#define SBCR_REGS_BASE 0x07fff990 - -#define SCBR_I2CMEN (1 << 0) /* FPGA I2C master enable */ -#define SCBR_I2CCEN (1 << 1) /* CPU I2C master enable */ - static int sdk7786_i2c_setup(void) { - void __iomem *sbcr; unsigned int tmp; - sbcr = ioremap_nocache(SBCR_REGS_BASE, SZ_16); - /* * Hand over I2C control to the FPGA. */ - tmp = ioread16(sbcr); + tmp = fpga_read_reg(SBCR); tmp &= ~SCBR_I2CCEN; tmp |= SCBR_I2CMEN; - iowrite16(tmp, sbcr); - - iounmap(sbcr); + fpga_write_reg(tmp, SBCR); return i2c_register_board_info(0, sdk7786_i2c_devices, ARRAY_SIZE(sdk7786_i2c_devices)); @@ -141,43 +132,6 @@ static int __init sdk7786_devices_setup(void) } __initcall(sdk7786_devices_setup); -#define FPGA_REGS_BASE 0x07fff800 -#define FPGA_REGS_SIZE 1152 - -#define INTASR 0x010 -#define INTAMR 0x020 -#define INTBSR 0x090 -#define INTBMR 0x0a0 -#define INTMSR 0x130 - -#define IASELR1 0x210 -#define IASELR2 0x220 -#define IASELR3 0x230 -#define IASELR4 0x240 -#define IASELR5 0x250 -#define IASELR6 0x260 -#define IASELR7 0x270 -#define IASELR8 0x280 -#define IASELR9 0x290 -#define IASELR10 0x2a0 -#define IASELR11 0x2b0 -#define IASELR12 0x2c0 -#define IASELR13 0x2d0 -#define IASELR14 0x2e0 -#define IASELR15 0x2f0 - -static void __iomem *fpga_regs; - -static u16 fpga_read_reg(unsigned int reg) -{ - return __raw_readw(fpga_regs + reg); -} - -static void fpga_write_reg(u16 val, unsigned int reg) -{ - __raw_writew(val, fpga_regs + reg); -} - enum { ATA_IRQ_BIT = 1, SPI_BUSY_BIT = 2, @@ -197,12 +151,6 @@ static void __init init_sdk7786_IRQ(void) { unsigned int tmp; - fpga_regs = ioremap_nocache(FPGA_REGS_BASE, FPGA_REGS_SIZE); - if (!fpga_regs) { - printk(KERN_ERR "Couldn't map FPGA registers\n"); - return; - } - /* Enable priority encoding for all IRLs */ fpga_write_reg(fpga_read_reg(INTMSR) | 0x0303, INTMSR); @@ -219,21 +167,9 @@ static void __init init_sdk7786_IRQ(void) plat_irq_setup_pins(IRQ_MODE_IRL3210_MASK); } -#define MODSWR_REGS 0x07fff830 - static int sdk7786_mode_pins(void) { - void __iomem *modswr; - int pin_states; - - modswr = ioremap_nocache(MODSWR_REGS, SZ_16); - if (!modswr) - return -ENXIO; - - pin_states = ioread16(modswr); - iounmap(modswr); - - return pin_states; + return fpga_read_reg(MODSWR); } static int sdk7786_clk_init(void) @@ -260,7 +196,11 @@ static int sdk7786_clk_init(void) /* Initialize the board */ static void __init sdk7786_setup(char **cmdline_p) { - printk(KERN_INFO "Renesas Technology Corp. SDK7786 support.\n"); + pr_info("Renesas Technology Europe SDK7786 support:\n"); + + sdk7786_fpga_init(); + + pr_info("\tPCB revision:\t%d\n", fpga_read_reg(PCBRR) & 0xf); } /* diff --git a/arch/sh/include/mach-sdk7786/mach/fpga.h b/arch/sh/include/mach-sdk7786/mach/fpga.h new file mode 100644 index 000000000000..a85d9853d34f --- /dev/null +++ b/arch/sh/include/mach-sdk7786/mach/fpga.h @@ -0,0 +1,112 @@ +#ifndef __MACH_SDK7786_FPGA_H +#define __MACH_SDK7786_FPGA_H + +#include +#include +#include + +#define SRSTR 0x000 +#define INTASR 0x010 +#define INTAMR 0x020 +#define MODSWR 0x030 +#define INTTESTR 0x040 +#define SYSSR 0x050 +#define NRGPR 0x060 +#define NMISR 0x070 + +#define NMIMR 0x080 +#define NMIMR_MAN_NMIM BIT(0) /* Manual NMI mask */ +#define NMIMR_AUX_NMIM BIT(1) /* Auxiliary NMI mask */ + +#define INTBSR 0x090 +#define INTBMR 0x0a0 +#define USRLEDR 0x0b0 +#define MAPSWR 0x0c0 +#define FPGAVR 0x0d0 +#define FPGADR 0x0e0 +#define PCBRR 0x0f0 +#define RSR 0x100 +#define EXTASR 0x110 +#define SPCAR 0x120 +#define INTMSR 0x130 +#define PCIECR 0x140 +#define FAER 0x150 +#define USRGPIR 0x160 +/* 0x170 reserved */ +#define LCLASR 0x180 + +#define SBCR 0x190 +#define SCBR_I2CMEN BIT(0) /* FPGA I2C master enable */ +#define SCBR_I2CCEN BIT(1) /* CPU I2C master enable */ + +#define PWRCR 0x1a0 +#define SPCBR 0x1b0 +#define SPICR 0x1c0 +#define SPIDR 0x1d0 +#define I2CCR 0x1e0 +#define I2CDR 0x1f0 +#define FPGACR 0x200 +#define IASELR1 0x210 +#define IASELR2 0x220 +#define IASELR3 0x230 +#define IASELR4 0x240 +#define IASELR5 0x250 +#define IASELR6 0x260 +#define IASELR7 0x270 +#define IASELR8 0x280 +#define IASELR9 0x290 +#define IASELR10 0x2a0 +#define IASELR11 0x2b0 +#define IASELR12 0x2c0 +#define IASELR13 0x2d0 +#define IASELR14 0x2e0 +#define IASELR15 0x2f0 +/* 0x300 reserved */ +#define IBSELR1 0x310 +#define IBSELR2 0x320 +#define IBSELR3 0x330 +#define IBSELR4 0x340 +#define IBSELR5 0x350 +#define IBSELR6 0x360 +#define IBSELR7 0x370 +#define IBSELR8 0x380 +#define IBSELR9 0x390 +#define IBSELR10 0x3a0 +#define IBSELR11 0x3b0 +#define IBSELR12 0x3c0 +#define IBSELR13 0x3d0 +#define IBSELR14 0x3e0 +#define IBSELR15 0x3f0 +#define USRACR 0x400 +#define BEEPR 0x410 +#define USRLCDR 0x420 +#define SMBCR 0x430 +#define SMBDR 0x440 +#define USBCR 0x450 +#define AMSR 0x460 +#define ACCR 0x470 +#define SDIFCR 0x480 + +/* arch/sh/boards/mach-sdk7786/fpga.c */ +extern void __iomem *sdk7786_fpga_base; +extern void sdk7786_fpga_init(void); + +#define SDK7786_FPGA_REGADDR(reg) (sdk7786_fpga_base + (reg)) + +/* + * A convenience wrapper from register offset to internal I2C address, + * when the FPGA is in I2C slave mode. + */ +#define SDK7786_FPGA_I2CADDR(reg) ((reg) >> 3) + +static inline u16 fpga_read_reg(unsigned int reg) +{ + return ioread16(sdk7786_fpga_base + reg); +} + +static inline void fpga_write_reg(u16 val, unsigned int reg) +{ + iowrite16(val, sdk7786_fpga_base + reg); +} + +#endif /* __MACH_SDK7786_FPGA_H */ -- cgit v1.2.3 From 5f240718b475dcddee86b138b624f24c681dbb29 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 20 Jan 2010 15:23:54 +0900 Subject: sh: mach-sdk7786: Split out FPGA IRQ controller setup. This moves out the FPGA IRQ controller setup code to its own file, in preparation for switching off of IRL mode and having it provide its own irq_chip. Signed-off-by: Paul Mundt --- arch/sh/boards/mach-sdk7786/Makefile | 2 +- arch/sh/boards/mach-sdk7786/irq.c | 48 +++++++++++++++++++++++++++++++++ arch/sh/boards/mach-sdk7786/setup.c | 40 +++------------------------ arch/sh/include/mach-sdk7786/mach/irq.h | 7 +++++ 4 files changed, 59 insertions(+), 38 deletions(-) create mode 100644 arch/sh/boards/mach-sdk7786/irq.c create mode 100644 arch/sh/include/mach-sdk7786/mach/irq.h (limited to 'arch/sh') diff --git a/arch/sh/boards/mach-sdk7786/Makefile b/arch/sh/boards/mach-sdk7786/Makefile index 50c8065deaa0..a29f19e85b63 100644 --- a/arch/sh/boards/mach-sdk7786/Makefile +++ b/arch/sh/boards/mach-sdk7786/Makefile @@ -1 +1 @@ -obj-y := setup.o fpga.o +obj-y := setup.o fpga.o irq.o diff --git a/arch/sh/boards/mach-sdk7786/irq.c b/arch/sh/boards/mach-sdk7786/irq.c new file mode 100644 index 000000000000..46943a0da5b7 --- /dev/null +++ b/arch/sh/boards/mach-sdk7786/irq.c @@ -0,0 +1,48 @@ +/* + * SDK7786 FPGA IRQ Controller Support. + * + * Copyright (C) 2010 Matt Fleming + * Copyright (C) 2010 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. + */ +#include +#include +#include + +enum { + ATA_IRQ_BIT = 1, + SPI_BUSY_BIT = 2, + LIRQ5_BIT = 3, + LIRQ6_BIT = 4, + LIRQ7_BIT = 5, + LIRQ8_BIT = 6, + KEY_IRQ_BIT = 7, + PEN_IRQ_BIT = 8, + ETH_IRQ_BIT = 9, + RTC_ALARM_BIT = 10, + CRYSTAL_FAIL_BIT = 12, + ETH_PME_BIT = 14, +}; + +void __init sdk7786_init_irq(void) +{ + unsigned int tmp; + + /* Enable priority encoding for all IRLs */ + fpga_write_reg(fpga_read_reg(INTMSR) | 0x0303, INTMSR); + + /* Clear FPGA interrupt status registers */ + fpga_write_reg(0x0000, INTASR); + fpga_write_reg(0x0000, INTBSR); + + /* Unmask FPGA interrupts */ + tmp = fpga_read_reg(INTAMR); + tmp &= ~(1 << ETH_IRQ_BIT); + fpga_write_reg(tmp, INTAMR); + + plat_irq_setup_pins(IRQ_MODE_IRL7654_MASK); + plat_irq_setup_pins(IRQ_MODE_IRL3210_MASK); +} diff --git a/arch/sh/boards/mach-sdk7786/setup.c b/arch/sh/boards/mach-sdk7786/setup.c index 8dbbdea9c983..3c3c9a38cfda 100644 --- a/arch/sh/boards/mach-sdk7786/setup.c +++ b/arch/sh/boards/mach-sdk7786/setup.c @@ -15,10 +15,11 @@ #include #include #include +#include +#include #include #include #include -#include static struct resource heartbeat_resource = { .start = 0x07fff8b0, @@ -132,41 +133,6 @@ static int __init sdk7786_devices_setup(void) } __initcall(sdk7786_devices_setup); -enum { - ATA_IRQ_BIT = 1, - SPI_BUSY_BIT = 2, - LIRQ5_BIT = 3, - LIRQ6_BIT = 4, - LIRQ7_BIT = 5, - LIRQ8_BIT = 6, - KEY_IRQ_BIT = 7, - PEN_IRQ_BIT = 8, - ETH_IRQ_BIT = 9, - RTC_ALARM_BIT = 10, - CRYSTAL_FAIL_BIT = 12, - ETH_PME_BIT = 14, -}; - -static void __init init_sdk7786_IRQ(void) -{ - unsigned int tmp; - - /* Enable priority encoding for all IRLs */ - fpga_write_reg(fpga_read_reg(INTMSR) | 0x0303, INTMSR); - - /* Clear FPGA interrupt status registers */ - fpga_write_reg(0x0000, INTASR); - fpga_write_reg(0x0000, INTBSR); - - /* Unmask FPGA interrupts */ - tmp = fpga_read_reg(INTAMR); - tmp &= ~(1 << ETH_IRQ_BIT); - fpga_write_reg(tmp, INTAMR); - - plat_irq_setup_pins(IRQ_MODE_IRL7654_MASK); - plat_irq_setup_pins(IRQ_MODE_IRL3210_MASK); -} - static int sdk7786_mode_pins(void) { return fpga_read_reg(MODSWR); @@ -211,5 +177,5 @@ static struct sh_machine_vector mv_sdk7786 __initmv = { .mv_setup = sdk7786_setup, .mv_mode_pins = sdk7786_mode_pins, .mv_clk_init = sdk7786_clk_init, - .mv_init_irq = init_sdk7786_IRQ, + .mv_init_irq = sdk7786_init_irq, }; diff --git a/arch/sh/include/mach-sdk7786/mach/irq.h b/arch/sh/include/mach-sdk7786/mach/irq.h new file mode 100644 index 000000000000..0f584635e6e5 --- /dev/null +++ b/arch/sh/include/mach-sdk7786/mach/irq.h @@ -0,0 +1,7 @@ +#ifndef __MACH_SDK7786_IRQ_H +#define __MACH_SDK7786_IRQ_H + +/* arch/sh/boards/mach-sdk7786/irq.c */ +extern void sdk7786_init_irq(void); + +#endif /* __MACH_SDK7786_IRQ_H */ -- cgit v1.2.3 From 2efa53b269ec1e9289a108e1506f53f6f1de440b Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 20 Jan 2010 16:40:48 +0900 Subject: sh: Make 29/32-bit mode check helper generally available. Presently __in_29bit_mode() is only defined for the PMB case, but it's also easily derived from the CONFIG_29BIT and CONFIG_32BIT && CONFIG_PMB=n cases. Signed-off-by: Paul Mundt --- arch/sh/include/asm/addrspace.h | 6 ------ arch/sh/include/asm/mmu.h | 10 +++++++++- arch/sh/mm/init.c | 7 ------- arch/sh/mm/pmb.c | 5 +++++ 4 files changed, 14 insertions(+), 14 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/addrspace.h b/arch/sh/include/asm/addrspace.h index 268efd62ed21..446b3831c214 100644 --- a/arch/sh/include/asm/addrspace.h +++ b/arch/sh/include/asm/addrspace.h @@ -65,11 +65,5 @@ #define P3_ADDR_MAX P4SEG #endif -#ifndef __ASSEMBLY__ -#ifdef CONFIG_PMB -extern int __in_29bit_mode(void); -#endif /* CONFIG_PMB */ -#endif /* __ASSEMBLY__ */ - #endif /* __KERNEL__ */ #endif /* __ASM_SH_ADDRSPACE_H */ diff --git a/arch/sh/include/asm/mmu.h b/arch/sh/include/asm/mmu.h index e5e8f48830ef..ca7d91e8aa72 100644 --- a/arch/sh/include/asm/mmu.h +++ b/arch/sh/include/asm/mmu.h @@ -31,6 +31,7 @@ #ifndef __ASSEMBLY__ #include +#include /* Default "unsigned long" context */ typedef unsigned long mm_context_id_t[NR_CPUS]; @@ -72,6 +73,7 @@ long pmb_remap(unsigned long virt, unsigned long phys, unsigned long size, unsigned long flags); void pmb_unmap(unsigned long addr); int pmb_init(void); +bool __in_29bit_mode(void); #else static inline long pmb_remap(unsigned long virt, unsigned long phys, unsigned long size, unsigned long flags) @@ -87,8 +89,14 @@ static inline int pmb_init(void) { return -ENODEV; } -#endif /* CONFIG_PMB */ +#ifdef CONFIG_29BIT +#define __in_29bit_mode() (1) +#else +#define __in_29bit_mode() (0) +#endif + +#endif /* CONFIG_PMB */ #endif /* __ASSEMBLY__ */ #endif /* __MMU_H */ diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 32ebd1592e63..491d9d5c8e0d 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -338,10 +338,3 @@ EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid); #endif #endif /* CONFIG_MEMORY_HOTPLUG */ - -#ifdef CONFIG_PMB -int __in_29bit_mode(void) -{ - return !(ctrl_inl(PMB_PASCR) & PASCR_SE); -} -#endif /* CONFIG_PMB */ diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c index b796b6c021b4..d318fa6caffe 100644 --- a/arch/sh/mm/pmb.c +++ b/arch/sh/mm/pmb.c @@ -436,6 +436,11 @@ int __uses_jump_to_uncached pmb_init(void) return 0; } +bool __in_29bit_mode(void) +{ + return (__raw_readl(PMB_PASCR) & PASCR_SE) == 0; +} + static int pmb_seq_show(struct seq_file *file, void *iter) { int i; -- cgit v1.2.3 From fbb82b03653cdb7fd1863b911e7540011259d2ce Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 20 Jan 2010 16:42:52 +0900 Subject: sh: machine_ops based reboot support. This provides a machine_ops-based reboot interface loosely cloned from x86, and converts the native sh32 and sh64 cases over to it. Necessary both for tying in SMP support and also enabling platforms like SDK7786 to add support for their microcontroller-based power managers. Signed-off-by: Paul Mundt --- arch/sh/include/asm/reboot.h | 21 +++++++++ arch/sh/include/asm/system.h | 1 + arch/sh/include/asm/system_32.h | 12 +++++ arch/sh/include/asm/system_64.h | 7 +++ arch/sh/kernel/Makefile | 3 +- arch/sh/kernel/idle.c | 14 ++++-- arch/sh/kernel/machine_kexec.c | 8 ++-- arch/sh/kernel/process_32.c | 48 -------------------- arch/sh/kernel/process_64.c | 25 +---------- arch/sh/kernel/reboot.c | 98 +++++++++++++++++++++++++++++++++++++++++ arch/sh/kernel/smp.c | 9 ---- 11 files changed, 156 insertions(+), 90 deletions(-) create mode 100644 arch/sh/include/asm/reboot.h create mode 100644 arch/sh/kernel/reboot.c (limited to 'arch/sh') diff --git a/arch/sh/include/asm/reboot.h b/arch/sh/include/asm/reboot.h new file mode 100644 index 000000000000..b3da0c63fc3d --- /dev/null +++ b/arch/sh/include/asm/reboot.h @@ -0,0 +1,21 @@ +#ifndef __ASM_SH_REBOOT_H +#define __ASM_SH_REBOOT_H + +#include + +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/system.h b/arch/sh/include/asm/system.h index 62e4fc1e4409..de2fc3963c12 100644 --- a/arch/sh/include/asm/system.h +++ b/arch/sh/include/asm/system.h @@ -143,6 +143,7 @@ extern struct dentry *sh_debugfs_root; void per_cpu_trap_init(void); void default_idle(void); void cpu_idle_wait(void); +void stop_this_cpu(void *); #ifdef CONFIG_SUPERH32 #define BUILD_TRAP_HANDLER(name) \ diff --git a/arch/sh/include/asm/system_32.h b/arch/sh/include/asm/system_32.h index 06814f5b59c7..34bd2bac9a5f 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 +#include #ifdef CONFIG_SH_DSP @@ -216,6 +217,17 @@ static inline reg_size_t register_align(void *val) int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs, struct mem_access *ma, int); +static inline void trigger_address_error(void) +{ + if (__in_29bit_mode()) + __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, unsigned long address); diff --git a/arch/sh/include/asm/system_64.h b/arch/sh/include/asm/system_64.h index ab1dd917ea87..604ba7802cc2 100644 --- a/arch/sh/include/asm/system_64.h +++ b/arch/sh/include/asm/system_64.h @@ -48,6 +48,13 @@ 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) diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile index 56704a6d723a..02fd3ae8b0ee 100644 --- a/arch/sh/kernel/Makefile +++ b/arch/sh/kernel/Makefile @@ -14,7 +14,8 @@ CFLAGS_REMOVE_return_address.o = -pg obj-y := debugtraps.o dma-nommu.o dumpstack.o \ idle.o io.o io_generic.o irq.o \ irq_$(BITS).o machvec.o nmi_debug.o process.o \ - process_$(BITS).o ptrace_$(BITS).o return_address.o \ + process_$(BITS).o ptrace_$(BITS).o \ + reboot.o return_address.o \ setup.o signal_$(BITS).o sys_sh.o sys_sh$(BITS).o \ syscalls_$(BITS).o time.o topology.o traps.o \ traps_$(BITS).o unwinder.o diff --git a/arch/sh/kernel/idle.c b/arch/sh/kernel/idle.c index 6b3d706deac1..0fd7b41f0a22 100644 --- a/arch/sh/kernel/idle.c +++ b/arch/sh/kernel/idle.c @@ -20,10 +20,9 @@ #include #include -static int hlt_counter; void (*pm_idle)(void) = NULL; -void (*pm_power_off)(void); -EXPORT_SYMBOL(pm_power_off); + +static int hlt_counter; static int __init nohlt_setup(char *__unused) { @@ -131,6 +130,15 @@ static void do_nothing(void *unused) { } +void stop_this_cpu(void *unused) +{ + local_irq_disable(); + cpu_clear(smp_processor_id(), cpu_online_map); + + for (;;) + cpu_sleep(); +} + /* * cpu_idle_wait - Used to ensure that all the CPUs discard old value of * pm_idle and update to new pm_idle value. Required while changing pm_idle diff --git a/arch/sh/kernel/machine_kexec.c b/arch/sh/kernel/machine_kexec.c index f52d8ed69e12..7672141c841b 100644 --- a/arch/sh/kernel/machine_kexec.c +++ b/arch/sh/kernel/machine_kexec.c @@ -22,6 +22,7 @@ #include #include #include +#include typedef void (*relocate_new_kernel_t)(unsigned long indirection_page, unsigned long reboot_code_buffer, @@ -31,12 +32,9 @@ extern const unsigned char relocate_new_kernel[]; extern const unsigned int relocate_new_kernel_size; extern void *vbr_base; -void machine_shutdown(void) -{ -} - -void machine_crash_shutdown(struct pt_regs *regs) +void native_machine_crash_shutdown(struct pt_regs *regs) { + /* Nothing to do for UP, but definitely broken for SMP.. */ } /* diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c index 856010f9ebc9..b6f43f0ea743 100644 --- a/arch/sh/kernel/process_32.c +++ b/arch/sh/kernel/process_32.c @@ -16,63 +16,15 @@ #include #include #include -#include #include -#include -#include -#include -#include #include #include -#include #include #include #include -#include #include #include #include -#include - -#ifdef CONFIG_32BIT -static void watchdog_trigger_immediate(void) -{ - sh_wdt_write_cnt(0xFF); - sh_wdt_write_csr(0xC2); -} - -void machine_restart(char * __unused) -{ - local_irq_disable(); - - /* Use watchdog timer to trigger reset */ - watchdog_trigger_immediate(); - - while (1) - cpu_sleep(); -} -#else -void machine_restart(char * __unused) -{ - /* SR.BL=1 and invoke address error to let CPU reset (manual reset) */ - asm volatile("ldc %0, sr\n\t" - "mov.l @%1, %0" : : "r" (0x10000000), "r" (0x80000001)); -} -#endif - -void machine_halt(void) -{ - local_irq_disable(); - - while (1) - cpu_sleep(); -} - -void machine_power_off(void) -{ - if (pm_power_off) - pm_power_off(); -} void show_regs(struct pt_regs * regs) { diff --git a/arch/sh/kernel/process_64.c b/arch/sh/kernel/process_64.c index c9554a70bd0e..6ae5987230f8 100644 --- a/arch/sh/kernel/process_64.c +++ b/arch/sh/kernel/process_64.c @@ -32,30 +32,7 @@ struct task_struct *last_task_used_math = NULL; -void machine_restart(char * __unused) -{ - extern void phys_stext(void); - - phys_stext(); -} - -void machine_halt(void) -{ - for (;;); -} - -void machine_power_off(void) -{ - __asm__ __volatile__ ( - "sleep\n\t" - "synci\n\t" - "nop;nop;nop;nop\n\t" - ); - - panic("Unexpected wakeup!\n"); -} - -void show_regs(struct pt_regs * regs) +void show_regs(struct pt_regs *regs) { unsigned long long ah, al, bh, bl, ch, cl; diff --git a/arch/sh/kernel/reboot.c b/arch/sh/kernel/reboot.c new file mode 100644 index 000000000000..b1fca66bb92e --- /dev/null +++ b/arch/sh/kernel/reboot.c @@ -0,0 +1,98 @@ +#include +#include +#include +#include +#include +#ifdef CONFIG_SUPERH32 +#include +#endif +#include +#include +#include + +void (*pm_power_off)(void); +EXPORT_SYMBOL(pm_power_off); + +#ifdef CONFIG_SUPERH32 +static void watchdog_trigger_immediate(void) +{ + sh_wdt_write_cnt(0xFF); + sh_wdt_write_csr(0xC2); +} +#endif + +static void native_machine_restart(char * __unused) +{ + local_irq_disable(); + + /* Address error with SR.BL=1 first. */ + trigger_address_error(); + +#ifdef CONFIG_SUPERH32 + /* If that fails or is unsupported, go for the watchdog next. */ + watchdog_trigger_immediate(); +#endif + + /* + * Give up and sleep. + */ + while (1) + cpu_sleep(); +} + +static void native_machine_shutdown(void) +{ + smp_send_stop(); +} + +static void native_machine_power_off(void) +{ + if (pm_power_off) + pm_power_off(); +} + +static void native_machine_halt(void) +{ + /* stop other cpus */ + machine_shutdown(); + + /* stop this cpu */ + stop_this_cpu(NULL); +} + +struct machine_ops machine_ops = { + .power_off = native_machine_power_off, + .shutdown = native_machine_shutdown, + .restart = native_machine_restart, + .halt = native_machine_halt, +#ifdef CONFIG_KEXEC + .crash_shutdown = native_machine_crash_shutdown, +#endif +}; + +void machine_power_off(void) +{ + machine_ops.power_off(); +} + +void machine_shutdown(void) +{ + machine_ops.shutdown(); +} + +void machine_restart(char *cmd) +{ + machine_ops.restart(cmd); +} + +void machine_halt(void) +{ + machine_ops.halt(); +} + +#ifdef CONFIG_KEXEC +void machine_crash_shutdown(struct pt_regs *regs) +{ + machine_ops.crash_shutdown(regs); +} +#endif diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c index 983e0792d5f3..e124cf7008df 100644 --- a/arch/sh/kernel/smp.c +++ b/arch/sh/kernel/smp.c @@ -161,15 +161,6 @@ void smp_send_reschedule(int cpu) plat_send_ipi(cpu, SMP_MSG_RESCHEDULE); } -static void stop_this_cpu(void *unused) -{ - cpu_clear(smp_processor_id(), cpu_online_map); - local_irq_disable(); - - for (;;) - cpu_relax(); -} - void smp_send_stop(void) { smp_call_function(stop_this_cpu, 0, 0); -- cgit v1.2.3 From b51989b8afe9409ee68c67ce2a5de4390693bd2b Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 20 Jan 2010 16:53:11 +0900 Subject: sh: mach-sdk7786: reset controller reboot support. This wires up the machine_ops reboot call to use the system reset controller. Signed-off-by: Paul Mundt --- arch/sh/boards/mach-sdk7786/setup.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/boards/mach-sdk7786/setup.c b/arch/sh/boards/mach-sdk7786/setup.c index 3c3c9a38cfda..f094ea2ee783 100644 --- a/arch/sh/boards/mach-sdk7786/setup.c +++ b/arch/sh/boards/mach-sdk7786/setup.c @@ -20,6 +20,7 @@ #include #include #include +#include static struct resource heartbeat_resource = { .start = 0x07fff8b0, @@ -159,6 +160,11 @@ static int sdk7786_clk_init(void) return ret; } +static void sdk7786_restart(char *cmd) +{ + fpga_write_reg(0xa5a5, SRSTR); +} + /* Initialize the board */ static void __init sdk7786_setup(char **cmdline_p) { @@ -167,6 +173,8 @@ static void __init sdk7786_setup(char **cmdline_p) sdk7786_fpga_init(); pr_info("\tPCB revision:\t%d\n", fpga_read_reg(PCBRR) & 0xf); + + machine_ops.restart = sdk7786_restart; } /* -- cgit v1.2.3 From 920efaabcbd34e6b8dc05c5b777df3e936af5812 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 20 Jan 2010 18:10:30 +0900 Subject: sh: Correct iounmap fixmap teardown. iounmap_fixed() had a couple of bugs in it that caused it to effectively fail at life. The total number of pages to unmap factored in the mapping offset and aligned up to the next page boundary, which doesn't match the ioremap_fixed() behaviour. When ioremap_fixed() pegs a slot, the address in the mapping data already contains the offset displacement, and the size is recorded verbatim given that we're only interested in total number of pages required. As such, we need to calculate the total number from the original size in the unmap path as well. At the same time, there was also an off-by-1 problem in the fixmap index calculation which has also been corrected. Previously subsequent remaps of an identical fixmap index would trigger the pte_ERROR() in set_pte_phys(): arch/sh/mm/init.c:77: bad pte 8053ffb0(0000781003fff506). arch/sh/mm/init.c:77: bad pte 8053ffb0(0000781003fff506). arch/sh/mm/init.c:77: bad pte 8053ffb0(0000781003fff506). arch/sh/mm/init.c:77: bad pte 8053ffb0(0000781003fff506). arch/sh/mm/init.c:77: bad pte 8053ffb0(0000781003fff506). arch/sh/mm/init.c:77: bad pte 8053ffb0(0000781003fff506). With this patch in place, the iounmap-driven fixmap teardown actually does what it's supposed to do. Signed-off-by: Paul Mundt --- arch/sh/mm/ioremap_fixed.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/mm/ioremap_fixed.c b/arch/sh/mm/ioremap_fixed.c index 551b513e8fce..0b78b1e20ef1 100644 --- a/arch/sh/mm/ioremap_fixed.c +++ b/arch/sh/mm/ioremap_fixed.c @@ -93,9 +93,7 @@ ioremap_fixed(resource_size_t phys_addr, unsigned long offset, int iounmap_fixed(void __iomem *addr) { enum fixed_addresses idx; - unsigned long virt_addr; struct ioremap_map *map; - unsigned long offset; unsigned int nrpages; int i, slot; @@ -114,12 +112,9 @@ int iounmap_fixed(void __iomem *addr) if (slot < 0) return -EINVAL; - virt_addr = (unsigned long)addr; + nrpages = map->size >> PAGE_SHIFT; - offset = virt_addr & ~PAGE_MASK; - nrpages = PAGE_ALIGN(offset + map->size - 1) >> PAGE_SHIFT; - - idx = FIX_IOREMAP_BEGIN + slot + nrpages; + idx = FIX_IOREMAP_BEGIN + slot + nrpages - 1; while (nrpages > 0) { __clear_fixmap(idx, __pgprot(_PAGE_WIRED)); --idx; -- cgit v1.2.3 From d9116d07f60383cef134c43a0ba15ec4375310fc Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 20 Jan 2010 18:25:19 +0900 Subject: sh: mach-sdk7786: Probe system FPGA area mapping. This implements dynamic probing for the system FPGA. The system reset controller contains a fixed magic read word in order to identify the FPGA. This just utilizes a simple loop that scans across all of the fixed physical areas (area 0 through area 6) to locate the FPGA. The FPGA also contains register information detailing the area mappings and chip select settings for all of the other blocks, so this needs to be done before we can set up anything else. Signed-off-by: Paul Mundt --- arch/sh/boards/mach-sdk7786/fpga.c | 43 +++++++++++++++++++++++++++++--- arch/sh/include/cpu-sh4/cpu/addrspace.h | 9 +++++++ arch/sh/include/mach-sdk7786/mach/fpga.h | 2 ++ 3 files changed, 50 insertions(+), 4 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/boards/mach-sdk7786/fpga.c b/arch/sh/boards/mach-sdk7786/fpga.c index 99f903c8b238..3e4ec66a0417 100644 --- a/arch/sh/boards/mach-sdk7786/fpga.c +++ b/arch/sh/boards/mach-sdk7786/fpga.c @@ -11,9 +11,44 @@ #include #include #include +#include -#define FPGA_REGS_BASE 0x07fff800 -#define FPGA_REGS_SIZE 0x490 +#define FPGA_REGS_OFFSET 0x03fff800 +#define FPGA_REGS_SIZE 0x490 + +/* + * The FPGA can be mapped in any of the generally available areas, + * so we attempt to scan for it using the fixed SRSTR read magic. + * + * Once the FPGA is located, the rest of the mapping data for the other + * components can be determined dynamically from its section mapping + * registers. + */ +static void __iomem *sdk7786_fpga_probe(void) +{ + unsigned long area; + void __iomem *base; + + /* + * Iterate over all of the areas where the FPGA could be mapped. + * The possible range is anywhere from area 0 through 6, area 7 + * is reserved. + */ + for (area = PA_AREA0; area < PA_AREA7; area += SZ_64M) { + base = ioremap_nocache(area + FPGA_REGS_OFFSET, FPGA_REGS_SIZE); + if (!base) { + /* Failed to remap this area, move along. */ + continue; + } + + if (ioread16(base + SRSTR) == SRSTR_MAGIC) + return base; /* Found it! */ + + iounmap(base); + } + + return NULL; +} void __iomem *sdk7786_fpga_base; @@ -21,9 +56,9 @@ void __init sdk7786_fpga_init(void) { u16 version, date; - sdk7786_fpga_base = ioremap_nocache(FPGA_REGS_BASE, FPGA_REGS_SIZE); + sdk7786_fpga_base = sdk7786_fpga_probe(); if (unlikely(!sdk7786_fpga_base)) { - panic("FPGA remapping failed.\n"); + panic("FPGA detection failed.\n"); return; } diff --git a/arch/sh/include/cpu-sh4/cpu/addrspace.h b/arch/sh/include/cpu-sh4/cpu/addrspace.h index a3fa733c1c7d..d51da25da72c 100644 --- a/arch/sh/include/cpu-sh4/cpu/addrspace.h +++ b/arch/sh/include/cpu-sh4/cpu/addrspace.h @@ -28,6 +28,15 @@ #define P4SEG_TLB_DATA 0xf7000000 #define P4SEG_REG_BASE 0xff000000 +#define PA_AREA0 0x00000000 +#define PA_AREA1 0x04000000 +#define PA_AREA2 0x08000000 +#define PA_AREA3 0x0c000000 +#define PA_AREA4 0x10000000 +#define PA_AREA5 0x14000000 +#define PA_AREA6 0x18000000 +#define PA_AREA7 0x1c000000 + #define PA_AREA5_IO 0xb4000000 /* Area 5 IO Memory */ #define PA_AREA6_IO 0xb8000000 /* Area 6 IO Memory */ diff --git a/arch/sh/include/mach-sdk7786/mach/fpga.h b/arch/sh/include/mach-sdk7786/mach/fpga.h index a85d9853d34f..2120d67dec70 100644 --- a/arch/sh/include/mach-sdk7786/mach/fpga.h +++ b/arch/sh/include/mach-sdk7786/mach/fpga.h @@ -6,6 +6,8 @@ #include #define SRSTR 0x000 +#define SRSTR_MAGIC 0x1971 /* Fixed magical read value */ + #define INTASR 0x010 #define INTAMR 0x020 #define MODSWR 0x030 -- cgit v1.2.3 From 35f99c0da17beb5004f06ba86a87d82c1a6467be Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 20 Jan 2010 18:48:17 +0900 Subject: sh: pretty print virtual memory map on boot. This cribs the pretty printing from arch/x86/mm/init_32.c to dump the virtual memory layout on boot. This is primarily intended as a debugging aid, given that the newer CPUs have full control over their address space and as such have little to nothing in common with the legacy layout. Signed-off-by: Paul Mundt --- arch/sh/mm/init.c | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 491d9d5c8e0d..f3e23ad075cb 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -260,6 +260,9 @@ void __init mem_init(void) memset(empty_zero_page, 0, PAGE_SIZE); __flush_wback_region(empty_zero_page, PAGE_SIZE); + /* Initialize the vDSO */ + vsyscall_init(); + codesize = (unsigned long) &_etext - (unsigned long) &_text; datasize = (unsigned long) &_edata - (unsigned long) &_etext; initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; @@ -272,8 +275,39 @@ void __init mem_init(void) datasize >> 10, initsize >> 10); - /* Initialize the vDSO */ - vsyscall_init(); + printk(KERN_INFO "virtual kernel memory layout:\n" + " fixmap : 0x%08lx - 0x%08lx (%4ld kB)\n" +#ifdef CONFIG_HIGHMEM + " pkmap : 0x%08lx - 0x%08lx (%4ld kB)\n" +#endif + " vmalloc : 0x%08lx - 0x%08lx (%4ld MB)\n" + " lowmem : 0x%08lx - 0x%08lx (%4ld MB)\n" + " .init : 0x%08lx - 0x%08lx (%4ld kB)\n" + " .data : 0x%08lx - 0x%08lx (%4ld kB)\n" + " .text : 0x%08lx - 0x%08lx (%4ld kB)\n", + FIXADDR_START, FIXADDR_TOP, + (FIXADDR_TOP - FIXADDR_START) >> 10, + +#ifdef CONFIG_HIGHMEM + PKMAP_BASE, PKMAP_BASE+LAST_PKMAP*PAGE_SIZE, + (LAST_PKMAP*PAGE_SIZE) >> 10, +#endif + + (unsigned long)VMALLOC_START, VMALLOC_END, + (VMALLOC_END - VMALLOC_START) >> 20, + + (unsigned long)memory_start, (unsigned long)high_memory, + ((unsigned long)high_memory - (unsigned long)memory_start) >> 20, + + (unsigned long)&__init_begin, (unsigned long)&__init_end, + ((unsigned long)&__init_end - + (unsigned long)&__init_begin) >> 10, + + (unsigned long)&_etext, (unsigned long)&_edata, + ((unsigned long)&_edata - (unsigned long)&_etext) >> 10, + + (unsigned long)&_text, (unsigned long)&_etext, + ((unsigned long)&_etext - (unsigned long)&_text) >> 10); mem_init_done = 1; } -- cgit v1.2.3 From 77c2019fc1b4495ce483ef2af9cb12bae23e353b Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 21 Jan 2010 14:19:41 +0900 Subject: sh: initial PMB mapping iteration by helper macro. All of the cached/uncached mapping setup is duplicated for each size, and also misses out on the 16MB case. Rather than duplicating the same iter code for that we just consolidate it in to a helper macro that builds an iter for each size. The 16MB case is then trivially bolted on at the end. Signed-off-by: Paul Mundt --- arch/sh/kernel/head_32.S | 207 ++++++++++++++--------------------------------- 1 file changed, 60 insertions(+), 147 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/kernel/head_32.S b/arch/sh/kernel/head_32.S index 8ee31a0b973e..ee954d1b8cc6 100644 --- a/arch/sh/kernel/head_32.S +++ b/arch/sh/kernel/head_32.S @@ -86,6 +86,62 @@ ENTRY(_stext) #endif #if defined(CONFIG_PMB) && !defined(CONFIG_PMB_LEGACY) + +#define __PMB_ITER_BY_SIZE(size) \ +.L##size: \ + mov #(size >> 4), r6; \ + shll16 r6; \ + shll8 r6; \ + \ + cmp/hi r5, r6; \ + bt 9999f; \ + \ + mov #(PMB_SZ_##size##M >> 2), r9; \ + shll2 r9; \ + \ + /* \ + * Cached mapping \ + */ \ + mov #PMB_C, r8; \ + or r0, r8; \ + or r9, r8; \ + mov.l r8, @r1; \ + mov.l r2, @r3; \ + \ + /* Increment to the next PMB_DATA entry */ \ + add r4, r1; \ + /* Increment to the next PMB_ADDR entry */ \ + add r4, r3; \ + /* Increment number of PMB entries */ \ + add #1, r10; \ + \ + /* \ + * Uncached mapping \ + */ \ + mov #(PMB_UB >> 8), r8; \ + shll8 r8; \ + \ + or r0, r8; \ + or r9, r8; \ + mov.l r8, @r1; \ + mov r2, r8; \ + add r7, r8; \ + mov.l r8, @r3; \ + \ + /* Increment to the next PMB_DATA entry */ \ + add r4, r1; \ + /* Increment to the next PMB_ADDR entry */ \ + add r4, r3; \ + /* Increment number of PMB entries */ \ + add #1, r10; \ + \ + sub r6, r5; \ + add r6, r0; \ + add r6, r2; \ + \ + bra .L##size; \ +9999: + /* * Reconfigure the initial PMB mappings setup by the hardware. * @@ -142,154 +198,11 @@ ENTRY(_stext) * r9 = scratch register * r10 = number of PMB entries we've setup */ -.L512: - mov #(512 >> 4), r6 - shll16 r6 - shll8 r6 - - cmp/hi r5, r6 - bt .L128 - - mov #(PMB_SZ_512M >> 2), r9 - shll2 r9 - - /* - * Cached mapping - */ - mov #PMB_C, r8 - or r0, r8 - or r9, r8 - mov.l r8, @r1 - mov.l r2, @r3 - - add r4, r1 /* Increment to the next PMB_DATA entry */ - add r4, r3 /* Increment to the next PMB_ADDR entry */ - - add #1, r10 /* Increment number of PMB entries */ - - /* - * Uncached mapping - */ - mov #(PMB_UB >> 8), r8 - shll8 r8 - - or r0, r8 - or r9, r8 - mov.l r8, @r1 - mov r2, r8 - add r7, r8 - mov.l r8, @r3 - - add r4, r1 /* Increment to the next PMB_DATA entry */ - add r4, r3 /* Increment to the next PMB_ADDR entry */ - - add #1, r10 /* Increment number of PMB entries */ - - sub r6, r5 - add r6, r0 - add r6, r2 - - bra .L512 - -.L128: - mov #(128 >> 4), r6 - shll16 r6 - shll8 r6 - - cmp/hi r5, r6 - bt .L64 - - mov #(PMB_SZ_128M >> 2), r9 - shll2 r9 - - /* - * Cached mapping - */ - mov #PMB_C, r8 - or r0, r8 - or r9, r8 - mov.l r8, @r1 - mov.l r2, @r3 - - add r4, r1 /* Increment to the next PMB_DATA entry */ - add r4, r3 /* Increment to the next PMB_ADDR entry */ - - add #1, r10 /* Increment number of PMB entries */ - - /* - * Uncached mapping - */ - mov #(PMB_UB >> 8), r8 - shll8 r8 - - or r0, r8 - or r9, r8 - mov.l r8, @r1 - mov r2, r8 - add r7, r8 - mov.l r8, @r3 - - add r4, r1 /* Increment to the next PMB_DATA entry */ - add r4, r3 /* Increment to the next PMB_ADDR entry */ - - add #1, r10 /* Increment number of PMB entries */ - - sub r6, r5 - add r6, r0 - add r6, r2 - - bra .L128 - -.L64: - mov #(64 >> 4), r6 - shll16 r6 - shll8 r6 - - cmp/hi r5, r6 - bt .Ldone - - mov #(PMB_SZ_64M >> 2), r9 - shll2 r9 - - /* - * Cached mapping - */ - mov #PMB_C, r8 - or r0, r8 - or r9, r8 - mov.l r8, @r1 - mov.l r2, @r3 - - add r4, r1 /* Increment to the next PMB_DATA entry */ - add r4, r3 /* Increment to the next PMB_ADDR entry */ - - add #1, r10 /* Increment number of PMB entries */ - - /* - * Uncached mapping - */ - mov #(PMB_UB >> 8), r8 - shll8 r8 - - or r0, r8 - or r9, r8 - mov.l r8, @r1 - mov r2, r8 - add r7, r8 - mov.l r8, @r3 - - add r4, r1 /* Increment to the next PMB_DATA entry */ - add r4, r3 /* Increment to the next PMB_ADDR entry */ - - add #1, r10 /* Increment number of PMB entries */ - - sub r6, r5 - add r6, r0 - add r6, r2 - - bra .L64 + __PMB_ITER_BY_SIZE(512) + __PMB_ITER_BY_SIZE(128) + __PMB_ITER_BY_SIZE(64) + __PMB_ITER_BY_SIZE(16) -.Ldone: /* Update cached_to_uncached */ mov.l .Lcached_to_uncached, r0 mov.l r7, @r0 -- cgit v1.2.3 From 2023b843d7b62d99e7356b872e99abc7d6667e49 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 21 Jan 2010 15:42:58 +0900 Subject: sh: Rework P2 to only include kernel text. This effectively neutralizes P2 by getting rid of P1 identity mapping for all available memory and instead only establishes a single unbuffered PMB entry (16MB -- the smallest available) that covers the kernel. As using segmentation for abusing caching attributes in drivers is no longer supported (and there are no drivers that can be enabled in 32-bit mode that do this), this provides us with all of the uncached access needs by the kernel itself. Drivers and their ilk need to specify their caching attributes when remapping through page tables, as usual. Signed-off-by: Paul Mundt --- arch/sh/kernel/head_32.S | 169 ++++++++++++++++++++++++++--------------------- 1 file changed, 92 insertions(+), 77 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/kernel/head_32.S b/arch/sh/kernel/head_32.S index ee954d1b8cc6..e93320135cda 100644 --- a/arch/sh/kernel/head_32.S +++ b/arch/sh/kernel/head_32.S @@ -86,7 +86,96 @@ ENTRY(_stext) #endif #if defined(CONFIG_PMB) && !defined(CONFIG_PMB_LEGACY) +/* + * Reconfigure the initial PMB mappings setup by the hardware. + * + * When we boot in 32-bit MMU mode there are 2 PMB entries already + * setup for us. + * + * Entry VPN PPN V SZ C UB WT + * --------------------------------------------------------------- + * 0 0x80000000 0x00000000 1 512MB 1 0 1 + * 1 0xA0000000 0x00000000 1 512MB 0 0 0 + * + * But we reprogram them here because we want complete control over + * our address space and the initial mappings may not map PAGE_OFFSET + * to __MEMORY_START (or even map all of our RAM). + * + * Once we've setup cached and uncached mappings we clear the rest of the + * PMB entries. This clearing also deals with the fact that PMB entries + * can persist across reboots. The PMB could have been left in any state + * when the reboot occurred, so to be safe we clear all entries and start + * with with a clean slate. + * + * The uncached mapping is constructed using the smallest possible + * mapping with a single unbufferable page. Only the kernel text needs to + * be covered via the uncached mapping so that certain functions can be + * run uncached. + * + * Drivers and the like that have previously abused the 1:1 identity + * mapping are unsupported in 32-bit mode and must specify their caching + * preference when page tables are constructed. + * + * This frees up the P2 space for more nefarious purposes. + * + * Register utilization is as follows: + * + * r0 = PMB_DATA data field + * r1 = PMB_DATA address field + * r2 = PMB_ADDR data field + * r3 = PMB_ADDR address field + * r4 = PMB_E_SHIFT + * r5 = remaining amount of RAM to map + * r6 = PMB mapping size we're trying to use + * r7 = cached_to_uncached + * r8 = scratch register + * r9 = scratch register + * r10 = number of PMB entries we've setup + */ + + mov.l .LMMUCR, r1 /* Flush the TLB */ + mov.l @r1, r0 + or #MMUCR_TI, r0 + mov.l r0, @r1 + + mov.l .LMEMORY_SIZE, r5 + mov r5, r7 + + mov #PMB_E_SHIFT, r0 + mov #0x1, r4 + shld r0, r4 + mov.l .LFIRST_DATA_ENTRY, r0 + mov.l .LPMB_DATA, r1 + mov.l .LFIRST_ADDR_ENTRY, r2 + mov.l .LPMB_ADDR, r3 + + mov #0, r10 + + /* + * Uncached mapping + */ + mov #(PMB_SZ_16M >> 2), r9 + shll2 r9 + + mov #(PMB_UB >> 8), r8 + shll8 r8 + + or r0, r8 + or r9, r8 + mov.l r8, @r1 + mov r2, r8 + add r7, r8 + mov.l r8, @r3 + + add r4, r1 + add r4, r3 + add #1, r10 + +/* + * Iterate over all of the available sizes from largest to + * smallest for constructing the cached mapping. + */ #define __PMB_ITER_BY_SIZE(size) \ .L##size: \ mov #(size >> 4), r6; \ @@ -113,26 +202,6 @@ ENTRY(_stext) /* Increment to the next PMB_ADDR entry */ \ add r4, r3; \ /* Increment number of PMB entries */ \ - add #1, r10; \ - \ - /* \ - * Uncached mapping \ - */ \ - mov #(PMB_UB >> 8), r8; \ - shll8 r8; \ - \ - or r0, r8; \ - or r9, r8; \ - mov.l r8, @r1; \ - mov r2, r8; \ - add r7, r8; \ - mov.l r8, @r3; \ - \ - /* Increment to the next PMB_DATA entry */ \ - add r4, r1; \ - /* Increment to the next PMB_ADDR entry */ \ - add r4, r3; \ - /* Increment number of PMB entries */ \ add #1, r10; \ \ sub r6, r5; \ @@ -142,68 +211,14 @@ ENTRY(_stext) bra .L##size; \ 9999: - /* - * Reconfigure the initial PMB mappings setup by the hardware. - * - * When we boot in 32-bit MMU mode there are 2 PMB entries already - * setup for us. - * - * Entry VPN PPN V SZ C UB WT - * --------------------------------------------------------------- - * 0 0x80000000 0x00000000 1 512MB 1 0 1 - * 1 0xA0000000 0x00000000 1 512MB 0 0 0 - * - * But we reprogram them here because we want complete control over - * our address space and the initial mappings may not map PAGE_OFFSET - * to __MEMORY_START (or even map all of our RAM). - * - * Once we've setup cached and uncached mappings for all of RAM we - * clear the rest of the PMB entries. - * - * This clearing also deals with the fact that PMB entries can persist - * across reboots. The PMB could have been left in any state when the - * reboot occurred, so to be safe we clear all entries and start with - * with a clean slate. - */ - - mov.l .LMMUCR, r1 /* Flush the TLB */ - mov.l @r1, r0 - or #MMUCR_TI, r0 - mov.l r0, @r1 - - mov.l .LMEMORY_SIZE, r5 - mov r5, r7 - - mov #PMB_E_SHIFT, r0 - mov #0x1, r4 - shld r0, r4 - - mov.l .LFIRST_DATA_ENTRY, r0 - mov.l .LPMB_DATA, r1 - mov.l .LFIRST_ADDR_ENTRY, r2 - mov.l .LPMB_ADDR, r3 - - mov #0, r10 - - /* - * r0 = PMB_DATA data field - * r1 = PMB_DATA address field - * r2 = PMB_ADDR data field - * r3 = PMB_ADDR address field - * r4 = PMB_E_SHIFT - * r5 = remaining amount of RAM to map - * r6 = PMB mapping size we're trying to use - * r7 = cached_to_uncached - * r8 = scratch register - * r9 = scratch register - * r10 = number of PMB entries we've setup - */ __PMB_ITER_BY_SIZE(512) __PMB_ITER_BY_SIZE(128) __PMB_ITER_BY_SIZE(64) __PMB_ITER_BY_SIZE(16) - /* Update cached_to_uncached */ + /* + * Now that we can access it, update cached_to_uncached. + */ mov.l .Lcached_to_uncached, r0 mov.l r7, @r0 -- cgit v1.2.3 From 3125ee72dca25fc2157dcddd07e2d740db921fc4 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 21 Jan 2010 15:54:31 +0900 Subject: sh: Track the uncached mapping size. This provides a variable for tracking the uncached mapping size, and uses it for pretty printing the uncached lowmem range. Beyond this, we'll also be building on top of this for figuring out from where the remainder of P2 becomes usable when constructing unrelated mappings. Signed-off-by: Paul Mundt --- arch/sh/include/asm/system.h | 1 + arch/sh/kernel/head_32.S | 10 +++++++++- arch/sh/mm/init.c | 21 ++++++++++++++------- 3 files changed, 24 insertions(+), 8 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/system.h b/arch/sh/include/asm/system.h index de2fc3963c12..6442f1783fe0 100644 --- a/arch/sh/include/asm/system.h +++ b/arch/sh/include/asm/system.h @@ -137,6 +137,7 @@ extern unsigned int instruction_size(unsigned int insn); #endif extern unsigned long cached_to_uncached; +extern unsigned long uncached_size; extern struct dentry *sh_debugfs_root; diff --git a/arch/sh/kernel/head_32.S b/arch/sh/kernel/head_32.S index e93320135cda..83f2b84b58da 100644 --- a/arch/sh/kernel/head_32.S +++ b/arch/sh/kernel/head_32.S @@ -217,11 +217,18 @@ ENTRY(_stext) __PMB_ITER_BY_SIZE(16) /* - * Now that we can access it, update cached_to_uncached. + * Now that we can access it, update cached_to_uncached and + * uncached_size. */ mov.l .Lcached_to_uncached, r0 mov.l r7, @r0 + mov.l .Luncached_size, r0 + mov #1, r7 + shll16 r7 + shll8 r7 + mov.l r7, @r0 + /* * Clear the remaining PMB entries. * @@ -300,5 +307,6 @@ ENTRY(stack_start) .LFIRST_DATA_ENTRY: .long __MEMORY_START | PMB_V .LMMUCR: .long MMUCR .Lcached_to_uncached: .long cached_to_uncached +.Luncached_size: .long uncached_size .LMEMORY_SIZE: .long __MEMORY_SIZE #endif diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index f3e23ad075cb..a28ff63c17a6 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -27,15 +27,17 @@ pgd_t swapper_pg_dir[PTRS_PER_PGD]; #ifdef CONFIG_SUPERH32 /* - * Handle trivial transitions between cached and uncached - * segments, making use of the 1:1 mapping relationship in - * 512MB lowmem. - * * This is the offset of the uncached section from its cached alias. - * Default value only valid in 29 bit mode, in 32bit mode will be - * overridden in pmb_init. + * + * Legacy platforms handle trivial transitions between cached and + * uncached segments by making use of the 1:1 mapping relationship in + * 512MB lowmem, others via a special uncached mapping. + * + * Default value only valid in 29 bit mode, in 32bit mode this will be + * updated by the early PMB initialization code. */ unsigned long cached_to_uncached = P2SEG - P1SEG; +unsigned long uncached_size = 0x20000000; #endif #ifdef CONFIG_MMU @@ -281,7 +283,8 @@ void __init mem_init(void) " pkmap : 0x%08lx - 0x%08lx (%4ld kB)\n" #endif " vmalloc : 0x%08lx - 0x%08lx (%4ld MB)\n" - " lowmem : 0x%08lx - 0x%08lx (%4ld MB)\n" + " lowmem : 0x%08lx - 0x%08lx (%4ld MB) (cached)\n" + " : 0x%08lx - 0x%08lx (%4ld MB) (uncached)\n" " .init : 0x%08lx - 0x%08lx (%4ld kB)\n" " .data : 0x%08lx - 0x%08lx (%4ld kB)\n" " .text : 0x%08lx - 0x%08lx (%4ld kB)\n", @@ -299,6 +302,10 @@ void __init mem_init(void) (unsigned long)memory_start, (unsigned long)high_memory, ((unsigned long)high_memory - (unsigned long)memory_start) >> 20, + (unsigned long)memory_start + cached_to_uncached, + (unsigned long)memory_start + cached_to_uncached + uncached_size, + uncached_size >> 20, + (unsigned long)&__init_begin, (unsigned long)&__init_end, ((unsigned long)&__init_end - (unsigned long)&__init_begin) >> 10, -- cgit v1.2.3 From 2dc2f8e0c46864e2a3722c84eaa96513d4cf8b2f Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 21 Jan 2010 16:05:25 +0900 Subject: sh: Kill off the special uncached section and fixmap. Now that cached_to_uncached works as advertized in 32-bit mode and we're never going to be able to map < 16MB anyways, there's no need for the special uncached section. Kill it off. Signed-off-by: Paul Mundt --- arch/sh/include/asm/fixmap.h | 4 +++- arch/sh/include/asm/system_32.h | 3 --- arch/sh/include/asm/system_64.h | 2 -- arch/sh/kernel/cpu/init.c | 4 ++-- arch/sh/kernel/cpu/sh3/probe.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-sh7723.c | 3 ++- arch/sh/kernel/cpu/sh4a/setup-sh7724.c | 3 ++- arch/sh/kernel/vmlinux.lds.S | 12 ------------ arch/sh/mm/cache-debugfs.c | 3 +-- arch/sh/mm/cache-sh4.c | 4 ++-- arch/sh/mm/cache-sh7705.c | 4 ++-- arch/sh/mm/init.c | 3 --- arch/sh/mm/pmb.c | 6 +++--- arch/sh/mm/tlb-pteaex.c | 3 +-- arch/sh/mm/tlb-sh4.c | 3 +-- 15 files changed, 20 insertions(+), 39 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/fixmap.h b/arch/sh/include/asm/fixmap.h index 38a1de866873..17b22b6c1001 100644 --- a/arch/sh/include/asm/fixmap.h +++ b/arch/sh/include/asm/fixmap.h @@ -55,11 +55,12 @@ enum fixed_addresses { #define FIX_N_COLOURS 8 FIX_CMAP_BEGIN, FIX_CMAP_END = FIX_CMAP_BEGIN + (FIX_N_COLOURS * NR_CPUS) - 1, - FIX_UNCACHED, + #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, #endif + /* * FIX_IOREMAP entries are useful for mapping physical address * space before ioremap() is useable, e.g. really early in boot @@ -68,6 +69,7 @@ enum fixed_addresses { #define FIX_N_IOREMAPS 32 FIX_IOREMAP_BEGIN, FIX_IOREMAP_END = FIX_IOREMAP_BEGIN + FIX_N_IOREMAPS, + __end_of_fixed_addresses }; diff --git a/arch/sh/include/asm/system_32.h b/arch/sh/include/asm/system_32.h index 34bd2bac9a5f..51296b36770e 100644 --- a/arch/sh/include/asm/system_32.h +++ b/arch/sh/include/asm/system_32.h @@ -145,9 +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. diff --git a/arch/sh/include/asm/system_64.h b/arch/sh/include/asm/system_64.h index 604ba7802cc2..3391bb6b21d8 100644 --- a/arch/sh/include/asm/system_64.h +++ b/arch/sh/include/asm/system_64.h @@ -33,8 +33,6 @@ do { \ &next->thread); \ } while (0) -#define __uses_jump_to_uncached - #define jump_to_uncached() do { } while (0) #define back_to_cached() do { } while (0) diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c index a5bb0550bbf3..05a7d2a373b6 100644 --- a/arch/sh/kernel/cpu/init.c +++ b/arch/sh/kernel/cpu/init.c @@ -98,7 +98,7 @@ static void __init expmask_init(void) #endif /* 2nd-level cache init */ -void __uses_jump_to_uncached __attribute__ ((weak)) l2_cache_init(void) +void __attribute__ ((weak)) l2_cache_init(void) { } @@ -106,7 +106,7 @@ void __uses_jump_to_uncached __attribute__ ((weak)) l2_cache_init(void) * Generic first-level cache init */ #ifdef CONFIG_SUPERH32 -static void __uses_jump_to_uncached cache_init(void) +static void cache_init(void) { unsigned long ccr, flags; diff --git a/arch/sh/kernel/cpu/sh3/probe.c b/arch/sh/kernel/cpu/sh3/probe.c index f9c7df64eb01..c2db65719f4d 100644 --- a/arch/sh/kernel/cpu/sh3/probe.c +++ b/arch/sh/kernel/cpu/sh3/probe.c @@ -16,7 +16,7 @@ #include #include -int __uses_jump_to_uncached detect_cpu_and_cache_system(void) +int detect_cpu_and_cache_system(void) { unsigned long addr0, addr1, data0, data1, data2, data3; diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c index 772b9265d0e4..9d426258aa00 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c @@ -592,7 +592,8 @@ void __init plat_early_device_setup(void) #define RAMCR_CACHE_L2FC 0x0002 #define RAMCR_CACHE_L2E 0x0001 #define L2_CACHE_ENABLE (RAMCR_CACHE_L2E|RAMCR_CACHE_L2FC) -void __uses_jump_to_uncached l2_cache_init(void) + +void l2_cache_init(void) { /* Enable L2 cache */ ctrl_outl(L2_CACHE_ENABLE, RAMCR); diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c index d32f96c1cc15..578e9f80271f 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c @@ -714,7 +714,8 @@ void __init plat_early_device_setup(void) #define RAMCR_CACHE_L2FC 0x0002 #define RAMCR_CACHE_L2E 0x0001 #define L2_CACHE_ENABLE (RAMCR_CACHE_L2E|RAMCR_CACHE_L2FC) -void __uses_jump_to_uncached l2_cache_init(void) + +void l2_cache_init(void) { /* Enable L2 cache */ ctrl_outl(L2_CACHE_ENABLE, RAMCR); diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S index 9e5a5878eeae..93e9b25a1811 100644 --- a/arch/sh/kernel/vmlinux.lds.S +++ b/arch/sh/kernel/vmlinux.lds.S @@ -53,18 +53,6 @@ SECTIONS NOTES RO_DATA(PAGE_SIZE) - - /* - * Code which must be executed uncached and the associated data - */ - . = ALIGN(PAGE_SIZE); - .uncached : AT(ADDR(.uncached) - LOAD_OFFSET) { - __uncached_start = .; - *(.uncached.text) - *(.uncached.data) - __uncached_end = .; - } - RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE) _edata = .; /* End of data section */ diff --git a/arch/sh/mm/cache-debugfs.c b/arch/sh/mm/cache-debugfs.c index 5ba067b26591..48ce82ee9fd2 100644 --- a/arch/sh/mm/cache-debugfs.c +++ b/arch/sh/mm/cache-debugfs.c @@ -22,8 +22,7 @@ enum cache_type { CACHE_TYPE_UNIFIED, }; -static int __uses_jump_to_uncached cache_seq_show(struct seq_file *file, - void *iter) +static int cache_seq_show(struct seq_file *file, void *iter) { unsigned int cache_type = (unsigned int)file->private; struct cache_info *cache; diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c index a2301daeefa3..87115b3ee70e 100644 --- a/arch/sh/mm/cache-sh4.c +++ b/arch/sh/mm/cache-sh4.c @@ -36,7 +36,7 @@ static void __flush_cache_one(unsigned long addr, unsigned long phys, * Called from kernel/module.c:sys_init_module and routine for a.out format, * signal handler code and kprobes code */ -static void __uses_jump_to_uncached sh4_flush_icache_range(void *args) +static void sh4_flush_icache_range(void *args) { struct flusher_data *data = args; unsigned long start, end; @@ -124,7 +124,7 @@ static void sh4_flush_dcache_page(void *arg) } /* TODO: Selective icache invalidation through IC address array.. */ -static void __uses_jump_to_uncached flush_icache_all(void) +static void flush_icache_all(void) { unsigned long flags, ccr; diff --git a/arch/sh/mm/cache-sh7705.c b/arch/sh/mm/cache-sh7705.c index f527fb70fce6..870293ee539e 100644 --- a/arch/sh/mm/cache-sh7705.c +++ b/arch/sh/mm/cache-sh7705.c @@ -78,7 +78,7 @@ static void sh7705_flush_icache_range(void *args) /* * Writeback&Invalidate the D-cache of the page */ -static void __uses_jump_to_uncached __flush_dcache_page(unsigned long phys) +static void __flush_dcache_page(unsigned long phys) { unsigned long ways, waysize, addrstart; unsigned long flags; @@ -144,7 +144,7 @@ static void sh7705_flush_dcache_page(void *arg) __flush_dcache_page(__pa(page_address(page))); } -static void __uses_jump_to_uncached sh7705_flush_cache_all(void *args) +static void sh7705_flush_cache_all(void *args) { unsigned long flags; diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index a28ff63c17a6..dffa6c749489 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -211,9 +211,6 @@ void __init paging_init(void) } free_area_init_nodes(max_zone_pfns); - - /* Set up the uncached fixmap */ - set_fixmap_nocache(FIX_UNCACHED, __pa(&__uncached_start)); } /* diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c index d318fa6caffe..3d5eece7e6d0 100644 --- a/arch/sh/mm/pmb.c +++ b/arch/sh/mm/pmb.c @@ -127,14 +127,14 @@ static void __set_pmb_entry(unsigned long vpn, unsigned long ppn, ctrl_outl(ppn | flags | PMB_V, mk_pmb_data(pos)); } -static void __uses_jump_to_uncached set_pmb_entry(struct pmb_entry *pmbe) +static void set_pmb_entry(struct pmb_entry *pmbe) { jump_to_uncached(); __set_pmb_entry(pmbe->vpn, pmbe->ppn, pmbe->flags, pmbe->entry); back_to_cached(); } -static void __uses_jump_to_uncached clear_pmb_entry(struct pmb_entry *pmbe) +static void clear_pmb_entry(struct pmb_entry *pmbe) { unsigned int entry = pmbe->entry; unsigned long addr; @@ -364,7 +364,7 @@ static inline int pmb_apply_legacy_mappings(void) } #endif -int __uses_jump_to_uncached pmb_init(void) +int pmb_init(void) { int i; unsigned long addr, data; diff --git a/arch/sh/mm/tlb-pteaex.c b/arch/sh/mm/tlb-pteaex.c index 409b7c2b4b9d..32dc674c550c 100644 --- a/arch/sh/mm/tlb-pteaex.c +++ b/arch/sh/mm/tlb-pteaex.c @@ -68,8 +68,7 @@ void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte) * in extended mode, the legacy 8-bit ASID field in address array 1 has * undefined behaviour. */ -void __uses_jump_to_uncached local_flush_tlb_one(unsigned long asid, - unsigned long page) +void local_flush_tlb_one(unsigned long asid, unsigned long page) { jump_to_uncached(); __raw_writel(page, MMU_UTLB_ADDRESS_ARRAY | MMU_PAGE_ASSOC_BIT); diff --git a/arch/sh/mm/tlb-sh4.c b/arch/sh/mm/tlb-sh4.c index 8cf550e2570f..624c1daa9f3f 100644 --- a/arch/sh/mm/tlb-sh4.c +++ b/arch/sh/mm/tlb-sh4.c @@ -64,8 +64,7 @@ void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte) local_irq_restore(flags); } -void __uses_jump_to_uncached local_flush_tlb_one(unsigned long asid, - unsigned long page) +void local_flush_tlb_one(unsigned long asid, unsigned long page) { unsigned long addr, data; -- cgit v1.2.3 From a077e91690fb32a1453423b2cf1df3492fd30c3a Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 21 Jan 2010 16:16:36 +0900 Subject: sh: Conserve fixmap slots when IOREMAP_FIXED=n. Presently the IOREMAP_FIXED fixmaps are always defined, even if the platform isn't capable of supporting it. Since we already have an ifdef for it, ifdef the entries, too. Signed-off-by: Paul Mundt --- arch/sh/include/asm/fixmap.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/fixmap.h b/arch/sh/include/asm/fixmap.h index 17b22b6c1001..6e7cea453895 100644 --- a/arch/sh/include/asm/fixmap.h +++ b/arch/sh/include/asm/fixmap.h @@ -61,6 +61,7 @@ enum fixed_addresses { 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 @@ -69,6 +70,7 @@ enum fixed_addresses { #define FIX_N_IOREMAPS 32 FIX_IOREMAP_BEGIN, FIX_IOREMAP_END = FIX_IOREMAP_BEGIN + FIX_N_IOREMAPS, +#endif __end_of_fixed_addresses }; -- cgit v1.2.3 From 9d56dd3b083a3bec56e9da35ce07baca81030b03 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 26 Jan 2010 12:58:40 +0900 Subject: sh: Mass ctrl_in/outX to __raw_read/writeX conversion. The old ctrl in/out routines are non-portable and unsuitable for cross-platform use. While drivers/sh has already been sanitized, there is still quite a lot of code that is not. This converts the arch/sh/ bits over, which permits us to flag the routines as deprecated whilst still building with -Werror for the architecture code, and to ensure that future users are not added. Signed-off-by: Paul Mundt --- arch/sh/boards/board-magicpanelr2.c | 74 ++++++++++++------------- arch/sh/boards/board-polaris.c | 22 ++++---- arch/sh/boards/board-shmin.c | 4 +- arch/sh/boards/mach-ap325rxa/setup.c | 16 +++--- arch/sh/boards/mach-cayman/irq.c | 16 +++--- arch/sh/boards/mach-dreamcast/rtc.c | 20 +++---- arch/sh/boards/mach-ecovec24/setup.c | 20 +++---- arch/sh/boards/mach-highlander/irq-r7780mp.c | 2 +- arch/sh/boards/mach-highlander/irq-r7780rp.c | 2 +- arch/sh/boards/mach-highlander/irq-r7785rp.c | 16 +++--- arch/sh/boards/mach-highlander/psw.c | 4 +- arch/sh/boards/mach-highlander/setup.c | 14 ++--- arch/sh/boards/mach-hp6xx/hp6xx_apm.c | 2 +- arch/sh/boards/mach-hp6xx/pm.c | 38 ++++++------- arch/sh/boards/mach-hp6xx/setup.c | 12 ++-- arch/sh/boards/mach-kfr2r09/setup.c | 14 ++--- arch/sh/boards/mach-landisk/gio.c | 12 ++-- arch/sh/boards/mach-landisk/irq.c | 6 +- arch/sh/boards/mach-landisk/psw.c | 4 +- arch/sh/boards/mach-landisk/setup.c | 4 +- arch/sh/boards/mach-microdev/io.c | 4 +- arch/sh/boards/mach-microdev/irq.c | 10 ++-- arch/sh/boards/mach-migor/setup.c | 8 +-- arch/sh/boards/mach-r2d/irq.c | 4 +- arch/sh/boards/mach-r2d/setup.c | 8 +-- arch/sh/boards/mach-rsk/devices-rsk7203.c | 2 +- arch/sh/boards/mach-sdk7780/irq.c | 4 +- arch/sh/boards/mach-sdk7780/setup.c | 6 +- arch/sh/boards/mach-se/7206/io.c | 2 +- arch/sh/boards/mach-se/7206/irq.c | 40 ++++++------- arch/sh/boards/mach-se/7343/irq.c | 10 ++-- arch/sh/boards/mach-se/7343/setup.c | 6 +- arch/sh/boards/mach-se/770x/irq.c | 14 ++--- arch/sh/boards/mach-se/7721/irq.c | 2 +- arch/sh/boards/mach-se/7721/setup.c | 8 +-- arch/sh/boards/mach-se/7722/irq.c | 10 ++-- arch/sh/boards/mach-se/7722/setup.c | 34 ++++++------ arch/sh/boards/mach-se/7724/irq.c | 20 +++---- arch/sh/boards/mach-se/7724/setup.c | 26 ++++----- arch/sh/boards/mach-se/7780/irq.c | 18 +++--- arch/sh/boards/mach-se/7780/setup.c | 26 ++++----- arch/sh/boards/mach-sh03/rtc.c | 50 ++++++++--------- arch/sh/boards/mach-sh7763rdp/irq.c | 10 ++-- arch/sh/boards/mach-sh7763rdp/setup.c | 40 ++++++------- arch/sh/boards/mach-snapgear/setup.c | 2 +- arch/sh/boards/mach-systemh/irq.c | 12 ++-- arch/sh/boards/mach-titan/io.c | 30 +++++----- arch/sh/boards/mach-x3proto/ilsel.c | 8 +-- arch/sh/boards/mach-x3proto/setup.c | 2 +- arch/sh/cchips/hd6446x/hd64461.c | 2 +- arch/sh/drivers/dma/dma-pvr2.c | 10 ++-- arch/sh/drivers/dma/dma-sh.c | 26 ++++----- arch/sh/drivers/dma/dmabrg.c | 22 ++++---- arch/sh/drivers/pci/fixups-rts7751r2d.c | 4 +- arch/sh/drivers/pci/pci-sh4.h | 4 +- arch/sh/drivers/pci/pci-sh5.h | 12 ++-- arch/sh/drivers/pci/pci-sh7751.c | 12 ++-- arch/sh/drivers/superhyway/ops-sh4-202.c | 8 +-- arch/sh/include/asm/dma-sh.h | 12 ++-- arch/sh/include/asm/mmu_context.h | 6 +- arch/sh/include/asm/mmu_context_32.h | 4 +- arch/sh/include/asm/watchdog.h | 18 +++--- arch/sh/include/cpu-sh2/cpu/watchdog.h | 4 +- arch/sh/include/cpu-sh3/cpu/dac.h | 12 ++-- arch/sh/include/mach-common/mach/magicpanelr2.h | 12 ++-- arch/sh/kernel/cpu/adc.c | 12 ++-- arch/sh/kernel/cpu/init.c | 10 ++-- arch/sh/kernel/cpu/irq/intc-sh5.c | 14 ++--- arch/sh/kernel/cpu/sh2/clock-sh7619.c | 6 +- arch/sh/kernel/cpu/sh2a/clock-sh7201.c | 8 +-- arch/sh/kernel/cpu/sh2a/clock-sh7203.c | 6 +- arch/sh/kernel/cpu/sh2a/clock-sh7206.c | 8 +-- arch/sh/kernel/cpu/sh3/clock-sh3.c | 8 +-- arch/sh/kernel/cpu/sh3/clock-sh7705.c | 8 +-- arch/sh/kernel/cpu/sh3/clock-sh7706.c | 8 +-- arch/sh/kernel/cpu/sh3/clock-sh7709.c | 8 +-- arch/sh/kernel/cpu/sh3/clock-sh7710.c | 8 +-- arch/sh/kernel/cpu/sh3/clock-sh7712.c | 6 +- arch/sh/kernel/cpu/sh3/probe.c | 26 ++++----- arch/sh/kernel/cpu/sh3/setup-sh3.c | 2 +- arch/sh/kernel/cpu/sh4/clock-sh4-202.c | 10 ++-- arch/sh/kernel/cpu/sh4/clock-sh4.c | 8 +-- arch/sh/kernel/cpu/sh4/probe.c | 6 +- arch/sh/kernel/cpu/sh4/setup-sh4-202.c | 2 +- arch/sh/kernel/cpu/sh4/setup-sh7750.c | 2 +- arch/sh/kernel/cpu/sh4/setup-sh7760.c | 2 +- arch/sh/kernel/cpu/sh4/sq.c | 10 ++-- arch/sh/kernel/cpu/sh4a/clock-sh7757.c | 8 +-- arch/sh/kernel/cpu/sh4a/clock-sh7763.c | 8 +-- arch/sh/kernel/cpu/sh4a/clock-sh7770.c | 8 +-- arch/sh/kernel/cpu/sh4a/clock-sh7780.c | 10 ++-- arch/sh/kernel/cpu/sh4a/clock-shx3.c | 10 ++-- arch/sh/kernel/cpu/sh4a/setup-sh7723.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-sh7724.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-sh7757.c | 26 ++++----- arch/sh/kernel/cpu/sh4a/setup-sh7763.c | 20 +++---- arch/sh/kernel/cpu/sh4a/setup-sh7770.c | 24 ++++---- arch/sh/kernel/cpu/sh4a/setup-sh7780.c | 24 ++++---- arch/sh/kernel/cpu/sh4a/setup-sh7785.c | 26 ++++----- arch/sh/kernel/cpu/sh4a/setup-sh7786.c | 24 ++++---- arch/sh/kernel/cpu/sh5/clock-sh5.c | 8 +-- arch/sh/kernel/io_trapped.c | 16 +++--- arch/sh/kernel/process_32.c | 2 +- arch/sh/kernel/signal_32.c | 6 +- arch/sh/kernel/traps.c | 4 +- arch/sh/mm/cache-debugfs.c | 4 +- arch/sh/mm/cache-sh2.c | 12 ++-- arch/sh/mm/cache-sh2a.c | 20 +++---- arch/sh/mm/cache-sh3.c | 6 +- arch/sh/mm/cache-sh4.c | 10 ++-- arch/sh/mm/cache-sh7705.c | 8 +-- arch/sh/mm/pmb.c | 24 ++++---- arch/sh/mm/tlb-sh3.c | 6 +- arch/sh/mm/tlb-sh4.c | 10 ++-- arch/sh/mm/tlbflush_32.c | 4 +- 115 files changed, 698 insertions(+), 698 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/boards/board-magicpanelr2.c b/arch/sh/boards/board-magicpanelr2.c index 99ffc5f1c0dd..efba450a0518 100644 --- a/arch/sh/boards/board-magicpanelr2.c +++ b/arch/sh/boards/board-magicpanelr2.c @@ -23,7 +23,7 @@ #include #include -#define LAN9115_READY (ctrl_inl(0xA8000084UL) & 0x00000001UL) +#define LAN9115_READY (__raw_readl(0xA8000084UL) & 0x00000001UL) /* Prefer cmdline over RedBoot */ static const char *probes[] = { "cmdlinepart", "RedBoot", NULL }; @@ -60,33 +60,33 @@ static void __init setup_chip_select(void) { /* CS2: LAN (0x08000000 - 0x0bffffff) */ /* no idle cycles, normal space, 8 bit data bus */ - ctrl_outl(0x36db0400, CS2BCR); + __raw_writel(0x36db0400, CS2BCR); /* (SW:1.5 WR:3 HW:1.5), ext. wait */ - ctrl_outl(0x000003c0, CS2WCR); + __raw_writel(0x000003c0, CS2WCR); /* CS4: CAN1 (0xb0000000 - 0xb3ffffff) */ /* no idle cycles, normal space, 8 bit data bus */ - ctrl_outl(0x00000200, CS4BCR); + __raw_writel(0x00000200, CS4BCR); /* (SW:1.5 WR:3 HW:1.5), ext. wait */ - ctrl_outl(0x00100981, CS4WCR); + __raw_writel(0x00100981, CS4WCR); /* CS5a: CAN2 (0xb4000000 - 0xb5ffffff) */ /* no idle cycles, normal space, 8 bit data bus */ - ctrl_outl(0x00000200, CS5ABCR); + __raw_writel(0x00000200, CS5ABCR); /* (SW:1.5 WR:3 HW:1.5), ext. wait */ - ctrl_outl(0x00100981, CS5AWCR); + __raw_writel(0x00100981, CS5AWCR); /* CS5b: CAN3 (0xb6000000 - 0xb7ffffff) */ /* no idle cycles, normal space, 8 bit data bus */ - ctrl_outl(0x00000200, CS5BBCR); + __raw_writel(0x00000200, CS5BBCR); /* (SW:1.5 WR:3 HW:1.5), ext. wait */ - ctrl_outl(0x00100981, CS5BWCR); + __raw_writel(0x00100981, CS5BWCR); /* CS6a: Rotary (0xb8000000 - 0xb9ffffff) */ /* no idle cycles, normal space, 8 bit data bus */ - ctrl_outl(0x00000200, CS6ABCR); + __raw_writel(0x00000200, CS6ABCR); /* (SW:1.5 WR:3 HW:1.5), no ext. wait */ - ctrl_outl(0x001009C1, CS6AWCR); + __raw_writel(0x001009C1, CS6AWCR); } static void __init setup_port_multiplexing(void) @@ -94,71 +94,71 @@ static void __init setup_port_multiplexing(void) /* A7 GPO(LED8); A6 GPO(LED7); A5 GPO(LED6); A4 GPO(LED5); * A3 GPO(LED4); A2 GPO(LED3); A1 GPO(LED2); A0 GPO(LED1); */ - ctrl_outw(0x5555, PORT_PACR); /* 01 01 01 01 01 01 01 01 */ + __raw_writew(0x5555, PORT_PACR); /* 01 01 01 01 01 01 01 01 */ /* B7 GPO(RST4); B6 GPO(RST3); B5 GPO(RST2); B4 GPO(RST1); * B3 GPO(PB3); B2 GPO(PB2); B1 GPO(PB1); B0 GPO(PB0); */ - ctrl_outw(0x5555, PORT_PBCR); /* 01 01 01 01 01 01 01 01 */ + __raw_writew(0x5555, PORT_PBCR); /* 01 01 01 01 01 01 01 01 */ /* C7 GPO(PC7); C6 GPO(PC6); C5 GPO(PC5); C4 GPO(PC4); * C3 LCD_DATA3; C2 LCD_DATA2; C1 LCD_DATA1; C0 LCD_DATA0; */ - ctrl_outw(0x5500, PORT_PCCR); /* 01 01 01 01 00 00 00 00 */ + __raw_writew(0x5500, PORT_PCCR); /* 01 01 01 01 00 00 00 00 */ /* D7 GPO(PD7); D6 GPO(PD6); D5 GPO(PD5); D4 GPO(PD4); * D3 GPO(PD3); D2 GPO(PD2); D1 GPO(PD1); D0 GPO(PD0); */ - ctrl_outw(0x5555, PORT_PDCR); /* 01 01 01 01 01 01 01 01 */ + __raw_writew(0x5555, PORT_PDCR); /* 01 01 01 01 01 01 01 01 */ /* E7 (x); E6 GPI(nu); E5 GPI(nu); E4 LCD_M_DISP; * E3 LCD_CL1; E2 LCD_CL2; E1 LCD_DON; E0 LCD_FLM; */ - ctrl_outw(0x3C00, PORT_PECR); /* 00 11 11 00 00 00 00 00 */ + __raw_writew(0x3C00, PORT_PECR); /* 00 11 11 00 00 00 00 00 */ /* F7 (x); F6 DA1(VLCD); F5 DA0(nc); F4 AN3; * F3 AN2(MID_AD); F2 AN1(EARTH_AD); F1 AN0(TEMP); F0 GPI+(nc); */ - ctrl_outw(0x0002, PORT_PFCR); /* 00 00 00 00 00 00 00 10 */ + __raw_writew(0x0002, PORT_PFCR); /* 00 00 00 00 00 00 00 10 */ /* G7 (x); G6 IRQ5(TOUCH_BUSY); G5 IRQ4(TOUCH_IRQ); G4 GPI(KEY2); * G3 GPI(KEY1); G2 GPO(LED11); G1 GPO(LED10); G0 GPO(LED9); */ - ctrl_outw(0x03D5, PORT_PGCR); /* 00 00 00 11 11 01 01 01 */ + __raw_writew(0x03D5, PORT_PGCR); /* 00 00 00 11 11 01 01 01 */ /* H7 (x); H6 /RAS(BRAS); H5 /CAS(BCAS); H4 CKE(BCKE); * H3 GPO(EARTH_OFF); H2 GPO(EARTH_TEST); H1 USB2_PWR; H0 USB1_PWR; */ - ctrl_outw(0x0050, PORT_PHCR); /* 00 00 00 00 01 01 00 00 */ + __raw_writew(0x0050, PORT_PHCR); /* 00 00 00 00 01 01 00 00 */ /* J7 (x); J6 AUDCK; J5 ASEBRKAK; J4 AUDATA3; * J3 AUDATA2; J2 AUDATA1; J1 AUDATA0; J0 AUDSYNC; */ - ctrl_outw(0x0000, PORT_PJCR); /* 00 00 00 00 00 00 00 00 */ + __raw_writew(0x0000, PORT_PJCR); /* 00 00 00 00 00 00 00 00 */ /* K7 (x); K6 (x); K5 (x); K4 (x); * K3 PINT7(/PWR2); K2 PINT6(/PWR1); K1 PINT5(nu); K0 PINT4(FLASH_READY) */ - ctrl_outw(0x00FF, PORT_PKCR); /* 00 00 00 00 11 11 11 11 */ + __raw_writew(0x00FF, PORT_PKCR); /* 00 00 00 00 11 11 11 11 */ /* L7 TRST; L6 TMS; L5 TDO; L4 TDI; * L3 TCK; L2 (x); L1 (x); L0 (x); */ - ctrl_outw(0x0000, PORT_PLCR); /* 00 00 00 00 00 00 00 00 */ + __raw_writew(0x0000, PORT_PLCR); /* 00 00 00 00 00 00 00 00 */ /* M7 GPO(CURRENT_SINK); M6 GPO(PWR_SWITCH); M5 GPO(LAN_SPEED); * M4 GPO(LAN_RESET); M3 GPO(BUZZER); M2 GPO(LCD_BL); * M1 CS5B(CAN3_CS); M0 GPI+(nc); */ - ctrl_outw(0x5552, PORT_PMCR); /* 01 01 01 01 01 01 00 10 */ + __raw_writew(0x5552, PORT_PMCR); /* 01 01 01 01 01 01 00 10 */ /* CURRENT_SINK=off, PWR_SWITCH=off, LAN_SPEED=100MBit, * LAN_RESET=off, BUZZER=off, LCD_BL=off */ #if CONFIG_SH_MAGIC_PANEL_R2_VERSION == 2 - ctrl_outb(0x30, PORT_PMDR); + __raw_writeb(0x30, PORT_PMDR); #elif CONFIG_SH_MAGIC_PANEL_R2_VERSION == 3 - ctrl_outb(0xF0, PORT_PMDR); + __raw_writeb(0xF0, PORT_PMDR); #else #error Unknown revision of PLATFORM_MP_R2 #endif @@ -167,8 +167,8 @@ static void __init setup_port_multiplexing(void) * P4 GPO(nu); P3 IRQ3(LAN_IRQ); P2 IRQ2(CAN3_IRQ); * P1 IRQ1(CAN2_IRQ); P0 IRQ0(CAN1_IRQ) */ - ctrl_outw(0x0100, PORT_PPCR); /* 00 00 00 01 00 00 00 00 */ - ctrl_outb(0x10, PORT_PPDR); + __raw_writew(0x0100, PORT_PPCR); /* 00 00 00 01 00 00 00 00 */ + __raw_writeb(0x10, PORT_PPDR); /* R7 A25; R6 A24; R5 A23; R4 A22; * R3 A21; R2 A20; R1 A19; R0 A0; @@ -185,22 +185,22 @@ static void __init setup_port_multiplexing(void) /* S7 (x); S6 (x); S5 (x); S4 GPO(EEPROM_CS2); * S3 GPO(EEPROM_CS1); S2 SIOF0_TXD; S1 SIOF0_RXD; S0 SIOF0_SCK; */ - ctrl_outw(0x0140, PORT_PSCR); /* 00 00 00 01 01 00 00 00 */ + __raw_writew(0x0140, PORT_PSCR); /* 00 00 00 01 01 00 00 00 */ /* T7 (x); T6 (x); T5 (x); T4 COM1_CTS; * T3 COM1_RTS; T2 COM1_TXD; T1 COM1_RXD; T0 GPO(WDOG) */ - ctrl_outw(0x0001, PORT_PTCR); /* 00 00 00 00 00 00 00 01 */ + __raw_writew(0x0001, PORT_PTCR); /* 00 00 00 00 00 00 00 01 */ /* U7 (x); U6 (x); U5 (x); U4 GPI+(/AC_FAULT); * U3 GPO(TOUCH_CS); U2 TOUCH_TXD; U1 TOUCH_RXD; U0 TOUCH_SCK; */ - ctrl_outw(0x0240, PORT_PUCR); /* 00 00 00 10 01 00 00 00 */ + __raw_writew(0x0240, PORT_PUCR); /* 00 00 00 10 01 00 00 00 */ /* V7 (x); V6 (x); V5 (x); V4 GPO(MID2); * V3 GPO(MID1); V2 CARD_TxD; V1 CARD_RxD; V0 GPI+(/BAT_FAULT); */ - ctrl_outw(0x0142, PORT_PVCR); /* 00 00 00 01 01 00 00 10 */ + __raw_writew(0x0142, PORT_PVCR); /* 00 00 00 01 01 00 00 10 */ } static void __init mpr2_setup(char **cmdline_p) @@ -209,24 +209,24 @@ static void __init mpr2_setup(char **cmdline_p) * /PCC_CD1, /PCC_CD2, PCC_BVD1, PCC_BVD2, * /IOIS16, IRQ4, IRQ5, USB1d_SUSPEND */ - ctrl_outw(0xAABC, PORT_PSELA); + __raw_writew(0xAABC, PORT_PSELA); /* set Pin Select Register B: * /SCIF0_RTS, /SCIF0_CTS, LCD_VCPWC, * LCD_VEPWC, IIC_SDA, IIC_SCL, Reserved */ - ctrl_outw(0x3C00, PORT_PSELB); + __raw_writew(0x3C00, PORT_PSELB); /* set Pin Select Register C: * SIOF1_SCK, SIOF1_RxD, SCIF1_RxD, SCIF1_TxD, Reserved */ - ctrl_outw(0x0000, PORT_PSELC); + __raw_writew(0x0000, PORT_PSELC); /* set Pin Select Register D: Reserved, SIOF1_TxD, Reserved, SIOF1_MCLK, * Reserved, SIOF1_SYNC, Reserved, SCIF1_SCK, Reserved */ - ctrl_outw(0x0000, PORT_PSELD); + __raw_writew(0x0000, PORT_PSELD); /* set USB TxRx Control: Reserved, DRV, Reserved, USB_TRANS, USB_SEL */ - ctrl_outw(0x0101, PORT_UTRCTL); + __raw_writew(0x0101, PORT_UTRCTL); /* set USB Clock Control: USSCS, USSTB, Reserved (HighByte always A5) */ - ctrl_outw(0xA5C0, PORT_UCLKCR_W); + __raw_writew(0xA5C0, PORT_UCLKCR_W); setup_chip_select(); diff --git a/arch/sh/boards/board-polaris.c b/arch/sh/boards/board-polaris.c index 5bc126900ce3..594866356c24 100644 --- a/arch/sh/boards/board-polaris.c +++ b/arch/sh/boards/board-polaris.c @@ -89,15 +89,15 @@ static int __init polaris_initialise(void) printk(KERN_INFO "Configuring Polaris external bus\n"); /* Configure area 5 with 2 wait states */ - wcr = ctrl_inw(WCR2); + wcr = __raw_readw(WCR2); wcr &= (~AREA5_WAIT_CTRL); wcr |= (WAIT_STATES_10 << 10); - ctrl_outw(wcr, WCR2); + __raw_writew(wcr, WCR2); /* Configure area 5 for 32-bit access */ - bcr_mask = ctrl_inw(BCR2); + bcr_mask = __raw_readw(BCR2); bcr_mask |= 1 << 10; - ctrl_outw(bcr_mask, BCR2); + __raw_writew(bcr_mask, BCR2); return platform_add_devices(polaris_devices, ARRAY_SIZE(polaris_devices)); @@ -128,13 +128,13 @@ static struct ipr_desc ipr_irq_desc = { static void __init init_polaris_irq(void) { /* Disable all interrupts */ - ctrl_outw(0, BCR_ILCRA); - ctrl_outw(0, BCR_ILCRB); - ctrl_outw(0, BCR_ILCRC); - ctrl_outw(0, BCR_ILCRD); - ctrl_outw(0, BCR_ILCRE); - ctrl_outw(0, BCR_ILCRF); - ctrl_outw(0, BCR_ILCRG); + __raw_writew(0, BCR_ILCRA); + __raw_writew(0, BCR_ILCRB); + __raw_writew(0, BCR_ILCRC); + __raw_writew(0, BCR_ILCRD); + __raw_writew(0, BCR_ILCRE); + __raw_writew(0, BCR_ILCRF); + __raw_writew(0, BCR_ILCRG); register_ipr_controller(&ipr_irq_desc); } diff --git a/arch/sh/boards/board-shmin.c b/arch/sh/boards/board-shmin.c index b1dcbbc89188..325bed53b87e 100644 --- a/arch/sh/boards/board-shmin.c +++ b/arch/sh/boards/board-shmin.c @@ -17,8 +17,8 @@ static void __init init_shmin_irq(void) { - ctrl_outw(0x2a00, PFC_PHCR); // IRQ0-3=IRQ - ctrl_outw(0x0aaa, INTC_ICR1); // IRQ0-3=IRQ-mode,Low-active. + __raw_writew(0x2a00, PFC_PHCR); // IRQ0-3=IRQ + __raw_writew(0x0aaa, INTC_ICR1); // IRQ0-3=IRQ-mode,Low-active. plat_irq_setup_pins(IRQ_MODE_IRQ); } diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c index 1f5fa5c44f6d..27277cbdb636 100644 --- a/arch/sh/boards/mach-ap325rxa/setup.c +++ b/arch/sh/boards/mach-ap325rxa/setup.c @@ -159,21 +159,21 @@ static void ap320_wvga_power_on(void *board_data) msleep(100); /* ASD AP-320/325 LCD ON */ - ctrl_outw(FPGA_LCDREG_VAL, FPGA_LCDREG); + __raw_writew(FPGA_LCDREG_VAL, FPGA_LCDREG); /* backlight */ gpio_set_value(GPIO_PTS3, 0); - ctrl_outw(0x100, FPGA_BKLREG); + __raw_writew(0x100, FPGA_BKLREG); } static void ap320_wvga_power_off(void *board_data) { /* backlight */ - ctrl_outw(0, FPGA_BKLREG); + __raw_writew(0, FPGA_BKLREG); gpio_set_value(GPIO_PTS3, 1); /* ASD AP-320/325 LCD OFF */ - ctrl_outw(0, FPGA_LCDREG); + __raw_writew(0, FPGA_LCDREG); } static struct sh_mobile_lcdc_info lcdc_info = { @@ -595,7 +595,7 @@ static int __init ap325rxa_devices_setup(void) gpio_request(GPIO_PTZ4, NULL); gpio_direction_output(GPIO_PTZ4, 0); /* SADDR */ - ctrl_outw(ctrl_inw(PORT_MSELCRB) & ~0x0001, PORT_MSELCRB); + __raw_writew(__raw_readw(PORT_MSELCRB) & ~0x0001, PORT_MSELCRB); /* FLCTL */ gpio_request(GPIO_FN_FCE, NULL); @@ -613,9 +613,9 @@ static int __init ap325rxa_devices_setup(void) gpio_request(GPIO_FN_FWE, NULL); gpio_request(GPIO_FN_FRB, NULL); - ctrl_outw(0, PORT_HIZCRC); - ctrl_outw(0xFFFF, PORT_DRVCRA); - ctrl_outw(0xFFFF, PORT_DRVCRB); + __raw_writew(0, PORT_HIZCRC); + __raw_writew(0xFFFF, PORT_DRVCRA); + __raw_writew(0xFFFF, PORT_DRVCRB); platform_resource_setup_memory(&ceu_device, "ceu", 4 << 20); diff --git a/arch/sh/boards/mach-cayman/irq.c b/arch/sh/boards/mach-cayman/irq.c index 33f770856319..1394b078db36 100644 --- a/arch/sh/boards/mach-cayman/irq.c +++ b/arch/sh/boards/mach-cayman/irq.c @@ -66,9 +66,9 @@ static void enable_cayman_irq(unsigned int irq) reg = EPLD_MASK_BASE + ((irq / 8) << 2); bit = 1<<(irq % 8); local_irq_save(flags); - mask = ctrl_inl(reg); + mask = __raw_readl(reg); mask |= bit; - ctrl_outl(mask, reg); + __raw_writel(mask, reg); local_irq_restore(flags); } @@ -83,9 +83,9 @@ void disable_cayman_irq(unsigned int irq) reg = EPLD_MASK_BASE + ((irq / 8) << 2); bit = 1<<(irq % 8); local_irq_save(flags); - mask = ctrl_inl(reg); + mask = __raw_readl(reg); mask &= ~bit; - ctrl_outl(mask, reg); + __raw_writel(mask, reg); local_irq_restore(flags); } @@ -109,8 +109,8 @@ int cayman_irq_demux(int evt) unsigned long status; int i; - status = ctrl_inl(EPLD_STATUS_BASE) & - ctrl_inl(EPLD_MASK_BASE) & 0xff; + status = __raw_readl(EPLD_STATUS_BASE) & + __raw_readl(EPLD_MASK_BASE) & 0xff; if (status == 0) { irq = -1; } else { @@ -126,8 +126,8 @@ int cayman_irq_demux(int evt) unsigned long status; int i; - status = ctrl_inl(EPLD_STATUS_BASE + 3 * sizeof(u32)) & - ctrl_inl(EPLD_MASK_BASE + 3 * sizeof(u32)) & 0xff; + status = __raw_readl(EPLD_STATUS_BASE + 3 * sizeof(u32)) & + __raw_readl(EPLD_MASK_BASE + 3 * sizeof(u32)) & 0xff; if (status == 0) { irq = -1; } else { diff --git a/arch/sh/boards/mach-dreamcast/rtc.c b/arch/sh/boards/mach-dreamcast/rtc.c index a7433685798d..061d65714fcc 100644 --- a/arch/sh/boards/mach-dreamcast/rtc.c +++ b/arch/sh/boards/mach-dreamcast/rtc.c @@ -35,11 +35,11 @@ static void aica_rtc_gettimeofday(struct timespec *ts) unsigned long val1, val2; do { - val1 = ((ctrl_inl(AICA_RTC_SECS_H) & 0xffff) << 16) | - (ctrl_inl(AICA_RTC_SECS_L) & 0xffff); + val1 = ((__raw_readl(AICA_RTC_SECS_H) & 0xffff) << 16) | + (__raw_readl(AICA_RTC_SECS_L) & 0xffff); - val2 = ((ctrl_inl(AICA_RTC_SECS_H) & 0xffff) << 16) | - (ctrl_inl(AICA_RTC_SECS_L) & 0xffff); + val2 = ((__raw_readl(AICA_RTC_SECS_H) & 0xffff) << 16) | + (__raw_readl(AICA_RTC_SECS_L) & 0xffff); } while (val1 != val2); ts->tv_sec = val1 - TWENTY_YEARS; @@ -60,14 +60,14 @@ static int aica_rtc_settimeofday(const time_t secs) unsigned long adj = secs + TWENTY_YEARS; do { - ctrl_outl((adj & 0xffff0000) >> 16, AICA_RTC_SECS_H); - ctrl_outl((adj & 0xffff), AICA_RTC_SECS_L); + __raw_writel((adj & 0xffff0000) >> 16, AICA_RTC_SECS_H); + __raw_writel((adj & 0xffff), AICA_RTC_SECS_L); - val1 = ((ctrl_inl(AICA_RTC_SECS_H) & 0xffff) << 16) | - (ctrl_inl(AICA_RTC_SECS_L) & 0xffff); + val1 = ((__raw_readl(AICA_RTC_SECS_H) & 0xffff) << 16) | + (__raw_readl(AICA_RTC_SECS_L) & 0xffff); - val2 = ((ctrl_inl(AICA_RTC_SECS_H) & 0xffff) << 16) | - (ctrl_inl(AICA_RTC_SECS_L) & 0xffff); + val2 = ((__raw_readl(AICA_RTC_SECS_H) & 0xffff) << 16) | + (__raw_readl(AICA_RTC_SECS_L) & 0xffff); } while (val1 != val2); return 0; diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index a49cce16e783..1135c3b848f2 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c @@ -696,13 +696,13 @@ static struct platform_device camera_devices[] = { #define FCLKBCR 0xa415000c static void fsimck_init(struct clk *clk) { - u32 status = ctrl_inl(clk->enable_reg); + u32 status = __raw_readl(clk->enable_reg); /* use external clock */ status &= ~0x000000ff; status |= 0x00000080; - ctrl_outl(status, clk->enable_reg); + __raw_writel(status, clk->enable_reg); } static struct clk_ops fsimck_clk_ops = { @@ -853,7 +853,7 @@ static int __init arch_setup(void) gpio_direction_output(GPIO_PTG1, 0); gpio_direction_output(GPIO_PTG2, 0); gpio_direction_output(GPIO_PTG3, 0); - ctrl_outw((ctrl_inw(PORT_HIZA) & ~(0x1 << 1)) , PORT_HIZA); + __raw_writew((__raw_readw(PORT_HIZA) & ~(0x1 << 1)) , PORT_HIZA); /* enable SH-Eth */ gpio_request(GPIO_PTA1, NULL); @@ -873,16 +873,16 @@ static int __init arch_setup(void) gpio_request(GPIO_FN_LNKSTA, NULL); /* enable USB */ - ctrl_outw(0x0000, 0xA4D80000); - ctrl_outw(0x0000, 0xA4D90000); + __raw_writew(0x0000, 0xA4D80000); + __raw_writew(0x0000, 0xA4D90000); gpio_request(GPIO_PTB3, NULL); gpio_request(GPIO_PTB4, NULL); gpio_request(GPIO_PTB5, NULL); gpio_direction_input(GPIO_PTB3); gpio_direction_output(GPIO_PTB4, 0); gpio_direction_output(GPIO_PTB5, 0); - ctrl_outw(0x0600, 0xa40501d4); - ctrl_outw(0x0600, 0xa4050192); + __raw_writew(0x0600, 0xa40501d4); + __raw_writew(0x0600, 0xa4050192); if (gpio_get_value(GPIO_PTB3)) { printk(KERN_INFO "USB1 function is selected\n"); @@ -923,7 +923,7 @@ static int __init arch_setup(void) gpio_request(GPIO_FN_LCDVSYN, NULL); gpio_request(GPIO_FN_LCDDON, NULL); gpio_request(GPIO_FN_LCDLCLK, NULL); - ctrl_outw((ctrl_inw(PORT_HIZA) & ~0x0001), PORT_HIZA); + __raw_writew((__raw_readw(PORT_HIZA) & ~0x0001), PORT_HIZA); gpio_request(GPIO_PTE6, NULL); gpio_request(GPIO_PTU1, NULL); @@ -935,7 +935,7 @@ static int __init arch_setup(void) gpio_direction_output(GPIO_PTA2, 0); /* I/O buffer drive ability is high */ - ctrl_outw((ctrl_inw(IODRIVEA) & ~0x00c0) | 0x0080 , IODRIVEA); + __raw_writew((__raw_readw(IODRIVEA) & ~0x00c0) | 0x0080 , IODRIVEA); if (gpio_get_value(GPIO_PTE6)) { /* DVI */ @@ -1067,7 +1067,7 @@ static int __init arch_setup(void) gpio_direction_output(GPIO_PTB7, 0); /* I/O buffer drive ability is high for SDHI1 */ - ctrl_outw((ctrl_inw(IODRIVEA) & ~0x3000) | 0x2000 , IODRIVEA); + __raw_writew((__raw_readw(IODRIVEA) & ~0x3000) | 0x2000 , IODRIVEA); #else /* enable MSIOF0 on CN11 (needs DS2.4 set to OFF) */ gpio_request(GPIO_FN_MSIOF0_TXD, NULL); diff --git a/arch/sh/boards/mach-highlander/irq-r7780mp.c b/arch/sh/boards/mach-highlander/irq-r7780mp.c index 83c28bcd4d2a..9893fd3a1358 100644 --- a/arch/sh/boards/mach-highlander/irq-r7780mp.c +++ b/arch/sh/boards/mach-highlander/irq-r7780mp.c @@ -64,7 +64,7 @@ static DECLARE_INTC_DESC(intc_desc, "r7780mp", vectors, unsigned char * __init highlander_plat_irq_setup(void) { - if ((ctrl_inw(0xa4000700) & 0xf000) == 0x2000) { + if ((__raw_readw(0xa4000700) & 0xf000) == 0x2000) { printk(KERN_INFO "Using r7780mp interrupt controller.\n"); register_intc_controller(&intc_desc); return irl2irq; diff --git a/arch/sh/boards/mach-highlander/irq-r7780rp.c b/arch/sh/boards/mach-highlander/irq-r7780rp.c index b721e86b5af4..0805b2151452 100644 --- a/arch/sh/boards/mach-highlander/irq-r7780rp.c +++ b/arch/sh/boards/mach-highlander/irq-r7780rp.c @@ -57,7 +57,7 @@ static DECLARE_INTC_DESC(intc_desc, "r7780rp", vectors, unsigned char * __init highlander_plat_irq_setup(void) { - if (ctrl_inw(0xa5000600)) { + if (__raw_readw(0xa5000600)) { printk(KERN_INFO "Using r7780rp interrupt controller.\n"); register_intc_controller(&intc_desc); return irl2irq; diff --git a/arch/sh/boards/mach-highlander/irq-r7785rp.c b/arch/sh/boards/mach-highlander/irq-r7785rp.c index 3811b060a39b..558b24862776 100644 --- a/arch/sh/boards/mach-highlander/irq-r7785rp.c +++ b/arch/sh/boards/mach-highlander/irq-r7785rp.c @@ -66,20 +66,20 @@ static DECLARE_INTC_DESC(intc_desc, "r7785rp", vectors, unsigned char * __init highlander_plat_irq_setup(void) { - if ((ctrl_inw(0xa4000158) & 0xf000) != 0x1000) + if ((__raw_readw(0xa4000158) & 0xf000) != 0x1000) return NULL; printk(KERN_INFO "Using r7785rp interrupt controller.\n"); - ctrl_outw(0x0000, PA_IRLSSR1); /* FPGA IRLSSR1(CF_CD clear) */ + __raw_writew(0x0000, PA_IRLSSR1); /* FPGA IRLSSR1(CF_CD clear) */ /* Setup the FPGA IRL */ - ctrl_outw(0x0000, PA_IRLPRA); /* FPGA IRLA */ - ctrl_outw(0xe598, PA_IRLPRB); /* FPGA IRLB */ - ctrl_outw(0x7060, PA_IRLPRC); /* FPGA IRLC */ - ctrl_outw(0x0000, PA_IRLPRD); /* FPGA IRLD */ - ctrl_outw(0x4321, PA_IRLPRE); /* FPGA IRLE */ - ctrl_outw(0xdcba, PA_IRLPRF); /* FPGA IRLF */ + __raw_writew(0x0000, PA_IRLPRA); /* FPGA IRLA */ + __raw_writew(0xe598, PA_IRLPRB); /* FPGA IRLB */ + __raw_writew(0x7060, PA_IRLPRC); /* FPGA IRLC */ + __raw_writew(0x0000, PA_IRLPRD); /* FPGA IRLD */ + __raw_writew(0x4321, PA_IRLPRE); /* FPGA IRLE */ + __raw_writew(0xdcba, PA_IRLPRF); /* FPGA IRLF */ register_intc_controller(&intc_desc); return irl2irq; diff --git a/arch/sh/boards/mach-highlander/psw.c b/arch/sh/boards/mach-highlander/psw.c index 37b1a2ee71a5..522786318d36 100644 --- a/arch/sh/boards/mach-highlander/psw.c +++ b/arch/sh/boards/mach-highlander/psw.c @@ -24,7 +24,7 @@ static irqreturn_t psw_irq_handler(int irq, void *arg) unsigned int l, mask; int ret = 0; - l = ctrl_inw(PA_DBSW); + l = __raw_readw(PA_DBSW); /* Nothing to do if there's no state change */ if (psw->state) { @@ -45,7 +45,7 @@ static irqreturn_t psw_irq_handler(int irq, void *arg) out: /* Clear the switch IRQs */ l |= (0x7 << 12); - ctrl_outw(l, PA_DBSW); + __raw_writew(l, PA_DBSW); return IRQ_RETVAL(ret); } diff --git a/arch/sh/boards/mach-highlander/setup.c b/arch/sh/boards/mach-highlander/setup.c index f663c14d8885..affd66747ba3 100644 --- a/arch/sh/boards/mach-highlander/setup.c +++ b/arch/sh/boards/mach-highlander/setup.c @@ -311,13 +311,13 @@ device_initcall(r7780rp_devices_setup); */ static int ivdr_clk_enable(struct clk *clk) { - ctrl_outw(ctrl_inw(PA_IVDRCTL) | (1 << IVDR_CK_ON), PA_IVDRCTL); + __raw_writew(__raw_readw(PA_IVDRCTL) | (1 << IVDR_CK_ON), PA_IVDRCTL); return 0; } static void ivdr_clk_disable(struct clk *clk) { - ctrl_outw(ctrl_inw(PA_IVDRCTL) & ~(1 << IVDR_CK_ON), PA_IVDRCTL); + __raw_writew(__raw_readw(PA_IVDRCTL) & ~(1 << IVDR_CK_ON), PA_IVDRCTL); } static struct clk_ops ivdr_clk_ops = { @@ -337,7 +337,7 @@ static struct clk *r7780rp_clocks[] = { static void r7780rp_power_off(void) { if (mach_is_r7780mp() || mach_is_r7785rp()) - ctrl_outw(0x0001, PA_POFF); + __raw_writew(0x0001, PA_POFF); } /* @@ -345,7 +345,7 @@ static void r7780rp_power_off(void) */ static void __init highlander_setup(char **cmdline_p) { - u16 ver = ctrl_inw(PA_VERREG); + u16 ver = __raw_readw(PA_VERREG); int i; printk(KERN_INFO "Renesas Solutions Highlander %s support.\n", @@ -370,12 +370,12 @@ static void __init highlander_setup(char **cmdline_p) clk_enable(clk); } - ctrl_outw(0x0000, PA_OBLED); /* Clear LED. */ + __raw_writew(0x0000, PA_OBLED); /* Clear LED. */ if (mach_is_r7780rp()) - ctrl_outw(0x0001, PA_SDPOW); /* SD Power ON */ + __raw_writew(0x0001, PA_SDPOW); /* SD Power ON */ - ctrl_outw(ctrl_inw(PA_IVDRCTL) | 0x01, PA_IVDRCTL); /* Si13112 */ + __raw_writew(__raw_readw(PA_IVDRCTL) | 0x01, PA_IVDRCTL); /* Si13112 */ pm_power_off = r7780rp_power_off; } diff --git a/arch/sh/boards/mach-hp6xx/hp6xx_apm.c b/arch/sh/boards/mach-hp6xx/hp6xx_apm.c index e85212faf40a..b49535c0ddd9 100644 --- a/arch/sh/boards/mach-hp6xx/hp6xx_apm.c +++ b/arch/sh/boards/mach-hp6xx/hp6xx_apm.c @@ -53,7 +53,7 @@ static void hp6x0_apm_get_power_status(struct apm_power_info *info) info->ac_line_status = (battery > HP680_BATTERY_AC_ON) ? APM_AC_ONLINE : APM_AC_OFFLINE; - pgdr = ctrl_inb(PGDR); + pgdr = __raw_readb(PGDR); if (pgdr & PGDR_MAIN_BATTERY_OUT) { info->battery_status = APM_BATTERY_STATUS_NOT_PRESENT; info->battery_flag = 0x80; diff --git a/arch/sh/boards/mach-hp6xx/pm.c b/arch/sh/boards/mach-hp6xx/pm.c index d936c1af7620..4499a3749d40 100644 --- a/arch/sh/boards/mach-hp6xx/pm.c +++ b/arch/sh/boards/mach-hp6xx/pm.c @@ -53,17 +53,17 @@ static void pm_enter(void) sh_wdt_write_cnt(0); /* disable PLL1 */ - frqcr = ctrl_inw(FRQCR); + frqcr = __raw_readw(FRQCR); frqcr &= ~(FRQCR_PLLEN | FRQCR_PSTBY); - ctrl_outw(frqcr, FRQCR); + __raw_writew(frqcr, FRQCR); /* enable standby */ - stbcr = ctrl_inb(STBCR); - ctrl_outb(stbcr | STBCR_STBY | STBCR_MSTP2, STBCR); + stbcr = __raw_readb(STBCR); + __raw_writeb(stbcr | STBCR_STBY | STBCR_MSTP2, STBCR); /* set self-refresh */ - mcr = ctrl_inw(MCR); - ctrl_outw(mcr & ~MCR_RFSH, MCR); + mcr = __raw_readw(MCR); + __raw_writew(mcr & ~MCR_RFSH, MCR); /* set interrupt handler */ asm volatile("stc vbr, %0" : "=r" (vbr_old)); @@ -73,8 +73,8 @@ static void pm_enter(void) &wakeup_start, &wakeup_end - &wakeup_start); asm volatile("ldc %0, vbr" : : "r" (vbr_new)); - ctrl_outw(0, RTCNT); - ctrl_outw(mcr | MCR_RFSH | MCR_RMODE, MCR); + __raw_writew(0, RTCNT); + __raw_writew(mcr | MCR_RFSH | MCR_RMODE, MCR); cpu_sleep(); @@ -83,14 +83,14 @@ static void pm_enter(void) free_page(vbr_new); /* enable PLL1 */ - frqcr = ctrl_inw(FRQCR); + frqcr = __raw_readw(FRQCR); frqcr |= FRQCR_PSTBY; - ctrl_outw(frqcr, FRQCR); + __raw_writew(frqcr, FRQCR); udelay(50); frqcr |= FRQCR_PLLEN; - ctrl_outw(frqcr, FRQCR); + __raw_writew(frqcr, FRQCR); - ctrl_outb(stbcr, STBCR); + __raw_writeb(stbcr, STBCR); clear_bl_bit(); } @@ -115,21 +115,21 @@ static int hp6x0_pm_enter(suspend_state_t state) outw(hd64461_stbcr, HD64461_STBCR); #endif - ctrl_outb(0x1f, DACR); + __raw_writeb(0x1f, DACR); - stbcr = ctrl_inb(STBCR); - ctrl_outb(0x01, STBCR); + stbcr = __raw_readb(STBCR); + __raw_writeb(0x01, STBCR); - stbcr2 = ctrl_inb(STBCR2); - ctrl_outb(0x7f , STBCR2); + stbcr2 = __raw_readb(STBCR2); + __raw_writeb(0x7f , STBCR2); outw(0xf07f, HD64461_SCPUCR); pm_enter(); outw(0, HD64461_SCPUCR); - ctrl_outb(stbcr, STBCR); - ctrl_outb(stbcr2, STBCR2); + __raw_writeb(stbcr, STBCR); + __raw_writeb(stbcr2, STBCR2); #ifdef CONFIG_HD64461_ENABLER hd64461_stbcr = inw(HD64461_STBCR); diff --git a/arch/sh/boards/mach-hp6xx/setup.c b/arch/sh/boards/mach-hp6xx/setup.c index e6dd5e96321e..8c9add5f4cfa 100644 --- a/arch/sh/boards/mach-hp6xx/setup.c +++ b/arch/sh/boards/mach-hp6xx/setup.c @@ -149,19 +149,19 @@ static void __init hp6xx_setup(char **cmdline_p) sh_dac_output(0, DAC_SPEAKER_VOLUME); sh_dac_disable(DAC_SPEAKER_VOLUME); - v8 = ctrl_inb(DACR); + v8 = __raw_readb(DACR); v8 &= ~DACR_DAE; - ctrl_outb(v8,DACR); + __raw_writeb(v8,DACR); - v8 = ctrl_inb(SCPDR); + v8 = __raw_readb(SCPDR); v8 |= SCPDR_TS_SCAN_X | SCPDR_TS_SCAN_Y; v8 &= ~SCPDR_TS_SCAN_ENABLE; - ctrl_outb(v8, SCPDR); + __raw_writeb(v8, SCPDR); - v = ctrl_inw(SCPCR); + v = __raw_readw(SCPCR); v &= ~SCPCR_TS_MASK; v |= SCPCR_TS_ENABLE; - ctrl_outw(v, SCPCR); + __raw_writew(v, SCPCR); } device_initcall(hp6xx_devices_setup); diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c index 5d7b5d92475e..ca9e82d77d0a 100644 --- a/arch/sh/boards/mach-kfr2r09/setup.c +++ b/arch/sh/boards/mach-kfr2r09/setup.c @@ -282,7 +282,7 @@ static int camera_power(struct device *dev, int mode) * use 1.8 V for VccQ_VIO * use 2.85V for VccQ_SR */ - ctrl_outw((ctrl_inw(DRVCRB) & ~0x0003) | 0x0001, DRVCRB); + __raw_writew((__raw_readw(DRVCRB) & ~0x0003) | 0x0001, DRVCRB); /* reset clear */ ret = gpio_request(GPIO_PTB4, NULL); @@ -492,13 +492,13 @@ static int kfr2r09_usb0_gadget_setup(void) if (kfr2r09_usb0_gadget_i2c_setup() != 0) return -ENODEV; /* unable to configure using i2c */ - ctrl_outw((ctrl_inw(PORT_MSELCRB) & ~0xc000) | 0x8000, PORT_MSELCRB); + __raw_writew((__raw_readw(PORT_MSELCRB) & ~0xc000) | 0x8000, PORT_MSELCRB); gpio_request(GPIO_FN_PDSTATUS, NULL); /* R-standby disables USB clock */ gpio_request(GPIO_PTV6, NULL); /* USBCLK_ON */ gpio_direction_output(GPIO_PTV6, 1); /* USBCLK_ON = H */ msleep(20); /* wait 20ms to let the clock settle */ clk_enable(clk_get(NULL, "usb0")); - ctrl_outw(0x0600, 0xa40501d4); + __raw_writew(0x0600, 0xa40501d4); return 0; } @@ -526,12 +526,12 @@ static int __init kfr2r09_devices_setup(void) gpio_direction_output(GPIO_PTG3, 1); /* HPON_ON = H */ /* setup NOR flash at CS0 */ - ctrl_outl(0x36db0400, BSC_CS0BCR); - ctrl_outl(0x00000500, BSC_CS0WCR); + __raw_writel(0x36db0400, BSC_CS0BCR); + __raw_writel(0x00000500, BSC_CS0WCR); /* setup NAND flash at CS4 */ - ctrl_outl(0x36db0400, BSC_CS4BCR); - ctrl_outl(0x00000500, BSC_CS4WCR); + __raw_writel(0x36db0400, BSC_CS4BCR); + __raw_writel(0x00000500, BSC_CS4WCR); /* setup KEYSC pins */ gpio_request(GPIO_FN_KEYOUT0, NULL); diff --git a/arch/sh/boards/mach-landisk/gio.c b/arch/sh/boards/mach-landisk/gio.c index 528013188196..01e6abb769b9 100644 --- a/arch/sh/boards/mach-landisk/gio.c +++ b/arch/sh/boards/mach-landisk/gio.c @@ -76,39 +76,39 @@ static long gio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) break; case GIODRV_IOCSGIODATA1: /* write byte */ - ctrl_outb((unsigned char)(0x0ff & data), addr); + __raw_writeb((unsigned char)(0x0ff & data), addr); break; case GIODRV_IOCSGIODATA2: /* write word */ if (addr & 0x01) { return -EFAULT; } - ctrl_outw((unsigned short int)(0x0ffff & data), addr); + __raw_writew((unsigned short int)(0x0ffff & data), addr); break; case GIODRV_IOCSGIODATA4: /* write long */ if (addr & 0x03) { return -EFAULT; } - ctrl_outl(data, addr); + __raw_writel(data, addr); break; case GIODRV_IOCGGIODATA1: /* read byte */ - data = ctrl_inb(addr); + data = __raw_readb(addr); break; case GIODRV_IOCGGIODATA2: /* read word */ if (addr & 0x01) { return -EFAULT; } - data = ctrl_inw(addr); + data = __raw_readw(addr); break; case GIODRV_IOCGGIODATA4: /* read long */ if (addr & 0x03) { return -EFAULT; } - data = ctrl_inl(addr); + data = __raw_readl(addr); break; default: return -EFAULT; diff --git a/arch/sh/boards/mach-landisk/irq.c b/arch/sh/boards/mach-landisk/irq.c index 7b284cde1f58..96f38a4187d0 100644 --- a/arch/sh/boards/mach-landisk/irq.c +++ b/arch/sh/boards/mach-landisk/irq.c @@ -22,14 +22,14 @@ static void disable_landisk_irq(unsigned int irq) { unsigned char mask = 0xff ^ (0x01 << (irq - 5)); - ctrl_outb(ctrl_inb(PA_IMASK) & mask, PA_IMASK); + __raw_writeb(__raw_readb(PA_IMASK) & mask, PA_IMASK); } static void enable_landisk_irq(unsigned int irq) { unsigned char value = (0x01 << (irq - 5)); - ctrl_outb(ctrl_inb(PA_IMASK) | value, PA_IMASK); + __raw_writeb(__raw_readb(PA_IMASK) | value, PA_IMASK); } static struct irq_chip landisk_irq_chip __read_mostly = { @@ -52,5 +52,5 @@ void __init init_landisk_IRQ(void) handle_level_irq, "level"); enable_landisk_irq(i); } - ctrl_outb(0x00, PA_PWRINT_CLR); + __raw_writeb(0x00, PA_PWRINT_CLR); } diff --git a/arch/sh/boards/mach-landisk/psw.c b/arch/sh/boards/mach-landisk/psw.c index e6b0efa098d1..bef83522f958 100644 --- a/arch/sh/boards/mach-landisk/psw.c +++ b/arch/sh/boards/mach-landisk/psw.c @@ -25,7 +25,7 @@ static irqreturn_t psw_irq_handler(int irq, void *arg) unsigned int sw_value; int ret = 0; - sw_value = (0x0ff & (~ctrl_inb(PA_STATUS))); + sw_value = (0x0ff & (~__raw_readb(PA_STATUS))); /* Nothing to do if there's no state change */ if (psw->state) { @@ -42,7 +42,7 @@ static irqreturn_t psw_irq_handler(int irq, void *arg) out: /* Clear the switch IRQs */ - ctrl_outb(0x00, PA_PWRINT_CLR); + __raw_writeb(0x00, PA_PWRINT_CLR); return IRQ_RETVAL(ret); } diff --git a/arch/sh/boards/mach-landisk/setup.c b/arch/sh/boards/mach-landisk/setup.c index 2d09d4d34f87..50337acc18c5 100644 --- a/arch/sh/boards/mach-landisk/setup.c +++ b/arch/sh/boards/mach-landisk/setup.c @@ -25,7 +25,7 @@ void init_landisk_IRQ(void); static void landisk_power_off(void) { - ctrl_outb(0x01, PA_SHUTDOWN); + __raw_writeb(0x01, PA_SHUTDOWN); } static struct resource cf_ide_resources[3]; @@ -88,7 +88,7 @@ __initcall(landisk_devices_setup); static void __init landisk_setup(char **cmdline_p) { /* LED ON */ - ctrl_outb(ctrl_inb(PA_LED) | 0x03, PA_LED); + __raw_writeb(__raw_readb(PA_LED) | 0x03, PA_LED); printk(KERN_INFO "I-O DATA DEVICE, INC. \"LANDISK Series\" support.\n"); pm_power_off = landisk_power_off; diff --git a/arch/sh/boards/mach-microdev/io.c b/arch/sh/boards/mach-microdev/io.c index 52dd748211c7..2960c659020e 100644 --- a/arch/sh/boards/mach-microdev/io.c +++ b/arch/sh/boards/mach-microdev/io.c @@ -141,10 +141,10 @@ static inline void delay(void) #if defined(CONFIG_PCI) /* System board present, just make a dummy SRAM access. (CS0 will be mapped to PCI memory, probably good to avoid it.) */ - ctrl_inw(0xa6800000); + __raw_readw(0xa6800000); #else /* CS0 will be mapped to flash, ROM etc so safe to access it. */ - ctrl_inw(0xa0000000); + __raw_readw(0xa0000000); #endif } diff --git a/arch/sh/boards/mach-microdev/irq.c b/arch/sh/boards/mach-microdev/irq.c index b551963579c1..a26d16669aa2 100644 --- a/arch/sh/boards/mach-microdev/irq.c +++ b/arch/sh/boards/mach-microdev/irq.c @@ -88,7 +88,7 @@ static void disable_microdev_irq(unsigned int irq) fpgaIrq = fpgaIrqTable[irq].fpgaIrq; /* disable interrupts on the FPGA INTC register */ - ctrl_outl(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTDSB_REG); + __raw_writel(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTDSB_REG); } static void enable_microdev_irq(unsigned int irq) @@ -107,13 +107,13 @@ static void enable_microdev_irq(unsigned int irq) priorityReg = MICRODEV_FPGA_INTPRI_REG(fpgaIrq); /* set priority for the interrupt */ - priorities = ctrl_inl(priorityReg); + priorities = __raw_readl(priorityReg); priorities &= ~MICRODEV_FPGA_INTPRI_MASK(fpgaIrq); priorities |= MICRODEV_FPGA_INTPRI_LEVEL(fpgaIrq, pri); - ctrl_outl(priorities, priorityReg); + __raw_writel(priorities, priorityReg); /* enable interrupts on the FPGA INTC register */ - ctrl_outl(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTENB_REG); + __raw_writel(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTENB_REG); } /* This function sets the desired irq handler to be a MicroDev type */ @@ -134,7 +134,7 @@ extern void __init init_microdev_irq(void) int i; /* disable interrupts on the FPGA INTC register */ - ctrl_outl(~0ul, MICRODEV_FPGA_INTDSB_REG); + __raw_writel(~0ul, MICRODEV_FPGA_INTDSB_REG); for (i = 0; i < NUM_EXTERNAL_IRQS; i++) make_microdev_irq(i); diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c index 507c77be476d..ed2eeeb390a5 100644 --- a/arch/sh/boards/mach-migor/setup.c +++ b/arch/sh/boards/mach-migor/setup.c @@ -516,8 +516,8 @@ static int __init migor_devices_setup(void) /* SMC91C111 - Enable IRQ0, Setup CS4 for 16-bit fast access */ gpio_request(GPIO_FN_IRQ0, NULL); - ctrl_outl(0x00003400, BSC_CS4BCR); - ctrl_outl(0x00110080, BSC_CS4WCR); + __raw_writel(0x00003400, BSC_CS4BCR); + __raw_writel(0x00110080, BSC_CS4WCR); /* KEYSC */ gpio_request(GPIO_FN_KEYOUT0, NULL); @@ -533,7 +533,7 @@ static int __init migor_devices_setup(void) /* NAND Flash */ gpio_request(GPIO_FN_CS6A_CE2B, NULL); - ctrl_outl((ctrl_inl(BSC_CS6ABCR) & ~0x0600) | 0x0200, BSC_CS6ABCR); + __raw_writel((__raw_readl(BSC_CS6ABCR) & ~0x0600) | 0x0200, BSC_CS6ABCR); gpio_request(GPIO_PTA1, NULL); gpio_direction_input(GPIO_PTA1); @@ -627,7 +627,7 @@ static int __init migor_devices_setup(void) #else gpio_direction_output(GPIO_PTT0, 1); #endif - ctrl_outw(ctrl_inw(PORT_MSELCRB) | 0x2000, PORT_MSELCRB); /* D15->D8 */ + __raw_writew(__raw_readw(PORT_MSELCRB) | 0x2000, PORT_MSELCRB); /* D15->D8 */ platform_resource_setup_memory(&migor_ceu_device, "ceu", 4 << 20); diff --git a/arch/sh/boards/mach-r2d/irq.c b/arch/sh/boards/mach-r2d/irq.c index 78d7b27c80da..574f009c3c31 100644 --- a/arch/sh/boards/mach-r2d/irq.c +++ b/arch/sh/boards/mach-r2d/irq.c @@ -129,7 +129,7 @@ void __init init_rts7751r2d_IRQ(void) { struct intc_desc *d; - switch (ctrl_inw(PA_VERREG) & 0xf0) { + switch (__raw_readw(PA_VERREG) & 0xf0) { #ifdef CONFIG_RTS7751R2D_PLUS case 0x10: printk(KERN_INFO "Using R2D-PLUS interrupt controller.\n"); @@ -147,7 +147,7 @@ void __init init_rts7751r2d_IRQ(void) #endif default: printk(KERN_INFO "Unknown R2D interrupt controller 0x%04x\n", - ctrl_inw(PA_VERREG)); + __raw_readw(PA_VERREG)); return; } diff --git a/arch/sh/boards/mach-r2d/setup.c b/arch/sh/boards/mach-r2d/setup.c index a625ecb93e47..b84df6a3a93c 100644 --- a/arch/sh/boards/mach-r2d/setup.c +++ b/arch/sh/boards/mach-r2d/setup.c @@ -70,7 +70,7 @@ static struct spi_board_info spi_bus[] = { static void r2d_chip_select(struct sh_spi_info *spi, int cs, int state) { BUG_ON(cs != 0); /* Single Epson RTC-9701JE attached on CS0 */ - ctrl_outw(state == BITBANG_CS_ACTIVE, PA_RTCCE); + __raw_writew(state == BITBANG_CS_ACTIVE, PA_RTCCE); } static struct sh_spi_info spi_info = { @@ -262,7 +262,7 @@ __initcall(rts7751r2d_devices_setup); static void rts7751r2d_power_off(void) { - ctrl_outw(0x0001, PA_POWOFF); + __raw_writew(0x0001, PA_POWOFF); } /* @@ -271,14 +271,14 @@ static void rts7751r2d_power_off(void) static void __init rts7751r2d_setup(char **cmdline_p) { void __iomem *sm501_reg; - u16 ver = ctrl_inw(PA_VERREG); + u16 ver = __raw_readw(PA_VERREG); printk(KERN_INFO "Renesas Technology Sales RTS7751R2D support.\n"); printk(KERN_INFO "FPGA version:%d (revision:%d)\n", (ver >> 4) & 0xf, ver & 0xf); - ctrl_outw(0x0000, PA_OUTPORT); + __raw_writew(0x0000, PA_OUTPORT); pm_power_off = rts7751r2d_power_off; /* sm501 dram configuration: diff --git a/arch/sh/boards/mach-rsk/devices-rsk7203.c b/arch/sh/boards/mach-rsk/devices-rsk7203.c index c37617e63220..4fa08ba10253 100644 --- a/arch/sh/boards/mach-rsk/devices-rsk7203.c +++ b/arch/sh/boards/mach-rsk/devices-rsk7203.c @@ -96,7 +96,7 @@ static int __init rsk7203_devices_setup(void) gpio_request(GPIO_FN_RXD0, NULL); /* Setup LAN9118: CS1 in 16-bit Big Endian Mode, IRQ0 at Port B */ - ctrl_outl(0x36db0400, 0xfffc0008); /* CS1BCR */ + __raw_writel(0x36db0400, 0xfffc0008); /* CS1BCR */ gpio_request(GPIO_FN_IRQ0_PB, NULL); return platform_add_devices(rsk7203_devices, diff --git a/arch/sh/boards/mach-sdk7780/irq.c b/arch/sh/boards/mach-sdk7780/irq.c index 855558163c58..e5f7564f2511 100644 --- a/arch/sh/boards/mach-sdk7780/irq.c +++ b/arch/sh/boards/mach-sdk7780/irq.c @@ -37,9 +37,9 @@ void __init init_sdk7780_IRQ(void) { printk(KERN_INFO "Using SDK7780 interrupt controller.\n"); - ctrl_outw(0xFFFF, FPGA_IRQ0MR); + __raw_writew(0xFFFF, FPGA_IRQ0MR); /* Setup IRL 0-3 */ - ctrl_outw(0x0003, FPGA_IMSR); + __raw_writew(0x0003, FPGA_IMSR); plat_irq_setup_pins(IRQ_MODE_IRL3210); register_intc_controller(&fpga_intc_desc); diff --git a/arch/sh/boards/mach-sdk7780/setup.c b/arch/sh/boards/mach-sdk7780/setup.c index b887373a2599..4da38db4b5fe 100644 --- a/arch/sh/boards/mach-sdk7780/setup.c +++ b/arch/sh/boards/mach-sdk7780/setup.c @@ -74,8 +74,8 @@ device_initcall(sdk7780_devices_setup); static void __init sdk7780_setup(char **cmdline_p) { - u16 ver = ctrl_inw(FPGA_FPVERR); - u16 dateStamp = ctrl_inw(FPGA_FPDATER); + u16 ver = __raw_readw(FPGA_FPVERR); + u16 dateStamp = __raw_readw(FPGA_FPDATER); printk(KERN_INFO "Renesas Technology Europe SDK7780 support.\n"); printk(KERN_INFO "Board version: %d (revision %d), " @@ -85,7 +85,7 @@ static void __init sdk7780_setup(char **cmdline_p) dateStamp); /* Setup pin mux'ing for PCIC */ - ctrl_outw(0x0000, GPIO_PECR); + __raw_writew(0x0000, GPIO_PECR); } /* diff --git a/arch/sh/boards/mach-se/7206/io.c b/arch/sh/boards/mach-se/7206/io.c index 180455642a43..adadc77532ee 100644 --- a/arch/sh/boards/mach-se/7206/io.c +++ b/arch/sh/boards/mach-se/7206/io.c @@ -16,7 +16,7 @@ static inline void delay(void) { - ctrl_inw(0x20000000); /* P2 ROM Area */ + __raw_readw(0x20000000); /* P2 ROM Area */ } /* MS7750 requires special versions of in*, out* routines, since diff --git a/arch/sh/boards/mach-se/7206/irq.c b/arch/sh/boards/mach-se/7206/irq.c index aef7f052851a..79be4bc59933 100644 --- a/arch/sh/boards/mach-se/7206/irq.c +++ b/arch/sh/boards/mach-se/7206/irq.c @@ -32,12 +32,12 @@ static void disable_se7206_irq(unsigned int irq) unsigned short msk0,msk1; /* Set the priority in IPR to 0 */ - val = ctrl_inw(INTC_IPR01); + val = __raw_readw(INTC_IPR01); val &= mask; - ctrl_outw(val, INTC_IPR01); + __raw_writew(val, INTC_IPR01); /* FPGA mask set */ - msk0 = ctrl_inw(INTMSK0); - msk1 = ctrl_inw(INTMSK1); + msk0 = __raw_readw(INTMSK0); + msk1 = __raw_readw(INTMSK1); switch (irq) { case IRQ0_IRQ: @@ -51,8 +51,8 @@ static void disable_se7206_irq(unsigned int irq) msk1 |= 0x00ff; break; } - ctrl_outw(msk0, INTMSK0); - ctrl_outw(msk1, INTMSK1); + __raw_writew(msk0, INTMSK0); + __raw_writew(msk1, INTMSK1); } static void enable_se7206_irq(unsigned int irq) @@ -62,13 +62,13 @@ static void enable_se7206_irq(unsigned int irq) unsigned short msk0,msk1; /* Set priority in IPR back to original value */ - val = ctrl_inw(INTC_IPR01); + val = __raw_readw(INTC_IPR01); val |= value; - ctrl_outw(val, INTC_IPR01); + __raw_writew(val, INTC_IPR01); /* FPGA mask reset */ - msk0 = ctrl_inw(INTMSK0); - msk1 = ctrl_inw(INTMSK1); + msk0 = __raw_readw(INTMSK0); + msk1 = __raw_readw(INTMSK1); switch (irq) { case IRQ0_IRQ: @@ -82,8 +82,8 @@ static void enable_se7206_irq(unsigned int irq) msk1 &= ~0x00ff; break; } - ctrl_outw(msk0, INTMSK0); - ctrl_outw(msk1, INTMSK1); + __raw_writew(msk0, INTMSK0); + __raw_writew(msk1, INTMSK1); } static void eoi_se7206_irq(unsigned int irq) @@ -93,8 +93,8 @@ static void eoi_se7206_irq(unsigned int irq) if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) enable_se7206_irq(irq); /* FPGA isr clear */ - sts0 = ctrl_inw(INTSTS0); - sts1 = ctrl_inw(INTSTS1); + sts0 = __raw_readw(INTSTS0); + sts1 = __raw_readw(INTSTS1); switch (irq) { case IRQ0_IRQ: @@ -108,8 +108,8 @@ static void eoi_se7206_irq(unsigned int irq) sts1 &= ~0x00ff; break; } - ctrl_outw(sts0, INTSTS0); - ctrl_outw(sts1, INTSTS1); + __raw_writew(sts0, INTSTS0); + __raw_writew(sts1, INTSTS1); } static struct irq_chip se7206_irq_chip __read_mostly = { @@ -136,11 +136,11 @@ void __init init_se7206_IRQ(void) make_se7206_irq(IRQ0_IRQ); /* SMC91C111 */ make_se7206_irq(IRQ1_IRQ); /* ATA */ make_se7206_irq(IRQ3_IRQ); /* SLOT / PCM */ - ctrl_outw(inw(INTC_ICR1) | 0x000b ,INTC_ICR1 ) ; /* ICR1 */ + __raw_writew(inw(INTC_ICR1) | 0x000b ,INTC_ICR1 ) ; /* ICR1 */ /* FPGA System register setup*/ - ctrl_outw(0x0000,INTSTS0); /* Clear INTSTS0 */ - ctrl_outw(0x0000,INTSTS1); /* Clear INTSTS1 */ + __raw_writew(0x0000,INTSTS0); /* Clear INTSTS0 */ + __raw_writew(0x0000,INTSTS1); /* Clear INTSTS1 */ /* IRQ0=LAN, IRQ1=ATA, IRQ3=SLT,PCM */ - ctrl_outw(0x0001,INTSEL); + __raw_writew(0x0001,INTSEL); } diff --git a/arch/sh/boards/mach-se/7343/irq.c b/arch/sh/boards/mach-se/7343/irq.c index c60fd13608d0..d4305c26e9f7 100644 --- a/arch/sh/boards/mach-se/7343/irq.c +++ b/arch/sh/boards/mach-se/7343/irq.c @@ -21,13 +21,13 @@ unsigned int se7343_fpga_irq[SE7343_FPGA_IRQ_NR] = { 0, }; static void disable_se7343_irq(unsigned int irq) { unsigned int bit = (unsigned int)get_irq_chip_data(irq); - ctrl_outw(ctrl_inw(PA_CPLD_IMSK) | 1 << bit, PA_CPLD_IMSK); + __raw_writew(__raw_readw(PA_CPLD_IMSK) | 1 << bit, PA_CPLD_IMSK); } static void enable_se7343_irq(unsigned int irq) { unsigned int bit = (unsigned int)get_irq_chip_data(irq); - ctrl_outw(ctrl_inw(PA_CPLD_IMSK) & ~(1 << bit), PA_CPLD_IMSK); + __raw_writew(__raw_readw(PA_CPLD_IMSK) & ~(1 << bit), PA_CPLD_IMSK); } static struct irq_chip se7343_irq_chip __read_mostly = { @@ -39,7 +39,7 @@ static struct irq_chip se7343_irq_chip __read_mostly = { static void se7343_irq_demux(unsigned int irq, struct irq_desc *desc) { - unsigned short intv = ctrl_inw(PA_CPLD_ST); + unsigned short intv = __raw_readw(PA_CPLD_ST); unsigned int ext_irq = 0; intv &= (1 << SE7343_FPGA_IRQ_NR) - 1; @@ -59,8 +59,8 @@ void __init init_7343se_IRQ(void) { int i, irq; - ctrl_outw(0, PA_CPLD_IMSK); /* disable all irqs */ - ctrl_outw(0x2000, 0xb03fffec); /* mrshpc irq enable */ + __raw_writew(0, PA_CPLD_IMSK); /* disable all irqs */ + __raw_writew(0x2000, 0xb03fffec); /* mrshpc irq enable */ for (i = 0; i < SE7343_FPGA_IRQ_NR; i++) { irq = create_irq(); diff --git a/arch/sh/boards/mach-se/7343/setup.c b/arch/sh/boards/mach-se/7343/setup.c index 3412bb2973ae..d2370af56d77 100644 --- a/arch/sh/boards/mach-se/7343/setup.c +++ b/arch/sh/boards/mach-se/7343/setup.c @@ -161,10 +161,10 @@ device_initcall(sh7343se_devices_setup); */ static void __init sh7343se_setup(char **cmdline_p) { - ctrl_outw(0xf900, FPGA_OUT); /* FPGA */ + __raw_writew(0xf900, FPGA_OUT); /* FPGA */ - ctrl_outw(0x0002, PORT_PECR); /* PORT E 1 = IRQ5 */ - ctrl_outw(0x0020, PORT_PSELD); + __raw_writew(0x0002, PORT_PECR); /* PORT E 1 = IRQ5 */ + __raw_writew(0x0020, PORT_PSELD); printk(KERN_INFO "MS7343CP01 Setup...done\n"); } diff --git a/arch/sh/boards/mach-se/770x/irq.c b/arch/sh/boards/mach-se/770x/irq.c index ec1fea571b52..1028c17b81bc 100644 --- a/arch/sh/boards/mach-se/770x/irq.c +++ b/arch/sh/boards/mach-se/770x/irq.c @@ -96,13 +96,13 @@ static struct ipr_desc ipr_irq_desc = { void __init init_se_IRQ(void) { /* Disable all interrupts */ - ctrl_outw(0, BCR_ILCRA); - ctrl_outw(0, BCR_ILCRB); - ctrl_outw(0, BCR_ILCRC); - ctrl_outw(0, BCR_ILCRD); - ctrl_outw(0, BCR_ILCRE); - ctrl_outw(0, BCR_ILCRF); - ctrl_outw(0, BCR_ILCRG); + __raw_writew(0, BCR_ILCRA); + __raw_writew(0, BCR_ILCRB); + __raw_writew(0, BCR_ILCRC); + __raw_writew(0, BCR_ILCRD); + __raw_writew(0, BCR_ILCRE); + __raw_writew(0, BCR_ILCRF); + __raw_writew(0, BCR_ILCRG); register_ipr_controller(&ipr_irq_desc); } diff --git a/arch/sh/boards/mach-se/7721/irq.c b/arch/sh/boards/mach-se/7721/irq.c index b417acc4dad0..d85022ea3f12 100644 --- a/arch/sh/boards/mach-se/7721/irq.c +++ b/arch/sh/boards/mach-se/7721/irq.c @@ -38,7 +38,7 @@ static DECLARE_INTC_DESC(intc_desc, "SE7721", vectors, void __init init_se7721_IRQ(void) { /* PPCR */ - ctrl_outw(ctrl_inw(0xa4050118) & ~0x00ff, 0xa4050118); + __raw_writew(__raw_readw(0xa4050118) & ~0x00ff, 0xa4050118); register_intc_controller(&intc_desc); intc_set_priority(MRSHPC_IRQ0, 0xf - MRSHPC_IRQ0); diff --git a/arch/sh/boards/mach-se/7721/setup.c b/arch/sh/boards/mach-se/7721/setup.c index 460da53b4961..7416ad7ee53a 100644 --- a/arch/sh/boards/mach-se/7721/setup.c +++ b/arch/sh/boards/mach-se/7721/setup.c @@ -80,10 +80,10 @@ device_initcall(se7721_devices_setup); static void __init se7721_setup(char **cmdline_p) { /* for USB */ - ctrl_outw(0x0000, 0xA405010C); /* PGCR */ - ctrl_outw(0x0000, 0xA405010E); /* PHCR */ - ctrl_outw(0x00AA, 0xA4050118); /* PPCR */ - ctrl_outw(0x0000, 0xA4050124); /* PSELA */ + __raw_writew(0x0000, 0xA405010C); /* PGCR */ + __raw_writew(0x0000, 0xA405010E); /* PHCR */ + __raw_writew(0x00AA, 0xA4050118); /* PPCR */ + __raw_writew(0x0000, 0xA4050124); /* PSELA */ } /* diff --git a/arch/sh/boards/mach-se/7722/irq.c b/arch/sh/boards/mach-se/7722/irq.c index b221b6842b0d..61605db04ee6 100644 --- a/arch/sh/boards/mach-se/7722/irq.c +++ b/arch/sh/boards/mach-se/7722/irq.c @@ -21,13 +21,13 @@ unsigned int se7722_fpga_irq[SE7722_FPGA_IRQ_NR] = { 0, }; static void disable_se7722_irq(unsigned int irq) { unsigned int bit = (unsigned int)get_irq_chip_data(irq); - ctrl_outw(ctrl_inw(IRQ01_MASK) | 1 << bit, IRQ01_MASK); + __raw_writew(__raw_readw(IRQ01_MASK) | 1 << bit, IRQ01_MASK); } static void enable_se7722_irq(unsigned int irq) { unsigned int bit = (unsigned int)get_irq_chip_data(irq); - ctrl_outw(ctrl_inw(IRQ01_MASK) & ~(1 << bit), IRQ01_MASK); + __raw_writew(__raw_readw(IRQ01_MASK) & ~(1 << bit), IRQ01_MASK); } static struct irq_chip se7722_irq_chip __read_mostly = { @@ -39,7 +39,7 @@ static struct irq_chip se7722_irq_chip __read_mostly = { static void se7722_irq_demux(unsigned int irq, struct irq_desc *desc) { - unsigned short intv = ctrl_inw(IRQ01_STS); + unsigned short intv = __raw_readw(IRQ01_STS); unsigned int ext_irq = 0; intv &= (1 << SE7722_FPGA_IRQ_NR) - 1; @@ -59,8 +59,8 @@ void __init init_se7722_IRQ(void) { int i, irq; - ctrl_outw(0, IRQ01_MASK); /* disable all irqs */ - ctrl_outw(0x2000, 0xb03fffec); /* mrshpc irq enable */ + __raw_writew(0, IRQ01_MASK); /* disable all irqs */ + __raw_writew(0x2000, 0xb03fffec); /* mrshpc irq enable */ for (i = 0; i < SE7722_FPGA_IRQ_NR; i++) { irq = create_irq(); diff --git a/arch/sh/boards/mach-se/7722/setup.c b/arch/sh/boards/mach-se/7722/setup.c index 93675418171d..80a4e571b310 100644 --- a/arch/sh/boards/mach-se/7722/setup.c +++ b/arch/sh/boards/mach-se/7722/setup.c @@ -156,32 +156,32 @@ device_initcall(se7722_devices_setup); static void __init se7722_setup(char **cmdline_p) { - ctrl_outw(0x010D, FPGA_OUT); /* FPGA */ + __raw_writew(0x010D, FPGA_OUT); /* FPGA */ - ctrl_outw(0x0000, PORT_PECR); /* PORT E 1 = IRQ5 ,E 0 = BS */ - ctrl_outw(0x1000, PORT_PJCR); /* PORT J 1 = IRQ1,J 0 =IRQ0 */ + __raw_writew(0x0000, PORT_PECR); /* PORT E 1 = IRQ5 ,E 0 = BS */ + __raw_writew(0x1000, PORT_PJCR); /* PORT J 1 = IRQ1,J 0 =IRQ0 */ /* LCDC I/O */ - ctrl_outw(0x0020, PORT_PSELD); + __raw_writew(0x0020, PORT_PSELD); /* SIOF1*/ - ctrl_outw(0x0003, PORT_PSELB); - ctrl_outw(0xe000, PORT_PSELC); - ctrl_outw(0x0000, PORT_PKCR); + __raw_writew(0x0003, PORT_PSELB); + __raw_writew(0xe000, PORT_PSELC); + __raw_writew(0x0000, PORT_PKCR); /* LCDC */ - ctrl_outw(0x4020, PORT_PHCR); - ctrl_outw(0x0000, PORT_PLCR); - ctrl_outw(0x0000, PORT_PMCR); - ctrl_outw(0x0002, PORT_PRCR); - ctrl_outw(0x0000, PORT_PXCR); /* LCDC,CS6A */ + __raw_writew(0x4020, PORT_PHCR); + __raw_writew(0x0000, PORT_PLCR); + __raw_writew(0x0000, PORT_PMCR); + __raw_writew(0x0002, PORT_PRCR); + __raw_writew(0x0000, PORT_PXCR); /* LCDC,CS6A */ /* KEYSC */ - ctrl_outw(0x0A10, PORT_PSELA); /* BS,SHHID2 */ - ctrl_outw(0x0000, PORT_PYCR); - ctrl_outw(0x0000, PORT_PZCR); - ctrl_outw(ctrl_inw(PORT_HIZCRA) & ~0x4000, PORT_HIZCRA); - ctrl_outw(ctrl_inw(PORT_HIZCRC) & ~0xc000, PORT_HIZCRC); + __raw_writew(0x0A10, PORT_PSELA); /* BS,SHHID2 */ + __raw_writew(0x0000, PORT_PYCR); + __raw_writew(0x0000, PORT_PZCR); + __raw_writew(__raw_readw(PORT_HIZCRA) & ~0x4000, PORT_HIZCRA); + __raw_writew(__raw_readw(PORT_HIZCRC) & ~0xc000, PORT_HIZCRC); } /* diff --git a/arch/sh/boards/mach-se/7724/irq.c b/arch/sh/boards/mach-se/7724/irq.c index f76cf3b49f23..e5e021a7d1e6 100644 --- a/arch/sh/boards/mach-se/7724/irq.c +++ b/arch/sh/boards/mach-se/7724/irq.c @@ -72,14 +72,14 @@ static void disable_se7724_irq(unsigned int irq) { struct fpga_irq set = get_fpga_irq(fpga2irq(irq)); unsigned int bit = irq - set.base; - ctrl_outw(ctrl_inw(set.mraddr) | 0x0001 << bit, set.mraddr); + __raw_writew(__raw_readw(set.mraddr) | 0x0001 << bit, set.mraddr); } static void enable_se7724_irq(unsigned int irq) { struct fpga_irq set = get_fpga_irq(fpga2irq(irq)); unsigned int bit = irq - set.base; - ctrl_outw(ctrl_inw(set.mraddr) & ~(0x0001 << bit), set.mraddr); + __raw_writew(__raw_readw(set.mraddr) & ~(0x0001 << bit), set.mraddr); } static struct irq_chip se7724_irq_chip __read_mostly = { @@ -92,7 +92,7 @@ static struct irq_chip se7724_irq_chip __read_mostly = { static void se7724_irq_demux(unsigned int irq, struct irq_desc *desc) { struct fpga_irq set = get_fpga_irq(irq); - unsigned short intv = ctrl_inw(set.sraddr); + unsigned short intv = __raw_readw(set.sraddr); struct irq_desc *ext_desc; unsigned int ext_irq = set.base; @@ -115,13 +115,13 @@ void __init init_se7724_IRQ(void) { int i; - ctrl_outw(0xffff, IRQ0_MR); /* mask all */ - ctrl_outw(0xffff, IRQ1_MR); /* mask all */ - ctrl_outw(0xffff, IRQ2_MR); /* mask all */ - ctrl_outw(0x0000, IRQ0_SR); /* clear irq */ - ctrl_outw(0x0000, IRQ1_SR); /* clear irq */ - ctrl_outw(0x0000, IRQ2_SR); /* clear irq */ - ctrl_outw(0x002a, IRQ_MODE); /* set irq type */ + __raw_writew(0xffff, IRQ0_MR); /* mask all */ + __raw_writew(0xffff, IRQ1_MR); /* mask all */ + __raw_writew(0xffff, IRQ2_MR); /* mask all */ + __raw_writew(0x0000, IRQ0_SR); /* clear irq */ + __raw_writew(0x0000, IRQ1_SR); /* clear irq */ + __raw_writew(0x0000, IRQ2_SR); /* clear irq */ + __raw_writew(0x002a, IRQ_MODE); /* set irq type */ for (i = 0; i < SE7724_FPGA_IRQ_NR; i++) set_irq_chip_and_handler_name(SE7724_FPGA_IRQ_BASE + i, diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c index cbfba783ee49..242dc843f574 100644 --- a/arch/sh/boards/mach-se/7724/setup.c +++ b/arch/sh/boards/mach-se/7724/setup.c @@ -256,12 +256,12 @@ static struct platform_device ceu1_device = { #define FCLKACR 0xa4150008 static void fsimck_init(struct clk *clk) { - u32 status = ctrl_inl(clk->enable_reg); + u32 status = __raw_readl(clk->enable_reg); /* use external clock */ status &= ~0x000000ff; status |= 0x00000080; - ctrl_outl(status, clk->enable_reg); + __raw_writel(status, clk->enable_reg); } static struct clk_ops fsimck_clk_ops = { @@ -522,7 +522,7 @@ static int __init sh_eth_is_eeprom_ready(void) int t = 10000; while (t--) { - if (!ctrl_inw(EEPROM_STAT)) + if (!__raw_readw(EEPROM_STAT)) return 1; cpu_relax(); } @@ -542,13 +542,13 @@ static void __init sh_eth_init(void) /* read MAC addr from EEPROM */ for (i = 0 ; i < 3 ; i++) { - ctrl_outw(0x0, EEPROM_OP); /* read */ - ctrl_outw(i*2, EEPROM_ADR); - ctrl_outw(0x1, EEPROM_STRT); + __raw_writew(0x0, EEPROM_OP); /* read */ + __raw_writew(i*2, EEPROM_ADR); + __raw_writew(0x1, EEPROM_STRT); if (!sh_eth_is_eeprom_ready()) return; - mac = ctrl_inw(EEPROM_DATA); + mac = __raw_readw(EEPROM_DATA); sh_eth_plat.mac_addr[i << 1] = mac & 0xff; sh_eth_plat.mac_addr[(i << 1) + 1] = mac >> 8; } @@ -585,7 +585,7 @@ arch_initcall(arch_setup); static int __init devices_setup(void) { - u16 sw = ctrl_inw(SW4140); /* select camera, monitor */ + u16 sw = __raw_readw(SW4140); /* select camera, monitor */ struct clk *fsia_clk; /* register board specific self-refresh code */ @@ -595,7 +595,7 @@ static int __init devices_setup(void) &ms7724se_sdram_leave_start, &ms7724se_sdram_leave_end); /* Reset Release */ - ctrl_outw(ctrl_inw(FPGA_OUT) & + __raw_writew(__raw_readw(FPGA_OUT) & ~((1 << 1) | /* LAN */ (1 << 6) | /* VIDEO DAC */ (1 << 7) | /* AK4643 */ @@ -604,7 +604,7 @@ static int __init devices_setup(void) FPGA_OUT); /* turn on USB clocks, use external clock */ - ctrl_outw((ctrl_inw(PORT_MSELCRB) & ~0xc000) | 0x8000, PORT_MSELCRB); + __raw_writew((__raw_readw(PORT_MSELCRB) & ~0xc000) | 0x8000, PORT_MSELCRB); #ifdef CONFIG_PM /* Let LED9 show STATUS2 */ @@ -633,10 +633,10 @@ static int __init devices_setup(void) #endif /* enable USB0 port */ - ctrl_outw(0x0600, 0xa40501d4); + __raw_writew(0x0600, 0xa40501d4); /* enable USB1 port */ - ctrl_outw(0x0600, 0xa4050192); + __raw_writew(0x0600, 0xa4050192); /* enable IRQ 0,1,2 */ gpio_request(GPIO_FN_INTC_IRQ0, NULL); @@ -684,7 +684,7 @@ static int __init devices_setup(void) gpio_request(GPIO_FN_LCDVCPWC, NULL); gpio_request(GPIO_FN_LCDRD, NULL); gpio_request(GPIO_FN_LCDLCLK, NULL); - ctrl_outw((ctrl_inw(PORT_HIZA) & ~0x0001), PORT_HIZA); + __raw_writew((__raw_readw(PORT_HIZA) & ~0x0001), PORT_HIZA); /* enable CEU0 */ gpio_request(GPIO_FN_VIO0_D15, NULL); diff --git a/arch/sh/boards/mach-se/7780/irq.c b/arch/sh/boards/mach-se/7780/irq.c index 121744c08714..d5c9edc172a3 100644 --- a/arch/sh/boards/mach-se/7780/irq.c +++ b/arch/sh/boards/mach-se/7780/irq.c @@ -24,30 +24,30 @@ void __init init_se7780_IRQ(void) { /* enable all interrupt at FPGA */ - ctrl_outw(0, FPGA_INTMSK1); + __raw_writew(0, FPGA_INTMSK1); /* mask SM501 interrupt */ - ctrl_outw((ctrl_inw(FPGA_INTMSK1) | 0x0002), FPGA_INTMSK1); + __raw_writew((__raw_readw(FPGA_INTMSK1) | 0x0002), FPGA_INTMSK1); /* enable all interrupt at FPGA */ - ctrl_outw(0, FPGA_INTMSK2); + __raw_writew(0, FPGA_INTMSK2); /* set FPGA INTSEL register */ /* FPGA + 0x06 */ - ctrl_outw( ((IRQPIN_SM501 << IRQPOS_SM501) | + __raw_writew( ((IRQPIN_SM501 << IRQPOS_SM501) | (IRQPIN_SMC91CX << IRQPOS_SMC91CX)), FPGA_INTSEL1); /* FPGA + 0x08 */ - ctrl_outw(((IRQPIN_EXTINT4 << IRQPOS_EXTINT4) | + __raw_writew(((IRQPIN_EXTINT4 << IRQPOS_EXTINT4) | (IRQPIN_EXTINT3 << IRQPOS_EXTINT3) | (IRQPIN_EXTINT2 << IRQPOS_EXTINT2) | (IRQPIN_EXTINT1 << IRQPOS_EXTINT1)), FPGA_INTSEL2); /* FPGA + 0x0A */ - ctrl_outw((IRQPIN_PCCPW << IRQPOS_PCCPW), FPGA_INTSEL3); + __raw_writew((IRQPIN_PCCPW << IRQPOS_PCCPW), FPGA_INTSEL3); plat_irq_setup_pins(IRQ_MODE_IRQ); /* install handlers for IRQ0-7 */ /* ICR1: detect low level(for 2ndcut) */ - ctrl_outl(0xAAAA0000, INTC_ICR1); + __raw_writel(0xAAAA0000, INTC_ICR1); /* * FPGA PCISEL register initialize @@ -63,6 +63,6 @@ void __init init_se7780_IRQ(void) * INTD || INTD | INTC | -- | INTA * ------------------------------------- */ - ctrl_outw(0x0013, FPGA_PCI_INTSEL1); - ctrl_outw(0xE402, FPGA_PCI_INTSEL2); + __raw_writew(0x0013, FPGA_PCI_INTSEL1); + __raw_writew(0xE402, FPGA_PCI_INTSEL2); } diff --git a/arch/sh/boards/mach-se/7780/setup.c b/arch/sh/boards/mach-se/7780/setup.c index f7bfb3f83692..6f7c207138e1 100644 --- a/arch/sh/boards/mach-se/7780/setup.c +++ b/arch/sh/boards/mach-se/7780/setup.c @@ -75,14 +75,14 @@ device_initcall(se7780_devices_setup); static void __init se7780_setup(char **cmdline_p) { /* "SH-Linux" on LED Display */ - ctrl_outw( 'S' , PA_LED_DISP + (DISP_SEL0_ADDR << 1) ); - ctrl_outw( 'H' , PA_LED_DISP + (DISP_SEL1_ADDR << 1) ); - ctrl_outw( '-' , PA_LED_DISP + (DISP_SEL2_ADDR << 1) ); - ctrl_outw( 'L' , PA_LED_DISP + (DISP_SEL3_ADDR << 1) ); - ctrl_outw( 'i' , PA_LED_DISP + (DISP_SEL4_ADDR << 1) ); - ctrl_outw( 'n' , PA_LED_DISP + (DISP_SEL5_ADDR << 1) ); - ctrl_outw( 'u' , PA_LED_DISP + (DISP_SEL6_ADDR << 1) ); - ctrl_outw( 'x' , PA_LED_DISP + (DISP_SEL7_ADDR << 1) ); + __raw_writew( 'S' , PA_LED_DISP + (DISP_SEL0_ADDR << 1) ); + __raw_writew( 'H' , PA_LED_DISP + (DISP_SEL1_ADDR << 1) ); + __raw_writew( '-' , PA_LED_DISP + (DISP_SEL2_ADDR << 1) ); + __raw_writew( 'L' , PA_LED_DISP + (DISP_SEL3_ADDR << 1) ); + __raw_writew( 'i' , PA_LED_DISP + (DISP_SEL4_ADDR << 1) ); + __raw_writew( 'n' , PA_LED_DISP + (DISP_SEL5_ADDR << 1) ); + __raw_writew( 'u' , PA_LED_DISP + (DISP_SEL6_ADDR << 1) ); + __raw_writew( 'x' , PA_LED_DISP + (DISP_SEL7_ADDR << 1) ); printk(KERN_INFO "Hitachi UL Solutions Engine 7780SE03 support.\n"); @@ -93,15 +93,15 @@ static void __init se7780_setup(char **cmdline_p) * REQ2/GNT2 -> Serial ATA * REQ3/GNT3 -> PCI slot */ - ctrl_outw(0x0213, FPGA_REQSEL); + __raw_writew(0x0213, FPGA_REQSEL); /* GPIO setting */ - ctrl_outw(0x0000, GPIO_PECR); - ctrl_outw(ctrl_inw(GPIO_PHCR)&0xfff3, GPIO_PHCR); - ctrl_outw(0x0c00, GPIO_PMSELR); + __raw_writew(0x0000, GPIO_PECR); + __raw_writew(__raw_readw(GPIO_PHCR)&0xfff3, GPIO_PHCR); + __raw_writew(0x0c00, GPIO_PMSELR); /* iVDR Power ON */ - ctrl_outw(0x0001, FPGA_IVDRPW); + __raw_writew(0x0001, FPGA_IVDRPW); } /* diff --git a/arch/sh/boards/mach-sh03/rtc.c b/arch/sh/boards/mach-sh03/rtc.c index a8b9f844ab5b..1b200990500c 100644 --- a/arch/sh/boards/mach-sh03/rtc.c +++ b/arch/sh/boards/mach-sh03/rtc.c @@ -44,15 +44,15 @@ unsigned long get_cmos_time(void) spin_lock(&sh03_rtc_lock); again: do { - sec = (ctrl_inb(RTC_SEC1) & 0xf) + (ctrl_inb(RTC_SEC10) & 0x7) * 10; - min = (ctrl_inb(RTC_MIN1) & 0xf) + (ctrl_inb(RTC_MIN10) & 0xf) * 10; - hour = (ctrl_inb(RTC_HOU1) & 0xf) + (ctrl_inb(RTC_HOU10) & 0xf) * 10; - day = (ctrl_inb(RTC_DAY1) & 0xf) + (ctrl_inb(RTC_DAY10) & 0xf) * 10; - mon = (ctrl_inb(RTC_MON1) & 0xf) + (ctrl_inb(RTC_MON10) & 0xf) * 10; - year = (ctrl_inb(RTC_YEA1) & 0xf) + (ctrl_inb(RTC_YEA10) & 0xf) * 10 - + (ctrl_inb(RTC_YEA100 ) & 0xf) * 100 - + (ctrl_inb(RTC_YEA1000) & 0xf) * 1000; - } while (sec != (ctrl_inb(RTC_SEC1) & 0xf) + (ctrl_inb(RTC_SEC10) & 0x7) * 10); + sec = (__raw_readb(RTC_SEC1) & 0xf) + (__raw_readb(RTC_SEC10) & 0x7) * 10; + min = (__raw_readb(RTC_MIN1) & 0xf) + (__raw_readb(RTC_MIN10) & 0xf) * 10; + hour = (__raw_readb(RTC_HOU1) & 0xf) + (__raw_readb(RTC_HOU10) & 0xf) * 10; + day = (__raw_readb(RTC_DAY1) & 0xf) + (__raw_readb(RTC_DAY10) & 0xf) * 10; + mon = (__raw_readb(RTC_MON1) & 0xf) + (__raw_readb(RTC_MON10) & 0xf) * 10; + year = (__raw_readb(RTC_YEA1) & 0xf) + (__raw_readb(RTC_YEA10) & 0xf) * 10 + + (__raw_readb(RTC_YEA100 ) & 0xf) * 100 + + (__raw_readb(RTC_YEA1000) & 0xf) * 1000; + } while (sec != (__raw_readb(RTC_SEC1) & 0xf) + (__raw_readb(RTC_SEC10) & 0x7) * 10); if (year == 0 || mon < 1 || mon > 12 || day > 31 || day < 1 || hour > 23 || min > 59 || sec > 59) { printk(KERN_ERR @@ -60,16 +60,16 @@ unsigned long get_cmos_time(void) printk("year=%d, mon=%d, day=%d, hour=%d, min=%d, sec=%d\n", year, mon, day, hour, min, sec); - ctrl_outb(0, RTC_SEC1); ctrl_outb(0, RTC_SEC10); - ctrl_outb(0, RTC_MIN1); ctrl_outb(0, RTC_MIN10); - ctrl_outb(0, RTC_HOU1); ctrl_outb(0, RTC_HOU10); - ctrl_outb(6, RTC_WEE1); - ctrl_outb(1, RTC_DAY1); ctrl_outb(0, RTC_DAY10); - ctrl_outb(1, RTC_MON1); ctrl_outb(0, RTC_MON10); - ctrl_outb(0, RTC_YEA1); ctrl_outb(0, RTC_YEA10); - ctrl_outb(0, RTC_YEA100); - ctrl_outb(2, RTC_YEA1000); - ctrl_outb(0, RTC_CTL); + __raw_writeb(0, RTC_SEC1); __raw_writeb(0, RTC_SEC10); + __raw_writeb(0, RTC_MIN1); __raw_writeb(0, RTC_MIN10); + __raw_writeb(0, RTC_HOU1); __raw_writeb(0, RTC_HOU10); + __raw_writeb(6, RTC_WEE1); + __raw_writeb(1, RTC_DAY1); __raw_writeb(0, RTC_DAY10); + __raw_writeb(1, RTC_MON1); __raw_writeb(0, RTC_MON10); + __raw_writeb(0, RTC_YEA1); __raw_writeb(0, RTC_YEA10); + __raw_writeb(0, RTC_YEA100); + __raw_writeb(2, RTC_YEA1000); + __raw_writeb(0, RTC_CTL); goto again; } @@ -93,9 +93,9 @@ static int set_rtc_mmss(unsigned long nowtime) /* gets recalled with irq locally disabled */ spin_lock(&sh03_rtc_lock); for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */ - if (!(ctrl_inb(RTC_CTL) & RTC_BUSY)) + if (!(__raw_readb(RTC_CTL) & RTC_BUSY)) break; - cmos_minutes = (ctrl_inb(RTC_MIN1) & 0xf) + (ctrl_inb(RTC_MIN10) & 0xf) * 10; + cmos_minutes = (__raw_readb(RTC_MIN1) & 0xf) + (__raw_readb(RTC_MIN10) & 0xf) * 10; real_seconds = nowtime % 60; real_minutes = nowtime / 60; if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) @@ -103,10 +103,10 @@ static int set_rtc_mmss(unsigned long nowtime) real_minutes %= 60; if (abs(real_minutes - cmos_minutes) < 30) { - ctrl_outb(real_seconds % 10, RTC_SEC1); - ctrl_outb(real_seconds / 10, RTC_SEC10); - ctrl_outb(real_minutes % 10, RTC_MIN1); - ctrl_outb(real_minutes / 10, RTC_MIN10); + __raw_writeb(real_seconds % 10, RTC_SEC1); + __raw_writeb(real_seconds / 10, RTC_SEC10); + __raw_writeb(real_minutes % 10, RTC_MIN1); + __raw_writeb(real_minutes / 10, RTC_MIN10); } else { printk(KERN_WARNING "set_rtc_mmss: can't update from %d to %d\n", diff --git a/arch/sh/boards/mach-sh7763rdp/irq.c b/arch/sh/boards/mach-sh7763rdp/irq.c index d8ebfa7d8c76..add698c8f2b4 100644 --- a/arch/sh/boards/mach-sh7763rdp/irq.c +++ b/arch/sh/boards/mach-sh7763rdp/irq.c @@ -28,18 +28,18 @@ void __init init_sh7763rdp_IRQ(void) { /* GPIO enabled */ - ctrl_outl(1 << 25, INTC_INT2MSKCR); + __raw_writel(1 << 25, INTC_INT2MSKCR); /* enable GPIO interrupts */ - ctrl_outl((ctrl_inl(INTC_INT2PRI7) & 0xFF00FFFF) | 0x000F0000, + __raw_writel((__raw_readl(INTC_INT2PRI7) & 0xFF00FFFF) | 0x000F0000, INTC_INT2PRI7); /* USBH enabled */ - ctrl_outl(1 << 17, INTC_INT2MSKCR1); + __raw_writel(1 << 17, INTC_INT2MSKCR1); /* GETHER enabled */ - ctrl_outl(1 << 16, INTC_INT2MSKCR1); + __raw_writel(1 << 16, INTC_INT2MSKCR1); /* DMAC enabled */ - ctrl_outl(1 << 8, INTC_INT2MSKCR); + __raw_writel(1 << 8, INTC_INT2MSKCR); } diff --git a/arch/sh/boards/mach-sh7763rdp/setup.c b/arch/sh/boards/mach-sh7763rdp/setup.c index 390534a0b35c..f64a6918224c 100644 --- a/arch/sh/boards/mach-sh7763rdp/setup.c +++ b/arch/sh/boards/mach-sh7763rdp/setup.c @@ -158,50 +158,50 @@ device_initcall(sh7763rdp_devices_setup); static void __init sh7763rdp_setup(char **cmdline_p) { /* Board version check */ - if (ctrl_inw(CPLD_BOARD_ID_ERV_REG) == 0xECB1) + if (__raw_readw(CPLD_BOARD_ID_ERV_REG) == 0xECB1) printk(KERN_INFO "RTE Standard Configuration\n"); else printk(KERN_INFO "RTA Standard Configuration\n"); /* USB pin select bits (clear bit 5-2 to 0) */ - ctrl_outw((ctrl_inw(PORT_PSEL2) & 0xFFC3), PORT_PSEL2); + __raw_writew((__raw_readw(PORT_PSEL2) & 0xFFC3), PORT_PSEL2); /* USBH setup port I controls to other (clear bits 4-9 to 0) */ - ctrl_outw(ctrl_inw(PORT_PICR) & 0xFC0F, PORT_PICR); + __raw_writew(__raw_readw(PORT_PICR) & 0xFC0F, PORT_PICR); /* Select USB Host controller */ - ctrl_outw(0x00, USB_USBHSC); + __raw_writew(0x00, USB_USBHSC); /* For LCD */ /* set PTJ7-1, bits 15-2 of PJCR to 0 */ - ctrl_outw(ctrl_inw(PORT_PJCR) & 0x0003, PORT_PJCR); + __raw_writew(__raw_readw(PORT_PJCR) & 0x0003, PORT_PJCR); /* set PTI5, bits 11-10 of PICR to 0 */ - ctrl_outw(ctrl_inw(PORT_PICR) & 0xF3FF, PORT_PICR); - ctrl_outw(0, PORT_PKCR); - ctrl_outw(0, PORT_PLCR); + __raw_writew(__raw_readw(PORT_PICR) & 0xF3FF, PORT_PICR); + __raw_writew(0, PORT_PKCR); + __raw_writew(0, PORT_PLCR); /* set PSEL2 bits 14-8, 5-4, of PSEL2 to 0 */ - ctrl_outw((ctrl_inw(PORT_PSEL2) & 0x00C0), PORT_PSEL2); + __raw_writew((__raw_readw(PORT_PSEL2) & 0x00C0), PORT_PSEL2); /* set PSEL3 bits 14-12, 6-4, 2-0 of PSEL3 to 0 */ - ctrl_outw((ctrl_inw(PORT_PSEL3) & 0x0700), PORT_PSEL3); + __raw_writew((__raw_readw(PORT_PSEL3) & 0x0700), PORT_PSEL3); /* For HAC */ /* bit3-0 0100:HAC & SSI1 enable */ - ctrl_outw((ctrl_inw(PORT_PSEL1) & 0xFFF0) | 0x0004, PORT_PSEL1); + __raw_writew((__raw_readw(PORT_PSEL1) & 0xFFF0) | 0x0004, PORT_PSEL1); /* bit14 1:SSI_HAC_CLK enable */ - ctrl_outw(ctrl_inw(PORT_PSEL4) | 0x4000, PORT_PSEL4); + __raw_writew(__raw_readw(PORT_PSEL4) | 0x4000, PORT_PSEL4); /* SH-Ether */ - ctrl_outw((ctrl_inw(PORT_PSEL1) & ~0xff00) | 0x2400, PORT_PSEL1); - ctrl_outw(0x0, PORT_PFCR); - ctrl_outw(0x0, PORT_PFCR); - ctrl_outw(0x0, PORT_PFCR); + __raw_writew((__raw_readw(PORT_PSEL1) & ~0xff00) | 0x2400, PORT_PSEL1); + __raw_writew(0x0, PORT_PFCR); + __raw_writew(0x0, PORT_PFCR); + __raw_writew(0x0, PORT_PFCR); /* MMC */ /*selects SCIF and MMC other functions */ - ctrl_outw(0x0001, PORT_PSEL0); + __raw_writew(0x0001, PORT_PSEL0); /* MMC clock operates */ - ctrl_outl(ctrl_inl(MSTPCR1) & ~0x8, MSTPCR1); - ctrl_outw(ctrl_inw(PORT_PACR) & ~0x3000, PORT_PACR); - ctrl_outw(ctrl_inw(PORT_PCCR) & ~0xCFC3, PORT_PCCR); + __raw_writel(__raw_readl(MSTPCR1) & ~0x8, MSTPCR1); + __raw_writew(__raw_readw(PORT_PACR) & ~0x3000, PORT_PACR); + __raw_writew(__raw_readw(PORT_PCCR) & ~0xCFC3, PORT_PCCR); } static struct sh_machine_vector mv_sh7763rdp __initmv = { diff --git a/arch/sh/boards/mach-snapgear/setup.c b/arch/sh/boards/mach-snapgear/setup.c index a3277a23cf14..331745dee379 100644 --- a/arch/sh/boards/mach-snapgear/setup.c +++ b/arch/sh/boards/mach-snapgear/setup.c @@ -30,7 +30,7 @@ static irqreturn_t eraseconfig_interrupt(int irq, void *dev_id) { - (void)ctrl_inb(0xb8000000); /* dummy read */ + (void)__raw_readb(0xb8000000); /* dummy read */ printk("SnapGear: erase switch interrupt!\n"); diff --git a/arch/sh/boards/mach-systemh/irq.c b/arch/sh/boards/mach-systemh/irq.c index 986a0e71d220..523aea5dc94e 100644 --- a/arch/sh/boards/mach-systemh/irq.c +++ b/arch/sh/boards/mach-systemh/irq.c @@ -41,13 +41,13 @@ static void disable_systemh_irq(unsigned int irq) unsigned long val, mask = 0x01 << 1; /* Clear the "irq"th bit in the mask and set it in the request */ - val = ctrl_inl((unsigned long)systemh_irq_mask_register); + val = __raw_readl((unsigned long)systemh_irq_mask_register); val &= ~mask; - ctrl_outl(val, (unsigned long)systemh_irq_mask_register); + __raw_writel(val, (unsigned long)systemh_irq_mask_register); - val = ctrl_inl((unsigned long)systemh_irq_request_register); + val = __raw_readl((unsigned long)systemh_irq_request_register); val |= mask; - ctrl_outl(val, (unsigned long)systemh_irq_request_register); + __raw_writel(val, (unsigned long)systemh_irq_request_register); } } @@ -57,9 +57,9 @@ static void enable_systemh_irq(unsigned int irq) unsigned long val, mask = 0x01 << 1; /* Set "irq"th bit in the mask register */ - val = ctrl_inl((unsigned long)systemh_irq_mask_register); + val = __raw_readl((unsigned long)systemh_irq_mask_register); val |= mask; - ctrl_outl(val, (unsigned long)systemh_irq_mask_register); + __raw_writel(val, (unsigned long)systemh_irq_mask_register); } } diff --git a/arch/sh/boards/mach-titan/io.c b/arch/sh/boards/mach-titan/io.c index 0130e9826aca..29754c5091f0 100644 --- a/arch/sh/boards/mach-titan/io.c +++ b/arch/sh/boards/mach-titan/io.c @@ -16,8 +16,8 @@ static inline unsigned int port2adr(unsigned int port) u8 titan_inb(unsigned long port) { if (PXSEG(port)) - return ctrl_inb(port); - return ctrl_inw(port2adr(port)) & 0xff; + return __raw_readb(port); + return __raw_readw(port2adr(port)) & 0xff; } u8 titan_inb_p(unsigned long port) @@ -25,9 +25,9 @@ u8 titan_inb_p(unsigned long port) u8 v; if (PXSEG(port)) - v = ctrl_inb(port); + v = __raw_readb(port); else - v = ctrl_inw(port2adr(port)) & 0xff; + v = __raw_readw(port2adr(port)) & 0xff; ctrl_delay(); return v; } @@ -35,9 +35,9 @@ u8 titan_inb_p(unsigned long port) u16 titan_inw(unsigned long port) { if (PXSEG(port)) - return ctrl_inw(port); + return __raw_readw(port); else if (port >= 0x2000) - return ctrl_inw(port2adr(port)); + return __raw_readw(port2adr(port)); else maybebadio(port); return 0; @@ -46,9 +46,9 @@ u16 titan_inw(unsigned long port) u32 titan_inl(unsigned long port) { if (PXSEG(port)) - return ctrl_inl(port); + return __raw_readl(port); else if (port >= 0x2000) - return ctrl_inw(port2adr(port)); + return __raw_readw(port2adr(port)); else maybebadio(port); return 0; @@ -57,26 +57,26 @@ u32 titan_inl(unsigned long port) void titan_outb(u8 value, unsigned long port) { if (PXSEG(port)) - ctrl_outb(value, port); + __raw_writeb(value, port); else - ctrl_outw(value, port2adr(port)); + __raw_writew(value, port2adr(port)); } void titan_outb_p(u8 value, unsigned long port) { if (PXSEG(port)) - ctrl_outb(value, port); + __raw_writeb(value, port); else - ctrl_outw(value, port2adr(port)); + __raw_writew(value, port2adr(port)); ctrl_delay(); } void titan_outw(u16 value, unsigned long port) { if (PXSEG(port)) - ctrl_outw(value, port); + __raw_writew(value, port); else if (port >= 0x2000) - ctrl_outw(value, port2adr(port)); + __raw_writew(value, port2adr(port)); else maybebadio(port); } @@ -84,7 +84,7 @@ void titan_outw(u16 value, unsigned long port) void titan_outl(u32 value, unsigned long port) { if (PXSEG(port)) - ctrl_outl(value, port); + __raw_writel(value, port); else maybebadio(port); } diff --git a/arch/sh/boards/mach-x3proto/ilsel.c b/arch/sh/boards/mach-x3proto/ilsel.c index b5c673c39337..5c9842704c60 100644 --- a/arch/sh/boards/mach-x3proto/ilsel.c +++ b/arch/sh/boards/mach-x3proto/ilsel.c @@ -70,10 +70,10 @@ static void __ilsel_enable(ilsel_source_t set, unsigned int bit) pr_debug("%s: bit#%d: addr - 0x%08lx (shift %d, set %d)\n", __func__, bit, addr, shift, set); - tmp = ctrl_inw(addr); + tmp = __raw_readw(addr); tmp &= ~(0xf << shift); tmp |= set << shift; - ctrl_outw(tmp, addr); + __raw_writew(tmp, addr); } /** @@ -142,9 +142,9 @@ void ilsel_disable(unsigned int irq) addr = mk_ilsel_addr(irq); - tmp = ctrl_inw(addr); + tmp = __raw_readw(addr); tmp &= ~(0xf << mk_ilsel_shift(irq)); - ctrl_outw(tmp, addr); + __raw_writew(tmp, addr); clear_bit(irq, &ilsel_level_map); } diff --git a/arch/sh/boards/mach-x3proto/setup.c b/arch/sh/boards/mach-x3proto/setup.c index efe4cb9f8a77..e284592fd42a 100644 --- a/arch/sh/boards/mach-x3proto/setup.c +++ b/arch/sh/boards/mach-x3proto/setup.c @@ -149,7 +149,7 @@ static void __init x3proto_init_irq(void) plat_irq_setup_pins(IRQ_MODE_IRL3210); /* Set ICR0.LVLMODE */ - ctrl_outl(ctrl_inl(0xfe410000) | (1 << 21), 0xfe410000); + __raw_writel(__raw_readl(0xfe410000) | (1 << 21), 0xfe410000); } static struct sh_machine_vector mv_x3proto __initmv = { diff --git a/arch/sh/cchips/hd6446x/hd64461.c b/arch/sh/cchips/hd6446x/hd64461.c index 50aa0c1f76ea..cbfedfb42e04 100644 --- a/arch/sh/cchips/hd6446x/hd64461.c +++ b/arch/sh/cchips/hd6446x/hd64461.c @@ -55,7 +55,7 @@ static struct irq_chip hd64461_irq_chip = { static void hd64461_irq_demux(unsigned int irq, struct irq_desc *desc) { - unsigned short intv = ctrl_inw(HD64461_NIRR); + unsigned short intv = __raw_readw(HD64461_NIRR); struct irq_desc *ext_desc; unsigned int ext_irq = HD64461_IRQBASE; diff --git a/arch/sh/drivers/dma/dma-pvr2.c b/arch/sh/drivers/dma/dma-pvr2.c index 391cbe1c2956..3cee58e7f1e5 100644 --- a/arch/sh/drivers/dma/dma-pvr2.c +++ b/arch/sh/drivers/dma/dma-pvr2.c @@ -40,10 +40,10 @@ static irqreturn_t pvr2_dma_interrupt(int irq, void *dev_id) static int pvr2_request_dma(struct dma_channel *chan) { - if (ctrl_inl(PVR2_DMA_MODE) != 0) + if (__raw_readl(PVR2_DMA_MODE) != 0) return -EBUSY; - ctrl_outl(0, PVR2_DMA_LMMODE0); + __raw_writel(0, PVR2_DMA_LMMODE0); return 0; } @@ -60,9 +60,9 @@ static int pvr2_xfer_dma(struct dma_channel *chan) xfer_complete = 0; - ctrl_outl(chan->dar, PVR2_DMA_ADDR); - ctrl_outl(chan->count, PVR2_DMA_COUNT); - ctrl_outl(chan->mode & DMA_MODE_MASK, PVR2_DMA_MODE); + __raw_writel(chan->dar, PVR2_DMA_ADDR); + __raw_writel(chan->count, PVR2_DMA_COUNT); + __raw_writel(chan->mode & DMA_MODE_MASK, PVR2_DMA_MODE); return 0; } diff --git a/arch/sh/drivers/dma/dma-sh.c b/arch/sh/drivers/dma/dma-sh.c index 37fb5b8bbc3f..565cc1a4cbba 100644 --- a/arch/sh/drivers/dma/dma-sh.c +++ b/arch/sh/drivers/dma/dma-sh.c @@ -54,7 +54,7 @@ static inline unsigned int get_dmte_irq(unsigned int chan) */ static inline unsigned int calc_xmit_shift(struct dma_channel *chan) { - u32 chcr = ctrl_inl(dma_base_addr[chan->chan] + CHCR); + u32 chcr = __raw_readl(dma_base_addr[chan->chan] + CHCR); return ts_shift[(chcr & CHCR_TS_MASK)>>CHCR_TS_SHIFT]; } @@ -70,13 +70,13 @@ static irqreturn_t dma_tei(int irq, void *dev_id) struct dma_channel *chan = dev_id; u32 chcr; - chcr = ctrl_inl(dma_base_addr[chan->chan] + CHCR); + chcr = __raw_readl(dma_base_addr[chan->chan] + CHCR); if (!(chcr & CHCR_TE)) return IRQ_NONE; chcr &= ~(CHCR_IE | CHCR_DE); - ctrl_outl(chcr, (dma_base_addr[chan->chan] + CHCR)); + __raw_writel(chcr, (dma_base_addr[chan->chan] + CHCR)); wake_up(&chan->wait_queue); @@ -115,7 +115,7 @@ sh_dmac_configure_channel(struct dma_channel *chan, unsigned long chcr) chan->flags &= ~DMA_TEI_CAPABLE; } - ctrl_outl(chcr, (dma_base_addr[chan->chan] + CHCR)); + __raw_writel(chcr, (dma_base_addr[chan->chan] + CHCR)); chan->flags |= DMA_CONFIGURED; return 0; @@ -126,13 +126,13 @@ static void sh_dmac_enable_dma(struct dma_channel *chan) int irq; u32 chcr; - chcr = ctrl_inl(dma_base_addr[chan->chan] + CHCR); + chcr = __raw_readl(dma_base_addr[chan->chan] + CHCR); chcr |= CHCR_DE; if (chan->flags & DMA_TEI_CAPABLE) chcr |= CHCR_IE; - ctrl_outl(chcr, (dma_base_addr[chan->chan] + CHCR)); + __raw_writel(chcr, (dma_base_addr[chan->chan] + CHCR)); if (chan->flags & DMA_TEI_CAPABLE) { irq = get_dmte_irq(chan->chan); @@ -150,9 +150,9 @@ static void sh_dmac_disable_dma(struct dma_channel *chan) disable_irq(irq); } - chcr = ctrl_inl(dma_base_addr[chan->chan] + CHCR); + chcr = __raw_readl(dma_base_addr[chan->chan] + CHCR); chcr &= ~(CHCR_DE | CHCR_TE | CHCR_IE); - ctrl_outl(chcr, (dma_base_addr[chan->chan] + CHCR)); + __raw_writel(chcr, (dma_base_addr[chan->chan] + CHCR)); } static int sh_dmac_xfer_dma(struct dma_channel *chan) @@ -183,12 +183,12 @@ static int sh_dmac_xfer_dma(struct dma_channel *chan) */ if (chan->sar || (mach_is_dreamcast() && chan->chan == PVR2_CASCADE_CHAN)) - ctrl_outl(chan->sar, (dma_base_addr[chan->chan]+SAR)); + __raw_writel(chan->sar, (dma_base_addr[chan->chan]+SAR)); if (chan->dar || (mach_is_dreamcast() && chan->chan == PVR2_CASCADE_CHAN)) - ctrl_outl(chan->dar, (dma_base_addr[chan->chan] + DAR)); + __raw_writel(chan->dar, (dma_base_addr[chan->chan] + DAR)); - ctrl_outl(chan->count >> calc_xmit_shift(chan), + __raw_writel(chan->count >> calc_xmit_shift(chan), (dma_base_addr[chan->chan] + TCR)); sh_dmac_enable_dma(chan); @@ -198,10 +198,10 @@ static int sh_dmac_xfer_dma(struct dma_channel *chan) static int sh_dmac_get_dma_residue(struct dma_channel *chan) { - if (!(ctrl_inl(dma_base_addr[chan->chan] + CHCR) & CHCR_DE)) + if (!(__raw_readl(dma_base_addr[chan->chan] + CHCR) & CHCR_DE)) return 0; - return ctrl_inl(dma_base_addr[chan->chan] + TCR) + return __raw_readl(dma_base_addr[chan->chan] + TCR) << calc_xmit_shift(chan); } diff --git a/arch/sh/drivers/dma/dmabrg.c b/arch/sh/drivers/dma/dmabrg.c index 5e22689c2fcf..72622e307613 100644 --- a/arch/sh/drivers/dma/dmabrg.c +++ b/arch/sh/drivers/dma/dmabrg.c @@ -86,8 +86,8 @@ static irqreturn_t dmabrg_irq(int irq, void *data) unsigned long dcr; unsigned int i; - dcr = ctrl_inl(DMABRGCR); - ctrl_outl(dcr & ~0x00ff0003, DMABRGCR); /* ack all */ + dcr = __raw_readl(DMABRGCR); + __raw_writel(dcr & ~0x00ff0003, DMABRGCR); /* ack all */ dcr &= dcr >> 8; /* ignore masked */ /* USB stuff, get it out of the way first */ @@ -109,17 +109,17 @@ static irqreturn_t dmabrg_irq(int irq, void *data) static void dmabrg_disable_irq(unsigned int dmairq) { unsigned long dcr; - dcr = ctrl_inl(DMABRGCR); + dcr = __raw_readl(DMABRGCR); dcr &= ~(1 << ((dmairq > 1) ? dmairq + 22 : dmairq + 8)); - ctrl_outl(dcr, DMABRGCR); + __raw_writel(dcr, DMABRGCR); } static void dmabrg_enable_irq(unsigned int dmairq) { unsigned long dcr; - dcr = ctrl_inl(DMABRGCR); + dcr = __raw_readl(DMABRGCR); dcr |= (1 << ((dmairq > 1) ? dmairq + 22 : dmairq + 8)); - ctrl_outl(dcr, DMABRGCR); + __raw_writel(dcr, DMABRGCR); } int dmabrg_request_irq(unsigned int dmairq, void(*handler)(void*), @@ -165,13 +165,13 @@ static int __init dmabrg_init(void) printk(KERN_INFO "DMABRG: DMAC ch0 not reserved!\n"); #endif - ctrl_outl(0, DMABRGCR); - ctrl_outl(0, DMACHCR0); - ctrl_outl(0x94000000, DMARSRA); /* enable DMABRG in DMAC 0 */ + __raw_writel(0, DMABRGCR); + __raw_writel(0, DMACHCR0); + __raw_writel(0x94000000, DMARSRA); /* enable DMABRG in DMAC 0 */ /* enable DMABRG mode, enable the DMAC */ - or = ctrl_inl(DMAOR); - ctrl_outl(or | DMAOR_BRG | DMAOR_DMEN, DMAOR); + or = __raw_readl(DMAOR); + __raw_writel(or | DMAOR_BRG | DMAOR_DMEN, DMAOR); ret = request_irq(DMABRGI0, dmabrg_irq, IRQF_DISABLED, "DMABRG USB address error", NULL); diff --git a/arch/sh/drivers/pci/fixups-rts7751r2d.c b/arch/sh/drivers/pci/fixups-rts7751r2d.c index 7898f14d6641..e248516118a9 100644 --- a/arch/sh/drivers/pci/fixups-rts7751r2d.c +++ b/arch/sh/drivers/pci/fixups-rts7751r2d.c @@ -43,7 +43,7 @@ int pci_fixup_pcic(struct pci_channel *chan) { unsigned long bcr1, mcr; - bcr1 = ctrl_inl(SH7751_BCR1); + bcr1 = __raw_readl(SH7751_BCR1); bcr1 |= 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */ pci_write_reg(chan, bcr1, SH4_PCIBCR1); @@ -54,7 +54,7 @@ int pci_fixup_pcic(struct pci_channel *chan) pci_write_reg(chan, 0xfb900047, SH7751_PCICONF1); pci_write_reg(chan, 0xab000001, SH7751_PCICONF4); - mcr = ctrl_inl(SH7751_MCR); + mcr = __raw_readl(SH7751_MCR); mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF; pci_write_reg(chan, mcr, SH4_PCIMCR); diff --git a/arch/sh/drivers/pci/pci-sh4.h b/arch/sh/drivers/pci/pci-sh4.h index 3d5296cde622..4744a7dede0c 100644 --- a/arch/sh/drivers/pci/pci-sh4.h +++ b/arch/sh/drivers/pci/pci-sh4.h @@ -167,13 +167,13 @@ struct sh4_pci_address_map { static inline void pci_write_reg(struct pci_channel *chan, unsigned long val, unsigned long reg) { - ctrl_outl(val, chan->reg_base + reg); + __raw_writel(val, chan->reg_base + reg); } static inline unsigned long pci_read_reg(struct pci_channel *chan, unsigned long reg) { - return ctrl_inl(chan->reg_base + reg); + return __raw_readl(chan->reg_base + reg); } #endif /* __PCI_SH4_H */ diff --git a/arch/sh/drivers/pci/pci-sh5.h b/arch/sh/drivers/pci/pci-sh5.h index f277628221f3..3f01decb4307 100644 --- a/arch/sh/drivers/pci/pci-sh5.h +++ b/arch/sh/drivers/pci/pci-sh5.h @@ -86,14 +86,14 @@ extern unsigned long pcicr_virt; /* #define PCISH5_VCR_REG(x) ( SH5PCI_VCR_BASE (PCISH5_VCR_##x)) */ /* Write I/O functions */ -#define SH5PCI_WRITE(reg,val) ctrl_outl((u32)(val),PCISH5_ICR_REG(reg)) -#define SH5PCI_WRITE_SHORT(reg,val) ctrl_outw((u16)(val),PCISH5_ICR_REG(reg)) -#define SH5PCI_WRITE_BYTE(reg,val) ctrl_outb((u8)(val),PCISH5_ICR_REG(reg)) +#define SH5PCI_WRITE(reg,val) __raw_writel((u32)(val),PCISH5_ICR_REG(reg)) +#define SH5PCI_WRITE_SHORT(reg,val) __raw_writew((u16)(val),PCISH5_ICR_REG(reg)) +#define SH5PCI_WRITE_BYTE(reg,val) __raw_writeb((u8)(val),PCISH5_ICR_REG(reg)) /* Read I/O functions */ -#define SH5PCI_READ(reg) ctrl_inl(PCISH5_ICR_REG(reg)) -#define SH5PCI_READ_SHORT(reg) ctrl_inw(PCISH5_ICR_REG(reg)) -#define SH5PCI_READ_BYTE(reg) ctrl_inb(PCISH5_ICR_REG(reg)) +#define SH5PCI_READ(reg) __raw_readl(PCISH5_ICR_REG(reg)) +#define SH5PCI_READ_SHORT(reg) __raw_readw(PCISH5_ICR_REG(reg)) +#define SH5PCI_READ_BYTE(reg) __raw_readb(PCISH5_ICR_REG(reg)) /* Set PCI config bits */ #define SET_CONFIG_BITS(bus,devfn,where) ((((bus) << 16) | ((devfn) << 8) | ((where) & ~3)) | 0x80000000) diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c index 70c1999a0ec4..2455cf32db5a 100644 --- a/arch/sh/drivers/pci/pci-sh7751.c +++ b/arch/sh/drivers/pci/pci-sh7751.c @@ -97,9 +97,9 @@ static int __init sh7751_pci_init(void) return ret; /* Set the BCR's to enable PCI access */ - reg = ctrl_inl(SH7751_BCR1); + reg = __raw_readl(SH7751_BCR1); reg |= 0x80000; - ctrl_outl(reg, SH7751_BCR1); + __raw_writel(reg, SH7751_BCR1); /* Turn the clocks back on (not done in reset)*/ pci_write_reg(chan, 0, SH4_PCICLKR); @@ -159,13 +159,13 @@ static int __init sh7751_pci_init(void) return -1; /* configure the wait control registers */ - word = ctrl_inl(SH7751_WCR1); + word = __raw_readl(SH7751_WCR1); pci_write_reg(chan, word, SH4_PCIWCR1); - word = ctrl_inl(SH7751_WCR2); + word = __raw_readl(SH7751_WCR2); pci_write_reg(chan, word, SH4_PCIWCR2); - word = ctrl_inl(SH7751_WCR3); + word = __raw_readl(SH7751_WCR3); pci_write_reg(chan, word, SH4_PCIWCR3); - word = ctrl_inl(SH7751_MCR); + word = __raw_readl(SH7751_MCR); pci_write_reg(chan, word, SH4_PCIMCR); /* NOTE: I'm ignoring the PCI error IRQs for now.. diff --git a/arch/sh/drivers/superhyway/ops-sh4-202.c b/arch/sh/drivers/superhyway/ops-sh4-202.c index 3b14bf860db6..6da62e9475c4 100644 --- a/arch/sh/drivers/superhyway/ops-sh4-202.c +++ b/arch/sh/drivers/superhyway/ops-sh4-202.c @@ -134,8 +134,8 @@ static int sh4202_read_vcr(unsigned long base, struct superhyway_vcr_info *vcr) * * Do not trust the documentation, for it is evil. */ - vcrh = ctrl_inl(base); - vcrl = ctrl_inl(base + sizeof(u32)); + vcrh = __raw_readl(base); + vcrl = __raw_readl(base + sizeof(u32)); tmp = ((u64)vcrh << 32) | vcrl; memcpy(vcr, &tmp, sizeof(u64)); @@ -147,8 +147,8 @@ static int sh4202_write_vcr(unsigned long base, struct superhyway_vcr_info vcr) { u64 tmp = *(u64 *)&vcr; - ctrl_outl((tmp >> 32) & 0xffffffff, base); - ctrl_outl(tmp & 0xffffffff, base + sizeof(u32)); + __raw_writel((tmp >> 32) & 0xffffffff, base); + __raw_writel(tmp & 0xffffffff, base + sizeof(u32)); return 0; } diff --git a/arch/sh/include/asm/dma-sh.h b/arch/sh/include/asm/dma-sh.h index 78eed3e0bdf5..47de10976991 100644 --- a/arch/sh/include/asm/dma-sh.h +++ b/arch/sh/include/asm/dma-sh.h @@ -20,14 +20,14 @@ 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 = { diff --git a/arch/sh/include/asm/mmu_context.h b/arch/sh/include/asm/mmu_context.h index 41080b173a7a..384c7471a374 100644 --- a/arch/sh/include/asm/mmu_context.h +++ b/arch/sh/include/asm/mmu_context.h @@ -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 8ef800c549ab..10e2e17210d2 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/watchdog.h b/arch/sh/include/asm/watchdog.h index 19dfff5c8511..85a7aca7fb8f 100644 --- a/arch/sh/include/asm/watchdog.h +++ b/arch/sh/include/asm/watchdog.h @@ -70,7 +70,7 @@ */ static inline __u32 sh_wdt_read_cnt(void) { - return ctrl_inl(WTCNT_R); + return __raw_readl(WTCNT_R); } /** @@ -82,7 +82,7 @@ static inline __u32 sh_wdt_read_cnt(void) */ static inline void sh_wdt_write_cnt(__u32 val) { - ctrl_outl((WTCNT_HIGH << 24) | (__u32)val, WTCNT); + __raw_writel((WTCNT_HIGH << 24) | (__u32)val, WTCNT); } /** @@ -94,7 +94,7 @@ static inline void sh_wdt_write_cnt(__u32 val) */ static inline void sh_wdt_write_bst(__u32 val) { - ctrl_outl((WTBST_HIGH << 24) | (__u32)val, WTBST); + __raw_writel((WTBST_HIGH << 24) | (__u32)val, WTBST); } /** * sh_wdt_read_csr - Read from Control/Status Register @@ -103,7 +103,7 @@ static inline void sh_wdt_write_bst(__u32 val) */ static inline __u32 sh_wdt_read_csr(void) { - return ctrl_inl(WTCSR_R); + return __raw_readl(WTCSR_R); } /** @@ -115,7 +115,7 @@ static inline __u32 sh_wdt_read_csr(void) */ static inline void sh_wdt_write_csr(__u32 val) { - ctrl_outl((WTCSR_HIGH << 24) | (__u32)val, WTCSR); + __raw_writel((WTCSR_HIGH << 24) | (__u32)val, WTCSR); } #else /** @@ -124,7 +124,7 @@ static inline void sh_wdt_write_csr(__u32 val) */ static inline __u8 sh_wdt_read_cnt(void) { - return ctrl_inb(WTCNT_R); + return __raw_readb(WTCNT_R); } /** @@ -136,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); } /** @@ -146,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); } /** @@ -158,7 +158,7 @@ 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__ */ diff --git a/arch/sh/include/cpu-sh2/cpu/watchdog.h b/arch/sh/include/cpu-sh2/cpu/watchdog.h index 393161c9c6d0..1eab8aa63a6d 100644 --- a/arch/sh/include/cpu-sh2/cpu/watchdog.h +++ b/arch/sh/include/cpu-sh2/cpu/watchdog.h @@ -44,7 +44,7 @@ static inline __u8 sh_wdt_read_rstcsr(void) /* * Same read/write brain-damage as for WTCNT here.. */ - return ctrl_inb(RSTCSR_R); + return __raw_readb(RSTCSR_R); } /** @@ -62,7 +62,7 @@ static inline void sh_wdt_write_rstcsr(__u8 val) * we can't presently touch the WOVF bit, since the upper byte * has to be swapped for this. So just leave it alone.. */ - ctrl_outw((WTCNT_HIGH << 8) | (__u16)val, RSTCSR); + __raw_writeb((WTCNT_HIGH << 8) | (__u16)val, RSTCSR); } #endif /* __ASM_CPU_SH2_WATCHDOG_H */ diff --git a/arch/sh/include/cpu-sh3/cpu/dac.h b/arch/sh/include/cpu-sh3/cpu/dac.h index 05fda8316ebc..98f1d15f0ab5 100644 --- a/arch/sh/include/cpu-sh3/cpu/dac.h +++ b/arch/sh/include/cpu-sh3/cpu/dac.h @@ -17,25 +17,25 @@ static __inline__ void sh_dac_enable(int channel) { unsigned char v; - v = ctrl_inb(DACR); + v = __raw_readb(DACR); if(channel) v |= DACR_DAOE1; else v |= DACR_DAOE0; - ctrl_outb(v,DACR); + __raw_writeb(v,DACR); } static __inline__ void sh_dac_disable(int channel) { unsigned char v; - v = ctrl_inb(DACR); + v = __raw_readb(DACR); if(channel) v &= ~DACR_DAOE1; else v &= ~DACR_DAOE0; - ctrl_outb(v,DACR); + __raw_writeb(v,DACR); } static __inline__ void sh_dac_output(u8 value, int channel) { - if(channel) ctrl_outb(value,DADR1); - else ctrl_outb(value,DADR0); + if(channel) __raw_writeb(value,DADR1); + else __raw_writeb(value,DADR0); } #endif /* __ASM_CPU_SH3_DAC_H */ diff --git a/arch/sh/include/mach-common/mach/magicpanelr2.h b/arch/sh/include/mach-common/mach/magicpanelr2.h index c644a77ee357..183a2f744251 100644 --- a/arch/sh/include/mach-common/mach/magicpanelr2.h +++ b/arch/sh/include/mach-common/mach/magicpanelr2.h @@ -19,12 +19,12 @@ #include -#define SETBITS_OUTB(mask, reg) ctrl_outb(ctrl_inb(reg) | mask, reg) -#define SETBITS_OUTW(mask, reg) ctrl_outw(ctrl_inw(reg) | mask, reg) -#define SETBITS_OUTL(mask, reg) ctrl_outl(ctrl_inl(reg) | mask, reg) -#define CLRBITS_OUTB(mask, reg) ctrl_outb(ctrl_inb(reg) & ~mask, reg) -#define CLRBITS_OUTW(mask, reg) ctrl_outw(ctrl_inw(reg) & ~mask, reg) -#define CLRBITS_OUTL(mask, reg) ctrl_outl(ctrl_inl(reg) & ~mask, reg) +#define SETBITS_OUTB(mask, reg) __raw_writeb(__raw_readb(reg) | mask, reg) +#define SETBITS_OUTW(mask, reg) __raw_writew(__raw_readw(reg) | mask, reg) +#define SETBITS_OUTL(mask, reg) __raw_writel(__raw_readl(reg) | mask, reg) +#define CLRBITS_OUTB(mask, reg) __raw_writeb(__raw_readb(reg) & ~mask, reg) +#define CLRBITS_OUTW(mask, reg) __raw_writew(__raw_readw(reg) & ~mask, reg) +#define CLRBITS_OUTL(mask, reg) __raw_writel(__raw_readl(reg) & ~mask, reg) #define PA_LED PORT_PADR /* LED */ diff --git a/arch/sh/kernel/cpu/adc.c b/arch/sh/kernel/cpu/adc.c index da3d6877f93d..d307571d54b6 100644 --- a/arch/sh/kernel/cpu/adc.c +++ b/arch/sh/kernel/cpu/adc.c @@ -18,19 +18,19 @@ int adc_single(unsigned int channel) off = (channel & 0x03) << 2; - csr = ctrl_inb(ADCSR); + csr = __raw_readb(ADCSR); csr = channel | ADCSR_ADST | ADCSR_CKS; - ctrl_outb(csr, ADCSR); + __raw_writeb(csr, ADCSR); do { - csr = ctrl_inb(ADCSR); + csr = __raw_readb(ADCSR); } while ((csr & ADCSR_ADF) == 0); csr &= ~(ADCSR_ADF | ADCSR_ADST); - ctrl_outb(csr, ADCSR); + __raw_writeb(csr, ADCSR); - return (((ctrl_inb(ADDRAH + off) << 8) | - ctrl_inb(ADDRAL + off)) >> 6); + return (((__raw_readb(ADDRAH + off) << 8) | + __raw_readb(ADDRAL + off)) >> 6); } EXPORT_SYMBOL(adc_single); diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c index 05a7d2a373b6..6311b0b1789d 100644 --- a/arch/sh/kernel/cpu/init.c +++ b/arch/sh/kernel/cpu/init.c @@ -61,10 +61,10 @@ onchip_setup(dsp); static void __init speculative_execution_init(void) { /* Clear RABD */ - ctrl_outl(ctrl_inl(CPUOPM) & ~CPUOPM_RABD, CPUOPM); + __raw_writel(__raw_readl(CPUOPM) & ~CPUOPM_RABD, CPUOPM); /* Flush the update */ - (void)ctrl_inl(CPUOPM); + (void)__raw_readl(CPUOPM); ctrl_barrier(); } #else @@ -111,7 +111,7 @@ static void cache_init(void) unsigned long ccr, flags; jump_to_uncached(); - ccr = ctrl_inl(CCR); + ccr = __raw_readl(CCR); /* * At this point we don't know whether the cache is enabled or not - a @@ -155,7 +155,7 @@ static void cache_init(void) for (addr = addrstart; addr < addrstart + waysize; addr += current_cpu_data.dcache.linesz) - ctrl_outl(0, addr); + __raw_writel(0, addr); addrstart += current_cpu_data.dcache.way_incr; } while (--ways); @@ -188,7 +188,7 @@ static void cache_init(void) l2_cache_init(); - ctrl_outl(flags, CCR); + __raw_writel(flags, CCR); back_to_cached(); } #else diff --git a/arch/sh/kernel/cpu/irq/intc-sh5.c b/arch/sh/kernel/cpu/irq/intc-sh5.c index 06e7e2959b54..96a239583948 100644 --- a/arch/sh/kernel/cpu/irq/intc-sh5.c +++ b/arch/sh/kernel/cpu/irq/intc-sh5.c @@ -123,7 +123,7 @@ static void enable_intc_irq(unsigned int irq) bitmask = 1 << (irq - 32); } - ctrl_outl(bitmask, reg); + __raw_writel(bitmask, reg); } static void disable_intc_irq(unsigned int irq) @@ -139,7 +139,7 @@ static void disable_intc_irq(unsigned int irq) bitmask = 1 << (irq - 32); } - ctrl_outl(bitmask, reg); + __raw_writel(bitmask, reg); } static void mask_and_ack_intc(unsigned int irq) @@ -170,11 +170,11 @@ void __init plat_irq_setup(void) /* Disable all interrupts and set all priorities to 0 to avoid trouble */ - ctrl_outl(-1, INTC_INTDSB_0); - ctrl_outl(-1, INTC_INTDSB_1); + __raw_writel(-1, INTC_INTDSB_0); + __raw_writel(-1, INTC_INTDSB_1); for (reg = INTC_INTPRI_0, i = 0; i < INTC_INTPRI_PREGS; i++, reg += 8) - ctrl_outl( NO_PRIORITY, reg); + __raw_writel( NO_PRIORITY, reg); #ifdef CONFIG_SH_CAYMAN @@ -199,7 +199,7 @@ void __init plat_irq_setup(void) reg = INTC_ICR_SET; i = IRQ_IRL0; } - ctrl_outl(INTC_ICR_IRLM, reg); + __raw_writel(INTC_ICR_IRLM, reg); /* Set interrupt priorities according to platform description */ for (data = 0, reg = INTC_INTPRI_0; i < NR_INTC_IRQS; i++) { @@ -207,7 +207,7 @@ void __init plat_irq_setup(void) ((i % INTC_INTPRI_PPREG) * 4); if ((i % INTC_INTPRI_PPREG) == (INTC_INTPRI_PPREG - 1)) { /* Upon the 7th, set Priority Register */ - ctrl_outl(data, reg); + __raw_writel(data, reg); data = 0; reg += 8; } diff --git a/arch/sh/kernel/cpu/sh2/clock-sh7619.c b/arch/sh/kernel/cpu/sh2/clock-sh7619.c index 4fe863170e31..0c9f24d7a02f 100644 --- a/arch/sh/kernel/cpu/sh2/clock-sh7619.c +++ b/arch/sh/kernel/cpu/sh2/clock-sh7619.c @@ -31,7 +31,7 @@ static const int pfc_divisors[] = {1,2,0,4}; static void master_clk_init(struct clk *clk) { - clk->rate *= PLL2 * pll1rate[(ctrl_inw(FREQCR) >> 8) & 7]; + clk->rate *= PLL2 * pll1rate[(__raw_readw(FREQCR) >> 8) & 7]; } static struct clk_ops sh7619_master_clk_ops = { @@ -40,7 +40,7 @@ static struct clk_ops sh7619_master_clk_ops = { static unsigned long module_clk_recalc(struct clk *clk) { - int idx = (ctrl_inw(FREQCR) & 0x0007); + int idx = (__raw_readw(FREQCR) & 0x0007); return clk->parent->rate / pfc_divisors[idx]; } @@ -50,7 +50,7 @@ static struct clk_ops sh7619_module_clk_ops = { static unsigned long bus_clk_recalc(struct clk *clk) { - return clk->parent->rate / pll1rate[(ctrl_inw(FREQCR) >> 8) & 7]; + return clk->parent->rate / pll1rate[(__raw_readw(FREQCR) >> 8) & 7]; } static struct clk_ops sh7619_bus_clk_ops = { diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7201.c b/arch/sh/kernel/cpu/sh2a/clock-sh7201.c index 7814c76159a7..b26264dc2aef 100644 --- a/arch/sh/kernel/cpu/sh2a/clock-sh7201.c +++ b/arch/sh/kernel/cpu/sh2a/clock-sh7201.c @@ -34,7 +34,7 @@ static const int pfc_divisors[]={1,2,3,4,6,8,12}; static void master_clk_init(struct clk *clk) { - return 10000000 * PLL2 * pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0007]; + return 10000000 * PLL2 * pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0007]; } static struct clk_ops sh7201_master_clk_ops = { @@ -43,7 +43,7 @@ static struct clk_ops sh7201_master_clk_ops = { static unsigned long module_clk_recalc(struct clk *clk) { - int idx = (ctrl_inw(FREQCR) & 0x0007); + int idx = (__raw_readw(FREQCR) & 0x0007); return clk->parent->rate / pfc_divisors[idx]; } @@ -53,7 +53,7 @@ static struct clk_ops sh7201_module_clk_ops = { static unsigned long bus_clk_recalc(struct clk *clk) { - int idx = (ctrl_inw(FREQCR) & 0x0007); + int idx = (__raw_readw(FREQCR) & 0x0007); return clk->parent->rate / pfc_divisors[idx]; } @@ -63,7 +63,7 @@ static struct clk_ops sh7201_bus_clk_ops = { static unsigned long cpu_clk_recalc(struct clk *clk) { - int idx = ((ctrl_inw(FREQCR) >> 4) & 0x0007); + int idx = ((__raw_readw(FREQCR) >> 4) & 0x0007); return clk->parent->rate / ifc_divisors[idx]; } diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7203.c b/arch/sh/kernel/cpu/sh2a/clock-sh7203.c index 940986965102..7e75d8f79502 100644 --- a/arch/sh/kernel/cpu/sh2a/clock-sh7203.c +++ b/arch/sh/kernel/cpu/sh2a/clock-sh7203.c @@ -39,7 +39,7 @@ static const int pfc_divisors[]={1,2,3,4,6,8,12}; static void master_clk_init(struct clk *clk) { - clk->rate *= pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0003] * PLL2 ; + clk->rate *= pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0003] * PLL2 ; } static struct clk_ops sh7203_master_clk_ops = { @@ -48,7 +48,7 @@ static struct clk_ops sh7203_master_clk_ops = { static unsigned long module_clk_recalc(struct clk *clk) { - int idx = (ctrl_inw(FREQCR) & 0x0007); + int idx = (__raw_readw(FREQCR) & 0x0007); return clk->parent->rate / pfc_divisors[idx]; } @@ -58,7 +58,7 @@ static struct clk_ops sh7203_module_clk_ops = { static unsigned long bus_clk_recalc(struct clk *clk) { - int idx = (ctrl_inw(FREQCR) & 0x0007); + int idx = (__raw_readw(FREQCR) & 0x0007); return clk->parent->rate / pfc_divisors[idx-2]; } diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7206.c b/arch/sh/kernel/cpu/sh2a/clock-sh7206.c index c2268bdeceeb..b27a5e2687ab 100644 --- a/arch/sh/kernel/cpu/sh2a/clock-sh7206.c +++ b/arch/sh/kernel/cpu/sh2a/clock-sh7206.c @@ -34,7 +34,7 @@ static const int pfc_divisors[]={1,2,3,4,6,8,12}; static void master_clk_init(struct clk *clk) { - clk->rate *= PLL2 * pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0007]; + clk->rate *= PLL2 * pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0007]; } static struct clk_ops sh7206_master_clk_ops = { @@ -43,7 +43,7 @@ static struct clk_ops sh7206_master_clk_ops = { static unsigned long module_clk_recalc(struct clk *clk) { - int idx = (ctrl_inw(FREQCR) & 0x0007); + int idx = (__raw_readw(FREQCR) & 0x0007); return clk->parent->rate / pfc_divisors[idx]; } @@ -53,7 +53,7 @@ static struct clk_ops sh7206_module_clk_ops = { static unsigned long bus_clk_recalc(struct clk *clk) { - return clk->parent->rate / pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0007]; + return clk->parent->rate / pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0007]; } static struct clk_ops sh7206_bus_clk_ops = { @@ -62,7 +62,7 @@ static struct clk_ops sh7206_bus_clk_ops = { static unsigned long cpu_clk_recalc(struct clk *clk) { - int idx = (ctrl_inw(FREQCR) & 0x0007); + int idx = (__raw_readw(FREQCR) & 0x0007); return clk->parent->rate / ifc_divisors[idx]; } diff --git a/arch/sh/kernel/cpu/sh3/clock-sh3.c b/arch/sh/kernel/cpu/sh3/clock-sh3.c index 27b8738f0b09..b78384afac09 100644 --- a/arch/sh/kernel/cpu/sh3/clock-sh3.c +++ b/arch/sh/kernel/cpu/sh3/clock-sh3.c @@ -28,7 +28,7 @@ static int pfc_divisors[] = { 1, 2, 3, 4, 6, 1, 1, 1 }; static void master_clk_init(struct clk *clk) { - int frqcr = ctrl_inw(FRQCR); + int frqcr = __raw_readw(FRQCR); int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003); clk->rate *= pfc_divisors[idx]; @@ -40,7 +40,7 @@ static struct clk_ops sh3_master_clk_ops = { static unsigned long module_clk_recalc(struct clk *clk) { - int frqcr = ctrl_inw(FRQCR); + int frqcr = __raw_readw(FRQCR); int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003); return clk->parent->rate / pfc_divisors[idx]; @@ -52,7 +52,7 @@ static struct clk_ops sh3_module_clk_ops = { static unsigned long bus_clk_recalc(struct clk *clk) { - int frqcr = ctrl_inw(FRQCR); + int frqcr = __raw_readw(FRQCR); int idx = ((frqcr & 0x8000) >> 13) | ((frqcr & 0x0030) >> 4); return clk->parent->rate / stc_multipliers[idx]; @@ -64,7 +64,7 @@ static struct clk_ops sh3_bus_clk_ops = { static unsigned long cpu_clk_recalc(struct clk *clk) { - int frqcr = ctrl_inw(FRQCR); + int frqcr = __raw_readw(FRQCR); int idx = ((frqcr & 0x4000) >> 12) | ((frqcr & 0x000c) >> 2); return clk->parent->rate / ifc_divisors[idx]; diff --git a/arch/sh/kernel/cpu/sh3/clock-sh7705.c b/arch/sh/kernel/cpu/sh3/clock-sh7705.c index 0ca8f2c3646c..0ecea1451c6f 100644 --- a/arch/sh/kernel/cpu/sh3/clock-sh7705.c +++ b/arch/sh/kernel/cpu/sh3/clock-sh7705.c @@ -32,7 +32,7 @@ static int pfc_divisors[] = { 1, 2, 3, 4, 6, 1, 1, 1 }; static void master_clk_init(struct clk *clk) { - clk->rate *= pfc_divisors[ctrl_inw(FRQCR) & 0x0003]; + clk->rate *= pfc_divisors[__raw_readw(FRQCR) & 0x0003]; } static struct clk_ops sh7705_master_clk_ops = { @@ -41,7 +41,7 @@ static struct clk_ops sh7705_master_clk_ops = { static unsigned long module_clk_recalc(struct clk *clk) { - int idx = ctrl_inw(FRQCR) & 0x0003; + int idx = __raw_readw(FRQCR) & 0x0003; return clk->parent->rate / pfc_divisors[idx]; } @@ -51,7 +51,7 @@ static struct clk_ops sh7705_module_clk_ops = { static unsigned long bus_clk_recalc(struct clk *clk) { - int idx = (ctrl_inw(FRQCR) & 0x0300) >> 8; + int idx = (__raw_readw(FRQCR) & 0x0300) >> 8; return clk->parent->rate / stc_multipliers[idx]; } @@ -61,7 +61,7 @@ static struct clk_ops sh7705_bus_clk_ops = { static unsigned long cpu_clk_recalc(struct clk *clk) { - int idx = (ctrl_inw(FRQCR) & 0x0030) >> 4; + int idx = (__raw_readw(FRQCR) & 0x0030) >> 4; return clk->parent->rate / ifc_divisors[idx]; } diff --git a/arch/sh/kernel/cpu/sh3/clock-sh7706.c b/arch/sh/kernel/cpu/sh3/clock-sh7706.c index 4bf7887d310a..6f9ff8b57dd6 100644 --- a/arch/sh/kernel/cpu/sh3/clock-sh7706.c +++ b/arch/sh/kernel/cpu/sh3/clock-sh7706.c @@ -24,7 +24,7 @@ static int pfc_divisors[] = { 1, 2, 4, 1, 3, 6, 1, 1 }; static void master_clk_init(struct clk *clk) { - int frqcr = ctrl_inw(FRQCR); + int frqcr = __raw_readw(FRQCR); int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003); clk->rate *= pfc_divisors[idx]; @@ -36,7 +36,7 @@ static struct clk_ops sh7706_master_clk_ops = { static unsigned long module_clk_recalc(struct clk *clk) { - int frqcr = ctrl_inw(FRQCR); + int frqcr = __raw_readw(FRQCR); int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003); return clk->parent->rate / pfc_divisors[idx]; @@ -48,7 +48,7 @@ static struct clk_ops sh7706_module_clk_ops = { static unsigned long bus_clk_recalc(struct clk *clk) { - int frqcr = ctrl_inw(FRQCR); + int frqcr = __raw_readw(FRQCR); int idx = ((frqcr & 0x8000) >> 13) | ((frqcr & 0x0030) >> 4); return clk->parent->rate / stc_multipliers[idx]; @@ -60,7 +60,7 @@ static struct clk_ops sh7706_bus_clk_ops = { static unsigned long cpu_clk_recalc(struct clk *clk) { - int frqcr = ctrl_inw(FRQCR); + int frqcr = __raw_readw(FRQCR); int idx = ((frqcr & 0x4000) >> 12) | ((frqcr & 0x000c) >> 2); return clk->parent->rate / ifc_divisors[idx]; diff --git a/arch/sh/kernel/cpu/sh3/clock-sh7709.c b/arch/sh/kernel/cpu/sh3/clock-sh7709.c index e8749505bd2a..f302ba09e681 100644 --- a/arch/sh/kernel/cpu/sh3/clock-sh7709.c +++ b/arch/sh/kernel/cpu/sh3/clock-sh7709.c @@ -24,7 +24,7 @@ static int pfc_divisors[] = { 1, 2, 4, 1, 3, 6, 1, 1 }; static void master_clk_init(struct clk *clk) { - int frqcr = ctrl_inw(FRQCR); + int frqcr = __raw_readw(FRQCR); int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003); clk->rate *= pfc_divisors[idx]; @@ -36,7 +36,7 @@ static struct clk_ops sh7709_master_clk_ops = { static unsigned long module_clk_recalc(struct clk *clk) { - int frqcr = ctrl_inw(FRQCR); + int frqcr = __raw_readw(FRQCR); int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003); return clk->parent->rate / pfc_divisors[idx]; @@ -48,7 +48,7 @@ static struct clk_ops sh7709_module_clk_ops = { static unsigned long bus_clk_recalc(struct clk *clk) { - int frqcr = ctrl_inw(FRQCR); + int frqcr = __raw_readw(FRQCR); int idx = (frqcr & 0x0080) ? ((frqcr & 0x8000) >> 13) | ((frqcr & 0x0030) >> 4) : 1; @@ -61,7 +61,7 @@ static struct clk_ops sh7709_bus_clk_ops = { static unsigned long cpu_clk_recalc(struct clk *clk) { - int frqcr = ctrl_inw(FRQCR); + int frqcr = __raw_readw(FRQCR); int idx = ((frqcr & 0x4000) >> 12) | ((frqcr & 0x000c) >> 2); return clk->parent->rate / ifc_divisors[idx]; diff --git a/arch/sh/kernel/cpu/sh3/clock-sh7710.c b/arch/sh/kernel/cpu/sh3/clock-sh7710.c index 030a58ba18a5..29a87d8946a4 100644 --- a/arch/sh/kernel/cpu/sh3/clock-sh7710.c +++ b/arch/sh/kernel/cpu/sh3/clock-sh7710.c @@ -26,7 +26,7 @@ static int md_table[] = { 1, 2, 3, 4, 6, 8, 12 }; static void master_clk_init(struct clk *clk) { - clk->rate *= md_table[ctrl_inw(FRQCR) & 0x0007]; + clk->rate *= md_table[__raw_readw(FRQCR) & 0x0007]; } static struct clk_ops sh7710_master_clk_ops = { @@ -35,7 +35,7 @@ static struct clk_ops sh7710_master_clk_ops = { static unsigned long module_clk_recalc(struct clk *clk) { - int idx = (ctrl_inw(FRQCR) & 0x0007); + int idx = (__raw_readw(FRQCR) & 0x0007); return clk->parent->rate / md_table[idx]; } @@ -45,7 +45,7 @@ static struct clk_ops sh7710_module_clk_ops = { static unsigned long bus_clk_recalc(struct clk *clk) { - int idx = (ctrl_inw(FRQCR) & 0x0700) >> 8; + int idx = (__raw_readw(FRQCR) & 0x0700) >> 8; return clk->parent->rate / md_table[idx]; } @@ -55,7 +55,7 @@ static struct clk_ops sh7710_bus_clk_ops = { static unsigned long cpu_clk_recalc(struct clk *clk) { - int idx = (ctrl_inw(FRQCR) & 0x0070) >> 4; + int idx = (__raw_readw(FRQCR) & 0x0070) >> 4; return clk->parent->rate / md_table[idx]; } diff --git a/arch/sh/kernel/cpu/sh3/clock-sh7712.c b/arch/sh/kernel/cpu/sh3/clock-sh7712.c index 6428ee6c77ed..b0d0c5203996 100644 --- a/arch/sh/kernel/cpu/sh3/clock-sh7712.c +++ b/arch/sh/kernel/cpu/sh3/clock-sh7712.c @@ -23,7 +23,7 @@ static int divisors[] = { 1, 2, 3, 4, 6 }; static void master_clk_init(struct clk *clk) { - int frqcr = ctrl_inw(FRQCR); + int frqcr = __raw_readw(FRQCR); int idx = (frqcr & 0x0300) >> 8; clk->rate *= multipliers[idx]; @@ -35,7 +35,7 @@ static struct clk_ops sh7712_master_clk_ops = { static unsigned long module_clk_recalc(struct clk *clk) { - int frqcr = ctrl_inw(FRQCR); + int frqcr = __raw_readw(FRQCR); int idx = frqcr & 0x0007; return clk->parent->rate / divisors[idx]; @@ -47,7 +47,7 @@ static struct clk_ops sh7712_module_clk_ops = { static unsigned long cpu_clk_recalc(struct clk *clk) { - int frqcr = ctrl_inw(FRQCR); + int frqcr = __raw_readw(FRQCR); int idx = (frqcr & 0x0030) >> 4; return clk->parent->rate / divisors[idx]; diff --git a/arch/sh/kernel/cpu/sh3/probe.c b/arch/sh/kernel/cpu/sh3/probe.c index c2db65719f4d..295ec4c99e98 100644 --- a/arch/sh/kernel/cpu/sh3/probe.c +++ b/arch/sh/kernel/cpu/sh3/probe.c @@ -30,23 +30,23 @@ int detect_cpu_and_cache_system(void) addr1 = CACHE_OC_ADDRESS_ARRAY + (1 << 12); /* First, write back & invalidate */ - data0 = ctrl_inl(addr0); - ctrl_outl(data0&~(SH_CACHE_VALID|SH_CACHE_UPDATED), addr0); - data1 = ctrl_inl(addr1); - ctrl_outl(data1&~(SH_CACHE_VALID|SH_CACHE_UPDATED), addr1); + data0 = __raw_readl(addr0); + __raw_writel(data0&~(SH_CACHE_VALID|SH_CACHE_UPDATED), addr0); + data1 = __raw_readl(addr1); + __raw_writel(data1&~(SH_CACHE_VALID|SH_CACHE_UPDATED), addr1); /* Next, check if there's shadow or not */ - data0 = ctrl_inl(addr0); + data0 = __raw_readl(addr0); data0 ^= SH_CACHE_VALID; - ctrl_outl(data0, addr0); - data1 = ctrl_inl(addr1); + __raw_writel(data0, addr0); + data1 = __raw_readl(addr1); data2 = data1 ^ SH_CACHE_VALID; - ctrl_outl(data2, addr1); - data3 = ctrl_inl(addr0); + __raw_writel(data2, addr1); + data3 = __raw_readl(addr0); /* Lastly, invaliate them. */ - ctrl_outl(data0&~SH_CACHE_VALID, addr0); - ctrl_outl(data2&~SH_CACHE_VALID, addr1); + __raw_writel(data0&~SH_CACHE_VALID, addr0); + __raw_writel(data2&~SH_CACHE_VALID, addr1); back_to_cached(); @@ -94,9 +94,9 @@ int detect_cpu_and_cache_system(void) boot_cpu_data.dcache.way_incr = (1 << 13); boot_cpu_data.dcache.entry_mask = 0x1ff0; boot_cpu_data.dcache.sets = 512; - ctrl_outl(CCR_CACHE_32KB, CCR3_REG); + __raw_writel(CCR_CACHE_32KB, CCR3_REG); #else - ctrl_outl(CCR_CACHE_16KB, CCR3_REG); + __raw_writel(CCR_CACHE_16KB, CCR3_REG); #endif #endif } diff --git a/arch/sh/kernel/cpu/sh3/setup-sh3.c b/arch/sh/kernel/cpu/sh3/setup-sh3.c index c98846857855..53be70b98116 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh3.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh3.c @@ -58,7 +58,7 @@ static DECLARE_INTC_DESC_ACK(intc_desc_irq45, "sh3-irq45", void __init plat_irq_setup_pins(int mode) { if (mode == IRQ_MODE_IRQ) { - ctrl_outw(ctrl_inw(INTC_ICR1) & ~INTC_ICR1_IRQLVL, INTC_ICR1); + __raw_writew(__raw_readw(INTC_ICR1) & ~INTC_ICR1_IRQLVL, INTC_ICR1); register_intc_controller(&intc_desc_irq0123); return; } diff --git a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c index 21421e34e7d5..6b80850294da 100644 --- a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c +++ b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c @@ -23,7 +23,7 @@ static int frqcr3_values[] = { 0, 1, 2, 3, 4, 5, 6 }; static unsigned long emi_clk_recalc(struct clk *clk) { - int idx = ctrl_inl(CPG2_FRQCR3) & 0x0007; + int idx = __raw_readl(CPG2_FRQCR3) & 0x0007; return clk->parent->rate / frqcr3_divisors[idx]; } @@ -52,7 +52,7 @@ static struct clk sh4202_emi_clk = { static unsigned long femi_clk_recalc(struct clk *clk) { - int idx = (ctrl_inl(CPG2_FRQCR3) >> 3) & 0x0007; + int idx = (__raw_readl(CPG2_FRQCR3) >> 3) & 0x0007; return clk->parent->rate / frqcr3_divisors[idx]; } @@ -92,7 +92,7 @@ static void shoc_clk_init(struct clk *clk) static unsigned long shoc_clk_recalc(struct clk *clk) { - int idx = (ctrl_inl(CPG2_FRQCR3) >> 6) & 0x0007; + int idx = (__raw_readl(CPG2_FRQCR3) >> 6) & 0x0007; return clk->parent->rate / frqcr3_divisors[idx]; } @@ -122,10 +122,10 @@ static int shoc_clk_set_rate(struct clk *clk, unsigned long rate, int algo_id) tmp = frqcr3_lookup(clk, rate); - frqcr3 = ctrl_inl(CPG2_FRQCR3); + frqcr3 = __raw_readl(CPG2_FRQCR3); frqcr3 &= ~(0x0007 << 6); frqcr3 |= tmp << 6; - ctrl_outl(frqcr3, CPG2_FRQCR3); + __raw_writel(frqcr3, CPG2_FRQCR3); clk->rate = clk->parent->rate / frqcr3_divisors[tmp]; diff --git a/arch/sh/kernel/cpu/sh4/clock-sh4.c b/arch/sh/kernel/cpu/sh4/clock-sh4.c index 73294d9cd049..5add75c1f539 100644 --- a/arch/sh/kernel/cpu/sh4/clock-sh4.c +++ b/arch/sh/kernel/cpu/sh4/clock-sh4.c @@ -28,7 +28,7 @@ static int pfc_divisors[] = { 2, 3, 4, 6, 8, 2, 2, 2 }; static void master_clk_init(struct clk *clk) { - clk->rate *= pfc_divisors[ctrl_inw(FRQCR) & 0x0007]; + clk->rate *= pfc_divisors[__raw_readw(FRQCR) & 0x0007]; } static struct clk_ops sh4_master_clk_ops = { @@ -37,7 +37,7 @@ static struct clk_ops sh4_master_clk_ops = { static unsigned long module_clk_recalc(struct clk *clk) { - int idx = (ctrl_inw(FRQCR) & 0x0007); + int idx = (__raw_readw(FRQCR) & 0x0007); return clk->parent->rate / pfc_divisors[idx]; } @@ -47,7 +47,7 @@ static struct clk_ops sh4_module_clk_ops = { static unsigned long bus_clk_recalc(struct clk *clk) { - int idx = (ctrl_inw(FRQCR) >> 3) & 0x0007; + int idx = (__raw_readw(FRQCR) >> 3) & 0x0007; return clk->parent->rate / bfc_divisors[idx]; } @@ -57,7 +57,7 @@ static struct clk_ops sh4_bus_clk_ops = { static unsigned long cpu_clk_recalc(struct clk *clk) { - int idx = (ctrl_inw(FRQCR) >> 6) & 0x0007; + int idx = (__raw_readw(FRQCR) >> 6) & 0x0007; return clk->parent->rate / ifc_divisors[idx]; } diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c index cc02b3145cca..822977a06d84 100644 --- a/arch/sh/kernel/cpu/sh4/probe.c +++ b/arch/sh/kernel/cpu/sh4/probe.c @@ -28,9 +28,9 @@ int __init detect_cpu_and_cache_system(void) [9] = (1 << 16) }; - pvr = (ctrl_inl(CCN_PVR) >> 8) & 0xffffff; - prr = (ctrl_inl(CCN_PRR) >> 4) & 0xff; - cvr = (ctrl_inl(CCN_CVR)); + pvr = (__raw_readl(CCN_PVR) >> 8) & 0xffffff; + prr = (__raw_readl(CCN_PRR) >> 4) & 0xff; + cvr = (__raw_readl(CCN_CVR)); /* * Setup some sane SH-4 defaults for the icache diff --git a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c index 4b733715cdb5..b9b7e10ad68f 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c @@ -198,7 +198,7 @@ void __init plat_irq_setup_pins(int mode) { switch (mode) { case IRQ_MODE_IRQ: /* individual interrupt mode for IRL3-0 */ - ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); + __raw_writew(__raw_readw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); register_intc_controller(&intc_desc_irlm); break; default: diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c index b2a9df1af64c..ffd79e57254f 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c @@ -442,7 +442,7 @@ void __init plat_irq_setup_pins(int mode) switch (mode) { case IRQ_MODE_IRQ: /* individual interrupt mode for IRL3-0 */ - ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); + __raw_writew(__raw_readw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); register_intc_controller(&intc_desc_irlm); break; default: diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c index 5b74cc0b43da..a16eb3656f4b 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c @@ -319,7 +319,7 @@ void __init plat_irq_setup_pins(int mode) { switch (mode) { case IRQ_MODE_IRQ: - ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); + __raw_writew(__raw_readw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); register_intc_controller(&intc_desc_irq); break; default: diff --git a/arch/sh/kernel/cpu/sh4/sq.c b/arch/sh/kernel/cpu/sh4/sq.c index 8a8a993f55ea..97aea9d69b00 100644 --- a/arch/sh/kernel/cpu/sh4/sq.c +++ b/arch/sh/kernel/cpu/sh4/sq.c @@ -43,9 +43,9 @@ static unsigned long *sq_bitmap; #define store_queue_barrier() \ do { \ - (void)ctrl_inl(P4SEG_STORE_QUE); \ - ctrl_outl(0, P4SEG_STORE_QUE + 0); \ - ctrl_outl(0, P4SEG_STORE_QUE + 8); \ + (void)__raw_readl(P4SEG_STORE_QUE); \ + __raw_writel(0, P4SEG_STORE_QUE + 0); \ + __raw_writel(0, P4SEG_STORE_QUE + 8); \ } while (0); /** @@ -123,8 +123,8 @@ static int __sq_remap(struct sq_mapping *map, unsigned long flags) * straightforward, as we can just load up each queue's QACR with * the physical address appropriately masked. */ - ctrl_outl(((map->addr >> 26) << 2) & 0x1c, SQ_QACR0); - ctrl_outl(((map->addr >> 26) << 2) & 0x1c, SQ_QACR1); + __raw_writel(((map->addr >> 26) << 2) & 0x1c, SQ_QACR0); + __raw_writel(((map->addr >> 26) << 2) & 0x1c, SQ_QACR1); #endif return 0; diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c index ddc235ca9664..86aae60677dc 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c @@ -35,7 +35,7 @@ static struct clk_ops sh7757_master_clk_ops = { static void module_clk_recalc(struct clk *clk) { - int idx = ctrl_inl(FRQCR) & 0x0000000f; + int idx = __raw_readl(FRQCR) & 0x0000000f; clk->rate = clk->parent->rate / p1fc_divisors[idx]; } @@ -45,7 +45,7 @@ static struct clk_ops sh7757_module_clk_ops = { static void bus_clk_recalc(struct clk *clk) { - int idx = (ctrl_inl(FRQCR) >> 8) & 0x0000000f; + int idx = (__raw_readl(FRQCR) >> 8) & 0x0000000f; clk->rate = clk->parent->rate / bfc_divisors[idx]; } @@ -55,7 +55,7 @@ static struct clk_ops sh7757_bus_clk_ops = { static void cpu_clk_recalc(struct clk *clk) { - int idx = (ctrl_inl(FRQCR) >> 20) & 0x0000000f; + int idx = (__raw_readl(FRQCR) >> 20) & 0x0000000f; clk->rate = clk->parent->rate / ifc_divisors[idx]; } @@ -78,7 +78,7 @@ void __init arch_init_clk_ops(struct clk_ops **ops, int idx) static void shyway_clk_recalc(struct clk *clk) { - int idx = (ctrl_inl(FRQCR) >> 12) & 0x0000000f; + int idx = (__raw_readl(FRQCR) >> 12) & 0x0000000f; clk->rate = clk->parent->rate / sfc_divisors[idx]; } diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7763.c b/arch/sh/kernel/cpu/sh4a/clock-sh7763.c index 370cd47642ef..9f401163e71e 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7763.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7763.c @@ -22,7 +22,7 @@ static int cfc_divisors[] = { 1, 1, 4, 1, 1, 1, 1, 1 }; static void master_clk_init(struct clk *clk) { - clk->rate *= p0fc_divisors[(ctrl_inl(FRQCR) >> 4) & 0x07]; + clk->rate *= p0fc_divisors[(__raw_readl(FRQCR) >> 4) & 0x07]; } static struct clk_ops sh7763_master_clk_ops = { @@ -31,7 +31,7 @@ static struct clk_ops sh7763_master_clk_ops = { static unsigned long module_clk_recalc(struct clk *clk) { - int idx = ((ctrl_inl(FRQCR) >> 4) & 0x07); + int idx = ((__raw_readl(FRQCR) >> 4) & 0x07); return clk->parent->rate / p0fc_divisors[idx]; } @@ -41,7 +41,7 @@ static struct clk_ops sh7763_module_clk_ops = { static unsigned long bus_clk_recalc(struct clk *clk) { - int idx = ((ctrl_inl(FRQCR) >> 16) & 0x07); + int idx = ((__raw_readl(FRQCR) >> 16) & 0x07); return clk->parent->rate / bfc_divisors[idx]; } @@ -68,7 +68,7 @@ void __init arch_init_clk_ops(struct clk_ops **ops, int idx) static unsigned long shyway_clk_recalc(struct clk *clk) { - int idx = ((ctrl_inl(FRQCR) >> 20) & 0x07); + int idx = ((__raw_readl(FRQCR) >> 20) & 0x07); return clk->parent->rate / cfc_divisors[idx]; } diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7770.c b/arch/sh/kernel/cpu/sh4a/clock-sh7770.c index e0b896769205..9e3354365d40 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7770.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7770.c @@ -21,7 +21,7 @@ static int pfc_divisors[] = { 1, 8, 1,10,12,16, 1, 1 }; static void master_clk_init(struct clk *clk) { - clk->rate *= pfc_divisors[(ctrl_inl(FRQCR) >> 28) & 0x000f]; + clk->rate *= pfc_divisors[(__raw_readl(FRQCR) >> 28) & 0x000f]; } static struct clk_ops sh7770_master_clk_ops = { @@ -30,7 +30,7 @@ static struct clk_ops sh7770_master_clk_ops = { static unsigned long module_clk_recalc(struct clk *clk) { - int idx = ((ctrl_inl(FRQCR) >> 28) & 0x000f); + int idx = ((__raw_readl(FRQCR) >> 28) & 0x000f); return clk->parent->rate / pfc_divisors[idx]; } @@ -40,7 +40,7 @@ static struct clk_ops sh7770_module_clk_ops = { static unsigned long bus_clk_recalc(struct clk *clk) { - int idx = (ctrl_inl(FRQCR) & 0x000f); + int idx = (__raw_readl(FRQCR) & 0x000f); return clk->parent->rate / bfc_divisors[idx]; } @@ -50,7 +50,7 @@ static struct clk_ops sh7770_bus_clk_ops = { static unsigned long cpu_clk_recalc(struct clk *clk) { - int idx = ((ctrl_inl(FRQCR) >> 24) & 0x000f); + int idx = ((__raw_readl(FRQCR) >> 24) & 0x000f); return clk->parent->rate / ifc_divisors[idx]; } diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7780.c b/arch/sh/kernel/cpu/sh4a/clock-sh7780.c index a249d823578e..150963a6001e 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7780.c @@ -22,7 +22,7 @@ static int cfc_divisors[] = { 1, 1, 4, 1, 6, 1, 1, 1 }; static void master_clk_init(struct clk *clk) { - clk->rate *= pfc_divisors[ctrl_inl(FRQCR) & 0x0003]; + clk->rate *= pfc_divisors[__raw_readl(FRQCR) & 0x0003]; } static struct clk_ops sh7780_master_clk_ops = { @@ -31,7 +31,7 @@ static struct clk_ops sh7780_master_clk_ops = { static unsigned long module_clk_recalc(struct clk *clk) { - int idx = (ctrl_inl(FRQCR) & 0x0003); + int idx = (__raw_readl(FRQCR) & 0x0003); return clk->parent->rate / pfc_divisors[idx]; } @@ -41,7 +41,7 @@ static struct clk_ops sh7780_module_clk_ops = { static unsigned long bus_clk_recalc(struct clk *clk) { - int idx = ((ctrl_inl(FRQCR) >> 16) & 0x0007); + int idx = ((__raw_readl(FRQCR) >> 16) & 0x0007); return clk->parent->rate / bfc_divisors[idx]; } @@ -51,7 +51,7 @@ static struct clk_ops sh7780_bus_clk_ops = { static unsigned long cpu_clk_recalc(struct clk *clk) { - int idx = ((ctrl_inl(FRQCR) >> 24) & 0x0001); + int idx = ((__raw_readl(FRQCR) >> 24) & 0x0001); return clk->parent->rate / ifc_divisors[idx]; } @@ -74,7 +74,7 @@ void __init arch_init_clk_ops(struct clk_ops **ops, int idx) static unsigned long shyway_clk_recalc(struct clk *clk) { - int idx = ((ctrl_inl(FRQCR) >> 20) & 0x0007); + int idx = ((__raw_readl(FRQCR) >> 20) & 0x0007); return clk->parent->rate / cfc_divisors[idx]; } diff --git a/arch/sh/kernel/cpu/sh4a/clock-shx3.c b/arch/sh/kernel/cpu/sh4a/clock-shx3.c index 23c27d32d982..e75c57bdfa5e 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-shx3.c +++ b/arch/sh/kernel/cpu/sh4a/clock-shx3.c @@ -33,7 +33,7 @@ static int cfc_divisors[] = { 1, 1, 4, 6 }; static void master_clk_init(struct clk *clk) { - clk->rate *= pfc_divisors[(ctrl_inl(FRQCR) >> PFC_POS) & PFC_MSK]; + clk->rate *= pfc_divisors[(__raw_readl(FRQCR) >> PFC_POS) & PFC_MSK]; } static struct clk_ops shx3_master_clk_ops = { @@ -42,7 +42,7 @@ static struct clk_ops shx3_master_clk_ops = { static unsigned long module_clk_recalc(struct clk *clk) { - int idx = ((ctrl_inl(FRQCR) >> PFC_POS) & PFC_MSK); + int idx = ((__raw_readl(FRQCR) >> PFC_POS) & PFC_MSK); return clk->parent->rate / pfc_divisors[idx]; } @@ -52,7 +52,7 @@ static struct clk_ops shx3_module_clk_ops = { static unsigned long bus_clk_recalc(struct clk *clk) { - int idx = ((ctrl_inl(FRQCR) >> BFC_POS) & BFC_MSK); + int idx = ((__raw_readl(FRQCR) >> BFC_POS) & BFC_MSK); return clk->parent->rate / bfc_divisors[idx]; } @@ -62,7 +62,7 @@ static struct clk_ops shx3_bus_clk_ops = { static unsigned long cpu_clk_recalc(struct clk *clk) { - int idx = ((ctrl_inl(FRQCR) >> IFC_POS) & IFC_MSK); + int idx = ((__raw_readl(FRQCR) >> IFC_POS) & IFC_MSK); return clk->parent->rate / ifc_divisors[idx]; } @@ -85,7 +85,7 @@ void __init arch_init_clk_ops(struct clk_ops **ops, int idx) static unsigned long shyway_clk_recalc(struct clk *clk) { - int idx = ((ctrl_inl(FRQCR) >> CFC_POS) & CFC_MSK); + int idx = ((__raw_readl(FRQCR) >> CFC_POS) & CFC_MSK); return clk->parent->rate / cfc_divisors[idx]; } diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c index 9d426258aa00..9e8620e3ad3e 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c @@ -596,7 +596,7 @@ void __init plat_early_device_setup(void) void l2_cache_init(void) { /* Enable L2 cache */ - ctrl_outl(L2_CACHE_ENABLE, RAMCR); + __raw_writel(L2_CACHE_ENABLE, RAMCR); } enum { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c index 578e9f80271f..aa0f6e9bb89e 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c @@ -718,7 +718,7 @@ void __init plat_early_device_setup(void) void l2_cache_init(void) { /* Enable L2 cache */ - ctrl_outl(L2_CACHE_ENABLE, RAMCR); + __raw_writel(L2_CACHE_ENABLE, RAMCR); } enum { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c index 37e32efbbaa7..e75edf58796a 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c @@ -487,17 +487,17 @@ static DECLARE_INTC_DESC(intc_desc_irl4567, "sh7757-irl4567", vectors_irl4567, void __init plat_irq_setup(void) { /* disable IRQ3-0 + IRQ7-4 */ - ctrl_outl(0xff000000, INTC_INTMSK0); + __raw_writel(0xff000000, INTC_INTMSK0); /* disable IRL3-0 + IRL7-4 */ - ctrl_outl(0xc0000000, INTC_INTMSK1); - ctrl_outl(0xfffefffe, INTC_INTMSK2); + __raw_writel(0xc0000000, INTC_INTMSK1); + __raw_writel(0xfffefffe, INTC_INTMSK2); /* select IRL mode for IRL3-0 + IRL7-4 */ - ctrl_outl(ctrl_inl(INTC_ICR0) & ~0x00c00000, INTC_ICR0); + __raw_writel(__raw_readl(INTC_ICR0) & ~0x00c00000, INTC_ICR0); /* disable holding function, ie enable "SH-4 Mode" */ - ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00200000, INTC_ICR0); + __raw_writel(__raw_readl(INTC_ICR0) | 0x00200000, INTC_ICR0); register_intc_controller(&intc_desc); } @@ -507,32 +507,32 @@ void __init plat_irq_setup_pins(int mode) switch (mode) { case IRQ_MODE_IRQ7654: /* select IRQ mode for IRL7-4 */ - ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00400000, INTC_ICR0); + __raw_writel(__raw_readl(INTC_ICR0) | 0x00400000, INTC_ICR0); register_intc_controller(&intc_desc_irq4567); break; case IRQ_MODE_IRQ3210: /* select IRQ mode for IRL3-0 */ - ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00800000, INTC_ICR0); + __raw_writel(__raw_readl(INTC_ICR0) | 0x00800000, INTC_ICR0); register_intc_controller(&intc_desc_irq0123); break; case IRQ_MODE_IRL7654: /* enable IRL7-4 but don't provide any masking */ - ctrl_outl(0x40000000, INTC_INTMSKCLR1); - ctrl_outl(0x0000fffe, INTC_INTMSKCLR2); + __raw_writel(0x40000000, INTC_INTMSKCLR1); + __raw_writel(0x0000fffe, INTC_INTMSKCLR2); break; case IRQ_MODE_IRL3210: /* enable IRL0-3 but don't provide any masking */ - ctrl_outl(0x80000000, INTC_INTMSKCLR1); - ctrl_outl(0xfffe0000, INTC_INTMSKCLR2); + __raw_writel(0x80000000, INTC_INTMSKCLR1); + __raw_writel(0xfffe0000, INTC_INTMSKCLR2); break; case IRQ_MODE_IRL7654_MASK: /* enable IRL7-4 and mask using cpu intc controller */ - ctrl_outl(0x40000000, INTC_INTMSKCLR1); + __raw_writel(0x40000000, INTC_INTMSKCLR1); register_intc_controller(&intc_desc_irl4567); break; case IRQ_MODE_IRL3210_MASK: /* enable IRL0-3 and mask using cpu intc controller */ - ctrl_outl(0x80000000, INTC_INTMSKCLR1); + __raw_writel(0x80000000, INTC_INTMSKCLR1); register_intc_controller(&intc_desc_irl0123); break; default: diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c index 6aba26fec416..7f6b0a5f7f82 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c @@ -538,11 +538,11 @@ static DECLARE_INTC_DESC(intc_irl3210_desc, "sh7763-irl3210", irl_vectors, void __init plat_irq_setup(void) { /* disable IRQ7-0 */ - ctrl_outl(0xff000000, INTC_INTMSK0); + __raw_writel(0xff000000, INTC_INTMSK0); /* disable IRL3-0 + IRL7-4 */ - ctrl_outl(0xc0000000, INTC_INTMSK1); - ctrl_outl(0xfffefffe, INTC_INTMSK2); + __raw_writel(0xc0000000, INTC_INTMSK1); + __raw_writel(0xfffefffe, INTC_INTMSK2); register_intc_controller(&intc_desc); } @@ -552,27 +552,27 @@ void __init plat_irq_setup_pins(int mode) switch (mode) { case IRQ_MODE_IRQ: /* select IRQ mode for IRL3-0 + IRL7-4 */ - ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00c00000, INTC_ICR0); + __raw_writel(__raw_readl(INTC_ICR0) | 0x00c00000, INTC_ICR0); register_intc_controller(&intc_irq_desc); break; case IRQ_MODE_IRL7654: /* enable IRL7-4 but don't provide any masking */ - ctrl_outl(0x40000000, INTC_INTMSKCLR1); - ctrl_outl(0x0000fffe, INTC_INTMSKCLR2); + __raw_writel(0x40000000, INTC_INTMSKCLR1); + __raw_writel(0x0000fffe, INTC_INTMSKCLR2); break; case IRQ_MODE_IRL3210: /* enable IRL0-3 but don't provide any masking */ - ctrl_outl(0x80000000, INTC_INTMSKCLR1); - ctrl_outl(0xfffe0000, INTC_INTMSKCLR2); + __raw_writel(0x80000000, INTC_INTMSKCLR1); + __raw_writel(0xfffe0000, INTC_INTMSKCLR2); break; case IRQ_MODE_IRL7654_MASK: /* enable IRL7-4 and mask using cpu intc controller */ - ctrl_outl(0x40000000, INTC_INTMSKCLR1); + __raw_writel(0x40000000, INTC_INTMSKCLR1); register_intc_controller(&intc_irl7654_desc); break; case IRQ_MODE_IRL3210_MASK: /* enable IRL0-3 and mask using cpu intc controller */ - ctrl_outl(0x80000000, INTC_INTMSKCLR1); + __raw_writel(0x80000000, INTC_INTMSKCLR1); register_intc_controller(&intc_irl3210_desc); break; default: diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c index c1643bc9590d..86d681ecf90e 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c @@ -694,17 +694,17 @@ static DECLARE_INTC_DESC(intc_irl3210_desc, "sh7780-irl3210", irl_vectors, void __init plat_irq_setup(void) { /* disable IRQ7-0 */ - ctrl_outl(0xff000000, INTC_INTMSK0); + __raw_writel(0xff000000, INTC_INTMSK0); /* disable IRL3-0 + IRL7-4 */ - ctrl_outl(0xc0000000, INTC_INTMSK1); - ctrl_outl(0xfffefffe, INTC_INTMSK2); + __raw_writel(0xc0000000, INTC_INTMSK1); + __raw_writel(0xfffefffe, INTC_INTMSK2); /* select IRL mode for IRL3-0 + IRL7-4 */ - ctrl_outl(ctrl_inl(INTC_ICR0) & ~0x00c00000, INTC_ICR0); + __raw_writel(__raw_readl(INTC_ICR0) & ~0x00c00000, INTC_ICR0); /* disable holding function, ie enable "SH-4 Mode" */ - ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00200000, INTC_ICR0); + __raw_writel(__raw_readl(INTC_ICR0) | 0x00200000, INTC_ICR0); register_intc_controller(&intc_desc); } @@ -714,27 +714,27 @@ void __init plat_irq_setup_pins(int mode) switch (mode) { case IRQ_MODE_IRQ: /* select IRQ mode for IRL3-0 + IRL7-4 */ - ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00c00000, INTC_ICR0); + __raw_writel(__raw_readl(INTC_ICR0) | 0x00c00000, INTC_ICR0); register_intc_controller(&intc_irq_desc); break; case IRQ_MODE_IRL7654: /* enable IRL7-4 but don't provide any masking */ - ctrl_outl(0x40000000, INTC_INTMSKCLR1); - ctrl_outl(0x0000fffe, INTC_INTMSKCLR2); + __raw_writel(0x40000000, INTC_INTMSKCLR1); + __raw_writel(0x0000fffe, INTC_INTMSKCLR2); break; case IRQ_MODE_IRL3210: /* enable IRL0-3 but don't provide any masking */ - ctrl_outl(0x80000000, INTC_INTMSKCLR1); - ctrl_outl(0xfffe0000, INTC_INTMSKCLR2); + __raw_writel(0x80000000, INTC_INTMSKCLR1); + __raw_writel(0xfffe0000, INTC_INTMSKCLR2); break; case IRQ_MODE_IRL7654_MASK: /* enable IRL7-4 and mask using cpu intc controller */ - ctrl_outl(0x40000000, INTC_INTMSKCLR1); + __raw_writel(0x40000000, INTC_INTMSKCLR1); register_intc_controller(&intc_irl7654_desc); break; case IRQ_MODE_IRL3210_MASK: /* enable IRL0-3 and mask using cpu intc controller */ - ctrl_outl(0x80000000, INTC_INTMSKCLR1); + __raw_writel(0x80000000, INTC_INTMSKCLR1); register_intc_controller(&intc_irl3210_desc); break; default: diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c index c310558490d5..f8f21618d785 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c @@ -461,17 +461,17 @@ static DECLARE_INTC_DESC(intc_irl3210_desc, "sh7780-irl3210", irl_vectors, void __init plat_irq_setup(void) { /* disable IRQ7-0 */ - ctrl_outl(0xff000000, INTC_INTMSK0); + __raw_writel(0xff000000, INTC_INTMSK0); /* disable IRL3-0 + IRL7-4 */ - ctrl_outl(0xc0000000, INTC_INTMSK1); - ctrl_outl(0xfffefffe, INTC_INTMSK2); + __raw_writel(0xc0000000, INTC_INTMSK1); + __raw_writel(0xfffefffe, INTC_INTMSK2); /* select IRL mode for IRL3-0 + IRL7-4 */ - ctrl_outl(ctrl_inl(INTC_ICR0) & ~0x00c00000, INTC_ICR0); + __raw_writel(__raw_readl(INTC_ICR0) & ~0x00c00000, INTC_ICR0); /* disable holding function, ie enable "SH-4 Mode" */ - ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00200000, INTC_ICR0); + __raw_writel(__raw_readl(INTC_ICR0) | 0x00200000, INTC_ICR0); register_intc_controller(&intc_desc); } @@ -481,27 +481,27 @@ void __init plat_irq_setup_pins(int mode) switch (mode) { case IRQ_MODE_IRQ: /* select IRQ mode for IRL3-0 + IRL7-4 */ - ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00c00000, INTC_ICR0); + __raw_writel(__raw_readl(INTC_ICR0) | 0x00c00000, INTC_ICR0); register_intc_controller(&intc_irq_desc); break; case IRQ_MODE_IRL7654: /* enable IRL7-4 but don't provide any masking */ - ctrl_outl(0x40000000, INTC_INTMSKCLR1); - ctrl_outl(0x0000fffe, INTC_INTMSKCLR2); + __raw_writel(0x40000000, INTC_INTMSKCLR1); + __raw_writel(0x0000fffe, INTC_INTMSKCLR2); break; case IRQ_MODE_IRL3210: /* enable IRL0-3 but don't provide any masking */ - ctrl_outl(0x80000000, INTC_INTMSKCLR1); - ctrl_outl(0xfffe0000, INTC_INTMSKCLR2); + __raw_writel(0x80000000, INTC_INTMSKCLR1); + __raw_writel(0xfffe0000, INTC_INTMSKCLR2); break; case IRQ_MODE_IRL7654_MASK: /* enable IRL7-4 and mask using cpu intc controller */ - ctrl_outl(0x40000000, INTC_INTMSKCLR1); + __raw_writel(0x40000000, INTC_INTMSKCLR1); register_intc_controller(&intc_irl7654_desc); break; case IRQ_MODE_IRL3210_MASK: /* enable IRL0-3 and mask using cpu intc controller */ - ctrl_outl(0x80000000, INTC_INTMSKCLR1); + __raw_writel(0x80000000, INTC_INTMSKCLR1); register_intc_controller(&intc_irl3210_desc); break; default: diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c index f685b9b21999..23448d8c6711 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c @@ -541,17 +541,17 @@ static DECLARE_INTC_DESC(intc_desc_irl4567, "sh7785-irl4567", vectors_irl4567, void __init plat_irq_setup(void) { /* disable IRQ3-0 + IRQ7-4 */ - ctrl_outl(0xff000000, INTC_INTMSK0); + __raw_writel(0xff000000, INTC_INTMSK0); /* disable IRL3-0 + IRL7-4 */ - ctrl_outl(0xc0000000, INTC_INTMSK1); - ctrl_outl(0xfffefffe, INTC_INTMSK2); + __raw_writel(0xc0000000, INTC_INTMSK1); + __raw_writel(0xfffefffe, INTC_INTMSK2); /* select IRL mode for IRL3-0 + IRL7-4 */ - ctrl_outl(ctrl_inl(INTC_ICR0) & ~0x00c00000, INTC_ICR0); + __raw_writel(__raw_readl(INTC_ICR0) & ~0x00c00000, INTC_ICR0); /* disable holding function, ie enable "SH-4 Mode" */ - ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00200000, INTC_ICR0); + __raw_writel(__raw_readl(INTC_ICR0) | 0x00200000, INTC_ICR0); register_intc_controller(&intc_desc); } @@ -561,32 +561,32 @@ void __init plat_irq_setup_pins(int mode) switch (mode) { case IRQ_MODE_IRQ7654: /* select IRQ mode for IRL7-4 */ - ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00400000, INTC_ICR0); + __raw_writel(__raw_readl(INTC_ICR0) | 0x00400000, INTC_ICR0); register_intc_controller(&intc_desc_irq4567); break; case IRQ_MODE_IRQ3210: /* select IRQ mode for IRL3-0 */ - ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00800000, INTC_ICR0); + __raw_writel(__raw_readl(INTC_ICR0) | 0x00800000, INTC_ICR0); register_intc_controller(&intc_desc_irq0123); break; case IRQ_MODE_IRL7654: /* enable IRL7-4 but don't provide any masking */ - ctrl_outl(0x40000000, INTC_INTMSKCLR1); - ctrl_outl(0x0000fffe, INTC_INTMSKCLR2); + __raw_writel(0x40000000, INTC_INTMSKCLR1); + __raw_writel(0x0000fffe, INTC_INTMSKCLR2); break; case IRQ_MODE_IRL3210: /* enable IRL0-3 but don't provide any masking */ - ctrl_outl(0x80000000, INTC_INTMSKCLR1); - ctrl_outl(0xfffe0000, INTC_INTMSKCLR2); + __raw_writel(0x80000000, INTC_INTMSKCLR1); + __raw_writel(0xfffe0000, INTC_INTMSKCLR2); break; case IRQ_MODE_IRL7654_MASK: /* enable IRL7-4 and mask using cpu intc controller */ - ctrl_outl(0x40000000, INTC_INTMSKCLR1); + __raw_writel(0x40000000, INTC_INTMSKCLR1); register_intc_controller(&intc_desc_irl4567); break; case IRQ_MODE_IRL3210_MASK: /* enable IRL0-3 and mask using cpu intc controller */ - ctrl_outl(0x80000000, INTC_INTMSKCLR1); + __raw_writel(0x80000000, INTC_INTMSKCLR1); register_intc_controller(&intc_desc_irl0123); break; default: diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c index 71673487ace0..7e585320710a 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c @@ -867,14 +867,14 @@ static DECLARE_INTC_DESC(intc_desc_irl4567, "sh7786-irl4567", vectors_irl4567, void __init plat_irq_setup(void) { /* disable IRQ3-0 + IRQ7-4 */ - ctrl_outl(0xff000000, INTC_INTMSK0); + __raw_writel(0xff000000, INTC_INTMSK0); /* disable IRL3-0 + IRL7-4 */ - ctrl_outl(0xc0000000, INTC_INTMSK1); - ctrl_outl(0xfffefffe, INTC_INTMSK2); + __raw_writel(0xc0000000, INTC_INTMSK1); + __raw_writel(0xfffefffe, INTC_INTMSK2); /* select IRL mode for IRL3-0 + IRL7-4 */ - ctrl_outl(ctrl_inl(INTC_ICR0) & ~0x00c00000, INTC_ICR0); + __raw_writel(__raw_readl(INTC_ICR0) & ~0x00c00000, INTC_ICR0); register_intc_controller(&intc_desc); } @@ -884,32 +884,32 @@ void __init plat_irq_setup_pins(int mode) switch (mode) { case IRQ_MODE_IRQ7654: /* select IRQ mode for IRL7-4 */ - ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00400000, INTC_ICR0); + __raw_writel(__raw_readl(INTC_ICR0) | 0x00400000, INTC_ICR0); register_intc_controller(&intc_desc_irq4567); break; case IRQ_MODE_IRQ3210: /* select IRQ mode for IRL3-0 */ - ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00800000, INTC_ICR0); + __raw_writel(__raw_readl(INTC_ICR0) | 0x00800000, INTC_ICR0); register_intc_controller(&intc_desc_irq0123); break; case IRQ_MODE_IRL7654: /* enable IRL7-4 but don't provide any masking */ - ctrl_outl(0x40000000, INTC_INTMSKCLR1); - ctrl_outl(0x0000fffe, INTC_INTMSKCLR2); + __raw_writel(0x40000000, INTC_INTMSKCLR1); + __raw_writel(0x0000fffe, INTC_INTMSKCLR2); break; case IRQ_MODE_IRL3210: /* enable IRL0-3 but don't provide any masking */ - ctrl_outl(0x80000000, INTC_INTMSKCLR1); - ctrl_outl(0xfffe0000, INTC_INTMSKCLR2); + __raw_writel(0x80000000, INTC_INTMSKCLR1); + __raw_writel(0xfffe0000, INTC_INTMSKCLR2); break; case IRQ_MODE_IRL7654_MASK: /* enable IRL7-4 and mask using cpu intc controller */ - ctrl_outl(0x40000000, INTC_INTMSKCLR1); + __raw_writel(0x40000000, INTC_INTMSKCLR1); register_intc_controller(&intc_desc_irl4567); break; case IRQ_MODE_IRL3210_MASK: /* enable IRL0-3 and mask using cpu intc controller */ - ctrl_outl(0x80000000, INTC_INTMSKCLR1); + __raw_writel(0x80000000, INTC_INTMSKCLR1); register_intc_controller(&intc_desc_irl0123); break; default: diff --git a/arch/sh/kernel/cpu/sh5/clock-sh5.c b/arch/sh/kernel/cpu/sh5/clock-sh5.c index 7f864ebc51d3..9cfc19b8dbe4 100644 --- a/arch/sh/kernel/cpu/sh5/clock-sh5.c +++ b/arch/sh/kernel/cpu/sh5/clock-sh5.c @@ -24,7 +24,7 @@ static unsigned long cprc_base; static void master_clk_init(struct clk *clk) { - int idx = (ctrl_inl(cprc_base + 0x00) >> 6) & 0x0007; + int idx = (__raw_readl(cprc_base + 0x00) >> 6) & 0x0007; clk->rate *= ifc_table[idx]; } @@ -34,7 +34,7 @@ static struct clk_ops sh5_master_clk_ops = { static unsigned long module_clk_recalc(struct clk *clk) { - int idx = (ctrl_inw(cprc_base) >> 12) & 0x0007; + int idx = (__raw_readw(cprc_base) >> 12) & 0x0007; return clk->parent->rate / ifc_table[idx]; } @@ -44,7 +44,7 @@ static struct clk_ops sh5_module_clk_ops = { static unsigned long bus_clk_recalc(struct clk *clk) { - int idx = (ctrl_inw(cprc_base) >> 3) & 0x0007; + int idx = (__raw_readw(cprc_base) >> 3) & 0x0007; return clk->parent->rate / ifc_table[idx]; } @@ -54,7 +54,7 @@ static struct clk_ops sh5_bus_clk_ops = { static unsigned long cpu_clk_recalc(struct clk *clk) { - int idx = (ctrl_inw(cprc_base) & 0x0007); + int idx = (__raw_readw(cprc_base) & 0x0007); return clk->parent->rate / ifc_table[idx]; } diff --git a/arch/sh/kernel/io_trapped.c b/arch/sh/kernel/io_trapped.c index 69be603aa2d7..16b83cc89a41 100644 --- a/arch/sh/kernel/io_trapped.c +++ b/arch/sh/kernel/io_trapped.c @@ -184,31 +184,31 @@ static unsigned long long copy_word(unsigned long src_addr, int src_len, switch (src_len) { case 1: - tmp = ctrl_inb(src_addr); + tmp = __raw_readb(src_addr); break; case 2: - tmp = ctrl_inw(src_addr); + tmp = __raw_readw(src_addr); break; case 4: - tmp = ctrl_inl(src_addr); + tmp = __raw_readl(src_addr); break; case 8: - tmp = ctrl_inq(src_addr); + tmp = __raw_readq(src_addr); break; } switch (dst_len) { case 1: - ctrl_outb(tmp, dst_addr); + __raw_writeb(tmp, dst_addr); break; case 2: - ctrl_outw(tmp, dst_addr); + __raw_writew(tmp, dst_addr); break; case 4: - ctrl_outl(tmp, dst_addr); + __raw_writel(tmp, dst_addr); break; case 8: - ctrl_outq(tmp, dst_addr); + __raw_writeq(tmp, dst_addr); break; } diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c index b6f43f0ea743..3cb88f114d7a 100644 --- a/arch/sh/kernel/process_32.c +++ b/arch/sh/kernel/process_32.c @@ -41,7 +41,7 @@ void show_regs(struct pt_regs * regs) printk("PC : %08lx SP : %08lx SR : %08lx ", regs->pc, regs->regs[15], regs->sr); #ifdef CONFIG_MMU - printk("TEA : %08x\n", ctrl_inl(MMU_TEA)); + printk("TEA : %08x\n", __raw_readl(MMU_TEA)); #else printk("\n"); #endif diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c index 6a7cce79eb4e..579cd2ca358d 100644 --- a/arch/sh/kernel/signal_32.c +++ b/arch/sh/kernel/signal_32.c @@ -528,7 +528,7 @@ handle_syscall_restart(unsigned long save_r0, struct pt_regs *regs, /* fallthrough */ case -ERESTARTNOINTR: regs->regs[0] = save_r0; - regs->pc -= instruction_size(ctrl_inw(regs->pc - 4)); + regs->pc -= instruction_size(__raw_readw(regs->pc - 4)); break; } } @@ -626,9 +626,9 @@ no_signal: regs->regs[0] == -ERESTARTSYS || regs->regs[0] == -ERESTARTNOINTR) { regs->regs[0] = save_r0; - regs->pc -= instruction_size(ctrl_inw(regs->pc - 4)); + regs->pc -= instruction_size(__raw_readw(regs->pc - 4)); } else if (regs->regs[0] == -ERESTART_RESTARTBLOCK) { - regs->pc -= instruction_size(ctrl_inw(regs->pc - 4)); + regs->pc -= instruction_size(__raw_readw(regs->pc - 4)); regs->regs[3] = __NR_restart_syscall; } } diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c index 7b036339dc92..0830c2a9f712 100644 --- a/arch/sh/kernel/traps.c +++ b/arch/sh/kernel/traps.c @@ -58,7 +58,7 @@ BUILD_TRAP_HANDLER(debug) TRAP_HANDLER_DECL; /* Rewind */ - regs->pc -= instruction_size(ctrl_inw(regs->pc - 4)); + regs->pc -= instruction_size(__raw_readw(regs->pc - 4)); if (notify_die(DIE_TRAP, "debug trap", regs, 0, vec & 0xff, SIGTRAP) == NOTIFY_STOP) @@ -75,7 +75,7 @@ BUILD_TRAP_HANDLER(bug) TRAP_HANDLER_DECL; /* Rewind */ - regs->pc -= instruction_size(ctrl_inw(regs->pc - 4)); + regs->pc -= instruction_size(__raw_readw(regs->pc - 4)); if (notify_die(DIE_TRAP, "bug trap", regs, 0, TRAPA_BUG_OPCODE & 0xff, SIGTRAP) == NOTIFY_STOP) diff --git a/arch/sh/mm/cache-debugfs.c b/arch/sh/mm/cache-debugfs.c index 48ce82ee9fd2..690ed010d002 100644 --- a/arch/sh/mm/cache-debugfs.c +++ b/arch/sh/mm/cache-debugfs.c @@ -36,7 +36,7 @@ static int cache_seq_show(struct seq_file *file, void *iter) */ jump_to_uncached(); - ccr = ctrl_inl(CCR); + ccr = __raw_readl(CCR); if ((ccr & CCR_CACHE_ENABLE) == 0) { back_to_cached(); @@ -89,7 +89,7 @@ static int cache_seq_show(struct seq_file *file, void *iter) for (addr = addrstart, line = 0; addr < addrstart + waysize; addr += cache->linesz, line++) { - unsigned long data = ctrl_inl(addr); + unsigned long data = __raw_readl(addr); /* Check the V bit, ignore invalid cachelines */ if ((data & 1) == 0) diff --git a/arch/sh/mm/cache-sh2.c b/arch/sh/mm/cache-sh2.c index 699a71f46327..defcf719f2e8 100644 --- a/arch/sh/mm/cache-sh2.c +++ b/arch/sh/mm/cache-sh2.c @@ -28,10 +28,10 @@ static void sh2__flush_wback_region(void *start, int size) unsigned long addr = CACHE_OC_ADDRESS_ARRAY | (v & 0x00000ff0); int way; for (way = 0; way < 4; way++) { - unsigned long data = ctrl_inl(addr | (way << 12)); + unsigned long data = __raw_readl(addr | (way << 12)); if ((data & CACHE_PHYSADDR_MASK) == (v & CACHE_PHYSADDR_MASK)) { data &= ~SH_CACHE_UPDATED; - ctrl_outl(data, addr | (way << 12)); + __raw_writel(data, addr | (way << 12)); } } } @@ -47,7 +47,7 @@ static void sh2__flush_purge_region(void *start, int size) & ~(L1_CACHE_BYTES-1); for (v = begin; v < end; v+=L1_CACHE_BYTES) - ctrl_outl((v & CACHE_PHYSADDR_MASK), + __raw_writel((v & CACHE_PHYSADDR_MASK), CACHE_OC_ADDRESS_ARRAY | (v & 0x00000ff0) | 0x00000008); } @@ -63,9 +63,9 @@ static void sh2__flush_invalidate_region(void *start, int size) local_irq_save(flags); jump_to_uncached(); - ccr = ctrl_inl(CCR); + ccr = __raw_readl(CCR); ccr |= CCR_CACHE_INVALIDATE; - ctrl_outl(ccr, CCR); + __raw_writel(ccr, CCR); back_to_cached(); local_irq_restore(flags); @@ -78,7 +78,7 @@ static void sh2__flush_invalidate_region(void *start, int size) & ~(L1_CACHE_BYTES-1); for (v = begin; v < end; v+=L1_CACHE_BYTES) - ctrl_outl((v & CACHE_PHYSADDR_MASK), + __raw_writel((v & CACHE_PHYSADDR_MASK), CACHE_OC_ADDRESS_ARRAY | (v & 0x00000ff0) | 0x00000008); #endif } diff --git a/arch/sh/mm/cache-sh2a.c b/arch/sh/mm/cache-sh2a.c index 975899d83564..1f51225426a2 100644 --- a/arch/sh/mm/cache-sh2a.c +++ b/arch/sh/mm/cache-sh2a.c @@ -32,10 +32,10 @@ static void sh2a__flush_wback_region(void *start, int size) unsigned long addr = CACHE_OC_ADDRESS_ARRAY | (v & 0x000007f0); int way; for (way = 0; way < 4; way++) { - unsigned long data = ctrl_inl(addr | (way << 11)); + unsigned long data = __raw_readl(addr | (way << 11)); if ((data & CACHE_PHYSADDR_MASK) == (v & CACHE_PHYSADDR_MASK)) { data &= ~SH_CACHE_UPDATED; - ctrl_outl(data, addr | (way << 11)); + __raw_writel(data, addr | (way << 11)); } } } @@ -58,7 +58,7 @@ static void sh2a__flush_purge_region(void *start, int size) jump_to_uncached(); for (v = begin; v < end; v+=L1_CACHE_BYTES) { - ctrl_outl((v & CACHE_PHYSADDR_MASK), + __raw_writel((v & CACHE_PHYSADDR_MASK), CACHE_OC_ADDRESS_ARRAY | (v & 0x000007f0) | 0x00000008); } back_to_cached(); @@ -78,17 +78,17 @@ static void sh2a__flush_invalidate_region(void *start, int size) jump_to_uncached(); #ifdef CONFIG_CACHE_WRITEBACK - ctrl_outl(ctrl_inl(CCR) | CCR_OCACHE_INVALIDATE, CCR); + __raw_writel(__raw_readl(CCR) | CCR_OCACHE_INVALIDATE, CCR); /* I-cache invalidate */ for (v = begin; v < end; v+=L1_CACHE_BYTES) { - ctrl_outl((v & CACHE_PHYSADDR_MASK), + __raw_writel((v & CACHE_PHYSADDR_MASK), CACHE_IC_ADDRESS_ARRAY | (v & 0x000007f0) | 0x00000008); } #else for (v = begin; v < end; v+=L1_CACHE_BYTES) { - ctrl_outl((v & CACHE_PHYSADDR_MASK), + __raw_writel((v & CACHE_PHYSADDR_MASK), CACHE_IC_ADDRESS_ARRAY | (v & 0x000007f0) | 0x00000008); - ctrl_outl((v & CACHE_PHYSADDR_MASK), + __raw_writel((v & CACHE_PHYSADDR_MASK), CACHE_OC_ADDRESS_ARRAY | (v & 0x000007f0) | 0x00000008); } #endif @@ -115,14 +115,14 @@ static void sh2a_flush_icache_range(void *args) int way; /* O-Cache writeback */ for (way = 0; way < 4; way++) { - unsigned long data = ctrl_inl(CACHE_OC_ADDRESS_ARRAY | addr | (way << 11)); + unsigned long data = __raw_readl(CACHE_OC_ADDRESS_ARRAY | addr | (way << 11)); if ((data & CACHE_PHYSADDR_MASK) == (v & CACHE_PHYSADDR_MASK)) { data &= ~SH_CACHE_UPDATED; - ctrl_outl(data, CACHE_OC_ADDRESS_ARRAY | addr | (way << 11)); + __raw_writel(data, CACHE_OC_ADDRESS_ARRAY | addr | (way << 11)); } } /* I-Cache invalidate */ - ctrl_outl(addr, + __raw_writel(addr, CACHE_IC_ADDRESS_ARRAY | addr | 0x00000008); } diff --git a/arch/sh/mm/cache-sh3.c b/arch/sh/mm/cache-sh3.c index faef80c98134..e37523f65195 100644 --- a/arch/sh/mm/cache-sh3.c +++ b/arch/sh/mm/cache-sh3.c @@ -50,12 +50,12 @@ static void sh3__flush_wback_region(void *start, int size) p = __pa(v); addr = addrstart | (v & current_cpu_data.dcache.entry_mask); local_irq_save(flags); - data = ctrl_inl(addr); + data = __raw_readl(addr); if ((data & CACHE_PHYSADDR_MASK) == (p & CACHE_PHYSADDR_MASK)) { data &= ~SH_CACHE_UPDATED; - ctrl_outl(data, addr); + __raw_writel(data, addr); local_irq_restore(flags); break; } @@ -86,7 +86,7 @@ static void sh3__flush_purge_region(void *start, int size) data = (v & 0xfffffc00); /* _Virtual_ address, ~U, ~V */ addr = CACHE_OC_ADDRESS_ARRAY | (v & current_cpu_data.dcache.entry_mask) | SH_CACHE_ASSOC; - ctrl_outl(data, addr); + __raw_writel(data, addr); } } diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c index 87115b3ee70e..2cfae81914aa 100644 --- a/arch/sh/mm/cache-sh4.c +++ b/arch/sh/mm/cache-sh4.c @@ -132,9 +132,9 @@ static void flush_icache_all(void) jump_to_uncached(); /* Flush I-cache */ - ccr = ctrl_inl(CCR); + ccr = __raw_readl(CCR); ccr |= CCR_CACHE_ICI; - ctrl_outl(ccr, CCR); + __raw_writel(ccr, CCR); /* * back_to_cached() will take care of the barrier for us, don't add @@ -377,9 +377,9 @@ extern void __weak sh4__flush_region_init(void); void __init sh4_cache_init(void) { printk("PVR=%08x CVR=%08x PRR=%08x\n", - ctrl_inl(CCN_PVR), - ctrl_inl(CCN_CVR), - ctrl_inl(CCN_PRR)); + __raw_readl(CCN_PVR), + __raw_readl(CCN_CVR), + __raw_readl(CCN_PRR)); local_flush_icache_range = sh4_flush_icache_range; local_flush_dcache_page = sh4_flush_dcache_page; diff --git a/arch/sh/mm/cache-sh7705.c b/arch/sh/mm/cache-sh7705.c index 870293ee539e..f498da1cce7a 100644 --- a/arch/sh/mm/cache-sh7705.c +++ b/arch/sh/mm/cache-sh7705.c @@ -48,10 +48,10 @@ static inline void cache_wback_all(void) unsigned long data; int v = SH_CACHE_UPDATED | SH_CACHE_VALID; - data = ctrl_inl(addr); + data = __raw_readl(addr); if ((data & v) == v) - ctrl_outl(data & ~v, addr); + __raw_writel(data & ~v, addr); } @@ -115,10 +115,10 @@ static void __flush_dcache_page(unsigned long phys) addr += current_cpu_data.dcache.linesz) { unsigned long data; - data = ctrl_inl(addr) & (0x1ffffC00 | SH_CACHE_VALID); + data = __raw_readl(addr) & (0x1ffffC00 | SH_CACHE_VALID); if (data == phys) { data &= ~(SH_CACHE_VALID | SH_CACHE_UPDATED); - ctrl_outl(data, addr); + __raw_writel(data, addr); } } diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c index 3d5eece7e6d0..3c9bf5b5c36f 100644 --- a/arch/sh/mm/pmb.c +++ b/arch/sh/mm/pmb.c @@ -112,7 +112,7 @@ static void pmb_free(struct pmb_entry *pmbe) static void __set_pmb_entry(unsigned long vpn, unsigned long ppn, unsigned long flags, int pos) { - ctrl_outl(vpn | PMB_V, mk_pmb_addr(pos)); + __raw_writel(vpn | PMB_V, mk_pmb_addr(pos)); #ifdef CONFIG_CACHE_WRITETHROUGH /* @@ -124,7 +124,7 @@ static void __set_pmb_entry(unsigned long vpn, unsigned long ppn, flags |= PMB_WT; #endif - ctrl_outl(ppn | flags | PMB_V, mk_pmb_data(pos)); + __raw_writel(ppn | flags | PMB_V, mk_pmb_data(pos)); } static void set_pmb_entry(struct pmb_entry *pmbe) @@ -146,10 +146,10 @@ static void clear_pmb_entry(struct pmb_entry *pmbe) /* Clear V-bit */ addr = mk_pmb_addr(entry); - ctrl_outl(ctrl_inl(addr) & ~PMB_V, addr); + __raw_writel(__raw_readl(addr) & ~PMB_V, addr); addr = mk_pmb_data(entry); - ctrl_outl(ctrl_inl(addr) & ~PMB_V, addr); + __raw_writel(__raw_readl(addr) & ~PMB_V, addr); back_to_cached(); } @@ -395,7 +395,7 @@ int pmb_init(void) unsigned long vpn, ppn, flags; addr = PMB_DATA + (i << PMB_E_SHIFT); - data = ctrl_inl(addr); + data = __raw_readl(addr); if (!(data & PMB_V)) continue; @@ -408,7 +408,7 @@ int pmb_init(void) data &= ~(PMB_C | PMB_WT); #endif } - ctrl_outl(data, addr); + __raw_writel(data, addr); ppn = data & PMB_PFN_MASK; @@ -416,7 +416,7 @@ int pmb_init(void) flags |= data & PMB_SZ_MASK; addr = PMB_ADDR + (i << PMB_E_SHIFT); - data = ctrl_inl(addr); + data = __raw_readl(addr); vpn = data & PMB_PFN_MASK; @@ -424,12 +424,12 @@ int pmb_init(void) WARN_ON(IS_ERR(pmbe)); } - ctrl_outl(0, PMB_IRMCR); + __raw_writel(0, PMB_IRMCR); /* Flush out the TLB */ - i = ctrl_inl(MMUCR); + i = __raw_readl(MMUCR); i |= MMUCR_TI; - ctrl_outl(i, MMUCR); + __raw_writel(i, MMUCR); back_to_cached(); @@ -454,8 +454,8 @@ static int pmb_seq_show(struct seq_file *file, void *iter) unsigned int size; char *sz_str = NULL; - addr = ctrl_inl(mk_pmb_addr(i)); - data = ctrl_inl(mk_pmb_data(i)); + addr = __raw_readl(mk_pmb_addr(i)); + data = __raw_readl(mk_pmb_data(i)); size = data & PMB_SZ_MASK; sz_str = (size == PMB_SZ_16M) ? " 16MB": diff --git a/arch/sh/mm/tlb-sh3.c b/arch/sh/mm/tlb-sh3.c index ace8e6d2f59d..4f5f7cbdd508 100644 --- a/arch/sh/mm/tlb-sh3.c +++ b/arch/sh/mm/tlb-sh3.c @@ -41,14 +41,14 @@ void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte) /* Set PTEH register */ vpn = (address & MMU_VPN_MASK) | get_asid(); - ctrl_outl(vpn, MMU_PTEH); + __raw_writel(vpn, MMU_PTEH); pteval = pte_val(pte); /* Set PTEL register */ pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */ /* conveniently, we want all the software flags to be 0 anyway */ - ctrl_outl(pteval, MMU_PTEL); + __raw_writel(pteval, MMU_PTEL); /* Load the TLB */ asm volatile("ldtlb": /* no output */ : /* no input */ : "memory"); @@ -75,5 +75,5 @@ void local_flush_tlb_one(unsigned long asid, unsigned long page) } for (i = 0; i < ways; i++) - ctrl_outl(data, addr + (i << 8)); + __raw_writel(data, addr + (i << 8)); } diff --git a/arch/sh/mm/tlb-sh4.c b/arch/sh/mm/tlb-sh4.c index 624c1daa9f3f..ccac77f504a8 100644 --- a/arch/sh/mm/tlb-sh4.c +++ b/arch/sh/mm/tlb-sh4.c @@ -29,7 +29,7 @@ void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte) /* Set PTEH register */ vpn = (address & MMU_VPN_MASK) | get_asid(); - ctrl_outl(vpn, MMU_PTEH); + __raw_writel(vpn, MMU_PTEH); pteval = pte.pte_low; @@ -41,13 +41,13 @@ void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte) * the protection bits (with the exception of the compat-mode SZ * and PR bits, which are cleared) being written out in PTEL. */ - ctrl_outl(pte.pte_high, MMU_PTEA); + __raw_writel(pte.pte_high, MMU_PTEA); #else if (cpu_data->flags & CPU_HAS_PTEA) { /* The last 3 bits and the first one of pteval contains * the PTEA timing control and space attribute bits */ - ctrl_outl(copy_ptea_attributes(pteval), MMU_PTEA); + __raw_writel(copy_ptea_attributes(pteval), MMU_PTEA); } #endif @@ -57,7 +57,7 @@ void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte) pteval |= _PAGE_WT; #endif /* conveniently, we want all the software flags to be 0 anyway */ - ctrl_outl(pteval, MMU_PTEL); + __raw_writel(pteval, MMU_PTEL); /* Load the TLB */ asm volatile("ldtlb": /* no output */ : /* no input */ : "memory"); @@ -77,6 +77,6 @@ void local_flush_tlb_one(unsigned long asid, unsigned long page) addr = MMU_UTLB_ADDRESS_ARRAY | MMU_PAGE_ASSOC_BIT; data = page | asid; /* VALID bit is off */ jump_to_uncached(); - ctrl_outl(data, addr); + __raw_writel(data, addr); back_to_cached(); } diff --git a/arch/sh/mm/tlbflush_32.c b/arch/sh/mm/tlbflush_32.c index 6f45c1f8a7fe..004bb3f25b5f 100644 --- a/arch/sh/mm/tlbflush_32.c +++ b/arch/sh/mm/tlbflush_32.c @@ -132,9 +132,9 @@ void local_flush_tlb_all(void) * It's same position, bit #2. */ local_irq_save(flags); - status = ctrl_inl(MMUCR); + status = __raw_readl(MMUCR); status |= 0x04; - ctrl_outl(status, MMUCR); + __raw_writel(status, MMUCR); ctrl_barrier(); local_irq_restore(flags); } -- cgit v1.2.3 From 485773f3e401fca31c112c1ff24797e42ff87afd Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 26 Jan 2010 13:02:10 +0900 Subject: sh: flag ctrl_in/outX as __deprecated. These routines are unsuitable for cross-platform use and no new code should be using them, flag them as deprecated in order to give drivers sufficient time to migrate over. Signed-off-by: Paul Mundt --- arch/sh/include/asm/io.h | 55 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 10 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h index e4f563f472eb..98c62fa168c2 100644 --- a/arch/sh/include/asm/io.h +++ b/arch/sh/include/asm/io.h @@ -80,16 +80,51 @@ #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 +/* + * Legacy SuperH on-chip I/O functions + * + * These are all deprecated, all new (and especially cross-platform) code + * should be using the __raw_xxx() routines directly. + */ +static inline u8 __deprecated ctrl_inb(unsigned long addr) +{ + return __raw_readb(addr); +} + +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); +} extern unsigned long generic_io_base; -- cgit v1.2.3 From 08b36c4a02b5a9db609fc6d93b9c41d7fa75713c Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 27 Jan 2010 21:56:57 +0900 Subject: sh: Optimize runtime disabling of trapped I/O. Presently trapped I/O is only registered if it's not explicitly disabled for the platforms that select it openly. From the fault path this runs through an address lookup before figuring out that nothing matches and falls back through the error path, but we can forego the lookup completely by testing if it's been explicitly disabled. This provides a measurable speedup for things like qemu that rely on runtime disabling. Signed-off-by: Paul Mundt --- arch/sh/kernel/io_trapped.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/kernel/io_trapped.c b/arch/sh/kernel/io_trapped.c index 16b83cc89a41..4a8bb4eeb8ad 100644 --- a/arch/sh/kernel/io_trapped.c +++ b/arch/sh/kernel/io_trapped.c @@ -271,6 +271,8 @@ int handle_trapped_io(struct pt_regs *regs, unsigned long address) insn_size_t instruction; int tmp; + if (trapped_io_disable) + return 0; if (!lookup_tiop(address)) return 0; -- cgit v1.2.3 From 660e2acad81c19b404f7d7d06e57a6d5e6ce7426 Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Wed, 27 Jan 2010 22:03:11 +0900 Subject: sh: kmemleak support. Enables support for kmemleak on sh. Signed-off-by: Chris Smith Signed-off-by: Paul Mundt --- arch/sh/kernel/vmlinux.lds.S | 6 +++--- lib/Kconfig.debug | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S index 93e9b25a1811..f0bc6b886eed 100644 --- a/arch/sh/kernel/vmlinux.lds.S +++ b/arch/sh/kernel/vmlinux.lds.S @@ -50,12 +50,12 @@ SECTIONS } = 0x0009 EXCEPTION_TABLE(16) - NOTES + + _sdata = .; RO_DATA(PAGE_SIZE) RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE) - - _edata = .; /* End of data section */ + _edata = .; DWARF_EH_FRAME diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 25c3ed594c54..d62e3cdab357 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -355,7 +355,7 @@ config SLUB_STATS config DEBUG_KMEMLEAK bool "Kernel memory leak detector" depends on DEBUG_KERNEL && EXPERIMENTAL && !MEMORY_HOTPLUG && \ - (X86 || ARM || PPC || S390) + (X86 || ARM || PPC || S390 || SUPERH) select DEBUG_FS if SYSFS select STACKTRACE if STACKTRACE_SUPPORT -- cgit v1.2.3 From 7013109f52ff38ad9ea38952cedc144c8e8b9636 Mon Sep 17 00:00:00 2001 From: Giuseppe CAVALLARO Date: Mon, 25 Jan 2010 16:12:07 +0100 Subject: sh: fixed cmpxchg gRB version This patch fixes a bug within the cmpxchg GRB version. A problem was notices while running some tests to stress the priority inheritance, for example pi_stress (http://rt.wiki.kernel.org/index.php/PI_Mutex_Test). Also, without this patch, after applying the latest work to consolidate atomic_cmpxchg() definitions (commit: 8c0b8139c87cfe8b95c6e763b4ca3190aa9b1ad0) the Kernel doesn't boot at all. Signed-off-by: Giuseppe Cavallaro Signed-off-by: Stuart Menefy Signed-off-by: Paul Mundt --- arch/sh/include/asm/cmpxchg-grb.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/cmpxchg-grb.h b/arch/sh/include/asm/cmpxchg-grb.h index e2681abe764f..4676bf57693a 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; -- cgit v1.2.3 From f655f5e956eaf4fcda983f3b3d37c76371556c27 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 28 Jan 2010 15:08:21 +0900 Subject: sh: mach-titan: Kill off unused PIO port mangling. Nothing is using this, kill it off. Fixing up access sizes can be done with trapped I/O for anyone wanting to make use of this for devices that need it, everything else is already pure MMIO. Signed-off-by: Paul Mundt --- arch/sh/Makefile | 1 - arch/sh/boards/Makefile | 1 + arch/sh/boards/board-titan.c | 24 +++++++++ arch/sh/boards/mach-titan/Makefile | 5 -- arch/sh/boards/mach-titan/io.c | 108 ------------------------------------- arch/sh/boards/mach-titan/setup.c | 44 --------------- 6 files changed, 25 insertions(+), 158 deletions(-) create mode 100644 arch/sh/boards/board-titan.c delete mode 100644 arch/sh/boards/mach-titan/Makefile delete mode 100644 arch/sh/boards/mach-titan/io.c delete mode 100644 arch/sh/boards/mach-titan/setup.c (limited to 'arch/sh') diff --git a/arch/sh/Makefile b/arch/sh/Makefile index 30c80fd29058..588579ac2e35 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -149,7 +149,6 @@ machdir-$(CONFIG_SH_X3PROTO) += mach-x3proto machdir-$(CONFIG_SH_SH7763RDP) += mach-sh7763rdp machdir-$(CONFIG_SH_SH4202_MICRODEV) += mach-microdev machdir-$(CONFIG_SH_LANDISK) += mach-landisk -machdir-$(CONFIG_SH_TITAN) += mach-titan machdir-$(CONFIG_SH_LBOX_RE2) += mach-lboxre2 machdir-$(CONFIG_SH_CAYMAN) += mach-cayman machdir-$(CONFIG_SH_RSK) += mach-rsk diff --git a/arch/sh/boards/Makefile b/arch/sh/boards/Makefile index ce0f26381784..4f90f9b7a922 100644 --- a/arch/sh/boards/Makefile +++ b/arch/sh/boards/Makefile @@ -8,3 +8,4 @@ obj-$(CONFIG_SH_SHMIN) += board-shmin.o obj-$(CONFIG_SH_EDOSK7760) += board-edosk7760.o obj-$(CONFIG_SH_ESPT) += board-espt.o obj-$(CONFIG_SH_POLARIS) += board-polaris.o +obj-$(CONFIG_SH_TITAN) += board-titan.o diff --git a/arch/sh/boards/board-titan.c b/arch/sh/boards/board-titan.c new file mode 100644 index 000000000000..94c36c7bc0b3 --- /dev/null +++ b/arch/sh/boards/board-titan.c @@ -0,0 +1,24 @@ +/* + * arch/sh/boards/titan/setup.c - Setup for Titan + * + * Copyright (C) 2006 Jamie Lenehan + * + * 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. + */ +#include +#include +#include +#include + +static void __init init_titan_irq(void) +{ + /* enable individual interrupt mode for externals */ + plat_irq_setup_pins(IRQ_MODE_IRQ); +} + +static struct sh_machine_vector mv_titan __initmv = { + .mv_name = "Titan", + .mv_init_irq = init_titan_irq, +}; diff --git a/arch/sh/boards/mach-titan/Makefile b/arch/sh/boards/mach-titan/Makefile deleted file mode 100644 index 08d753700062..000000000000 --- a/arch/sh/boards/mach-titan/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for the Nimble Microsystems TITAN specific parts of the kernel -# - -obj-y := setup.o io.o diff --git a/arch/sh/boards/mach-titan/io.c b/arch/sh/boards/mach-titan/io.c deleted file mode 100644 index 29754c5091f0..000000000000 --- a/arch/sh/boards/mach-titan/io.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * I/O routines for Titan - */ -#include -#include -#include -#include -#include - -static inline unsigned int port2adr(unsigned int port) -{ - maybebadio((unsigned long)port); - return port; -} - -u8 titan_inb(unsigned long port) -{ - if (PXSEG(port)) - return __raw_readb(port); - return __raw_readw(port2adr(port)) & 0xff; -} - -u8 titan_inb_p(unsigned long port) -{ - u8 v; - - if (PXSEG(port)) - v = __raw_readb(port); - else - v = __raw_readw(port2adr(port)) & 0xff; - ctrl_delay(); - return v; -} - -u16 titan_inw(unsigned long port) -{ - if (PXSEG(port)) - return __raw_readw(port); - else if (port >= 0x2000) - return __raw_readw(port2adr(port)); - else - maybebadio(port); - return 0; -} - -u32 titan_inl(unsigned long port) -{ - if (PXSEG(port)) - return __raw_readl(port); - else if (port >= 0x2000) - return __raw_readw(port2adr(port)); - else - maybebadio(port); - return 0; -} - -void titan_outb(u8 value, unsigned long port) -{ - if (PXSEG(port)) - __raw_writeb(value, port); - else - __raw_writew(value, port2adr(port)); -} - -void titan_outb_p(u8 value, unsigned long port) -{ - if (PXSEG(port)) - __raw_writeb(value, port); - else - __raw_writew(value, port2adr(port)); - ctrl_delay(); -} - -void titan_outw(u16 value, unsigned long port) -{ - if (PXSEG(port)) - __raw_writew(value, port); - else if (port >= 0x2000) - __raw_writew(value, port2adr(port)); - else - maybebadio(port); -} - -void titan_outl(u32 value, unsigned long port) -{ - if (PXSEG(port)) - __raw_writel(value, port); - else - maybebadio(port); -} - -void titan_insl(unsigned long port, void *dst, unsigned long count) -{ - maybebadio(port); -} - -void titan_outsl(unsigned long port, const void *src, unsigned long count) -{ - maybebadio(port); -} - -void __iomem *titan_ioport_map(unsigned long port, unsigned int size) -{ - if (PXSEG(port)) - return (void __iomem *)port; - - return (void __iomem *)port2adr(port); -} diff --git a/arch/sh/boards/mach-titan/setup.c b/arch/sh/boards/mach-titan/setup.c deleted file mode 100644 index 81e7e0f03863..000000000000 --- a/arch/sh/boards/mach-titan/setup.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * arch/sh/boards/titan/setup.c - Setup for Titan - * - * Copyright (C) 2006 Jamie Lenehan - * - * 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. - */ -#include -#include -#include -#include - -static void __init init_titan_irq(void) -{ - /* enable individual interrupt mode for externals */ - plat_irq_setup_pins(IRQ_MODE_IRQ); -} - -static struct sh_machine_vector mv_titan __initmv = { - .mv_name = "Titan", - - .mv_inb = titan_inb, - .mv_inw = titan_inw, - .mv_inl = titan_inl, - .mv_outb = titan_outb, - .mv_outw = titan_outw, - .mv_outl = titan_outl, - - .mv_inb_p = titan_inb_p, - .mv_inw_p = titan_inw, - .mv_inl_p = titan_inl, - .mv_outb_p = titan_outb_p, - .mv_outw_p = titan_outw, - .mv_outl_p = titan_outl, - - .mv_insl = titan_insl, - .mv_outsl = titan_outsl, - - .mv_ioport_map = titan_ioport_map, - - .mv_init_irq = init_titan_irq, -}; -- cgit v1.2.3 From 621266bdf4b78fa92f7eabd7688b86f0dbd61d64 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 28 Jan 2010 15:55:37 +0900 Subject: sh: Quiet noisy coherent DMA unmapping on R2D. IRQs are re-enabled at a later stage when doing the unmapping on R2D via the sm501 USB coherent DMA, resulting in the irqs_disabled() check producing considerable noise for this configuration. Just kill off the check, which was blindly copied from x86 anyways. Signed-off-by: Paul Mundt --- arch/sh/include/asm/dma-mapping.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/dma-mapping.h b/arch/sh/include/asm/dma-mapping.h index 87ced133a363..bea3337a426a 100644 --- a/arch/sh/include/asm/dma-mapping.h +++ b/arch/sh/include/asm/dma-mapping.h @@ -89,8 +89,6 @@ static inline void dma_free_coherent(struct device *dev, size_t size, { struct dma_map_ops *ops = get_dma_ops(dev); - WARN_ON(irqs_disabled()); /* for portability */ - if (dma_release_from_coherent(dev, get_order(size), vaddr)) return; -- cgit v1.2.3 From 849593591ce3b5f9352966c9d410284dc04d03b6 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 28 Jan 2010 18:15:05 +0900 Subject: sh: Fix up read-only variable assignment in pcibios_align_resource(). arch/sh/drivers/pci/pci.c:167: error: assignment of read-only location '*res' Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/pci.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index c481df639022..191075e91cda 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c @@ -162,10 +162,8 @@ void pcibios_align_resource(void *data, struct resource *res, /* * Put everything into 0x00-0xff region modulo 0x400. */ - if (start & 0x300) { + if (start & 0x300) start = (start + 0x3ff) & ~0x3ff; - res->start = start; - } } else if (res->flags & IORESOURCE_MEM) { if (start < PCIBIOS_MIN_MEM + chan->mem_resource->start) start = PCIBIOS_MIN_MEM + chan->mem_resource->start; -- cgit v1.2.3 From d627a2ebd1a303aa4ac1962c553d1e8738735d01 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 28 Jan 2010 18:17:29 +0900 Subject: sh: Fix up the ioremap_fixed() build for nommu. arch/sh/kernel/setup.c:455: error: implicit declaration of function 'ioremap_fixed_init' Signed-off-by: Paul Mundt --- arch/sh/include/asm/io.h | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h index 98c62fa168c2..bd5fafa23eb4 100644 --- a/arch/sh/include/asm/io.h +++ b/arch/sh/include/asm/io.h @@ -273,24 +273,6 @@ void __iomem *__ioremap_caller(unsigned long offset, unsigned long size, pgprot_t prot, void *caller); void __iounmap(void __iomem *addr); -#ifdef CONFIG_IOREMAP_FIXED -extern void __iomem *ioremap_fixed(resource_size_t, unsigned long, - unsigned long, pgprot_t); -extern int iounmap_fixed(void __iomem *); -extern void ioremap_fixed_init(void); -#else -static inline void __iomem * -ioremap_fixed(resource_size_t phys_addr, unsigned long offset, - 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 - static inline void __iomem * __ioremap(unsigned long offset, unsigned long size, pgprot_t prot) { @@ -365,6 +347,24 @@ ioremap_prot(resource_size_t offset, unsigned long size, unsigned long flags) } #endif +#ifdef CONFIG_IOREMAP_FIXED +extern void __iomem *ioremap_fixed(resource_size_t, unsigned long, + unsigned long, pgprot_t); +extern int iounmap_fixed(void __iomem *); +extern void ioremap_fixed_init(void); +#else +static inline void __iomem * +ioremap_fixed(resource_size_t phys_addr, unsigned long offset, + 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 -- cgit v1.2.3 From abec86a80247ab3a40d2afc9c8e8c26efcab2391 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 28 Jan 2010 18:26:37 +0900 Subject: sh: Kill off superfluous sh_bios references from compressed loader. The VBR value needs to be initialized in order for any of the bios trapping to work, and as we don't do that until slightly later in the boot process, this has no real chance of working. The only reason for using this in the past was due to the fact that early serial initialization wasn't possible, but now that early sh-sci is supported by everyone, there's no longer any reason to support the sh_bios hacks in the first place. Given that, we just kill off the references completely. Signed-off-by: Paul Mundt --- arch/sh/boot/compressed/Makefile | 4 ---- arch/sh/boot/compressed/misc.c | 19 ------------------- 2 files changed, 23 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/boot/compressed/Makefile b/arch/sh/boot/compressed/Makefile index 6b95a2a48267..5d660b90943b 100644 --- a/arch/sh/boot/compressed/Makefile +++ b/arch/sh/boot/compressed/Makefile @@ -11,10 +11,6 @@ targets := vmlinux vmlinux.bin vmlinux.bin.gz \ OBJECTS = $(obj)/head_$(BITS).o $(obj)/misc.o $(obj)/cache.o -ifdef CONFIG_SH_STANDARD_BIOS -OBJECTS += $(obj)/../../kernel/sh_bios.o -endif - # # IMAGE_OFFSET is the load offset of the compression loader # diff --git a/arch/sh/boot/compressed/misc.c b/arch/sh/boot/compressed/misc.c index 4b319e9e4f88..d509a5050623 100644 --- a/arch/sh/boot/compressed/misc.c +++ b/arch/sh/boot/compressed/misc.c @@ -14,7 +14,6 @@ #include #include #include -#include /* * gzip declarations @@ -66,29 +65,11 @@ static unsigned long free_mem_end_ptr; #include "../../../../lib/decompress_unlzo.c" #endif -#ifdef CONFIG_SH_STANDARD_BIOS -size_t strlen(const char *s) -{ - int i = 0; - - while (*s++) - i++; - return i; -} - -int puts(const char *s) -{ - int len = strlen(s); - sh_bios_console_write(s, len); - return len; -} -#else int puts(const char *s) { /* This should be updated to use the sh-sci routines */ return 0; } -#endif void* memset(void* s, int c, size_t n) { -- cgit v1.2.3 From 339ce1a4dc2ca26444c4f65c31b71a5056f3bb0b Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Mon, 18 Jan 2010 16:47:07 +1100 Subject: perf: Fix inconsistency between IP and callchain sampling When running perf across all cpus with backtracing (-a -g), sometimes we get samples without associated backtraces: 23.44% init [kernel] [k] restore 11.46% init eeba0c [k] 0x00000000eeba0c 6.77% swapper [kernel] [k] .perf_ctx_adjust_freq 5.73% init [kernel] [k] .__trace_hcall_entry 4.69% perf libc-2.9.so [.] 0x0000000006bb8c | |--11.11%-- 0xfffa941bbbc It turns out the backtrace code has a check for the idle task and the IP sampling does not. This creates problems when profiling an interrupt heavy workload (in my case 10Gbit ethernet) since we get no backtraces for interrupts received while idle (ie most of the workload). Right now x86 and sh check that current is not NULL, which should never happen so remove that too. Idle task's exclusion must be performed from the core code, on top of perf_event_attr:exclude_idle. Signed-off-by: Anton Blanchard Cc: Peter Zijlstra Cc: Paul Mackerras Cc: Ingo Molnar Cc: Benjamin Herrenschmidt Cc: Paul Mundt LKML-Reference: <20100118054707.GT12666@kryten> Signed-off-by: Frederic Weisbecker --- arch/powerpc/kernel/perf_callchain.c | 3 --- arch/sh/kernel/perf_callchain.c | 3 --- arch/x86/kernel/cpu/perf_event.c | 3 --- 3 files changed, 9 deletions(-) (limited to 'arch/sh') diff --git a/arch/powerpc/kernel/perf_callchain.c b/arch/powerpc/kernel/perf_callchain.c index a3c11cac3d71..95ad9dad298e 100644 --- a/arch/powerpc/kernel/perf_callchain.c +++ b/arch/powerpc/kernel/perf_callchain.c @@ -495,9 +495,6 @@ struct perf_callchain_entry *perf_callchain(struct pt_regs *regs) entry->nr = 0; - if (current->pid == 0) /* idle task? */ - return entry; - if (!user_mode(regs)) { perf_callchain_kernel(regs, entry); if (current->mm) diff --git a/arch/sh/kernel/perf_callchain.c b/arch/sh/kernel/perf_callchain.c index 24ea837eac5b..a9dd3abde28e 100644 --- a/arch/sh/kernel/perf_callchain.c +++ b/arch/sh/kernel/perf_callchain.c @@ -68,9 +68,6 @@ perf_do_callchain(struct pt_regs *regs, struct perf_callchain_entry *entry) is_user = user_mode(regs); - if (!current || current->pid == 0) - return; - if (is_user && current->state != TASK_RUNNING) return; diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index b1bb8c550526..ed1998b28a7c 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -2425,9 +2425,6 @@ perf_do_callchain(struct pt_regs *regs, struct perf_callchain_entry *entry) is_user = user_mode(regs); - if (!current || current->pid == 0) - return; - if (is_user && current->state != TASK_RUNNING) return; -- cgit v1.2.3 From 9762528f37ddc7071509dddb10e7b4b3b957fd01 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 29 Jan 2010 16:14:29 +0900 Subject: sh: Kill off deprecated fixed PCI memory window accessors. This kills off the deprected fixed memory range accessors for the cases of non-translatable ioremapping. Signed-off-by: Paul Mundt --- arch/sh/include/asm/pci.h | 14 -------------- arch/sh/mm/ioremap.c | 15 --------------- 2 files changed, 29 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index 67f3999b544e..f362d8a045e7 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h @@ -99,20 +99,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); diff --git a/arch/sh/mm/ioremap.c b/arch/sh/mm/ioremap.c index bb03308e8408..94583c5da855 100644 --- a/arch/sh/mm/ioremap.c +++ b/arch/sh/mm/ioremap.c @@ -45,18 +45,6 @@ __ioremap_caller(unsigned long phys_addr, unsigned long size, if (!size || last_addr < phys_addr) return NULL; - /* - * If we're in the fixed PCI memory range, mapping through page - * tables is not only pointless, but also fundamentally broken. - * Just return the physical address instead. - * - * For boards that map a small PCI memory aperture somewhere in - * P1/P2 space, ioremap() will already do the right thing, - * and we'll never get this far. - */ - if (is_pci_memory_fixed_range(phys_addr, size)) - return (void __iomem *)phys_addr; - /* * Mappings have to be page-aligned */ @@ -125,9 +113,6 @@ static inline int iomapping_nontranslatable(unsigned long offset) return 1; #endif - if (is_pci_memory_fixed_range(offset, 0)) - return 1; - return 0; } -- cgit v1.2.3 From a45635dfb08a1fa2cf77bf1f2c4074961ce2e625 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 29 Jan 2010 22:19:04 +0900 Subject: sh: Reworked SH7780 PCI initialization. This consolidates the PCI initialization code for all of the pci-sh7780 users, and sets up the memory window dynamically as opposed to using hardcoded window positions. A number of bugs were fixed at the same time, including the PIO handling and master abort timeout settings being incorrect. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/fixups-r7780rp.c | 12 --- arch/sh/drivers/pci/fixups-sdk7780.c | 19 ----- arch/sh/drivers/pci/pci-sh4.h | 13 ++- arch/sh/drivers/pci/pci-sh7780.c | 149 +++++++++++++++++++---------------- arch/sh/drivers/pci/pci-sh7780.h | 54 ++----------- 5 files changed, 102 insertions(+), 145 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/drivers/pci/fixups-r7780rp.c b/arch/sh/drivers/pci/fixups-r7780rp.c index 15ca65cb667e..08b2d8658a00 100644 --- a/arch/sh/drivers/pci/fixups-r7780rp.c +++ b/arch/sh/drivers/pci/fixups-r7780rp.c @@ -22,15 +22,3 @@ int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) { return irq_tab[slot]; } - -int pci_fixup_pcic(struct pci_channel *chan) -{ - pci_write_reg(chan, 0x000043ff, SH4_PCIINTM); - pci_write_reg(chan, 0x00000000, SH7780_PCIIBAR); - pci_write_reg(chan, 0x08000000, SH7780_PCICSCR0); - pci_write_reg(chan, 0x0000001b, SH7780_PCICSAR0); - pci_write_reg(chan, 0xfd000000, SH7780_PCICSCR1); - pci_write_reg(chan, 0x0000000f, SH7780_PCICSAR1); - - return 0; -} diff --git a/arch/sh/drivers/pci/fixups-sdk7780.c b/arch/sh/drivers/pci/fixups-sdk7780.c index 250b0edd7365..0930f988ac29 100644 --- a/arch/sh/drivers/pci/fixups-sdk7780.c +++ b/arch/sh/drivers/pci/fixups-sdk7780.c @@ -31,22 +31,3 @@ int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) { return sdk7780_irq_tab[pin-1][slot]; } -int pci_fixup_pcic(struct pci_channel *chan) -{ - /* Enable all interrupts, so we know what to fix */ - pci_write_reg(chan, 0x0000C3FF, SH7780_PCIIMR); - - /* Set up standard PCI config registers */ - pci_write_reg(chan, 0x08000000, SH7780_PCIMBAR0); /* PCI */ - pci_write_reg(chan, 0x08000000, SH4_PCILAR0); /* SHwy */ - pci_write_reg(chan, 0x07F00001, SH4_PCILSR0); /* size 128M w/ MBAR */ - - pci_write_reg(chan, 0x00000000, SH7780_PCIMBAR1); - pci_write_reg(chan, 0x00000000, SH4_PCILAR1); - pci_write_reg(chan, 0x00000000, SH4_PCILSR1); - - pci_write_reg(chan, 0xAB000801, SH7780_PCIIBAR); - pci_write_reg(chan, 0xA5000C01, SH4_PCICR); - - return 0; -} diff --git a/arch/sh/drivers/pci/pci-sh4.h b/arch/sh/drivers/pci/pci-sh4.h index 4744a7dede0c..43dddd827561 100644 --- a/arch/sh/drivers/pci/pci-sh4.h +++ b/arch/sh/drivers/pci/pci-sh4.h @@ -49,6 +49,17 @@ #define SH4_PCIINT_MWPD 0x00000002 /* Master Write PERR Detect */ #define SH4_PCIINT_MRPD 0x00000001 /* Master Read PERR Detect */ #define SH4_PCIINTM 0x118 /* PCI Interrupt Mask */ + #define SH4_PCIINTM_TTADIM BIT(14) /* Target-target abort interrupt */ + #define SH4_PCIINTM_TMTOIM BIT(9) /* Target retry timeout */ + #define SH4_PCIINTM_MDEIM BIT(8) /* Master function disable error */ + #define SH4_PCIINTM_APEDIM BIT(7) /* Address parity error detection */ + #define SH4_PCIINTM_SDIM BIT(6) /* SERR detection */ + #define SH4_PCIINTM_DPEITWM BIT(5) /* Data parity error for target write */ + #define SH4_PCIINTM_PEDITRM BIT(4) /* PERR detection for target read */ + #define SH4_PCIINTM_TADIMM BIT(3) /* Target abort for master */ + #define SH4_PCIINTM_MADIMM BIT(2) /* Master abort for master */ + #define SH4_PCIINTM_MWPDIM BIT(1) /* Master write data parity error */ + #define SH4_PCIINTM_MRDPEIM BIT(0) /* Master read data parity error */ #define SH4_PCIALR 0x11C /* Error Address Register */ #define SH4_PCICLR 0x120 /* Error Command/Data */ #define SH4_PCICLR_MPIO 0x80000000 @@ -61,7 +72,7 @@ #define SH4_PCIAINT 0x130 /* Arbiter Interrupt Register */ #define SH4_PCIAINT_MBKN 0x00002000 /* Master Broken Interrupt */ #define SH4_PCIAINT_TBTO 0x00001000 /* Target Bus Time Out */ - #define SH4_PCIAINT_MBTO 0x00001000 /* Master Bus Time Out */ + #define SH4_PCIAINT_MBTO 0x00000800 /* Master Bus Time Out */ #define SH4_PCIAINT_TABT 0x00000008 /* Target Abort */ #define SH4_PCIAINT_MABT 0x00000004 /* Master Abort */ #define SH4_PCIAINT_RDPE 0x00000002 /* Read Data Parity Error */ diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c index 323b92d565fe..019e1afcd0a3 100644 --- a/arch/sh/drivers/pci/pci-sh7780.c +++ b/arch/sh/drivers/pci/pci-sh7780.c @@ -1,7 +1,7 @@ /* * Low-Level PCI Support for the SH7780 * - * Copyright (C) 2005 - 2009 Paul Mundt + * Copyright (C) 2005 - 2010 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 @@ -14,11 +14,13 @@ #include #include #include "pci-sh4.h" +#include +#include static struct resource sh7785_io_resource = { .name = "SH7785_IO", - .start = SH7780_PCI_IO_BASE, - .end = SH7780_PCI_IO_BASE + SH7780_PCI_IO_SIZE - 1, + .start = 0x1000, + .end = SH7780_PCI_IO_SIZE - 1, .flags = IORESOURCE_IO }; @@ -38,25 +40,14 @@ static struct pci_channel sh7780_pci_controller = { .io_map_base = SH7780_PCI_IO_BASE, }; -static struct sh4_pci_address_map sh7780_pci_map = { - .window0 = { -#if defined(CONFIG_32BIT) - .base = SH7780_32BIT_DDR_BASE_ADDR, - .size = 0x40000000, -#else - .base = SH7780_CS0_BASE_ADDR, - .size = 0x20000000, -#endif - }, -}; - static int __init sh7780_pci_init(void) { struct pci_channel *chan = &sh7780_pci_controller; + phys_addr_t memphys; + size_t memsize; unsigned int id; - const char *type = NULL; + const char *type; int ret; - u32 word; printk(KERN_NOTICE "PCI: Starting intialization.\n"); @@ -65,17 +56,24 @@ static int __init sh7780_pci_init(void) /* Enable CPU access to the PCIC registers. */ __raw_writel(PCIECR_ENBL, PCIECR); - id = __raw_readw(chan->reg_base + SH7780_PCIVID); - if (id != SH7780_VENDOR_ID) { + /* Reset */ + __raw_writel(SH4_PCICR_PREFIX | SH4_PCICR_PRST, + chan->reg_base + SH4_PCICR); + + /* Wait for it to come back up.. */ + mdelay(100); + + id = __raw_readw(chan->reg_base + PCI_VENDOR_ID); + if (id != PCI_VENDOR_ID_RENESAS) { printk(KERN_ERR "PCI: Unknown vendor ID 0x%04x.\n", id); return -ENODEV; } - id = __raw_readw(chan->reg_base + SH7780_PCIDID); - type = (id == SH7763_DEVICE_ID) ? "SH7763" : - (id == SH7780_DEVICE_ID) ? "SH7780" : - (id == SH7781_DEVICE_ID) ? "SH7781" : - (id == SH7785_DEVICE_ID) ? "SH7785" : + id = __raw_readw(chan->reg_base + PCI_DEVICE_ID); + type = (id == PCI_DEVICE_ID_RENESAS_SH7763) ? "SH7763" : + (id == PCI_DEVICE_ID_RENESAS_SH7780) ? "SH7780" : + (id == PCI_DEVICE_ID_RENESAS_SH7781) ? "SH7781" : + (id == PCI_DEVICE_ID_RENESAS_SH7785) ? "SH7785" : NULL; if (unlikely(!type)) { printk(KERN_ERR "PCI: Found an unsupported Renesas host " @@ -85,59 +83,78 @@ static int __init sh7780_pci_init(void) printk(KERN_NOTICE "PCI: Found a Renesas %s host " "controller, revision %d.\n", type, - __raw_readb(chan->reg_base + SH7780_PCIRID)); + __raw_readb(chan->reg_base + PCI_REVISION_ID)); if ((ret = sh4_pci_check_direct(chan)) != 0) return ret; /* - * Set the class and sub-class codes. + * Now throw it in to register initialization mode and + * start the real work. */ - __raw_writeb(PCI_CLASS_BRIDGE_HOST >> 8, - chan->reg_base + SH7780_PCIBCC); - __raw_writeb(PCI_CLASS_BRIDGE_HOST & 0xff, - chan->reg_base + SH7780_PCISUB); + __raw_writel(SH4_PCICR_PREFIX, chan->reg_base + SH4_PCICR); + + memphys = __pa(memory_start); + memsize = memory_end - memory_start; /* * Set IO and Mem windows to local address * Make PCI and local address the same for easy 1 to 1 mapping */ - pci_write_reg(chan, sh7780_pci_map.window0.size - 0xfffff, SH4_PCILSR0); - /* Set the values on window 0 PCI config registers */ - pci_write_reg(chan, sh7780_pci_map.window0.base, SH4_PCILAR0); - pci_write_reg(chan, sh7780_pci_map.window0.base, SH7780_PCIMBAR0); - - pci_write_reg(chan, 0x0000380f, SH4_PCIAINTM); - - /* Set up standard PCI config registers */ - __raw_writew(0xFB00, chan->reg_base + SH7780_PCISTATUS); - __raw_writew(0x0047, chan->reg_base + SH7780_PCICMD); - __raw_writew(0x1912, chan->reg_base + SH7780_PCISVID); - __raw_writew(0x0001, chan->reg_base + SH7780_PCISID); - - __raw_writeb(0x00, chan->reg_base + SH7780_PCIPIF); - - /* Apply any last-minute PCIC fixups */ - pci_fixup_pcic(chan); - - pci_write_reg(chan, 0xfd000000, SH7780_PCIMBR0); - pci_write_reg(chan, 0x00fc0000, SH7780_PCIMBMR0); - -#ifdef CONFIG_32BIT - pci_write_reg(chan, 0xc0000000, SH7780_PCIMBR2); - pci_write_reg(chan, 0x20000000 - SH7780_PCI_IO_SIZE, SH7780_PCIMBMR2); -#endif - - /* Set IOBR for windows containing area specified in pci.h */ - pci_write_reg(chan, chan->io_resource->start & ~(SH7780_PCI_IO_SIZE-1), - SH7780_PCIIOBR); - pci_write_reg(chan, ((SH7780_PCI_IO_SIZE-1) & (7<<18)), - SH7780_PCIIOBMR); - - /* SH7780 init done, set central function init complete */ - /* use round robin mode to stop a device starving/overruning */ - word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_FTO; - pci_write_reg(chan, word, SH4_PCICR); + __raw_writel(0, chan->reg_base + PCI_BASE_ADDRESS_0); + + __raw_writel(memphys, chan->reg_base + SH4_PCILAR0); + __raw_writel((memsize - 1) << 9 | 1, + chan->reg_base + SH4_PCILSR0); + + /* Clear out PCI arbiter IRQs */ + __raw_writel(0, chan->reg_base + SH4_PCIAINT); + + /* Unmask all of the arbiter IRQs. */ + __raw_writel(SH4_PCIAINT_MBKN | SH4_PCIAINT_TBTO | SH4_PCIAINT_MBTO | \ + SH4_PCIAINT_TABT | SH4_PCIAINT_MABT | SH4_PCIAINT_RDPE | \ + SH4_PCIAINT_WDPE, chan->reg_base + SH4_PCIAINTM); + + /* Clear all error conditions */ + __raw_writew(PCI_STATUS_DETECTED_PARITY | \ + PCI_STATUS_SIG_SYSTEM_ERROR | \ + PCI_STATUS_REC_MASTER_ABORT | \ + PCI_STATUS_REC_TARGET_ABORT | \ + PCI_STATUS_SIG_TARGET_ABORT | \ + PCI_STATUS_PARITY, chan->reg_base + PCI_STATUS); + + __raw_writew(PCI_COMMAND_SERR | PCI_COMMAND_WAIT | \ + PCI_COMMAND_PARITY | PCI_COMMAND_MASTER | \ + PCI_COMMAND_MEMORY, chan->reg_base + PCI_COMMAND); + + /* Unmask all of the PCI IRQs */ + __raw_writel(SH4_PCIINTM_TTADIM | SH4_PCIINTM_TMTOIM | \ + SH4_PCIINTM_MDEIM | SH4_PCIINTM_APEDIM | \ + SH4_PCIINTM_SDIM | SH4_PCIINTM_DPEITWM | \ + SH4_PCIINTM_PEDITRM | SH4_PCIINTM_TADIMM | \ + SH4_PCIINTM_MADIMM | SH4_PCIINTM_MWPDIM | \ + SH4_PCIINTM_MRDPEIM, chan->reg_base + SH4_PCIINTM); + + /* + * Disable the cache snoop controller for non-coherent DMA. + */ + __raw_writel(0, chan->reg_base + SH7780_PCICSCR0); + __raw_writel(0, chan->reg_base + SH7780_PCICSAR0); + __raw_writel(0, chan->reg_base + SH7780_PCICSCR1); + __raw_writel(0, chan->reg_base + SH7780_PCICSAR1); + + __raw_writel(0xfd000000, chan->reg_base + SH7780_PCIMBR0); + __raw_writel(0x00fc0000, chan->reg_base + SH7780_PCIMBMR0); + + __raw_writel(0, chan->reg_base + SH7780_PCIIOBR); + __raw_writel(0, chan->reg_base + SH7780_PCIIOBMR); + + /* + * Initialization mode complete, release the control register and + * enable round robin mode to stop device overruns/starvation. + */ + __raw_writel(SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_FTO, + chan->reg_base + SH4_PCICR); register_pci_controller(chan); diff --git a/arch/sh/drivers/pci/pci-sh7780.h b/arch/sh/drivers/pci/pci-sh7780.h index 4a52478c97cf..dee069c3865d 100644 --- a/arch/sh/drivers/pci/pci-sh7780.h +++ b/arch/sh/drivers/pci/pci-sh7780.h @@ -12,12 +12,11 @@ #ifndef _PCI_SH7780_H_ #define _PCI_SH7780_H_ -/* Platform Specific Values */ -#define SH7780_VENDOR_ID 0x1912 -#define SH7781_DEVICE_ID 0x0001 -#define SH7780_DEVICE_ID 0x0002 -#define SH7763_DEVICE_ID 0x0004 -#define SH7785_DEVICE_ID 0x0007 +#define PCI_VENDOR_ID_RENESAS 0x1912 +#define PCI_DEVICE_ID_RENESAS_SH7781 0x0001 +#define PCI_DEVICE_ID_RENESAS_SH7780 0x0002 +#define PCI_DEVICE_ID_RENESAS_SH7763 0x0004 +#define PCI_DEVICE_ID_RENESAS_SH7785 0x0007 /* SH7780 Control Registers */ #define PCIECR 0xFE000008 @@ -36,35 +35,6 @@ #define SH7780_PCIREG_BASE 0xFE040000 /* PCI regs base address */ /* SH7780 PCI Config Registers */ -#define SH7780_PCIVID 0x000 /* Vendor ID */ -#define SH7780_PCIDID 0x002 /* Device ID */ -#define SH7780_PCICMD 0x004 /* Command */ -#define SH7780_PCISTATUS 0x006 /* Status */ -#define SH7780_PCIRID 0x008 /* Revision ID */ -#define SH7780_PCIPIF 0x009 /* Program Interface */ -#define SH7780_PCISUB 0x00a /* Sub class code */ -#define SH7780_PCIBCC 0x00b /* Base class code */ -#define SH7780_PCICLS 0x00c /* Cache line size */ -#define SH7780_PCILTM 0x00d /* latency timer */ -#define SH7780_PCIHDR 0x00e /* Header type */ -#define SH7780_PCIBIST 0x00f /* BIST */ -#define SH7780_PCIIBAR 0x010 /* IO Base address */ -#define SH7780_PCIMBAR0 0x014 /* Memory base address0 */ -#define SH7780_PCIMBAR1 0x018 /* Memory base address1 */ -#define SH7780_PCISVID 0x02c /* Sub system vendor ID */ -#define SH7780_PCISID 0x02e /* Sub system ID */ -#define SH7780_PCICP 0x034 -#define SH7780_PCIINTLINE 0x03c /* Interrupt line */ -#define SH7780_PCIINTPIN 0x03d /* Interrupt pin */ -#define SH7780_PCIMINGNT 0x03e /* Minumum grand */ -#define SH7780_PCIMAXLAT 0x03f /* Maxmum latency */ -#define SH7780_PCICID 0x040 -#define SH7780_PCINIP 0x041 -#define SH7780_PCIPMC 0x042 -#define SH7780_PCIPMCSR 0x044 -#define SH7780_PCIPMCSR_BSE 0x046 -#define SH7780_PCICDD 0x047 - #define SH7780_PCIIR 0x114 /* PCI Interrupt Register */ #define SH7780_PCIIMR 0x118 /* PCI Interrupt Mask Register */ #define SH7780_PCIAIR 0x11C /* Error Address Register */ @@ -78,6 +48,8 @@ #define SH7780_PCIMBR0 0x1E0 #define SH7780_PCIMBMR0 0x1E4 +#define SH7780_PCIMBR1 0x1E8 +#define SH7780_PCIMBMR1 0x1EC #define SH7780_PCIMBR2 0x1F0 #define SH7780_PCIMBMR2 0x1F4 #define SH7780_PCIIOBR 0x1F8 @@ -87,16 +59,4 @@ #define SH7780_PCICSAR0 0x218 /* Cache Snoop1 Addr. Register */ #define SH7780_PCICSAR1 0x21C /* Cache Snoop2 Addr. Register */ -/* General Memory Config Addresses */ -#define SH7780_CS0_BASE_ADDR 0x0 -#define SH7780_MEM_REGION_SIZE 0x04000000 -#define SH7780_CS1_BASE_ADDR (SH7780_CS0_BASE_ADDR + SH7780_MEM_REGION_SIZE) -#define SH7780_CS2_BASE_ADDR (SH7780_CS1_BASE_ADDR + SH7780_MEM_REGION_SIZE) -#define SH7780_CS3_BASE_ADDR (SH7780_CS2_BASE_ADDR + SH7780_MEM_REGION_SIZE) -#define SH7780_CS4_BASE_ADDR (SH7780_CS3_BASE_ADDR + SH7780_MEM_REGION_SIZE) -#define SH7780_CS5_BASE_ADDR (SH7780_CS4_BASE_ADDR + SH7780_MEM_REGION_SIZE) -#define SH7780_CS6_BASE_ADDR (SH7780_CS5_BASE_ADDR + SH7780_MEM_REGION_SIZE) - -#define SH7780_32BIT_DDR_BASE_ADDR 0x40000000 - #endif /* _PCI_SH7780_H_ */ -- cgit v1.2.3 From ac8ab54a8e41a5ed0ee2161d45b6dc855490989f Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 29 Jan 2010 22:22:27 +0900 Subject: sh: Bail out early on PCI resource conflicts. Presently we just call in to request_resource() for the ioport and iomem resources without checking for errors. This has already hidden a couple of bugs, so add some error handling in for good measure. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/pci.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index 191075e91cda..82e59bc6210e 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c @@ -53,8 +53,12 @@ static DEFINE_MUTEX(pci_scan_mutex); void __devinit register_pci_controller(struct pci_channel *hose) { - request_resource(&iomem_resource, hose->mem_resource); - request_resource(&ioport_resource, hose->io_resource); + if (request_resource(&iomem_resource, hose->mem_resource) < 0) + goto out; + if (request_resource(&ioport_resource, hose->io_resource) < 0) { + release_resource(hose->mem_resource); + goto out; + } *hose_tail = hose; hose_tail = &hose->next; @@ -76,6 +80,9 @@ void __devinit register_pci_controller(struct pci_channel *hose) pcibios_scanbus(hose); mutex_unlock(&pci_scan_mutex); } + +out: + printk(KERN_WARNING "Skipping PCI bus scan due to resource conflict\n"); } static int __init pcibios_init(void) @@ -319,20 +326,9 @@ void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) if (flags & IORESOURCE_IO) return ioport_map_pci(dev, start, len); - - /* - * Presently the IORESOURCE_MEM case is a bit special, most - * SH7751 style PCI controllers have PCI memory at a fixed - * location in the address space where no remapping is desired. - * With the IORESOURCE_MEM case more care has to be taken - * to inhibit page table mapping for legacy cores, but this is - * punted off to __ioremap(). - * -- PFM. - */ if (flags & IORESOURCE_MEM) { if (flags & IORESOURCE_CACHEABLE) return ioremap(start, len); - return ioremap_nocache(start, len); } -- cgit v1.2.3 From 320e68da59353fe6ad51b81f6865c4b674ad66ea Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 29 Jan 2010 22:38:13 +0900 Subject: sh: support PCI domains. Newer SH parts are now commonly shipping with multiple controllers, so we wire up PCI domain support to deal with them. Shamelessly cloned from the MIPS implementation. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 4 ++++ arch/sh/drivers/pci/pci.c | 17 +++++++++++++++-- arch/sh/include/asm/pci.h | 13 ++++++++++++- 3 files changed, 31 insertions(+), 3 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 352879c1b86b..bae53831c06b 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -826,11 +826,15 @@ config MAPLE config PCI bool "PCI support" depends on SYS_SUPPORTS_PCI + select PCI_DOMAINS help Find out whether you have a PCI motherboard. PCI is the name of a bus system, i.e. the way the CPU talks to the other stuff inside your box. If you have PCI, say Y, otherwise N. +config PCI_DOMAINS + bool + source "drivers/pci/pcie/Kconfig" source "drivers/pci/Kconfig" diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index 82e59bc6210e..45a15cab01df 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c @@ -33,15 +33,22 @@ static int pci_initialized; static void __devinit pcibios_scanbus(struct pci_channel *hose) { static int next_busno; + static int need_domain_info; struct pci_bus *bus; bus = pci_scan_bus(next_busno, hose->pci_ops, hose); + hose->bus = bus; + + need_domain_info = need_domain_info || hose->index; + hose->need_domain_info = need_domain_info; if (bus) { next_busno = bus->subordinate + 1; /* Don't allow 8-bit bus number overflow inside the hose - reserve some space for bridges. */ - if (next_busno > 224) + if (next_busno > 224) { next_busno = 0; + need_domain_info = 1; + } pci_bus_size_bridges(bus); pci_bus_assign_resources(bus); @@ -307,9 +314,15 @@ static void __iomem *ioport_map_pci(struct pci_dev *dev, { struct pci_channel *chan = dev->sysdata; - if (!chan->io_map_base) + if (unlikely(!chan->io_map_base)) { chan->io_map_base = generic_io_base; + if (pci_domains_supported) + panic("To avoid data corruption io_map_base MUST be " + "set with multiple PCI domains."); + } + + return (void __iomem *)(chan->io_map_base + port); } diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index f362d8a045e7..d124a009889f 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h @@ -15,6 +15,7 @@ */ struct pci_channel { struct pci_channel *next; + struct pci_bus *bus; struct pci_ops *pci_ops; struct resource *io_resource; @@ -24,8 +25,10 @@ struct pci_channel { unsigned long mem_offset; unsigned long reg_base; - unsigned long io_map_base; + + unsigned int index; + unsigned int need_domain_info; }; extern void register_pci_controller(struct pci_channel *hose); @@ -108,6 +111,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) { -- cgit v1.2.3 From 396c56a9c69ebb0baf9171a6365ac9fda322728d Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Sat, 30 Jan 2010 01:41:21 +0900 Subject: sh: Kill off broken type 1 PCI config access checks. The host controllers only support type 1, so there's not much else to test for. Some of the older controllers also supported type 2 accesses, but we've never supported those, and likely never will. Beyond that, the P1SEG test is meaningless for 32-bit mode, so rather than refactoring it, just kill the type 1 test off completely. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/ops-sh4.c | 28 ---------------------------- arch/sh/drivers/pci/pci-sh4.h | 1 - arch/sh/drivers/pci/pci-sh7751.c | 4 ---- arch/sh/drivers/pci/pci-sh7780.c | 4 ---- 4 files changed, 37 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/drivers/pci/ops-sh4.c b/arch/sh/drivers/pci/ops-sh4.c index 78bebebdc99c..e55e81a71727 100644 --- a/arch/sh/drivers/pci/ops-sh4.c +++ b/arch/sh/drivers/pci/ops-sh4.c @@ -102,34 +102,6 @@ struct pci_ops sh4_pci_ops = { .write = sh4_pci_write, }; -/* - * Not really related to pci_ops, but it's common and not worth shoving - * somewhere else for now.. - */ -int __init sh4_pci_check_direct(struct pci_channel *chan) -{ - /* - * Check if configuration works. - */ - unsigned int tmp = pci_read_reg(chan, SH4_PCIPAR); - - pci_write_reg(chan, P1SEG, SH4_PCIPAR); - - if (pci_read_reg(chan, SH4_PCIPAR) == P1SEG) { - pci_write_reg(chan, tmp, SH4_PCIPAR); - printk(KERN_INFO "PCI: Using configuration type 1\n"); - request_region(chan->reg_base + SH4_PCIPAR, 8, - "PCI conf1"); - return 0; - } - - pci_write_reg(chan, tmp, SH4_PCIPAR); - - printk(KERN_ERR "PCI: %s failed\n", __func__); - - return -EINVAL; -} - int __attribute__((weak)) pci_fixup_pcic(struct pci_channel *chan) { /* Nothing to do. */ diff --git a/arch/sh/drivers/pci/pci-sh4.h b/arch/sh/drivers/pci/pci-sh4.h index 43dddd827561..cbf763b3015e 100644 --- a/arch/sh/drivers/pci/pci-sh4.h +++ b/arch/sh/drivers/pci/pci-sh4.h @@ -162,7 +162,6 @@ /* arch/sh/kernel/drivers/pci/ops-sh4.c */ extern struct pci_ops sh4_pci_ops; -int sh4_pci_check_direct(struct pci_channel *chan); int pci_fixup_pcic(struct pci_channel *chan); struct sh4_pci_address_space { diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c index 2455cf32db5a..02306ddb4011 100644 --- a/arch/sh/drivers/pci/pci-sh7751.c +++ b/arch/sh/drivers/pci/pci-sh7751.c @@ -79,7 +79,6 @@ static int __init sh7751_pci_init(void) struct pci_channel *chan = &sh7751_pci_controller; unsigned int id; u32 word, reg; - int ret; printk(KERN_NOTICE "PCI: Starting intialization.\n"); @@ -93,9 +92,6 @@ static int __init sh7751_pci_init(void) return -ENODEV; } - if ((ret = sh4_pci_check_direct(chan)) != 0) - return ret; - /* Set the BCR's to enable PCI access */ reg = __raw_readl(SH7751_BCR1); reg |= 0x80000; diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c index 019e1afcd0a3..40531cd367b7 100644 --- a/arch/sh/drivers/pci/pci-sh7780.c +++ b/arch/sh/drivers/pci/pci-sh7780.c @@ -47,7 +47,6 @@ static int __init sh7780_pci_init(void) size_t memsize; unsigned int id; const char *type; - int ret; printk(KERN_NOTICE "PCI: Starting intialization.\n"); @@ -85,9 +84,6 @@ static int __init sh7780_pci_init(void) "controller, revision %d.\n", type, __raw_readb(chan->reg_base + PCI_REVISION_ID)); - if ((ret = sh4_pci_check_direct(chan)) != 0) - return ret; - /* * Now throw it in to register initialization mode and * start the real work. -- cgit v1.2.3 From 97b19778ee5dd0484493f12f6a9cf9391cf0aefb Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Sat, 30 Jan 2010 11:04:38 +0900 Subject: sh: mach-se: Fix up irq_desc reference. The irq_desc needs to be accessed with irq_to_desc(), this fixes up a build error with irq_desc being undefined. Signed-off-by: Paul Mundt --- arch/sh/boards/mach-se/7206/irq.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch/sh') diff --git a/arch/sh/boards/mach-se/7206/irq.c b/arch/sh/boards/mach-se/7206/irq.c index 79be4bc59933..8d82175d83ab 100644 --- a/arch/sh/boards/mach-se/7206/irq.c +++ b/arch/sh/boards/mach-se/7206/irq.c @@ -89,8 +89,9 @@ static void enable_se7206_irq(unsigned int irq) static void eoi_se7206_irq(unsigned int irq) { unsigned short sts0,sts1; + struct irq_desc *desc = irq_to_desc(irq); - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS))) enable_se7206_irq(irq); /* FPGA isr clear */ sts0 = __raw_readw(INTSTS0); -- cgit v1.2.3 From 31a090ae0693af189fc7a8ad16cece4878acad33 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Sat, 30 Jan 2010 11:29:56 +0900 Subject: sh: Fix up asm/hw_breakpoint.h header check. Presently headers_check complains about linux/kdebug.h being unexported, so just bump the __KERNEL__ ifdef up, as per the x86 change. Signed-off-by: Paul Mundt --- arch/sh/include/asm/hw_breakpoint.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/hw_breakpoint.h b/arch/sh/include/asm/hw_breakpoint.h index 7295d6290249..965dd780d51b 100644 --- a/arch/sh/include/asm/hw_breakpoint.h +++ b/arch/sh/include/asm/hw_breakpoint.h @@ -1,12 +1,12 @@ #ifndef __ASM_SH_HW_BREAKPOINT_H #define __ASM_SH_HW_BREAKPOINT_H -#include -#include - #ifdef __KERNEL__ #define __ARCH_HW_BREAKPOINT_H +#include +#include + struct arch_hw_breakpoint { char *name; /* Contains name of the symbol to set bkpt */ unsigned long address; -- cgit v1.2.3 From aee4467b5ce5047401efb4175b1360ec1734affc Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 1 Feb 2010 11:33:22 +0900 Subject: sh: Fix up large system memory handling for SH7780 PCI. For systems that have more than 512MB we need to set up an additional mapping, this fixes up the rounding to the next power of two and splits out the mapping accordingly between the two local bus mapping windows. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/pci-sh7780.c | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c index 40531cd367b7..8405c8fded6f 100644 --- a/arch/sh/drivers/pci/pci-sh7780.c +++ b/arch/sh/drivers/pci/pci-sh7780.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "pci-sh4.h" #include #include @@ -59,7 +60,11 @@ static int __init sh7780_pci_init(void) __raw_writel(SH4_PCICR_PREFIX | SH4_PCICR_PRST, chan->reg_base + SH4_PCICR); - /* Wait for it to come back up.. */ + /* + * Wait for it to come back up. The spec says to allow for up to + * 1 second after toggling the reset pin, but in practice 100ms + * is more than enough. + */ mdelay(100); id = __raw_readw(chan->reg_base + PCI_VENDOR_ID); @@ -90,17 +95,34 @@ static int __init sh7780_pci_init(void) */ __raw_writel(SH4_PCICR_PREFIX, chan->reg_base + SH4_PCICR); + __raw_writel(0, chan->reg_base + PCI_BASE_ADDRESS_0); + memphys = __pa(memory_start); - memsize = memory_end - memory_start; + memsize = roundup_pow_of_two(memory_end - memory_start); /* - * Set IO and Mem windows to local address - * Make PCI and local address the same for easy 1 to 1 mapping + * If there's more than 512MB of memory, we need to roll over to + * LAR1/LSR1. */ - __raw_writel(0, chan->reg_base + PCI_BASE_ADDRESS_0); + if (memsize > SZ_512M) { + __raw_writel(memphys + SZ_512M, chan->reg_base + SH4_PCILAR1); + __raw_writel((((memsize - SZ_512M) - SZ_1M) & 0x1ff00000) | 1, + chan->reg_base + SH4_PCILSR1); + memsize = SZ_512M; + } else { + /* + * Otherwise just zero it out and disable it. + */ + __raw_writel(0, chan->reg_base + SH4_PCILAR1); + __raw_writel(0, chan->reg_base + SH4_PCILSR1); + } + /* + * LAR0/LSR0 covers up to the first 512MB, which is enough to + * cover all of lowmem on most platforms. + */ __raw_writel(memphys, chan->reg_base + SH4_PCILAR0); - __raw_writel((memsize - 1) << 9 | 1, + __raw_writel(((memsize - SZ_1M) & 0x1ff00000) | 1, chan->reg_base + SH4_PCILSR0); /* Clear out PCI arbiter IRQs */ -- cgit v1.2.3 From 85b59f5bb24aeca1a987cbb206e228bf630c8327 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 1 Feb 2010 13:01:42 +0900 Subject: sh: Enable PCI66 support for SH7780 host controller. This adds some helper glue for scanning the bus and determining if all of the devices are 66MHz capable or not before flipping on 66MHz mode. This isn't quite to spec, but it's fairly consistent with what other embedded controllers end up having to do. Scanning code cribbed from the MIPS txx9 PCI code. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/Makefile | 2 +- arch/sh/drivers/pci/common.c | 64 ++++++++++++++++++++++++++++++++++++++++ arch/sh/drivers/pci/pci-sh7780.c | 29 ++++++++++++++++++ arch/sh/drivers/pci/pci.c | 2 ++ arch/sh/include/asm/pci.h | 2 ++ 5 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 arch/sh/drivers/pci/common.c (limited to 'arch/sh') diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile index 2c458b602beb..4a59e6890876 100644 --- a/arch/sh/drivers/pci/Makefile +++ b/arch/sh/drivers/pci/Makefile @@ -1,7 +1,7 @@ # # Makefile for the PCI specific kernel interface routines under Linux. # -obj-y += pci.o +obj-y += common.o pci.o obj-$(CONFIG_CPU_SUBTYPE_SH7751) += pci-sh7751.o ops-sh4.o obj-$(CONFIG_CPU_SUBTYPE_SH7751R) += pci-sh7751.o ops-sh4.o diff --git a/arch/sh/drivers/pci/common.c b/arch/sh/drivers/pci/common.c new file mode 100644 index 000000000000..f67c946a8612 --- /dev/null +++ b/arch/sh/drivers/pci/common.c @@ -0,0 +1,64 @@ +#include +#include + +static int __init +early_read_config_word(struct pci_channel *hose, + int top_bus, int bus, int devfn, int offset, u16 *value) +{ + struct pci_dev fake_dev; + struct pci_bus fake_bus; + + fake_dev.bus = &fake_bus; + fake_dev.sysdata = hose; + fake_dev.devfn = devfn; + fake_bus.number = bus; + fake_bus.sysdata = hose; + fake_bus.ops = hose->pci_ops; + + if (bus != top_bus) + /* Fake a parent bus structure. */ + fake_bus.parent = &fake_bus; + else + fake_bus.parent = NULL; + + return pci_read_config_word(&fake_dev, offset, value); +} + +int __init pci_is_66mhz_capable(struct pci_channel *hose, + int top_bus, int current_bus) +{ + u32 pci_devfn; + unsigned short vid; + int cap66 = -1; + u16 stat; + + printk(KERN_INFO "PCI: Checking 66MHz capabilities...\n"); + + for (pci_devfn = 0; pci_devfn < 0xff; pci_devfn++) { + if (PCI_FUNC(pci_devfn)) + continue; + if (early_read_config_word(hose, top_bus, current_bus, + pci_devfn, PCI_VENDOR_ID, &vid) != + PCIBIOS_SUCCESSFUL) + continue; + if (vid == 0xffff) + continue; + + /* check 66MHz capability */ + if (cap66 < 0) + cap66 = 1; + if (cap66) { + early_read_config_word(hose, top_bus, current_bus, + pci_devfn, PCI_STATUS, &stat); + if (!(stat & PCI_STATUS_66MHZ)) { + printk(KERN_DEBUG + "PCI: %02x:%02x not 66MHz capable.\n", + current_bus, pci_devfn); + cap66 = 0; + break; + } + } + } + + return cap66 > 0; +} diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c index 8405c8fded6f..b68f45b6451a 100644 --- a/arch/sh/drivers/pci/pci-sh7780.c +++ b/arch/sh/drivers/pci/pci-sh7780.c @@ -41,6 +41,29 @@ static struct pci_channel sh7780_pci_controller = { .io_map_base = SH7780_PCI_IO_BASE, }; +static void __init sh7780_pci66_init(struct pci_channel *hose) +{ + unsigned int tmp; + + if (!pci_is_66mhz_capable(hose, 0, 0)) + return; + + /* Enable register access */ + tmp = __raw_readl(hose->reg_base + SH4_PCICR); + tmp |= SH4_PCICR_PREFIX; + __raw_writel(tmp, hose->reg_base + SH4_PCICR); + + /* Enable 66MHz operation */ + tmp = __raw_readw(hose->reg_base + PCI_STATUS); + tmp |= PCI_STATUS_66MHZ; + __raw_writew(tmp, hose->reg_base + PCI_STATUS); + + /* Done */ + tmp = __raw_readl(hose->reg_base + SH4_PCICR); + tmp |= SH4_PCICR_PREFIX | SH4_PCICR_CFIN; + __raw_writel(tmp, hose->reg_base + SH4_PCICR); +} + static int __init sh7780_pci_init(void) { struct pci_channel *chan = &sh7780_pci_controller; @@ -176,6 +199,12 @@ static int __init sh7780_pci_init(void) register_pci_controller(chan); + sh7780_pci66_init(chan); + + printk(KERN_NOTICE "PCI: Running at %dMHz.\n", + (__raw_readw(chan->reg_base + PCI_STATUS) & PCI_STATUS_66MHZ) ? + 66 : 33); + return 0; } arch_initcall(sh7780_pci_init); diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index 45a15cab01df..63b11fddffec 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c @@ -88,6 +88,8 @@ void __devinit register_pci_controller(struct pci_channel *hose) mutex_unlock(&pci_scan_mutex); } + return; + out: printk(KERN_WARNING "Skipping PCI bus scan due to resource conflict\n"); } diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index d124a009889f..5849d435c441 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h @@ -32,6 +32,8 @@ struct pci_channel { }; extern void register_pci_controller(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; -- cgit v1.2.3 From bcf39352eb9e9026f7a1028d4bce3707b65f104b Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 1 Feb 2010 13:11:25 +0900 Subject: sh: Handle PCI controller resource conflicts. register_pci_controller() can fail, but presently is a void function. Change this over to an int so that we can bail early before continuing on with post-registration initialization (such as throwing the controller in to 66MHz mode in the case of the SH7780 host controller). Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/pci-dreamcast.c | 4 +--- arch/sh/drivers/pci/pci-sh5.c | 4 +--- arch/sh/drivers/pci/pci-sh7751.c | 4 +--- arch/sh/drivers/pci/pci-sh7780.c | 5 ++++- arch/sh/drivers/pci/pci.c | 5 +++-- arch/sh/drivers/pci/pcie-sh7786.c | 4 +--- arch/sh/include/asm/pci.h | 2 +- 7 files changed, 12 insertions(+), 16 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/drivers/pci/pci-dreamcast.c b/arch/sh/drivers/pci/pci-dreamcast.c index 210f9d4af141..bd5a1e50ebf6 100644 --- a/arch/sh/drivers/pci/pci-dreamcast.c +++ b/arch/sh/drivers/pci/pci-dreamcast.c @@ -95,8 +95,6 @@ static int __init gapspci_init(void) outl(0x00002001, GAPSPCI_BBA_CONFIG+0x10); outl(0x01000000, GAPSPCI_BBA_CONFIG+0x14); - register_pci_controller(&dreamcast_pci_controller); - - return 0; + return register_pci_controller(&dreamcast_pci_controller); } arch_initcall(gapspci_init); diff --git a/arch/sh/drivers/pci/pci-sh5.c b/arch/sh/drivers/pci/pci-sh5.c index 873ed2b44055..bce73faabc88 100644 --- a/arch/sh/drivers/pci/pci-sh5.c +++ b/arch/sh/drivers/pci/pci-sh5.c @@ -216,8 +216,6 @@ static int __init sh5pci_init(void) sh5_mem_resource.start = memStart; sh5_mem_resource.end = memStart + memSize; - register_pci_controller(&sh5pci_controller); - - return 0; + return register_pci_controller(&sh5pci_controller); } arch_initcall(sh5pci_init); diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c index 02306ddb4011..6ad5beb524aa 100644 --- a/arch/sh/drivers/pci/pci-sh7751.c +++ b/arch/sh/drivers/pci/pci-sh7751.c @@ -176,8 +176,6 @@ static int __init sh7751_pci_init(void) word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_ARBM; pci_write_reg(chan, word, SH4_PCICR); - register_pci_controller(chan); - - return 0; + return register_pci_controller(chan); } arch_initcall(sh7751_pci_init); diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c index b68f45b6451a..0e0ddd67e6e1 100644 --- a/arch/sh/drivers/pci/pci-sh7780.c +++ b/arch/sh/drivers/pci/pci-sh7780.c @@ -71,6 +71,7 @@ static int __init sh7780_pci_init(void) size_t memsize; unsigned int id; const char *type; + int ret; printk(KERN_NOTICE "PCI: Starting intialization.\n"); @@ -197,7 +198,9 @@ static int __init sh7780_pci_init(void) __raw_writel(SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_FTO, chan->reg_base + SH4_PCICR); - register_pci_controller(chan); + ret = register_pci_controller(chan); + if (unlikely(ret)) + return ret; sh7780_pci66_init(chan); diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index 63b11fddffec..488331c45033 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c @@ -58,7 +58,7 @@ static void __devinit pcibios_scanbus(struct pci_channel *hose) static DEFINE_MUTEX(pci_scan_mutex); -void __devinit register_pci_controller(struct pci_channel *hose) +int __devinit register_pci_controller(struct pci_channel *hose) { if (request_resource(&iomem_resource, hose->mem_resource) < 0) goto out; @@ -88,10 +88,11 @@ void __devinit register_pci_controller(struct pci_channel *hose) mutex_unlock(&pci_scan_mutex); } - return; + return 0; out: printk(KERN_WARNING "Skipping PCI bus scan due to resource conflict\n"); + return -1; } static int __init pcibios_init(void) diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c index ac37ee879bab..feac1fef21eb 100644 --- a/arch/sh/drivers/pci/pcie-sh7786.c +++ b/arch/sh/drivers/pci/pcie-sh7786.c @@ -296,9 +296,7 @@ static int __devinit sh7786_pcie_init_hw(struct sh7786_pcie_port *port) if (unlikely(ret < 0)) return ret; - register_pci_controller(port->hose); - - return 0; + return register_pci_controller(port->hose); } static struct sh7786_pcie_hwops sh7786_65nm_pcie_hwops __initdata = { diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index 5849d435c441..bbd10cf79825 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h @@ -31,7 +31,7 @@ struct pci_channel { unsigned int need_domain_info; }; -extern void register_pci_controller(struct pci_channel *hose); +extern int register_pci_controller(struct pci_channel *hose); extern int pci_is_66mhz_capable(struct pci_channel *hose, int top_bus, int current_bus); -- cgit v1.2.3 From ef407beefbd9928792ccc93857e408e0057bc17b Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 1 Feb 2010 16:39:46 +0900 Subject: sh: Hook up ERR/PERR/SERR detection for SH7780 PCI host controllers. These were never handled before, so implement some common infrastructure to support them, then make use of that in the SH7780-specific code. In practice there is little here that can not be generalized for SH4 parts, which will be an incremental change as the 7780/7751 code is gradually unified. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/common.c | 79 +++++++++++++++ arch/sh/drivers/pci/ops-sh4.c | 2 +- arch/sh/drivers/pci/pci-sh7780.c | 203 +++++++++++++++++++++++++++++++++------ arch/sh/drivers/pci/pci.c | 51 ++++++++++ arch/sh/include/asm/pci.h | 11 +++ 5 files changed, 317 insertions(+), 29 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/drivers/pci/common.c b/arch/sh/drivers/pci/common.c index f67c946a8612..25aec005da18 100644 --- a/arch/sh/drivers/pci/common.c +++ b/arch/sh/drivers/pci/common.c @@ -1,4 +1,6 @@ #include +#include +#include #include static int __init @@ -62,3 +64,80 @@ int __init pci_is_66mhz_capable(struct pci_channel *hose, return cap66 > 0; } + +static void pcibios_enable_err(unsigned long __data) +{ + struct pci_channel *hose = (struct pci_channel *)__data; + + del_timer(&hose->err_timer); + printk(KERN_DEBUG "PCI: re-enabling error IRQ.\n"); + enable_irq(hose->err_irq); +} + +static void pcibios_enable_serr(unsigned long __data) +{ + struct pci_channel *hose = (struct pci_channel *)__data; + + del_timer(&hose->serr_timer); + printk(KERN_DEBUG "PCI: re-enabling system error IRQ.\n"); + enable_irq(hose->serr_irq); +} + +void pcibios_enable_timers(struct pci_channel *hose) +{ + if (hose->err_irq) { + init_timer(&hose->err_timer); + hose->err_timer.data = (unsigned long)hose; + hose->err_timer.function = pcibios_enable_err; + } + + if (hose->serr_irq) { + init_timer(&hose->serr_timer); + hose->serr_timer.data = (unsigned long)hose; + hose->serr_timer.function = pcibios_enable_serr; + } +} + +/* + * A simple handler for the regular PCI status errors, called from IRQ + * context. + */ +unsigned int pcibios_handle_status_errors(unsigned long addr, + unsigned int status, + struct pci_channel *hose) +{ + unsigned int cmd = 0; + + if (status & PCI_STATUS_REC_MASTER_ABORT) { + printk(KERN_DEBUG "PCI: master abort, pc=0x%08lx\n", addr); + cmd |= PCI_STATUS_REC_MASTER_ABORT; + } + + if (status & PCI_STATUS_REC_TARGET_ABORT) { + printk(KERN_DEBUG "PCI: target abort: "); + pcibios_report_status(PCI_STATUS_REC_TARGET_ABORT | + PCI_STATUS_SIG_TARGET_ABORT | + PCI_STATUS_REC_MASTER_ABORT, 1); + printk("\n"); + + cmd |= PCI_STATUS_REC_TARGET_ABORT; + } + + if (status & (PCI_STATUS_PARITY | PCI_STATUS_DETECTED_PARITY)) { + printk(KERN_DEBUG "PCI: parity error detected: "); + pcibios_report_status(PCI_STATUS_PARITY | + PCI_STATUS_DETECTED_PARITY, 1); + printk("\n"); + + cmd |= PCI_STATUS_PARITY | PCI_STATUS_DETECTED_PARITY; + + /* Now back off of the IRQ for awhile */ + if (hose->err_irq) { + disable_irq(hose->err_irq); + hose->err_timer.expires = jiffies + HZ; + add_timer(&hose->err_timer); + } + } + + return cmd; +} diff --git a/arch/sh/drivers/pci/ops-sh4.c b/arch/sh/drivers/pci/ops-sh4.c index e55e81a71727..0b81999fb88b 100644 --- a/arch/sh/drivers/pci/ops-sh4.c +++ b/arch/sh/drivers/pci/ops-sh4.c @@ -16,7 +16,7 @@ * Direct access to PCI hardware... */ #define CONFIG_CMD(bus, devfn, where) \ - (P1SEG | (bus->number << 16) | (devfn << 8) | (where & ~3)) + (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3)) static DEFINE_SPINLOCK(sh4_pci_lock); diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c index 0e0ddd67e6e1..86373314f458 100644 --- a/arch/sh/drivers/pci/pci-sh7780.c +++ b/arch/sh/drivers/pci/pci-sh7780.c @@ -11,6 +11,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -39,8 +42,165 @@ static struct pci_channel sh7780_pci_controller = { .io_resource = &sh7785_io_resource, .io_offset = 0x00000000, .io_map_base = SH7780_PCI_IO_BASE, + .serr_irq = evt2irq(0xa00), + .err_irq = evt2irq(0xaa0), }; +struct pci_errors { + unsigned int mask; + const char *str; +} pci_arbiter_errors[] = { + { SH4_PCIAINT_MBKN, "master broken" }, + { SH4_PCIAINT_TBTO, "target bus time out" }, + { SH4_PCIAINT_MBTO, "master bus time out" }, + { SH4_PCIAINT_TABT, "target abort" }, + { SH4_PCIAINT_MABT, "master abort" }, + { SH4_PCIAINT_RDPE, "read data parity error" }, + { SH4_PCIAINT_WDPE, "write data parity error" }, +}, pci_interrupt_errors[] = { + { SH4_PCIINT_MLCK, "master lock error" }, + { SH4_PCIINT_TABT, "target-target abort" }, + { SH4_PCIINT_TRET, "target retry time out" }, + { SH4_PCIINT_MFDE, "master function disable erorr" }, + { SH4_PCIINT_PRTY, "address parity error" }, + { SH4_PCIINT_SERR, "SERR" }, + { SH4_PCIINT_TWDP, "data parity error for target write" }, + { SH4_PCIINT_TRDP, "PERR detected for target read" }, + { SH4_PCIINT_MTABT, "target abort for master" }, + { SH4_PCIINT_MMABT, "master abort for master" }, + { SH4_PCIINT_MWPD, "master write data parity error" }, + { SH4_PCIINT_MRPD, "master read data parity error" }, +}; + +static irqreturn_t sh7780_pci_err_irq(int irq, void *dev_id) +{ + struct pci_channel *hose = dev_id; + unsigned long addr; + unsigned int status; + unsigned int cmd; + int i; + + addr = __raw_readl(hose->reg_base + SH4_PCIALR); + + /* + * Handle status errors. + */ + status = __raw_readw(hose->reg_base + PCI_STATUS); + if (status & (PCI_STATUS_PARITY | + PCI_STATUS_DETECTED_PARITY | + PCI_STATUS_SIG_TARGET_ABORT | + PCI_STATUS_REC_TARGET_ABORT | + PCI_STATUS_REC_MASTER_ABORT)) { + cmd = pcibios_handle_status_errors(addr, status, hose); + if (likely(cmd)) + __raw_writew(cmd, hose->reg_base + PCI_STATUS); + } + + /* + * Handle arbiter errors. + */ + status = __raw_readl(hose->reg_base + SH4_PCIAINT); + for (i = cmd = 0; i < ARRAY_SIZE(pci_arbiter_errors); i++) { + if (status & pci_arbiter_errors[i].mask) { + printk(KERN_DEBUG "PCI: %s, addr=%08lx\n", + pci_arbiter_errors[i].str, addr); + cmd |= pci_arbiter_errors[i].mask; + } + } + __raw_writel(cmd, hose->reg_base + SH4_PCIAINT); + + /* + * Handle the remaining PCI errors. + */ + status = __raw_readl(hose->reg_base + SH4_PCIINT); + for (i = cmd = 0; i < ARRAY_SIZE(pci_interrupt_errors); i++) { + if (status & pci_interrupt_errors[i].mask) { + printk(KERN_DEBUG "PCI: %s, addr=%08lx\n", + pci_interrupt_errors[i].str, addr); + cmd |= pci_interrupt_errors[i].mask; + } + } + __raw_writel(cmd, hose->reg_base + SH4_PCIINT); + + return IRQ_HANDLED; +} + +static irqreturn_t sh7780_pci_serr_irq(int irq, void *dev_id) +{ + struct pci_channel *hose = dev_id; + + printk(KERN_DEBUG "PCI: system error received: "); + pcibios_report_status(PCI_STATUS_SIG_SYSTEM_ERROR, 1); + printk("\n"); + + /* Deassert SERR */ + __raw_writel(SH4_PCIINTM_SDIM, hose->reg_base + SH4_PCIINTM); + + /* Back off the IRQ for awhile */ + disable_irq(irq); + hose->serr_timer.expires = jiffies + HZ; + add_timer(&hose->serr_timer); + + return IRQ_HANDLED; +} + +static int __init sh7780_pci_setup_irqs(struct pci_channel *hose) +{ + int ret; + + /* Clear out PCI arbiter IRQs */ + __raw_writel(0, hose->reg_base + SH4_PCIAINT); + + /* Clear all error conditions */ + __raw_writew(PCI_STATUS_DETECTED_PARITY | \ + PCI_STATUS_SIG_SYSTEM_ERROR | \ + PCI_STATUS_REC_MASTER_ABORT | \ + PCI_STATUS_REC_TARGET_ABORT | \ + PCI_STATUS_SIG_TARGET_ABORT | \ + PCI_STATUS_PARITY, hose->reg_base + PCI_STATUS); + + ret = request_irq(hose->serr_irq, sh7780_pci_serr_irq, IRQF_DISABLED, + "PCI SERR interrupt", hose); + if (unlikely(ret)) { + printk(KERN_ERR "PCI: Failed hooking SERR IRQ\n"); + return ret; + } + + /* + * The PCI ERR IRQ needs to be IRQF_SHARED since all of the power + * down IRQ vectors are routed through the ERR IRQ vector. We + * only request_irq() once as there is only a single masking + * source for multiple events. + */ + ret = request_irq(hose->err_irq, sh7780_pci_err_irq, IRQF_SHARED, + "PCI ERR interrupt", hose); + if (unlikely(ret)) { + free_irq(hose->serr_irq, hose); + return ret; + } + + /* Unmask all of the arbiter IRQs. */ + __raw_writel(SH4_PCIAINT_MBKN | SH4_PCIAINT_TBTO | SH4_PCIAINT_MBTO | \ + SH4_PCIAINT_TABT | SH4_PCIAINT_MABT | SH4_PCIAINT_RDPE | \ + SH4_PCIAINT_WDPE, hose->reg_base + SH4_PCIAINTM); + + /* Unmask all of the PCI IRQs */ + __raw_writel(SH4_PCIINTM_TTADIM | SH4_PCIINTM_TMTOIM | \ + SH4_PCIINTM_MDEIM | SH4_PCIINTM_APEDIM | \ + SH4_PCIINTM_SDIM | SH4_PCIINTM_DPEITWM | \ + SH4_PCIINTM_PEDITRM | SH4_PCIINTM_TADIMM | \ + SH4_PCIINTM_MADIMM | SH4_PCIINTM_MWPDIM | \ + SH4_PCIINTM_MRDPEIM, hose->reg_base + SH4_PCIINTM); + + return ret; +} + +static inline void __init sh7780_pci_teardown_irqs(struct pci_channel *hose) +{ + free_irq(hose->err_irq, hose); + free_irq(hose->serr_irq, hose); +} + static void __init sh7780_pci66_init(struct pci_channel *hose) { unsigned int tmp; @@ -149,33 +309,12 @@ static int __init sh7780_pci_init(void) __raw_writel(((memsize - SZ_1M) & 0x1ff00000) | 1, chan->reg_base + SH4_PCILSR0); - /* Clear out PCI arbiter IRQs */ - __raw_writel(0, chan->reg_base + SH4_PCIAINT); - - /* Unmask all of the arbiter IRQs. */ - __raw_writel(SH4_PCIAINT_MBKN | SH4_PCIAINT_TBTO | SH4_PCIAINT_MBTO | \ - SH4_PCIAINT_TABT | SH4_PCIAINT_MABT | SH4_PCIAINT_RDPE | \ - SH4_PCIAINT_WDPE, chan->reg_base + SH4_PCIAINTM); - - /* Clear all error conditions */ - __raw_writew(PCI_STATUS_DETECTED_PARITY | \ - PCI_STATUS_SIG_SYSTEM_ERROR | \ - PCI_STATUS_REC_MASTER_ABORT | \ - PCI_STATUS_REC_TARGET_ABORT | \ - PCI_STATUS_SIG_TARGET_ABORT | \ - PCI_STATUS_PARITY, chan->reg_base + PCI_STATUS); - - __raw_writew(PCI_COMMAND_SERR | PCI_COMMAND_WAIT | \ - PCI_COMMAND_PARITY | PCI_COMMAND_MASTER | \ - PCI_COMMAND_MEMORY, chan->reg_base + PCI_COMMAND); - - /* Unmask all of the PCI IRQs */ - __raw_writel(SH4_PCIINTM_TTADIM | SH4_PCIINTM_TMTOIM | \ - SH4_PCIINTM_MDEIM | SH4_PCIINTM_APEDIM | \ - SH4_PCIINTM_SDIM | SH4_PCIINTM_DPEITWM | \ - SH4_PCIINTM_PEDITRM | SH4_PCIINTM_TADIMM | \ - SH4_PCIINTM_MADIMM | SH4_PCIINTM_MWPDIM | \ - SH4_PCIINTM_MRDPEIM, chan->reg_base + SH4_PCIINTM); + /* + * Hook up the ERR and SERR IRQs. + */ + ret = sh7780_pci_setup_irqs(chan); + if (unlikely(ret)) + return ret; /* * Disable the cache snoop controller for non-coherent DMA. @@ -191,6 +330,10 @@ static int __init sh7780_pci_init(void) __raw_writel(0, chan->reg_base + SH7780_PCIIOBR); __raw_writel(0, chan->reg_base + SH7780_PCIIOBMR); + __raw_writew(PCI_COMMAND_SERR | PCI_COMMAND_WAIT | \ + PCI_COMMAND_PARITY | PCI_COMMAND_MASTER | \ + PCI_COMMAND_MEMORY, chan->reg_base + PCI_COMMAND); + /* * Initialization mode complete, release the control register and * enable round robin mode to stop device overruns/starvation. @@ -200,7 +343,7 @@ static int __init sh7780_pci_init(void) ret = register_pci_controller(chan); if (unlikely(ret)) - return ret; + goto err; sh7780_pci66_init(chan); @@ -209,5 +352,9 @@ static int __init sh7780_pci_init(void) 66 : 33); return 0; + +err: + sh7780_pci_teardown_irqs(chan); + return ret; } arch_initcall(sh7780_pci_init); diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index 488331c45033..8e42dfbbe76a 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c @@ -78,6 +78,11 @@ int __devinit register_pci_controller(struct pci_channel *hose) "registering PCI controller with io_map_base unset\n"); } + /* + * Setup the ERR/PERR and SERR timers, if available. + */ + pcibios_enable_timers(hose); + /* * Scan the bus if it is register after the PCI subsystem * initialization. @@ -289,6 +294,52 @@ char * __devinit pcibios_setup(char *str) return str; } +/* + * We can't use pci_find_device() here since we are + * called from interrupt context. + */ +static void pcibios_bus_report_status(struct pci_bus *bus, + unsigned int status_mask, int warn) +{ + struct pci_dev *dev; + + list_for_each_entry(dev, &bus->devices, bus_list) { + u16 status; + + /* + * ignore host bridge - we handle + * that separately + */ + if (dev->bus->number == 0 && dev->devfn == 0) + continue; + + pci_read_config_word(dev, PCI_STATUS, &status); + if (status == 0xffff) + continue; + + if ((status & status_mask) == 0) + continue; + + /* clear the status errors */ + pci_write_config_word(dev, PCI_STATUS, status & status_mask); + + if (warn) + printk("(%s: %04X) ", pci_name(dev), status); + } + + list_for_each_entry(dev, &bus->devices, bus_list) + if (dev->subordinate) + pcibios_bus_report_status(dev->subordinate, status_mask, warn); +} + +void pcibios_report_status(unsigned int status_mask, int warn) +{ + struct pci_channel *hose; + + for (hose = hose_head; hose; hose = hose->next) + pcibios_bus_report_status(hose->bus, status_mask, warn); +} + int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine) { diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index bbd10cf79825..1de83f2161f7 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h @@ -29,9 +29,20 @@ struct pci_channel { unsigned int index; unsigned int need_domain_info; + + /* Optional error handling */ + struct timer_list err_timer, serr_timer; + unsigned int err_irq, serr_irq; }; +/* arch/sh/drivers/pci/pci.c */ 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 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); -- cgit v1.2.3 From b6c58b1d987a5795086c5c2babd8c7367d2fdb8c Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 1 Feb 2010 20:01:50 +0900 Subject: sh: Improved multi-resource handling for SH7780 PCI. The SH7780 PCI controller supports 3 different ranges of PCI memory in addition to its PCI I/O window. In the case of 29-bit mode, only 2 memory windows are supported, while in 32-bit mode all 3 are visible. This attempts to make the resource handling completely dynamic and to permit platforms to map in as many apertures as they can handle. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/fixups-dreamcast.c | 2 +- arch/sh/drivers/pci/fixups-se7751.c | 6 +-- arch/sh/drivers/pci/pci-dreamcast.c | 28 +++++------ arch/sh/drivers/pci/pci-sh5.c | 15 +++--- arch/sh/drivers/pci/pci-sh7751.c | 32 ++++++------- arch/sh/drivers/pci/pci-sh7780.c | 86 +++++++++++++++++++++++++--------- arch/sh/drivers/pci/pci-sh7780.h | 14 +----- arch/sh/drivers/pci/pci.c | 37 +++++++++------ arch/sh/include/asm/pci.h | 5 +- 9 files changed, 133 insertions(+), 92 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/drivers/pci/fixups-dreamcast.c b/arch/sh/drivers/pci/fixups-dreamcast.c index ed7f489936f1..942ef4f155f5 100644 --- a/arch/sh/drivers/pci/fixups-dreamcast.c +++ b/arch/sh/drivers/pci/fixups-dreamcast.c @@ -39,7 +39,7 @@ static void __init gapspci_fixup_resources(struct pci_dev *dev) /* * We also assume that dev->devfn == 0 */ - dev->resource[1].start = p->io_resource->start + 0x100; + dev->resource[1].start = p->resources[0].start + 0x100; dev->resource[1].end = dev->resource[1].start + 0x200 - 1; /* diff --git a/arch/sh/drivers/pci/fixups-se7751.c b/arch/sh/drivers/pci/fixups-se7751.c index 475fa9f0fe2c..a4c7d3a4efca 100644 --- a/arch/sh/drivers/pci/fixups-se7751.c +++ b/arch/sh/drivers/pci/fixups-se7751.c @@ -97,12 +97,12 @@ int pci_fixup_pcic(struct pci_channel *chan) * meaning all calls go straight through... use BUG_ON to * catch erroneous assumption. */ - BUG_ON(chan->mem_resource->start != SH7751_PCI_MEMORY_BASE); + BUG_ON(chan->resources[1].start != SH7751_PCI_MEMORY_BASE); - PCIC_WRITE(SH7751_PCIMBR, chan->mem_resource->start); + PCIC_WRITE(SH7751_PCIMBR, chan->resources[1].start); /* Set IOBR for window containing area specified in pci.h */ - PCIC_WRITE(SH7751_PCIIOBR, (chan->io_resource->start & SH7751_PCIIOBR_MASK)); + PCIC_WRITE(SH7751_PCIIOBR, (chan->resources[0].start & SH7751_PCIIOBR_MASK)); /* All done, may as well say so... */ printk("SH7751 PCI: Finished initialization of the PCI controller\n"); diff --git a/arch/sh/drivers/pci/pci-dreamcast.c b/arch/sh/drivers/pci/pci-dreamcast.c index bd5a1e50ebf6..633694193af8 100644 --- a/arch/sh/drivers/pci/pci-dreamcast.c +++ b/arch/sh/drivers/pci/pci-dreamcast.c @@ -25,25 +25,25 @@ #include #include -static struct resource gapspci_io_resource = { - .name = "GAPSPCI IO", - .start = GAPSPCI_BBA_CONFIG, - .end = GAPSPCI_BBA_CONFIG + GAPSPCI_BBA_CONFIG_SIZE - 1, - .flags = IORESOURCE_IO, -}; - -static struct resource gapspci_mem_resource = { - .name = "GAPSPCI mem", - .start = GAPSPCI_DMA_BASE, - .end = GAPSPCI_DMA_BASE + GAPSPCI_DMA_SIZE - 1, - .flags = IORESOURCE_MEM, +static struct resource gapspci_resources[] = { + { + .name = "GAPSPCI IO", + .start = GAPSPCI_BBA_CONFIG, + .end = GAPSPCI_BBA_CONFIG + GAPSPCI_BBA_CONFIG_SIZE - 1, + .flags = IORESOURCE_IO, + }, { + .name = "GAPSPCI mem", + .start = GAPSPCI_DMA_BASE, + .end = GAPSPCI_DMA_BASE + GAPSPCI_DMA_SIZE - 1, + .flags = IORESOURCE_MEM, + }, }; static struct pci_channel dreamcast_pci_controller = { .pci_ops = &gapspci_pci_ops, - .io_resource = &gapspci_io_resource, + .resources = gapspci_resources, + .nr_resources = ARRAY_SIZE(gapspci_resources), .io_offset = 0x00000000, - .mem_resource = &gapspci_mem_resource, .mem_offset = 0x00000000, }; diff --git a/arch/sh/drivers/pci/pci-sh5.c b/arch/sh/drivers/pci/pci-sh5.c index bce73faabc88..0bf296c78795 100644 --- a/arch/sh/drivers/pci/pci-sh5.c +++ b/arch/sh/drivers/pci/pci-sh5.c @@ -89,14 +89,13 @@ static irqreturn_t pcish5_serr_irq(int irq, void *dev_id) return IRQ_NONE; } -static struct resource sh5_io_resource = { /* place holder */ }; -static struct resource sh5_mem_resource = { /* place holder */ }; +static struct resource sh5_pci_resources[2]; static struct pci_channel sh5pci_controller = { .pci_ops = &sh5_pci_ops, - .mem_resource = &sh5_mem_resource, + .resources = sh5_pci_resources, + .nr_resources = ARRAY_SIZE(sh5_pci_resources), .mem_offset = 0x00000000, - .io_resource = &sh5_io_resource, .io_offset = 0x00000000, }; @@ -210,11 +209,11 @@ static int __init sh5pci_init(void) SH5PCI_WRITE(AINTM, ~0); SH5PCI_WRITE(PINTM, ~0); - sh5_io_resource.start = PCI_IO_AREA; - sh5_io_resource.end = PCI_IO_AREA + 0x10000; + sh5_pci_resources[0].start = PCI_IO_AREA; + sh5_pci_resources[0].end = PCI_IO_AREA + 0x10000; - sh5_mem_resource.start = memStart; - sh5_mem_resource.end = memStart + memSize; + sh5_pci_resources[1].start = memStart; + sh5_pci_resources[1].end = memStart + memSize; return register_pci_controller(&sh5pci_controller); } diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c index 6ad5beb524aa..17811e5d287b 100644 --- a/arch/sh/drivers/pci/pci-sh7751.c +++ b/arch/sh/drivers/pci/pci-sh7751.c @@ -44,25 +44,25 @@ static int __init __area_sdram_check(struct pci_channel *chan, return 1; } -static struct resource sh7751_io_resource = { - .name = "SH7751_IO", - .start = SH7751_PCI_IO_BASE, - .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1, - .flags = IORESOURCE_IO -}; - -static struct resource sh7751_mem_resource = { - .name = "SH7751_mem", - .start = SH7751_PCI_MEMORY_BASE, - .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1, - .flags = IORESOURCE_MEM +static struct resource sh7751_pci_resources[] = { + { + .name = "SH7751_IO", + .start = SH7751_PCI_IO_BASE, + .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1, + .flags = IORESOURCE_IO + }, { + .name = "SH7751_mem", + .start = SH7751_PCI_MEMORY_BASE, + .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1, + .flags = IORESOURCE_MEM + }, }; static struct pci_channel sh7751_pci_controller = { .pci_ops = &sh4_pci_ops, - .mem_resource = &sh7751_mem_resource, + .resources = sh7751_pci_resources, + .nr_resources = ARRAY_SIZE(sh7751_pci_resources), .mem_offset = 0x00000000, - .io_resource = &sh7751_io_resource, .io_offset = 0x00000000, .io_map_base = SH7751_PCI_IO_BASE, }; @@ -128,13 +128,13 @@ static int __init sh7751_pci_init(void) /* Set the local 16MB PCI memory space window to * the lowest PCI mapped address */ - word = chan->mem_resource->start & SH4_PCIMBR_MASK; + word = chan->resources[1].start & SH4_PCIMBR_MASK; pr_debug("PCI: Setting upper bits of Memory window to 0x%x\n", word); pci_write_reg(chan, word , SH4_PCIMBR); /* Make sure the MSB's of IO window are set to access PCI space * correctly */ - word = chan->io_resource->start & SH4_PCIIOBR_MASK; + word = chan->resources[0].start & SH4_PCIIOBR_MASK; pr_debug("PCI: Setting upper bits of IO window to 0x%x\n", word); pci_write_reg(chan, word, SH4_PCIIOBR); diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c index 86373314f458..472f67aec337 100644 --- a/arch/sh/drivers/pci/pci-sh7780.c +++ b/arch/sh/drivers/pci/pci-sh7780.c @@ -21,27 +21,40 @@ #include #include -static struct resource sh7785_io_resource = { - .name = "SH7785_IO", - .start = 0x1000, - .end = SH7780_PCI_IO_SIZE - 1, - .flags = IORESOURCE_IO -}; - -static struct resource sh7785_mem_resource = { - .name = "SH7785_mem", - .start = SH7780_PCI_MEMORY_BASE, - .end = SH7780_PCI_MEMORY_BASE + SH7780_PCI_MEM_SIZE - 1, - .flags = IORESOURCE_MEM +static struct resource sh7785_pci_resources[] = { + { + .name = "SH7785_IO", + .start = 0x1000, + .end = SZ_4M - 1, + .flags = IORESOURCE_IO, + }, { + .name = "PCI MEM 0", + .start = 0xfd000000, + .end = 0xfd000000 + SZ_16M - 1, + .flags = IORESOURCE_MEM, + }, { + .name = "PCI MEM 1", + .start = 0x10000000, + .end = 0x10000000 + SZ_64M - 1, + .flags = IORESOURCE_MEM, + }, { + /* + * 32-bit only resources must be last. + */ + .name = "PCI MEM 2", + .start = 0xc0000000, + .end = 0xc0000000 + SZ_512M - 1, + .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT, + }, }; static struct pci_channel sh7780_pci_controller = { .pci_ops = &sh4_pci_ops, - .mem_resource = &sh7785_mem_resource, - .mem_offset = 0x00000000, - .io_resource = &sh7785_io_resource, - .io_offset = 0x00000000, - .io_map_base = SH7780_PCI_IO_BASE, + .resources = sh7785_pci_resources, + .nr_resources = ARRAY_SIZE(sh7785_pci_resources), + .io_offset = 0, + .mem_offset = 0, + .io_map_base = 0xfe200000, .serr_irq = evt2irq(0xa00), .err_irq = evt2irq(0xaa0), }; @@ -231,7 +244,7 @@ static int __init sh7780_pci_init(void) size_t memsize; unsigned int id; const char *type; - int ret; + int ret, i; printk(KERN_NOTICE "PCI: Starting intialization.\n"); @@ -279,8 +292,6 @@ static int __init sh7780_pci_init(void) */ __raw_writel(SH4_PCICR_PREFIX, chan->reg_base + SH4_PCICR); - __raw_writel(0, chan->reg_base + PCI_BASE_ADDRESS_0); - memphys = __pa(memory_start); memsize = roundup_pow_of_two(memory_end - memory_start); @@ -324,9 +335,40 @@ static int __init sh7780_pci_init(void) __raw_writel(0, chan->reg_base + SH7780_PCICSCR1); __raw_writel(0, chan->reg_base + SH7780_PCICSAR1); - __raw_writel(0xfd000000, chan->reg_base + SH7780_PCIMBR0); - __raw_writel(0x00fc0000, chan->reg_base + SH7780_PCIMBMR0); + /* + * Setup the memory BARs + */ + for (i = 0; i < chan->nr_resources; i++) { + struct resource *res = chan->resources + (i + 1); + resource_size_t size; + + if (unlikely(res->flags & IORESOURCE_IO)) + continue; + + /* + * Make sure we're in the right physical addressing mode + * for dealing with the resource. + */ + if ((res->flags & IORESOURCE_MEM_32BIT) && __in_29bit_mode()) { + chan->nr_resources--; + continue; + } + size = resource_size(res); + + /* + * The MBMR mask is calculated in units of 256kB, which + * keeps things pretty simple. + */ + __raw_writel(((roundup_pow_of_two(size) / SZ_256K) - 1) << 18, + chan->reg_base + SH7780_PCIMBMR(i)); + __raw_writel(res->start, chan->reg_base + SH7780_PCIMBR(i)); + } + + /* + * And I/O. + */ + __raw_writel(0, chan->reg_base + PCI_BASE_ADDRESS_0); __raw_writel(0, chan->reg_base + SH7780_PCIIOBR); __raw_writel(0, chan->reg_base + SH7780_PCIIOBMR); diff --git a/arch/sh/drivers/pci/pci-sh7780.h b/arch/sh/drivers/pci/pci-sh7780.h index dee069c3865d..205dcbefe275 100644 --- a/arch/sh/drivers/pci/pci-sh7780.h +++ b/arch/sh/drivers/pci/pci-sh7780.h @@ -26,12 +26,6 @@ #define SH7780_PCI_CONFIG_BASE 0xFD000000 /* Config space base addr */ #define SH7780_PCI_CONFIG_SIZE 0x01000000 /* Config space size */ -#define SH7780_PCI_MEMORY_BASE 0xFD000000 /* Memory space base addr */ -#define SH7780_PCI_MEM_SIZE 0x01000000 /* Size of Memory window */ - -#define SH7780_PCI_IO_BASE 0xFE200000 /* IO space base address */ -#define SH7780_PCI_IO_SIZE 0x00400000 /* Size of IO window */ - #define SH7780_PCIREG_BASE 0xFE040000 /* PCI regs base address */ /* SH7780 PCI Config Registers */ @@ -46,12 +40,8 @@ #define SH7780_PCIPINT 0x1CC /* Power Mgmnt Int. Register */ #define SH7780_PCIPINTM 0x1D0 /* Power Mgmnt Mask Register */ -#define SH7780_PCIMBR0 0x1E0 -#define SH7780_PCIMBMR0 0x1E4 -#define SH7780_PCIMBR1 0x1E8 -#define SH7780_PCIMBMR1 0x1EC -#define SH7780_PCIMBR2 0x1F0 -#define SH7780_PCIMBMR2 0x1F4 +#define SH7780_PCIMBR(x) (0x1E0 + ((x) * 8)) +#define SH7780_PCIMBMR(x) (0x1E4 + ((x) * 8)) #define SH7780_PCIIOBR 0x1F8 #define SH7780_PCIIOBMR 0x1FC #define SH7780_PCICSCR0 0x210 /* Cache Snoop1 Cnt. Register */ diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index 8e42dfbbe76a..f4a69833fce2 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c @@ -60,11 +60,18 @@ static DEFINE_MUTEX(pci_scan_mutex); int __devinit register_pci_controller(struct pci_channel *hose) { - if (request_resource(&iomem_resource, hose->mem_resource) < 0) - goto out; - if (request_resource(&ioport_resource, hose->io_resource) < 0) { - release_resource(hose->mem_resource); - goto out; + int i; + + for (i = 0; i < hose->nr_resources; i++) { + struct resource *res = hose->resources + i; + + if (res->flags & IORESOURCE_IO) { + if (request_resource(&ioport_resource, res) < 0) + goto out; + } else { + if (request_resource(&iomem_resource, res) < 0) + goto out; + } } *hose_tail = hose; @@ -96,6 +103,9 @@ int __devinit register_pci_controller(struct pci_channel *hose) return 0; out: + for (--i; i >= 0; i--) + release_resource(&hose->resources[i]); + printk(KERN_WARNING "Skipping PCI bus scan due to resource conflict\n"); return -1; } @@ -149,11 +159,13 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus) { struct pci_dev *dev = bus->self; struct list_head *ln; - struct pci_channel *chan = bus->sysdata; + struct pci_channel *hose = bus->sysdata; if (!dev) { - bus->resource[0] = chan->io_resource; - bus->resource[1] = chan->mem_resource; + int i; + + for (i = 0; i < hose->nr_resources; i++) + bus->resource[i] = hose->resources + i; } for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) { @@ -174,21 +186,18 @@ void pcibios_align_resource(void *data, struct resource *res, resource_size_t size, resource_size_t align) { struct pci_dev *dev = data; - struct pci_channel *chan = dev->sysdata; + struct pci_channel *hose = dev->sysdata; resource_size_t start = res->start; if (res->flags & IORESOURCE_IO) { - if (start < PCIBIOS_MIN_IO + chan->io_resource->start) - start = PCIBIOS_MIN_IO + chan->io_resource->start; + if (start < PCIBIOS_MIN_IO + hose->resources[0].start) + start = PCIBIOS_MIN_IO + hose->resources[0].start; /* * Put everything into 0x00-0xff region modulo 0x400. */ if (start & 0x300) start = (start + 0x3ff) & ~0x3ff; - } else if (res->flags & IORESOURCE_MEM) { - if (start < PCIBIOS_MIN_MEM + chan->mem_resource->start) - start = PCIBIOS_MIN_MEM + chan->mem_resource->start; } res->start = start; diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index 1de83f2161f7..6d762cca2312 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h @@ -18,8 +18,9 @@ struct pci_channel { 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; -- cgit v1.2.3 From b4f74767a04e175c028336e06507fcc05f5a8618 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Tue, 19 Jan 2010 07:31:13 +0000 Subject: sh: add high impedance mode management for SIUA pins on sh7722 This improves power management for the SIUA controller on sh7722. Similar patches might be desired for other SIU-enabled SH platforms. Signed-off-by: Guennadi Liakhovetski Acked-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/pinmux-sh7722.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/kernel/cpu/sh4a/pinmux-sh7722.c b/arch/sh/kernel/cpu/sh4a/pinmux-sh7722.c index cb9d07bd59f8..0688a7502f86 100644 --- a/arch/sh/kernel/cpu/sh4a/pinmux-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/pinmux-sh7722.c @@ -278,6 +278,7 @@ enum { HIZA8_LCDC, HIZA8_HIZ, HIZA7_LCDC, HIZA7_HIZ, HIZA6_LCDC, HIZA6_HIZ, + HIZB4_SIUA, HIZB4_HIZ, HIZB1_VIO, HIZB1_HIZ, HIZB0_VIO, HIZB0_HIZ, HIZC15_IRQ7, HIZC15_HIZ, @@ -546,7 +547,7 @@ static pinmux_enum_t pinmux_data[] = { PINMUX_DATA(VIO_VD2_MARK, PSE3_VIO, MSELB9_VIO2, HIZB0_VIO, FOE_VIO_VD2), PINMUX_DATA(VIO_HD2_MARK, PSE3_VIO, MSELB9_VIO2, - HIZB1_VIO, HIZB1_VIO, FCE_VIO_HD2), + HIZB1_VIO, FCE_VIO_HD2), PINMUX_DATA(VIO_CLK2_MARK, PSE3_VIO, MSELB9_VIO2, HIZB1_VIO, FRB_VIO_CLK2), @@ -658,14 +659,14 @@ static pinmux_enum_t pinmux_data[] = { PINMUX_DATA(SDHICLK_MARK, SDHICLK), /* SIU - Port A */ - PINMUX_DATA(SIUAOLR_MARK, PSC13_SIUAOLR, SIUAOLR_SIOF1_SYNC), - PINMUX_DATA(SIUAOBT_MARK, PSC14_SIUAOBT, SIUAOBT_SIOF1_SCK), - PINMUX_DATA(SIUAISLD_MARK, PSC15_SIUAISLD, SIUAISLD_SIOF1_RXD), - PINMUX_DATA(SIUAILR_MARK, PSC11_SIUAILR, SIUAILR_SIOF1_SS2), - PINMUX_DATA(SIUAIBT_MARK, PSC12_SIUAIBT, SIUAIBT_SIOF1_SS1), - PINMUX_DATA(SIUAOSLD_MARK, PSB0_SIUAOSLD, SIUAOSLD_SIOF1_TXD), - PINMUX_DATA(SIUMCKA_MARK, PSE11_SIUMCKA_SIOF1_MCK, PSB1_SIUMCKA, PTK0), - PINMUX_DATA(SIUFCKA_MARK, PSE11_SIUFCKA, PTK0), + PINMUX_DATA(SIUAOLR_MARK, PSC13_SIUAOLR, HIZB4_SIUA, SIUAOLR_SIOF1_SYNC), + PINMUX_DATA(SIUAOBT_MARK, PSC14_SIUAOBT, HIZB4_SIUA, SIUAOBT_SIOF1_SCK), + PINMUX_DATA(SIUAISLD_MARK, PSC15_SIUAISLD, HIZB4_SIUA, SIUAISLD_SIOF1_RXD), + PINMUX_DATA(SIUAILR_MARK, PSC11_SIUAILR, HIZB4_SIUA, SIUAILR_SIOF1_SS2), + PINMUX_DATA(SIUAIBT_MARK, PSC12_SIUAIBT, HIZB4_SIUA, SIUAIBT_SIOF1_SS1), + PINMUX_DATA(SIUAOSLD_MARK, PSB0_SIUAOSLD, HIZB4_SIUA, SIUAOSLD_SIOF1_TXD), + PINMUX_DATA(SIUMCKA_MARK, PSE11_SIUMCKA_SIOF1_MCK, HIZB4_SIUA, PSB1_SIUMCKA, PTK0), + PINMUX_DATA(SIUFCKA_MARK, PSE11_SIUFCKA, HIZB4_SIUA, PTK0), /* SIU - Port B */ PINMUX_DATA(SIUBOLR_MARK, PSB11_SIUBOLR, SIOSTRB1_SIUBOLR), @@ -1612,7 +1613,7 @@ static struct pinmux_cfg_reg pinmux_config_regs[] = { 0, 0, 0, 0, 0, 0, - 0, 0, + HIZB4_SIUA, HIZB4_HIZ, 0, 0, 0, 0, HIZB1_VIO, HIZB1_HIZ, -- cgit v1.2.3 From c7a967273a539a9a38413753c58125e777e2d30d Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 2 Feb 2010 17:38:04 +0900 Subject: sh: mach-se: Convert SH7724 solution engine FPGA to sparseirq. This uses the new create_irq_nr() to build up the FPGA's desired virtual IRQ mapping and permits us to finally flip on sparseirq for this board. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 2 +- arch/sh/boards/mach-se/7724/irq.c | 38 +++++++++++++++++++++++++++----------- 2 files changed, 28 insertions(+), 12 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index bae53831c06b..0f023bb62f99 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -731,7 +731,7 @@ config GUSA_RB config SPARSE_IRQ def_bool y depends on SUPERH32 && !SH_DREAMCAST && !SH_HIGHLANDER && \ - !SH_RTS7751R2D && !HD64461 && !SH_7724_SOLUTION_ENGINE + !SH_RTS7751R2D && !HD64461 help This enables support for sparse irqs. This is useful in general as most CPUs have a fairly sparse array of IRQ vectors, which diff --git a/arch/sh/boards/mach-se/7724/irq.c b/arch/sh/boards/mach-se/7724/irq.c index e5e021a7d1e6..0942be2daef6 100644 --- a/arch/sh/boards/mach-se/7724/irq.c +++ b/arch/sh/boards/mach-se/7724/irq.c @@ -93,18 +93,15 @@ static void se7724_irq_demux(unsigned int irq, struct irq_desc *desc) { struct fpga_irq set = get_fpga_irq(irq); unsigned short intv = __raw_readw(set.sraddr); - struct irq_desc *ext_desc; unsigned int ext_irq = set.base; intv &= set.mask; - while (intv) { - if (intv & 0x0001) { - ext_desc = irq_desc + ext_irq; - handle_level_irq(ext_irq, ext_desc); - } - intv >>= 1; - ext_irq++; + for (; intv; intv >>= 1, ext_irq++) { + if (!(intv & 1)) + continue; + + generic_handle_irq(ext_irq); } } @@ -113,7 +110,7 @@ static void se7724_irq_demux(unsigned int irq, struct irq_desc *desc) */ void __init init_se7724_IRQ(void) { - int i; + int i, nid = cpu_to_node(boot_cpu_data); __raw_writew(0xffff, IRQ0_MR); /* mask all */ __raw_writew(0xffff, IRQ1_MR); /* mask all */ @@ -123,10 +120,29 @@ void __init init_se7724_IRQ(void) __raw_writew(0x0000, IRQ2_SR); /* clear irq */ __raw_writew(0x002a, IRQ_MODE); /* set irq type */ - for (i = 0; i < SE7724_FPGA_IRQ_NR; i++) - set_irq_chip_and_handler_name(SE7724_FPGA_IRQ_BASE + i, + for (i = 0; i < SE7724_FPGA_IRQ_NR; i++) { + int irq, wanted; + + wanted = SE7724_FPGA_IRQ_BASE + i; + + irq = create_irq_nr(wanted, nid); + if (unlikely(irq == 0)) { + pr_err("%s: failed hooking irq %d for FPGA\n", + __func__, wanted); + return; + } + + if (unlikely(irq != wanted)) { + pr_err("%s: got irq %d but wanted %d, bailing.\n", + __func__, irq, wanted); + destroy_irq(irq); + return; + } + + set_irq_chip_and_handler_name(irq, &se7724_irq_chip, handle_level_irq, "level"); + } set_irq_chained_handler(IRQ0_IRQ, se7724_irq_demux); set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW); -- cgit v1.2.3 From 6eb6f98396f7bd653d8fb15b06364c8c7d70e22c Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 2 Feb 2010 17:48:17 +0900 Subject: sh: hd6446x: Convert to sparseirq. Follows the se7724 change and converts the hd64461 IRQ handling to sparseirq. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 2 +- arch/sh/cchips/hd6446x/hd64461.c | 21 +++++++++++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 0f023bb62f99..9e565d962dc0 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -731,7 +731,7 @@ config GUSA_RB config SPARSE_IRQ def_bool y depends on SUPERH32 && !SH_DREAMCAST && !SH_HIGHLANDER && \ - !SH_RTS7751R2D && !HD64461 + !SH_RTS7751R2D help This enables support for sparse irqs. This is useful in general as most CPUs have a fairly sparse array of IRQ vectors, which diff --git a/arch/sh/cchips/hd6446x/hd64461.c b/arch/sh/cchips/hd6446x/hd64461.c index cbfedfb42e04..b447091fc064 100644 --- a/arch/sh/cchips/hd6446x/hd64461.c +++ b/arch/sh/cchips/hd6446x/hd64461.c @@ -73,7 +73,7 @@ static void hd64461_irq_demux(unsigned int irq, struct irq_desc *desc) int __init setup_hd64461(void) { - int i; + int i, nid = cpu_to_node(boot_cpu_data); if (!MACH_HD64461) return 0; @@ -90,9 +90,26 @@ int __init setup_hd64461(void) __raw_writew(0xffff, HD64461_NIMR); /* IRQ 80 -> 95 belongs to HD64461 */ - for (i = HD64461_IRQBASE; i < HD64461_IRQBASE + 16; i++) + for (i = HD64461_IRQBASE; i < HD64461_IRQBASE + 16; i++) { + unsigned int irq; + + irq = create_irq_nr(i, nid); + if (unlikely(irq == 0)) { + pr_err("%s: failed hooking irq %d for HD64461\n", + __func__, i); + return -EBUSY; + } + + if (unlikely(irq != i)) { + pr_err("%s: got irq %d but wanted %d, bailing.\n", + __func__, irq, i); + destroy_irq(irq); + return -EINVAL; + } + set_irq_chip_and_handler(i, &hd64461_irq_chip, handle_level_irq); + } set_irq_chained_handler(CONFIG_HD64461_IRQ, hd64461_irq_demux); set_irq_type(CONFIG_HD64461_IRQ, IRQ_TYPE_LEVEL_LOW); -- cgit v1.2.3 From deb9b22b8968fa0166d89c8ad1346e816cf1aec4 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 2 Feb 2010 18:01:55 +0900 Subject: sh: mach-dreamcast: Convert to sparseirq. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 3 +-- arch/sh/boards/mach-dreamcast/irq.c | 27 +++++++++++++++++++++++++++ arch/sh/boards/mach-dreamcast/setup.c | 18 +----------------- arch/sh/include/mach-dreamcast/mach/sysasic.h | 5 +++++ 4 files changed, 34 insertions(+), 19 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 9e565d962dc0..3b3c036cbc30 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -730,8 +730,7 @@ config GUSA_RB config SPARSE_IRQ def_bool y - depends on SUPERH32 && !SH_DREAMCAST && !SH_HIGHLANDER && \ - !SH_RTS7751R2D + depends on SUPERH32 && !SH_HIGHLANDER && !SH_RTS7751R2D help This enables support for sparse irqs. This is useful in general as most CPUs have a fairly sparse array of IRQ vectors, which diff --git a/arch/sh/boards/mach-dreamcast/irq.c b/arch/sh/boards/mach-dreamcast/irq.c index f55fc8e795e9..d932667410ab 100644 --- a/arch/sh/boards/mach-dreamcast/irq.c +++ b/arch/sh/boards/mach-dreamcast/irq.c @@ -135,3 +135,30 @@ int systemasic_irq_demux(int irq) /* Not reached */ return irq; } + +void systemasic_irq_init(void) +{ + int i, nid = cpu_to_node(boot_cpu_data); + + /* Assign all virtual IRQs to the System ASIC int. handler */ + for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++) { + unsigned int irq; + + irq = create_irq_nr(i, nid); + if (unlikely(irq == 0)) { + pr_err("%s: failed hooking irq %d for systemasic\n", + __func__, i); + return; + } + + if (unlikely(irq != i)) { + pr_err("%s: got irq %d but wanted %d, bailing.\n", + __func__, irq, i); + destroy_irq(irq); + return; + } + + set_irq_chip_and_handler(i, &systemasic_int, + handle_level_irq); + } +} diff --git a/arch/sh/boards/mach-dreamcast/setup.c b/arch/sh/boards/mach-dreamcast/setup.c index a4b7402d6176..ad1a4db72e04 100644 --- a/arch/sh/boards/mach-dreamcast/setup.c +++ b/arch/sh/boards/mach-dreamcast/setup.c @@ -28,25 +28,8 @@ #include #include -extern struct irq_chip systemasic_int; -extern void aica_time_init(void); -extern int systemasic_irq_demux(int); - static void __init dreamcast_setup(char **cmdline_p) { - int i; - - /* Mask all hardware events */ - /* XXX */ - - /* Acknowledge any previous events */ - /* XXX */ - - /* Assign all virtual IRQs to the System ASIC int. handler */ - for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++) - set_irq_chip_and_handler(i, &systemasic_int, - handle_level_irq); - board_time_init = aica_time_init; } @@ -54,4 +37,5 @@ static struct sh_machine_vector mv_dreamcast __initmv = { .mv_name = "Sega Dreamcast", .mv_setup = dreamcast_setup, .mv_irq_demux = systemasic_irq_demux, + .mv_init_irq = systemasic_irq_init, }; diff --git a/arch/sh/include/mach-dreamcast/mach/sysasic.h b/arch/sh/include/mach-dreamcast/mach/sysasic.h index f33426608a87..58f710e1ebc2 100644 --- a/arch/sh/include/mach-dreamcast/mach/sysasic.h +++ b/arch/sh/include/mach-dreamcast/mach/sysasic.h @@ -39,5 +39,10 @@ #define HW_EVENT_IRQ_MAX (HW_EVENT_IRQ_BASE + 95) +/* arch/sh/boards/mach-dreamcast/irq.c */ +extern int systemasic_irq_demux(int); +extern void systemasic_irq_init(void); +extern void aica_time_init(void); + #endif /* __ASM_SH_DREAMCAST_SYSASIC_H */ -- cgit v1.2.3 From 4b842c8571240d1173eaf00e114cc5cc160f1722 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 2 Feb 2010 19:15:17 +0900 Subject: sh: enable sparseirq for highlander and r2d. highlander and r2d are the only remaining ones that were blocking sparseirq being turned on by default, but it turns out that they already work fine with it by virtue of register_intc_controller(). As such, we can kill off the dependencies and turn it on by default. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 3b3c036cbc30..7354e8da3902 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -87,6 +87,10 @@ config GENERIC_IRQ_PROBE config IRQ_PER_CPU def_bool y +config SPARSE_IRQ + def_bool y + depends on SUPERH32 + config GENERIC_GPIO def_bool n @@ -728,18 +732,6 @@ config GUSA_RB LLSC, this should be more efficient than the other alternative of disabling interrupts around the atomic sequence. -config SPARSE_IRQ - def_bool y - depends on SUPERH32 && !SH_HIGHLANDER && !SH_RTS7751R2D - help - This enables support for sparse irqs. This is useful in general - as most CPUs have a fairly sparse array of IRQ vectors, which - the irq_desc then maps directly on to. Systems with a high - number of off-chip IRQs will want to treat this as - experimental until they have been independently verified. - - If you don't know what to do here, say N. - endmenu menu "Boot options" -- cgit v1.2.3 From 37feecb0ae8c29b713b957c053b05ad10c42c73b Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 2 Feb 2010 19:17:42 +0900 Subject: sh: Disable generic IRQ probing. IRQ autoprobing hasn't actually worked for us at all since very early in 2.6, but no one seems to have noticed given that none of the drivers that use it see much testing. yenta_socket is the odd one out, and that depends on PCI IRQs which are fixed on all SH platforms anyways. Consequently, turning off autoprobing fixes up crashes triggered by yenta_socket and at least gets it working again on r7785rp. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 3 --- 1 file changed, 3 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 7354e8da3902..05cef5061293 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -81,9 +81,6 @@ config GENERIC_HARDIRQS config GENERIC_HARDIRQS_NO__DO_IRQ def_bool y -config GENERIC_IRQ_PROBE - def_bool y - config IRQ_PER_CPU def_bool y -- cgit v1.2.3 From 9ad62ec4f752c82b39aa5927f23d894b46ae10b9 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 3 Feb 2010 16:46:20 +0900 Subject: sh: Fix up early PCI PERR/SERR IRQ handling. This adds support for handling early PERR/SERR triggering in between controller registration and the initial bus scan. Buggy cards end up asserting these as soon as the M66EN scan is undertaken, resulting in an early crash. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/common.c | 51 +++++++++++++++++++++++++++------------- arch/sh/drivers/pci/pci-sh7780.c | 2 +- arch/sh/drivers/pci/pci.c | 51 +++++++++++++++++++++++++++++++++------- arch/sh/include/asm/pci.h | 12 ++++++++++ 4 files changed, 90 insertions(+), 26 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/drivers/pci/common.c b/arch/sh/drivers/pci/common.c index 25aec005da18..dbf138199871 100644 --- a/arch/sh/drivers/pci/common.c +++ b/arch/sh/drivers/pci/common.c @@ -3,29 +3,48 @@ #include #include -static int __init -early_read_config_word(struct pci_channel *hose, - int top_bus, int bus, int devfn, int offset, u16 *value) +/* + * These functions are used early on before PCI scanning is done + * and all of the pci_dev and pci_bus structures have been created. + */ +static struct pci_dev *fake_pci_dev(struct pci_channel *hose, + int top_bus, int busnr, int devfn) { - struct pci_dev fake_dev; - struct pci_bus fake_bus; + static struct pci_dev dev; + static struct pci_bus bus; - fake_dev.bus = &fake_bus; - fake_dev.sysdata = hose; - fake_dev.devfn = devfn; - fake_bus.number = bus; - fake_bus.sysdata = hose; - fake_bus.ops = hose->pci_ops; + dev.bus = &bus; + dev.sysdata = hose; + dev.devfn = devfn; + bus.number = busnr; + bus.sysdata = hose; + bus.ops = hose->pci_ops; - if (bus != top_bus) + if(busnr != top_bus) /* Fake a parent bus structure. */ - fake_bus.parent = &fake_bus; + bus.parent = &bus; else - fake_bus.parent = NULL; + bus.parent = NULL; - return pci_read_config_word(&fake_dev, offset, value); + return &dev; } +#define EARLY_PCI_OP(rw, size, type) \ +int __init early_##rw##_config_##size(struct pci_channel *hose, \ + int top_bus, int bus, int devfn, int offset, type value) \ +{ \ + return pci_##rw##_config_##size( \ + fake_pci_dev(hose, top_bus, bus, devfn), \ + offset, value); \ +} + +EARLY_PCI_OP(read, byte, u8 *) +EARLY_PCI_OP(read, word, u16 *) +EARLY_PCI_OP(read, dword, u32 *) +EARLY_PCI_OP(write, byte, u8) +EARLY_PCI_OP(write, word, u16) +EARLY_PCI_OP(write, dword, u32) + int __init pci_is_66mhz_capable(struct pci_channel *hose, int top_bus, int current_bus) { @@ -133,7 +152,7 @@ unsigned int pcibios_handle_status_errors(unsigned long addr, /* Now back off of the IRQ for awhile */ if (hose->err_irq) { - disable_irq(hose->err_irq); + disable_irq_nosync(hose->err_irq); hose->err_timer.expires = jiffies + HZ; add_timer(&hose->err_timer); } diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c index 472f67aec337..1e147f445c1a 100644 --- a/arch/sh/drivers/pci/pci-sh7780.c +++ b/arch/sh/drivers/pci/pci-sh7780.c @@ -150,7 +150,7 @@ static irqreturn_t sh7780_pci_serr_irq(int irq, void *dev_id) __raw_writel(SH4_PCIINTM_SDIM, hose->reg_base + SH4_PCIINTM); /* Back off the IRQ for awhile */ - disable_irq(irq); + disable_irq_nosync(irq); hose->serr_timer.expires = jiffies + HZ; add_timer(&hose->serr_timer); diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index f4a69833fce2..41d8f014f1df 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c @@ -204,7 +204,7 @@ void pcibios_align_resource(void *data, struct resource *res, } void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, - struct resource *res) + struct resource *res) { struct pci_channel *hose = dev->sysdata; unsigned long offset = 0; @@ -218,9 +218,8 @@ void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, region->end = res->end - offset; } -void __devinit -pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, - struct pci_bus_region *region) +void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, + struct pci_bus_region *region) { struct pci_channel *hose = dev->sysdata; unsigned long offset = 0; @@ -303,12 +302,41 @@ char * __devinit pcibios_setup(char *str) return str; } +static void __init +pcibios_bus_report_status_early(struct pci_channel *hose, + int top_bus, int current_bus, + unsigned int status_mask, int warn) +{ + unsigned int pci_devfn; + u16 status; + int ret; + + for (pci_devfn = 0; pci_devfn < 0xff; pci_devfn++) { + if (PCI_FUNC(pci_devfn)) + continue; + ret = early_read_config_word(hose, top_bus, current_bus, + pci_devfn, PCI_STATUS, &status); + if (ret != PCIBIOS_SUCCESSFUL) + continue; + if (status == 0xffff) + continue; + + early_write_config_word(hose, top_bus, current_bus, + pci_devfn, PCI_STATUS, + status & status_mask); + if (warn) + printk("(%02x:%02x: %04X) ", current_bus, + pci_devfn, status); + } +} + /* * We can't use pci_find_device() here since we are * called from interrupt context. */ -static void pcibios_bus_report_status(struct pci_bus *bus, - unsigned int status_mask, int warn) +static void __init_refok +pcibios_bus_report_status(struct pci_bus *bus, unsigned int status_mask, + int warn) { struct pci_dev *dev; @@ -341,12 +369,17 @@ static void pcibios_bus_report_status(struct pci_bus *bus, pcibios_bus_report_status(dev->subordinate, status_mask, warn); } -void pcibios_report_status(unsigned int status_mask, int warn) +void __init_refok pcibios_report_status(unsigned int status_mask, int warn) { struct pci_channel *hose; - for (hose = hose_head; hose; hose = hose->next) - pcibios_bus_report_status(hose->bus, status_mask, warn); + for (hose = hose_head; hose; hose = hose->next) { + if (unlikely(!hose->bus)) + pcibios_bus_report_status_early(hose, hose_head->index, + hose->index, status_mask, warn); + else + pcibios_bus_report_status(hose->bus, status_mask, warn); + } } int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index 6d762cca2312..1042f7f0a48b 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h @@ -41,6 +41,18 @@ 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); -- cgit v1.2.3 From 3b0be1a4f2f7d8280574aa6e5eac2dd3dd57e2b7 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 5 Feb 2010 16:11:25 +0900 Subject: sh: Fix an off-by-1 in SH7780 PCIC memory resource mapping. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/pci-sh7780.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c index 1e147f445c1a..ffdcbf10b95e 100644 --- a/arch/sh/drivers/pci/pci-sh7780.c +++ b/arch/sh/drivers/pci/pci-sh7780.c @@ -23,7 +23,7 @@ static struct resource sh7785_pci_resources[] = { { - .name = "SH7785_IO", + .name = "PCI IO", .start = 0x1000, .end = SZ_4M - 1, .flags = IORESOURCE_IO, @@ -338,8 +338,8 @@ static int __init sh7780_pci_init(void) /* * Setup the memory BARs */ - for (i = 0; i < chan->nr_resources; i++) { - struct resource *res = chan->resources + (i + 1); + for (i = 1; i < chan->nr_resources; i++) { + struct resource *res = chan->resources + i; resource_size_t size; if (unlikely(res->flags & IORESOURCE_IO)) @@ -361,8 +361,8 @@ static int __init sh7780_pci_init(void) * keeps things pretty simple. */ __raw_writel(((roundup_pow_of_two(size) / SZ_256K) - 1) << 18, - chan->reg_base + SH7780_PCIMBMR(i)); - __raw_writel(res->start, chan->reg_base + SH7780_PCIMBR(i)); + chan->reg_base + SH7780_PCIMBMR(i - 1)); + __raw_writel(res->start, chan->reg_base + SH7780_PCIMBR(i - 1)); } /* -- cgit v1.2.3 From b06ede84dd1473dec7c6af03a41c8d04d2fee437 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 5 Feb 2010 17:45:14 +0900 Subject: sh: Fix up hp6xx build. With the sparseirq conversion there was a stray irq_desc reference left over, this tidies it up and brings the demuxer in line with what the solution engine boards are doing. Signed-off-by: Paul Mundt --- arch/sh/cchips/hd6446x/hd64461.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/cchips/hd6446x/hd64461.c b/arch/sh/cchips/hd6446x/hd64461.c index b447091fc064..bcb31ae84a51 100644 --- a/arch/sh/cchips/hd6446x/hd64461.c +++ b/arch/sh/cchips/hd6446x/hd64461.c @@ -56,18 +56,15 @@ static struct irq_chip hd64461_irq_chip = { static void hd64461_irq_demux(unsigned int irq, struct irq_desc *desc) { unsigned short intv = __raw_readw(HD64461_NIRR); - struct irq_desc *ext_desc; unsigned int ext_irq = HD64461_IRQBASE; intv &= (1 << HD64461_IRQ_NUM) - 1; - while (intv) { - if (intv & 1) { - ext_desc = irq_desc + ext_irq; - handle_level_irq(ext_irq, ext_desc); - } - intv >>= 1; - ext_irq++; + for (; intv; intv >>= 1, ext_irq++) { + if (!(intv & 1)) + continue; + + generic_handle_irq(ext_irq); } } -- cgit v1.2.3 From c9334f6067dbe0380141fc75b122e0a533878838 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Mon, 25 Jan 2010 11:42:23 -0600 Subject: sh: add mm API for DMA to vmalloc/vmap areas Signed-off-by: James Bottomley --- arch/sh/include/asm/cacheflush.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/cacheflush.h b/arch/sh/include/asm/cacheflush.h index dda96eb3e7c0..da3ebec921a7 100644 --- a/arch/sh/include/asm/cacheflush.h +++ b/arch/sh/include/asm/cacheflush.h @@ -63,6 +63,14 @@ static inline void flush_anon_page(struct vm_area_struct *vma, 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) -- cgit v1.2.3 From 623b4ac4bf9e767991c66e29b47dd4b19458fb42 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 3 Feb 2010 14:44:12 +0000 Subject: sh: fix Transfer Size calculation in both DMA drivers Both the original arch/sh/drivers/dma/dma-sh.c and the new SH dmaengine drivers do not take into account bits 3:2 of the Transfer Size field in the CHCR register, besides, bit-field defines set bit 2, but the mask only passes bits 1:0 through. TS_16BLK and TS_32BLK macros are bogus too. This patch fixes all these issues for sh7722 and sh7724, other CPUs stay unchanged and might need to be fixed too. Signed-off-by: Guennadi Liakhovetski Acked-by: Dan Williams Signed-off-by: Paul Mundt --- arch/sh/drivers/dma/dma-sh.c | 5 +- arch/sh/include/asm/dma-sh.h | 2 +- arch/sh/include/cpu-sh3/cpu/dma.h | 20 ++++--- arch/sh/include/cpu-sh4/cpu/dma-sh4a.h | 97 +++++++++++++++++++++++++--------- arch/sh/include/cpu-sh4/cpu/dma.h | 35 ++++++------ drivers/dma/shdma.c | 6 ++- 6 files changed, 114 insertions(+), 51 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/drivers/dma/dma-sh.c b/arch/sh/drivers/dma/dma-sh.c index 37fb5b8bbc3f..31830cb0af89 100644 --- a/arch/sh/drivers/dma/dma-sh.c +++ b/arch/sh/drivers/dma/dma-sh.c @@ -52,11 +52,14 @@ static inline unsigned int get_dmte_irq(unsigned int chan) * * iterations to complete the transfer. */ +static unsigned int ts_shift[] = TS_SHIFT; static inline unsigned int calc_xmit_shift(struct dma_channel *chan) { u32 chcr = ctrl_inl(dma_base_addr[chan->chan] + CHCR); + int cnt = ((chcr & CHCR_TS_LOW_MASK) >> CHCR_TS_LOW_SHIFT) | + ((chcr & CHCR_TS_HIGH_MASK) >> CHCR_TS_HIGH_SHIFT); - return ts_shift[(chcr & CHCR_TS_MASK)>>CHCR_TS_SHIFT]; + return ts_shift[cnt]; } /* diff --git a/arch/sh/include/asm/dma-sh.h b/arch/sh/include/asm/dma-sh.h index 78eed3e0bdf5..01d2fc72551b 100644 --- a/arch/sh/include/asm/dma-sh.h +++ b/arch/sh/include/asm/dma-sh.h @@ -83,7 +83,7 @@ static int dmte_irq_map[] __maybe_unused = { * 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 = { diff --git a/arch/sh/include/cpu-sh3/cpu/dma.h b/arch/sh/include/cpu-sh3/cpu/dma.h index 0ea15f3f2363..207811a7a650 100644 --- a/arch/sh/include/cpu-sh3/cpu/dma.h +++ b/arch/sh/include/cpu-sh3/cpu/dma.h @@ -20,8 +20,10 @@ #define TS_32 0x00000010 #define TS_128 0x00000018 -#define CHCR_TS_MASK 0x18 -#define CHCR_TS_SHIFT 3 +#define CHCR_TS_LOW_MASK 0x18 +#define CHCR_TS_LOW_SHIFT 3 +#define CHCR_TS_HIGH_MASK 0 +#define CHCR_TS_HIGH_SHIFT 0 #define DMAOR_INIT DMAOR_DME @@ -36,11 +38,13 @@ enum { XMIT_SZ_128BIT, }; -static unsigned int ts_shift[] __maybe_unused = { - [XMIT_SZ_8BIT] = 0, - [XMIT_SZ_16BIT] = 1, - [XMIT_SZ_32BIT] = 2, - [XMIT_SZ_128BIT] = 4, -}; +#define TS_SHIFT { \ + [XMIT_SZ_8BIT] = 0, \ + [XMIT_SZ_16BIT] = 1, \ + [XMIT_SZ_32BIT] = 2, \ + [XMIT_SZ_128BIT] = 4, \ +} + +#define TS_INDEX2VAL(i) (((i) & 3) << CHCR_TS_LOW_SHIFT) #endif /* __ASM_CPU_SH3_DMA_H */ diff --git a/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h b/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h index c4ed660c14cf..cc1cf3e8f163 100644 --- a/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h +++ b/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h @@ -2,13 +2,26 @@ #define __ASM_SH_CPU_SH4_DMA_SH7780_H #if defined(CONFIG_CPU_SUBTYPE_SH7343) || \ - defined(CONFIG_CPU_SUBTYPE_SH7722) || \ defined(CONFIG_CPU_SUBTYPE_SH7730) #define DMTE0_IRQ 48 #define DMTE4_IRQ 76 #define DMAE0_IRQ 78 /* DMA Error IRQ*/ #define SH_DMAC_BASE0 0xFE008020 #define SH_DMARS_BASE 0xFE009000 +#define CHCR_TS_LOW_MASK 0x00000018 +#define CHCR_TS_LOW_SHIFT 3 +#define CHCR_TS_HIGH_MASK 0 +#define CHCR_TS_HIGH_SHIFT 0 +#elif defined(CONFIG_CPU_SUBTYPE_SH7722) +#define DMTE0_IRQ 48 +#define DMTE4_IRQ 76 +#define DMAE0_IRQ 78 /* DMA Error IRQ*/ +#define SH_DMAC_BASE0 0xFE008020 +#define SH_DMARS_BASE 0xFE009000 +#define CHCR_TS_LOW_MASK 0x00000018 +#define CHCR_TS_LOW_SHIFT 3 +#define CHCR_TS_HIGH_MASK 0x00300000 +#define CHCR_TS_HIGH_SHIFT 20 #elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \ defined(CONFIG_CPU_SUBTYPE_SH7764) #define DMTE0_IRQ 34 @@ -16,8 +29,11 @@ #define DMAE0_IRQ 38 #define SH_DMAC_BASE0 0xFF608020 #define SH_DMARS_BASE 0xFF609000 -#elif defined(CONFIG_CPU_SUBTYPE_SH7723) || \ - defined(CONFIG_CPU_SUBTYPE_SH7724) +#define CHCR_TS_LOW_MASK 0x00000018 +#define CHCR_TS_LOW_SHIFT 3 +#define CHCR_TS_HIGH_MASK 0 +#define CHCR_TS_HIGH_SHIFT 0 +#elif defined(CONFIG_CPU_SUBTYPE_SH7723) #define DMTE0_IRQ 48 /* DMAC0A*/ #define DMTE4_IRQ 76 /* DMAC0B */ #define DMTE6_IRQ 40 @@ -30,6 +46,27 @@ #define SH_DMAC_BASE0 0xFE008020 #define SH_DMAC_BASE1 0xFDC08020 #define SH_DMARS_BASE 0xFDC09000 +#define CHCR_TS_LOW_MASK 0x00000018 +#define CHCR_TS_LOW_SHIFT 3 +#define CHCR_TS_HIGH_MASK 0 +#define CHCR_TS_HIGH_SHIFT 0 +#elif defined(CONFIG_CPU_SUBTYPE_SH7724) +#define DMTE0_IRQ 48 /* DMAC0A*/ +#define DMTE4_IRQ 76 /* DMAC0B */ +#define DMTE6_IRQ 40 +#define DMTE8_IRQ 42 /* DMAC1A */ +#define DMTE9_IRQ 43 +#define DMTE10_IRQ 72 /* DMAC1B */ +#define DMTE11_IRQ 73 +#define DMAE0_IRQ 78 /* DMA Error IRQ*/ +#define DMAE1_IRQ 74 /* DMA Error IRQ*/ +#define SH_DMAC_BASE0 0xFE008020 +#define SH_DMAC_BASE1 0xFDC08020 +#define SH_DMARS_BASE 0xFDC09000 +#define CHCR_TS_LOW_MASK 0x00000018 +#define CHCR_TS_LOW_SHIFT 3 +#define CHCR_TS_HIGH_MASK 0x00600000 +#define CHCR_TS_HIGH_SHIFT 21 #elif defined(CONFIG_CPU_SUBTYPE_SH7780) #define DMTE0_IRQ 34 #define DMTE4_IRQ 44 @@ -42,6 +79,10 @@ #define SH_DMAC_BASE0 0xFC808020 #define SH_DMAC_BASE1 0xFC818020 #define SH_DMARS_BASE 0xFC809000 +#define CHCR_TS_LOW_MASK 0x00000018 +#define CHCR_TS_LOW_SHIFT 3 +#define CHCR_TS_HIGH_MASK 0 +#define CHCR_TS_HIGH_SHIFT 0 #else /* SH7785 */ #define DMTE0_IRQ 33 #define DMTE4_IRQ 37 @@ -55,17 +96,16 @@ #define SH_DMAC_BASE0 0xFC808020 #define SH_DMAC_BASE1 0xFCC08020 #define SH_DMARS_BASE 0xFC809000 +#define CHCR_TS_LOW_MASK 0x00000018 +#define CHCR_TS_LOW_SHIFT 3 +#define CHCR_TS_HIGH_MASK 0 +#define CHCR_TS_HIGH_SHIFT 0 #endif -#define REQ_HE 0x000000C0 -#define REQ_H 0x00000080 -#define REQ_LE 0x00000040 -#define TM_BURST 0x0000020 -#define TS_8 0x00000000 -#define TS_16 0x00000008 -#define TS_32 0x00000010 -#define TS_16BLK 0x00000018 -#define TS_32BLK 0x00100000 +#define REQ_HE 0x000000C0 +#define REQ_H 0x00000080 +#define REQ_LE 0x00000040 +#define TM_BURST 0x00000020 /* * The SuperH DMAC supports a number of transmit sizes, we list them here, @@ -74,22 +114,31 @@ * Defaults to a 64-bit transfer size. */ enum { - XMIT_SZ_8BIT, - XMIT_SZ_16BIT, - XMIT_SZ_32BIT, - XMIT_SZ_128BIT, - XMIT_SZ_256BIT, + XMIT_SZ_8BIT = 0, + XMIT_SZ_16BIT = 1, + XMIT_SZ_32BIT = 2, + XMIT_SZ_64BIT = 7, + XMIT_SZ_128BIT = 3, + XMIT_SZ_256BIT = 4, + XMIT_SZ_128BIT_BLK = 0xb, + XMIT_SZ_256BIT_BLK = 0xc, }; /* * The DMA count is defined as the number of bytes to transfer. */ -static unsigned int ts_shift[] __maybe_unused = { - [XMIT_SZ_8BIT] = 0, - [XMIT_SZ_16BIT] = 1, - [XMIT_SZ_32BIT] = 2, - [XMIT_SZ_128BIT] = 4, - [XMIT_SZ_256BIT] = 5, -}; +#define TS_SHIFT { \ + [XMIT_SZ_8BIT] = 0, \ + [XMIT_SZ_16BIT] = 1, \ + [XMIT_SZ_32BIT] = 2, \ + [XMIT_SZ_64BIT] = 3, \ + [XMIT_SZ_128BIT] = 4, \ + [XMIT_SZ_256BIT] = 5, \ + [XMIT_SZ_128BIT_BLK] = 4, \ + [XMIT_SZ_256BIT_BLK] = 5, \ +} + +#define TS_INDEX2VAL(i) ((((i) & 3) << CHCR_TS_LOW_SHIFT) | \ + ((((i) >> 2) & 3) << CHCR_TS_HIGH_SHIFT)) #endif /* __ASM_SH_CPU_SH4_DMA_SH7780_H */ diff --git a/arch/sh/include/cpu-sh4/cpu/dma.h b/arch/sh/include/cpu-sh4/cpu/dma.h index bcb30246e85c..114a369705bc 100644 --- a/arch/sh/include/cpu-sh4/cpu/dma.h +++ b/arch/sh/include/cpu-sh4/cpu/dma.h @@ -6,8 +6,6 @@ #ifdef CONFIG_CPU_SH4A #define DMAOR_INIT (DMAOR_DME) -#define CHCR_TS_MASK 0x18 -#define CHCR_TS_SHIFT 3 #include #else /* CONFIG_CPU_SH4A */ @@ -29,8 +27,10 @@ #define TS_32 0x00000030 #define TS_64 0x00000000 -#define CHCR_TS_MASK 0x70 -#define CHCR_TS_SHIFT 4 +#define CHCR_TS_LOW_MASK 0x70 +#define CHCR_TS_LOW_SHIFT 4 +#define CHCR_TS_HIGH_MASK 0 +#define CHCR_TS_HIGH_SHIFT 0 #define DMAOR_COD 0x00000008 @@ -41,23 +41,26 @@ * Defaults to a 64-bit transfer size. */ enum { - XMIT_SZ_64BIT, - XMIT_SZ_8BIT, - XMIT_SZ_16BIT, - XMIT_SZ_32BIT, - XMIT_SZ_256BIT, + XMIT_SZ_8BIT = 1, + XMIT_SZ_16BIT = 2, + XMIT_SZ_32BIT = 3, + XMIT_SZ_64BIT = 0, + XMIT_SZ_256BIT = 4, }; /* * The DMA count is defined as the number of bytes to transfer. */ -static unsigned int ts_shift[] __maybe_unused = { - [XMIT_SZ_64BIT] = 3, - [XMIT_SZ_8BIT] = 0, - [XMIT_SZ_16BIT] = 1, - [XMIT_SZ_32BIT] = 2, - [XMIT_SZ_256BIT] = 5, -}; +#define TS_SHIFT { \ + [XMIT_SZ_8BIT] = 0, \ + [XMIT_SZ_16BIT] = 1, \ + [XMIT_SZ_32BIT] = 2, \ + [XMIT_SZ_64BIT] = 3, \ + [XMIT_SZ_256BIT] = 5, \ +} + +#define TS_INDEX2VAL(i) (((i) & 7) << CHCR_TS_LOW_SHIFT) + #endif #endif /* __ASM_CPU_SH4_DMA_H */ diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index 427c3effc432..3e1037c5ebd1 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c @@ -105,10 +105,14 @@ static bool dmae_is_busy(struct sh_dmae_chan *sh_chan) return false; /* waiting */ } +static unsigned int ts_shift[] = TS_SHIFT; static inline unsigned int calc_xmit_shift(struct sh_dmae_chan *sh_chan) { u32 chcr = sh_dmae_readl(sh_chan, CHCR); - return ts_shift[(chcr & CHCR_TS_MASK) >> CHCR_TS_SHIFT]; + int cnt = ((chcr & CHCR_TS_LOW_MASK) >> CHCR_TS_LOW_SHIFT) | + ((chcr & CHCR_TS_HIGH_MASK) >> CHCR_TS_HIGH_SHIFT); + + return ts_shift[cnt]; } static void dmae_set_reg(struct sh_dmae_chan *sh_chan, struct sh_dmae_regs *hw) -- cgit v1.2.3 From cfefe99795251d76d92e8457f4152f532a961ec5 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 3 Feb 2010 14:46:41 +0000 Subject: sh: implement DMA_SLAVE capability in SH dmaengine driver Tested to work with a SIU ASoC driver on sh7722 (migor). Signed-off-by: Guennadi Liakhovetski Acked-by: Dan Williams Signed-off-by: Paul Mundt --- arch/sh/include/asm/dma-sh.h | 41 ++++++- arch/sh/include/cpu-sh4/cpu/dma-sh4a.h | 15 +-- drivers/dma/shdma.c | 190 ++++++++++++++++++++++++--------- drivers/dma/shdma.h | 7 +- 4 files changed, 192 insertions(+), 61 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/dma-sh.h b/arch/sh/include/asm/dma-sh.h index 01d2fc72551b..c8d8ce78f346 100644 --- a/arch/sh/include/asm/dma-sh.h +++ b/arch/sh/include/asm/dma-sh.h @@ -64,8 +64,10 @@ static int dmte_irq_map[] __maybe_unused = { #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 @@ -123,10 +125,47 @@ static u32 dma_base_addr[] __maybe_unused = { */ #define SHDMA_MIX_IRQ (1 << 1) #define SHDMA_DMAOR1 (1 << 2) -#define SHDMA_DMAE1 (1 << 3) +#define SHDMA_DMAE1 (1 << 3) + +enum sh_dmae_slave_chan_id { + SHDMA_SLAVE_SCIF0_TX, + SHDMA_SLAVE_SCIF0_RX, + SHDMA_SLAVE_SCIF1_TX, + SHDMA_SLAVE_SCIF1_RX, + SHDMA_SLAVE_SCIF2_TX, + SHDMA_SLAVE_SCIF2_RX, + SHDMA_SLAVE_SCIF3_TX, + SHDMA_SLAVE_SCIF3_RX, + SHDMA_SLAVE_SCIF4_TX, + SHDMA_SLAVE_SCIF4_RX, + SHDMA_SLAVE_SCIF5_TX, + SHDMA_SLAVE_SCIF5_RX, + SHDMA_SLAVE_SIUA_TX, + SHDMA_SLAVE_SIUA_RX, + SHDMA_SLAVE_SIUB_TX, + SHDMA_SLAVE_SIUB_RX, + SHDMA_SLAVE_NUMBER, /* Must stay last */ +}; + +struct sh_dmae_slave_config { + enum sh_dmae_slave_chan_id slave_id; + dma_addr_t addr; + u32 chcr; + char mid_rid; +}; struct sh_dmae_pdata { unsigned int mode; + struct sh_dmae_slave_config *config; + int config_num; +}; + +struct device; + +struct sh_dmae_slave { + enum sh_dmae_slave_chan_id slave_id; /* Set by the platform */ + struct device *dma_dev; /* Set by the platform */ + struct sh_dmae_slave_config *config; /* Set by the driver */ }; #endif /* __DMA_SH_H */ diff --git a/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h b/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h index cc1cf3e8f163..e734ea47d8a0 100644 --- a/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h +++ b/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h @@ -7,7 +7,7 @@ #define DMTE4_IRQ 76 #define DMAE0_IRQ 78 /* DMA Error IRQ*/ #define SH_DMAC_BASE0 0xFE008020 -#define SH_DMARS_BASE 0xFE009000 +#define SH_DMARS_BASE0 0xFE009000 #define CHCR_TS_LOW_MASK 0x00000018 #define CHCR_TS_LOW_SHIFT 3 #define CHCR_TS_HIGH_MASK 0 @@ -17,7 +17,7 @@ #define DMTE4_IRQ 76 #define DMAE0_IRQ 78 /* DMA Error IRQ*/ #define SH_DMAC_BASE0 0xFE008020 -#define SH_DMARS_BASE 0xFE009000 +#define SH_DMARS_BASE0 0xFE009000 #define CHCR_TS_LOW_MASK 0x00000018 #define CHCR_TS_LOW_SHIFT 3 #define CHCR_TS_HIGH_MASK 0x00300000 @@ -28,7 +28,7 @@ #define DMTE4_IRQ 44 #define DMAE0_IRQ 38 #define SH_DMAC_BASE0 0xFF608020 -#define SH_DMARS_BASE 0xFF609000 +#define SH_DMARS_BASE0 0xFF609000 #define CHCR_TS_LOW_MASK 0x00000018 #define CHCR_TS_LOW_SHIFT 3 #define CHCR_TS_HIGH_MASK 0 @@ -45,7 +45,7 @@ #define DMAE1_IRQ 74 /* DMA Error IRQ*/ #define SH_DMAC_BASE0 0xFE008020 #define SH_DMAC_BASE1 0xFDC08020 -#define SH_DMARS_BASE 0xFDC09000 +#define SH_DMARS_BASE0 0xFDC09000 #define CHCR_TS_LOW_MASK 0x00000018 #define CHCR_TS_LOW_SHIFT 3 #define CHCR_TS_HIGH_MASK 0 @@ -62,7 +62,8 @@ #define DMAE1_IRQ 74 /* DMA Error IRQ*/ #define SH_DMAC_BASE0 0xFE008020 #define SH_DMAC_BASE1 0xFDC08020 -#define SH_DMARS_BASE 0xFDC09000 +#define SH_DMARS_BASE0 0xFE009000 +#define SH_DMARS_BASE1 0xFDC09000 #define CHCR_TS_LOW_MASK 0x00000018 #define CHCR_TS_LOW_SHIFT 3 #define CHCR_TS_HIGH_MASK 0x00600000 @@ -78,7 +79,7 @@ #define DMAE0_IRQ 38 /* DMA Error IRQ */ #define SH_DMAC_BASE0 0xFC808020 #define SH_DMAC_BASE1 0xFC818020 -#define SH_DMARS_BASE 0xFC809000 +#define SH_DMARS_BASE0 0xFC809000 #define CHCR_TS_LOW_MASK 0x00000018 #define CHCR_TS_LOW_SHIFT 3 #define CHCR_TS_HIGH_MASK 0 @@ -95,7 +96,7 @@ #define DMAE1_IRQ 58 /* DMA Error IRQ1 */ #define SH_DMAC_BASE0 0xFC808020 #define SH_DMAC_BASE1 0xFCC08020 -#define SH_DMARS_BASE 0xFC809000 +#define SH_DMARS_BASE0 0xFC809000 #define CHCR_TS_LOW_MASK 0x00000018 #define CHCR_TS_LOW_SHIFT 3 #define CHCR_TS_HIGH_MASK 0 diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index 3e1037c5ebd1..b75ce8b84c46 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c @@ -48,6 +48,9 @@ enum sh_dmae_desc_status { */ #define RS_DEFAULT (RS_DUAL) +/* A bitmask with bits enough for enum sh_dmae_slave_chan_id */ +static unsigned long sh_dmae_slave_used[BITS_TO_LONGS(SHDMA_SLAVE_NUMBER)]; + static void sh_dmae_chan_ld_cleanup(struct sh_dmae_chan *sh_chan, bool all); #define SH_DMAC_CHAN_BASE(id) (dma_base_addr[id]) @@ -61,12 +64,6 @@ static u32 sh_dmae_readl(struct sh_dmae_chan *sh_dc, u32 reg) return ctrl_inl(SH_DMAC_CHAN_BASE(sh_dc->id) + reg); } -static void dmae_init(struct sh_dmae_chan *sh_chan) -{ - u32 chcr = RS_DEFAULT; /* default is DUAL mode */ - sh_dmae_writel(sh_chan, chcr, CHCR); -} - /* * Reset DMA controller * @@ -106,9 +103,8 @@ static bool dmae_is_busy(struct sh_dmae_chan *sh_chan) } static unsigned int ts_shift[] = TS_SHIFT; -static inline unsigned int calc_xmit_shift(struct sh_dmae_chan *sh_chan) +static inline unsigned int calc_xmit_shift(u32 chcr) { - u32 chcr = sh_dmae_readl(sh_chan, CHCR); int cnt = ((chcr & CHCR_TS_LOW_MASK) >> CHCR_TS_LOW_SHIFT) | ((chcr & CHCR_TS_HIGH_MASK) >> CHCR_TS_HIGH_SHIFT); @@ -119,7 +115,7 @@ static void dmae_set_reg(struct sh_dmae_chan *sh_chan, struct sh_dmae_regs *hw) { sh_dmae_writel(sh_chan, hw->sar, SAR); sh_dmae_writel(sh_chan, hw->dar, DAR); - sh_dmae_writel(sh_chan, hw->tcr >> calc_xmit_shift(sh_chan), TCR); + sh_dmae_writel(sh_chan, hw->tcr >> sh_chan->xmit_shift, TCR); } static void dmae_start(struct sh_dmae_chan *sh_chan) @@ -127,7 +123,7 @@ static void dmae_start(struct sh_dmae_chan *sh_chan) u32 chcr = sh_dmae_readl(sh_chan, CHCR); chcr |= CHCR_DE | CHCR_IE; - sh_dmae_writel(sh_chan, chcr, CHCR); + sh_dmae_writel(sh_chan, chcr & ~CHCR_TE, CHCR); } static void dmae_halt(struct sh_dmae_chan *sh_chan) @@ -138,20 +134,27 @@ static void dmae_halt(struct sh_dmae_chan *sh_chan) sh_dmae_writel(sh_chan, chcr, CHCR); } +static void dmae_init(struct sh_dmae_chan *sh_chan) +{ + u32 chcr = RS_DEFAULT; /* default is DUAL mode */ + sh_chan->xmit_shift = calc_xmit_shift(chcr); + sh_dmae_writel(sh_chan, chcr, CHCR); +} + static int dmae_set_chcr(struct sh_dmae_chan *sh_chan, u32 val) { /* When DMA was working, can not set data to CHCR */ if (dmae_is_busy(sh_chan)) return -EBUSY; + sh_chan->xmit_shift = calc_xmit_shift(val); sh_dmae_writel(sh_chan, val, CHCR); + return 0; } -#define DMARS1_ADDR 0x04 -#define DMARS2_ADDR 0x08 -#define DMARS_SHIFT 8 -#define DMARS_CHAN_MSK 0x01 +#define DMARS_SHIFT 8 +#define DMARS_CHAN_MSK 0x01 static int dmae_set_dmars(struct sh_dmae_chan *sh_chan, u16 val) { u32 addr; @@ -163,29 +166,18 @@ static int dmae_set_dmars(struct sh_dmae_chan *sh_chan, u16 val) if (sh_chan->id & DMARS_CHAN_MSK) shift = DMARS_SHIFT; - switch (sh_chan->id) { - /* DMARS0 */ - case 0: - case 1: - addr = SH_DMARS_BASE; - break; - /* DMARS1 */ - case 2: - case 3: - addr = (SH_DMARS_BASE + DMARS1_ADDR); - break; - /* DMARS2 */ - case 4: - case 5: - addr = (SH_DMARS_BASE + DMARS2_ADDR); - break; - default: + if (sh_chan->id < 6) + /* DMA0RS0 - DMA0RS2 */ + addr = SH_DMARS_BASE0 + (sh_chan->id / 2) * 4; +#ifdef SH_DMARS_BASE1 + else if (sh_chan->id < 12) + /* DMA1RS0 - DMA1RS2 */ + addr = SH_DMARS_BASE1 + ((sh_chan->id - 6) / 2) * 4; +#endif + else return -EINVAL; - } - ctrl_outw((val << shift) | - (ctrl_inw(addr) & (shift ? 0xFF00 : 0x00FF)), - addr); + ctrl_outw((val << shift) | (ctrl_inw(addr) & (0xFF00 >> shift)), addr); return 0; } @@ -253,10 +245,53 @@ static struct sh_desc *sh_dmae_get_desc(struct sh_dmae_chan *sh_chan) return NULL; } +static struct sh_dmae_slave_config *sh_dmae_find_slave( + struct sh_dmae_chan *sh_chan, enum sh_dmae_slave_chan_id slave_id) +{ + struct dma_device *dma_dev = sh_chan->common.device; + struct sh_dmae_device *shdev = container_of(dma_dev, + struct sh_dmae_device, common); + struct sh_dmae_pdata *pdata = &shdev->pdata; + int i; + + if ((unsigned)slave_id >= SHDMA_SLAVE_NUMBER) + return NULL; + + for (i = 0; i < pdata->config_num; i++) + if (pdata->config[i].slave_id == slave_id) + return pdata->config + i; + + return NULL; +} + static int sh_dmae_alloc_chan_resources(struct dma_chan *chan) { struct sh_dmae_chan *sh_chan = to_sh_chan(chan); struct sh_desc *desc; + struct sh_dmae_slave *param = chan->private; + + /* + * This relies on the guarantee from dmaengine that alloc_chan_resources + * never runs concurrently with itself or free_chan_resources. + */ + if (param) { + struct sh_dmae_slave_config *cfg; + + cfg = sh_dmae_find_slave(sh_chan, param->slave_id); + if (!cfg) + return -EINVAL; + + if (test_and_set_bit(param->slave_id, sh_dmae_slave_used)) + return -EBUSY; + + param->config = cfg; + + dmae_set_dmars(sh_chan, cfg->mid_rid); + dmae_set_chcr(sh_chan, cfg->chcr); + } else { + if ((sh_dmae_readl(sh_chan, CHCR) & 0x700) != 0x400) + dmae_set_chcr(sh_chan, RS_DEFAULT); + } spin_lock_bh(&sh_chan->desc_lock); while (sh_chan->descs_allocated < NR_DESCS_PER_CHANNEL) { @@ -289,10 +324,18 @@ static void sh_dmae_free_chan_resources(struct dma_chan *chan) struct sh_desc *desc, *_desc; LIST_HEAD(list); + dmae_halt(sh_chan); + /* Prepared and not submitted descriptors can still be on the queue */ if (!list_empty(&sh_chan->ld_queue)) sh_dmae_chan_ld_cleanup(sh_chan, true); + if (chan->private) { + /* The caller is holding dma_list_mutex */ + struct sh_dmae_slave *param = chan->private; + clear_bit(param->slave_id, sh_dmae_slave_used); + } + spin_lock_bh(&sh_chan->desc_lock); list_splice_init(&sh_chan->ld_free, &list); @@ -304,7 +347,7 @@ static void sh_dmae_free_chan_resources(struct dma_chan *chan) kfree(desc); } -/* +/** * sh_dmae_add_desc - get, set up and return one transfer descriptor * @sh_chan: DMA channel * @flags: DMA transfer flags @@ -351,12 +394,14 @@ static struct sh_desc *sh_dmae_add_desc(struct sh_dmae_chan *sh_chan, new->async_tx.cookie = -EINVAL; } - dev_dbg(sh_chan->dev, "chaining (%u/%u)@%x -> %x with %p, cookie %d\n", + dev_dbg(sh_chan->dev, + "chaining (%u/%u)@%x -> %x with %p, cookie %d, shift %d\n", copy_size, *len, *src, *dest, &new->async_tx, - new->async_tx.cookie); + new->async_tx.cookie, sh_chan->xmit_shift); new->mark = DESC_PREPARED; new->async_tx.flags = flags; + new->direction = direction; *len -= copy_size; if (direction == DMA_BIDIRECTIONAL || direction == DMA_TO_DEVICE) @@ -465,6 +510,8 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_memcpy( if (!chan || !len) return NULL; + chan->private = NULL; + sh_chan = to_sh_chan(chan); sg_init_table(&sg, 1); @@ -477,6 +524,44 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_memcpy( flags); } +static struct dma_async_tx_descriptor *sh_dmae_prep_slave_sg( + struct dma_chan *chan, struct scatterlist *sgl, unsigned int sg_len, + enum dma_data_direction direction, unsigned long flags) +{ + struct sh_dmae_slave *param; + struct sh_dmae_chan *sh_chan; + + if (!chan) + return NULL; + + sh_chan = to_sh_chan(chan); + param = chan->private; + + /* Someone calling slave DMA on a public channel? */ + if (!param || !sg_len) { + dev_warn(sh_chan->dev, "%s: bad parameter: %p, %d, %d\n", + __func__, param, sg_len, param ? param->slave_id : -1); + return NULL; + } + + /* + * if (param != NULL), this is a successfully requested slave channel, + * therefore param->config != NULL too. + */ + return sh_dmae_prep_sg(sh_chan, sgl, sg_len, ¶m->config->addr, + direction, flags); +} + +static void sh_dmae_terminate_all(struct dma_chan *chan) +{ + struct sh_dmae_chan *sh_chan = to_sh_chan(chan); + + if (!chan) + return; + + sh_dmae_chan_ld_cleanup(sh_chan, true); +} + static dma_async_tx_callback __ld_cleanup(struct sh_dmae_chan *sh_chan, bool all) { struct sh_desc *desc, *_desc; @@ -508,7 +593,11 @@ static dma_async_tx_callback __ld_cleanup(struct sh_dmae_chan *sh_chan, bool all cookie = tx->cookie; if (desc->mark == DESC_COMPLETED && desc->chunks == 1) { - BUG_ON(sh_chan->completed_cookie != desc->cookie - 1); + if (sh_chan->completed_cookie != desc->cookie - 1) + dev_dbg(sh_chan->dev, + "Completing cookie %d, expected %d\n", + desc->cookie, + sh_chan->completed_cookie + 1); sh_chan->completed_cookie = desc->cookie; } @@ -581,7 +670,7 @@ static void sh_chan_xfer_ld_queue(struct sh_dmae_chan *sh_chan) return; } - /* Find the first un-transfer desciptor */ + /* Find the first not transferred desciptor */ list_for_each_entry(sd, &sh_chan->ld_queue, node) if (sd->mark == DESC_SUBMITTED) { /* Get the ld start address from ld_queue */ @@ -685,11 +774,14 @@ static void dmae_do_tasklet(unsigned long data) struct sh_dmae_chan *sh_chan = (struct sh_dmae_chan *)data; struct sh_desc *desc; u32 sar_buf = sh_dmae_readl(sh_chan, SAR); + u32 dar_buf = sh_dmae_readl(sh_chan, DAR); spin_lock(&sh_chan->desc_lock); list_for_each_entry(desc, &sh_chan->ld_queue, node) { - if ((desc->hw.sar + desc->hw.tcr) == sar_buf && - desc->mark == DESC_SUBMITTED) { + if (desc->mark == DESC_SUBMITTED && + ((desc->direction == DMA_FROM_DEVICE && + (desc->hw.dar + desc->hw.tcr) == dar_buf) || + (desc->hw.sar + desc->hw.tcr) == sar_buf)) { dev_dbg(sh_chan->dev, "done #%d@%p dst %u\n", desc->async_tx.cookie, &desc->async_tx, desc->hw.dar); @@ -762,7 +854,7 @@ static int __devinit sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id) } snprintf(new_sh_chan->dev_id, sizeof(new_sh_chan->dev_id), - "sh-dmae%d", new_sh_chan->id); + "sh-dmae%d", new_sh_chan->id); /* set up channel irq */ err = request_irq(irq, &sh_dmae_interrupt, irqflags, @@ -773,11 +865,6 @@ static int __devinit sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id) goto err_no_irq; } - /* CHCR register control function */ - new_sh_chan->set_chcr = dmae_set_chcr; - /* DMARS register control function */ - new_sh_chan->set_dmars = dmae_set_dmars; - shdev->chan[id] = new_sh_chan; return 0; @@ -848,12 +935,19 @@ static int __init sh_dmae_probe(struct platform_device *pdev) INIT_LIST_HEAD(&shdev->common.channels); dma_cap_set(DMA_MEMCPY, shdev->common.cap_mask); + dma_cap_set(DMA_SLAVE, shdev->common.cap_mask); + shdev->common.device_alloc_chan_resources = sh_dmae_alloc_chan_resources; shdev->common.device_free_chan_resources = sh_dmae_free_chan_resources; shdev->common.device_prep_dma_memcpy = sh_dmae_prep_memcpy; shdev->common.device_is_tx_complete = sh_dmae_is_complete; shdev->common.device_issue_pending = sh_dmae_memcpy_issue_pending; + + /* Compulsory for DMA_SLAVE fields */ + shdev->common.device_prep_slave_sg = sh_dmae_prep_slave_sg; + shdev->common.device_terminate_all = sh_dmae_terminate_all; + shdev->common.dev = &pdev->dev; /* Default transfer size of 32 bytes requires 32-byte alignment */ shdev->common.copy_align = 5; diff --git a/drivers/dma/shdma.h b/drivers/dma/shdma.h index 108f1cffb6f5..7e227f3c87c4 100644 --- a/drivers/dma/shdma.h +++ b/drivers/dma/shdma.h @@ -29,6 +29,7 @@ struct sh_desc { struct sh_dmae_regs hw; struct list_head node; struct dma_async_tx_descriptor async_tx; + enum dma_data_direction direction; dma_cookie_t cookie; int chunks; int mark; @@ -45,13 +46,9 @@ struct sh_dmae_chan { struct device *dev; /* Channel device */ struct tasklet_struct tasklet; /* Tasklet */ int descs_allocated; /* desc count */ + int xmit_shift; /* log_2(bytes_per_xfer) */ int id; /* Raw id of this channel */ char dev_id[16]; /* unique name per DMAC of channel */ - - /* Set chcr */ - int (*set_chcr)(struct sh_dmae_chan *sh_chan, u32 regs); - /* Set DMA resource */ - int (*set_dmars)(struct sh_dmae_chan *sh_chan, u16 res); }; struct sh_dmae_device { -- cgit v1.2.3 From 858918b77b29d0e9ce7f524d1b57d602d85f5d64 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Sun, 7 Feb 2010 12:40:36 +0000 Subject: sh: Optimise FDE/CIE lookup by using red-black trees Now that the DWARF unwinder is being used to provide perf callstacks unwinding speed is an issue. It is no longer being used in exceptional circumstances where we don't care about runtime performance, e.g. when panicing, so it makes sense improve performance is possible. With this patch I saw a 42% improvement in unwind time when calling return_address(1). Greater improvements will be seen as the number of levels unwound increases as each unwind is now cheaper. Note that insertion time has doubled but that's just the price we pay for keeping the trees balanced. However, this is a one-time cost for kernel boot/module load and so the improvements in lookup time dominate the extra time we spend keeping the trees balanced. Signed-off-by: Matt Fleming Signed-off-by: Paul Mundt --- arch/sh/include/asm/dwarf.h | 19 ++--- arch/sh/include/asm/module.h | 17 ++++- arch/sh/kernel/dwarf.c | 174 +++++++++++++++++++++++++++++-------------- 3 files changed, 143 insertions(+), 67 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/dwarf.h b/arch/sh/include/asm/dwarf.h index bdccbbfdc0bd..d62abd1d0c05 100644 --- a/arch/sh/include/asm/dwarf.h +++ b/arch/sh/include/asm/dwarf.h @@ -243,16 +243,13 @@ struct dwarf_cie { unsigned long cie_pointer; - struct list_head link; - unsigned long flags; #define DWARF_CIE_Z_AUGMENTATION (1 << 0) - /* - * 'mod' will be non-NULL if this CIE came from a module's - * .eh_frame section. - */ - struct module *mod; + /* linked-list entry if this CIE is from a module */ + struct list_head link; + + struct rb_node node; }; /** @@ -266,13 +263,11 @@ struct dwarf_fde { unsigned long address_range; unsigned char *instructions; unsigned char *end; + + /* linked-list entry if this FDE is from a module */ struct list_head link; - /* - * 'mod' will be non-NULL if this FDE came from a module's - * .eh_frame section. - */ - struct module *mod; + struct rb_node node; }; /** diff --git a/arch/sh/include/asm/module.h b/arch/sh/include/asm/module.h index 068bf1659750..b7927de86f9f 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 +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/kernel/dwarf.c b/arch/sh/kernel/dwarf.c index e51168064e56..bd1c497280a6 100644 --- a/arch/sh/kernel/dwarf.c +++ b/arch/sh/kernel/dwarf.c @@ -39,10 +39,10 @@ static mempool_t *dwarf_frame_pool; static struct kmem_cache *dwarf_reg_cachep; static mempool_t *dwarf_reg_pool; -static LIST_HEAD(dwarf_cie_list); +static struct rb_root cie_root; static DEFINE_SPINLOCK(dwarf_cie_lock); -static LIST_HEAD(dwarf_fde_list); +static struct rb_root fde_root; static DEFINE_SPINLOCK(dwarf_fde_lock); static struct dwarf_cie *cached_cie; @@ -301,7 +301,8 @@ static inline int dwarf_entry_len(char *addr, unsigned long *len) */ static struct dwarf_cie *dwarf_lookup_cie(unsigned long cie_ptr) { - struct dwarf_cie *cie; + struct rb_node **rb_node = &cie_root.rb_node; + struct dwarf_cie *cie = NULL; unsigned long flags; spin_lock_irqsave(&dwarf_cie_lock, flags); @@ -315,16 +316,24 @@ static struct dwarf_cie *dwarf_lookup_cie(unsigned long cie_ptr) goto out; } - list_for_each_entry(cie, &dwarf_cie_list, link) { - if (cie->cie_pointer == cie_ptr) { - cached_cie = cie; - break; + while (*rb_node) { + struct dwarf_cie *cie_tmp; + + cie_tmp = rb_entry(*rb_node, struct dwarf_cie, node); + BUG_ON(!cie_tmp); + + if (cie_ptr == cie_tmp->cie_pointer) { + cie = cie_tmp; + cached_cie = cie_tmp; + goto out; + } else { + if (cie_ptr < cie_tmp->cie_pointer) + rb_node = &(*rb_node)->rb_left; + else + rb_node = &(*rb_node)->rb_right; } } - /* Couldn't find the entry in the list. */ - if (&cie->link == &dwarf_cie_list) - cie = NULL; out: spin_unlock_irqrestore(&dwarf_cie_lock, flags); return cie; @@ -336,25 +345,34 @@ out: */ struct dwarf_fde *dwarf_lookup_fde(unsigned long pc) { - struct dwarf_fde *fde; + struct rb_node **rb_node = &fde_root.rb_node; + struct dwarf_fde *fde = NULL; unsigned long flags; spin_lock_irqsave(&dwarf_fde_lock, flags); - list_for_each_entry(fde, &dwarf_fde_list, link) { - unsigned long start, end; + while (*rb_node) { + struct dwarf_fde *fde_tmp; + unsigned long tmp_start, tmp_end; - start = fde->initial_location; - end = fde->initial_location + fde->address_range; + fde_tmp = rb_entry(*rb_node, struct dwarf_fde, node); + BUG_ON(!fde_tmp); - if (pc >= start && pc < end) - break; - } + tmp_start = fde_tmp->initial_location; + tmp_end = fde_tmp->initial_location + fde_tmp->address_range; - /* Couldn't find the entry in the list. */ - if (&fde->link == &dwarf_fde_list) - fde = NULL; + if (pc < tmp_start) { + rb_node = &(*rb_node)->rb_left; + } else { + if (pc < tmp_end) { + fde = fde_tmp; + goto out; + } else + rb_node = &(*rb_node)->rb_right; + } + } +out: spin_unlock_irqrestore(&dwarf_fde_lock, flags); return fde; @@ -552,8 +570,8 @@ extern void ret_from_irq(void); * on the callstack. Each of the lower (older) stack frames are * linked via the "prev" member. */ -struct dwarf_frame * dwarf_unwind_stack(unsigned long pc, - struct dwarf_frame *prev) +struct dwarf_frame *dwarf_unwind_stack(unsigned long pc, + struct dwarf_frame *prev) { struct dwarf_frame *frame; struct dwarf_cie *cie; @@ -708,6 +726,8 @@ bail: static int dwarf_parse_cie(void *entry, void *p, unsigned long len, unsigned char *end, struct module *mod) { + struct rb_node **rb_node = &cie_root.rb_node; + struct rb_node *parent; struct dwarf_cie *cie; unsigned long flags; int count; @@ -802,11 +822,30 @@ static int dwarf_parse_cie(void *entry, void *p, unsigned long len, cie->initial_instructions = p; cie->instructions_end = end; - cie->mod = mod; - /* Add to list */ spin_lock_irqsave(&dwarf_cie_lock, flags); - list_add_tail(&cie->link, &dwarf_cie_list); + + while (*rb_node) { + struct dwarf_cie *cie_tmp; + + cie_tmp = rb_entry(*rb_node, struct dwarf_cie, node); + + parent = *rb_node; + + if (cie->cie_pointer < cie_tmp->cie_pointer) + rb_node = &parent->rb_left; + else if (cie->cie_pointer >= cie_tmp->cie_pointer) + rb_node = &parent->rb_right; + else + WARN_ON(1); + } + + rb_link_node(&cie->node, parent, rb_node); + rb_insert_color(&cie->node, &cie_root); + + if (mod != NULL) + list_add_tail(&cie->link, &mod->arch.cie_list); + spin_unlock_irqrestore(&dwarf_cie_lock, flags); return 0; @@ -816,6 +855,8 @@ static int dwarf_parse_fde(void *entry, u32 entry_type, void *start, unsigned long len, unsigned char *end, struct module *mod) { + struct rb_node **rb_node = &fde_root.rb_node; + struct rb_node *parent; struct dwarf_fde *fde; struct dwarf_cie *cie; unsigned long flags; @@ -863,11 +904,38 @@ static int dwarf_parse_fde(void *entry, u32 entry_type, fde->instructions = p; fde->end = end; - fde->mod = mod; - /* Add to list. */ spin_lock_irqsave(&dwarf_fde_lock, flags); - list_add_tail(&fde->link, &dwarf_fde_list); + + while (*rb_node) { + struct dwarf_fde *fde_tmp; + unsigned long tmp_start, tmp_end; + unsigned long start, end; + + fde_tmp = rb_entry(*rb_node, struct dwarf_fde, node); + + start = fde->initial_location; + end = fde->initial_location + fde->address_range; + + tmp_start = fde_tmp->initial_location; + tmp_end = fde_tmp->initial_location + fde_tmp->address_range; + + parent = *rb_node; + + if (start < tmp_start) + rb_node = &parent->rb_left; + else if (start >= tmp_end) + rb_node = &parent->rb_right; + else + WARN_ON(1); + } + + rb_link_node(&fde->node, parent, rb_node); + rb_insert_color(&fde->node, &fde_root); + + if (mod != NULL) + list_add_tail(&fde->link, &mod->arch.fde_list); + spin_unlock_irqrestore(&dwarf_fde_lock, flags); return 0; @@ -912,19 +980,29 @@ static struct unwinder dwarf_unwinder = { static void dwarf_unwinder_cleanup(void) { - struct dwarf_cie *cie, *cie_tmp; - struct dwarf_fde *fde, *fde_tmp; + struct rb_node **fde_rb_node = &fde_root.rb_node; + struct rb_node **cie_rb_node = &cie_root.rb_node; /* * Deallocate all the memory allocated for the DWARF unwinder. * Traverse all the FDE/CIE lists and remove and free all the * memory associated with those data structures. */ - list_for_each_entry_safe(cie, cie_tmp, &dwarf_cie_list, link) - kfree(cie); + while (*fde_rb_node) { + struct dwarf_fde *fde; - list_for_each_entry_safe(fde, fde_tmp, &dwarf_fde_list, link) + fde = rb_entry(*fde_rb_node, struct dwarf_fde, node); + rb_erase(*fde_rb_node, &fde_root); kfree(fde); + } + + while (*cie_rb_node) { + struct dwarf_cie *cie; + + cie = rb_entry(*cie_rb_node, struct dwarf_cie, node); + rb_erase(*cie_rb_node, &cie_root); + kfree(cie); + } kmem_cache_destroy(dwarf_reg_cachep); kmem_cache_destroy(dwarf_frame_cachep); @@ -1024,6 +1102,8 @@ int module_dwarf_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, /* Did we find the .eh_frame section? */ if (i != hdr->e_shnum) { + INIT_LIST_HEAD(&me->arch.cie_list); + INIT_LIST_HEAD(&me->arch.fde_list); err = dwarf_parse_section((char *)start, (char *)end, me); if (err) { printk(KERN_WARNING "%s: failed to parse DWARF info\n", @@ -1044,38 +1124,26 @@ int module_dwarf_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, */ void module_dwarf_cleanup(struct module *mod) { - struct dwarf_fde *fde; - struct dwarf_cie *cie; + struct dwarf_fde *fde, *ftmp; + struct dwarf_cie *cie, *ctmp; unsigned long flags; spin_lock_irqsave(&dwarf_cie_lock, flags); -again_cie: - list_for_each_entry(cie, &dwarf_cie_list, link) { - if (cie->mod == mod) - break; - } - - if (&cie->link != &dwarf_cie_list) { + list_for_each_entry_safe(cie, ctmp, &mod->arch.cie_list, link) { list_del(&cie->link); + rb_erase(&cie->node, &cie_root); kfree(cie); - goto again_cie; } spin_unlock_irqrestore(&dwarf_cie_lock, flags); spin_lock_irqsave(&dwarf_fde_lock, flags); -again_fde: - list_for_each_entry(fde, &dwarf_fde_list, link) { - if (fde->mod == mod) - break; - } - - if (&fde->link != &dwarf_fde_list) { + list_for_each_entry_safe(fde, ftmp, &mod->arch.fde_list, link) { list_del(&fde->link); + rb_erase(&fde->node, &fde_root); kfree(fde); - goto again_fde; } spin_unlock_irqrestore(&dwarf_fde_lock, flags); @@ -1094,8 +1162,6 @@ again_fde: static int __init dwarf_unwinder_init(void) { int err; - INIT_LIST_HEAD(&dwarf_cie_list); - INIT_LIST_HEAD(&dwarf_fde_list); dwarf_frame_cachep = kmem_cache_create("dwarf_frames", sizeof(struct dwarf_frame), 0, -- cgit v1.2.3 From 7561f2dd393bd0c6397e6b2a6b021cdb827a2eb1 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 8 Feb 2010 16:36:56 +0900 Subject: sh: Fix up SH7786 PCI resource definitions. This adds in some of the missing memory resources for channels 1/2 and gets the code building again for the recent changes. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/pcie-sh7786.c | 112 +++++++++++++++++++++----------------- arch/sh/drivers/pci/pcie-sh7786.h | 38 ------------- 2 files changed, 63 insertions(+), 87 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c index feac1fef21eb..95d095f26d66 100644 --- a/arch/sh/drivers/pci/pcie-sh7786.c +++ b/arch/sh/drivers/pci/pcie-sh7786.c @@ -1,7 +1,7 @@ /* * Low-Level PCI Express Support for the SH7786 * - * Copyright (C) 2009 Paul Mundt + * Copyright (C) 2009 - 2010 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 @@ -30,60 +30,84 @@ static struct sh7786_pcie_hwops { int (*port_init_hw)(struct sh7786_pcie_port *port); } *sh7786_pcie_hwops; -static struct resource sh7786_pci_32bit_mem_resources[] = { +static struct resource sh7786_pci0_resources[] = { { - .name = "pci0_mem", - .start = SH4A_PCIMEM_BASEA, - .end = SH4A_PCIMEM_BASEA + SZ_64M - 1, - .flags = IORESOURCE_MEM, + .name = "PCIe0 IO", + .start = 0xfd000000, + .end = 0xfd000000 + SZ_8M - 1, + .flags = IORESOURCE_IO, }, { - .name = "pci1_mem", - .start = SH4A_PCIMEM_BASEA1, - .end = SH4A_PCIMEM_BASEA1 + SZ_64M - 1, - .flags = IORESOURCE_MEM, + .name = "PCIe0 MEM 0", + .start = 0xc0000000, + .end = 0xc0000000 + SZ_512M - 1, + .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT, }, { - .name = "pci2_mem", - .start = SH4A_PCIMEM_BASEA2, - .end = SH4A_PCIMEM_BASEA2 + SZ_64M - 1, + .name = "PCIe0 MEM 1", + .start = 0x10000000, + .end = 0x10000000 + SZ_64M - 1, .flags = IORESOURCE_MEM, + }, { + .name = "PCIe0 MEM 2", + .start = 0xfe100000, + .end = 0xfe100000 + SZ_1M - 1, }, }; -static struct resource sh7786_pci_29bit_mem_resource = { - .start = SH4A_PCIMEM_BASE, - .end = SH4A_PCIMEM_BASE + SZ_64M - 1, - .flags = IORESOURCE_MEM, +static struct resource sh7786_pci1_resources[] = { + { + .name = "PCIe1 IO", + .start = 0xfd800000, + .end = 0xfd800000 + SZ_8M - 1, + .flags = IORESOURCE_IO, + }, { + .name = "PCIe1 MEM 0", + .start = 0xa0000000, + .end = 0xa0000000 + SZ_512M - 1, + .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT, + }, { + .name = "PCIe1 MEM 1", + .start = 0x30000000, + .end = 0x30000000 + SZ_256M - 1, + .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT, + }, { + .name = "PCIe1 MEM 2", + .start = 0xfe300000, + .end = 0xfe300000 + SZ_1M - 1, + }, }; -static struct resource sh7786_pci_io_resources[] = { +static struct resource sh7786_pci2_resources[] = { { - .name = "pci0_io", - .start = SH4A_PCIIO_BASE, - .end = SH4A_PCIIO_BASE + SZ_8M - 1, - .flags = IORESOURCE_IO, + .name = "PCIe2 IO", + .start = 0xfc800000, + .end = 0xfc800000 + SZ_4M - 1, }, { - .name = "pci1_io", - .start = SH4A_PCIIO_BASE1, - .end = SH4A_PCIIO_BASE1 + SZ_8M - 1, - .flags = IORESOURCE_IO, + .name = "PCIe2 MEM 0", + .start = 0x80000000, + .end = 0x80000000 + SZ_512M - 1, + .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT, }, { - .name = "pci2_io", - .start = SH4A_PCIIO_BASE2, - .end = SH4A_PCIIO_BASE2 + SZ_4M - 1, - .flags = IORESOURCE_IO, + .name = "PCIe2 MEM 1", + .start = 0x20000000, + .end = 0x20000000 + SZ_256M - 1, + .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT, + }, { + .name = "PCIe2 MEM 2", + .start = 0xfcd00000, + .end = 0xfcd00000 + SZ_1M - 1, }, }; extern struct pci_ops sh7786_pci_ops; -#define DEFINE_CONTROLLER(start, idx) \ -{ \ - .pci_ops = &sh7786_pci_ops, \ - .reg_base = start, \ - /* mem_resource filled in at probe time */ \ - .mem_offset = 0, \ - .io_resource = &sh7786_pci_io_resources[idx], \ - .io_offset = 0, \ +#define DEFINE_CONTROLLER(start, idx) \ +{ \ + .pci_ops = &sh7786_pci_ops, \ + .resources = sh7786_pci##idx##_resources, \ + .nr_resources = ARRAY_SIZE(sh7786_pci##idx##_resources), \ + .reg_base = start, \ + .mem_offset = 0, \ + .io_offset = 0, \ } static struct pci_channel sh7786_pci_channels[] = { @@ -330,17 +354,7 @@ static int __init sh7786_pcie_init(void) port->index = i; port->hose = sh7786_pci_channels + i; - port->hose->io_map_base = port->hose->io_resource->start; - - /* - * Check if we are booting in 29 or 32-bit mode - * - * 32-bit mode provides each controller with its own - * memory window, while 29-bit mode uses a shared one. - */ - port->hose->mem_resource = test_mode_pin(MODE_PIN10) ? - &sh7786_pci_32bit_mem_resources[i] : - &sh7786_pci_29bit_mem_resource; + port->hose->io_map_base = port->hose->resources[0].start; ret |= sh7786_pcie_hwops->port_init_hw(port); } diff --git a/arch/sh/drivers/pci/pcie-sh7786.h b/arch/sh/drivers/pci/pcie-sh7786.h index c655290a7750..6666ea29cba8 100644 --- a/arch/sh/drivers/pci/pcie-sh7786.h +++ b/arch/sh/drivers/pci/pcie-sh7786.h @@ -30,47 +30,9 @@ * for other(Max Payload Size=4096B,PCIIO_SIZE=8M) */ -/* PCI0-0: PCI I/O space */ -#define SH4A_PCIIO_BASE 0xFD000000 /* PCI I/O for controller 0 */ -#define SH4A_PCIIO_BASE1 0xFD800000 /* PCI I/O for controller 1 (Rev1.14)*/ -#define SH4A_PCIIO_BASE2 0xFC800000 /* PCI I/O for controller 2 (Rev1.171)*/ - -#define SH4A_PCIIO_SIZE64 0x00010000 /* PLX allows only 64K */ -#define SH4A_PCIIO_SIZE 0x00800000 /* 8M */ -#define SH4A_PCIIO_SIZE2 0x00400000 /* 4M (Rev1.171)*/ - -/* PCI0-1: PCI memory space 29-bit address */ -#define SH4A_PCIMEM_BASE 0x10000000 -#define SH4A_PCIMEM_SIZE 0x04000000 /* 64M */ - -/* PCI0-2: PCI memory space 32-bit address */ -#define SH4A_PCIMEM_BASEA 0xC0000000 /* for controller 0 */ -#define SH4A_PCIMEM_BASEA1 0xA0000000 /* for controller 1 (Rev1.14)*/ -#define SH4A_PCIMEM_BASEA2 0x80000000 /* for controller 2 (Rev1.171)*/ -#define SH4A_PCIMEM_SIZEA 0x20000000 /* 512M */ - /* PCI0: PCI memory target transfer 32-bit address translation value(Rev1.11T)*/ #define SH4A_PCIBMSTR_TRANSLATION 0x20000000 -#define SH4A_PCI_DEVICE_ID 0x0002 -#define SH4A_PCI_VENDOR_ID 0x1912 - -// PCI compatible 000-03f -#define PCI_CMD 0x004 -#define PCI_RID 0x008 -#define PCI_IBAR 0x010 -#define PCI_MBAR0 0x014 -#define PCI_MBAR1 0x018 - -/* PCI power management/MSI/capablity 040-0ff */ -/* PCIE extended 100-fff */ - -/* SH7786 device identification */ // Rev1.171 -#define SH4A_PVR (0xFF000030) -#define SH4A_PVR_SHX3 (0x10400000) -#define SH4A_PRR (0xFF000044) -#define SH4A_PRR_SH7786 (0x00000400) // Rev1.171 - /* SPVCR0 */ #define SH4A_PCIEVCR0 (0x000000) /* R - 0x0000 0000 32 */ #define BITS_TOP_MB (24) -- cgit v1.2.3 From 8d9adabac3a3a3742c7a47da9e456108a0fd2efb Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 9 Feb 2010 06:49:48 +0000 Subject: sh: sh7722/Migo-R SDHI vector merge Merge the SDHI vectors in the sh7722 INTC table and update the SDHI platform data for Migo-R. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/boards/mach-migor/setup.c | 2 +- arch/sh/kernel/cpu/sh4a/setup-sh7722.c | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c index ed2eeeb390a5..d1e51a9baf9c 100644 --- a/arch/sh/boards/mach-migor/setup.c +++ b/arch/sh/boards/mach-migor/setup.c @@ -397,7 +397,7 @@ static struct resource sdhi_cn9_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = 101, + .start = 100, .flags = IORESOURCE_IRQ, }, }; diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index b5335b5e309c..0949135a125c 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c @@ -446,6 +446,7 @@ void __init plat_early_device_setup(void) enum { UNUSED=0, + ENABLED, /* interrupt sources */ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7, @@ -461,7 +462,6 @@ enum { SCIF0, SCIF1, SCIF2, SIOF0, SIOF1, SIO, FLCTL_FLSTEI, FLCTL_FLENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I, I2C_ALI, I2C_TACKI, I2C_WAITI, I2C_DTEI, - SDHI0, SDHI1, SDHI2, SDHI3, CMT, TSIF, SIU, TWODG, TMU0, TMU1, TMU2, IRDA, JPU, LCDC, @@ -494,8 +494,8 @@ static struct intc_vect vectors[] __initdata = { INTC_VECT(FLCTL_FLTREQ0I, 0xdc0), INTC_VECT(FLCTL_FLTREQ1I, 0xde0), INTC_VECT(I2C_ALI, 0xe00), INTC_VECT(I2C_TACKI, 0xe20), INTC_VECT(I2C_WAITI, 0xe40), INTC_VECT(I2C_DTEI, 0xe60), - INTC_VECT(SDHI0, 0xe80), INTC_VECT(SDHI1, 0xea0), - INTC_VECT(SDHI2, 0xec0), INTC_VECT(SDHI3, 0xee0), + INTC_VECT(SDHI, 0xe80), INTC_VECT(SDHI, 0xea0), + INTC_VECT(SDHI, 0xec0), INTC_VECT(SDHI, 0xee0), INTC_VECT(CMT, 0xf00), INTC_VECT(TSIF, 0xf20), INTC_VECT(SIU, 0xf80), INTC_VECT(TWODG, 0xfa0), INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420), @@ -513,7 +513,6 @@ static struct intc_group groups[] __initdata = { INTC_GROUP(FLCTL, FLCTL_FLSTEI, FLCTL_FLENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I), INTC_GROUP(I2C, I2C_ALI, I2C_TACKI, I2C_WAITI, I2C_DTEI), - INTC_GROUP(SDHI, SDHI0, SDHI1, SDHI2, SDHI3), }; static struct intc_mask_reg mask_registers[] __initdata = { @@ -535,7 +534,7 @@ static struct intc_mask_reg mask_registers[] __initdata = { { I2C_DTEI, I2C_WAITI, I2C_TACKI, I2C_ALI, FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLENDI, FLCTL_FLSTEI } }, { 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */ - { SDHI3, SDHI2, SDHI1, SDHI0, 0, 0, TWODG, SIU } }, + { 0, 0, ENABLED, ENABLED, 0, 0, TWODG, SIU } }, { 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */ { 0, 0, 0, CMT, 0, USB_USBI1, USB_USBI0, } }, { 0xa40800a8, 0xa40800e8, 8, /* IMR10 / IMCR10 */ @@ -573,9 +572,12 @@ static struct intc_mask_reg ack_registers[] __initdata = { { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, }; -static DECLARE_INTC_DESC_ACK(intc_desc, "sh7722", vectors, groups, - mask_registers, prio_registers, sense_registers, - ack_registers); +static struct intc_desc intc_desc __initdata = { + .name = "sh7722", + .force_enable = ENABLED, + .hw = INTC_HW_DESC(vectors, groups, mask_registers, + prio_registers, sense_registers, ack_registers), +}; void __init plat_irq_setup(void) { -- cgit v1.2.3 From e3e80046e0ce2a595e607a62b650a9b4efea6558 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 9 Feb 2010 06:49:56 +0000 Subject: sh: sh7723/AP325 SDHI vector merge Merge the SDHI vectors in the sh7723 INTC table and update the SDHI platform data for AP325. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/boards/mach-ap325rxa/setup.c | 4 ++-- arch/sh/kernel/cpu/sh4a/setup-sh7723.c | 32 +++++++++++++++++--------------- 2 files changed, 19 insertions(+), 17 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c index 27277cbdb636..b5980696abbe 100644 --- a/arch/sh/boards/mach-ap325rxa/setup.c +++ b/arch/sh/boards/mach-ap325rxa/setup.c @@ -420,7 +420,7 @@ static struct resource sdhi0_cn3_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = 101, + .start = 100, .flags = IORESOURCE_IRQ, }, }; @@ -443,7 +443,7 @@ static struct resource sdhi1_cn7_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = 24, + .start = 23, .flags = IORESOURCE_IRQ, }, }; diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c index 9e8620e3ad3e..7b90ebcfa20e 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c @@ -601,6 +601,7 @@ void l2_cache_init(void) enum { UNUSED=0, + ENABLED, /* interrupt sources */ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7, @@ -623,7 +624,6 @@ enum { SCIFA_SCIFA1, FLCTL_FLSTEI,FLCTL_FLTENDI,FLCTL_FLTREQ0I,FLCTL_FLTREQ1I, I2C_ALI,I2C_TACKI,I2C_WAITI,I2C_DTEI, - SDHI0_SDHII0,SDHI0_SDHII1,SDHI0_SDHII2, CMT_CMTI, TSIF_TSIFI, SIU_SIUI, @@ -631,7 +631,6 @@ enum { TMU0_TUNI0, TMU0_TUNI1, TMU0_TUNI2, IRDA_IRDAI, ATAPI_ATAPII, - SDHI1_SDHII0,SDHI1_SDHII1,SDHI1_SDHII2, VEU2H1_VEU2HI, LCDC_LCDCI, TMU1_TUNI0,TMU1_TUNI1,TMU1_TUNI2, @@ -702,9 +701,9 @@ static struct intc_vect vectors[] __initdata = { INTC_VECT(I2C_WAITI,0xE40), INTC_VECT(I2C_DTEI,0xE60), - INTC_VECT(SDHI0_SDHII0,0xE80), - INTC_VECT(SDHI0_SDHII1,0xEA0), - INTC_VECT(SDHI0_SDHII2,0xEC0), + INTC_VECT(SDHI0, 0xE80), + INTC_VECT(SDHI0, 0xEA0), + INTC_VECT(SDHI0, 0xEC0), INTC_VECT(CMT_CMTI,0xF00), INTC_VECT(TSIF_TSIFI,0xF20), @@ -718,9 +717,9 @@ static struct intc_vect vectors[] __initdata = { INTC_VECT(IRDA_IRDAI,0x480), INTC_VECT(ATAPI_ATAPII,0x4A0), - INTC_VECT(SDHI1_SDHII0,0x4E0), - INTC_VECT(SDHI1_SDHII1,0x500), - INTC_VECT(SDHI1_SDHII2,0x520), + INTC_VECT(SDHI1, 0x4E0), + INTC_VECT(SDHI1, 0x500), + INTC_VECT(SDHI1, 0x520), INTC_VECT(VEU2H1_VEU2HI,0x560), INTC_VECT(LCDC_LCDCI,0x580), @@ -739,15 +738,14 @@ static struct intc_group groups[] __initdata = { INTC_GROUP(FLCTL,FLCTL_FLSTEI,FLCTL_FLTENDI,FLCTL_FLTREQ0I,FLCTL_FLTREQ1I), INTC_GROUP(I2C,I2C_ALI,I2C_TACKI,I2C_WAITI,I2C_DTEI), INTC_GROUP(_2DG, _2DG_TRI,_2DG_INI,_2DG_CEI), - INTC_GROUP(SDHI1, SDHI1_SDHII0,SDHI1_SDHII1,SDHI1_SDHII2), INTC_GROUP(RTC, RTC_ATI,RTC_PRI,RTC_CUI), INTC_GROUP(DMAC1B, DMAC1B_DEI4,DMAC1B_DEI5,DMAC1B_DADERR), - INTC_GROUP(SDHI0,SDHI0_SDHII0,SDHI0_SDHII1,SDHI0_SDHII2), }; static struct intc_mask_reg mask_registers[] __initdata = { { 0xa4080080, 0xa40800c0, 8, /* IMR0 / IMCR0 */ - { 0, TMU1_TUNI2,TMU1_TUNI1,TMU1_TUNI0,0,SDHI1_SDHII2,SDHI1_SDHII1,SDHI1_SDHII0} }, + { 0, TMU1_TUNI2, TMU1_TUNI1, TMU1_TUNI0, + 0, 0, ENABLED, ENABLED } }, { 0xa4080084, 0xa40800c4, 8, /* IMR1 / IMCR1 */ { VIO_VOUI, VIO_VEU2HI,VIO_BEUI,VIO_CEUI,DMAC0A_DEI3,DMAC0A_DEI2,DMAC0A_DEI1,DMAC0A_DEI0 } }, { 0xa4080088, 0xa40800c8, 8, /* IMR2 / IMCR2 */ @@ -764,7 +762,8 @@ static struct intc_mask_reg mask_registers[] __initdata = { { I2C_DTEI, I2C_WAITI, I2C_TACKI, I2C_ALI, FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLTENDI, FLCTL_FLSTEI } }, { 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */ - { 0,SDHI0_SDHII2,SDHI0_SDHII1,SDHI0_SDHII0,0,0,SCIFA_SCIFA2,SIU_SIUI } }, + { 0, 0, ENABLED, ENABLED, + 0, 0, SCIFA_SCIFA2, SIU_SIUI } }, { 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */ { 0, 0, 0, CMT_CMTI, 0, 0, USB_USI0,0 } }, { 0xa40800a8, 0xa40800e8, 8, /* IMR10 / IMCR10 */ @@ -804,9 +803,12 @@ static struct intc_mask_reg ack_registers[] __initdata = { { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, }; -static DECLARE_INTC_DESC_ACK(intc_desc, "sh7723", vectors, groups, - mask_registers, prio_registers, sense_registers, - ack_registers); +static struct intc_desc intc_desc __initdata = { + .name = "sh7723", + .force_enable = ENABLED, + .hw = INTC_HW_DESC(vectors, groups, mask_registers, + prio_registers, sense_registers, ack_registers), +}; void __init plat_irq_setup(void) { -- cgit v1.2.3 From 3844eadcfd2ba975110e3ca8479efa8c093129ce Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 9 Feb 2010 06:50:04 +0000 Subject: sh: sh7724/Ecovec24/KFR2R09/MS7724SE SDHI vector merge Merge the SDHI vectors in the sh7724 INTC table and update the SDHI platform data for Ecovec24, KFR2R09 and MS7724SE. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/boards/mach-ecovec24/setup.c | 4 ++-- arch/sh/boards/mach-kfr2r09/setup.c | 2 +- arch/sh/boards/mach-se/7724/setup.c | 4 ++-- arch/sh/kernel/cpu/sh4a/setup-sh7724.c | 32 ++++++++++++++++---------------- 4 files changed, 21 insertions(+), 21 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index 1135c3b848f2..8e3b05f93a65 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c @@ -453,7 +453,7 @@ static struct resource sdhi0_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = 101, + .start = 100, .flags = IORESOURCE_IRQ, }, }; @@ -489,7 +489,7 @@ static struct resource sdhi1_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = 24, + .start = 23, .flags = IORESOURCE_IRQ, }, }; diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c index ca9e82d77d0a..b2cd0ed8664e 100644 --- a/arch/sh/boards/mach-kfr2r09/setup.c +++ b/arch/sh/boards/mach-kfr2r09/setup.c @@ -351,7 +351,7 @@ static struct resource kfr2r09_sh_sdhi0_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = 101, + .start = 100, .flags = IORESOURCE_IRQ, }, }; diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c index c7dbbece44b0..50e4d1599576 100644 --- a/arch/sh/boards/mach-se/7724/setup.c +++ b/arch/sh/boards/mach-se/7724/setup.c @@ -451,7 +451,7 @@ static struct resource sdhi0_cn7_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = 101, + .start = 100, .flags = IORESOURCE_IRQ, }, }; @@ -474,7 +474,7 @@ static struct resource sdhi1_cn8_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = 24, + .start = 23, .flags = IORESOURCE_IRQ, }, }; diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c index aa0f6e9bb89e..c0815a43b6a3 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c @@ -723,6 +723,7 @@ void l2_cache_init(void) enum { UNUSED = 0, + ENABLED, /* interrupt sources */ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7, @@ -751,14 +752,12 @@ enum { ETHI, I2C1_ALI, I2C1_TACKI, I2C1_WAITI, I2C1_DTEI, I2C0_ALI, I2C0_TACKI, I2C0_WAITI, I2C0_DTEI, - SDHI0_SDHII0, SDHI0_SDHII1, SDHI0_SDHII2, SDHI0_SDHII3, CMT, TSIF, FSI, SCIFA5, TMU0_TUNI0, TMU0_TUNI1, TMU0_TUNI2, IRDA, - SDHI1_SDHII0, SDHI1_SDHII1, SDHI1_SDHII2, JPU, _2DDMAC, MMC_MMC2I, MMC_MMC3I, @@ -840,10 +839,10 @@ static struct intc_vect vectors[] __initdata = { INTC_VECT(I2C0_WAITI, 0xE40), INTC_VECT(I2C0_DTEI, 0xE60), - INTC_VECT(SDHI0_SDHII0, 0xE80), - INTC_VECT(SDHI0_SDHII1, 0xEA0), - INTC_VECT(SDHI0_SDHII2, 0xEC0), - INTC_VECT(SDHI0_SDHII3, 0xEE0), + INTC_VECT(SDHI0, 0xE80), + INTC_VECT(SDHI0, 0xEA0), + INTC_VECT(SDHI0, 0xEC0), + INTC_VECT(SDHI0, 0xEE0), INTC_VECT(CMT, 0xF00), INTC_VECT(TSIF, 0xF20), @@ -856,9 +855,9 @@ static struct intc_vect vectors[] __initdata = { INTC_VECT(IRDA, 0x480), - INTC_VECT(SDHI1_SDHII0, 0x4E0), - INTC_VECT(SDHI1_SDHII1, 0x500), - INTC_VECT(SDHI1_SDHII2, 0x520), + INTC_VECT(SDHI1, 0x4E0), + INTC_VECT(SDHI1, 0x500), + INTC_VECT(SDHI1, 0x520), INTC_VECT(JPU, 0x560), INTC_VECT(_2DDMAC, 0x4A0), @@ -884,8 +883,6 @@ static struct intc_group groups[] __initdata = { INTC_GROUP(DMAC0B, DMAC0B_DEI4, DMAC0B_DEI5, DMAC0B_DADERR), INTC_GROUP(I2C0, I2C0_ALI, I2C0_TACKI, I2C0_WAITI, I2C0_DTEI), INTC_GROUP(I2C1, I2C1_ALI, I2C1_TACKI, I2C1_WAITI, I2C1_DTEI), - INTC_GROUP(SDHI0, SDHI0_SDHII0, SDHI0_SDHII1, SDHI0_SDHII2, SDHI0_SDHII3), - INTC_GROUP(SDHI1, SDHI1_SDHII0, SDHI1_SDHII1, SDHI1_SDHII2), INTC_GROUP(SPU, SPU_SPUI0, SPU_SPUI1), INTC_GROUP(MMCIF, MMC_MMC2I, MMC_MMC3I), }; @@ -893,7 +890,7 @@ static struct intc_group groups[] __initdata = { static struct intc_mask_reg mask_registers[] __initdata = { { 0xa4080080, 0xa40800c0, 8, /* IMR0 / IMCR0 */ { 0, TMU1_TUNI2, TMU1_TUNI1, TMU1_TUNI0, - 0, SDHI1_SDHII2, SDHI1_SDHII1, SDHI1_SDHII0 } }, + 0, 0, ENABLED, ENABLED } }, { 0xa4080084, 0xa40800c4, 8, /* IMR1 / IMCR1 */ { VIO_VOU, VIO_VEU1, VIO_BEU0, VIO_CEU0, DMAC0A_DEI3, DMAC0A_DEI2, DMAC0A_DEI1, DMAC0A_DEI0 } }, @@ -915,7 +912,7 @@ static struct intc_mask_reg mask_registers[] __initdata = { { I2C0_DTEI, I2C0_WAITI, I2C0_TACKI, I2C0_ALI, I2C1_DTEI, I2C1_WAITI, I2C1_TACKI, I2C1_ALI } }, { 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */ - { SDHI0_SDHII3, SDHI0_SDHII2, SDHI0_SDHII1, SDHI0_SDHII0, + { 0, 0, ENABLED, ENABLED, 0, 0, SCIFA5, FSI } }, { 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */ { 0, 0, 0, CMT, 0, USB1, USB0, 0 } }, @@ -962,9 +959,12 @@ static struct intc_mask_reg ack_registers[] __initdata = { { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, }; -static DECLARE_INTC_DESC_ACK(intc_desc, "sh7724", vectors, groups, - mask_registers, prio_registers, sense_registers, - ack_registers); +static struct intc_desc intc_desc __initdata = { + .name = "sh7724", + .force_enable = ENABLED, + .hw = INTC_HW_DESC(vectors, groups, mask_registers, + prio_registers, sense_registers, ack_registers), +}; void __init plat_irq_setup(void) { -- cgit v1.2.3 From 801cd56e3e2c2b727399d2c50c50139b2d7c98e8 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 9 Feb 2010 08:22:30 +0000 Subject: sh: break out enable/reparent div4 clocks on sh7723 Break out sh7723 div4 clocks for SIU and IRDA as reparent / enable clocks. Similar to the SIU clock patch for sh7722 by Guennadi. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7723.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c index 20a31c2255a8..76731b61998e 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c @@ -117,8 +117,7 @@ static struct clk_div_mult_table div4_table = { .nr_multipliers = ARRAY_SIZE(multipliers), }; -enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P, - DIV4_SIUA, DIV4_SIUB, DIV4_IRDA, DIV4_NR }; +enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P, DIV4_NR }; #define DIV4(_str, _reg, _bit, _mask, _flags) \ SH_CLK_DIV4(_str, &pll_clk, _reg, _bit, _mask, _flags) @@ -130,11 +129,20 @@ struct clk div4_clks[DIV4_NR] = { [DIV4_B] = DIV4("bus_clk", FRQCR, 8, 0x0dbf, CLK_ENABLE_ON_INIT), [DIV4_B3] = DIV4("b3_clk", FRQCR, 4, 0x0db4, CLK_ENABLE_ON_INIT), [DIV4_P] = DIV4("peripheral_clk", FRQCR, 0, 0x0dbf, 0), - [DIV4_SIUA] = DIV4("siua_clk", SCLKACR, 0, 0x0dbf, 0), - [DIV4_SIUB] = DIV4("siub_clk", SCLKBCR, 0, 0x0dbf, 0), +}; + +enum { DIV4_IRDA, DIV4_ENABLE_NR }; + +struct clk div4_enable_clks[DIV4_ENABLE_NR] = { [DIV4_IRDA] = DIV4("irda_clk", IRDACLKCR, 0, 0x0dbf, 0), }; +enum { DIV4_SIUA, DIV4_SIUB, DIV4_REPARENT_NR }; + +struct clk div4_reparent_clks[DIV4_REPARENT_NR] = { + [DIV4_SIUA] = DIV4("siua_clk", SCLKACR, 0, 0x0dbf, 0), + [DIV4_SIUB] = DIV4("siub_clk", SCLKBCR, 0, 0x0dbf, 0), +}; struct clk div6_clks[] = { SH_CLK_DIV6("video_clk", &pll_clk, VCLKCR, 0), }; @@ -215,6 +223,14 @@ int __init arch_clk_init(void) if (!ret) ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table); + if (!ret) + ret = sh_clk_div4_enable_register(div4_enable_clks, + DIV4_ENABLE_NR, &div4_table); + + if (!ret) + ret = sh_clk_div4_reparent_register(div4_reparent_clks, + DIV4_REPARENT_NR, &div4_table); + if (!ret) ret = sh_clk_div6_register(div6_clks, ARRAY_SIZE(div6_clks)); -- cgit v1.2.3 From 7578a4c625a5cc32812946338a4549f3090be113 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 10 Feb 2010 16:00:58 +0900 Subject: sh: Fix up multi-resource mapping for SH7786 PCIe. This reworks some of the SH7786 PCIe initialization code to dynamically setup and size the various resource windows, as opposed to the original code that simply wired in a couple of them statically. At the same time, we tidy up the initialization code a bit, kill off some read-only register twiddling that was gleaned from the bus analyzer, and also propagate the physical slot/channel mapping. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/pcie-sh7786.c | 89 ++++++++++++++++++++++++++++++++------- arch/sh/drivers/pci/pcie-sh7786.h | 36 ++++------------ 2 files changed, 82 insertions(+), 43 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c index 95d095f26d66..ae91a2dd9183 100644 --- a/arch/sh/drivers/pci/pcie-sh7786.c +++ b/arch/sh/drivers/pci/pcie-sh7786.c @@ -204,7 +204,9 @@ static int pcie_init(struct sh7786_pcie_port *port) { struct pci_channel *chan = port->hose; unsigned int data; - int ret; + phys_addr_t memphys; + size_t memsize; + int ret, i; /* Begin initialization */ pci_write_reg(chan, 0, SH4A_PCIETCTLR); @@ -227,15 +229,24 @@ static int pcie_init(struct sh7786_pcie_port *port) data |= PCI_CAP_ID_EXP; pci_write_reg(chan, data, SH4A_PCIEEXPCAP0); - /* Enable x4 link width and extended sync. */ + /* Enable data link layer active state reporting */ + pci_write_reg(chan, PCI_EXP_LNKCAP_DLLLARC, SH4A_PCIEEXPCAP3); + + /* Enable extended sync and ASPM L0s support */ data = pci_read_reg(chan, SH4A_PCIEEXPCAP4); - data &= ~(PCI_EXP_LNKSTA_NLW << 16); - data |= (1 << 22) | PCI_EXP_LNKCTL_ES; + data &= ~PCI_EXP_LNKCTL_ASPMC; + data |= PCI_EXP_LNKCTL_ES | 1; pci_write_reg(chan, data, SH4A_PCIEEXPCAP4); + /* Write out the physical slot number */ + data = pci_read_reg(chan, SH4A_PCIEEXPCAP5); + data &= ~PCI_EXP_SLTCAP_PSN; + data |= (port->index + 1) << 19; + pci_write_reg(chan, data, SH4A_PCIEEXPCAP5); + /* Set the completion timer timeout to the maximum 32ms. */ data = pci_read_reg(chan, SH4A_PCIETLCTLR); - data &= ~0xffff; + data &= ~0x3f00; data |= 0x32 << 8; pci_write_reg(chan, data, SH4A_PCIETLCTLR); @@ -248,6 +259,33 @@ static int pcie_init(struct sh7786_pcie_port *port) data |= (0xff << 16); pci_write_reg(chan, data, SH4A_PCIEMACCTLR); + memphys = __pa(memory_start); + memsize = roundup_pow_of_two(memory_end - memory_start); + + /* + * If there's more than 512MB of memory, we need to roll over to + * LAR1/LAMR1. + */ + if (memsize > SZ_512M) { + __raw_writel(memphys + SZ_512M, chan->reg_base + SH4A_PCIELAR1); + __raw_writel(((memsize - SZ_512M) - SZ_256) | 1, + chan->reg_base + SH4A_PCIELAMR1); + memsize = SZ_512M; + } else { + /* + * Otherwise just zero it out and disable it. + */ + __raw_writel(0, chan->reg_base + SH4A_PCIELAR1); + __raw_writel(0, chan->reg_base + SH4A_PCIELAMR1); + } + + /* + * LAR0/LAMR0 covers up to the first 512MB, which is enough to + * cover all of lowmem on most platforms. + */ + __raw_writel(memphys, chan->reg_base + SH4A_PCIELAR0); + __raw_writel((memsize - SZ_256) | 1, chan->reg_base + SH4A_PCIELAMR0); + /* Finish initialization */ data = pci_read_reg(chan, SH4A_PCIETCTLR); data |= 0x1; @@ -267,10 +305,14 @@ static int pcie_init(struct sh7786_pcie_port *port) if (unlikely(ret != 0)) return -ENODEV; - pci_write_reg(chan, 0x00100007, SH4A_PCIEPCICONF1); + data = pci_read_reg(chan, SH4A_PCIEPCICONF1); + data &= ~(PCI_STATUS_DEVSEL_MASK << 16); + data |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | + (PCI_STATUS_CAP_LIST | PCI_STATUS_DEVSEL_FAST) << 16; + pci_write_reg(chan, data, SH4A_PCIEPCICONF1); + pci_write_reg(chan, 0x80888000, SH4A_PCIETXVC0DCTLR); pci_write_reg(chan, 0x00222000, SH4A_PCIERXVC0DCTLR); - pci_write_reg(chan, 0x000050A0, SH4A_PCIEEXPCAP2); wmb(); @@ -278,15 +320,32 @@ static int pcie_init(struct sh7786_pcie_port *port) printk(KERN_NOTICE "PCI: PCIe#%d link width %d\n", port->index, (data >> 20) & 0x3f); - pci_write_reg(chan, 0x007c0000, SH4A_PCIEPAMR0); - pci_write_reg(chan, 0x00000000, SH4A_PCIEPARH0); - pci_write_reg(chan, 0x00000000, SH4A_PCIEPARL0); - pci_write_reg(chan, 0x80000100, SH4A_PCIEPTCTLR0); - pci_write_reg(chan, 0x03fc0000, SH4A_PCIEPAMR2); - pci_write_reg(chan, 0x00000000, SH4A_PCIEPARH2); - pci_write_reg(chan, 0x00000000, SH4A_PCIEPARL2); - pci_write_reg(chan, 0x80000000, SH4A_PCIEPTCTLR2); + for (i = 0; i < chan->nr_resources; i++) { + struct resource *res = chan->resources + i; + resource_size_t size; + u32 enable_mask; + + pci_write_reg(chan, 0x00000000, SH4A_PCIEPTCTLR(i)); + + size = resource_size(res); + + /* + * The PAMR mask is calculated in units of 256kB, which + * keeps things pretty simple. + */ + __raw_writel(((roundup_pow_of_two(size) / SZ_256K) - 1) << 18, + chan->reg_base + SH4A_PCIEPAMR(i)); + + pci_write_reg(chan, 0x00000000, SH4A_PCIEPARH(i)); + pci_write_reg(chan, 0x00000000, SH4A_PCIEPARL(i)); + + enable_mask = MASK_PARE; + if (res->flags & IORESOURCE_IO) + enable_mask |= MASK_SPC; + + pci_write_reg(chan, enable_mask, SH4A_PCIEPTCTLR(i)); + } return 0; } diff --git a/arch/sh/drivers/pci/pcie-sh7786.h b/arch/sh/drivers/pci/pcie-sh7786.h index 6666ea29cba8..90a6992576b0 100644 --- a/arch/sh/drivers/pci/pcie-sh7786.h +++ b/arch/sh/drivers/pci/pcie-sh7786.h @@ -312,23 +312,23 @@ #define SH4A_PCIECSAR5 (0x0202B4) /* R/W R/W 0x0000 0000 32 */ #define SH4A_PCIESTCTLR5 (0x0202B8) /* R/W R/W 0x0000 0000 32 */ -/* PCIEPARL0 */ -#define SH4A_PCIEPARL0 (0x020400) /* R/W R/W 0x0000 0000 32 */ +/* PCIEPARL */ +#define SH4A_PCIEPARL(x) (0x020400 + ((x) * 0x20)) /* R/W R/W 0x0000 0000 32 */ #define BITS_PAL (18) #define MASK_PAL (0x3fff< Date: Wed, 10 Feb 2010 16:06:42 +0900 Subject: sh: update sdk7786 defconfig. This plugs in USB and PCI and other bits for SDK7786. Signed-off-by: Paul Mundt --- arch/sh/configs/sdk7786_defconfig | 360 +++++++++++++++++++++++++++++++++++--- 1 file changed, 337 insertions(+), 23 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/configs/sdk7786_defconfig b/arch/sh/configs/sdk7786_defconfig index 1721d2c5c7e8..9b331eab968e 100644 --- a/arch/sh/configs/sdk7786_defconfig +++ b/arch/sh/configs/sdk7786_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.33-rc3 -# Thu Jan 14 20:37:44 2010 +# Linux kernel version: 2.6.33-rc7 +# Tue Feb 9 15:27:06 2010 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_IRQ_PER_CPU=y +CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_GPIO is not set CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y @@ -23,6 +23,7 @@ CONFIG_ARCH_HIBERNATION_POSSIBLE=y CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_SYS_SUPPORTS_SMP=y CONFIG_SYS_SUPPORTS_NUMA=y +CONFIG_SYS_SUPPORTS_PCI=y CONFIG_SYS_SUPPORTS_TMU=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_LOCKDEP_SUPPORT=y @@ -134,6 +135,7 @@ CONFIG_EVENT_PROFILE=y # CONFIG_PERF_COUNTERS is not set # CONFIG_DEBUG_PERF_USE_VMALLOC is not set CONFIG_VM_EVENT_COUNTERS=y +CONFIG_PCI_QUIRKS=y # CONFIG_COMPAT_BRK is not set CONFIG_SLAB=y # CONFIG_SLUB is not set @@ -143,7 +145,6 @@ CONFIG_TRACEPOINTS=y # CONFIG_OPROFILE is not set CONFIG_HAVE_OPROFILE=y # CONFIG_KPROBES is not set -CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y @@ -267,7 +268,7 @@ CONFIG_MMU=y CONFIG_PAGE_OFFSET=0x80000000 CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_MEMORY_START=0x60000000 -CONFIG_MEMORY_SIZE=0x08000000 +CONFIG_MEMORY_SIZE=0x20000000 # CONFIG_29BIT is not set CONFIG_32BIT=y CONFIG_PMB=y @@ -284,6 +285,7 @@ CONFIG_ARCH_SELECT_MEMORY_MODEL=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y CONFIG_ARCH_MEMORY_PROBE=y +CONFIG_IOREMAP_FIXED=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set @@ -341,9 +343,7 @@ CONFIG_SH_SDK7786=y # Timer and clock configuration # CONFIG_SH_TIMER_TMU=y -CONFIG_SH_PCLK_FREQ=50000000 CONFIG_SH_CLK_CPG=y -CONFIG_SH_CLK_CPG_LEGACY=y CONFIG_TICK_ONESHOT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y @@ -401,7 +401,6 @@ CONFIG_SECCOMP=y # CONFIG_PREEMPT_VOLUNTARY is not set CONFIG_PREEMPT=y CONFIG_GUSA=y -CONFIG_SPARSE_IRQ=y # # Boot options @@ -411,13 +410,26 @@ CONFIG_BOOT_LINK_OFFSET=0x00800000 CONFIG_ENTRY_OFFSET=0x00001000 CONFIG_CMDLINE_OVERWRITE=y # CONFIG_CMDLINE_EXTEND is not set -CONFIG_CMDLINE="console=ttySC1,115200 earlyprintk=sh-sci.1,115200 root=/dev/nfs ip=dhcp" +CONFIG_CMDLINE="console=ttySC1,115200 earlyprintk=sh-sci.1,115200 root=/dev/sda1 nmi_debug=state,debounce rootdelay=10" # # Bus options # +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCIEPORTBUS=y +CONFIG_PCIEAER=y +# CONFIG_PCIE_ECRC is not set +CONFIG_PCIEAER_INJECT=y +CONFIG_PCIEASPM=y +CONFIG_PCIEASPM_DEBUG=y # CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCI_LEGACY is not set +CONFIG_PCI_DEBUG=y +# CONFIG_PCI_STUB is not set +# CONFIG_PCI_IOV is not set # CONFIG_PCCARD is not set +# CONFIG_HOTPLUG_PCI is not set # # Executable file formats @@ -430,8 +442,14 @@ CONFIG_BINFMT_MISC=y # # Power management options (EXPERIMENTAL) # -# CONFIG_PM is not set -# CONFIG_CPU_IDLE is not set +CONFIG_PM=y +CONFIG_PM_DEBUG=y +CONFIG_PM_VERBOSE=y +# CONFIG_HIBERNATION is not set +CONFIG_PM_RUNTIME=y +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y CONFIG_NET=y # @@ -538,6 +556,9 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_MTD is not set # CONFIG_PARPORT is not set CONFIG_BLK_DEV=y +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set @@ -545,6 +566,7 @@ CONFIG_BLK_DEV=y # DRBD disabled because PROC_FS, INET or CONNECTOR not selected # # CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set # CONFIG_BLK_DEV_UB is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 @@ -555,8 +577,12 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 # CONFIG_BLK_DEV_HD is not set CONFIG_MISC_DEVICES=y # CONFIG_AD525X_DPOT is not set +# CONFIG_PHANTOM is not set +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set # CONFIG_ICS932S401 is not set # CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_HP_ILO is not set # CONFIG_ISL29003 is not set # CONFIG_DS1682 is not set # CONFIG_TI_DAC7512 is not set @@ -570,6 +596,7 @@ CONFIG_MISC_DEVICES=y # CONFIG_EEPROM_LEGACY is not set # CONFIG_EEPROM_MAX6875 is not set # CONFIG_EEPROM_93CX6 is not set +# CONFIG_CB710_CORE is not set CONFIG_HAVE_IDE=y # CONFIG_IDE is not set @@ -608,19 +635,131 @@ CONFIG_SCSI_WAIT_SCAN=m # CONFIG_SCSI_SRP_ATTRS is not set CONFIG_SCSI_LOWLEVEL=y # CONFIG_ISCSI_TCP is not set +# CONFIG_SCSI_BNX2_ISCSI is not set +# CONFIG_BE2ISCSI is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_HPSA is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_3W_SAS is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_MVSAS is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_MPT2SAS is not set +# CONFIG_SCSI_HPTIOP is not set # CONFIG_LIBFC is not set # CONFIG_LIBFCOE is not set +# CONFIG_FCOE is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_PMCRAID is not set +# CONFIG_SCSI_PM8001 is not set +# CONFIG_SCSI_SRP is not set +# CONFIG_SCSI_BFA_FC is not set # CONFIG_SCSI_DH is not set # CONFIG_SCSI_OSD_INITIATOR is not set CONFIG_ATA=y # CONFIG_ATA_NONSTANDARD is not set CONFIG_ATA_VERBOSE_ERROR=y CONFIG_SATA_PMP=y +# CONFIG_SATA_AHCI is not set +CONFIG_SATA_SIL24=y CONFIG_ATA_SFF=y +# CONFIG_SATA_SVW is not set +# CONFIG_ATA_PIIX is not set # CONFIG_SATA_MV is not set +# CONFIG_SATA_NV is not set +# CONFIG_PDC_ADMA is not set +# CONFIG_SATA_QSTOR is not set +# CONFIG_SATA_PROMISE is not set +# CONFIG_SATA_SX4 is not set +# CONFIG_SATA_SIL is not set +# CONFIG_SATA_SIS is not set +# CONFIG_SATA_ULI is not set +# CONFIG_SATA_VIA is not set +# CONFIG_SATA_VITESSE is not set +# CONFIG_SATA_INIC162X is not set +# CONFIG_PATA_ALI is not set +# CONFIG_PATA_AMD is not set +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATP867X is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_CMD640_PCI is not set +# CONFIG_PATA_CMD64X is not set +# CONFIG_PATA_CS5520 is not set +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CYPRESS is not set +# CONFIG_PATA_EFAR is not set +# CONFIG_ATA_GENERIC is not set +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +# CONFIG_PATA_IT821X is not set +# CONFIG_PATA_IT8213 is not set +# CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_TRIFLEX is not set +# CONFIG_PATA_MARVELL is not set +# CONFIG_PATA_MPIIX is not set +# CONFIG_PATA_OLDPIIX is not set +# CONFIG_PATA_NETCELL is not set +# CONFIG_PATA_NINJA32 is not set +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_NS87415 is not set +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PDC2027X is not set +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_RADISYS is not set +# CONFIG_PATA_RDC is not set +# CONFIG_PATA_RZ1000 is not set +# CONFIG_PATA_SC1200 is not set +# CONFIG_PATA_SERVERWORKS is not set +# CONFIG_PATA_SIL680 is not set +# CONFIG_PATA_SIS is not set +# CONFIG_PATA_TOSHIBA is not set +# CONFIG_PATA_VIA is not set +# CONFIG_PATA_WINBOND is not set CONFIG_PATA_PLATFORM=y +# CONFIG_PATA_SCH is not set # CONFIG_MD is not set +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# You can enable one or both FireWire driver stacks. +# + +# +# The newer stack is recommended. +# +# CONFIG_FIREWIRE is not set +# CONFIG_IEEE1394 is not set +# CONFIG_I2O is not set CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set # CONFIG_BONDING is not set @@ -628,6 +767,7 @@ CONFIG_NETDEVICES=y # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set # CONFIG_VETH is not set +# CONFIG_ARCNET is not set CONFIG_PHYLIB=y # @@ -652,12 +792,18 @@ CONFIG_NET_ETHERNET=y CONFIG_MII=y # CONFIG_AX88796 is not set # CONFIG_STNIC is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set CONFIG_SMC91X=y # CONFIG_ENC28J60 is not set # CONFIG_ETHOC is not set # CONFIG_SMC911X is not set CONFIG_SMSC911X=y # CONFIG_DNET is not set +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set # CONFIG_IBM_NEW_EMAC_ZMII is not set # CONFIG_IBM_NEW_EMAC_RGMII is not set # CONFIG_IBM_NEW_EMAC_TAH is not set @@ -665,13 +811,18 @@ CONFIG_SMSC911X=y # CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_NET_PCI is not set # CONFIG_B44 is not set # CONFIG_KS8842 is not set # CONFIG_KS8851 is not set # CONFIG_KS8851_MLL is not set +# CONFIG_ATL2 is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set +# CONFIG_TR is not set CONFIG_WLAN=y +# CONFIG_ATMEL is not set +# CONFIG_PRISM54 is not set # CONFIG_USB_ZD1201 is not set # CONFIG_HOSTAP is not set @@ -688,31 +839,94 @@ CONFIG_WLAN=y # CONFIG_USB_RTL8150 is not set # CONFIG_USB_USBNET is not set # CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set +# CONFIG_NET_FC is not set # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_VMXNET3 is not set # CONFIG_ISDN is not set # CONFIG_PHONE is not set # # Input device support # -# CONFIG_INPUT is not set +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ADP5588 is not set +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_QT2160 is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_MAX7359 is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_SH_KEYSC is not set +# CONFIG_KEYBOARD_XTKBD is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MOUSE_PS2_ELANTECH is not set +# CONFIG_MOUSE_PS2_SENTELIC is not set +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_APPLETOUCH is not set +# CONFIG_MOUSE_BCM5974 is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_MOUSE_SYNAPTICS_I2C is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set # # Hardware I/O ports # -# CONFIG_SERIO is not set +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_ALTERA_PS2 is not set # CONFIG_GAMEPORT is not set # # Character devices # -# CONFIG_VT is not set +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set CONFIG_DEVKMEM=y # CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_NOZOMI is not set # # Serial drivers @@ -728,14 +942,17 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=6 CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set # CONFIG_LEGACY_PTYS is not set # CONFIG_IPMI_HANDLER is not set # CONFIG_HW_RANDOM is not set # CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set # CONFIG_RAW_DRIVER is not set # CONFIG_TCG_TPM is not set +CONFIG_DEVPORT=y CONFIG_I2C=y CONFIG_I2C_BOARDINFO=y # CONFIG_I2C_COMPAT is not set @@ -746,12 +963,29 @@ CONFIG_I2C_HELPER_AUTO=y # I2C Hardware Bus support # +# +# PC SMBus host controller drivers +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_ISCH is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set + # # I2C system bus drivers (mostly embedded / system-on-chip) # # CONFIG_I2C_DESIGNWARE is not set # CONFIG_I2C_OCORES is not set -CONFIG_I2C_SDK7786=y # CONFIG_I2C_SH_MOBILE is not set # CONFIG_I2C_SIMTEC is not set @@ -772,10 +1006,10 @@ CONFIG_I2C_SDK7786=y # Miscellaneous I2C Chip support # # CONFIG_SENSORS_TSL2550 is not set -CONFIG_I2C_DEBUG_CORE=y -CONFIG_I2C_DEBUG_ALGO=y -CONFIG_I2C_DEBUG_BUS=y -CONFIG_I2C_DEBUG_CHIP=y +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set CONFIG_SPI=y # CONFIG_SPI_DEBUG is not set CONFIG_SPI_MASTER=y @@ -810,8 +1044,15 @@ CONFIG_WATCHDOG=y # Watchdog Device Drivers # # CONFIG_SOFT_WATCHDOG is not set +# CONFIG_ALIM7101_WDT is not set # CONFIG_SH_WDT is not set +# +# PCI-based Watchdog Cards +# +# CONFIG_PCIPCWATCHDOG is not set +# CONFIG_WDTPCI is not set + # # USB-based Watchdog Cards # @@ -849,6 +1090,8 @@ CONFIG_SSB_POSSIBLE=y # # Graphics support # +CONFIG_VGA_ARB=y +# CONFIG_DRM is not set # CONFIG_VGASTATE is not set CONFIG_VIDEO_OUTPUT_CONTROL=m # CONFIG_FB is not set @@ -858,11 +1101,56 @@ CONFIG_VIDEO_OUTPUT_CONTROL=m # Display device support # # CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +CONFIG_DUMMY_CONSOLE=y # CONFIG_SOUND is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HIDRAW is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_HID_PID is not set +# CONFIG_USB_HIDDEV is not set + +# +# Special HID drivers +# +# CONFIG_HID_A4TECH is not set +# CONFIG_HID_APPLE is not set +# CONFIG_HID_BELKIN is not set +# CONFIG_HID_CHERRY is not set +# CONFIG_HID_CHICONY is not set +# CONFIG_HID_CYPRESS is not set +# CONFIG_HID_DRAGONRISE is not set +# CONFIG_HID_EZKEY is not set +# CONFIG_HID_KYE is not set +# CONFIG_HID_GYRATION is not set +# CONFIG_HID_TWINHAN is not set +# CONFIG_HID_KENSINGTON is not set +# CONFIG_HID_LOGITECH is not set +# CONFIG_HID_MICROSOFT is not set +# CONFIG_HID_MONTEREY is not set +# CONFIG_HID_NTRIG is not set +# CONFIG_HID_PANTHERLORD is not set +# CONFIG_HID_PETALYNX is not set +# CONFIG_HID_SAMSUNG is not set +# CONFIG_HID_SONY is not set +# CONFIG_HID_SUNPLUS is not set +# CONFIG_HID_GREENASIA is not set +# CONFIG_HID_SMARTJOYPLUS is not set +# CONFIG_HID_TOPSEED is not set +# CONFIG_HID_THRUSTMASTER is not set +# CONFIG_HID_ZEROPLUS is not set CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y -# CONFIG_USB_ARCH_HAS_EHCI is not set +CONFIG_USB_ARCH_HAS_EHCI=y CONFIG_USB=y # CONFIG_USB_DEBUG is not set # CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set @@ -873,6 +1161,7 @@ CONFIG_USB=y # CONFIG_USB_DEVICEFS is not set CONFIG_USB_DEVICE_CLASS=y # CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_SUSPEND is not set # CONFIG_USB_OTG is not set # CONFIG_USB_OTG_WHITELIST is not set # CONFIG_USB_OTG_BLACKLIST_HUB is not set @@ -884,13 +1173,20 @@ CONFIG_USB_MON=y # USB Host Controller Drivers # # CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_XHCI_HCD is not set +# CONFIG_USB_EHCI_HCD is not set # CONFIG_USB_OXU210HP_HCD is not set # CONFIG_USB_ISP116X_HCD is not set # CONFIG_USB_ISP1760_HCD is not set # CONFIG_USB_ISP1362_HCD is not set -# CONFIG_USB_OHCI_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_UHCI_HCD is not set # CONFIG_USB_SL811_HCD is not set -CONFIG_USB_R8A66597_HCD=m +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_WHCI_HCD is not set # CONFIG_USB_HWA_HCD is not set # CONFIG_USB_GADGET_MUSB_HDRC is not set @@ -909,7 +1205,19 @@ CONFIG_USB_R8A66597_HCD=m # # also be needed; see USB_STORAGE Help for more info # -# CONFIG_USB_STORAGE is not set +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set # CONFIG_USB_LIBUSUAL is not set # @@ -989,10 +1297,12 @@ CONFIG_USB_GADGET_DUALSPEED=y # OTG and related infrastructure # # CONFIG_NOP_USB_XCEIV is not set +# CONFIG_UWB is not set # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set # CONFIG_ACCESSIBILITY is not set +# CONFIG_INFINIBAND is not set CONFIG_RTC_LIB=y CONFIG_RTC_CLASS=y CONFIG_RTC_HCTOSYS=y @@ -1063,10 +1373,13 @@ CONFIG_RTC_DRV_SH=y # CONFIG_DMADEVICES is not set # CONFIG_AUXDISPLAY is not set CONFIG_UIO=m +# CONFIG_UIO_CIF is not set # CONFIG_UIO_PDRV is not set # CONFIG_UIO_PDRV_GENIRQ is not set # CONFIG_UIO_SMX is not set +# CONFIG_UIO_AEC is not set # CONFIG_UIO_SERCOS3 is not set +# CONFIG_UIO_PCI_GENERIC is not set # # TI VLYNQ @@ -1418,6 +1731,7 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_DEV_HIFN_795X is not set CONFIG_BINARY_PRINTF=y # -- cgit v1.2.3 From b0f3ae03aca0f331b851ae94bc066124e7f104df Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 12 Feb 2010 15:40:00 +0900 Subject: sh: Isolate uncached mapping support. This splits out the uncached mapping support under its own config option, presently only used by 29-bit mode and 32-bit + PMB. This will make it possible to optionally add an uncached mapping on sh64 as well as booting without an uncached mapping for 32-bit. Signed-off-by: Paul Mundt --- arch/sh/include/asm/ptrace.h | 19 +++++++++++++------ arch/sh/include/asm/system.h | 3 ++- arch/sh/include/asm/system_64.h | 1 + arch/sh/mm/Kconfig | 5 +++++ arch/sh/mm/init.c | 11 ++++++++--- 5 files changed, 29 insertions(+), 10 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/ptrace.h b/arch/sh/include/asm/ptrace.h index 201d11ef211f..e879dffa324b 100644 --- a/arch/sh/include/asm/ptrace.h +++ b/arch/sh/include/asm/ptrace.h @@ -102,13 +102,15 @@ 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 #ifdef __KERNEL__ #include +#include +#include #define user_mode(regs) (((regs)->sr & 0x40000000)==0) #define instruction_pointer(regs) ((unsigned long)(regs)->pc) @@ -137,9 +139,14 @@ 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; +#ifdef CONFIG_UNCACHED_MAPPING + /* + * If PC points in to the uncached mapping, fix it up and hand + * back the cached equivalent. + */ + if ((pc >= (memory_start + cached_to_uncached)) && + (pc < (memory_start + cached_to_uncached + uncached_size))) + pc -= cached_to_uncached; #endif return pc; diff --git a/arch/sh/include/asm/system.h b/arch/sh/include/asm/system.h index 6442f1783fe0..0bd7a17d5e1a 100644 --- a/arch/sh/include/asm/system.h +++ b/arch/sh/include/asm/system.h @@ -10,7 +10,6 @@ #include #include #include -#include #define AT_VECTOR_SIZE_ARCH 5 /* entries in ARCH_DLINFO */ @@ -114,6 +113,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); diff --git a/arch/sh/include/asm/system_64.h b/arch/sh/include/asm/system_64.h index 3391bb6b21d8..36338646dfc8 100644 --- a/arch/sh/include/asm/system_64.h +++ b/arch/sh/include/asm/system_64.h @@ -18,6 +18,7 @@ /* * 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, diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index b89075256b70..65cb5b83e072 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig @@ -75,6 +75,7 @@ config MEMORY_SIZE config 29BIT def_bool !32BIT depends on SUPERH32 + select UNCACHED_MAPPING config 32BIT bool @@ -84,6 +85,7 @@ config PMB bool "Support 32-bit physical addressing through PMB" depends on MMU && EXPERIMENTAL && CPU_SH4A && !CPU_SH4AL_DSP select 32BIT + select UNCACHED_MAPPING help If you say Y here, physical addressing will be extended to 32-bits through the SH-4A PMB. If this is not set, legacy @@ -173,6 +175,9 @@ config IOREMAP_FIXED def_bool y depends on X2TLB || SUPERH64 +config UNCACHED_MAPPING + bool + choice prompt "Kernel page size" default PAGE_SIZE_4KB diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index dffa6c749489..58012b6bbe76 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -21,11 +21,12 @@ #include #include #include +#include DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); pgd_t swapper_pg_dir[PTRS_PER_PGD]; -#ifdef CONFIG_SUPERH32 +#ifdef CONFIG_UNCACHED_MAPPING /* * This is the offset of the uncached section from its cached alias. * @@ -36,8 +37,8 @@ pgd_t swapper_pg_dir[PTRS_PER_PGD]; * Default value only valid in 29 bit mode, in 32bit mode this will be * updated by the early PMB initialization code. */ -unsigned long cached_to_uncached = P2SEG - P1SEG; -unsigned long uncached_size = 0x20000000; +unsigned long cached_to_uncached = 0x20000000; +unsigned long uncached_size = SZ_512M; #endif #ifdef CONFIG_MMU @@ -281,7 +282,9 @@ void __init mem_init(void) #endif " vmalloc : 0x%08lx - 0x%08lx (%4ld MB)\n" " lowmem : 0x%08lx - 0x%08lx (%4ld MB) (cached)\n" +#ifdef CONFIG_UNCACHED_MAPPING " : 0x%08lx - 0x%08lx (%4ld MB) (uncached)\n" +#endif " .init : 0x%08lx - 0x%08lx (%4ld kB)\n" " .data : 0x%08lx - 0x%08lx (%4ld kB)\n" " .text : 0x%08lx - 0x%08lx (%4ld kB)\n", @@ -299,9 +302,11 @@ void __init mem_init(void) (unsigned long)memory_start, (unsigned long)high_memory, ((unsigned long)high_memory - (unsigned long)memory_start) >> 20, +#ifdef CONFIG_UNCACHED_MAPPING (unsigned long)memory_start + cached_to_uncached, (unsigned long)memory_start + cached_to_uncached + uncached_size, uncached_size >> 20, +#endif (unsigned long)&__init_begin, (unsigned long)&__init_end, ((unsigned long)&__init_end - -- cgit v1.2.3 From 19f6b8b44e3f633d5d7d1ed68848b1eb89a1e800 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 12 Feb 2010 15:41:45 +0900 Subject: sh64: fix up memory offset calculation. The linker script offsets were broken by the recent 29/32-bit integration, so this fixes it up for sh64. Signed-off-by: Paul Mundt --- arch/sh/include/asm/vmlinux.lds.h | 8 ++++++++ arch/sh/kernel/vmlinux.lds.S | 19 +++++-------------- 2 files changed, 13 insertions(+), 14 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/vmlinux.lds.h b/arch/sh/include/asm/vmlinux.lds.h index 244ec4ad9a79..d58ad493b3a6 100644 --- a/arch/sh/include/asm/vmlinux.lds.h +++ b/arch/sh/include/asm/vmlinux.lds.h @@ -14,4 +14,12 @@ #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/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S index f0bc6b886eed..dcf48915e2ea 100644 --- a/arch/sh/kernel/vmlinux.lds.S +++ b/arch/sh/kernel/vmlinux.lds.S @@ -3,10 +3,12 @@ * Written by Niibe Yutaka and Paul Mundt */ #ifdef CONFIG_SUPERH64 -#define LOAD_OFFSET CONFIG_PAGE_OFFSET +#define LOAD_OFFSET PAGE_OFFSET +#define MEMORY_OFFSET __MEMORY_START OUTPUT_ARCH(sh:sh5) #else #define LOAD_OFFSET 0 +#define MEMORY_OFFSET 0 OUTPUT_ARCH(sh) #endif @@ -14,16 +16,10 @@ OUTPUT_ARCH(sh) #include #include -#if defined(CONFIG_32BIT) && !defined(CONFIG_PMB_LEGACY) -#define MEMORY_OFFSET 0 -#else -#define MEMORY_OFFSET (CONFIG_MEMORY_START & 0x1fffffff) -#endif - ENTRY(_start) SECTIONS { - . = CONFIG_PAGE_OFFSET + MEMORY_OFFSET + CONFIG_ZERO_PAGE_OFFSET; + . = PAGE_OFFSET + MEMORY_OFFSET + CONFIG_ZERO_PAGE_OFFSET; _text = .; /* Text and read-only data */ @@ -34,12 +30,7 @@ SECTIONS .text : AT(ADDR(.text) - LOAD_OFFSET) { HEAD_TEXT TEXT_TEXT - -#ifdef CONFIG_SUPERH64 - *(.text64) - *(.text..SHmedia32) -#endif - + EXTRA_TEXT SCHED_TEXT LOCK_TEXT KPROBES_TEXT -- cgit v1.2.3 From 04c869735541c27dd137c55f35f8a18bb372bbe1 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 15 Feb 2010 16:10:57 +0900 Subject: sh: Fix up legacy PMB mode offset calculation. The change for fixing up sh64 inadvertently inverted the logic for legacy PMB, fix that back up. Signed-off-by: Paul Mundt --- arch/sh/kernel/vmlinux.lds.S | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S index dcf48915e2ea..0e66c7b30e0f 100644 --- a/arch/sh/kernel/vmlinux.lds.S +++ b/arch/sh/kernel/vmlinux.lds.S @@ -4,11 +4,9 @@ */ #ifdef CONFIG_SUPERH64 #define LOAD_OFFSET PAGE_OFFSET -#define MEMORY_OFFSET __MEMORY_START OUTPUT_ARCH(sh:sh5) #else #define LOAD_OFFSET 0 -#define MEMORY_OFFSET 0 OUTPUT_ARCH(sh) #endif @@ -16,6 +14,13 @@ OUTPUT_ARCH(sh) #include #include +#if defined(CONFIG_29BIT) || defined(CONFIG_SUPERH64) || \ + defined(CONFIG_PMB_LEGACY) + #define MEMORY_OFFSET __MEMORY_START +#else + #define MEMORY_OFFSET 0 +#endif + ENTRY(_start) SECTIONS { -- cgit v1.2.3 From fb1e776050f0f6a7b90eba03a1d001756454f9dc Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 15 Feb 2010 11:53:43 +0000 Subject: sh: fix sh7724 SDHI support using INTC force_disable Update the sh7724 INTC tables with force_enable support to mask out pending unsupported SDHI interrupt sources. Without this patch the kernel locks up due to a pending SDHI interrupt that the tmio_mmc driver cannot handle. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/setup-sh7724.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c index c0815a43b6a3..31e3451f7e3d 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c @@ -724,6 +724,7 @@ void l2_cache_init(void) enum { UNUSED = 0, ENABLED, + DISABLED, /* interrupt sources */ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7, @@ -890,7 +891,7 @@ static struct intc_group groups[] __initdata = { static struct intc_mask_reg mask_registers[] __initdata = { { 0xa4080080, 0xa40800c0, 8, /* IMR0 / IMCR0 */ { 0, TMU1_TUNI2, TMU1_TUNI1, TMU1_TUNI0, - 0, 0, ENABLED, ENABLED } }, + 0, DISABLED, ENABLED, ENABLED } }, { 0xa4080084, 0xa40800c4, 8, /* IMR1 / IMCR1 */ { VIO_VOU, VIO_VEU1, VIO_BEU0, VIO_CEU0, DMAC0A_DEI3, DMAC0A_DEI2, DMAC0A_DEI1, DMAC0A_DEI0 } }, @@ -912,7 +913,7 @@ static struct intc_mask_reg mask_registers[] __initdata = { { I2C0_DTEI, I2C0_WAITI, I2C0_TACKI, I2C0_ALI, I2C1_DTEI, I2C1_WAITI, I2C1_TACKI, I2C1_ALI } }, { 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */ - { 0, 0, ENABLED, ENABLED, + { DISABLED, DISABLED, ENABLED, ENABLED, 0, 0, SCIFA5, FSI } }, { 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */ { 0, 0, 0, CMT, 0, USB1, USB0, 0 } }, @@ -962,6 +963,7 @@ static struct intc_mask_reg ack_registers[] __initdata = { static struct intc_desc intc_desc __initdata = { .name = "sh7724", .force_enable = ENABLED, + .force_disable = DISABLED, .hw = INTC_HW_DESC(vectors, groups, mask_registers, prio_registers, sense_registers, ack_registers), }; -- cgit v1.2.3 From 319c2cc761505ee54a9536c5d0b9c2ee3fb33866 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Mon, 15 Feb 2010 08:37:50 +0000 Subject: sh: Fix zImage boot using fixed PMB. Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Yoshihiro Shimoda Signed-off-by: Paul Mundt --- arch/sh/boot/compressed/misc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/sh') diff --git a/arch/sh/boot/compressed/misc.c b/arch/sh/boot/compressed/misc.c index d509a5050623..9ba07927d16a 100644 --- a/arch/sh/boot/compressed/misc.c +++ b/arch/sh/boot/compressed/misc.c @@ -117,7 +117,7 @@ void decompress_kernel(void) output_addr = (CONFIG_MEMORY_START + 0x2000); #else output_addr = __pa((unsigned long)&_text+PAGE_SIZE); -#ifdef CONFIG_29BIT +#if defined(CONFIG_29BIT) || defined(CONFIG_PMB_LEGACY) output_addr |= P2SEG; #endif #endif -- cgit v1.2.3 From 55cef91a5d553265f03fe159f9fcdfac36902248 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 16 Feb 2010 17:14:04 +0900 Subject: sh: Prevent fixed slot PMB remapping from clobbering boot entries. The PMB initialization code walks the entries and synchronizes the software PMB state with the hardware mappings, preserving the slot index. Unfortunately pmb_alloc() only tested the bit position in the entry map and failed to set it, resulting in subsequent remaps being able to be dynamically assigned a slot that trampled an existing boot mapping with general badness ensuing. Signed-off-by: Paul Mundt --- arch/sh/mm/pmb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/sh') diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c index 3c9bf5b5c36f..a06483076a41 100644 --- a/arch/sh/mm/pmb.c +++ b/arch/sh/mm/pmb.c @@ -77,7 +77,7 @@ static struct pmb_entry *pmb_alloc(unsigned long vpn, unsigned long ppn, if (pos < 0) return ERR_PTR(pos); } else { - if (test_bit(entry, &pmb_map)) + if (test_and_set_bit(entry, &pmb_map)) return ERR_PTR(-ENOSPC); pos = entry; } -- cgit v1.2.3 From efd54ea315f645ef318708aab5714a5f1f432d03 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 16 Feb 2010 18:39:30 +0900 Subject: sh: Merge the legacy PMB mapping and entry synchronization code. This merges the code for iterating over the legacy PMB mappings and the code for synchronizing software state with the hardware mappings. There's really no reason to do the same iteration twice, and this also buys us the legacy entry logging facility for the dynamic PMB case. Signed-off-by: Paul Mundt --- arch/sh/include/asm/mmu.h | 1 + arch/sh/mm/pmb.c | 162 ++++++++++++++++++++-------------------------- 2 files changed, 70 insertions(+), 93 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/mmu.h b/arch/sh/include/asm/mmu.h index ca7d91e8aa72..2fcbedb55002 100644 --- a/arch/sh/include/asm/mmu.h +++ b/arch/sh/include/asm/mmu.h @@ -25,6 +25,7 @@ #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) diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c index a06483076a41..f822f83418e4 100644 --- a/arch/sh/mm/pmb.c +++ b/arch/sh/mm/pmb.c @@ -276,41 +276,57 @@ static void __pmb_unmap(struct pmb_entry *pmbe) } while (pmbe); } -#ifdef CONFIG_PMB_LEGACY +static inline void +pmb_log_mapping(unsigned long data_val, unsigned long vpn, unsigned long ppn) +{ + unsigned int size; + const char *sz_str; + + size = data_val & PMB_SZ_MASK; + + sz_str = (size == PMB_SZ_16M) ? " 16MB": + (size == PMB_SZ_64M) ? " 64MB": + (size == PMB_SZ_128M) ? "128MB": + "512MB"; + + pr_info("\t0x%08lx -> 0x%08lx [ %s %scached ]\n", + vpn >> PAGE_SHIFT, ppn >> PAGE_SHIFT, sz_str, + (data_val & PMB_C) ? "" : "un"); +} + static inline unsigned int pmb_ppn_in_range(unsigned long ppn) { - return ppn >= __MEMORY_START && ppn < __MEMORY_START + __MEMORY_SIZE; + return ppn >= __pa(memory_start) && ppn < __pa(memory_end); } -static int pmb_apply_legacy_mappings(void) +static int pmb_synchronize_mappings(void) { unsigned int applied = 0; int i; - pr_info("PMB: Preserving legacy mappings:\n"); + pr_info("PMB: boot mappings:\n"); /* - * The following entries are setup by the bootloader. + * Run through the initial boot mappings, log the established + * ones, and blow away anything that falls outside of the valid + * PPN range. Specifically, we only care about existing mappings + * that impact the cached/uncached sections. * - * Entry VPN PPN V SZ C UB - * -------------------------------------------------------- - * 0 0xA0000000 0x00000000 1 64MB 0 0 - * 1 0xA4000000 0x04000000 1 16MB 0 0 - * 2 0xA6000000 0x08000000 1 16MB 0 0 - * 9 0x88000000 0x48000000 1 128MB 1 1 - * 10 0x90000000 0x50000000 1 128MB 1 1 - * 11 0x98000000 0x58000000 1 128MB 1 1 - * 13 0xA8000000 0x48000000 1 128MB 0 0 - * 14 0xB0000000 0x50000000 1 128MB 0 0 - * 15 0xB8000000 0x58000000 1 128MB 0 0 + * Note that touching these can be a bit of a minefield; the boot + * loader can establish multi-page mappings with the same caching + * attributes, so we need to ensure that we aren't modifying a + * mapping that we're presently executing from, or may execute + * from in the case of straddling page boundaries. * - * The only entries the we need are the ones that map the kernel - * at the cached and uncached addresses. + * In the future we will have to tidy up after the boot loader by + * jumping between the cached and uncached mappings and tearing + * down alternating mappings while executing from the other. */ for (i = 0; i < PMB_ENTRY_MAX; i++) { unsigned long addr, data; unsigned long addr_val, data_val; - unsigned long ppn, vpn; + unsigned long ppn, vpn, flags; + struct pmb_entry *pmbe; addr = mk_pmb_addr(i); data = mk_pmb_data(i); @@ -330,106 +346,66 @@ static int pmb_apply_legacy_mappings(void) /* * Only preserve in-range mappings. */ - if (pmb_ppn_in_range(ppn)) { - unsigned int size; - char *sz_str = NULL; - - size = data_val & PMB_SZ_MASK; - - sz_str = (size == PMB_SZ_16M) ? " 16MB": - (size == PMB_SZ_64M) ? " 64MB": - (size == PMB_SZ_128M) ? "128MB": - "512MB"; - - pr_info("\t0x%08lx -> 0x%08lx [ %s %scached ]\n", - vpn >> PAGE_SHIFT, ppn >> PAGE_SHIFT, sz_str, - (data_val & PMB_C) ? "" : "un"); - - applied++; - } else { + if (!pmb_ppn_in_range(ppn)) { /* * Invalidate anything out of bounds. */ __raw_writel(addr_val & ~PMB_V, addr); __raw_writel(data_val & ~PMB_V, data); + continue; } + + /* + * Update the caching attributes if necessary + */ + if (data_val & PMB_C) { +#if defined(CONFIG_CACHE_WRITETHROUGH) + data_val |= PMB_WT; +#elif defined(CONFIG_CACHE_WRITEBACK) + data_val &= ~PMB_WT; +#else + data_val &= ~(PMB_C | PMB_WT); +#endif + __raw_writel(data_val, data); + } + + flags = data_val & (PMB_SZ_MASK | PMB_CACHE_MASK); + + pmbe = pmb_alloc(vpn, ppn, flags, i); + if (IS_ERR(pmbe)) { + WARN_ON_ONCE(1); + continue; + } + + pmb_log_mapping(data_val, vpn, ppn); + + applied++; } return (applied == 0); } -#else -static inline int pmb_apply_legacy_mappings(void) -{ - return 1; -} -#endif int pmb_init(void) { - int i; - unsigned long addr, data; - unsigned long ret; + int ret; jump_to_uncached(); - /* - * Attempt to apply the legacy boot mappings if configured. If - * this is successful then we simply carry on with those and - * don't bother establishing additional memory mappings. Dynamic - * device mappings through pmb_remap() can still be bolted on - * after this. - */ - ret = pmb_apply_legacy_mappings(); - if (ret == 0) { - back_to_cached(); - return 0; - } - /* * Sync our software copy of the PMB mappings with those in * hardware. The mappings in the hardware PMB were either set up * by the bootloader or very early on by the kernel. */ - for (i = 0; i < PMB_ENTRY_MAX; i++) { - struct pmb_entry *pmbe; - unsigned long vpn, ppn, flags; - - addr = PMB_DATA + (i << PMB_E_SHIFT); - data = __raw_readl(addr); - if (!(data & PMB_V)) - continue; - - if (data & PMB_C) { -#if defined(CONFIG_CACHE_WRITETHROUGH) - data |= PMB_WT; -#elif defined(CONFIG_CACHE_WRITEBACK) - data &= ~PMB_WT; -#else - data &= ~(PMB_C | PMB_WT); -#endif - } - __raw_writel(data, addr); - - ppn = data & PMB_PFN_MASK; - - flags = data & (PMB_C | PMB_WT | PMB_UB); - flags |= data & PMB_SZ_MASK; - - addr = PMB_ADDR + (i << PMB_E_SHIFT); - data = __raw_readl(addr); - - vpn = data & PMB_PFN_MASK; - - pmbe = pmb_alloc(vpn, ppn, flags, i); - WARN_ON(IS_ERR(pmbe)); + ret = pmb_synchronize_mappings(); + if (unlikely(ret == 0)) { + back_to_cached(); + return 0; } __raw_writel(0, PMB_IRMCR); /* Flush out the TLB */ - i = __raw_readl(MMUCR); - i |= MMUCR_TI; - __raw_writel(i, MMUCR); + __raw_writel(__raw_readl(MMUCR) | MMUCR_TI, MMUCR); back_to_cached(); -- cgit v1.2.3 From 1d5cfcdff793e2f34ec61d902fa5ee0c7e4a2208 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 16 Feb 2010 21:43:38 +0900 Subject: sh: Kill off some superfluous legacy PMB special casing. The __va()/__pa() offsets and the boot memory offsets are consistent for all PMB users, so there is no need to special case these for legacy PMB. Kill the special casing off and depend on CONFIG_PMB across the board. This also fixes up yet another addressing bug for sh64. Signed-off-by: Paul Mundt --- arch/sh/include/asm/page.h | 7 +------ arch/sh/kernel/vmlinux.lds.S | 7 +++---- 2 files changed, 4 insertions(+), 10 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/page.h b/arch/sh/include/asm/page.h index 61e58105adc3..3accdc5ab122 100644 --- a/arch/sh/include/asm/page.h +++ b/arch/sh/include/asm/page.h @@ -127,12 +127,7 @@ 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_LEGACY) -/* 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) +#ifdef CONFIG_PMB #define __pa(x) ((unsigned long)(x)-PAGE_OFFSET+__MEMORY_START) #define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET-__MEMORY_START)) #else diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S index 0e66c7b30e0f..7f8a709c3ada 100644 --- a/arch/sh/kernel/vmlinux.lds.S +++ b/arch/sh/kernel/vmlinux.lds.S @@ -14,11 +14,10 @@ OUTPUT_ARCH(sh) #include #include -#if defined(CONFIG_29BIT) || defined(CONFIG_SUPERH64) || \ - defined(CONFIG_PMB_LEGACY) - #define MEMORY_OFFSET __MEMORY_START +#ifdef CONFIG_PMB + #define MEMORY_OFFSET 0 #else - #define MEMORY_OFFSET 0 + #define MEMORY_OFFSET __MEMORY_START #endif ENTRY(_start) -- cgit v1.2.3 From 49f3bfe9334a4cf86079d2ee1d08e674b58862a9 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 17 Feb 2010 12:33:22 +0900 Subject: sh: Setup boot CPU VBR early to enable early page faults. vmemmap and the vmsplit code amongst others need to be able to take page faults much earlier than trap_init() time, so move this in to the early CPU initialization. VBR setup for secondary CPUs is already handled through start_secondary(), so we only need to do this for the boot CPU. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/init.c | 21 +++++++++++++++++---- arch/sh/kernel/traps_32.c | 7 ------- 2 files changed, 17 insertions(+), 11 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c index 6311b0b1789d..c736422344eb 100644 --- a/arch/sh/kernel/cpu/init.c +++ b/arch/sh/kernel/cpu/init.c @@ -24,6 +24,7 @@ #include #include #include +#include #ifdef CONFIG_SH_FPU #define cpu_has_fpu 1 @@ -342,9 +343,21 @@ asmlinkage void __init sh_cpu_init(void) speculative_execution_init(); expmask_init(); - /* - * Boot processor to setup the FP and extended state context info. - */ - if (raw_smp_processor_id() == 0) + /* Do the rest of the boot processor setup */ + if (raw_smp_processor_id() == 0) { + /* Save off the BIOS VBR, if there is one */ + sh_bios_vbr_init(); + + /* + * Setup VBR for boot CPU. Secondary CPUs do this through + * start_secondary(). + */ + per_cpu_trap_init(); + + /* + * Boot processor to setup the FP and extended state + * context info. + */ init_thread_xstate(); + } } diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c index 9c090cb68878..c3d86fa71ddf 100644 --- a/arch/sh/kernel/traps_32.c +++ b/arch/sh/kernel/traps_32.c @@ -30,7 +30,6 @@ #include #include #include -#include #ifdef CONFIG_CPU_SH2 # define TRAP_RESERVED_INST 4 @@ -848,12 +847,6 @@ void __init trap_init(void) #ifdef TRAP_UBC set_exception_table_vec(TRAP_UBC, breakpoint_trap_handler); #endif - - /* Save off the BIOS VBR, if there is one */ - sh_bios_vbr_init(); - - /* Setup VBR for boot cpu */ - per_cpu_trap_init(); } void show_stack(struct task_struct *tsk, unsigned long *sp) -- cgit v1.2.3 From e9125ac0bf78bc19181359a3411d2e2bb757942d Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 16 Feb 2010 05:17:52 +0000 Subject: sh: fix sh7722 SDHI support using INTC force_disable Update the sh7722 INTC tables with force_enable support to mask out pending unsupported SDHI interrupt sources. Without this patch the kernel locks up due to a pending SDHI interrupt that the tmio_mmc driver cannot handle. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/setup-sh7722.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'arch/sh') diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index 0949135a125c..ef3f97827808 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c @@ -447,6 +447,7 @@ void __init plat_early_device_setup(void) enum { UNUSED=0, ENABLED, + DISABLED, /* interrupt sources */ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7, @@ -534,7 +535,7 @@ static struct intc_mask_reg mask_registers[] __initdata = { { I2C_DTEI, I2C_WAITI, I2C_TACKI, I2C_ALI, FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLENDI, FLCTL_FLSTEI } }, { 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */ - { 0, 0, ENABLED, ENABLED, 0, 0, TWODG, SIU } }, + { DISABLED, DISABLED, ENABLED, ENABLED, 0, 0, TWODG, SIU } }, { 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */ { 0, 0, 0, CMT, 0, USB_USBI1, USB_USBI0, } }, { 0xa40800a8, 0xa40800e8, 8, /* IMR10 / IMCR10 */ @@ -575,6 +576,7 @@ static struct intc_mask_reg ack_registers[] __initdata = { static struct intc_desc intc_desc __initdata = { .name = "sh7722", .force_enable = ENABLED, + .force_disable = DISABLED, .hw = INTC_HW_DESC(vectors, groups, mask_registers, prio_registers, sense_registers, ack_registers), }; -- cgit v1.2.3 From 838a4a9dcee0cbaeb0943531da00ac44d578f315 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 16 Feb 2010 05:19:19 +0000 Subject: sh: fix sh7723 SDHI support using INTC force_disable Update the sh7723 INTC tables with force_enable support to mask out pending unsupported SDHI interrupt sources. Without this patch the kernel locks up due to a pending SDHI interrupt that the tmio_mmc driver cannot handle. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/setup-sh7723.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c index 7b90ebcfa20e..85c61f624702 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c @@ -602,6 +602,7 @@ void l2_cache_init(void) enum { UNUSED=0, ENABLED, + DISABLED, /* interrupt sources */ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7, @@ -745,7 +746,7 @@ static struct intc_group groups[] __initdata = { static struct intc_mask_reg mask_registers[] __initdata = { { 0xa4080080, 0xa40800c0, 8, /* IMR0 / IMCR0 */ { 0, TMU1_TUNI2, TMU1_TUNI1, TMU1_TUNI0, - 0, 0, ENABLED, ENABLED } }, + 0, DISABLED, ENABLED, ENABLED } }, { 0xa4080084, 0xa40800c4, 8, /* IMR1 / IMCR1 */ { VIO_VOUI, VIO_VEU2HI,VIO_BEUI,VIO_CEUI,DMAC0A_DEI3,DMAC0A_DEI2,DMAC0A_DEI1,DMAC0A_DEI0 } }, { 0xa4080088, 0xa40800c8, 8, /* IMR2 / IMCR2 */ @@ -762,7 +763,7 @@ static struct intc_mask_reg mask_registers[] __initdata = { { I2C_DTEI, I2C_WAITI, I2C_TACKI, I2C_ALI, FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLTENDI, FLCTL_FLSTEI } }, { 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */ - { 0, 0, ENABLED, ENABLED, + { 0, DISABLED, ENABLED, ENABLED, 0, 0, SCIFA_SCIFA2, SIU_SIUI } }, { 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */ { 0, 0, 0, CMT_CMTI, 0, 0, USB_USI0,0 } }, @@ -806,6 +807,7 @@ static struct intc_mask_reg ack_registers[] __initdata = { static struct intc_desc intc_desc __initdata = { .name = "sh7723", .force_enable = ENABLED, + .force_disable = DISABLED, .hw = INTC_HW_DESC(vectors, groups, mask_registers, prio_registers, sense_registers, ack_registers), }; -- cgit v1.2.3 From 7bdda6209f224aa784a036df54b22cb338d2e859 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 17 Feb 2010 13:23:00 +0900 Subject: sh: Fix up more 64-bit pgprot truncation on SH-X2 TLB. Both the store queue API and the PMB remapping take unsigned long for their pgprot flags, which cuts off the extended protection bits. In the case of the PMB this isn't really a problem since the cache attribute bits that we care about are all in the lower 32-bits, but we do it just to be safe. The store queue remapping on the other hand depends on the extended prot bits for enabling userspace access to the mappings. Signed-off-by: Paul Mundt --- arch/sh/include/asm/mmu.h | 5 +++-- arch/sh/include/cpu-sh4/cpu/sq.h | 3 ++- arch/sh/kernel/cpu/sh4/sq.c | 13 ++++++------- arch/sh/mm/ioremap.c | 2 +- arch/sh/mm/pmb.c | 6 +++++- drivers/video/pvr2fb.c | 2 +- 6 files changed, 18 insertions(+), 13 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/mmu.h b/arch/sh/include/asm/mmu.h index 2fcbedb55002..151bc922701b 100644 --- a/arch/sh/include/asm/mmu.h +++ b/arch/sh/include/asm/mmu.h @@ -33,6 +33,7 @@ #ifndef __ASSEMBLY__ #include #include +#include /* Default "unsigned long" context */ typedef unsigned long mm_context_id_t[NR_CPUS]; @@ -71,13 +72,13 @@ struct pmb_entry { #ifdef CONFIG_PMB /* arch/sh/mm/pmb.c */ long pmb_remap(unsigned long virt, unsigned long phys, - unsigned long size, unsigned long flags); + unsigned long size, pgprot_t prot); void pmb_unmap(unsigned long addr); int pmb_init(void); bool __in_29bit_mode(void); #else static inline long pmb_remap(unsigned long virt, unsigned long phys, - unsigned long size, unsigned long flags) + unsigned long size, pgprot_t prot) { return -EINVAL; } diff --git a/arch/sh/include/cpu-sh4/cpu/sq.h b/arch/sh/include/cpu-sh4/cpu/sq.h index 586d6491816a..74716ba2dc3c 100644 --- a/arch/sh/include/cpu-sh4/cpu/sq.h +++ b/arch/sh/include/cpu-sh4/cpu/sq.h @@ -12,6 +12,7 @@ #define __ASM_CPU_SH4_SQ_H #include +#include /* * Store queues range from e0000000-e3fffffc, allowing approx. 64MB to be @@ -28,7 +29,7 @@ /* arch/sh/kernel/cpu/sh4/sq.c */ unsigned long sq_remap(unsigned long phys, unsigned int size, - const char *name, unsigned long flags); + const char *name, pgprot_t prot); void sq_unmap(unsigned long vaddr); void sq_flush_range(unsigned long start, unsigned int len); diff --git a/arch/sh/kernel/cpu/sh4/sq.c b/arch/sh/kernel/cpu/sh4/sq.c index 97aea9d69b00..fc065f9da6e5 100644 --- a/arch/sh/kernel/cpu/sh4/sq.c +++ b/arch/sh/kernel/cpu/sh4/sq.c @@ -100,7 +100,7 @@ static inline void sq_mapping_list_del(struct sq_mapping *map) spin_unlock_irq(&sq_mapping_lock); } -static int __sq_remap(struct sq_mapping *map, unsigned long flags) +static int __sq_remap(struct sq_mapping *map, pgprot_t prot) { #if defined(CONFIG_MMU) struct vm_struct *vma; @@ -113,7 +113,7 @@ static int __sq_remap(struct sq_mapping *map, unsigned long flags) if (ioremap_page_range((unsigned long)vma->addr, (unsigned long)vma->addr + map->size, - vma->phys_addr, __pgprot(flags))) { + vma->phys_addr, prot)) { vunmap(vma->addr); return -EAGAIN; } @@ -135,14 +135,14 @@ static int __sq_remap(struct sq_mapping *map, unsigned long flags) * @phys: Physical address of mapping. * @size: Length of mapping. * @name: User invoking mapping. - * @flags: Protection flags. + * @prot: Protection bits. * * Remaps the physical address @phys through the next available store queue * address of @size length. @name is logged at boot time as well as through * the sysfs interface. */ unsigned long sq_remap(unsigned long phys, unsigned int size, - const char *name, unsigned long flags) + const char *name, pgprot_t prot) { struct sq_mapping *map; unsigned long end; @@ -177,7 +177,7 @@ unsigned long sq_remap(unsigned long phys, unsigned int size, map->sq_addr = P4SEG_STORE_QUE + (page << PAGE_SHIFT); - ret = __sq_remap(map, pgprot_val(PAGE_KERNEL_NOCACHE) | flags); + ret = __sq_remap(map, prot); if (unlikely(ret != 0)) goto out; @@ -309,8 +309,7 @@ static ssize_t mapping_store(const char *buf, size_t count) return -EIO; if (likely(len)) { - int ret = sq_remap(base, len, "Userspace", - pgprot_val(PAGE_SHARED)); + int ret = sq_remap(base, len, "Userspace", PAGE_SHARED); if (ret < 0) return ret; } else diff --git a/arch/sh/mm/ioremap.c b/arch/sh/mm/ioremap.c index 94583c5da855..c68d2d7d00a9 100644 --- a/arch/sh/mm/ioremap.c +++ b/arch/sh/mm/ioremap.c @@ -80,7 +80,7 @@ __ioremap_caller(unsigned long phys_addr, unsigned long size, if (unlikely(phys_addr >= P1SEG)) { unsigned long mapped; - mapped = pmb_remap(addr, phys_addr, size, pgprot_val(pgprot)); + mapped = pmb_remap(addr, phys_addr, size, pgprot); if (likely(mapped)) { addr += mapped; phys_addr += mapped; diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c index f822f83418e4..509a444a30ab 100644 --- a/arch/sh/mm/pmb.c +++ b/arch/sh/mm/pmb.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -166,12 +167,15 @@ static struct { }; long pmb_remap(unsigned long vaddr, unsigned long phys, - unsigned long size, unsigned long flags) + unsigned long size, pgprot_t prot) { struct pmb_entry *pmbp, *pmbe; unsigned long wanted; int pmb_flags, i; long err; + u64 flags; + + flags = pgprot_val(prot); /* Convert typical pgprot value to the PMB equivalent */ if (flags & _PAGE_CACHABLE) { diff --git a/drivers/video/pvr2fb.c b/drivers/video/pvr2fb.c index 53f8f1100e81..f9975100d56d 100644 --- a/drivers/video/pvr2fb.c +++ b/drivers/video/pvr2fb.c @@ -831,7 +831,7 @@ static int __devinit pvr2fb_common_init(void) printk(KERN_NOTICE "fb%d: registering with SQ API\n", fb_info->node); pvr2fb_map = sq_remap(fb_info->fix.smem_start, fb_info->fix.smem_len, - fb_info->fix.id, pgprot_val(PAGE_SHARED)); + fb_info->fix.id, PAGE_SHARED); printk(KERN_NOTICE "fb%d: Mapped video memory to SQ addr 0x%lx\n", fb_info->node, pvr2fb_map); -- cgit v1.2.3 From 51becfd96287b3913b13075699433730984e2f4f Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 17 Feb 2010 15:33:30 +0900 Subject: sh: PMB tidying. Some overdue cleanup of the PMB code, killing off unused functionality and duplication sprinkled about the tree. Signed-off-by: Paul Mundt --- arch/sh/include/asm/mmu.h | 4 ++- arch/sh/kernel/head_32.S | 2 +- arch/sh/mm/pmb.c | 83 ++++++++++++++++++++++------------------------- 3 files changed, 42 insertions(+), 47 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/mmu.h b/arch/sh/include/asm/mmu.h index 151bc922701b..44c904341414 100644 --- a/arch/sh/include/asm/mmu.h +++ b/arch/sh/include/asm/mmu.h @@ -11,7 +11,9 @@ #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 diff --git a/arch/sh/kernel/head_32.S b/arch/sh/kernel/head_32.S index 83f2b84b58da..91ae76277d8f 100644 --- a/arch/sh/kernel/head_32.S +++ b/arch/sh/kernel/head_32.S @@ -236,7 +236,7 @@ ENTRY(_stext) * r10 = number of entries we've setup so far */ mov #0, r1 - mov #PMB_ENTRY_MAX, r0 + mov #NR_PMB_ENTRIES, r0 .Lagain: mov.l r1, @r3 /* Clear PMB_ADDR entry */ diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c index 509a444a30ab..924f3e4b3a82 100644 --- a/arch/sh/mm/pmb.c +++ b/arch/sh/mm/pmb.c @@ -21,32 +21,31 @@ #include #include #include +#include +#include #include #include #include #include #include -#include #include -#define NR_PMB_ENTRIES 16 - -static void __pmb_unmap(struct pmb_entry *); +static void pmb_unmap_entry(struct pmb_entry *); static struct pmb_entry pmb_entry_list[NR_PMB_ENTRIES]; -static unsigned long pmb_map; +static DECLARE_BITMAP(pmb_map, NR_PMB_ENTRIES); -static inline unsigned long mk_pmb_entry(unsigned int entry) +static __always_inline unsigned long mk_pmb_entry(unsigned int entry) { return (entry & PMB_E_MASK) << PMB_E_SHIFT; } -static inline unsigned long mk_pmb_addr(unsigned int entry) +static __always_inline unsigned long mk_pmb_addr(unsigned int entry) { return mk_pmb_entry(entry) | PMB_ADDR; } -static inline unsigned long mk_pmb_data(unsigned int entry) +static __always_inline unsigned long mk_pmb_data(unsigned int entry) { return mk_pmb_entry(entry) | PMB_DATA; } @@ -56,12 +55,12 @@ static int pmb_alloc_entry(void) unsigned int pos; repeat: - pos = find_first_zero_bit(&pmb_map, NR_PMB_ENTRIES); + pos = find_first_zero_bit(pmb_map, NR_PMB_ENTRIES); if (unlikely(pos > NR_PMB_ENTRIES)) return -ENOSPC; - if (test_and_set_bit(pos, &pmb_map)) + if (test_and_set_bit(pos, pmb_map)) goto repeat; return pos; @@ -78,7 +77,7 @@ static struct pmb_entry *pmb_alloc(unsigned long vpn, unsigned long ppn, if (pos < 0) return ERR_PTR(pos); } else { - if (test_and_set_bit(entry, &pmb_map)) + if (test_and_set_bit(entry, pmb_map)) return ERR_PTR(-ENOSPC); pos = entry; } @@ -104,16 +103,17 @@ static void pmb_free(struct pmb_entry *pmbe) pmbe->flags = 0; pmbe->entry = 0; - clear_bit(pos, &pmb_map); + clear_bit(pos, pmb_map); } /* - * Must be in P2 for __set_pmb_entry() + * Must be run uncached. */ -static void __set_pmb_entry(unsigned long vpn, unsigned long ppn, - unsigned long flags, int pos) +static void set_pmb_entry(struct pmb_entry *pmbe) { - __raw_writel(vpn | PMB_V, mk_pmb_addr(pos)); + jump_to_uncached(); + + __raw_writel(pmbe->vpn | PMB_V, mk_pmb_addr(pmbe->entry)); #ifdef CONFIG_CACHE_WRITETHROUGH /* @@ -121,17 +121,12 @@ static void __set_pmb_entry(unsigned long vpn, unsigned long ppn, * invalid, so care must be taken to manually adjust cacheable * translations. */ - if (likely(flags & PMB_C)) - flags |= PMB_WT; + if (likely(pmbe->flags & PMB_C)) + pmbe->flags |= PMB_WT; #endif - __raw_writel(ppn | flags | PMB_V, mk_pmb_data(pos)); -} + __raw_writel(pmbe->ppn | pmbe->flags | PMB_V, mk_pmb_data(pmbe->entry)); -static void set_pmb_entry(struct pmb_entry *pmbe) -{ - jump_to_uncached(); - __set_pmb_entry(pmbe->vpn, pmbe->ppn, pmbe->flags, pmbe->entry); back_to_cached(); } @@ -140,9 +135,6 @@ static void clear_pmb_entry(struct pmb_entry *pmbe) unsigned int entry = pmbe->entry; unsigned long addr; - if (unlikely(entry >= NR_PMB_ENTRIES)) - return; - jump_to_uncached(); /* Clear V-bit */ @@ -155,15 +147,14 @@ static void clear_pmb_entry(struct pmb_entry *pmbe) back_to_cached(); } - static struct { unsigned long size; int flag; } pmb_sizes[] = { - { .size = 0x20000000, .flag = PMB_SZ_512M, }, - { .size = 0x08000000, .flag = PMB_SZ_128M, }, - { .size = 0x04000000, .flag = PMB_SZ_64M, }, - { .size = 0x01000000, .flag = PMB_SZ_16M, }, + { .size = SZ_512M, .flag = PMB_SZ_512M, }, + { .size = SZ_128M, .flag = PMB_SZ_128M, }, + { .size = SZ_64M, .flag = PMB_SZ_64M, }, + { .size = SZ_16M, .flag = PMB_SZ_16M, }, }; long pmb_remap(unsigned long vaddr, unsigned long phys, @@ -230,34 +221,36 @@ again: return wanted - size; out: - if (pmbp) - __pmb_unmap(pmbp); + pmb_unmap_entry(pmbp); return err; } void pmb_unmap(unsigned long addr) { - struct pmb_entry *pmbe = NULL; + struct pmb_entry *pmbe; int i; for (i = 0; i < ARRAY_SIZE(pmb_entry_list); i++) { - if (test_bit(i, &pmb_map)) { + if (test_bit(i, pmb_map)) { pmbe = &pmb_entry_list[i]; - if (pmbe->vpn == addr) + if (pmbe->vpn == addr) { + pmb_unmap_entry(pmbe); break; + } } } +} +static void pmb_unmap_entry(struct pmb_entry *pmbe) +{ if (unlikely(!pmbe)) return; - __pmb_unmap(pmbe); -} - -static void __pmb_unmap(struct pmb_entry *pmbe) -{ - BUG_ON(!test_bit(pmbe->entry, &pmb_map)); + if (!test_bit(pmbe->entry, pmb_map)) { + WARN_ON(1); + return; + } do { struct pmb_entry *pmblink = pmbe; @@ -326,7 +319,7 @@ static int pmb_synchronize_mappings(void) * jumping between the cached and uncached mappings and tearing * down alternating mappings while executing from the other. */ - for (i = 0; i < PMB_ENTRY_MAX; i++) { + for (i = 0; i < NR_PMB_ENTRIES; i++) { unsigned long addr, data; unsigned long addr_val, data_val; unsigned long ppn, vpn, flags; @@ -494,7 +487,7 @@ static int pmb_sysdev_suspend(struct sys_device *dev, pm_message_t state) prev_state.event == PM_EVENT_FREEZE) { struct pmb_entry *pmbe; for (i = 0; i < ARRAY_SIZE(pmb_entry_list); i++) { - if (test_bit(i, &pmb_map)) { + if (test_bit(i, pmb_map)) { pmbe = &pmb_entry_list[i]; set_pmb_entry(pmbe); } -- cgit v1.2.3 From 9edef28653a519bf0a48250f36cce96b1736ec4e Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 17 Feb 2010 16:28:00 +0900 Subject: sh: uncached mapping helpers. This adds some helper routines for uncached mapping support. This simplifies some of the cases where we need to check the uncached mapping boundaries in addition to giving us a centralized location for building more complex manipulation on top of. Signed-off-by: Paul Mundt --- arch/sh/include/asm/page.h | 19 ++++++++++++++++++- arch/sh/include/asm/ptrace.h | 11 ++--------- arch/sh/kernel/head_32.S | 8 +++++++- arch/sh/mm/Makefile | 1 + arch/sh/mm/init.c | 21 ++------------------- arch/sh/mm/uncached.c | 28 ++++++++++++++++++++++++++++ 6 files changed, 58 insertions(+), 30 deletions(-) create mode 100644 arch/sh/mm/uncached.c (limited to 'arch/sh') diff --git a/arch/sh/include/asm/page.h b/arch/sh/include/asm/page.h index 3accdc5ab122..8237d9f53e56 100644 --- a/arch/sh/include/asm/page.h +++ b/arch/sh/include/asm/page.h @@ -50,13 +50,22 @@ extern unsigned long shm_align_mask; extern unsigned long max_low_pfn, min_low_pfn; extern unsigned long memory_start, memory_end; +#ifdef CONFIG_UNCACHED_MAPPING +extern unsigned long uncached_start, uncached_end; + +extern int virt_addr_uncached(unsigned long kaddr); +extern void uncached_init(void); +#else +#define virt_addr_uncached(kaddr) (0) +#define uncached_init() do { } while (0) +#endif + 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); @@ -135,6 +144,14 @@ typedef struct page *pgtable_t; #define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET)) #endif +#ifdef CONFIG_UNCACHED_MAPPING +#define UNCAC_ADDR(addr) ((addr) - PAGE_OFFSET + uncached_start) +#define CAC_ADDR(addr) ((addr) - uncached_start + PAGE_OFFSET) +#else +#define UNCAC_ADDR(addr) ((addr)) +#define CAC_ADDR(addr) ((addr)) +#endif + #define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) #define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) diff --git a/arch/sh/include/asm/ptrace.h b/arch/sh/include/asm/ptrace.h index e879dffa324b..e11b14ea2c43 100644 --- a/arch/sh/include/asm/ptrace.h +++ b/arch/sh/include/asm/ptrace.h @@ -139,15 +139,8 @@ static inline unsigned long profile_pc(struct pt_regs *regs) { unsigned long pc = instruction_pointer(regs); -#ifdef CONFIG_UNCACHED_MAPPING - /* - * If PC points in to the uncached mapping, fix it up and hand - * back the cached equivalent. - */ - if ((pc >= (memory_start + cached_to_uncached)) && - (pc < (memory_start + cached_to_uncached + uncached_size))) - pc -= cached_to_uncached; -#endif + if (virt_addr_uncached(pc)) + return CAC_ADDR(pc); return pc; } diff --git a/arch/sh/kernel/head_32.S b/arch/sh/kernel/head_32.S index 91ae76277d8f..79ff39517f8e 100644 --- a/arch/sh/kernel/head_32.S +++ b/arch/sh/kernel/head_32.S @@ -152,6 +152,7 @@ ENTRY(_stext) mov #0, r10 +#ifdef CONFIG_UNCACHED_MAPPING /* * Uncached mapping */ @@ -171,6 +172,7 @@ ENTRY(_stext) add r4, r1 add r4, r3 add #1, r10 +#endif /* * Iterate over all of the available sizes from largest to @@ -216,6 +218,7 @@ ENTRY(_stext) __PMB_ITER_BY_SIZE(64) __PMB_ITER_BY_SIZE(16) +#ifdef CONFIG_UNCACHED_MAPPING /* * Now that we can access it, update cached_to_uncached and * uncached_size. @@ -228,6 +231,7 @@ ENTRY(_stext) shll16 r7 shll8 r7 mov.l r7, @r0 +#endif /* * Clear the remaining PMB entries. @@ -306,7 +310,9 @@ ENTRY(stack_start) .LFIRST_ADDR_ENTRY: .long PAGE_OFFSET | PMB_V .LFIRST_DATA_ENTRY: .long __MEMORY_START | PMB_V .LMMUCR: .long MMUCR +.LMEMORY_SIZE: .long __MEMORY_SIZE +#ifdef CONFIG_UNCACHED_MAPPING .Lcached_to_uncached: .long cached_to_uncached .Luncached_size: .long uncached_size -.LMEMORY_SIZE: .long __MEMORY_SIZE +#endif #endif diff --git a/arch/sh/mm/Makefile b/arch/sh/mm/Makefile index de714cbd961a..3dc8a8a63822 100644 --- a/arch/sh/mm/Makefile +++ b/arch/sh/mm/Makefile @@ -36,6 +36,7 @@ obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o obj-$(CONFIG_PMB) += pmb.o obj-$(CONFIG_NUMA) += numa.o obj-$(CONFIG_IOREMAP_FIXED) += ioremap_fixed.o +obj-$(CONFIG_UNCACHED_MAPPING) += uncached.o # Special flags for fault_64.o. This puts restrictions on the number of # caller-save registers that the compiler can target when building this file. diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 58012b6bbe76..08e280d7cc7e 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -26,21 +26,6 @@ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); pgd_t swapper_pg_dir[PTRS_PER_PGD]; -#ifdef CONFIG_UNCACHED_MAPPING -/* - * This is the offset of the uncached section from its cached alias. - * - * Legacy platforms handle trivial transitions between cached and - * uncached segments by making use of the 1:1 mapping relationship in - * 512MB lowmem, others via a special uncached mapping. - * - * Default value only valid in 29 bit mode, in 32bit mode this will be - * updated by the early PMB initialization code. - */ -unsigned long cached_to_uncached = 0x20000000; -unsigned long uncached_size = SZ_512M; -#endif - #ifdef CONFIG_MMU static pte_t *__get_pte_phys(unsigned long addr) { @@ -260,7 +245,7 @@ void __init mem_init(void) memset(empty_zero_page, 0, PAGE_SIZE); __flush_wback_region(empty_zero_page, PAGE_SIZE); - /* Initialize the vDSO */ + uncached_init(); vsyscall_init(); codesize = (unsigned long) &_etext - (unsigned long) &_text; @@ -303,9 +288,7 @@ void __init mem_init(void) ((unsigned long)high_memory - (unsigned long)memory_start) >> 20, #ifdef CONFIG_UNCACHED_MAPPING - (unsigned long)memory_start + cached_to_uncached, - (unsigned long)memory_start + cached_to_uncached + uncached_size, - uncached_size >> 20, + uncached_start, uncached_end, uncached_size >> 20, #endif (unsigned long)&__init_begin, (unsigned long)&__init_end, diff --git a/arch/sh/mm/uncached.c b/arch/sh/mm/uncached.c new file mode 100644 index 000000000000..807906981d9d --- /dev/null +++ b/arch/sh/mm/uncached.c @@ -0,0 +1,28 @@ +#include +#include +#include + +/* + * This is the offset of the uncached section from its cached alias. + * + * Legacy platforms handle trivial transitions between cached and + * uncached segments by making use of the 1:1 mapping relationship in + * 512MB lowmem, others via a special uncached mapping. + * + * Default value only valid in 29 bit mode, in 32bit mode this will be + * updated by the early PMB initialization code. + */ +unsigned long cached_to_uncached = SZ_512M; +unsigned long uncached_size = SZ_512M; +unsigned long uncached_start, uncached_end; + +int virt_addr_uncached(unsigned long kaddr) +{ + return (kaddr >= uncached_start) && (kaddr < uncached_end); +} + +void __init uncached_init(void) +{ + uncached_start = memory_end; + uncached_end = uncached_start + uncached_size; +} -- cgit v1.2.3 From d7813bc9e8e384f5a293b05c095c799d41af3668 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 17 Feb 2010 17:56:38 +0900 Subject: sh: Build PMB entry links for existing contiguous multi-page mappings. This plugs in entry sizing support for existing mappings and then builds on top of that for linking together entries that are mapping contiguous areas. This will ultimately permit us to coalesce mappings and promote head pages while reclaiming PMB slots for dynamic remapping. Signed-off-by: Paul Mundt --- arch/sh/include/asm/mmu.h | 2 +- arch/sh/mm/pmb.c | 59 +++++++++++++++++++++++------------------------ 2 files changed, 30 insertions(+), 31 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/mmu.h b/arch/sh/include/asm/mmu.h index 44c904341414..5453169bf052 100644 --- a/arch/sh/include/asm/mmu.h +++ b/arch/sh/include/asm/mmu.h @@ -59,6 +59,7 @@ struct pmb_entry { unsigned long vpn; unsigned long ppn; unsigned long flags; + unsigned long size; /* * 0 .. NR_PMB_ENTRIES for specific entry selection, or @@ -66,7 +67,6 @@ struct pmb_entry { */ int entry; - struct pmb_entry *next; /* Adjacent entry link for contiguous multi-entry mappings */ struct pmb_entry *link; }; diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c index 924f3e4b3a82..f2ad6e374b64 100644 --- a/arch/sh/mm/pmb.c +++ b/arch/sh/mm/pmb.c @@ -90,20 +90,15 @@ static struct pmb_entry *pmb_alloc(unsigned long vpn, unsigned long ppn, pmbe->ppn = ppn; pmbe->flags = flags; pmbe->entry = pos; + pmbe->size = 0; return pmbe; } static void pmb_free(struct pmb_entry *pmbe) { - int pos = pmbe->entry; - - pmbe->vpn = 0; - pmbe->ppn = 0; - pmbe->flags = 0; - pmbe->entry = 0; - - clear_bit(pos, pmb_map); + clear_bit(pmbe->entry, pmb_map); + pmbe->entry = PMB_NO_ENTRY; } /* @@ -198,6 +193,8 @@ again: vaddr += pmb_sizes[i].size; size -= pmb_sizes[i].size; + pmbe->size = pmb_sizes[i].size; + /* * Link adjacent entries that span multiple PMB entries * for easier tear-down. @@ -273,25 +270,7 @@ static void pmb_unmap_entry(struct pmb_entry *pmbe) } while (pmbe); } -static inline void -pmb_log_mapping(unsigned long data_val, unsigned long vpn, unsigned long ppn) -{ - unsigned int size; - const char *sz_str; - - size = data_val & PMB_SZ_MASK; - - sz_str = (size == PMB_SZ_16M) ? " 16MB": - (size == PMB_SZ_64M) ? " 64MB": - (size == PMB_SZ_128M) ? "128MB": - "512MB"; - - pr_info("\t0x%08lx -> 0x%08lx [ %s %scached ]\n", - vpn >> PAGE_SHIFT, ppn >> PAGE_SHIFT, sz_str, - (data_val & PMB_C) ? "" : "un"); -} - -static inline unsigned int pmb_ppn_in_range(unsigned long ppn) +static __always_inline unsigned int pmb_ppn_in_range(unsigned long ppn) { return ppn >= __pa(memory_start) && ppn < __pa(memory_end); } @@ -299,7 +278,8 @@ static inline unsigned int pmb_ppn_in_range(unsigned long ppn) static int pmb_synchronize_mappings(void) { unsigned int applied = 0; - int i; + struct pmb_entry *pmbp = NULL; + int i, j; pr_info("PMB: boot mappings:\n"); @@ -323,6 +303,7 @@ static int pmb_synchronize_mappings(void) unsigned long addr, data; unsigned long addr_val, data_val; unsigned long ppn, vpn, flags; + unsigned int size; struct pmb_entry *pmbe; addr = mk_pmb_addr(i); @@ -366,7 +347,8 @@ static int pmb_synchronize_mappings(void) __raw_writel(data_val, data); } - flags = data_val & (PMB_SZ_MASK | PMB_CACHE_MASK); + size = data_val & PMB_SZ_MASK; + flags = size | (data_val & PMB_CACHE_MASK); pmbe = pmb_alloc(vpn, ppn, flags, i); if (IS_ERR(pmbe)) { @@ -374,7 +356,24 @@ static int pmb_synchronize_mappings(void) continue; } - pmb_log_mapping(data_val, vpn, ppn); + for (j = 0; j < ARRAY_SIZE(pmb_sizes); j++) + if (pmb_sizes[j].flag == size) + pmbe->size = pmb_sizes[j].size; + + /* + * Compare the previous entry against the current one to + * see if the entries span a contiguous mapping. If so, + * setup the entry links accordingly. + */ + if (pmbp && ((pmbe->vpn == (pmbp->vpn + pmbp->size)) && + (pmbe->ppn == (pmbp->ppn + pmbp->size)))) + pmbp->link = pmbe; + + pmbp = pmbe; + + pr_info("\t0x%08lx -> 0x%08lx [ %ldMB %scached ]\n", + vpn >> PAGE_SHIFT, ppn >> PAGE_SHIFT, pmbe->size >> 20, + (data_val & PMB_C) ? "" : "un"); applied++; } -- cgit v1.2.3 From 0065b96775f1eff167a2c3343a41582e8fab4c6c Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 17 Feb 2010 18:05:23 +0900 Subject: sh: Fix up dynamically created write-through PMB mappings. Write-through PMB mappings still require the cache bit to be set, even if they're to be flagged with a different cache policy and bufferability bit. To reduce some of the confusion surrounding the flag encoding we centralize the cache mask based on the system cache policy while we're at it. Signed-off-by: Paul Mundt --- arch/sh/mm/pmb.c | 56 ++++++++++++++++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 24 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c index f2ad6e374b64..cb808a8aaffc 100644 --- a/arch/sh/mm/pmb.c +++ b/arch/sh/mm/pmb.c @@ -101,6 +101,26 @@ static void pmb_free(struct pmb_entry *pmbe) pmbe->entry = PMB_NO_ENTRY; } +/* + * Ensure that the PMB entries match our cache configuration. + * + * When we are in 32-bit address extended mode, CCR.CB becomes + * invalid, so care must be taken to manually adjust cacheable + * translations. + */ +static __always_inline unsigned long pmb_cache_flags(void) +{ + unsigned long flags = 0; + +#if defined(CONFIG_CACHE_WRITETHROUGH) + flags |= PMB_C | PMB_WT | PMB_UB; +#elif defined(CONFIG_CACHE_WRITEBACK) + flags |= PMB_C; +#endif + + return flags; +} + /* * Must be run uncached. */ @@ -108,18 +128,10 @@ static void set_pmb_entry(struct pmb_entry *pmbe) { jump_to_uncached(); - __raw_writel(pmbe->vpn | PMB_V, mk_pmb_addr(pmbe->entry)); - -#ifdef CONFIG_CACHE_WRITETHROUGH - /* - * When we are in 32-bit address extended mode, CCR.CB becomes - * invalid, so care must be taken to manually adjust cacheable - * translations. - */ - if (likely(pmbe->flags & PMB_C)) - pmbe->flags |= PMB_WT; -#endif + pmbe->flags &= ~PMB_CACHE_MASK; + pmbe->flags |= pmb_cache_flags(); + __raw_writel(pmbe->vpn | PMB_V, mk_pmb_addr(pmbe->entry)); __raw_writel(pmbe->ppn | pmbe->flags | PMB_V, mk_pmb_data(pmbe->entry)); back_to_cached(); @@ -163,14 +175,15 @@ long pmb_remap(unsigned long vaddr, unsigned long phys, flags = pgprot_val(prot); + pmb_flags = PMB_WT | PMB_UB; + /* Convert typical pgprot value to the PMB equivalent */ if (flags & _PAGE_CACHABLE) { - if (flags & _PAGE_WT) - pmb_flags = PMB_WT; - else - pmb_flags = PMB_C; - } else - pmb_flags = PMB_WT | PMB_UB; + pmb_flags |= PMB_C; + + if ((flags & _PAGE_WT) == 0) + pmb_flags &= ~(PMB_WT | PMB_UB); + } pmbp = NULL; wanted = size; @@ -337,13 +350,8 @@ static int pmb_synchronize_mappings(void) * Update the caching attributes if necessary */ if (data_val & PMB_C) { -#if defined(CONFIG_CACHE_WRITETHROUGH) - data_val |= PMB_WT; -#elif defined(CONFIG_CACHE_WRITEBACK) - data_val &= ~PMB_WT; -#else - data_val &= ~(PMB_C | PMB_WT); -#endif + data_val &= ~PMB_CACHE_MASK; + data_val |= pmb_cache_flags(); __raw_writel(data_val, data); } -- cgit v1.2.3 From e7b8e675d9c71b868b66f62f725a948047514719 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 26 Jan 2010 04:40:03 -0500 Subject: tracing: Unify arch_syscall_addr() implementations Most implementations of arch_syscall_addr() are the same, so create a default version in common code and move the one piece that differs (the syscall table) to asm/syscall.h. New arch ports don't have to waste time copying & pasting this simple function. The s390/sparc versions need to be different, so document why. Signed-off-by: Mike Frysinger Acked-by: David S. Miller Acked-by: Paul Mundt Acked-by: Heiko Carstens Cc: Steven Rostedt LKML-Reference: <1264498803-17278-1-git-send-email-vapier@gentoo.org> Signed-off-by: Frederic Weisbecker --- Documentation/trace/ftrace-design.txt | 5 ++--- arch/s390/include/asm/syscall.h | 7 +++++++ arch/s390/kernel/ftrace.c | 10 ---------- arch/sh/include/asm/syscall.h | 2 ++ arch/sh/kernel/ftrace.c | 9 --------- arch/sparc/include/asm/syscall.h | 7 +++++++ arch/sparc/kernel/ftrace.c | 11 ----------- arch/x86/include/asm/syscall.h | 2 ++ arch/x86/kernel/ftrace.c | 10 ---------- include/linux/ftrace.h | 6 ++++++ kernel/trace/trace_syscalls.c | 5 +++++ 11 files changed, 31 insertions(+), 43 deletions(-) (limited to 'arch/sh') diff --git a/Documentation/trace/ftrace-design.txt b/Documentation/trace/ftrace-design.txt index 239f14b2b55a..99df1101d2a5 100644 --- a/Documentation/trace/ftrace-design.txt +++ b/Documentation/trace/ftrace-design.txt @@ -218,11 +218,10 @@ HAVE_SYSCALL_TRACEPOINTS You need very few things to get the syscalls tracing in an arch. +- Support HAVE_ARCH_TRACEHOOK (see arch/Kconfig). - Have a NR_syscalls variable in that provides the number of syscalls supported by the arch. -- Implement arch_syscall_addr() that resolves a syscall address from a - syscall number. -- Support the TIF_SYSCALL_TRACEPOINT thread flags +- Support the TIF_SYSCALL_TRACEPOINT thread flags. - Put the trace_sys_enter() and trace_sys_exit() tracepoints calls from ptrace in the ptrace syscalls tracing path. - Tag this arch as HAVE_SYSCALL_TRACEPOINTS. diff --git a/arch/s390/include/asm/syscall.h b/arch/s390/include/asm/syscall.h index e0a73d3eb837..8429686951f9 100644 --- a/arch/s390/include/asm/syscall.h +++ b/arch/s390/include/asm/syscall.h @@ -15,6 +15,13 @@ #include #include +/* + * The syscall table always contains 32 bit pointers since we know that the + * address of the function to be called is (way) below 4GB. So the "int" + * type here is what we want [need] for both 32 bit and 64 bit systems. + */ +extern const unsigned int sys_call_table[]; + static inline long syscall_get_nr(struct task_struct *task, struct pt_regs *regs) { diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c index 5a82bc68193e..9e69449e77ad 100644 --- a/arch/s390/kernel/ftrace.c +++ b/arch/s390/kernel/ftrace.c @@ -200,13 +200,3 @@ out: return parent; } #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ - -#ifdef CONFIG_FTRACE_SYSCALLS - -extern unsigned int sys_call_table[]; - -unsigned long __init arch_syscall_addr(int nr) -{ - return (unsigned long)sys_call_table[nr]; -} -#endif diff --git a/arch/sh/include/asm/syscall.h b/arch/sh/include/asm/syscall.h index 6a381429ee9d..aa7777bdc370 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/kernel/ftrace.c b/arch/sh/kernel/ftrace.c index a48cdedc73b5..30e13196d35b 100644 --- a/arch/sh/kernel/ftrace.c +++ b/arch/sh/kernel/ftrace.c @@ -399,12 +399,3 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) } } #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ - -#ifdef CONFIG_FTRACE_SYSCALLS -extern unsigned long *sys_call_table; - -unsigned long __init arch_syscall_addr(int nr) -{ - return (unsigned long)sys_call_table[nr]; -} -#endif /* CONFIG_FTRACE_SYSCALLS */ diff --git a/arch/sparc/include/asm/syscall.h b/arch/sparc/include/asm/syscall.h index 7486c605e23c..025a02ad2e31 100644 --- a/arch/sparc/include/asm/syscall.h +++ b/arch/sparc/include/asm/syscall.h @@ -5,6 +5,13 @@ #include #include +/* + * The syscall table always contains 32 bit pointers since we know that the + * address of the function to be called is (way) below 4GB. So the "int" + * type here is what we want [need] for both 32 bit and 64 bit systems. + */ +extern const unsigned int sys_call_table[]; + /* The system call number is given by the user in %g1 */ static inline long syscall_get_nr(struct task_struct *task, struct pt_regs *regs) diff --git a/arch/sparc/kernel/ftrace.c b/arch/sparc/kernel/ftrace.c index 29973daa9930..9103a56b39e8 100644 --- a/arch/sparc/kernel/ftrace.c +++ b/arch/sparc/kernel/ftrace.c @@ -91,14 +91,3 @@ int __init ftrace_dyn_arch_init(void *data) return 0; } #endif - -#ifdef CONFIG_FTRACE_SYSCALLS - -extern unsigned int sys_call_table[]; - -unsigned long __init arch_syscall_addr(int nr) -{ - return (unsigned long)sys_call_table[nr]; -} - -#endif diff --git a/arch/x86/include/asm/syscall.h b/arch/x86/include/asm/syscall.h index 8d33bc5462d1..c4a348f7bd43 100644 --- a/arch/x86/include/asm/syscall.h +++ b/arch/x86/include/asm/syscall.h @@ -16,6 +16,8 @@ #include #include +extern const unsigned long sys_call_table[]; + /* * Only the low 32 bits of orig_ax are meaningful, so we return int. * This importantly ignores the high bits on 64-bit, so comparisons diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index 309689245431..0d93a941934c 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c @@ -484,13 +484,3 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, } } #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ - -#ifdef CONFIG_FTRACE_SYSCALLS - -extern unsigned long *sys_call_table; - -unsigned long __init arch_syscall_addr(int nr) -{ - return (unsigned long)(&sys_call_table)[nr]; -} -#endif diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 0b4f97d24d7f..1cbb36f2759c 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -511,4 +511,10 @@ static inline void trace_hw_branch_oops(void) {} #endif /* CONFIG_HW_BRANCH_TRACER */ +#ifdef CONFIG_FTRACE_SYSCALLS + +unsigned long arch_syscall_addr(int nr); + +#endif /* CONFIG_FTRACE_SYSCALLS */ + #endif /* _LINUX_FTRACE_H */ diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c index 49cea70fbf6d..ecf00782b46c 100644 --- a/kernel/trace/trace_syscalls.c +++ b/kernel/trace/trace_syscalls.c @@ -394,6 +394,11 @@ int init_syscall_trace(struct ftrace_event_call *call) return id; } +unsigned long __init arch_syscall_addr(int nr) +{ + return (unsigned long)sys_call_table[nr]; +} + int __init init_ftrace_syscalls(void) { struct syscall_metadata *meta; -- cgit v1.2.3 From d53a0d33bc3a50ea0e8dd1680a2e8435770b162a Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 17 Feb 2010 21:17:02 +0900 Subject: sh: PMB locking overhaul. This implements some locking for the PMB code. A high level rwlock is added for dealing with rw accesses on the entry map while a per-entry data structure spinlock is added to deal with the PMB entry changing out from underneath us. Signed-off-by: Paul Mundt --- arch/sh/include/asm/mmu.h | 18 ------ arch/sh/mm/pmb.c | 152 ++++++++++++++++++++++++++++++++++------------ 2 files changed, 114 insertions(+), 56 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/mmu.h b/arch/sh/include/asm/mmu.h index 5453169bf052..e42c4e2a41df 100644 --- a/arch/sh/include/asm/mmu.h +++ b/arch/sh/include/asm/mmu.h @@ -53,24 +53,6 @@ typedef struct { #endif } mm_context_t; -struct pmb_entry; - -struct pmb_entry { - unsigned long vpn; - unsigned long ppn; - unsigned long flags; - unsigned long size; - - /* - * 0 .. NR_PMB_ENTRIES for specific entry selection, or - * PMB_NO_ENTRY to search for a free one - */ - int entry; - - /* Adjacent entry link for contiguous multi-entry mappings */ - struct pmb_entry *link; -}; - #ifdef CONFIG_PMB /* arch/sh/mm/pmb.c */ long pmb_remap(unsigned long virt, unsigned long phys, diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c index cb808a8aaffc..e65e8b8e2a5e 100644 --- a/arch/sh/mm/pmb.c +++ b/arch/sh/mm/pmb.c @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include #include #include @@ -30,8 +32,29 @@ #include #include +struct pmb_entry; + +struct pmb_entry { + unsigned long vpn; + unsigned long ppn; + unsigned long flags; + unsigned long size; + + spinlock_t lock; + + /* + * 0 .. NR_PMB_ENTRIES for specific entry selection, or + * PMB_NO_ENTRY to search for a free one + */ + int entry; + + /* Adjacent entry link for contiguous multi-entry mappings */ + struct pmb_entry *link; +}; + static void pmb_unmap_entry(struct pmb_entry *); +static DEFINE_RWLOCK(pmb_rwlock); static struct pmb_entry pmb_entry_list[NR_PMB_ENTRIES]; static DECLARE_BITMAP(pmb_map, NR_PMB_ENTRIES); @@ -52,16 +75,13 @@ static __always_inline unsigned long mk_pmb_data(unsigned int entry) static int pmb_alloc_entry(void) { - unsigned int pos; + int pos; -repeat: pos = find_first_zero_bit(pmb_map, NR_PMB_ENTRIES); - - if (unlikely(pos > NR_PMB_ENTRIES)) - return -ENOSPC; - - if (test_and_set_bit(pos, pmb_map)) - goto repeat; + if (pos >= 0 && pos < NR_PMB_ENTRIES) + __set_bit(pos, pmb_map); + else + pos = -ENOSPC; return pos; } @@ -70,21 +90,32 @@ static struct pmb_entry *pmb_alloc(unsigned long vpn, unsigned long ppn, unsigned long flags, int entry) { struct pmb_entry *pmbe; + unsigned long irqflags; + void *ret = NULL; int pos; + write_lock_irqsave(&pmb_rwlock, irqflags); + if (entry == PMB_NO_ENTRY) { pos = pmb_alloc_entry(); - if (pos < 0) - return ERR_PTR(pos); + if (unlikely(pos < 0)) { + ret = ERR_PTR(pos); + goto out; + } } else { - if (test_and_set_bit(entry, pmb_map)) - return ERR_PTR(-ENOSPC); + if (__test_and_set_bit(entry, pmb_map)) { + ret = ERR_PTR(-ENOSPC); + goto out; + } + pos = entry; } + write_unlock_irqrestore(&pmb_rwlock, irqflags); + pmbe = &pmb_entry_list[pos]; - if (!pmbe) - return ERR_PTR(-ENOMEM); + + spin_lock_init(&pmbe->lock); pmbe->vpn = vpn; pmbe->ppn = ppn; @@ -93,11 +124,15 @@ static struct pmb_entry *pmb_alloc(unsigned long vpn, unsigned long ppn, pmbe->size = 0; return pmbe; + +out: + write_unlock_irqrestore(&pmb_rwlock, irqflags); + return ret; } static void pmb_free(struct pmb_entry *pmbe) { - clear_bit(pmbe->entry, pmb_map); + __clear_bit(pmbe->entry, pmb_map); pmbe->entry = PMB_NO_ENTRY; } @@ -124,7 +159,7 @@ static __always_inline unsigned long pmb_cache_flags(void) /* * Must be run uncached. */ -static void set_pmb_entry(struct pmb_entry *pmbe) +static void __set_pmb_entry(struct pmb_entry *pmbe) { jump_to_uncached(); @@ -137,7 +172,7 @@ static void set_pmb_entry(struct pmb_entry *pmbe) back_to_cached(); } -static void clear_pmb_entry(struct pmb_entry *pmbe) +static void __clear_pmb_entry(struct pmb_entry *pmbe) { unsigned int entry = pmbe->entry; unsigned long addr; @@ -154,6 +189,15 @@ static void clear_pmb_entry(struct pmb_entry *pmbe) back_to_cached(); } +static void set_pmb_entry(struct pmb_entry *pmbe) +{ + unsigned long flags; + + spin_lock_irqsave(&pmbe->lock, flags); + __set_pmb_entry(pmbe); + spin_unlock_irqrestore(&pmbe->lock, flags); +} + static struct { unsigned long size; int flag; @@ -190,6 +234,8 @@ long pmb_remap(unsigned long vaddr, unsigned long phys, again: for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++) { + unsigned long flags; + if (size < pmb_sizes[i].size) continue; @@ -200,7 +246,9 @@ again: goto out; } - set_pmb_entry(pmbe); + spin_lock_irqsave(&pmbe->lock, flags); + + __set_pmb_entry(pmbe); phys += pmb_sizes[i].size; vaddr += pmb_sizes[i].size; @@ -212,8 +260,11 @@ again: * Link adjacent entries that span multiple PMB entries * for easier tear-down. */ - if (likely(pmbp)) + if (likely(pmbp)) { + spin_lock(&pmbp->lock); pmbp->link = pmbe; + spin_unlock(&pmbp->lock); + } pmbp = pmbe; @@ -223,9 +274,11 @@ again: * pmb_sizes[i].size again. */ i--; + + spin_unlock_irqrestore(&pmbe->lock, flags); } - if (size >= 0x1000000) + if (size >= SZ_16M) goto again; return wanted - size; @@ -238,29 +291,32 @@ out: void pmb_unmap(unsigned long addr) { - struct pmb_entry *pmbe; + struct pmb_entry *pmbe = NULL; int i; + read_lock(&pmb_rwlock); + for (i = 0; i < ARRAY_SIZE(pmb_entry_list); i++) { if (test_bit(i, pmb_map)) { pmbe = &pmb_entry_list[i]; - if (pmbe->vpn == addr) { - pmb_unmap_entry(pmbe); + if (pmbe->vpn == addr) break; - } } } + + read_unlock(&pmb_rwlock); + + pmb_unmap_entry(pmbe); } static void pmb_unmap_entry(struct pmb_entry *pmbe) { + unsigned long flags; + if (unlikely(!pmbe)) return; - if (!test_bit(pmbe->entry, pmb_map)) { - WARN_ON(1); - return; - } + write_lock_irqsave(&pmb_rwlock, flags); do { struct pmb_entry *pmblink = pmbe; @@ -272,15 +328,17 @@ static void pmb_unmap_entry(struct pmb_entry *pmbe) * this entry in pmb_alloc() (even if we haven't filled * it yet). * - * Therefore, calling clear_pmb_entry() is safe as no + * Therefore, calling __clear_pmb_entry() is safe as no * other mapping can be using that slot. */ - clear_pmb_entry(pmbe); + __clear_pmb_entry(pmbe); pmbe = pmblink->link; pmb_free(pmblink); } while (pmbe); + + write_unlock_irqrestore(&pmb_rwlock, flags); } static __always_inline unsigned int pmb_ppn_in_range(unsigned long ppn) @@ -316,6 +374,7 @@ static int pmb_synchronize_mappings(void) unsigned long addr, data; unsigned long addr_val, data_val; unsigned long ppn, vpn, flags; + unsigned long irqflags; unsigned int size; struct pmb_entry *pmbe; @@ -364,21 +423,31 @@ static int pmb_synchronize_mappings(void) continue; } + spin_lock_irqsave(&pmbe->lock, irqflags); + for (j = 0; j < ARRAY_SIZE(pmb_sizes); j++) if (pmb_sizes[j].flag == size) pmbe->size = pmb_sizes[j].size; - /* - * Compare the previous entry against the current one to - * see if the entries span a contiguous mapping. If so, - * setup the entry links accordingly. - */ - if (pmbp && ((pmbe->vpn == (pmbp->vpn + pmbp->size)) && - (pmbe->ppn == (pmbp->ppn + pmbp->size)))) - pmbp->link = pmbe; + if (pmbp) { + spin_lock(&pmbp->lock); + + /* + * Compare the previous entry against the current one to + * see if the entries span a contiguous mapping. If so, + * setup the entry links accordingly. + */ + if ((pmbe->vpn == (pmbp->vpn + pmbp->size)) && + (pmbe->ppn == (pmbp->ppn + pmbp->size))) + pmbp->link = pmbe; + + spin_unlock(&pmbp->lock); + } pmbp = pmbe; + spin_unlock_irqrestore(&pmbe->lock, irqflags); + pr_info("\t0x%08lx -> 0x%08lx [ %ldMB %scached ]\n", vpn >> PAGE_SHIFT, ppn >> PAGE_SHIFT, pmbe->size >> 20, (data_val & PMB_C) ? "" : "un"); @@ -493,14 +562,21 @@ static int pmb_sysdev_suspend(struct sys_device *dev, pm_message_t state) if (state.event == PM_EVENT_ON && prev_state.event == PM_EVENT_FREEZE) { struct pmb_entry *pmbe; + + read_lock(&pmb_rwlock); + for (i = 0; i < ARRAY_SIZE(pmb_entry_list); i++) { if (test_bit(i, pmb_map)) { pmbe = &pmb_entry_list[i]; set_pmb_entry(pmbe); } } + + read_unlock(&pmb_rwlock); } + prev_state = state; + return 0; } -- cgit v1.2.3 From b8f7918f332873a79e4c820e90e7a245ce4d3042 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 18 Feb 2010 13:23:30 +0900 Subject: sh: Provide uncached I/O helpers. There are lots of registers that can only be updated from the uncached mapping, so we add some helpers for those cases in order to make it easier to ensure that we only make the jump when it's absolutely necessary. Signed-off-by: Paul Mundt --- arch/sh/include/asm/io.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h index bd5fafa23eb4..7dab7b23a5ec 100644 --- a/arch/sh/include/asm/io.h +++ b/arch/sh/include/asm/io.h @@ -133,6 +133,28 @@ static inline void ctrl_delay(void) __raw_readw(generic_io_base); } +#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(); \ +} + +__BUILD_UNCACHED_IO(b, u8) +__BUILD_UNCACHED_IO(w, u16) +__BUILD_UNCACHED_IO(l, u32) +__BUILD_UNCACHED_IO(q, u64) + #define __BUILD_MEMORY_STRING(bwlq, type) \ \ static inline void __raw_writes##bwlq(volatile void __iomem *mem, \ -- cgit v1.2.3 From 2e450643d70b62e0192577681b227d7d5d2efa45 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 18 Feb 2010 13:26:05 +0900 Subject: sh: Use uncached I/O helpers in PMB setup. The PMB code is an example of something that spends an absurd amount of time running uncached when only a couple of operations really need to be. This switches over to the shiny new uncached helpers, permitting us to spend far more time running cached. Additionally, MMUCR twiddling is perfectly safe from cached space given that it's paired with a control register barrier, so fix that up, too. Signed-off-by: Paul Mundt --- arch/sh/mm/pmb.c | 46 +++++++++++++++++++--------------------------- 1 file changed, 19 insertions(+), 27 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c index e65e8b8e2a5e..b9d5476e1284 100644 --- a/arch/sh/mm/pmb.c +++ b/arch/sh/mm/pmb.c @@ -161,32 +161,28 @@ static __always_inline unsigned long pmb_cache_flags(void) */ static void __set_pmb_entry(struct pmb_entry *pmbe) { - jump_to_uncached(); - pmbe->flags &= ~PMB_CACHE_MASK; pmbe->flags |= pmb_cache_flags(); - __raw_writel(pmbe->vpn | PMB_V, mk_pmb_addr(pmbe->entry)); - __raw_writel(pmbe->ppn | pmbe->flags | PMB_V, mk_pmb_data(pmbe->entry)); - - back_to_cached(); + writel_uncached(pmbe->vpn | PMB_V, mk_pmb_addr(pmbe->entry)); + writel_uncached(pmbe->ppn | pmbe->flags | PMB_V, + mk_pmb_data(pmbe->entry)); } static void __clear_pmb_entry(struct pmb_entry *pmbe) { - unsigned int entry = pmbe->entry; - unsigned long addr; + unsigned long addr, data; + unsigned long addr_val, data_val; - jump_to_uncached(); + addr = mk_pmb_addr(pmbe->entry); + data = mk_pmb_data(pmbe->entry); - /* Clear V-bit */ - addr = mk_pmb_addr(entry); - __raw_writel(__raw_readl(addr) & ~PMB_V, addr); + addr_val = __raw_readl(addr); + data_val = __raw_readl(data); - addr = mk_pmb_data(entry); - __raw_writel(__raw_readl(addr) & ~PMB_V, addr); - - back_to_cached(); + /* Clear V-bit */ + writel_uncached(addr_val & ~PMB_V, addr); + writel_uncached(data_val & ~PMB_V, data); } static void set_pmb_entry(struct pmb_entry *pmbe) @@ -400,8 +396,8 @@ static int pmb_synchronize_mappings(void) /* * Invalidate anything out of bounds. */ - __raw_writel(addr_val & ~PMB_V, addr); - __raw_writel(data_val & ~PMB_V, data); + writel_uncached(addr_val & ~PMB_V, addr); + writel_uncached(data_val & ~PMB_V, data); continue; } @@ -411,7 +407,8 @@ static int pmb_synchronize_mappings(void) if (data_val & PMB_C) { data_val &= ~PMB_CACHE_MASK; data_val |= pmb_cache_flags(); - __raw_writel(data_val, data); + + writel_uncached(data_val, data); } size = data_val & PMB_SZ_MASK; @@ -462,25 +459,20 @@ int pmb_init(void) { int ret; - jump_to_uncached(); - /* * Sync our software copy of the PMB mappings with those in * hardware. The mappings in the hardware PMB were either set up * by the bootloader or very early on by the kernel. */ ret = pmb_synchronize_mappings(); - if (unlikely(ret == 0)) { - back_to_cached(); + if (unlikely(ret == 0)) return 0; - } - __raw_writel(0, PMB_IRMCR); + writel_uncached(0, PMB_IRMCR); /* Flush out the TLB */ __raw_writel(__raw_readl(MMUCR) | MMUCR_TI, MMUCR); - - back_to_cached(); + ctrl_barrier(); return 0; } -- cgit v1.2.3 From d01447b3197c2c470a14666be2c640407bbbfec7 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 18 Feb 2010 18:13:51 +0900 Subject: sh: Merge legacy and dynamic PMB modes. This implements a bit of rework for the PMB code, which permits us to kill off the legacy PMB mode completely. Rather than trusting the boot loader to do the right thing, we do a quick verification of the PMB contents to determine whether to have the kernel setup the initial mappings or whether it needs to mangle them later on instead. If we're booting from legacy mappings, the kernel will now take control of them and make them match the kernel's initial mapping configuration. This is accomplished by breaking the initialization phase out in to multiple steps: synchronization, merging, and resizing. With the recent rework, the synchronization code establishes page links for compound mappings already, so we build on top of this for promoting mappings and reclaiming unused slots. At the same time, the changes introduced for the uncached helpers also permit us to dynamically resize the uncached mapping without any particular headaches. The smallest page size is more than sufficient for mapping all of kernel text, and as we're careful not to jump to any far off locations in the setup code the mapping can safely be resized regardless of whether we are executing from it or not. Signed-off-by: Paul Mundt --- arch/sh/boot/compressed/misc.c | 2 +- arch/sh/include/asm/mmu.h | 12 +- arch/sh/include/asm/page.h | 11 +- arch/sh/include/asm/uncached.h | 18 +++ arch/sh/kernel/head_32.S | 42 ++++++- arch/sh/kernel/setup.c | 2 + arch/sh/mm/Kconfig | 10 -- arch/sh/mm/init.c | 1 - arch/sh/mm/pmb.c | 243 +++++++++++++++++++++++++++++++++++------ arch/sh/mm/uncached.c | 6 + 10 files changed, 276 insertions(+), 71 deletions(-) create mode 100644 arch/sh/include/asm/uncached.h (limited to 'arch/sh') diff --git a/arch/sh/boot/compressed/misc.c b/arch/sh/boot/compressed/misc.c index 9ba07927d16a..27140a6b365d 100644 --- a/arch/sh/boot/compressed/misc.c +++ b/arch/sh/boot/compressed/misc.c @@ -117,7 +117,7 @@ void decompress_kernel(void) output_addr = (CONFIG_MEMORY_START + 0x2000); #else output_addr = __pa((unsigned long)&_text+PAGE_SIZE); -#if defined(CONFIG_29BIT) || defined(CONFIG_PMB_LEGACY) +#if defined(CONFIG_29BIT) output_addr |= P2SEG; #endif #endif diff --git a/arch/sh/include/asm/mmu.h b/arch/sh/include/asm/mmu.h index e42c4e2a41df..15a05b615ba7 100644 --- a/arch/sh/include/asm/mmu.h +++ b/arch/sh/include/asm/mmu.h @@ -58,7 +58,7 @@ typedef struct { long pmb_remap(unsigned long virt, unsigned long phys, unsigned long size, pgprot_t prot); void pmb_unmap(unsigned long addr); -int pmb_init(void); +void pmb_init(void); bool __in_29bit_mode(void); #else static inline long pmb_remap(unsigned long virt, unsigned long phys, @@ -67,14 +67,8 @@ static inline long pmb_remap(unsigned long virt, unsigned long phys, return -EINVAL; } -static inline void pmb_unmap(unsigned long addr) -{ -} - -static inline int pmb_init(void) -{ - return -ENODEV; -} +#define pmb_unmap(addr) do { } while (0) +#define pmb_init(addr) do { } while (0) #ifdef CONFIG_29BIT #define __in_29bit_mode() (1) diff --git a/arch/sh/include/asm/page.h b/arch/sh/include/asm/page.h index 8237d9f53e56..d71feb359304 100644 --- a/arch/sh/include/asm/page.h +++ b/arch/sh/include/asm/page.h @@ -45,21 +45,12 @@ #endif #ifndef __ASSEMBLY__ +#include extern unsigned long shm_align_mask; extern unsigned long max_low_pfn, min_low_pfn; extern unsigned long memory_start, memory_end; -#ifdef CONFIG_UNCACHED_MAPPING -extern unsigned long uncached_start, uncached_end; - -extern int virt_addr_uncached(unsigned long kaddr); -extern void uncached_init(void); -#else -#define virt_addr_uncached(kaddr) (0) -#define uncached_init() do { } while (0) -#endif - static inline unsigned long pages_do_alias(unsigned long addr1, unsigned long addr2) { diff --git a/arch/sh/include/asm/uncached.h b/arch/sh/include/asm/uncached.h new file mode 100644 index 000000000000..e3419f96626a --- /dev/null +++ b/arch/sh/include/asm/uncached.h @@ -0,0 +1,18 @@ +#ifndef __ASM_SH_UNCACHED_H +#define __ASM_SH_UNCACHED_H + +#include + +#ifdef CONFIG_UNCACHED_MAPPING +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); +#else +#define virt_addr_uncached(kaddr) (0) +#define uncached_init() do { } while (0) +#define uncached_resize(size) BUG() +#endif + +#endif /* __ASM_SH_UNCACHED_H */ diff --git a/arch/sh/kernel/head_32.S b/arch/sh/kernel/head_32.S index 79ff39517f8e..fe0b743881b0 100644 --- a/arch/sh/kernel/head_32.S +++ b/arch/sh/kernel/head_32.S @@ -85,7 +85,7 @@ ENTRY(_stext) ldc r0, r7_bank ! ... and initial thread_info #endif -#if defined(CONFIG_PMB) && !defined(CONFIG_PMB_LEGACY) +#ifdef CONFIG_PMB /* * Reconfigure the initial PMB mappings setup by the hardware. * @@ -139,7 +139,6 @@ ENTRY(_stext) mov.l r0, @r1 mov.l .LMEMORY_SIZE, r5 - mov r5, r7 mov #PMB_E_SHIFT, r0 mov #0x1, r4 @@ -150,6 +149,40 @@ ENTRY(_stext) mov.l .LFIRST_ADDR_ENTRY, r2 mov.l .LPMB_ADDR, r3 + /* + * First we need to walk the PMB and figure out if there are any + * existing mappings that match the initial mappings VPN/PPN. + * If these have already been established by the bootloader, we + * don't bother setting up new entries here, and let the late PMB + * initialization take care of things instead. + * + * Note that we may need to coalesce and merge entries in order + * to reclaim more available PMB slots, which is much more than + * we want to do at this early stage. + */ + mov #0, r10 + mov #NR_PMB_ENTRIES, r9 + + mov r1, r7 /* temporary PMB_DATA iter */ + +.Lvalidate_existing_mappings: + + mov.l @r7, r8 + and r0, r8 + cmp/eq r0, r8 /* Check for valid __MEMORY_START mappings */ + bt .Lpmb_done + + add #1, r10 /* Increment the loop counter */ + cmp/eq r9, r10 + bf/s .Lvalidate_existing_mappings + add r4, r7 /* Increment to the next PMB_DATA entry */ + + /* + * If we've fallen through, continue with setting up the initial + * mappings. + */ + + mov r5, r7 /* cached_to_uncached */ mov #0, r10 #ifdef CONFIG_UNCACHED_MAPPING @@ -252,7 +285,8 @@ ENTRY(_stext) mov.l 6f, r0 icbi @r0 -#endif /* !CONFIG_PMB_LEGACY */ +.Lpmb_done: +#endif /* CONFIG_PMB */ #ifndef CONFIG_SH_NO_BSS_INIT /* @@ -304,7 +338,7 @@ ENTRY(stack_start) 6: .long sh_cpu_init 7: .long init_thread_union -#if defined(CONFIG_PMB) && !defined(CONFIG_PMB_LEGACY) +#ifdef CONFIG_PMB .LPMB_ADDR: .long PMB_ADDR .LPMB_DATA: .long PMB_DATA .LFIRST_ADDR_ENTRY: .long PAGE_OFFSET | PMB_V diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index e187750dd319..3459e70eed72 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -421,6 +421,8 @@ void __init setup_arch(char **cmdline_p) parse_early_param(); + uncached_init(); + plat_early_device_setup(); /* Let earlyprintk output early console messages */ diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index 65cb5b83e072..1445ca6257df 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig @@ -91,16 +91,6 @@ config PMB 32-bits through the SH-4A PMB. If this is not set, legacy 29-bit physical addressing will be used. -config PMB_LEGACY - bool "Support legacy boot mappings for PMB" - depends on PMB - select 32BIT - help - If this option is enabled, fixed PMB mappings are inherited - from the boot loader, and the kernel does not attempt dynamic - management. This is the closest to legacy 29-bit physical mode, - and allows systems to support up to 512MiB of system memory. - config X2TLB def_bool y depends on (CPU_SHX2 || CPU_SHX3) && MMU diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 08e280d7cc7e..68028e8f26ce 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -245,7 +245,6 @@ void __init mem_init(void) memset(empty_zero_page, 0, PAGE_SIZE); __flush_wback_region(empty_zero_page, PAGE_SIZE); - uncached_init(); vsyscall_init(); codesize = (unsigned long) &_etext - (unsigned long) &_text; diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c index b9d5476e1284..198bcff5e96f 100644 --- a/arch/sh/mm/pmb.c +++ b/arch/sh/mm/pmb.c @@ -52,7 +52,7 @@ struct pmb_entry { struct pmb_entry *link; }; -static void pmb_unmap_entry(struct pmb_entry *); +static void pmb_unmap_entry(struct pmb_entry *, int depth); static DEFINE_RWLOCK(pmb_rwlock); static struct pmb_entry pmb_entry_list[NR_PMB_ENTRIES]; @@ -115,13 +115,14 @@ static struct pmb_entry *pmb_alloc(unsigned long vpn, unsigned long ppn, pmbe = &pmb_entry_list[pos]; + memset(pmbe, 0, sizeof(struct pmb_entry)); + spin_lock_init(&pmbe->lock); pmbe->vpn = vpn; pmbe->ppn = ppn; pmbe->flags = flags; pmbe->entry = pos; - pmbe->size = 0; return pmbe; @@ -133,7 +134,9 @@ out: static void pmb_free(struct pmb_entry *pmbe) { __clear_bit(pmbe->entry, pmb_map); - pmbe->entry = PMB_NO_ENTRY; + + pmbe->entry = PMB_NO_ENTRY; + pmbe->link = NULL; } /* @@ -161,9 +164,6 @@ static __always_inline unsigned long pmb_cache_flags(void) */ static void __set_pmb_entry(struct pmb_entry *pmbe) { - pmbe->flags &= ~PMB_CACHE_MASK; - pmbe->flags |= pmb_cache_flags(); - writel_uncached(pmbe->vpn | PMB_V, mk_pmb_addr(pmbe->entry)); writel_uncached(pmbe->ppn | pmbe->flags | PMB_V, mk_pmb_data(pmbe->entry)); @@ -280,7 +280,7 @@ again: return wanted - size; out: - pmb_unmap_entry(pmbp); + pmb_unmap_entry(pmbp, NR_PMB_ENTRIES); return err; } @@ -302,18 +302,40 @@ void pmb_unmap(unsigned long addr) read_unlock(&pmb_rwlock); - pmb_unmap_entry(pmbe); + pmb_unmap_entry(pmbe, NR_PMB_ENTRIES); } -static void pmb_unmap_entry(struct pmb_entry *pmbe) +static bool pmb_can_merge(struct pmb_entry *a, struct pmb_entry *b) { - unsigned long flags; + return (b->vpn == (a->vpn + a->size)) && + (b->ppn == (a->ppn + a->size)) && + (b->flags == a->flags); +} - if (unlikely(!pmbe)) - return; +static bool pmb_size_valid(unsigned long size) +{ + int i; - write_lock_irqsave(&pmb_rwlock, flags); + for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++) + if (pmb_sizes[i].size == size) + return true; + + return false; +} + +static int pmb_size_to_flags(unsigned long size) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++) + if (pmb_sizes[i].size == size) + return pmb_sizes[i].flag; + return 0; +} + +static void __pmb_unmap_entry(struct pmb_entry *pmbe, int depth) +{ do { struct pmb_entry *pmblink = pmbe; @@ -332,8 +354,18 @@ static void pmb_unmap_entry(struct pmb_entry *pmbe) pmbe = pmblink->link; pmb_free(pmblink); - } while (pmbe); + } while (pmbe && --depth); +} + +static void pmb_unmap_entry(struct pmb_entry *pmbe, int depth) +{ + unsigned long flags; + if (unlikely(!pmbe)) + return; + + write_lock_irqsave(&pmb_rwlock, flags); + __pmb_unmap_entry(pmbe, depth); write_unlock_irqrestore(&pmb_rwlock, flags); } @@ -342,14 +374,40 @@ static __always_inline unsigned int pmb_ppn_in_range(unsigned long ppn) return ppn >= __pa(memory_start) && ppn < __pa(memory_end); } -static int pmb_synchronize_mappings(void) +static void __init pmb_notify(void) { - unsigned int applied = 0; - struct pmb_entry *pmbp = NULL; - int i, j; + int i; pr_info("PMB: boot mappings:\n"); + read_lock(&pmb_rwlock); + + for (i = 0; i < ARRAY_SIZE(pmb_entry_list); i++) { + struct pmb_entry *pmbe; + + if (!test_bit(i, pmb_map)) + continue; + + pmbe = &pmb_entry_list[i]; + + pr_info(" 0x%08lx -> 0x%08lx [ %4ldMB %2scached ]\n", + pmbe->vpn >> PAGE_SHIFT, pmbe->ppn >> PAGE_SHIFT, + pmbe->size >> 20, (pmbe->flags & PMB_C) ? "" : "un"); + } + + read_unlock(&pmb_rwlock); +} + +/* + * Sync our software copy of the PMB mappings with those in hardware. The + * mappings in the hardware PMB were either set up by the bootloader or + * very early on by the kernel. + */ +static void __init pmb_synchronize(void) +{ + struct pmb_entry *pmbp = NULL; + int i, j; + /* * Run through the initial boot mappings, log the established * ones, and blow away anything that falls outside of the valid @@ -432,10 +490,10 @@ static int pmb_synchronize_mappings(void) /* * Compare the previous entry against the current one to * see if the entries span a contiguous mapping. If so, - * setup the entry links accordingly. + * setup the entry links accordingly. Compound mappings + * are later coalesced. */ - if ((pmbe->vpn == (pmbp->vpn + pmbp->size)) && - (pmbe->ppn == (pmbp->ppn + pmbp->size))) + if (pmb_can_merge(pmbp, pmbe)) pmbp->link = pmbe; spin_unlock(&pmbp->lock); @@ -444,37 +502,150 @@ static int pmb_synchronize_mappings(void) pmbp = pmbe; spin_unlock_irqrestore(&pmbe->lock, irqflags); + } +} - pr_info("\t0x%08lx -> 0x%08lx [ %ldMB %scached ]\n", - vpn >> PAGE_SHIFT, ppn >> PAGE_SHIFT, pmbe->size >> 20, - (data_val & PMB_C) ? "" : "un"); +static void __init pmb_merge(struct pmb_entry *head) +{ + unsigned long span, newsize; + struct pmb_entry *tail; + int i = 1, depth = 0; + + span = newsize = head->size; - applied++; + tail = head->link; + while (tail) { + span += tail->size; + + if (pmb_size_valid(span)) { + newsize = span; + depth = i; + } + + /* This is the end of the line.. */ + if (!tail->link) + break; + + tail = tail->link; + i++; } - return (applied == 0); + /* + * The merged page size must be valid. + */ + if (!pmb_size_valid(newsize)) + return; + + head->flags &= ~PMB_SZ_MASK; + head->flags |= pmb_size_to_flags(newsize); + + head->size = newsize; + + __pmb_unmap_entry(head->link, depth); + __set_pmb_entry(head); } -int pmb_init(void) +static void __init pmb_coalesce(void) { - int ret; + unsigned long flags; + int i; + + write_lock_irqsave(&pmb_rwlock, flags); + + for (i = 0; i < ARRAY_SIZE(pmb_entry_list); i++) { + struct pmb_entry *pmbe; + + if (!test_bit(i, pmb_map)) + continue; + + pmbe = &pmb_entry_list[i]; + + /* + * We're only interested in compound mappings + */ + if (!pmbe->link) + continue; + + /* + * Nothing to do if it already uses the largest possible + * page size. + */ + if (pmbe->size == SZ_512M) + continue; + + pmb_merge(pmbe); + } + + write_unlock_irqrestore(&pmb_rwlock, flags); +} + +#ifdef CONFIG_UNCACHED_MAPPING +static void __init pmb_resize(void) +{ + int i; /* - * Sync our software copy of the PMB mappings with those in - * hardware. The mappings in the hardware PMB were either set up - * by the bootloader or very early on by the kernel. + * If the uncached mapping was constructed by the kernel, it will + * already be a reasonable size. */ - ret = pmb_synchronize_mappings(); - if (unlikely(ret == 0)) - return 0; + if (uncached_size == SZ_16M) + return; + + read_lock(&pmb_rwlock); + + for (i = 0; i < ARRAY_SIZE(pmb_entry_list); i++) { + struct pmb_entry *pmbe; + unsigned long flags; + + if (!test_bit(i, pmb_map)) + continue; + + pmbe = &pmb_entry_list[i]; + + if (pmbe->vpn != uncached_start) + continue; + + /* + * Found it, now resize it. + */ + spin_lock_irqsave(&pmbe->lock, flags); + + pmbe->size = SZ_16M; + pmbe->flags &= ~PMB_SZ_MASK; + pmbe->flags |= pmb_size_to_flags(pmbe->size); + + uncached_resize(pmbe->size); + + __set_pmb_entry(pmbe); + + spin_unlock_irqrestore(&pmbe->lock, flags); + } + + read_lock(&pmb_rwlock); +} +#endif + +void __init pmb_init(void) +{ + /* Synchronize software state */ + pmb_synchronize(); + + /* Attempt to combine compound mappings */ + pmb_coalesce(); + +#ifdef CONFIG_UNCACHED_MAPPING + /* Resize initial mappings, if necessary */ + pmb_resize(); +#endif + + /* Log them */ + pmb_notify(); writel_uncached(0, PMB_IRMCR); /* Flush out the TLB */ __raw_writel(__raw_readl(MMUCR) | MMUCR_TI, MMUCR); ctrl_barrier(); - - return 0; } bool __in_29bit_mode(void) diff --git a/arch/sh/mm/uncached.c b/arch/sh/mm/uncached.c index 807906981d9d..cf20a5c5136a 100644 --- a/arch/sh/mm/uncached.c +++ b/arch/sh/mm/uncached.c @@ -26,3 +26,9 @@ void __init uncached_init(void) uncached_start = memory_end; uncached_end = uncached_start + uncached_size; } + +void __init uncached_resize(unsigned long size) +{ + uncached_size = size; + uncached_end = uncached_start + uncached_size; +} -- cgit v1.2.3 From 8c563a30cdfff2833c4c2078d25b5d1469706a6d Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Thu, 4 Feb 2010 23:46:13 +0000 Subject: sh: Turn on speculative return for SH7785 and SH7786 Signed-off-by: Matt Fleming Signed-off-by: Paul Mundt --- arch/sh/Kconfig.cpu | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch/sh') diff --git a/arch/sh/Kconfig.cpu b/arch/sh/Kconfig.cpu index cd6e3ea598d5..ddf096c7d8bf 100644 --- a/arch/sh/Kconfig.cpu +++ b/arch/sh/Kconfig.cpu @@ -68,7 +68,8 @@ config SH_STORE_QUEUES config SPECULATIVE_EXECUTION bool "Speculative subroutine return" - depends on CPU_SUBTYPE_SH7780 && EXPERIMENTAL + depends on EXPERIMENTAL + depends on CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785 || CPU_SUBTYPE_SH7786 help This enables support for a speculative instruction fetch for subroutine return. There are various pitfalls associated with -- cgit v1.2.3 From de7ca2144c36291a491bd39afad172f56432a4bb Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 19 Feb 2010 09:12:00 +0000 Subject: sh: clock-cpg div4 set_rate() shift fix Make sure the div4 bitfield is shifted according to the enable_bit value in sh_clk_div4_set_rate(). Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/clock-cpg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/kernel/cpu/clock-cpg.c b/arch/sh/kernel/cpu/clock-cpg.c index 2827abb5d2ab..72a5e621a9bb 100644 --- a/arch/sh/kernel/cpu/clock-cpg.c +++ b/arch/sh/kernel/cpu/clock-cpg.c @@ -192,8 +192,8 @@ static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate, int algo_id return idx; value = __raw_readl(clk->enable_reg); - value &= ~0xf; - value |= idx; + value &= ~(0xf << clk->enable_bit); + value |= (idx << clk->enable_bit); __raw_writel(value, clk->enable_reg); return 0; -- cgit v1.2.3 From 0a5f337ecd20e70e84a5cfc0f2c24d0366087026 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 19 Feb 2010 09:22:25 +0000 Subject: sh: introduce struct clk_div4_table This patch introduces struct clk_div4_table. The structure will be used to keep div4 specific data, and is with this patch replacing the struct clk_div_mult_table pointer arg used by the sh_clk_div4_register() functions. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/include/asm/clock.h | 10 +++++++--- arch/sh/kernel/cpu/clock-cpg.c | 16 +++++++++------- arch/sh/kernel/cpu/sh4a/clock-sh7343.c | 6 +++++- arch/sh/kernel/cpu/sh4a/clock-sh7366.c | 6 +++++- arch/sh/kernel/cpu/sh4a/clock-sh7722.c | 6 +++++- arch/sh/kernel/cpu/sh4a/clock-sh7723.c | 6 +++++- arch/sh/kernel/cpu/sh4a/clock-sh7724.c | 6 +++++- arch/sh/kernel/cpu/sh4a/clock-sh7785.c | 6 +++++- arch/sh/kernel/cpu/sh4a/clock-sh7786.c | 6 +++++- 9 files changed, 51 insertions(+), 17 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/clock.h b/arch/sh/include/asm/clock.h index 501d0b076283..dbb5746e88f6 100644 --- a/arch/sh/include/asm/clock.h +++ b/arch/sh/include/asm/clock.h @@ -146,12 +146,16 @@ int sh_clk_mstp32_register(struct clk *clks, int nr); .flags = _flags, \ } +struct clk_div4_table { + struct clk_div_mult_table *div_mult_table; +}; + int sh_clk_div4_register(struct clk *clks, int nr, - struct clk_div_mult_table *table); + struct clk_div4_table *table); int sh_clk_div4_enable_register(struct clk *clks, int nr, - struct clk_div_mult_table *table); + struct clk_div4_table *table); int sh_clk_div4_reparent_register(struct clk *clks, int nr, - struct clk_div_mult_table *table); + struct clk_div4_table *table); #define SH_CLK_DIV6(_name, _parent, _reg, _flags) \ { \ diff --git a/arch/sh/kernel/cpu/clock-cpg.c b/arch/sh/kernel/cpu/clock-cpg.c index 72a5e621a9bb..1fc8a0e50603 100644 --- a/arch/sh/kernel/cpu/clock-cpg.c +++ b/arch/sh/kernel/cpu/clock-cpg.c @@ -149,7 +149,8 @@ int __init sh_clk_div6_register(struct clk *clks, int nr) static unsigned long sh_clk_div4_recalc(struct clk *clk) { - struct clk_div_mult_table *table = clk->priv; + struct clk_div4_table *d4t = clk->priv; + struct clk_div_mult_table *table = d4t->div_mult_table; unsigned int idx; clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, @@ -162,7 +163,8 @@ static unsigned long sh_clk_div4_recalc(struct clk *clk) static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent) { - struct clk_div_mult_table *table = clk->priv; + struct clk_div4_table *d4t = clk->priv; + struct clk_div_mult_table *table = d4t->div_mult_table; u32 value; int ret; @@ -234,11 +236,11 @@ static struct clk_ops sh_clk_div4_reparent_clk_ops = { }; static int __init sh_clk_div4_register_ops(struct clk *clks, int nr, - struct clk_div_mult_table *table, struct clk_ops *ops) + struct clk_div4_table *table, struct clk_ops *ops) { struct clk *clkp; void *freq_table; - int nr_divs = table->nr_divisors; + int nr_divs = table->div_mult_table->nr_divisors; int freq_table_size = sizeof(struct cpufreq_frequency_table); int ret = 0; int k; @@ -267,20 +269,20 @@ static int __init sh_clk_div4_register_ops(struct clk *clks, int nr, } int __init sh_clk_div4_register(struct clk *clks, int nr, - struct clk_div_mult_table *table) + struct clk_div4_table *table) { return sh_clk_div4_register_ops(clks, nr, table, &sh_clk_div4_clk_ops); } int __init sh_clk_div4_enable_register(struct clk *clks, int nr, - struct clk_div_mult_table *table) + struct clk_div4_table *table) { return sh_clk_div4_register_ops(clks, nr, table, &sh_clk_div4_enable_clk_ops); } int __init sh_clk_div4_reparent_register(struct clk *clks, int nr, - struct clk_div_mult_table *table) + struct clk_div4_table *table) { return sh_clk_div4_register_ops(clks, nr, table, &sh_clk_div4_reparent_clk_ops); diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c index 0ee3ee861252..2c16df37eda6 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c @@ -107,13 +107,17 @@ struct clk *main_clks[] = { static int multipliers[] = { 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; static int divisors[] = { 1, 3, 2, 5, 3, 4, 5, 6, 8, 10, 12, 16, 20 }; -static struct clk_div_mult_table div4_table = { +static struct clk_div_mult_table div4_div_mult_table = { .divisors = divisors, .nr_divisors = ARRAY_SIZE(divisors), .multipliers = multipliers, .nr_multipliers = ARRAY_SIZE(multipliers), }; +static struct clk_div4_table div4_table = { + .div_mult_table = &div4_div_mult_table, +}; + enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P, DIV4_SIUA, DIV4_SIUB, DIV4_NR }; diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c index a95ebaba095c..91588d280cd8 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7366.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7366.c @@ -110,13 +110,17 @@ struct clk *main_clks[] = { static int multipliers[] = { 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; static int divisors[] = { 1, 3, 2, 5, 3, 4, 5, 6, 8, 10, 12, 16, 20 }; -static struct clk_div_mult_table div4_table = { +static struct clk_div_mult_table div4_div_mult_table = { .divisors = divisors, .nr_divisors = ARRAY_SIZE(divisors), .multipliers = multipliers, .nr_multipliers = ARRAY_SIZE(multipliers), }; +static struct clk_div4_table div4_table = { + .div_mult_table = &div4_div_mult_table, +}; + enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P, DIV4_SIUA, DIV4_SIUB, DIV4_NR }; diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c index 860ee2bf4bf0..15db6d521c5c 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c @@ -110,13 +110,17 @@ struct clk *main_clks[] = { static int multipliers[] = { 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; static int divisors[] = { 1, 3, 2, 5, 3, 4, 5, 6, 8, 10, 12, 16, 20 }; -static struct clk_div_mult_table div4_table = { +static struct clk_div_mult_table div4_div_mult_table = { .divisors = divisors, .nr_divisors = ARRAY_SIZE(divisors), .multipliers = multipliers, .nr_multipliers = ARRAY_SIZE(multipliers), }; +static struct clk_div4_table div4_table = { + .div_mult_table = &div4_div_mult_table, +}; + #define DIV4(_str, _reg, _bit, _mask, _flags) \ SH_CLK_DIV4(_str, &pll_clk, _reg, _bit, _mask, _flags) diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c index 76731b61998e..50babe01fe44 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c @@ -110,13 +110,17 @@ struct clk *main_clks[] = { static int multipliers[] = { 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; static int divisors[] = { 1, 3, 2, 5, 3, 4, 5, 6, 8, 10, 12, 16, 20 }; -static struct clk_div_mult_table div4_table = { +static struct clk_div_mult_table div4_div_mult_table = { .divisors = divisors, .nr_divisors = ARRAY_SIZE(divisors), .multipliers = multipliers, .nr_multipliers = ARRAY_SIZE(multipliers), }; +static struct clk_div4_table div4_table = { + .div_mult_table = &div4_div_mult_table, +}; + enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P, DIV4_NR }; #define DIV4(_str, _reg, _bit, _mask, _flags) \ diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c index 9db743802f06..70517900ef8f 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c @@ -129,11 +129,15 @@ struct clk *main_clks[] = { static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 0, 24, 32, 36, 48, 0, 72 }; -static struct clk_div_mult_table div4_table = { +static struct clk_div_mult_table div4_div_mult_table = { .divisors = divisors, .nr_divisors = ARRAY_SIZE(divisors), }; +static struct clk_div4_table div4_table = { + .div_mult_table = &div4_div_mult_table, +}; + enum { DIV4_I, DIV4_SH, DIV4_B, DIV4_P, DIV4_M1, DIV4_NR }; #define DIV4(_str, _reg, _bit, _mask, _flags) \ diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c index 73abfbf2f16d..d997f0a25b10 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c @@ -57,11 +57,15 @@ static struct clk *clks[] = { static unsigned int div2[] = { 1, 2, 4, 6, 8, 12, 16, 18, 24, 32, 36, 48 }; -static struct clk_div_mult_table div4_table = { +static struct clk_div_mult_table div4_div_mult_table = { .divisors = div2, .nr_divisors = ARRAY_SIZE(div2), }; +static struct clk_div4_table div4_table = { + .div_mult_table = &div4_div_mult_table, +}; + enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_DDR, DIV4_GA, DIV4_DU, DIV4_P, DIV4_NR }; diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c index 494c636012bb..af69fd468703 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c @@ -59,11 +59,15 @@ static struct clk *clks[] = { static unsigned int div2[] = { 1, 2, 4, 6, 8, 12, 16, 18, 24, 32, 36, 48 }; -static struct clk_div_mult_table div4_table = { +static struct clk_div_mult_table div4_div_mult_table = { .divisors = div2, .nr_divisors = ARRAY_SIZE(div2), }; +static struct clk_div4_table div4_table = { + .div_mult_table = &div4_div_mult_table, +}; + enum { DIV4_I, DIV4_SH, DIV4_B, DIV4_DDR, DIV4_DU, DIV4_P, DIV4_NR }; #define DIV4(_str, _bit, _mask, _flags) \ -- cgit v1.2.3 From 7be85c6eb4462cd973e680d9dcf897a7b5b26165 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 19 Feb 2010 09:26:56 +0000 Subject: sh: add sh7724 kick callback to clk_div4_table This patch adds a ->kick() callback to clk_div4_table and ties it into sh_clk_div4_set_rate(). A sh7724 specific kick function is also added that updates the KICK bit whenever div4 clocks in FRQCRA and FRQCRB have been set. Allows us to set the VPU clock. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/include/asm/clock.h | 1 + arch/sh/kernel/cpu/clock-cpg.c | 4 ++++ arch/sh/kernel/cpu/sh4a/clock-sh7724.c | 11 +++++++++++ 3 files changed, 16 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/clock.h b/arch/sh/include/asm/clock.h index dbb5746e88f6..11da4c5beb68 100644 --- a/arch/sh/include/asm/clock.h +++ b/arch/sh/include/asm/clock.h @@ -148,6 +148,7 @@ int sh_clk_mstp32_register(struct clk *clks, int nr); struct clk_div4_table { struct clk_div_mult_table *div_mult_table; + void (*kick)(struct clk *clk); }; int sh_clk_div4_register(struct clk *clks, int nr, diff --git a/arch/sh/kernel/cpu/clock-cpg.c b/arch/sh/kernel/cpu/clock-cpg.c index 1fc8a0e50603..eed5eaff96ba 100644 --- a/arch/sh/kernel/cpu/clock-cpg.c +++ b/arch/sh/kernel/cpu/clock-cpg.c @@ -188,6 +188,7 @@ static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent) static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate, int algo_id) { + struct clk_div4_table *d4t = clk->priv; unsigned long value; int idx = clk_rate_table_find(clk, clk->freq_table, rate); if (idx < 0) @@ -198,6 +199,9 @@ static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate, int algo_id value |= (idx << clk->enable_bit); __raw_writel(value, clk->enable_reg); + if (d4t->kick) + d4t->kick(clk); + return 0; } diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c index 70517900ef8f..a8a993fc894a 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c @@ -127,6 +127,16 @@ struct clk *main_clks[] = { &div3_clk, }; +static void div4_kick(struct clk *clk) +{ + unsigned long value; + + /* set KICK bit in FRQCRA to update hardware setting */ + value = __raw_readl(FRQCRA); + value |= (1 << 31); + __raw_writel(value, FRQCRA); +} + static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 0, 24, 32, 36, 48, 0, 72 }; static struct clk_div_mult_table div4_div_mult_table = { @@ -136,6 +146,7 @@ static struct clk_div_mult_table div4_div_mult_table = { static struct clk_div4_table div4_table = { .div_mult_table = &div4_div_mult_table, + .kick = div4_kick, }; enum { DIV4_I, DIV4_SH, DIV4_B, DIV4_P, DIV4_M1, DIV4_NR }; -- cgit v1.2.3 From 6f26d19fce5907cdd0fd953ac1a1d0b1e6e5982c Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 19 Feb 2010 09:33:47 +0000 Subject: sh: always enable sh7724 vpu_clk and set to 166MHz on Ecovec Update the sh7724 processor code to always enable vpu_clk. On the Ecovec board, set the vpu_clk to 166 Mhz. The 166MHz setting results in a divide-by-6 setup for vpu_clk and improves the VPU performance compared to the power-on-reset/bootloader configuration. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/boards/mach-ecovec24/setup.c | 5 +++++ arch/sh/kernel/cpu/sh4a/clock-sh7724.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'arch/sh') diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index 8e3b05f93a65..a17dbb3ac73f 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c @@ -1121,6 +1121,11 @@ static int __init arch_setup(void) gpio_request(GPIO_FN_INTC_IRQ1, NULL); gpio_direction_input(GPIO_FN_INTC_IRQ1); + /* set VPU clock to 166 MHz */ + clk = clk_get(NULL, "vpu_clk"); + clk_set_rate(clk, clk_round_rate(clk, 166000000)); + clk_put(clk); + /* enable I2C device */ i2c_register_board_info(0, i2c0_devices, ARRAY_SIZE(i2c0_devices)); diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c index a8a993fc894a..6707061fbf54 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c @@ -159,7 +159,7 @@ struct clk div4_clks[DIV4_NR] = { [DIV4_SH] = DIV4("shyway_clk", FRQCRA, 12, 0x2f7c, CLK_ENABLE_ON_INIT), [DIV4_B] = DIV4("bus_clk", FRQCRA, 8, 0x2f7c, CLK_ENABLE_ON_INIT), [DIV4_P] = DIV4("peripheral_clk", FRQCRA, 0, 0x2f7c, 0), - [DIV4_M1] = DIV4("vpu_clk", FRQCRB, 4, 0x2f7c, 0), + [DIV4_M1] = DIV4("vpu_clk", FRQCRB, 4, 0x2f7c, CLK_ENABLE_ON_INIT), }; struct clk div6_clks[] = { -- cgit v1.2.3 From 16afc9fb0298a66da25ee015eb3c8a8f55e3744a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 22 Feb 2010 05:18:10 +0000 Subject: sh: sh7724: Update FSI/SPU2 clock When FSI and Network (= NFS file system) were used at the same time, the I/O of FSI was unstable. This patch updates the SPU2 clock (which is used for FSI) to solve this issue. Special thanks to Jeremy. Signed-off-by: Jeremy Baker Signed-off-by: Kuninori Morimoto Signed-off-by: Paul Mundt --- arch/sh/boards/mach-ecovec24/setup.c | 5 +++++ arch/sh/boards/mach-se/7724/setup.c | 15 ++++++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index a17dbb3ac73f..6f2e8a78b461 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c @@ -1105,6 +1105,11 @@ static int __init arch_setup(void) gpio_request(GPIO_FN_FSIOBLRCK, NULL); gpio_request(GPIO_FN_CLKAUDIOBO, NULL); + /* set SPU2 clock to 83.4 MHz */ + clk = clk_get(NULL, "spu_clk"); + clk_set_rate(clk, clk_round_rate(clk, 83333333)); + clk_put(clk); + /* change parent of FSI B */ clk = clk_get(NULL, "fsib_clk"); clk_register(&fsimckb_clk); diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c index 50e4d1599576..1f6cf8604943 100644 --- a/arch/sh/boards/mach-se/7724/setup.c +++ b/arch/sh/boards/mach-se/7724/setup.c @@ -586,7 +586,7 @@ arch_initcall(arch_setup); static int __init devices_setup(void) { u16 sw = __raw_readw(SW4140); /* select camera, monitor */ - struct clk *fsia_clk; + struct clk *clk; /* register board specific self-refresh code */ sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF, @@ -755,13 +755,18 @@ static int __init devices_setup(void) gpio_request(GPIO_FN_CLKAUDIOBO, NULL); gpio_request(GPIO_FN_FSIIASD, NULL); + /* set SPU2 clock to 83.4 MHz */ + clk = clk_get(NULL, "spu_clk"); + clk_set_rate(clk, clk_round_rate(clk, 83333333)); + clk_put(clk); + /* change parent of FSI A */ - fsia_clk = clk_get(NULL, "fsia_clk"); + clk = clk_get(NULL, "fsia_clk"); clk_register(&fsimcka_clk); - clk_set_parent(fsia_clk, &fsimcka_clk); - clk_set_rate(fsia_clk, 11000); + clk_set_parent(clk, &fsimcka_clk); + clk_set_rate(clk, 11000); clk_set_rate(&fsimcka_clk, 11000); - clk_put(fsia_clk); + clk_put(clk); /* SDHI0 connected to cn7 */ gpio_request(GPIO_FN_SDHI0CD, NULL); -- cgit v1.2.3 From b26b2d494b659f988b4d75eb394dfa0ddac415c9 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Fri, 1 Jan 2010 17:40:49 +0100 Subject: resource/PCI: align functions now return start of resource As suggested by Linus, align functions should return the start of a resource, not void. An update of "res->start" is no longer necessary. Cc: Bjorn Helgaas Cc: Yinghai Lu Signed-off-by: Dominik Brodowski Signed-off-by: Jesse Barnes --- arch/alpha/kernel/pci.c | 4 ++-- arch/arm/kernel/bios32.c | 8 +++++--- arch/cris/arch-v32/drivers/pci/bios.c | 14 ++++++-------- arch/frv/mb93090-mb00/pci-frv.c | 14 ++++++-------- arch/ia64/pci/pci.c | 3 ++- arch/mips/pci/pci.c | 4 ++-- arch/mips/pmc-sierra/yosemite/ht.c | 10 +++++----- arch/mn10300/unit-asb2305/pci-asb2305.c | 16 +++++++--------- arch/parisc/kernel/pci.c | 10 +++++----- arch/powerpc/kernel/pci-common.c | 13 ++++++------- arch/sh/drivers/pci/pci.c | 6 +++--- arch/sparc/kernel/pci.c | 5 +++-- arch/sparc/kernel/pcic.c | 5 +++-- arch/x86/pci/i386.c | 12 +++++------- arch/xtensa/kernel/pci.c | 11 +++++------ drivers/pci/bus.c | 6 ++++-- drivers/pcmcia/rsrc_mgr.c | 12 ++++++------ drivers/pcmcia/rsrc_nonstatic.c | 16 +++++++++------- include/linux/ioport.h | 6 ++++-- include/linux/pci.h | 8 +++++--- kernel/resource.c | 14 +++++++++----- 21 files changed, 102 insertions(+), 95 deletions(-) (limited to 'arch/sh') diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c index a91ba28999b5..5cf111ed851c 100644 --- a/arch/alpha/kernel/pci.c +++ b/arch/alpha/kernel/pci.c @@ -126,7 +126,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_final); #define MB (1024*KB) #define GB (1024*MB) -void +resource_size_t pcibios_align_resource(void *data, struct resource *res, resource_size_t size, resource_size_t align) { @@ -184,7 +184,7 @@ pcibios_align_resource(void *data, struct resource *res, } } - res->start = start; + return start; } #undef KB #undef MB diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index 809681900ec8..a7c85f84f06c 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c @@ -616,15 +616,17 @@ char * __init pcibios_setup(char *str) * but we want to try to avoid allocating at 0x2900-0x2bff * which might be mirrored at 0x0100-0x03ff.. */ -void pcibios_align_resource(void *data, struct resource *res, - resource_size_t size, resource_size_t align) +resource_size_t pcibios_align_resource(void *data, struct resource *res, + resource_size_t size, resource_size_t align) { resource_size_t start = res->start; if (res->flags & IORESOURCE_IO && start & 0x300) start = (start + 0x3ff) & ~0x3ff; - res->start = (start + align - 1) & ~(align - 1); + start = (start + align - 1) & ~(align - 1); + + return start; } /** diff --git a/arch/cris/arch-v32/drivers/pci/bios.c b/arch/cris/arch-v32/drivers/pci/bios.c index 77ee319193c3..5811e2f8945c 100644 --- a/arch/cris/arch-v32/drivers/pci/bios.c +++ b/arch/cris/arch-v32/drivers/pci/bios.c @@ -41,18 +41,16 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, return 0; } -void +resource_size_t pcibios_align_resource(void *data, struct resource *res, resource_size_t size, resource_size_t align) { - if (res->flags & IORESOURCE_IO) { - resource_size_t start = res->start; + resource_size_t start = res->start; - if (start & 0x300) { - start = (start + 0x3ff) & ~0x3ff; - res->start = start; - } - } + if ((res->flags & IORESOURCE_IO) && (start & 0x300)) + start = (start + 0x3ff) & ~0x3ff; + + return start } int pcibios_enable_resources(struct pci_dev *dev, int mask) diff --git a/arch/frv/mb93090-mb00/pci-frv.c b/arch/frv/mb93090-mb00/pci-frv.c index 566bdeb499d1..c947aa43f2a9 100644 --- a/arch/frv/mb93090-mb00/pci-frv.c +++ b/arch/frv/mb93090-mb00/pci-frv.c @@ -32,18 +32,16 @@ * but we want to try to avoid allocating at 0x2900-0x2bff * which might have be mirrored at 0x0100-0x03ff.. */ -void +resource_size_t pcibios_align_resource(void *data, struct resource *res, resource_size_t size, resource_size_t align) { - if (res->flags & IORESOURCE_IO) { - resource_size_t start = res->start; + resource_size_t start = res->start; - if (start & 0x300) { - start = (start + 0x3ff) & ~0x3ff; - res->start = start; - } - } + if ((res->flags & IORESOURCE_IO) && (start & 0x300)) + start = (start + 0x3ff) & ~0x3ff; + + return start } diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index df639db779f9..ef574cd311d1 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -547,10 +547,11 @@ pcibios_disable_device (struct pci_dev *dev) acpi_pci_irq_disable(dev); } -void +resource_size_t pcibios_align_resource (void *data, struct resource *res, resource_size_t size, resource_size_t align) { + return res->start; } /* diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index 9a11c2226891..9085988f7cf3 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c @@ -49,7 +49,7 @@ static int pci_initialized; * but we want to try to avoid allocating at 0x2900-0x2bff * which might have be mirrored at 0x0100-0x03ff.. */ -void +resource_size_t pcibios_align_resource(void *data, struct resource *res, resource_size_t size, resource_size_t align) { @@ -73,7 +73,7 @@ pcibios_align_resource(void *data, struct resource *res, start = PCIBIOS_MIN_MEM + hose->mem_resource->start; } - res->start = start; + return start; } static void __devinit pcibios_scanbus(struct pci_controller *hose) diff --git a/arch/mips/pmc-sierra/yosemite/ht.c b/arch/mips/pmc-sierra/yosemite/ht.c index 678388fd34b1..5e410087b628 100644 --- a/arch/mips/pmc-sierra/yosemite/ht.c +++ b/arch/mips/pmc-sierra/yosemite/ht.c @@ -345,14 +345,13 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) return pcibios_enable_resources(dev); } -void pcibios_align_resource(void *data, struct resource *res, - resource_size_t size, resource_size_t align) +resource_size_t pcibios_align_resource(void *data, struct resource *res, + resource_size_t size, resource_size_t align) { struct pci_dev *dev = data; + resource_size_t start = res->start; if (res->flags & IORESOURCE_IO) { - resource_size_t start = res->start; - /* We need to avoid collisions with `mirrored' VGA ports and other strange ISA hardware, so we always want the addresses kilobyte aligned. */ @@ -363,8 +362,9 @@ void pcibios_align_resource(void *data, struct resource *res, } start = (start + 1024 - 1) & ~(1024 - 1); - res->start = start; } + + return start; } struct pci_ops titan_pci_ops = { diff --git a/arch/mn10300/unit-asb2305/pci-asb2305.c b/arch/mn10300/unit-asb2305/pci-asb2305.c index 78cd134ddf7d..b0b3758fba08 100644 --- a/arch/mn10300/unit-asb2305/pci-asb2305.c +++ b/arch/mn10300/unit-asb2305/pci-asb2305.c @@ -31,9 +31,11 @@ * but we want to try to avoid allocating at 0x2900-0x2bff * which might have be mirrored at 0x0100-0x03ff.. */ -void pcibios_align_resource(void *data, struct resource *res, - resource_size_t size, resource_size_t align) +resource_size_t pcibios_align_resource(void *data, struct resource *res, + resource_size_t size, resource_size_t align) { + resource_size_t start = res->start; + #if 0 struct pci_dev *dev = data; @@ -47,14 +49,10 @@ void pcibios_align_resource(void *data, struct resource *res, ); #endif - if (res->flags & IORESOURCE_IO) { - unsigned long start = res->start; + if ((res->flags & IORESOURCE_IO) && (start & 0x300)) + start = (start + 0x3ff) & ~0x3ff; - if (start & 0x300) { - start = (start + 0x3ff) & ~0x3ff; - res->start = start; - } - } + return start; } diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c index f7064abc3bb6..4463a31973ba 100644 --- a/arch/parisc/kernel/pci.c +++ b/arch/parisc/kernel/pci.c @@ -254,10 +254,10 @@ EXPORT_SYMBOL(pcibios_bus_to_resource); * Since we are just checking candidates, don't use any fields other * than res->start. */ -void pcibios_align_resource(void *data, struct resource *res, +resource_size_t pcibios_align_resource(void *data, struct resource *res, resource_size_t size, resource_size_t alignment) { - resource_size_t mask, align; + resource_size_t mask, align, start = res->start; DBG_RES("pcibios_align_resource(%s, (%p) [%lx,%lx]/%x, 0x%lx, 0x%lx)\n", pci_name(((struct pci_dev *) data)), @@ -269,10 +269,10 @@ void pcibios_align_resource(void *data, struct resource *res, /* Align to largest of MIN or input size */ mask = max(alignment, align) - 1; - res->start += mask; - res->start &= ~mask; + start += mask; + start &= ~mask; - /* The caller updates the end field, we don't. */ + return start; } diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index cadbed679fbb..d7eebbaf01f1 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -1181,21 +1181,20 @@ static int skip_isa_ioresource_align(struct pci_dev *dev) * but we want to try to avoid allocating at 0x2900-0x2bff * which might have be mirrored at 0x0100-0x03ff.. */ -void pcibios_align_resource(void *data, struct resource *res, +resource_size_t pcibios_align_resource(void *data, struct resource *res, resource_size_t size, resource_size_t align) { struct pci_dev *dev = data; + resource_size_t start = res->start; if (res->flags & IORESOURCE_IO) { - resource_size_t start = res->start; - if (skip_isa_ioresource_align(dev)) - return; - if (start & 0x300) { + return start; + if (start & 0x300) start = (start + 0x3ff) & ~0x3ff; - res->start = start; - } } + + return start; } EXPORT_SYMBOL(pcibios_align_resource); diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index c481df639022..b36ca825b3d3 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c @@ -148,8 +148,8 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus) * addresses to be allocated in the 0x000-0x0ff region * modulo 0x400. */ -void pcibios_align_resource(void *data, struct resource *res, - resource_size_t size, resource_size_t align) +resource_size_t pcibios_align_resource(void *data, struct resource *res, + resource_size_t size, resource_size_t align) { struct pci_dev *dev = data; struct pci_channel *chan = dev->sysdata; @@ -171,7 +171,7 @@ void pcibios_align_resource(void *data, struct resource *res, start = PCIBIOS_MIN_MEM + chan->mem_resource->start; } - res->start = start; + return start; } void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index 592b03d85167..d56c1f34689e 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -722,9 +722,10 @@ void pcibios_update_irq(struct pci_dev *pdev, int irq) { } -void pcibios_align_resource(void *data, struct resource *res, - resource_size_t size, resource_size_t align) +resource_size_t pcibios_align_resource(void *data, struct resource *res, + resource_size_t size, resource_size_t align) { + return res->start; } int pcibios_enable_device(struct pci_dev *dev, int mask) diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c index 4e2724ec2bb6..46fda64ff163 100644 --- a/arch/sparc/kernel/pcic.c +++ b/arch/sparc/kernel/pcic.c @@ -768,9 +768,10 @@ char * __devinit pcibios_setup(char *str) return str; } -void pcibios_align_resource(void *data, struct resource *res, - resource_size_t size, resource_size_t align) +resource_size_t pcibios_align_resource(void *data, struct resource *res, + resource_size_t size, resource_size_t align) { + return res->start; } int pcibios_enable_device(struct pci_dev *pdev, int mask) diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c index 5dc9e8c63fcd..924e40c916d3 100644 --- a/arch/x86/pci/i386.c +++ b/arch/x86/pci/i386.c @@ -60,22 +60,20 @@ skip_isa_ioresource_align(struct pci_dev *dev) { * but we want to try to avoid allocating at 0x2900-0x2bff * which might have be mirrored at 0x0100-0x03ff.. */ -void +resource_size_t pcibios_align_resource(void *data, struct resource *res, resource_size_t size, resource_size_t align) { struct pci_dev *dev = data; + resource_size_t start = res->start; if (res->flags & IORESOURCE_IO) { - resource_size_t start = res->start; - if (skip_isa_ioresource_align(dev)) - return; - if (start & 0x300) { + return start; + if (start & 0x300) start = (start + 0x3ff) & ~0x3ff; - res->start = start; - } } + return start; } EXPORT_SYMBOL(pcibios_align_resource); diff --git a/arch/xtensa/kernel/pci.c b/arch/xtensa/kernel/pci.c index b7c073484e01..d7efab03164e 100644 --- a/arch/xtensa/kernel/pci.c +++ b/arch/xtensa/kernel/pci.c @@ -69,26 +69,25 @@ static int pci_bus_count; * but we want to try to avoid allocating at 0x2900-0x2bff * which might have be mirrored at 0x0100-0x03ff.. */ -void +resource_size_t pcibios_align_resource(void *data, struct resource *res, resource_size_t size, resource_size_t align) { struct pci_dev *dev = data; + resource_size_t start = res->start; if (res->flags & IORESOURCE_IO) { - resource_size_t start = res->start; - if (size > 0x100) { printk(KERN_ERR "PCI: I/O Region %s/%d too large" " (%ld bytes)\n", pci_name(dev), dev->resource - res, size); } - if (start & 0x300) { + if (start & 0x300) start = (start + 0x3ff) & ~0x3ff; - res->start = start; - } } + + return start; } int diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index cef28a79103f..d29d69a37940 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -36,8 +36,10 @@ int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, resource_size_t size, resource_size_t align, resource_size_t min, unsigned int type_mask, - void (*alignf)(void *, struct resource *, resource_size_t, - resource_size_t), + resource_size_t (*alignf)(void *, + struct resource *, + resource_size_t, + resource_size_t), void *alignf_data) { int i, ret = -ENOMEM; diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c index 52db17263d8b..f92a2dac13a2 100644 --- a/drivers/pcmcia/rsrc_mgr.c +++ b/drivers/pcmcia/rsrc_mgr.c @@ -114,22 +114,20 @@ struct pcmcia_align_data { unsigned long offset; }; -static void pcmcia_align(void *align_data, struct resource *res, - unsigned long size, unsigned long align) +static resource_size_t pcmcia_align(void *align_data, struct resource *res, + resource_size_t size, resource_size_t align) { struct pcmcia_align_data *data = align_data; - unsigned long start; + resource_size_t start; start = (res->start & ~data->mask) + data->offset; if (start < res->start) start += data->mask + 1; - res->start = start; #ifdef CONFIG_X86 if (res->flags & IORESOURCE_IO) { if (start & 0x300) { start = (start + 0x3ff) & ~0x3ff; - res->start = start; } } #endif @@ -137,9 +135,11 @@ static void pcmcia_align(void *align_data, struct resource *res, #ifdef CONFIG_M68K if (res->flags & IORESOURCE_IO) { if ((res->start + size - 1) >= 1024) - res->start = res->end; + start = res->end; } #endif + + return start; } diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index 9b0dc433a8c3..b65902870e44 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c @@ -533,7 +533,7 @@ struct pcmcia_align_data { struct resource_map *map; }; -static void +static resource_size_t pcmcia_common_align(void *align_data, struct resource *res, resource_size_t size, resource_size_t align) { @@ -545,17 +545,18 @@ pcmcia_common_align(void *align_data, struct resource *res, start = (res->start & ~data->mask) + data->offset; if (start < res->start) start += data->mask + 1; - res->start = start; + return start; } -static void +static resource_size_t pcmcia_align(void *align_data, struct resource *res, resource_size_t size, resource_size_t align) { struct pcmcia_align_data *data = align_data; struct resource_map *m; + resource_size_t start; - pcmcia_common_align(data, res, size, align); + start = pcmcia_common_align(data, res, size, align); for (m = data->map->next; m != data->map; m = m->next) { unsigned long start = m->base; @@ -567,8 +568,7 @@ pcmcia_align(void *align_data, struct resource *res, resource_size_t size, * fit here. */ if (res->start < start) { - res->start = start; - pcmcia_common_align(data, res, size, align); + start = pcmcia_common_align(data, res, size, align); } /* @@ -586,7 +586,9 @@ pcmcia_align(void *align_data, struct resource *res, resource_size_t size, * If we failed to find something suitable, ensure we fail. */ if (m == data->map) - res->start = res->end; + start = res->end; + + return start; } /* diff --git a/include/linux/ioport.h b/include/linux/ioport.h index 7129504e053d..f4195de4eb9d 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h @@ -120,8 +120,10 @@ extern void insert_resource_expand_to_fit(struct resource *root, struct resource extern int allocate_resource(struct resource *root, struct resource *new, resource_size_t size, resource_size_t min, resource_size_t max, resource_size_t align, - void (*alignf)(void *, struct resource *, - resource_size_t, resource_size_t), + resource_size_t (*alignf)(void *, + struct resource *, + resource_size_t, + resource_size_t), void *alignf_data); int adjust_resource(struct resource *res, resource_size_t start, resource_size_t size); diff --git a/include/linux/pci.h b/include/linux/pci.h index 16f48e7506ed..1bd9f52b24b8 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -592,7 +592,8 @@ int __must_check pcibios_enable_device(struct pci_dev *, int mask); char *pcibios_setup(char *str); /* Used only when drivers/pci/setup.c is used */ -void pcibios_align_resource(void *, struct resource *, resource_size_t, +resource_size_t pcibios_align_resource(void *, struct resource *, + resource_size_t, resource_size_t); void pcibios_update_irq(struct pci_dev *, int irq); @@ -827,8 +828,9 @@ int __must_check pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, resource_size_t size, resource_size_t align, resource_size_t min, unsigned int type_mask, - void (*alignf)(void *, struct resource *, - resource_size_t, resource_size_t), + resource_size_t (*alignf)(void *, struct resource *, + resource_size_t, + resource_size_t), void *alignf_data); void pci_enable_bridges(struct pci_bus *bus); diff --git a/kernel/resource.c b/kernel/resource.c index af96c1e4b54b..e697f20e2288 100644 --- a/kernel/resource.c +++ b/kernel/resource.c @@ -303,8 +303,10 @@ int walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages, static int find_resource(struct resource *root, struct resource *new, resource_size_t size, resource_size_t min, resource_size_t max, resource_size_t align, - void (*alignf)(void *, struct resource *, - resource_size_t, resource_size_t), + resource_size_t (*alignf)(void *, + struct resource *, + resource_size_t, + resource_size_t), void *alignf_data) { struct resource *this = root->child; @@ -330,7 +332,7 @@ static int find_resource(struct resource *root, struct resource *new, tmp.end = max; tmp.start = ALIGN(tmp.start, align); if (alignf) - alignf(alignf_data, &tmp, size, align); + tmp.start = alignf(alignf_data, &tmp, size, align); if (tmp.start < tmp.end && tmp.end - tmp.start >= size - 1) { new->start = tmp.start; new->end = tmp.start + size - 1; @@ -358,8 +360,10 @@ static int find_resource(struct resource *root, struct resource *new, int allocate_resource(struct resource *root, struct resource *new, resource_size_t size, resource_size_t min, resource_size_t max, resource_size_t align, - void (*alignf)(void *, struct resource *, - resource_size_t, resource_size_t), + resource_size_t (*alignf)(void *, + struct resource *, + resource_size_t, + resource_size_t), void *alignf_data) { int err; -- cgit v1.2.3 From 3b7a17fcdae532d29dffab9d564a28be08960988 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Fri, 1 Jan 2010 17:40:50 +0100 Subject: resource/PCI: mark struct resource as const Now that we return the new resource start position, there is no need to update "struct resource" inside the align function. Therefore, mark the struct resource as const. Cc: Bjorn Helgaas Cc: Yinghai Lu Signed-off-by: Dominik Brodowski Signed-off-by: Jesse Barnes --- arch/alpha/kernel/pci.c | 2 +- arch/arm/kernel/bios32.c | 2 +- arch/cris/arch-v32/drivers/pci/bios.c | 2 +- arch/frv/mb93090-mb00/pci-frv.c | 2 +- arch/ia64/pci/pci.c | 2 +- arch/mips/pci/pci.c | 2 +- arch/mips/pmc-sierra/yosemite/ht.c | 2 +- arch/mn10300/unit-asb2305/pci-asb2305.c | 2 +- arch/parisc/kernel/pci.c | 2 +- arch/powerpc/kernel/pci-common.c | 2 +- arch/sh/drivers/pci/pci.c | 2 +- arch/sparc/kernel/pci.c | 2 +- arch/sparc/kernel/pcic.c | 2 +- arch/x86/pci/i386.c | 2 +- arch/xtensa/kernel/pci.c | 4 ++-- drivers/pci/bus.c | 2 +- drivers/pcmcia/rsrc_mgr.c | 3 ++- drivers/pcmcia/rsrc_nonstatic.c | 6 +++--- include/linux/ioport.h | 2 +- include/linux/pci.h | 5 +++-- kernel/resource.c | 4 ++-- 21 files changed, 28 insertions(+), 26 deletions(-) (limited to 'arch/sh') diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c index 5cf111ed851c..c9ab94ee1ca8 100644 --- a/arch/alpha/kernel/pci.c +++ b/arch/alpha/kernel/pci.c @@ -127,7 +127,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_final); #define GB (1024*MB) resource_size_t -pcibios_align_resource(void *data, struct resource *res, +pcibios_align_resource(void *data, const struct resource *res, resource_size_t size, resource_size_t align) { struct pci_dev *dev = data; diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index a7c85f84f06c..bd397e0b663e 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c @@ -616,7 +616,7 @@ char * __init pcibios_setup(char *str) * but we want to try to avoid allocating at 0x2900-0x2bff * which might be mirrored at 0x0100-0x03ff.. */ -resource_size_t pcibios_align_resource(void *data, struct resource *res, +resource_size_t pcibios_align_resource(void *data, const struct resource *res, resource_size_t size, resource_size_t align) { resource_size_t start = res->start; diff --git a/arch/cris/arch-v32/drivers/pci/bios.c b/arch/cris/arch-v32/drivers/pci/bios.c index 5811e2f8945c..d4b9c36ddc0f 100644 --- a/arch/cris/arch-v32/drivers/pci/bios.c +++ b/arch/cris/arch-v32/drivers/pci/bios.c @@ -42,7 +42,7 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, } resource_size_t -pcibios_align_resource(void *data, struct resource *res, +pcibios_align_resource(void *data, const struct resource *res, resource_size_t size, resource_size_t align) { resource_size_t start = res->start; diff --git a/arch/frv/mb93090-mb00/pci-frv.c b/arch/frv/mb93090-mb00/pci-frv.c index c947aa43f2a9..1ed15d7fea20 100644 --- a/arch/frv/mb93090-mb00/pci-frv.c +++ b/arch/frv/mb93090-mb00/pci-frv.c @@ -33,7 +33,7 @@ * which might have be mirrored at 0x0100-0x03ff.. */ resource_size_t -pcibios_align_resource(void *data, struct resource *res, +pcibios_align_resource(void *data, const struct resource *res, resource_size_t size, resource_size_t align) { resource_size_t start = res->start; diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index ef574cd311d1..783c83bb2b49 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -548,7 +548,7 @@ pcibios_disable_device (struct pci_dev *dev) } resource_size_t -pcibios_align_resource (void *data, struct resource *res, +pcibios_align_resource (void *data, const struct resource *res, resource_size_t size, resource_size_t align) { return res->start; diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index 9085988f7cf3..f87f5e188fa6 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c @@ -50,7 +50,7 @@ static int pci_initialized; * which might have be mirrored at 0x0100-0x03ff.. */ resource_size_t -pcibios_align_resource(void *data, struct resource *res, +pcibios_align_resource(void *data, const struct resource *res, resource_size_t size, resource_size_t align) { struct pci_dev *dev = data; diff --git a/arch/mips/pmc-sierra/yosemite/ht.c b/arch/mips/pmc-sierra/yosemite/ht.c index 5e410087b628..fd22597edb64 100644 --- a/arch/mips/pmc-sierra/yosemite/ht.c +++ b/arch/mips/pmc-sierra/yosemite/ht.c @@ -345,7 +345,7 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) return pcibios_enable_resources(dev); } -resource_size_t pcibios_align_resource(void *data, struct resource *res, +resource_size_t pcibios_align_resource(void *data, const struct resource *res, resource_size_t size, resource_size_t align) { struct pci_dev *dev = data; diff --git a/arch/mn10300/unit-asb2305/pci-asb2305.c b/arch/mn10300/unit-asb2305/pci-asb2305.c index b0b3758fba08..d6119b879a98 100644 --- a/arch/mn10300/unit-asb2305/pci-asb2305.c +++ b/arch/mn10300/unit-asb2305/pci-asb2305.c @@ -31,7 +31,7 @@ * but we want to try to avoid allocating at 0x2900-0x2bff * which might have be mirrored at 0x0100-0x03ff.. */ -resource_size_t pcibios_align_resource(void *data, struct resource *res, +resource_size_t pcibios_align_resource(void *data, const struct resource *res, resource_size_t size, resource_size_t align) { resource_size_t start = res->start; diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c index 4463a31973ba..5179e5e6f8fb 100644 --- a/arch/parisc/kernel/pci.c +++ b/arch/parisc/kernel/pci.c @@ -254,7 +254,7 @@ EXPORT_SYMBOL(pcibios_bus_to_resource); * Since we are just checking candidates, don't use any fields other * than res->start. */ -resource_size_t pcibios_align_resource(void *data, struct resource *res, +resource_size_t pcibios_align_resource(void *data, const struct resource *res, resource_size_t size, resource_size_t alignment) { resource_size_t mask, align, start = res->start; diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index d7eebbaf01f1..e640810e813f 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -1181,7 +1181,7 @@ static int skip_isa_ioresource_align(struct pci_dev *dev) * but we want to try to avoid allocating at 0x2900-0x2bff * which might have be mirrored at 0x0100-0x03ff.. */ -resource_size_t pcibios_align_resource(void *data, struct resource *res, +resource_size_t pcibios_align_resource(void *data, const struct resource *res, resource_size_t size, resource_size_t align) { struct pci_dev *dev = data; diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index b36ca825b3d3..96213fd172ce 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c @@ -148,7 +148,7 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus) * addresses to be allocated in the 0x000-0x0ff region * modulo 0x400. */ -resource_size_t pcibios_align_resource(void *data, struct resource *res, +resource_size_t pcibios_align_resource(void *data, const struct resource *res, resource_size_t size, resource_size_t align) { struct pci_dev *dev = data; diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index d56c1f34689e..37b66c60abe3 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -722,7 +722,7 @@ void pcibios_update_irq(struct pci_dev *pdev, int irq) { } -resource_size_t pcibios_align_resource(void *data, struct resource *res, +resource_size_t pcibios_align_resource(void *data, const struct resource *res, resource_size_t size, resource_size_t align) { return res->start; diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c index 46fda64ff163..75e88c00bca3 100644 --- a/arch/sparc/kernel/pcic.c +++ b/arch/sparc/kernel/pcic.c @@ -768,7 +768,7 @@ char * __devinit pcibios_setup(char *str) return str; } -resource_size_t pcibios_align_resource(void *data, struct resource *res, +resource_size_t pcibios_align_resource(void *data, const struct resource *res, resource_size_t size, resource_size_t align) { return res->start; diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c index 924e40c916d3..5a8fbf8d4cac 100644 --- a/arch/x86/pci/i386.c +++ b/arch/x86/pci/i386.c @@ -61,7 +61,7 @@ skip_isa_ioresource_align(struct pci_dev *dev) { * which might have be mirrored at 0x0100-0x03ff.. */ resource_size_t -pcibios_align_resource(void *data, struct resource *res, +pcibios_align_resource(void *data, const struct resource *res, resource_size_t size, resource_size_t align) { struct pci_dev *dev = data; diff --git a/arch/xtensa/kernel/pci.c b/arch/xtensa/kernel/pci.c index d7efab03164e..cd1026931203 100644 --- a/arch/xtensa/kernel/pci.c +++ b/arch/xtensa/kernel/pci.c @@ -70,8 +70,8 @@ static int pci_bus_count; * which might have be mirrored at 0x0100-0x03ff.. */ resource_size_t -pcibios_align_resource(void *data, struct resource *res, resource_size_t size, - resource_size_t align) +pcibios_align_resource(void *data, const struct resource *res, + resource_size_t size, resource_size_t align) { struct pci_dev *dev = data; resource_size_t start = res->start; diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index d29d69a37940..a26135bb0ffd 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -37,7 +37,7 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, resource_size_t size, resource_size_t align, resource_size_t min, unsigned int type_mask, resource_size_t (*alignf)(void *, - struct resource *, + const struct resource *, resource_size_t, resource_size_t), void *alignf_data) diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c index f92a2dac13a2..f8401a0ef89b 100644 --- a/drivers/pcmcia/rsrc_mgr.c +++ b/drivers/pcmcia/rsrc_mgr.c @@ -114,7 +114,8 @@ struct pcmcia_align_data { unsigned long offset; }; -static resource_size_t pcmcia_align(void *align_data, struct resource *res, +static resource_size_t pcmcia_align(void *align_data, + const struct resource *res, resource_size_t size, resource_size_t align) { struct pcmcia_align_data *data = align_data; diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index b65902870e44..45d75dc452f0 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c @@ -534,7 +534,7 @@ struct pcmcia_align_data { }; static resource_size_t -pcmcia_common_align(void *align_data, struct resource *res, +pcmcia_common_align(void *align_data, const struct resource *res, resource_size_t size, resource_size_t align) { struct pcmcia_align_data *data = align_data; @@ -549,8 +549,8 @@ pcmcia_common_align(void *align_data, struct resource *res, } static resource_size_t -pcmcia_align(void *align_data, struct resource *res, resource_size_t size, - resource_size_t align) +pcmcia_align(void *align_data, const struct resource *res, + resource_size_t size, resource_size_t align) { struct pcmcia_align_data *data = align_data; struct resource_map *m; diff --git a/include/linux/ioport.h b/include/linux/ioport.h index f4195de4eb9d..4a811891dbe3 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h @@ -121,7 +121,7 @@ extern int allocate_resource(struct resource *root, struct resource *new, resource_size_t size, resource_size_t min, resource_size_t max, resource_size_t align, resource_size_t (*alignf)(void *, - struct resource *, + const struct resource *, resource_size_t, resource_size_t), void *alignf_data); diff --git a/include/linux/pci.h b/include/linux/pci.h index 1bd9f52b24b8..449d51560fc2 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -592,7 +592,7 @@ int __must_check pcibios_enable_device(struct pci_dev *, int mask); char *pcibios_setup(char *str); /* Used only when drivers/pci/setup.c is used */ -resource_size_t pcibios_align_resource(void *, struct resource *, +resource_size_t pcibios_align_resource(void *, const struct resource *, resource_size_t, resource_size_t); void pcibios_update_irq(struct pci_dev *, int irq); @@ -828,7 +828,8 @@ int __must_check pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, resource_size_t size, resource_size_t align, resource_size_t min, unsigned int type_mask, - resource_size_t (*alignf)(void *, struct resource *, + resource_size_t (*alignf)(void *, + const struct resource *, resource_size_t, resource_size_t), void *alignf_data); diff --git a/kernel/resource.c b/kernel/resource.c index e697f20e2288..7fd123ad00aa 100644 --- a/kernel/resource.c +++ b/kernel/resource.c @@ -304,7 +304,7 @@ static int find_resource(struct resource *root, struct resource *new, resource_size_t size, resource_size_t min, resource_size_t max, resource_size_t align, resource_size_t (*alignf)(void *, - struct resource *, + const struct resource *, resource_size_t, resource_size_t), void *alignf_data) @@ -361,7 +361,7 @@ int allocate_resource(struct resource *root, struct resource *new, resource_size_t size, resource_size_t min, resource_size_t max, resource_size_t align, resource_size_t (*alignf)(void *, - struct resource *, + const struct resource *, resource_size_t, resource_size_t), void *alignf_data) -- cgit v1.2.3 From 7c1b2c6890a1a033dde4f6991c0a1fcd69cf58ce Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 23 Feb 2010 11:48:50 +0900 Subject: sh: allow alignment fault mode to be configured at kernel boot. Follow the ARM change, which is what our alignment helpers are based on in the first place. Signed-off-by: Paul Mundt --- arch/sh/mm/alignment.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/mm/alignment.c b/arch/sh/mm/alignment.c index 2da808802a4c..00fb9e3f057c 100644 --- a/arch/sh/mm/alignment.c +++ b/arch/sh/mm/alignment.c @@ -27,6 +27,8 @@ static int se_usermode = UM_WARN | UM_FIXUP; /* 0: no warning 1: print a warning message, disabled by default */ static int se_kernmode_warn; +core_param(alignment, se_usermode, int, 0600); + void inc_unaligned_byte_access(void) { se_half++; -- cgit v1.2.3 From 94ea5e449ae834af058ef005d16a8ad44fcf13d6 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 23 Feb 2010 12:56:30 +0900 Subject: sh: wire up SET/GET_UNALIGN_CTL. This hooks up the SET/GET_UNALIGN_CTL knobs cribbing the bulk of it from the PPC and ia64 implementations. The thread flags happen to be the logical inverse of what the global fault mode is set to, so this works out pretty cleanly. By default the global fault mode is used, with tasks now being able to override their own settings via prctl(). Signed-off-by: Paul Mundt --- arch/sh/include/asm/processor.h | 12 ++++++++++++ arch/sh/include/asm/processor_32.h | 6 +++++- arch/sh/include/asm/processor_64.h | 5 +++++ arch/sh/mm/alignment.c | 30 +++++++++++++++++++++++++++++- 4 files changed, 51 insertions(+), 2 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/processor.h b/arch/sh/include/asm/processor.h index 87a8d1ef64e4..9605e062840f 100644 --- a/arch/sh/include/asm/processor.h +++ b/arch/sh/include/asm/processor.h @@ -107,6 +107,13 @@ 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; @@ -114,6 +121,11 @@ extern unsigned int mem_init_done; 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 488f0a906a41..572b4eb09493 100644 --- a/arch/sh/include/asm/processor_32.h +++ b/arch/sh/include/asm/processor_32.h @@ -101,8 +101,11 @@ struct thread_struct { unsigned long sp; unsigned long pc; + /* Various thread flags, see SH_THREAD_xxx */ + unsigned long flags; + /* Save middle states of ptrace breakpoints */ - struct perf_event *ptrace_bps[HBP_NUM]; + struct perf_event *ptrace_bps[HBP_NUM]; #ifdef CONFIG_SH_DSP /* Dsp status information */ @@ -115,6 +118,7 @@ struct thread_struct { #define INIT_THREAD { \ .sp = sizeof(init_stack) + (long) &init_stack, \ + .flags = 0, \ } /* Forward declaration, a strange C thing */ diff --git a/arch/sh/include/asm/processor_64.h b/arch/sh/include/asm/processor_64.h index 7b1560f03d14..621bc4618c6b 100644 --- a/arch/sh/include/asm/processor_64.h +++ b/arch/sh/include/asm/processor_64.h @@ -108,6 +108,10 @@ union thread_xstate { 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 @@ -138,6 +142,7 @@ struct thread_struct { .trap_no = 0, \ .error_code = 0, \ .address = 0, \ + .flags = 0, \ } /* diff --git a/arch/sh/mm/alignment.c b/arch/sh/mm/alignment.c index 00fb9e3f057c..b2595b8548ee 100644 --- a/arch/sh/mm/alignment.c +++ b/arch/sh/mm/alignment.c @@ -14,6 +14,7 @@ #include #include #include +#include static unsigned long se_user; static unsigned long se_sys; @@ -59,9 +60,36 @@ void inc_unaligned_kernel_access(void) se_sys++; } +/* + * This defaults to the global policy which can be set from the command + * line, while processes can overload their preferences via prctl(). + */ unsigned int unaligned_user_action(void) { - return se_usermode; + unsigned int action = se_usermode; + + if (current->thread.flags & SH_THREAD_UAC_SIGBUS) { + action &= ~UM_FIXUP; + action |= UM_SIGNAL; + } + + if (current->thread.flags & SH_THREAD_UAC_NOPRINT) + action &= ~UM_WARN; + + return action; +} + +int get_unalign_ctl(struct task_struct *tsk, unsigned long addr) +{ + return put_user(tsk->thread.flags & SH_THREAD_UAC_MASK, + (unsigned int __user *)addr); +} + +int set_unalign_ctl(struct task_struct *tsk, unsigned int val) +{ + tsk->thread.flags = (tsk->thread.flags & ~SH_THREAD_UAC_MASK) | + (val & SH_THREAD_UAC_MASK); + return 0; } void unaligned_fixups_notify(struct task_struct *tsk, insn_size_t insn, -- cgit v1.2.3 From 263657168549075b57ecfbf730738105d1af8b65 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 24 Feb 2010 00:32:28 +0000 Subject: sh: mach-ecovec24: Add sh_sir support Signed-off-by: Kuninori Morimoto Signed-off-by: Paul Mundt --- arch/sh/boards/mach-ecovec24/setup.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index 6f2e8a78b461..8cdf11e00ee6 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c @@ -751,6 +751,26 @@ static struct platform_device fsi_device = { }, }; +/* IrDA */ +static struct resource irda_resources[] = { + [0] = { + .name = "IrDA", + .start = 0xA45D0000, + .end = 0xA45D0049, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 20, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device irda_device = { + .name = "sh_sir", + .num_resources = ARRAY_SIZE(irda_resources), + .resource = irda_resources, +}; + static struct platform_device *ecovec_devices[] __initdata = { &heartbeat_device, &nor_flash_device, @@ -771,6 +791,7 @@ static struct platform_device *ecovec_devices[] __initdata = { &camera_devices[1], &camera_devices[2], &fsi_device, + &irda_device, }; #define EEPROM_ADDR 0x50 @@ -1131,6 +1152,12 @@ static int __init arch_setup(void) clk_set_rate(clk, clk_round_rate(clk, 166000000)); clk_put(clk); + /* enable IrDA */ + gpio_request(GPIO_FN_IRDA_OUT, NULL); + gpio_request(GPIO_FN_IRDA_IN, NULL); + gpio_request(GPIO_PTU5, NULL); + gpio_direction_output(GPIO_PTU5, 0); + /* enable I2C device */ i2c_register_board_info(0, i2c0_devices, ARRAY_SIZE(i2c0_devices)); -- cgit v1.2.3 From bbb892aac4724b7cc6e1626665310eddfd747235 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 23 Feb 2010 08:19:14 +0000 Subject: sh: ms7724: Add sh_sir support Signed-off-by: Kuninori Morimoto Signed-off-by: Paul Mundt --- arch/sh/boards/mach-se/7724/setup.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c index 1f6cf8604943..6419f27a9ef2 100644 --- a/arch/sh/boards/mach-se/7724/setup.c +++ b/arch/sh/boards/mach-se/7724/setup.c @@ -489,6 +489,26 @@ static struct platform_device sdhi1_cn8_device = { }, }; +/* IrDA */ +static struct resource irda_resources[] = { + [0] = { + .name = "IrDA", + .start = 0xA45D0000, + .end = 0xA45D0049, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 20, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device irda_device = { + .name = "sh_sir", + .num_resources = ARRAY_SIZE(irda_resources), + .resource = irda_resources, +}; + static struct platform_device *ms7724se_devices[] __initdata = { &heartbeat_device, &smc91x_eth_device, @@ -503,6 +523,7 @@ static struct platform_device *ms7724se_devices[] __initdata = { &fsi_device, &sdhi0_cn7_device, &sdhi1_cn8_device, + &irda_device, }; /* I2C device */ @@ -599,6 +620,7 @@ static int __init devices_setup(void) ~((1 << 1) | /* LAN */ (1 << 6) | /* VIDEO DAC */ (1 << 7) | /* AK4643 */ + (1 << 8) | /* IrDA */ (1 << 12) | /* USB0 */ (1 << 14)), /* RMII */ FPGA_OUT); @@ -788,6 +810,10 @@ static int __init devices_setup(void) gpio_request(GPIO_FN_SDHI1CMD, NULL); gpio_request(GPIO_FN_SDHI1CLK, NULL); + /* enable IrDA */ + gpio_request(GPIO_FN_IRDA_OUT, NULL); + gpio_request(GPIO_FN_IRDA_IN, NULL); + /* * enable SH-Eth * -- cgit v1.2.3 From 29463c28a553e1959ec45cc8ad9d2eb434663cdf Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 24 Feb 2010 00:16:47 +0000 Subject: sh: ms7724: modify scan_timing for KEYSC KEYSC::SCN register of SH7724 is 3bit. Thus, scan_timing should be 0 - 7 here. Signed-off-by: Kuninori Morimoto Signed-off-by: Paul Mundt --- arch/sh/boards/mach-se/7724/setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/sh') diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c index 6419f27a9ef2..ee5251f92811 100644 --- a/arch/sh/boards/mach-se/7724/setup.c +++ b/arch/sh/boards/mach-se/7724/setup.c @@ -313,7 +313,7 @@ static struct platform_device fsi_device = { /* KEYSC in SoC (Needs SW33-2 set to ON) */ static struct sh_keysc_info keysc_info = { .mode = SH_KEYSC_MODE_1, - .scan_timing = 10, + .scan_timing = 3, .delay = 50, .keycodes = { KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, -- cgit v1.2.3 From 41bfb7d7a6ce3d8dd83112e65f5d97feefde818a Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 25 Feb 2010 11:03:24 +0000 Subject: sh: SH-Mobile R-standby register save/restore Add code to save/restore registers during R-standby sleep on SH-Mobile processors. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/include/asm/suspend.h | 1 + arch/sh/kernel/cpu/shmobile/pm.c | 3 +- arch/sh/kernel/cpu/shmobile/sleep.S | 121 +++++++++++++++++++++++++++++++++++- 3 files changed, 122 insertions(+), 3 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/suspend.h b/arch/sh/include/asm/suspend.h index fe9c2a1ad047..64eb41a063e8 100644 --- a/arch/sh/include/asm/suspend.h +++ b/arch/sh/include/asm/suspend.h @@ -92,5 +92,6 @@ extern unsigned long sh_mobile_sleep_supported; #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/kernel/cpu/shmobile/pm.c b/arch/sh/kernel/cpu/shmobile/pm.c index ca029a44743c..e55968712706 100644 --- a/arch/sh/kernel/cpu/shmobile/pm.c +++ b/arch/sh/kernel/cpu/shmobile/pm.c @@ -33,7 +33,8 @@ ATOMIC_NOTIFIER_HEAD(sh_mobile_post_sleep_notifier_list); #define SUSP_MODE_SLEEP (SUSP_SH_SLEEP) #define SUSP_MODE_SLEEP_SF (SUSP_SH_SLEEP | SUSP_SH_SF) #define SUSP_MODE_STANDBY_SF (SUSP_SH_STANDBY | SUSP_SH_SF) -#define SUSP_MODE_RSTANDBY (SUSP_SH_RSTANDBY | SUSP_SH_MMU | SUSP_SH_SF) +#define SUSP_MODE_RSTANDBY_SF \ + (SUSP_SH_RSTANDBY | SUSP_SH_MMU | SUSP_SH_REGS | SUSP_SH_SF) /* * U-standby mode is unsupported since it needs bootloader hacks */ diff --git a/arch/sh/kernel/cpu/shmobile/sleep.S b/arch/sh/kernel/cpu/shmobile/sleep.S index e9dd7fa0abd2..e6aac65f5750 100644 --- a/arch/sh/kernel/cpu/shmobile/sleep.S +++ b/arch/sh/kernel/cpu/shmobile/sleep.S @@ -48,8 +48,48 @@ ENTRY(sh_mobile_sleep_enter_start) stc sr, r0 mov.l r0, @(SH_SLEEP_SR, r5) - /* save sp */ + /* save general purpose registers to stack if needed */ + mov.l @(SH_SLEEP_MODE, r5), r0 + tst #SUSP_SH_REGS, r0 + bt skip_regs_save + + sts.l pr, @-r15 + mov.l r14, @-r15 + mov.l r13, @-r15 + mov.l r12, @-r15 + mov.l r11, @-r15 + mov.l r10, @-r15 + mov.l r9, @-r15 + mov.l r8, @-r15 + + /* make sure bank0 is selected, save low registers */ + mov.l rb_bit, r9 + not r9, r9 + bsr set_sr + mov #0, r10 + + bsr save_low_regs + nop + + /* switch to bank 1, save low registers */ + mov.l rb_bit, r10 + bsr set_sr + mov #-1, r9 + + bsr save_low_regs + nop + + /* switch back to bank 0 */ + mov.l rb_bit, r9 + not r9, r9 + bsr set_sr + mov #0, r10 + +skip_regs_save: + + /* save sp, also set to internal ram */ mov.l r15, @(SH_SLEEP_SP, r5) + mov r5, r15 /* save stbcr */ bsr save_register @@ -60,7 +100,7 @@ ENTRY(sh_mobile_sleep_enter_start) tst #SUSP_SH_MMU, r0 bt skip_mmu_save_disable - /* save mmu state */ + /* save mmu state */ bsr save_register mov #SH_SLEEP_REG_PTEH, r0 @@ -177,6 +217,29 @@ get_register: mov.l @(r0, r5), r0 rts nop + +set_sr: + stc sr, r8 + and r9, r8 + or r10, r8 + ldc r8, sr + rts + nop + +save_low_regs: + mov.l r7, @-r15 + mov.l r6, @-r15 + mov.l r5, @-r15 + mov.l r4, @-r15 + mov.l r3, @-r15 + mov.l r2, @-r15 + mov.l r1, @-r15 + rts + mov.l r0, @-r15 + + .balign 4 +rb_bit: .long 0x20000000 ! RB=1 + ENTRY(sh_mobile_sleep_enter_end) .balign 4 @@ -270,6 +333,40 @@ skip_restore_sf: icbi @r0 skip_restore_mmu: + + /* restore general purpose registers if needed */ + mov.l @(SH_SLEEP_MODE, r5), r0 + tst #SUSP_SH_REGS, r0 + bt skip_restore_regs + + /* switch to bank 1, restore low registers */ + mov.l _rb_bit, r10 + bsr _set_sr + mov #-1, r9 + + bsr restore_low_regs + nop + + /* switch to bank0, restore low registers */ + mov.l _rb_bit, r9 + not r9, r9 + bsr _set_sr + mov #0, r10 + + bsr restore_low_regs + nop + + /* restore the rest of the registers */ + mov.l @r15+, r8 + mov.l @r15+, r9 + mov.l @r15+, r10 + mov.l @r15+, r11 + mov.l @r15+, r12 + mov.l @r15+, r13 + mov.l @r15+, r14 + lds.l @r15+, pr + +skip_restore_regs: rte nop @@ -283,6 +380,26 @@ restore_register: rts nop +_set_sr: + stc sr, r8 + and r9, r8 + or r10, r8 + ldc r8, sr + rts + nop + +restore_low_regs: + mov.l @r15+, r0 + mov.l @r15+, r1 + mov.l @r15+, r2 + mov.l @r15+, r3 + mov.l @r15+, r4 + mov.l @r15+, r5 + mov.l @r15+, r6 + rts + mov.l @r15+, r7 + .balign 4 +_rb_bit: .long 0x20000000 ! RB=1 1: .long ~0x7ff ENTRY(sh_mobile_sleep_resume_end) -- cgit v1.2.3 From b67cf2848af1cf4a4c9c277429092ae59adf859b Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 25 Feb 2010 11:06:02 +0000 Subject: sh: ms7724se r-standby support This patch adds board specific r-standby resume code for ms7724se. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/boards/mach-se/7724/sdram.S | 79 +++++++++++++++++++++++++++++++++++++ arch/sh/boards/mach-se/7724/setup.c | 3 +- 2 files changed, 81 insertions(+), 1 deletion(-) (limited to 'arch/sh') diff --git a/arch/sh/boards/mach-se/7724/sdram.S b/arch/sh/boards/mach-se/7724/sdram.S index 9040167d5022..6fa4734d09c7 100644 --- a/arch/sh/boards/mach-se/7724/sdram.S +++ b/arch/sh/boards/mach-se/7724/sdram.S @@ -39,6 +39,10 @@ ENTRY(ms7724se_sdram_leave_start) /* DBSC: put memory in auto-refresh mode */ + mov.l @(SH_SLEEP_MODE, r5), r0 + tst #SUSP_SH_RSTANDBY, r0 + bf resume_rstandby + ED 0xFD000040, 0x00000000 /* DBRFPDN0 */ WAIT 1 ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */ @@ -49,4 +53,79 @@ ENTRY(ms7724se_sdram_leave_start) rts nop +resume_rstandby: + + /* CPG: setup clocks before restarting external memory */ + + ED 0xA4150024, 0x00004000 /* PLLCR */ + + mov.l FRQCRA,r0 + mov.l @r0,r3 + mov.l KICK,r1 + or r1, r3 + mov.l r3, @r0 + + mov.l LSTATS,r0 + mov #1,r1 +WAIT_LSTATS: + mov.l @r0,r3 + tst r1,r3 + bf WAIT_LSTATS + + /* DBSC: re-initialize and put in auto-refresh */ + + ED 0xFD000108, 0x00000181 /* DBPDCNT0 */ + ED 0xFD000020, 0x015B0002 /* DBCONF */ + ED 0xFD000030, 0x03071502 /* DBTR0 */ + ED 0xFD000034, 0x02020102 /* DBTR1 */ + ED 0xFD000038, 0x01090405 /* DBTR2 */ + ED 0xFD00003C, 0x00000002 /* DBTR3 */ + ED 0xFD000008, 0x00000005 /* DBKIND */ + ED 0xFD000040, 0x00000001 /* DBRFPDN0 */ + ED 0xFD000040, 0x00000000 /* DBRFPDN0 */ + ED 0xFD000018, 0x00000001 /* DBCKECNT */ + + mov #100,r0 +WAIT_400NS: + dt r0 + bf WAIT_400NS + + ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */ + ED 0xFD000060, 0x00020000 /* DBMRCNT (EMR2) */ + ED 0xFD000060, 0x00030000 /* DBMRCNT (EMR3) */ + ED 0xFD000060, 0x00010004 /* DBMRCNT (EMR) */ + ED 0xFD000060, 0x00000532 /* DBMRCNT (MRS) */ + ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */ + ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */ + ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */ + ED 0xFD000060, 0x00000432 /* DBMRCNT (MRS) */ + ED 0xFD000060, 0x000103c0 /* DBMRCNT (EMR) */ + ED 0xFD000060, 0x00010040 /* DBMRCNT (EMR) */ + + mov #100,r0 +WAIT_400NS_2: + dt r0 + bf WAIT_400NS_2 + + ED 0xFD000010, 0x00000001 /* DBEN */ + ED 0xFD000044, 0x0000050f /* DBRFPDN1 */ + ED 0xFD000048, 0x236800e6 /* DBRFPDN2 */ + + mov.l DUMMY,r0 + mov.l @r0, r1 /* force single dummy read */ + + ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */ + ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */ + ED 0xFD000108, 0x00000080 /* DBPDCNT0 */ + ED 0xFD000040, 0x00010000 /* DBRFPDN0 */ + + rts + nop + + .balign 4 +DUMMY: .long 0xac400000 +FRQCRA: .long 0xa4150000 +KICK: .long 0x80000000 +LSTATS: .long 0xa4150060 + ENTRY(ms7724se_sdram_leave_end) diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c index ee5251f92811..563f3dcb1f9b 100644 --- a/arch/sh/boards/mach-se/7724/setup.c +++ b/arch/sh/boards/mach-se/7724/setup.c @@ -610,7 +610,8 @@ static int __init devices_setup(void) struct clk *clk; /* register board specific self-refresh code */ - sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF, + sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF | + SUSP_SH_RSTANDBY, &ms7724se_sdram_enter_start, &ms7724se_sdram_enter_end, &ms7724se_sdram_leave_start, -- cgit v1.2.3 From 2839bd61f671d3debf9ef0893a0470fd97b2e2ce Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 25 Feb 2010 11:07:52 +0000 Subject: sh: ecovec r-standby support This patch adds board specific r-standby resume code for ecovec. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/boards/mach-ecovec24/sdram.S | 59 ++++++++++++++++++++++++++++++++++++ arch/sh/boards/mach-ecovec24/setup.c | 3 +- 2 files changed, 61 insertions(+), 1 deletion(-) (limited to 'arch/sh') diff --git a/arch/sh/boards/mach-ecovec24/sdram.S b/arch/sh/boards/mach-ecovec24/sdram.S index 833440044407..3963c6f23d52 100644 --- a/arch/sh/boards/mach-ecovec24/sdram.S +++ b/arch/sh/boards/mach-ecovec24/sdram.S @@ -37,6 +37,10 @@ ENTRY(ecovec24_sdram_enter_end) .balign 4 ENTRY(ecovec24_sdram_leave_start) + mov.l @(SH_SLEEP_MODE, r5), r0 + tst #SUSP_SH_RSTANDBY, r0 + bf resume_rstandby + /* DBSC: put memory in auto-refresh mode */ ED 0xFD000040, 0x00000000 /* DBRFPDN0 */ @@ -49,4 +53,59 @@ ENTRY(ecovec24_sdram_leave_start) rts nop +resume_rstandby: + + /* DBSC: re-initialize and put in auto-refresh */ + + ED 0xFD000108, 0x00000181 /* DBPDCNT0 */ + ED 0xFD000020, 0x015B0002 /* DBCONF */ + ED 0xFD000030, 0x03071502 /* DBTR0 */ + ED 0xFD000034, 0x02020102 /* DBTR1 */ + ED 0xFD000038, 0x01090405 /* DBTR2 */ + ED 0xFD00003C, 0x00000002 /* DBTR3 */ + ED 0xFD000008, 0x00000005 /* DBKIND */ + ED 0xFD000040, 0x00000001 /* DBRFPDN0 */ + ED 0xFD000040, 0x00000000 /* DBRFPDN0 */ + ED 0xFD000018, 0x00000001 /* DBCKECNT */ + + mov #100,r0 +WAIT_400NS: + dt r0 + bf WAIT_400NS + + ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */ + ED 0xFD000060, 0x00020000 /* DBMRCNT (EMR2) */ + ED 0xFD000060, 0x00030000 /* DBMRCNT (EMR3) */ + ED 0xFD000060, 0x00010004 /* DBMRCNT (EMR) */ + ED 0xFD000060, 0x00000532 /* DBMRCNT (MRS) */ + ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */ + ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */ + ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */ + ED 0xFD000060, 0x00000432 /* DBMRCNT (MRS) */ + ED 0xFD000060, 0x000103c0 /* DBMRCNT (EMR) */ + ED 0xFD000060, 0x00010040 /* DBMRCNT (EMR) */ + + mov #100,r0 +WAIT_400NS_2: + dt r0 + bf WAIT_400NS_2 + + ED 0xFD000010, 0x00000001 /* DBEN */ + ED 0xFD000044, 0x0000050f /* DBRFPDN1 */ + ED 0xFD000048, 0x236800e6 /* DBRFPDN2 */ + + mov.l DUMMY,r0 + mov.l @r0, r1 /* force single dummy read */ + + ED 0xFD000014, 0x00000002 /* DBCMDCNT (PALL) */ + ED 0xFD000014, 0x00000004 /* DBCMDCNT (REF) */ + ED 0xFD000108, 0x00000080 /* DBPDCNT0 */ + ED 0xFD000040, 0x00010000 /* DBRFPDN0 */ + + rts + nop + + .balign 4 +DUMMY: .long 0xac400000 + ENTRY(ecovec24_sdram_leave_end) diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index 8cdf11e00ee6..3248406ea7ff 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c @@ -850,7 +850,8 @@ static int __init arch_setup(void) struct clk *clk; /* register board specific self-refresh code */ - sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF, + sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF | + SUSP_SH_RSTANDBY, &ecovec24_sdram_enter_start, &ecovec24_sdram_enter_end, &ecovec24_sdram_leave_start, -- cgit v1.2.3 From 6b3b55750b0de4a4ff2742efd34ff74665fa4e2f Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 25 Feb 2010 11:10:54 +0000 Subject: sh: ecovec build fix for CONFIG_I2C=n Allow building the ecovec board support code even though I2C support is disabled. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/boards/mach-ecovec24/setup.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'arch/sh') diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index 3248406ea7ff..39ed8722d11a 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c @@ -794,6 +794,7 @@ static struct platform_device *ecovec_devices[] __initdata = { &irda_device, }; +#ifdef CONFIG_I2C #define EEPROM_ADDR 0x50 static u8 mac_read(struct i2c_adapter *a, u8 command) { @@ -836,6 +837,12 @@ static void __init sh_eth_init(struct sh_eth_plat_data *pd) msleep(10); } } +#else +static void __init sh_eth_init(struct sh_eth_plat_data *pd) +{ + pr_err("unable to read sh_eth MAC address\n"); +} +#endif #define PORT_HIZA 0xA4050158 #define IODRIVEA 0xA405018A -- cgit v1.2.3 From b5f5fe80fa98a60daa0fa94512d1599b1e26674c Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 25 Feb 2010 11:14:28 +0000 Subject: sh: remove dead LED code for migo-r and ms7724se CONFIG_PM is always set on SH-Mobile these days so get rid of the unused LED setup code. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/boards/mach-migor/setup.c | 12 ------------ arch/sh/boards/mach-se/7724/setup.c | 17 ----------------- 2 files changed, 29 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c index d1e51a9baf9c..e08d5132bb1e 100644 --- a/arch/sh/boards/mach-migor/setup.c +++ b/arch/sh/boards/mach-migor/setup.c @@ -496,23 +496,11 @@ static int __init migor_devices_setup(void) &migor_sdram_enter_end, &migor_sdram_leave_start, &migor_sdram_leave_end); -#ifdef CONFIG_PM /* Let D11 LED show STATUS0 */ gpio_request(GPIO_FN_STATUS0, NULL); /* Lit D12 LED show PDSTATUS */ gpio_request(GPIO_FN_PDSTATUS, NULL); -#else - /* Lit D11 LED */ - gpio_request(GPIO_PTJ7, NULL); - gpio_direction_output(GPIO_PTJ7, 1); - gpio_export(GPIO_PTJ7, 0); - - /* Lit D12 LED */ - gpio_request(GPIO_PTJ5, NULL); - gpio_direction_output(GPIO_PTJ5, 1); - gpio_export(GPIO_PTJ5, 0); -#endif /* SMC91C111 - Enable IRQ0, Setup CS4 for 16-bit fast access */ gpio_request(GPIO_FN_IRQ0, NULL); diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c index 563f3dcb1f9b..66cdbc3c7af9 100644 --- a/arch/sh/boards/mach-se/7724/setup.c +++ b/arch/sh/boards/mach-se/7724/setup.c @@ -629,7 +629,6 @@ static int __init devices_setup(void) /* turn on USB clocks, use external clock */ __raw_writew((__raw_readw(PORT_MSELCRB) & ~0xc000) | 0x8000, PORT_MSELCRB); -#ifdef CONFIG_PM /* Let LED9 show STATUS2 */ gpio_request(GPIO_FN_STATUS2, NULL); @@ -638,22 +637,6 @@ static int __init devices_setup(void) /* Lit LED11 show PDSTATUS */ gpio_request(GPIO_FN_PDSTATUS, NULL); -#else - /* Lit LED9 */ - gpio_request(GPIO_PTJ6, NULL); - gpio_direction_output(GPIO_PTJ6, 1); - gpio_export(GPIO_PTJ6, 0); - - /* Lit LED10 */ - gpio_request(GPIO_PTJ5, NULL); - gpio_direction_output(GPIO_PTJ5, 1); - gpio_export(GPIO_PTJ5, 0); - - /* Lit LED11 */ - gpio_request(GPIO_PTJ7, NULL); - gpio_direction_output(GPIO_PTJ7, 1); - gpio_export(GPIO_PTJ7, 0); -#endif /* enable USB0 port */ __raw_writew(0x0600, 0xa40501d4); -- cgit v1.2.3 From 3675c750cf2effc6a2d9582cd1b9d3043aded3b6 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 6 Jan 2010 18:42:16 +0900 Subject: soc-camera: ov772x: Modify buswidth control This patch removes "buswidth" struct member, and sets the default buswidth to the natively supported 10 bit. You can select 8 bit buswidth by new flag. This patch also modify ap325rxa/migor setup.c Signed-off-by: Kuninori Morimoto Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- arch/sh/boards/mach-ap325rxa/setup.c | 4 ++-- arch/sh/boards/mach-migor/setup.c | 2 +- drivers/media/video/ov772x.c | 22 +++++++--------------- include/media/ov772x.h | 10 +++++----- 4 files changed, 15 insertions(+), 23 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c index 1f5fa5c44f6d..71f556fe3f38 100644 --- a/arch/sh/boards/mach-ap325rxa/setup.c +++ b/arch/sh/boards/mach-ap325rxa/setup.c @@ -471,8 +471,8 @@ static struct i2c_board_info ap325rxa_i2c_camera[] = { }; static struct ov772x_camera_info ov7725_info = { - .buswidth = SOCAM_DATAWIDTH_8, - .flags = OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP, + .flags = OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP | \ + OV772X_FLAG_8BIT, .edgectrl = OV772X_AUTO_EDGECTRL(0xf, 0), }; diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c index 507c77be476d..9b4676fa6fbb 100644 --- a/arch/sh/boards/mach-migor/setup.c +++ b/arch/sh/boards/mach-migor/setup.c @@ -431,7 +431,7 @@ static struct i2c_board_info migor_i2c_camera[] = { }; static struct ov772x_camera_info ov7725_info = { - .buswidth = SOCAM_DATAWIDTH_8, + .flags = OV772X_FLAG_8BIT, }; static struct soc_camera_link ov7725_link = { diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c index 3a45e945a528..7f8ece30c77b 100644 --- a/drivers/media/video/ov772x.c +++ b/drivers/media/video/ov772x.c @@ -547,7 +547,6 @@ static const struct v4l2_queryctrl ov772x_controls[] = { }, }; - /* * general function */ @@ -634,7 +633,12 @@ static unsigned long ov772x_query_bus_param(struct soc_camera_device *icd) struct soc_camera_link *icl = to_soc_camera_link(icd); unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER | SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH | - SOCAM_DATA_ACTIVE_HIGH | priv->info->buswidth; + SOCAM_DATA_ACTIVE_HIGH; + + if (priv->info->flags & OV772X_FLAG_8BIT) + flags |= SOCAM_DATAWIDTH_8; + else + flags |= SOCAM_DATAWIDTH_10; return soc_camera_apply_sensor_flags(icl, flags); } @@ -1039,15 +1043,6 @@ static int ov772x_video_probe(struct soc_camera_device *icd, to_soc_camera_host(icd->dev.parent)->nr != icd->iface) return -ENODEV; - /* - * ov772x only use 8 or 10 bit bus width - */ - if (SOCAM_DATAWIDTH_10 != priv->info->buswidth && - SOCAM_DATAWIDTH_8 != priv->info->buswidth) { - dev_err(&client->dev, "bus width error\n"); - return -ENODEV; - } - /* * check and show product ID and manufacturer ID */ @@ -1130,7 +1125,6 @@ static int ov772x_probe(struct i2c_client *client, const struct i2c_device_id *did) { struct ov772x_priv *priv; - struct ov772x_camera_info *info; struct soc_camera_device *icd = client->dev.platform_data; struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); struct soc_camera_link *icl; @@ -1145,8 +1139,6 @@ static int ov772x_probe(struct i2c_client *client, if (!icl || !icl->priv) return -EINVAL; - info = icl->priv; - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { dev_err(&adapter->dev, "I2C-Adapter doesn't support " @@ -1158,7 +1150,7 @@ static int ov772x_probe(struct i2c_client *client, if (!priv) return -ENOMEM; - priv->info = info; + priv->info = icl->priv; v4l2_i2c_subdev_init(&priv->subdev, client, &ov772x_subdev_ops); diff --git a/include/media/ov772x.h b/include/media/ov772x.h index 14c77efd6a85..548bf1155c83 100644 --- a/include/media/ov772x.h +++ b/include/media/ov772x.h @@ -15,8 +15,9 @@ #include /* for flags */ -#define OV772X_FLAG_VFLIP 0x00000001 /* Vertical flip image */ -#define OV772X_FLAG_HFLIP 0x00000002 /* Horizontal flip image */ +#define OV772X_FLAG_VFLIP (1 << 0) /* Vertical flip image */ +#define OV772X_FLAG_HFLIP (1 << 1) /* Horizontal flip image */ +#define OV772X_FLAG_8BIT (1 << 2) /* default 10 bit */ /* * for Edge ctrl @@ -53,9 +54,8 @@ struct ov772x_edge_ctrl { * ov772x camera info */ struct ov772x_camera_info { - unsigned long buswidth; - unsigned long flags; - struct ov772x_edge_ctrl edgectrl; + unsigned long flags; + struct ov772x_edge_ctrl edgectrl; }; #endif /* __OV772X_H__ */ -- cgit v1.2.3