diff options
Diffstat (limited to 'arch/unicore32/kernel')
| -rw-r--r-- | arch/unicore32/kernel/Makefile | 4 | ||||
| -rw-r--r-- | arch/unicore32/kernel/clock.c | 8 | ||||
| -rw-r--r-- | arch/unicore32/kernel/cpu-ucv2.c | 93 | ||||
| -rw-r--r-- | arch/unicore32/kernel/dma.c | 1 | ||||
| -rw-r--r-- | arch/unicore32/kernel/early_printk.c | 14 | ||||
| -rw-r--r-- | arch/unicore32/kernel/entry.S | 33 | ||||
| -rw-r--r-- | arch/unicore32/kernel/head.S | 2 | ||||
| -rw-r--r-- | arch/unicore32/kernel/hibernate.c | 1 | ||||
| -rw-r--r-- | arch/unicore32/kernel/init_task.c | 44 | ||||
| -rw-r--r-- | arch/unicore32/kernel/irq.c | 1 | ||||
| -rw-r--r-- | arch/unicore32/kernel/ksyms.c | 42 | ||||
| -rw-r--r-- | arch/unicore32/kernel/ksyms.h | 2 | ||||
| -rw-r--r-- | arch/unicore32/kernel/module.c | 14 | ||||
| -rw-r--r-- | arch/unicore32/kernel/pci.c | 24 | ||||
| -rw-r--r-- | arch/unicore32/kernel/process.c | 113 | ||||
| -rw-r--r-- | arch/unicore32/kernel/puv3-nb0916.c | 1 | ||||
| -rw-r--r-- | arch/unicore32/kernel/pwm.c | 263 | ||||
| -rw-r--r-- | arch/unicore32/kernel/setup.c | 4 | ||||
| -rw-r--r-- | arch/unicore32/kernel/setup.h | 11 | ||||
| -rw-r--r-- | arch/unicore32/kernel/signal.c | 74 | ||||
| -rw-r--r-- | arch/unicore32/kernel/sys.c | 88 | ||||
| -rw-r--r-- | arch/unicore32/kernel/traps.c | 9 |
22 files changed, 79 insertions, 767 deletions
diff --git a/arch/unicore32/kernel/Makefile b/arch/unicore32/kernel/Makefile index aeb0f181568..607a72f2ae3 100644 --- a/arch/unicore32/kernel/Makefile +++ b/arch/unicore32/kernel/Makefile @@ -9,14 +9,12 @@ obj-y += setup.o signal.o sys.o stacktrace.o traps.o obj-$(CONFIG_MODULES) += ksyms.o module.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o -obj-$(CONFIG_CPU_FREQ) += cpu-ucv2.o obj-$(CONFIG_UNICORE_FPU_F64) += fpu-ucf64.o # obj-y for architecture PKUnity v3 obj-$(CONFIG_ARCH_PUV3) += clock.o irq.o time.o obj-$(CONFIG_PUV3_GPIO) += gpio.o -obj-$(CONFIG_PUV3_PWM) += pwm.o obj-$(CONFIG_PUV3_PM) += pm.o sleep.o obj-$(CONFIG_HIBERNATION) += hibernate.o hibernate_asm.o @@ -29,4 +27,4 @@ obj-$(CONFIG_PUV3_NB0916) += puv3-nb0916.o head-y := head.o obj-$(CONFIG_DEBUG_LL) += debug.o -extra-y := $(head-y) init_task.o vmlinux.lds +extra-y := $(head-y) vmlinux.lds diff --git a/arch/unicore32/kernel/clock.c b/arch/unicore32/kernel/clock.c index 18d4563e6fa..b1ca775f6f6 100644 --- a/arch/unicore32/kernel/clock.c +++ b/arch/unicore32/kernel/clock.c @@ -179,7 +179,7 @@ int clk_set_rate(struct clk *clk, unsigned long rate) } #ifdef CONFIG_CPU_FREQ if (clk == &clk_mclk_clk) { - u32 pll_rate, divstatus = PM_DIVSTATUS; + u32 pll_rate, divstatus = readl(PM_DIVSTATUS); int ret, i; /* lookup mclk_clk_table */ @@ -201,10 +201,10 @@ int clk_set_rate(struct clk *clk, unsigned long rate) / (((divstatus & 0x0000f000) >> 12) + 1); /* set pll sys cfg reg. */ - PM_PLLSYSCFG = pll_rate; + writel(pll_rate, PM_PLLSYSCFG); - PM_PMCR = PM_PMCR_CFBSYS; - while ((PM_PLLDFCDONE & PM_PLLDFCDONE_SYSDFC) + writel(PM_PMCR_CFBSYS, PM_PMCR); + while ((readl(PM_PLLDFCDONE) & PM_PLLDFCDONE_SYSDFC) != PM_PLLDFCDONE_SYSDFC) udelay(100); /* about 1ms */ diff --git a/arch/unicore32/kernel/cpu-ucv2.c b/arch/unicore32/kernel/cpu-ucv2.c deleted file mode 100644 index 4a99f62584c..00000000000 --- a/arch/unicore32/kernel/cpu-ucv2.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * linux/arch/unicore32/kernel/cpu-ucv2.c: clock scaling for the UniCore-II - * - * Code specific to PKUnity SoC and UniCore ISA - * - * Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn> - * Copyright (C) 2001-2010 Guan Xuetao - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/init.h> -#include <linux/clk.h> -#include <linux/cpufreq.h> - -#include <mach/hardware.h> - -static struct cpufreq_driver ucv2_driver; - -/* make sure that only the "userspace" governor is run - * -- anything else wouldn't make sense on this platform, anyway. - */ -int ucv2_verify_speed(struct cpufreq_policy *policy) -{ - if (policy->cpu) - return -EINVAL; - - cpufreq_verify_within_limits(policy, - policy->cpuinfo.min_freq, policy->cpuinfo.max_freq); - - return 0; -} - -static unsigned int ucv2_getspeed(unsigned int cpu) -{ - struct clk *mclk = clk_get(NULL, "MAIN_CLK"); - - if (cpu) - return 0; - return clk_get_rate(mclk)/1000; -} - -static int ucv2_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) -{ - unsigned int cur = ucv2_getspeed(0); - struct cpufreq_freqs freqs; - struct clk *mclk = clk_get(NULL, "MAIN_CLK"); - - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - - if (!clk_set_rate(mclk, target_freq * 1000)) { - freqs.old = cur; - freqs.new = target_freq; - freqs.cpu = 0; - } - - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - - return 0; -} - -static int __init ucv2_cpu_init(struct cpufreq_policy *policy) -{ - if (policy->cpu != 0) - return -EINVAL; - policy->cur = ucv2_getspeed(0); - policy->min = policy->cpuinfo.min_freq = 250000; - policy->max = policy->cpuinfo.max_freq = 1000000; - policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; - return 0; -} - -static struct cpufreq_driver ucv2_driver = { - .flags = CPUFREQ_STICKY, - .verify = ucv2_verify_speed, - .target = ucv2_target, - .get = ucv2_getspeed, - .init = ucv2_cpu_init, - .name = "UniCore-II", -}; - -static int __init ucv2_cpufreq_init(void) -{ - return cpufreq_register_driver(&ucv2_driver); -} - -arch_initcall(ucv2_cpufreq_init); diff --git a/arch/unicore32/kernel/dma.c b/arch/unicore32/kernel/dma.c index ae441bc3122..ed2d4d78d9c 100644 --- a/arch/unicore32/kernel/dma.c +++ b/arch/unicore32/kernel/dma.c @@ -18,7 +18,6 @@ #include <linux/errno.h> #include <linux/io.h> -#include <asm/system.h> #include <asm/irq.h> #include <mach/hardware.h> #include <mach/dma.h> diff --git a/arch/unicore32/kernel/early_printk.c b/arch/unicore32/kernel/early_printk.c index 3922255f1fa..f2f6323c8d6 100644 --- a/arch/unicore32/kernel/early_printk.c +++ b/arch/unicore32/kernel/early_printk.c @@ -33,23 +33,13 @@ static struct console early_ocd_console = { .index = -1, }; -/* Direct interface for emergencies */ -static struct console *early_console = &early_ocd_console; - -static int __initdata keep_early; - static int __init setup_early_printk(char *buf) { - if (!buf) + if (!buf || early_console) return 0; + early_console = &early_ocd_console; if (strstr(buf, "keep")) - keep_early = 1; - - if (!strncmp(buf, "ocd", 3)) - early_console = &early_ocd_console; - - if (keep_early) early_console->flags &= ~CON_BOOT; else early_console->flags |= CON_BOOT; diff --git a/arch/unicore32/kernel/entry.S b/arch/unicore32/kernel/entry.S index 00a259f9819..bcdedd80890 100644 --- a/arch/unicore32/kernel/entry.S +++ b/arch/unicore32/kernel/entry.S @@ -544,8 +544,6 @@ fast_work_pending: work_pending: cand.a r1, #_TIF_NEED_RESCHED bne work_resched - cand.a r1, #_TIF_SIGPENDING|_TIF_NOTIFY_RESUME - beq no_work_pending mov r0, sp @ 'regs' mov r2, why @ 'syscall' cand.a r1, #_TIF_SIGPENDING @ delivering a signal? @@ -575,17 +573,16 @@ ENDPROC(ret_to_user) */ ENTRY(ret_from_fork) b.l schedule_tail - get_thread_info tsk - ldw r1, [tsk+], #TI_FLAGS @ check for syscall tracing - mov why, #1 - cand.a r1, #_TIF_SYSCALL_TRACE @ are we tracing syscalls? - beq ret_slow_syscall - mov r1, sp - mov r0, #1 @ trace exit [IP = 1] - b.l syscall_trace b ret_slow_syscall ENDPROC(ret_from_fork) +ENTRY(ret_from_kernel_thread) + b.l schedule_tail + mov r0, r5 + adr lr, ret_slow_syscall + mov pc, r4 +ENDPROC(ret_from_kernel_thread) + /*============================================================================= * SWI handler *----------------------------------------------------------------------------- @@ -671,28 +668,12 @@ __cr_alignment: #endif .ltorg -ENTRY(sys_execve) - add r3, sp, #S_OFF - b __sys_execve -ENDPROC(sys_execve) - -ENTRY(sys_clone) - add ip, sp, #S_OFF - stw ip, [sp+], #4 - b __sys_clone -ENDPROC(sys_clone) - ENTRY(sys_rt_sigreturn) add r0, sp, #S_OFF mov why, #0 @ prevent syscall restart handling b __sys_rt_sigreturn ENDPROC(sys_rt_sigreturn) -ENTRY(sys_sigaltstack) - ldw r2, [sp+], #S_OFF + S_SP - b do_sigaltstack -ENDPROC(sys_sigaltstack) - __INIT /* diff --git a/arch/unicore32/kernel/head.S b/arch/unicore32/kernel/head.S index 8caf322e110..e8f0b98c02e 100644 --- a/arch/unicore32/kernel/head.S +++ b/arch/unicore32/kernel/head.S @@ -17,7 +17,7 @@ #include <generated/asm-offsets.h> #include <asm/memory.h> #include <asm/thread_info.h> -#include <asm/system.h> +#include <asm/hwdef-copro.h> #include <asm/pgtable-hwdef.h> #if (PHYS_OFFSET & 0x003fffff) diff --git a/arch/unicore32/kernel/hibernate.c b/arch/unicore32/kernel/hibernate.c index 7d0f0b7983a..d75ef8b6cb5 100644 --- a/arch/unicore32/kernel/hibernate.c +++ b/arch/unicore32/kernel/hibernate.c @@ -15,7 +15,6 @@ #include <linux/suspend.h> #include <linux/bootmem.h> -#include <asm/system.h> #include <asm/page.h> #include <asm/pgtable.h> #include <asm/pgalloc.h> diff --git a/arch/unicore32/kernel/init_task.c b/arch/unicore32/kernel/init_task.c deleted file mode 100644 index a35a1e50e4f..00000000000 --- a/arch/unicore32/kernel/init_task.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * linux/arch/unicore32/kernel/init_task.c - * - * Code specific to PKUnity SoC and UniCore ISA - * - * Copyright (C) 2001-2010 GUAN Xue-tao - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/fs.h> -#include <linux/sched.h> -#include <linux/init.h> -#include <linux/init_task.h> -#include <linux/mqueue.h> -#include <linux/uaccess.h> - -#include <asm/pgtable.h> - -static struct signal_struct init_signals = INIT_SIGNALS(init_signals); -static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); -/* - * Initial thread structure. - * - * We need to make sure that this is 8192-byte aligned due to the - * way process stacks are handled. This is done by making sure - * the linker maps this in the .text segment right after head.S, - * and making head.S ensure the proper alignment. - * - * The things we do for performance.. - */ -union thread_union init_thread_union __init_task_data = { - INIT_THREAD_INFO(init_task) }; - -/* - * Initial task structure. - * - * All other task structs will be allocated on slabs in fork.c - */ -struct task_struct init_task = INIT_TASK(init_task); -EXPORT_SYMBOL(init_task); diff --git a/arch/unicore32/kernel/irq.c b/arch/unicore32/kernel/irq.c index d4efa7d679f..0be5ccd7ccd 100644 --- a/arch/unicore32/kernel/irq.c +++ b/arch/unicore32/kernel/irq.c @@ -26,7 +26,6 @@ #include <linux/syscore_ops.h> #include <linux/gpio.h> -#include <asm/system.h> #include <mach/hardware.h> #include "setup.h" diff --git a/arch/unicore32/kernel/ksyms.c b/arch/unicore32/kernel/ksyms.c index d98bd812cae..0323528a80f 100644 --- a/arch/unicore32/kernel/ksyms.c +++ b/arch/unicore32/kernel/ksyms.c @@ -20,45 +20,18 @@ #include <linux/io.h> #include <asm/checksum.h> -#include <asm/system.h> #include "ksyms.h" +EXPORT_SYMBOL(find_first_bit); +EXPORT_SYMBOL(find_first_zero_bit); EXPORT_SYMBOL(find_next_zero_bit); EXPORT_SYMBOL(find_next_bit); -EXPORT_SYMBOL(__backtrace); - /* platform dependent support */ EXPORT_SYMBOL(__udelay); EXPORT_SYMBOL(__const_udelay); - /* networking */ -EXPORT_SYMBOL(csum_partial); -EXPORT_SYMBOL(csum_partial_copy_from_user); -EXPORT_SYMBOL(csum_partial_copy_nocheck); -EXPORT_SYMBOL(__csum_ipv6_magic); - - /* io */ -#ifndef __raw_readsb -EXPORT_SYMBOL(__raw_readsb); -#endif -#ifndef __raw_readsw -EXPORT_SYMBOL(__raw_readsw); -#endif -#ifndef __raw_readsl -EXPORT_SYMBOL(__raw_readsl); -#endif -#ifndef __raw_writesb -EXPORT_SYMBOL(__raw_writesb); -#endif -#ifndef __raw_writesw -EXPORT_SYMBOL(__raw_writesw); -#endif -#ifndef __raw_writesl -EXPORT_SYMBOL(__raw_writesl); -#endif - /* string / mem functions */ EXPORT_SYMBOL(strchr); EXPORT_SYMBOL(strrchr); @@ -77,23 +50,12 @@ EXPORT_SYMBOL(__copy_from_user); EXPORT_SYMBOL(__copy_to_user); EXPORT_SYMBOL(__clear_user); -EXPORT_SYMBOL(__get_user_1); -EXPORT_SYMBOL(__get_user_2); -EXPORT_SYMBOL(__get_user_4); - -EXPORT_SYMBOL(__put_user_1); -EXPORT_SYMBOL(__put_user_2); -EXPORT_SYMBOL(__put_user_4); -EXPORT_SYMBOL(__put_user_8); - EXPORT_SYMBOL(__ashldi3); EXPORT_SYMBOL(__ashrdi3); EXPORT_SYMBOL(__divsi3); EXPORT_SYMBOL(__lshrdi3); EXPORT_SYMBOL(__modsi3); -EXPORT_SYMBOL(__muldi3); EXPORT_SYMBOL(__ucmpdi2); EXPORT_SYMBOL(__udivsi3); EXPORT_SYMBOL(__umodsi3); -EXPORT_SYMBOL(__bswapsi2); diff --git a/arch/unicore32/kernel/ksyms.h b/arch/unicore32/kernel/ksyms.h index 185cdc712d0..31472ad9467 100644 --- a/arch/unicore32/kernel/ksyms.h +++ b/arch/unicore32/kernel/ksyms.h @@ -8,8 +8,6 @@ extern void __ashrdi3(void); extern void __divsi3(void); extern void __lshrdi3(void); extern void __modsi3(void); -extern void __muldi3(void); extern void __ucmpdi2(void); extern void __udivsi3(void); extern void __umodsi3(void); -extern void __bswapsi2(void); diff --git a/arch/unicore32/kernel/module.c b/arch/unicore32/kernel/module.c index 8fbe8577f5e..dc41f6dfedb 100644 --- a/arch/unicore32/kernel/module.c +++ b/arch/unicore32/kernel/module.c @@ -24,17 +24,9 @@ void *module_alloc(unsigned long size) { - struct vm_struct *area; - - size = PAGE_ALIGN(size); - if (!size) - return NULL; - - area = __get_vm_area(size, VM_ALLOC, MODULES_VADDR, MODULES_END); - if (!area) - return NULL; - - return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC); + return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END, + GFP_KERNEL, PAGE_KERNEL_EXEC, NUMA_NO_NODE, + __builtin_return_address(0)); } int diff --git a/arch/unicore32/kernel/pci.c b/arch/unicore32/kernel/pci.c index a8f07fe10ca..374a055a8e6 100644 --- a/arch/unicore32/kernel/pci.c +++ b/arch/unicore32/kernel/pci.c @@ -21,7 +21,6 @@ #include <linux/io.h> static int debug_pci; -static int use_firmware; #define CONFIG_CMD(bus, devfn, where) \ (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3)) @@ -155,14 +154,6 @@ void __init puv3_pci_adjust_zones(unsigned long *zone_size, zhole_size[0] = 0; } -void __devinit pcibios_update_irq(struct pci_dev *dev, int irq) -{ - if (debug_pci) - printk(KERN_DEBUG "PCI: Assigning IRQ %02d to %s\n", - irq, pci_name(dev)); - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); -} - /* * If the bus contains any of these devices, then we must not turn on * parity checking of any kind. @@ -176,7 +167,7 @@ static inline int pdev_bad_for_parity(struct pci_dev *dev) * pcibios_fixup_bus - Called after each bus is probed, * but before its children are examined. */ -void __devinit pcibios_fixup_bus(struct pci_bus *bus) +void pcibios_fixup_bus(struct pci_bus *bus) { struct pci_dev *dev; u16 features = PCI_COMMAND_SERR @@ -259,9 +250,7 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus) printk(KERN_INFO "PCI: bus%d: Fast back to back transfers %sabled\n", bus->number, (features & PCI_COMMAND_FAST_BACK) ? "en" : "dis"); } -#ifdef CONFIG_HOTPLUG EXPORT_SYMBOL(pcibios_fixup_bus); -#endif static int __init pci_common_init(void) { @@ -276,7 +265,7 @@ static int __init pci_common_init(void) pci_fixup_irqs(pci_common_swizzle, pci_puv3_map_irq); - if (!use_firmware) { + if (!pci_has_flag(PCI_PROBE_ONLY)) { /* * Size the bridge windows. */ @@ -288,22 +277,17 @@ static int __init pci_common_init(void) pci_bus_assign_resources(puv3_bus); } - /* - * Tell drivers about devices found. - */ - pci_bus_add_devices(puv3_bus); - return 0; } subsys_initcall(pci_common_init); -char * __devinit pcibios_setup(char *str) +char * __init pcibios_setup(char *str) { if (!strcmp(str, "debug")) { debug_pci = 1; return NULL; } else if (!strcmp(str, "firmware")) { - use_firmware = 1; + pci_add_flags(PCI_PROBE_ONLY); return NULL; } return str; diff --git a/arch/unicore32/kernel/process.c b/arch/unicore32/kernel/process.c index 52edc2b6287..b008e996146 100644 --- a/arch/unicore32/kernel/process.c +++ b/arch/unicore32/kernel/process.c @@ -34,7 +34,6 @@ #include <asm/cacheflush.h> #include <asm/processor.h> -#include <asm/system.h> #include <asm/stacktrace.h> #include "setup.h" @@ -46,42 +45,12 @@ static const char * const processor_modes[] = { "UK18", "UK19", "UK1A", "EXTN", "UK1C", "UK1D", "UK1E", "SUSR" }; -/* - * The idle thread, has rather strange semantics for calling pm_idle, - * but this is what x86 does and we need to do the same, so that - * things like cpuidle get called in the same way. - */ -void cpu_idle(void) +void arch_cpu_idle(void) { - /* endless idle loop with no priority at all */ - while (1) { - tick_nohz_idle_enter(); - rcu_idle_enter(); - while (!need_resched()) { - local_irq_disable(); - stop_critical_timings(); - cpu_do_idle(); - local_irq_enable(); - start_critical_timings(); - } - rcu_idle_exit(); - tick_nohz_idle_exit(); - preempt_enable_no_resched(); - schedule(); - preempt_disable(); - } + cpu_do_idle(); + local_irq_enable(); } -static char reboot_mode = 'h'; - -int __init reboot_setup(char *str) -{ - reboot_mode = str[0]; - return 1; -} - -__setup("reboot=", reboot_setup); - void machine_halt(void) { gpio_set_value(GPO_SOFT_OFF, 0); @@ -91,6 +60,7 @@ void machine_halt(void) * Function pointers to optional machine specific functions */ void (*pm_power_off)(void) = NULL; +EXPORT_SYMBOL(pm_power_off); void machine_power_off(void) { @@ -109,7 +79,7 @@ void machine_restart(char *cmd) * we may need it to insert some 1:1 mappings so that * soft boot works. */ - setup_mm_for_reboot(reboot_mode); + setup_mm_for_reboot(); /* Clean and invalidate caches */ flush_cache_all(); @@ -123,7 +93,7 @@ void machine_restart(char *cmd) /* * Now handle reboot code. */ - if (reboot_mode == 's') { + if (reboot_mode == REBOOT_SOFT) { /* Jump into ROM at address 0xffff0000 */ cpu_reset(VECTORS_BASE); } else { @@ -165,11 +135,7 @@ void __show_regs(struct pt_regs *regs) unsigned long flags; char buf[64]; - printk(KERN_DEFAULT "CPU: %d %s (%s %.*s)\n", - raw_smp_processor_id(), print_tainted(), - init_utsname()->release, - (int)strcspn(init_utsname()->version, " "), - init_utsname()->version); + show_regs_print_info(KERN_DEFAULT); print_symbol("PC is at %s\n", instruction_pointer(regs)); print_symbol("LR is at %s\n", regs->UCreg_lr); printk(KERN_DEFAULT "pc : [<%08lx>] lr : [<%08lx>] psr: %08lx\n" @@ -259,25 +225,32 @@ void release_thread(struct task_struct *dead_task) } asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); +asmlinkage void ret_from_kernel_thread(void) __asm__("ret_from_kernel_thread"); int copy_thread(unsigned long clone_flags, unsigned long stack_start, - unsigned long stk_sz, struct task_struct *p, struct pt_regs *regs) + unsigned long stk_sz, struct task_struct *p) { struct thread_info *thread = task_thread_info(p); struct pt_regs *childregs = task_pt_regs(p); - *childregs = *regs; - childregs->UCreg_00 = 0; - childregs->UCreg_sp = stack_start; - memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save)); thread->cpu_context.sp = (unsigned long)childregs; - thread->cpu_context.pc = (unsigned long)ret_from_fork; - - if (clone_flags & CLONE_SETTLS) - childregs->UCreg_16 = regs->UCreg_03; - + if (unlikely(p->flags & PF_KTHREAD)) { + thread->cpu_context.pc = (unsigned long)ret_from_kernel_thread; + thread->cpu_context.r4 = stack_start; + thread->cpu_context.r5 = stk_sz; + memset(childregs, 0, sizeof(struct pt_regs)); + } else { + thread->cpu_context.pc = (unsigned long)ret_from_fork; + *childregs = *current_pt_regs(); + childregs->UCreg_00 = 0; + if (stack_start) + childregs->UCreg_sp = stack_start; + + if (clone_flags & CLONE_SETTLS) + childregs->UCreg_16 = childregs->UCreg_03; + } return 0; } @@ -306,42 +279,6 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fp) } EXPORT_SYMBOL(dump_fpu); -/* - * Shuffle the argument into the correct register before calling the - * thread function. r1 is the thread argument, r2 is the pointer to - * the thread function, and r3 points to the exit function. - */ -asm(".pushsection .text\n" -" .align\n" -" .type kernel_thread_helper, #function\n" -"kernel_thread_helper:\n" -" mov.a asr, r7\n" -" mov r0, r4\n" -" mov lr, r6\n" -" mov pc, r5\n" -" .size kernel_thread_helper, . - kernel_thread_helper\n" -" .popsection"); - -/* - * Create a kernel thread. - */ -pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) -{ - struct pt_regs regs; - - memset(®s, 0, sizeof(regs)); - - regs.UCreg_04 = (unsigned long)arg; - regs.UCreg_05 = (unsigned long)fn; - regs.UCreg_06 = (unsigned long)do_exit; - regs.UCreg_07 = PRIV_MODE; - regs.UCreg_pc = (unsigned long)kernel_thread_helper; - regs.UCreg_asr = regs.UCreg_07 | PSR_I_BIT; - - return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); -} -EXPORT_SYMBOL(kernel_thread); - unsigned long get_wchan(struct task_struct *p) { struct stackframe frame; @@ -381,7 +318,7 @@ int vectors_user_mapping(void) return install_special_mapping(mm, 0xffff0000, PAGE_SIZE, VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC | - VM_ALWAYSDUMP | VM_RESERVED, + VM_DONTEXPAND | VM_DONTDUMP, NULL); } diff --git a/arch/unicore32/kernel/puv3-nb0916.c b/arch/unicore32/kernel/puv3-nb0916.c index 181108b8ecc..0c6618e7189 100644 --- a/arch/unicore32/kernel/puv3-nb0916.c +++ b/arch/unicore32/kernel/puv3-nb0916.c @@ -54,6 +54,7 @@ static struct platform_pwm_backlight_data nb0916_backlight_data = { .max_brightness = 100, .dft_brightness = 100, .pwm_period_ns = 70 * 1024, + .enable_gpio = -1, }; static struct gpio_keys_button nb0916_gpio_keys[] = { diff --git a/arch/unicore32/kernel/pwm.c b/arch/unicore32/kernel/pwm.c deleted file mode 100644 index 4615d51e3ba..00000000000 --- a/arch/unicore32/kernel/pwm.c +++ /dev/null @@ -1,263 +0,0 @@ -/* - * linux/arch/unicore32/kernel/pwm.c - * - * Code specific to PKUnity SoC and UniCore ISA - * - * Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn> - * Copyright (C) 2001-2010 Guan Xuetao - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/platform_device.h> -#include <linux/slab.h> -#include <linux/err.h> -#include <linux/clk.h> -#include <linux/io.h> -#include <linux/pwm.h> - -#include <asm/div64.h> -#include <mach/hardware.h> - -struct pwm_device { - struct list_head node; - struct platform_device *pdev; - - const char *label; - struct clk *clk; - int clk_enabled; - - unsigned int use_count; - unsigned int pwm_id; -}; - -/* - * period_ns = 10^9 * (PRESCALE + 1) * (PV + 1) / PWM_CLK_RATE - * duty_ns = 10^9 * (PRESCALE + 1) * DC / PWM_CLK_RATE - */ -int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) -{ - unsigned long long c; - unsigned long period_cycles, prescale, pv, dc; - - if (pwm == NULL || period_ns == 0 || duty_ns > period_ns) - return -EINVAL; - - c = clk_get_rate(pwm->clk); - c = c * period_ns; - do_div(c, 1000000000); - period_cycles = c; - - if (period_cycles < 1) - period_cycles = 1; - prescale = (period_cycles - 1) / 1024; - pv = period_cycles / (prescale + 1) - 1; - - if (prescale > 63) - return -EINVAL; - - if (duty_ns == period_ns) - dc = OST_PWMDCCR_FDCYCLE; - else - dc = (pv + 1) * duty_ns / period_ns; - - /* NOTE: the clock to PWM has to be enabled first - * before writing to the registers - */ - clk_enable(pwm->clk); - OST_PWMPWCR = prescale; - OST_PWMDCCR = pv - dc; - OST_PWMPCR = pv; - clk_disable(pwm->clk); - - return 0; -} -EXPORT_SYMBOL(pwm_config); - -int pwm_enable(struct pwm_device *pwm) -{ - int rc = 0; - - if (!pwm->clk_enabled) { - rc = clk_enable(pwm->clk); - if (!rc) - pwm->clk_enabled = 1; - } - return rc; -} -EXPORT_SYMBOL(pwm_enable); - -void pwm_disable(struct pwm_device *pwm) -{ - if (pwm->clk_enabled) { - clk_disable(pwm->clk); - pwm->clk_enabled = 0; - } -} -EXPORT_SYMBOL(pwm_disable); - -static DEFINE_MUTEX(pwm_lock); -static LIST_HEAD(pwm_list); - -struct pwm_device *pwm_request(int pwm_id, const char *label) -{ - struct pwm_device *pwm; - int found = 0; - - mutex_lock(&pwm_lock); - - list_for_each_entry(pwm, &pwm_list, node) { - if (pwm->pwm_id == pwm_id) { - found = 1; - break; - } - } - - if (found) { - if (pwm->use_count == 0) { - pwm->use_count++; - pwm->label = label; - } else - pwm = ERR_PTR(-EBUSY); - } else - pwm = ERR_PTR(-ENOENT); - - mutex_unlock(&pwm_lock); - return pwm; -} -EXPORT_SYMBOL(pwm_request); - -void pwm_free(struct pwm_device *pwm) -{ - mutex_lock(&pwm_lock); - - if (pwm->use_count) { - pwm->use_count--; - pwm->label = NULL; - } else - pr_warning("PWM device already freed\n"); - - mutex_unlock(&pwm_lock); -} -EXPORT_SYMBOL(pwm_free); - -static inline void __add_pwm(struct pwm_device *pwm) -{ - mutex_lock(&pwm_lock); - list_add_tail(&pwm->node, &pwm_list); - mutex_unlock(&pwm_lock); -} - -static struct pwm_device *pwm_probe(struct platform_device *pdev, - unsigned int pwm_id, struct pwm_device *parent_pwm) -{ - struct pwm_device *pwm; - struct resource *r; - int ret = 0; - - pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL); - if (pwm == NULL) { - dev_err(&pdev->dev, "failed to allocate memory\n"); - return ERR_PTR(-ENOMEM); - } - - pwm->clk = clk_get(NULL, "OST_CLK"); - if (IS_ERR(pwm->clk)) { - ret = PTR_ERR(pwm->clk); - goto err_free; - } - pwm->clk_enabled = 0; - - pwm->use_count = 0; - pwm->pwm_id = pwm_id; - pwm->pdev = pdev; - - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (r == NULL) { - dev_err(&pdev->dev, "no memory resource defined\n"); - ret = -ENODEV; - goto err_free_clk; - } - - r = request_mem_region(r->start, resource_size(r), pdev->name); - if (r == NULL) { - dev_err(&pdev->dev, "failed to request memory resource\n"); - ret = -EBUSY; - goto err_free_clk; - } - - __add_pwm(pwm); - platform_set_drvdata(pdev, pwm); - return pwm; - -err_free_clk: - clk_put(pwm->clk); -err_free: - kfree(pwm); - return ERR_PTR(ret); -} - -static int __devinit puv3_pwm_probe(struct platform_device *pdev) -{ - struct pwm_device *pwm = pwm_probe(pdev, pdev->id, NULL); - - if (IS_ERR(pwm)) - return PTR_ERR(pwm); - - return 0; -} - -static int __devexit pwm_remove(struct platform_device *pdev) -{ - struct pwm_device *pwm; - struct resource *r; - - pwm = platform_get_drvdata(pdev); - if (pwm == NULL) - return -ENODEV; - - mutex_lock(&pwm_lock); - list_del(&pwm->node); - mutex_unlock(&pwm_lock); - - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(r->start, resource_size(r)); - - clk_put(pwm->clk); - kfree(pwm); - return 0; -} - -static struct platform_driver puv3_pwm_driver = { - .driver = { - .name = "PKUnity-v3-PWM", - }, - .probe = puv3_pwm_probe, - .remove = __devexit_p(pwm_remove), -}; - -static int __init pwm_init(void) -{ - int ret = 0; - - ret = platform_driver_register(&puv3_pwm_driver); - if (ret) { - printk(KERN_ERR "failed to register puv3_pwm_driver\n"); - return ret; - } - - return ret; -} -arch_initcall(pwm_init); - -static void __exit pwm_exit(void) -{ - platform_driver_unregister(&puv3_pwm_driver); -} -module_exit(pwm_exit); - -MODULE_LICENSE("GPL v2"); diff --git a/arch/unicore32/kernel/setup.c b/arch/unicore32/kernel/setup.c index 87adbf5ebfe..3fa317f9612 100644 --- a/arch/unicore32/kernel/setup.c +++ b/arch/unicore32/kernel/setup.c @@ -53,6 +53,10 @@ struct stack { static struct stack stacks[NR_CPUS]; +#ifdef CONFIG_VGA_CONSOLE +struct screen_info screen_info; +#endif + char elf_platform[ELF_PLATFORM_SIZE]; EXPORT_SYMBOL(elf_platform); diff --git a/arch/unicore32/kernel/setup.h b/arch/unicore32/kernel/setup.h index dcd1306eb5c..f5c51b85ad2 100644 --- a/arch/unicore32/kernel/setup.h +++ b/arch/unicore32/kernel/setup.h @@ -12,14 +12,17 @@ #ifndef __UNICORE_KERNEL_SETUP_H__ #define __UNICORE_KERNEL_SETUP_H__ +#include <asm/hwdef-copro.h> + extern void paging_init(void); extern void puv3_core_init(void); +extern void cpu_init(void); extern void puv3_ps2_init(void); extern void pci_puv3_preinit(void); extern void __init puv3_init_gpio(void); -extern void setup_mm_for_reboot(char mode); +extern void setup_mm_for_reboot(void); extern char __stubs_start[], __stubs_end[]; extern char __vectors_start[], __vectors_end[]; @@ -27,4 +30,10 @@ extern char __vectors_start[], __vectors_end[]; extern void kernel_thread_helper(void); extern void __init early_signal_init(void); + +extern asmlinkage void __backtrace(void); +extern asmlinkage void c_backtrace(unsigned long fp, int pmode); + +extern void __show_regs(struct pt_regs *); + #endif diff --git a/arch/unicore32/kernel/signal.c b/arch/unicore32/kernel/signal.c index 911b549a6df..6905f0ebdc7 100644 --- a/arch/unicore32/kernel/signal.c +++ b/arch/unicore32/kernel/signal.c @@ -12,7 +12,6 @@ #include <linux/errno.h> #include <linux/signal.h> #include <linux/personality.h> -#include <linux/freezer.h> #include <linux/uaccess.h> #include <linux/tracehook.h> #include <linux/elf.h> @@ -21,8 +20,6 @@ #include <asm/cacheflush.h> #include <asm/ucontext.h> -#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) - /* * For UniCore syscalls, we encode the syscall number into the instruction. */ @@ -61,10 +58,8 @@ static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf) int err; err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set)); - if (err == 0) { - sigdelsetmask(&set, ~_BLOCKABLE); + if (err == 0) set_current_blocked(&set); - } err |= __get_user(regs->UCreg_00, &sf->uc.uc_mcontext.regs.UCreg_00); err |= __get_user(regs->UCreg_01, &sf->uc.uc_mcontext.regs.UCreg_01); @@ -128,8 +123,7 @@ asmlinkage int __sys_rt_sigreturn(struct pt_regs *regs) if (restore_sigframe(regs, &frame->sig)) goto badframe; - if (do_sigaltstack(&frame->sig.uc.uc_stack, NULL, regs->UCreg_sp) - == -EFAULT) + if (restore_altstack(&frame->sig.uc.uc_stack)) goto badframe; return regs->UCreg_00; @@ -270,7 +264,6 @@ static int setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info, { struct rt_sigframe __user *frame = get_sigframe(ka, regs, sizeof(*frame)); - stack_t stack; int err = 0; if (!frame) @@ -280,13 +273,7 @@ static int setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info, err |= __put_user(0, &frame->sig.uc.uc_flags); err |= __put_user(NULL, &frame->sig.uc.uc_link); - - memset(&stack, 0, sizeof(stack)); - stack.ss_sp = (void __user *)current->sas_ss_sp; - stack.ss_flags = sas_ss_flags(regs->UCreg_sp); - stack.ss_size = current->sas_ss_size; - err |= __copy_to_user(&frame->sig.uc.uc_stack, &stack, sizeof(stack)); - + err |= __save_altstack(&frame->sig.uc.uc_stack, regs->UCreg_sp); err |= setup_sigframe(&frame->sig, regs, set); if (err == 0) err |= setup_return(regs, ka, frame->sig.retcode, frame, usig); @@ -312,13 +299,12 @@ static inline void setup_syscall_restart(struct pt_regs *regs) /* * OK, we're invoking a handler */ -static int handle_signal(unsigned long sig, struct k_sigaction *ka, - siginfo_t *info, sigset_t *oldset, - struct pt_regs *regs, int syscall) +static void handle_signal(unsigned long sig, struct k_sigaction *ka, + siginfo_t *info, struct pt_regs *regs, int syscall) { struct thread_info *thread = current_thread_info(); struct task_struct *tsk = current; - sigset_t blocked; + sigset_t *oldset = sigmask_to_save(); int usig = sig; int ret; @@ -364,18 +350,10 @@ static int handle_signal(unsigned long sig, struct k_sigaction *ka, if (ret != 0) { force_sigsegv(sig, tsk); - return ret; + return; } - /* - * Block the signal if we were successful. - */ - sigorsets(&blocked, &tsk->blocked, &ka->sa.sa_mask); - if (!(ka->sa.sa_flags & SA_NODEFER)) - sigaddset(&blocked, sig); - set_current_blocked(&blocked); - - return 0; + signal_delivered(sig, info, ka, regs, 0); } /* @@ -402,32 +380,12 @@ static void do_signal(struct pt_regs *regs, int syscall) if (!user_mode(regs)) return; - if (try_to_freeze()) - goto no_signal; - signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { - sigset_t *oldset; - - if (test_thread_flag(TIF_RESTORE_SIGMASK)) - oldset = ¤t->saved_sigmask; - else - oldset = ¤t->blocked; - if (handle_signal(signr, &ka, &info, oldset, regs, syscall) - == 0) { - /* - * A signal was successfully delivered; the saved - * sigmask will have been stored in the signal frame, - * and will be restored by sigreturn, so we can simply - * clear the TIF_RESTORE_SIGMASK flag. - */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) - clear_thread_flag(TIF_RESTORE_SIGMASK); - } + handle_signal(signr, &ka, &info, regs, syscall); return; } - no_signal: /* * No signal to deliver to the process - restart the syscall. */ @@ -450,15 +408,11 @@ static void do_signal(struct pt_regs *regs, int syscall) regs->UCreg_00 == -ERESTARTNOINTR) { setup_syscall_restart(regs); } - - /* If there's no signal to deliver, we just put the saved - * sigmask back. - */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) { - clear_thread_flag(TIF_RESTORE_SIGMASK); - sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); - } } + /* If there's no signal to deliver, we just put the saved + * sigmask back. + */ + restore_saved_sigmask(); } asmlinkage void do_notify_resume(struct pt_regs *regs, @@ -470,8 +424,6 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, if (thread_flags & _TIF_NOTIFY_RESUME) { clear_thread_flag(TIF_NOTIFY_RESUME); tracehook_notify_resume(regs); - if (current->replacement_session_keyring) - key_replace_session_keyring(); } } diff --git a/arch/unicore32/kernel/sys.c b/arch/unicore32/kernel/sys.c index 3afe60a39ac..f9e86253931 100644 --- a/arch/unicore32/kernel/sys.c +++ b/arch/unicore32/kernel/sys.c @@ -28,97 +28,11 @@ #include <asm/syscalls.h> #include <asm/cacheflush.h> -/* Clone a task - this clones the calling program thread. - * This is called indirectly via a small wrapper - */ -asmlinkage long __sys_clone(unsigned long clone_flags, unsigned long newsp, - void __user *parent_tid, void __user *child_tid, - struct pt_regs *regs) -{ - if (!newsp) - newsp = regs->UCreg_sp; - - return do_fork(clone_flags, newsp, regs, 0, - parent_tid, child_tid); -} - -/* sys_execve() executes a new program. - * This is called indirectly via a small wrapper - */ -asmlinkage long __sys_execve(const char __user *filename, - const char __user *const __user *argv, - const char __user *const __user *envp, - struct pt_regs *regs) -{ - int error; - char *fn; - - fn = getname(filename); - error = PTR_ERR(fn); - if (IS_ERR(fn)) - goto out; - error = do_execve(fn, argv, envp, regs); - putname(fn); -out: - return error; -} - -int kernel_execve(const char *filename, - const char *const argv[], - const char *const envp[]) -{ - struct pt_regs regs; - int ret; - - memset(®s, 0, sizeof(struct pt_regs)); - ret = do_execve(filename, - (const char __user *const __user *)argv, - (const char __user *const __user *)envp, ®s); - if (ret < 0) - goto out; - - /* - * Save argc to the register structure for userspace. - */ - regs.UCreg_00 = ret; - - /* - * We were successful. We won't be returning to our caller, but - * instead to user space by manipulating the kernel stack. - */ - asm("add r0, %0, %1\n\t" - "mov r1, %2\n\t" - "mov r2, %3\n\t" - "mov r22, #0\n\t" /* not a syscall */ - "mov r23, %0\n\t" /* thread structure */ - "b.l memmove\n\t" /* copy regs to top of stack */ - "mov sp, r0\n\t" /* reposition stack pointer */ - "b ret_to_user" - : - : "r" (current_thread_info()), - "Ir" (THREAD_START_SP - sizeof(regs)), - "r" (®s), - "Ir" (sizeof(regs)) - : "r0", "r1", "r2", "r3", "ip", "lr", "memory"); - - out: - return ret; -} -EXPORT_SYMBOL(kernel_execve); - -/* Note: used by the compat code even in 64-bit Linux. */ -SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len, - unsigned long, prot, unsigned long, flags, - unsigned long, fd, unsigned long, off_4k) -{ - return sys_mmap_pgoff(addr, len, prot, flags, fd, - off_4k); -} - /* Provide the actual syscall number to call mapping. */ #undef __SYSCALL #define __SYSCALL(nr, call) [nr] = (call), +#define sys_mmap2 sys_mmap_pgoff /* Note that we don't include <linux/unistd.h> but <asm/unistd.h> */ void *sys_call_table[__NR_syscalls] = { [0 ... __NR_syscalls-1] = sys_ni_syscall, diff --git a/arch/unicore32/kernel/traps.c b/arch/unicore32/kernel/traps.c index b9a26465e72..c54e32410ea 100644 --- a/arch/unicore32/kernel/traps.c +++ b/arch/unicore32/kernel/traps.c @@ -26,7 +26,6 @@ #include <linux/unistd.h> #include <asm/cacheflush.h> -#include <asm/system.h> #include <asm/traps.h> #include "setup.h" @@ -171,12 +170,6 @@ static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) c_backtrace(fp, mode); } -void dump_stack(void) -{ - dump_backtrace(NULL, NULL); -} -EXPORT_SYMBOL(dump_stack); - void show_stack(struct task_struct *tsk, unsigned long *sp) { dump_backtrace(NULL, tsk); @@ -232,7 +225,7 @@ void die(const char *str, struct pt_regs *regs, int err) ret = __die(str, err, thread, regs); bust_spinlocks(0); - add_taint(TAINT_DIE); + add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); spin_unlock_irq(&die_lock); oops_exit(); |
