~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to arch/x86/kernel/process_64.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
#include <linux/tick.h>
36
36
#include <linux/prctl.h>
37
37
#include <linux/uaccess.h>
38
 
#include <linux/idle.h>
39
38
#include <linux/io.h>
40
39
#include <linux/ftrace.h>
41
 
#include <trace/pm.h>
42
40
 
43
41
#include <asm/pgtable.h>
44
42
#include <asm/system.h>
53
51
#include <asm/syscalls.h>
54
52
#include <asm/debugreg.h>
55
53
 
56
 
DEFINE_TRACE(pm_idle_exit);
57
 
DEFINE_TRACE(pm_idle_entry);
58
 
 
59
54
asmlinkage extern void ret_from_fork(void);
60
55
 
61
56
DEFINE_PER_CPU(unsigned long, old_rsp);
62
57
static DEFINE_PER_CPU(unsigned char, is_idle);
63
58
 
 
59
static ATOMIC_NOTIFIER_HEAD(idle_notifier);
 
60
 
 
61
void idle_notifier_register(struct notifier_block *n)
 
62
{
 
63
        atomic_notifier_chain_register(&idle_notifier, n);
 
64
}
 
65
EXPORT_SYMBOL_GPL(idle_notifier_register);
 
66
 
 
67
void idle_notifier_unregister(struct notifier_block *n)
 
68
{
 
69
        atomic_notifier_chain_unregister(&idle_notifier, n);
 
70
}
 
71
EXPORT_SYMBOL_GPL(idle_notifier_unregister);
 
72
 
64
73
void enter_idle(void)
65
74
{
66
75
        percpu_write(is_idle, 1);
67
 
        /*
68
 
         * Trace last event before calling notifiers. Notifiers flush
69
 
         * data from buffers before going to idle.
70
 
         */
71
 
        trace_pm_idle_entry();
72
 
        notify_idle(IDLE_START);
 
76
        atomic_notifier_call_chain(&idle_notifier, IDLE_START, NULL);
73
77
}
74
 
EXPORT_SYMBOL_GPL(enter_idle);
75
78
 
76
 
void __exit_idle(void)
 
79
static void __exit_idle(void)
77
80
{
78
81
        if (x86_test_and_clear_bit_percpu(0, is_idle) == 0)
79
82
                return;
80
 
        notify_idle(IDLE_END);
81
 
        trace_pm_idle_exit();
 
83
        atomic_notifier_call_chain(&idle_notifier, IDLE_END, NULL);
82
84
}
83
 
EXPORT_SYMBOL_GPL(__exit_idle);
84
85
 
85
86
/* Called from interrupts to signify idle end */
86
87
void exit_idle(void)
90
91
                return;
91
92
        __exit_idle();
92
93
}
93
 
EXPORT_SYMBOL_GPL(exit_idle);
94
94
 
95
95
#ifndef CONFIG_SMP
96
96
static inline void play_dead(void)
338
338
        regs->cs                = _cs;
339
339
        regs->ss                = _ss;
340
340
        regs->flags             = X86_EFLAGS_IF;
341
 
        set_fs(USER_DS);
342
341
        /*
343
342
         * Free the old FP and other extended state
344
343
         */
501
500
        /* Make sure to be in 64bit mode */
502
501
        clear_thread_flag(TIF_IA32);
503
502
 
 
503
        /* Ensure the corresponding mm is not marked. */
 
504
        if (current->mm)
 
505
                current->mm->context.ia32_compat = 0;
 
506
 
504
507
        /* TBD: overwrites user setup. Should have two bits.
505
508
           But 64bit processes have always behaved this way,
506
509
           so it's not too bad. The main problem is just that
516
519
        set_thread_flag(TIF_IA32);
517
520
        current->personality |= force_personality32;
518
521
 
 
522
        /* Mark the associated mm as containing 32-bit tasks. */
 
523
        if (current->mm)
 
524
                current->mm->context.ia32_compat = 1;
 
525
 
519
526
        /* Prepare the first "return" to user space */
520
527
        current_thread_info()->status |= TS_COMPAT;
521
528
}