diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2013-05-01 08:47:44 -0700 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2013-05-01 08:47:44 -0700 |
commit | bf61c8840efe60fd8f91446860b63338fb424158 (patch) | |
tree | 7a71832407a4f0d6346db773343f4c3ae2257b19 /arch/m32r/kernel/process.c | |
parent | 5846115b30f3a881e542c8bfde59a699c1c13740 (diff) | |
parent | 0c6a61657da78098472fd0eb71cc01f2387fa1bb (diff) |
Merge branch 'next' into for-linus
Prepare first set of updates for 3.10 merge window.
Diffstat (limited to 'arch/m32r/kernel/process.c')
-rw-r--r-- | arch/m32r/kernel/process.c | 177 |
1 files changed, 19 insertions, 158 deletions
diff --git a/arch/m32r/kernel/process.c b/arch/m32r/kernel/process.c index e7366276ef30..bde899e155d3 100644 --- a/arch/m32r/kernel/process.c +++ b/arch/m32r/kernel/process.c @@ -44,36 +44,10 @@ unsigned long thread_saved_pc(struct task_struct *tsk) return tsk->thread.lr; } -/* - * Powermanagement idle function, if any.. - */ -static void (*pm_idle)(void) = NULL; - void (*pm_power_off)(void) = NULL; EXPORT_SYMBOL(pm_power_off); /* - * We use this is we don't have any better - * idle routine.. - */ -static void default_idle(void) -{ - /* M32R_FIXME: Please use "cpu_sleep" mode. */ - cpu_relax(); -} - -/* - * On SMP it's slightly faster (but much more power-consuming!) - * to poll the ->work.need_resched flag instead of waiting for the - * cross-CPU IPI to arrive. Use this option with caution. - */ -static void poll_idle (void) -{ - /* M32R_FIXME */ - cpu_relax(); -} - -/* * The idle thread. There's no useful work to be * done, so just try to conserve power and have a * low exit latency (ie sit in a loop waiting for @@ -84,14 +58,8 @@ void cpu_idle (void) /* endless idle loop with no priority at all */ while (1) { rcu_idle_enter(); - while (!need_resched()) { - void (*idle)(void) = pm_idle; - - if (!idle) - idle = default_idle; - - idle(); - } + while (!need_resched()) + cpu_relax(); rcu_idle_exit(); schedule_preempt_disabled(); } @@ -120,21 +88,6 @@ void machine_power_off(void) /* M32R_FIXME */ } -static int __init idle_setup (char *str) -{ - if (!strncmp(str, "poll", 4)) { - printk("using poll in idle threads.\n"); - pm_idle = poll_idle; - } else if (!strncmp(str, "sleep", 4)) { - printk("using sleep in idle threads.\n"); - pm_idle = default_idle; - } - - return 1; -} - -__setup("idle=", idle_setup); - void show_regs(struct pt_regs * regs) { printk("\n"); @@ -165,41 +118,6 @@ void show_regs(struct pt_regs * regs) } /* - * Create a kernel thread - */ - -/* - * This is the mechanism for creating a new kernel thread. - * - * NOTE! Only a kernel-only process(ie the swapper or direct descendants - * who haven't done an "execve()") should use this: it will work within - * a system call from a "real" process, but the process memory space will - * not be free'd until both the parent and the child have exited. - */ -static void kernel_thread_helper(void *nouse, int (*fn)(void *), void *arg) -{ - fn(arg); - do_exit(-1); -} - -int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) -{ - struct pt_regs regs; - - memset(®s, 0, sizeof (regs)); - regs.r1 = (unsigned long)fn; - regs.r2 = (unsigned long)arg; - - regs.bpc = (unsigned long)kernel_thread_helper; - - regs.psw = M32R_PSW_BIE; - - /* Ok, create the new process. */ - return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, - NULL); -} - -/* * Free current thread data structures etc.. */ void exit_thread(void) @@ -227,88 +145,31 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) } int copy_thread(unsigned long clone_flags, unsigned long spu, - unsigned long unused, struct task_struct *tsk, struct pt_regs *regs) + unsigned long arg, struct task_struct *tsk) { struct pt_regs *childregs = task_pt_regs(tsk); extern void ret_from_fork(void); - - /* Copy registers */ - *childregs = *regs; - - childregs->spu = spu; - childregs->r0 = 0; /* Child gets zero as return value */ - regs->r0 = tsk->pid; + extern void ret_from_kernel_thread(void); + + if (unlikely(tsk->flags & PF_KTHREAD)) { + memset(childregs, 0, sizeof(struct pt_regs)); + childregs->psw = M32R_PSW_BIE; + childregs->r1 = spu; /* fn */ + childregs->r0 = arg; + tsk->thread.lr = (unsigned long)ret_from_kernel_thread; + } else { + /* Copy registers */ + *childregs = *current_pt_regs(); + if (spu) + childregs->spu = spu; + childregs->r0 = 0; /* Child gets zero as return value */ + tsk->thread.lr = (unsigned long)ret_from_fork; + } tsk->thread.sp = (unsigned long)childregs; - tsk->thread.lr = (unsigned long)ret_from_fork; return 0; } -asmlinkage int sys_fork(unsigned long r0, unsigned long r1, unsigned long r2, - unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, - struct pt_regs regs) -{ -#ifdef CONFIG_MMU - return do_fork(SIGCHLD, regs.spu, ®s, 0, NULL, NULL); -#else - return -EINVAL; -#endif /* CONFIG_MMU */ -} - -asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, - unsigned long parent_tidptr, - unsigned long child_tidptr, - unsigned long r4, unsigned long r5, unsigned long r6, - struct pt_regs regs) -{ - if (!newsp) - newsp = regs.spu; - - return do_fork(clone_flags, newsp, ®s, 0, - (int __user *)parent_tidptr, (int __user *)child_tidptr); -} - -/* - * This is trivial, and on the face of it looks like it - * could equally well be done in user mode. - * - * Not so, for quite unobvious reasons - register pressure. - * In user mode vfork() cannot have a stack frame, and if - * done by calling the "clone()" system call directly, you - * do not have enough call-clobbered registers to hold all - * the information you need. - */ -asmlinkage int sys_vfork(unsigned long r0, unsigned long r1, unsigned long r2, - unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, - struct pt_regs regs) -{ - return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.spu, ®s, 0, - NULL, NULL); -} - -/* - * sys_execve() executes a new program. - */ -asmlinkage int sys_execve(const char __user *ufilename, - const char __user *const __user *uargv, - const char __user *const __user *uenvp, - unsigned long r3, unsigned long r4, unsigned long r5, - unsigned long r6, struct pt_regs regs) -{ - int error; - struct filename *filename; - - filename = getname(ufilename); - error = PTR_ERR(filename); - if (IS_ERR(filename)) - goto out; - - error = do_execve(filename->name, uargv, uenvp, ®s); - putname(filename); -out: - return error; -} - /* * These bracket the sleeping functions.. */ |