diff options
Diffstat (limited to 'arch/blackfin/kernel')
-rw-r--r-- | arch/blackfin/kernel/asm-offsets.c | 3 | ||||
-rw-r--r-- | arch/blackfin/kernel/bfin_dma_5xx.c | 11 | ||||
-rw-r--r-- | arch/blackfin/kernel/bfin_gpio.c | 19 | ||||
-rw-r--r-- | arch/blackfin/kernel/bfin_ksyms.c | 2 | ||||
-rw-r--r-- | arch/blackfin/kernel/cplb-nompu/cplbinit.c | 6 | ||||
-rw-r--r-- | arch/blackfin/kernel/fixed_code.S | 2 | ||||
-rw-r--r-- | arch/blackfin/kernel/gptimers.c | 2 | ||||
-rw-r--r-- | arch/blackfin/kernel/init_task.c | 1 | ||||
-rw-r--r-- | arch/blackfin/kernel/irqchip.c | 5 | ||||
-rw-r--r-- | arch/blackfin/kernel/module.c | 37 | ||||
-rw-r--r-- | arch/blackfin/kernel/process.c | 2 | ||||
-rw-r--r-- | arch/blackfin/kernel/ptrace.c | 4 | ||||
-rw-r--r-- | arch/blackfin/kernel/signal.c | 13 | ||||
-rw-r--r-- | arch/blackfin/kernel/sys_bfin.c | 17 | ||||
-rw-r--r-- | arch/blackfin/kernel/time-ts.c | 10 | ||||
-rw-r--r-- | arch/blackfin/kernel/traps.c | 24 |
16 files changed, 99 insertions, 59 deletions
diff --git a/arch/blackfin/kernel/asm-offsets.c b/arch/blackfin/kernel/asm-offsets.c index 721f15f3ceb..881afe9082c 100644 --- a/arch/blackfin/kernel/asm-offsets.c +++ b/arch/blackfin/kernel/asm-offsets.c @@ -56,9 +56,6 @@ int main(void) /* offsets into the thread struct */ DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp)); DEFINE(THREAD_USP, offsetof(struct thread_struct, usp)); - DEFINE(THREAD_SR, offsetof(struct thread_struct, seqstat)); - DEFINE(PT_SR, offsetof(struct thread_struct, seqstat)); - DEFINE(THREAD_ESP0, offsetof(struct thread_struct, esp0)); DEFINE(THREAD_PC, offsetof(struct thread_struct, pc)); DEFINE(KERNEL_STACK_SIZE, THREAD_SIZE); diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c index fd5448d6107..d54f19085f3 100644 --- a/arch/blackfin/kernel/bfin_dma_5xx.c +++ b/arch/blackfin/kernel/bfin_dma_5xx.c @@ -90,6 +90,17 @@ int request_dma(unsigned int channel, char *device_id) { pr_debug("request_dma() : BEGIN \n"); + +#if defined(CONFIG_BF561) && ANOMALY_05000182 + if (channel >= CH_IMEM_STREAM0_DEST && channel <= CH_IMEM_STREAM1_DEST) { + if (get_cclk() > 500000000) { + printk(KERN_WARNING + "Request IMDMA failed due to ANOMALY 05000182\n"); + return -EFAULT; + } + } +#endif + mutex_lock(&(dma_ch[channel].dmalock)); if ((dma_ch[channel].chan_status == DMA_CHANNEL_REQUESTED) diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c index 7e8eaf4a31b..b6d89d1644c 100644 --- a/arch/blackfin/kernel/bfin_gpio.c +++ b/arch/blackfin/kernel/bfin_gpio.c @@ -1130,6 +1130,25 @@ void bfin_gpio_irq_prepare(unsigned gpio) #else +int gpio_get_value(unsigned gpio) +{ + unsigned long flags; + int ret; + + if (unlikely(get_gpio_edge(gpio))) { + local_irq_save(flags); + set_gpio_edge(gpio, 0); + ret = get_gpio_data(gpio); + set_gpio_edge(gpio, 1); + local_irq_restore(flags); + + return ret; + } else + return get_gpio_data(gpio); +} +EXPORT_SYMBOL(gpio_get_value); + + int gpio_direction_input(unsigned gpio) { unsigned long flags; diff --git a/arch/blackfin/kernel/bfin_ksyms.c b/arch/blackfin/kernel/bfin_ksyms.c index 053edff6c0d..4367330909b 100644 --- a/arch/blackfin/kernel/bfin_ksyms.c +++ b/arch/blackfin/kernel/bfin_ksyms.c @@ -90,7 +90,9 @@ EXPORT_SYMBOL(__umodsi3); EXPORT_SYMBOL(outsb); EXPORT_SYMBOL(insb); EXPORT_SYMBOL(outsw); +EXPORT_SYMBOL(outsw_8); EXPORT_SYMBOL(insw); +EXPORT_SYMBOL(insw_8); EXPORT_SYMBOL(outsl); EXPORT_SYMBOL(insl); EXPORT_SYMBOL(insl_16); diff --git a/arch/blackfin/kernel/cplb-nompu/cplbinit.c b/arch/blackfin/kernel/cplb-nompu/cplbinit.c index 917325bfbd8..6be0c50122e 100644 --- a/arch/blackfin/kernel/cplb-nompu/cplbinit.c +++ b/arch/blackfin/kernel/cplb-nompu/cplbinit.c @@ -254,7 +254,8 @@ close_cplbtab(struct cplb_tab *table) } /* helper function */ -static void __fill_code_cplbtab(struct cplb_tab *t, int i, u32 a_start, u32 a_end) +static void __init +__fill_code_cplbtab(struct cplb_tab *t, int i, u32 a_start, u32 a_end) { if (cplb_data[i].psize) { fill_cplbtab(t, @@ -291,7 +292,8 @@ static void __fill_code_cplbtab(struct cplb_tab *t, int i, u32 a_start, u32 a_en } } -static void __fill_data_cplbtab(struct cplb_tab *t, int i, u32 a_start, u32 a_end) +static void __init +__fill_data_cplbtab(struct cplb_tab *t, int i, u32 a_start, u32 a_end) { if (cplb_data[i].psize) { fill_cplbtab(t, diff --git a/arch/blackfin/kernel/fixed_code.S b/arch/blackfin/kernel/fixed_code.S index 5ed47228a39..4b03ba02548 100644 --- a/arch/blackfin/kernel/fixed_code.S +++ b/arch/blackfin/kernel/fixed_code.S @@ -1,6 +1,6 @@ /* * This file contains sequences of code that will be copied to a - * fixed location, defined in <asm/atomic_seq.h>. The interrupt + * fixed location, defined in <asm/fixed_code.h>. The interrupt * handlers ensure that these sequences appear to be atomic when * executed from userspace. * These are aligned to 16 bytes, so that we have some space to replace diff --git a/arch/blackfin/kernel/gptimers.c b/arch/blackfin/kernel/gptimers.c index e698554895a..3a3e9615b00 100644 --- a/arch/blackfin/kernel/gptimers.c +++ b/arch/blackfin/kernel/gptimers.c @@ -10,8 +10,8 @@ #include <linux/kernel.h> #include <linux/module.h> +#include <linux/io.h> -#include <asm/io.h> #include <asm/blackfin.h> #include <asm/gptimers.h> diff --git a/arch/blackfin/kernel/init_task.c b/arch/blackfin/kernel/init_task.c index c640154030e..6bdba7b2110 100644 --- a/arch/blackfin/kernel/init_task.c +++ b/arch/blackfin/kernel/init_task.c @@ -34,7 +34,6 @@ #include <linux/fs.h> static struct fs_struct init_fs = INIT_FS; -static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS(init_signals); static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); diff --git a/arch/blackfin/kernel/irqchip.c b/arch/blackfin/kernel/irqchip.c index 73647c15877..07402f57c9d 100644 --- a/arch/blackfin/kernel/irqchip.c +++ b/arch/blackfin/kernel/irqchip.c @@ -60,9 +60,14 @@ static struct irq_chip bad_chip = { }; static struct irq_desc bad_irq_desc = { + .status = IRQ_DISABLED, .chip = &bad_chip, .handle_irq = handle_bad_irq, .depth = 1, + .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock), +#ifdef CONFIG_SMP + .affinity = CPU_MASK_ALL +#endif }; int show_interrupts(struct seq_file *p, void *v) diff --git a/arch/blackfin/kernel/module.c b/arch/blackfin/kernel/module.c index 8b9fe29d03f..14a42848f37 100644 --- a/arch/blackfin/kernel/module.c +++ b/arch/blackfin/kernel/module.c @@ -160,6 +160,13 @@ int module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs, char *secstrings, struct module *mod) { + /* + * XXX: sechdrs are vmalloced in kernel/module.c + * and would be vfreed just after module is loaded, + * so we hack to keep the only information we needed + * in mod->arch to correctly free L1 I/D sram later. + * NOTE: this breaks the semantic of mod->arch structure. + */ Elf_Shdr *s, *sechdrs_end = sechdrs + hdr->e_shnum; void *dest = NULL; @@ -167,8 +174,8 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs, if ((strcmp(".l1.text", secstrings + s->sh_name) == 0) || ((strcmp(".text", secstrings + s->sh_name) == 0) && (hdr->e_flags & FLG_CODE_IN_L1) && (s->sh_size > 0))) { - mod->arch.text_l1 = s; dest = l1_inst_sram_alloc(s->sh_size); + mod->arch.text_l1 = dest; if (dest == NULL) { printk(KERN_ERR "module %s: L1 instruction memory allocation failed\n", @@ -182,8 +189,8 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs, if ((strcmp(".l1.data", secstrings + s->sh_name) == 0) || ((strcmp(".data", secstrings + s->sh_name) == 0) && (hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) { - mod->arch.data_a_l1 = s; dest = l1_data_sram_alloc(s->sh_size); + mod->arch.data_a_l1 = dest; if (dest == NULL) { printk(KERN_ERR "module %s: L1 data memory allocation failed\n", @@ -197,8 +204,8 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs, if (strcmp(".l1.bss", secstrings + s->sh_name) == 0 || ((strcmp(".bss", secstrings + s->sh_name) == 0) && (hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) { - mod->arch.bss_a_l1 = s; dest = l1_data_sram_alloc(s->sh_size); + mod->arch.bss_a_l1 = dest; if (dest == NULL) { printk(KERN_ERR "module %s: L1 data memory allocation failed\n", @@ -210,8 +217,8 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs, s->sh_addr = (unsigned long)dest; } if (strcmp(".l1.data.B", secstrings + s->sh_name) == 0) { - mod->arch.data_b_l1 = s; dest = l1_data_B_sram_alloc(s->sh_size); + mod->arch.data_b_l1 = dest; if (dest == NULL) { printk(KERN_ERR "module %s: L1 data memory allocation failed\n", @@ -223,8 +230,8 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs, s->sh_addr = (unsigned long)dest; } if (strcmp(".l1.bss.B", secstrings + s->sh_name) == 0) { - mod->arch.bss_b_l1 = s; dest = l1_data_B_sram_alloc(s->sh_size); + mod->arch.bss_b_l1 = dest; if (dest == NULL) { printk(KERN_ERR "module %s: L1 data memory allocation failed\n", @@ -416,14 +423,14 @@ module_finalize(const Elf_Ehdr * hdr, void module_arch_cleanup(struct module *mod) { - if ((mod->arch.text_l1) && (mod->arch.text_l1->sh_addr)) - l1_inst_sram_free((void *)mod->arch.text_l1->sh_addr); - if ((mod->arch.data_a_l1) && (mod->arch.data_a_l1->sh_addr)) - l1_data_sram_free((void *)mod->arch.data_a_l1->sh_addr); - if ((mod->arch.bss_a_l1) && (mod->arch.bss_a_l1->sh_addr)) - l1_data_sram_free((void *)mod->arch.bss_a_l1->sh_addr); - if ((mod->arch.data_b_l1) && (mod->arch.data_b_l1->sh_addr)) - l1_data_B_sram_free((void *)mod->arch.data_b_l1->sh_addr); - if ((mod->arch.bss_b_l1) && (mod->arch.bss_b_l1->sh_addr)) - l1_data_B_sram_free((void *)mod->arch.bss_b_l1->sh_addr); + if (mod->arch.text_l1) + l1_inst_sram_free((void *)mod->arch.text_l1); + if (mod->arch.data_a_l1) + l1_data_sram_free((void *)mod->arch.data_a_l1); + if (mod->arch.bss_a_l1) + l1_data_sram_free((void *)mod->arch.bss_a_l1); + if (mod->arch.data_b_l1) + l1_data_B_sram_free((void *)mod->arch.data_b_l1); + if (mod->arch.bss_b_l1) + l1_data_B_sram_free((void *)mod->arch.bss_b_l1); } diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c index be9fdd00d7c..53c2cd25544 100644 --- a/arch/blackfin/kernel/process.c +++ b/arch/blackfin/kernel/process.c @@ -245,7 +245,7 @@ unsigned long get_wchan(struct task_struct *p) void finish_atomic_sections (struct pt_regs *regs) { - int __user *up0 = (int __user *)®s->p0; + int __user *up0 = (int __user *)regs->p0; if (regs->pc < ATOMIC_SEQS_START || regs->pc >= ATOMIC_SEQS_END) return; diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c index b4f062c172c..f51ab088098 100644 --- a/arch/blackfin/kernel/ptrace.c +++ b/arch/blackfin/kernel/ptrace.c @@ -185,8 +185,8 @@ void ptrace_disable(struct task_struct *child) { unsigned long tmp; /* make sure the single step bit is not set. */ - tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16); - put_reg(child, PT_SR, tmp); + tmp = get_reg(child, PT_SYSCFG) & ~TRACE_BITS; + put_reg(child, PT_SYSCFG, tmp); } long arch_ptrace(struct task_struct *child, long request, long addr, long data) diff --git a/arch/blackfin/kernel/signal.c b/arch/blackfin/kernel/signal.c index cb9d883d493..dbc3bbf846b 100644 --- a/arch/blackfin/kernel/signal.c +++ b/arch/blackfin/kernel/signal.c @@ -42,6 +42,9 @@ #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) +/* Location of the trace bit in SYSCFG. */ +#define TRACE_BITS 0x0001 + struct fdpic_func_descriptor { unsigned long text; unsigned long GOT; @@ -225,6 +228,16 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info, regs->r1 = (unsigned long)(&frame->info); regs->r2 = (unsigned long)(&frame->uc); + /* + * Clear the trace flag when entering the signal handler, but + * notify any tracer that was single-stepping it. The tracer + * may want to single-step inside the handler too. + */ + if (regs->syscfg & TRACE_BITS) { + regs->syscfg &= ~TRACE_BITS; + ptrace_notify(SIGTRAP); + } + return 0; give_sigsegv: diff --git a/arch/blackfin/kernel/sys_bfin.c b/arch/blackfin/kernel/sys_bfin.c index efb7b25a263..fce49d7cf00 100644 --- a/arch/blackfin/kernel/sys_bfin.c +++ b/arch/blackfin/kernel/sys_bfin.c @@ -45,23 +45,6 @@ #include <asm/cacheflush.h> #include <asm/dma.h> -/* - * sys_pipe() is the normal C calling standard for creating - * a pipe. It's not the way unix traditionally does this, though. - */ -asmlinkage int sys_pipe(unsigned long __user *fildes) -{ - int fd[2]; - int error; - - error = do_pipe(fd); - if (!error) { - if (copy_to_user(fildes, fd, 2 * sizeof(int))) - error = -EFAULT; - } - return error; -} - /* common code for old and new mmaps */ static inline long do_mmap2(unsigned long addr, unsigned long len, diff --git a/arch/blackfin/kernel/time-ts.c b/arch/blackfin/kernel/time-ts.c index 4482c47c09e..e887efc86c2 100644 --- a/arch/blackfin/kernel/time-ts.c +++ b/arch/blackfin/kernel/time-ts.c @@ -60,7 +60,7 @@ static inline unsigned long long cycles_2_ns(cycle_t cyc) static cycle_t read_cycles(void) { - return get_cycles(); + return __bfin_cycles_off + (get_cycles() << __bfin_cycles_mod); } unsigned long long sched_clock(void) @@ -117,7 +117,7 @@ static void bfin_timer_set_mode(enum clock_event_mode mode, break; } case CLOCK_EVT_MODE_ONESHOT: - bfin_write_TSCALE(0); + bfin_write_TSCALE(TIME_SCALE - 1); bfin_write_TCOUNT(0); bfin_write_TCNTL(TMPWR | TMREN); CSYNC(); @@ -183,10 +183,14 @@ irqreturn_t timer_interrupt(int irq, void *dev_id) static int __init bfin_clockevent_init(void) { + unsigned long timer_clk; + + timer_clk = get_cclk() / TIME_SCALE; + setup_irq(IRQ_CORETMR, &bfin_timer_irq); bfin_timer_init(); - clockevent_bfin.mult = div_sc(get_cclk(), NSEC_PER_SEC, clockevent_bfin.shift); + clockevent_bfin.mult = div_sc(timer_clk, NSEC_PER_SEC, clockevent_bfin.shift); clockevent_bfin.max_delta_ns = clockevent_delta2ns(-1, &clockevent_bfin); clockevent_bfin.min_delta_ns = clockevent_delta2ns(100, &clockevent_bfin); clockevents_register_device(&clockevent_bfin); diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index 5b847070dae..f061f518162 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c @@ -67,7 +67,7 @@ void __init trap_init(void) CSYNC(); } -void *saved_icplb_fault_addr, *saved_dcplb_fault_addr; +unsigned long saved_icplb_fault_addr, saved_dcplb_fault_addr; int kstack_depth_to_print = 48; @@ -364,13 +364,13 @@ asmlinkage void trap_c(struct pt_regs *fp) /* 0x27 - Data CPLB Multiple Hits - Linux Trap Zero, handled here */ case VEC_CPLB_MHIT: info.si_code = ILL_CPLB_MULHIT; -#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO sig = SIGSEGV; - printk(KERN_NOTICE "NULL pointer access (probably)\n"); -#else - sig = SIGILL; - printk(KERN_NOTICE EXC_0x27(KERN_NOTICE)); +#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO + if (saved_dcplb_fault_addr < FIXED_CODE_START) + printk(KERN_NOTICE "NULL pointer access\n"); + else #endif + printk(KERN_NOTICE EXC_0x27(KERN_NOTICE)); CHK_DEBUGGER_TRAP(); break; /* 0x28 - Emulation Watchpoint, handled here */ @@ -419,13 +419,13 @@ asmlinkage void trap_c(struct pt_regs *fp) /* 0x2D - Instruction CPLB Multiple Hits, handled here */ case VEC_CPLB_I_MHIT: info.si_code = ILL_CPLB_MULHIT; -#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO sig = SIGSEGV; - printk(KERN_NOTICE "Jump to address 0 - 0x0fff\n"); -#else - sig = SIGILL; - printk(KERN_NOTICE EXC_0x2D(KERN_NOTICE)); +#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO + if (saved_icplb_fault_addr < FIXED_CODE_START) + printk(KERN_NOTICE "Jump to NULL address\n"); + else #endif + printk(KERN_NOTICE EXC_0x2D(KERN_NOTICE)); CHK_DEBUGGER_TRAP(); break; /* 0x2E - Illegal use of Supervisor Resource, handled here */ @@ -939,8 +939,6 @@ void panic_cplb_error(int cplb_panic, struct pt_regs *fp) oops_in_progress = 1; - printk(KERN_EMERG "DCPLB_FAULT_ADDR=%p\n", saved_dcplb_fault_addr); - printk(KERN_EMERG "ICPLB_FAULT_ADDR=%p\n", saved_icplb_fault_addr); dump_bfin_process(fp); dump_bfin_mem(fp); show_regs(fp); |