]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/sh/kernel/process.c
Merge branch 'ucc_geth' of master.kernel.org:/pub/scm/linux/kernel/git/leo/fsl-soc...
[linux-2.6-omap-h63xx.git] / arch / sh / kernel / process.c
index 6b4f5748d0be682a2b6334ca7d6f5ccc406be271..15ae322dbd741a594529835c2c543987125d37f9 100644 (file)
@@ -17,6 +17,8 @@
 #include <linux/kexec.h>
 #include <linux/kdebug.h>
 #include <linux/tick.h>
+#include <linux/reboot.h>
+#include <linux/fs.h>
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
 #include <asm/pgalloc.h>
@@ -26,8 +28,6 @@
 static int hlt_counter;
 int ubc_usercnt = 0;
 
-#define HARD_IDLE_TIMEOUT (HZ / 3)
-
 void (*pm_idle)(void);
 void (*pm_power_off)(void);
 EXPORT_SYMBOL(pm_power_off);
@@ -44,16 +44,39 @@ void enable_hlt(void)
 }
 EXPORT_SYMBOL(enable_hlt);
 
+static int __init nohlt_setup(char *__unused)
+{
+       hlt_counter = 1;
+       return 1;
+}
+__setup("nohlt", nohlt_setup);
+
+static int __init hlt_setup(char *__unused)
+{
+       hlt_counter = 0;
+       return 1;
+}
+__setup("hlt", hlt_setup);
+
 void default_idle(void)
 {
-       if (!hlt_counter)
-               cpu_sleep();
-       else
-               cpu_relax();
+       if (!hlt_counter) {
+               clear_thread_flag(TIF_POLLING_NRFLAG);
+               smp_mb__after_clear_bit();
+               set_bl_bit();
+               while (!need_resched())
+                       cpu_sleep();
+               clear_bl_bit();
+               set_thread_flag(TIF_POLLING_NRFLAG);
+       } else
+               while (!need_resched())
+                       cpu_relax();
 }
 
 void cpu_idle(void)
 {
+       set_thread_flag(TIF_POLLING_NRFLAG);
+
        /* endless idle loop with no priority at all */
        while (1) {
                void (*idle)(void) = pm_idle;
@@ -298,9 +321,7 @@ static void ubc_set_tracing(int asid, unsigned long pc)
        ctrl_outl(pc, UBC_BARA);
 
 #ifdef CONFIG_MMU
-       /* We don't have any ASID settings for the SH-2! */
-       if (current_cpu_data.type != CPU_SH7604)
-               ctrl_outb(asid, UBC_BASRA);
+       ctrl_outb(asid, UBC_BASRA);
 #endif
 
        ctrl_outl(0, UBC_BAMRA);
@@ -384,8 +405,8 @@ asmlinkage int sys_fork(unsigned long r4, unsigned long r5,
                        unsigned long r6, unsigned long r7,
                        struct pt_regs __regs)
 {
-       struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
 #ifdef CONFIG_MMU
+       struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
        return do_fork(SIGCHLD, regs->regs[15], regs, 0, NULL, NULL);
 #else
        /* fork almost works, enough to trick you into looking elsewhere :-( */
@@ -428,23 +449,20 @@ asmlinkage int sys_vfork(unsigned long r4, unsigned long r5,
 /*
  * sys_execve() executes a new program.
  */
-asmlinkage int sys_execve(char *ufilename, char **uargv,
-                         char **uenvp, unsigned long r7,
+asmlinkage int sys_execve(char __user *ufilename, char __user * __user *uargv,
+                         char __user * __user *uenvp, unsigned long r7,
                          struct pt_regs __regs)
 {
        struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
        int error;
        char *filename;
 
-       filename = getname((char __user *)ufilename);
+       filename = getname(ufilename);
        error = PTR_ERR(filename);
        if (IS_ERR(filename))
                goto out;
 
-       error = do_execve(filename,
-                         (char __user * __user *)uargv,
-                         (char __user * __user *)uenvp,
-                         regs);
+       error = do_execve(filename, uargv, uenvp, regs);
        if (error == 0) {
                task_lock(current);
                current->ptrace &= ~PT_DTRACE;
@@ -457,7 +475,6 @@ out:
 
 unsigned long get_wchan(struct task_struct *p)
 {
-       unsigned long schedule_frame;
        unsigned long pc;
 
        if (!p || p == current || p->state == TASK_RUNNING)
@@ -467,10 +484,13 @@ unsigned long get_wchan(struct task_struct *p)
         * The same comment as on the Alpha applies here, too ...
         */
        pc = thread_saved_pc(p);
+
+#ifdef CONFIG_FRAME_POINTER
        if (in_sched_functions(pc)) {
-               schedule_frame = (unsigned long)p->thread.sp;
+               unsigned long schedule_frame = (unsigned long)p->thread.sp;
                return ((unsigned long *)schedule_frame)[21];
        }
+#endif
 
        return pc;
 }