diff options
author | Vitja Makarov <vitja.makarov@gmail.com> | 2008-02-29 12:24:23 +0800 |
---|---|---|
committer | Bryan Wu <cooloney@kernel.org> | 2008-02-29 12:24:23 +0800 |
commit | 8b5f79f9d7ee4f4edb0212886771c977476eb811 (patch) | |
tree | 5c9928710ad8c2556b64cee56fea768ce5ac4ba7 /arch/blackfin/kernel/process.c | |
parent | 3dc5063786b273f1aee545844f6bd4e9651ebffe (diff) |
[Blackfin] arch: initial generic time and clock sources
This patch enables Hight-Res Timers and tickless kernel
Signed-off-by: Vitja Makarov <vitja.makarov@gmail.com>
Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Bryan Wu <cooloney@kernel.org>
Diffstat (limited to 'arch/blackfin/kernel/process.c')
-rw-r--r-- | arch/blackfin/kernel/process.c | 43 |
1 files changed, 28 insertions, 15 deletions
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c index 6b8459c6616..6dedb2da8b6 100644 --- a/arch/blackfin/kernel/process.c +++ b/arch/blackfin/kernel/process.c @@ -32,6 +32,8 @@ #include <linux/unistd.h> #include <linux/user.h> #include <linux/uaccess.h> +#include <linux/sched.h> +#include <linux/tick.h> #include <linux/fs.h> #include <linux/err.h> @@ -69,33 +71,44 @@ EXPORT_SYMBOL(pm_power_off); * The idle loop on BFIN */ #ifdef CONFIG_IDLE_L1 -void default_idle(void)__attribute__((l1_text)); +static void default_idle(void)__attribute__((l1_text)); void cpu_idle(void)__attribute__((l1_text)); #endif -void default_idle(void) +/* + * This is our default idle handler. We need to disable + * interrupts here to ensure we don't miss a wakeup call. + */ +static void default_idle(void) { - while (!need_resched()) { - local_irq_disable(); - if (likely(!need_resched())) - idle_with_irq_disabled(); - local_irq_enable(); - } -} + local_irq_disable(); + if (!need_resched()) + idle_with_irq_disabled(); -void (*idle)(void) = default_idle; + local_irq_enable(); +} /* - * 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 - * somebody to say that they'd like to reschedule) + * The idle thread. We try to conserve power, while trying to keep + * overall latency low. The architecture specific idle is passed + * a value to indicate the level of "idleness" of the system. */ void cpu_idle(void) { /* endless idle loop with no priority at all */ while (1) { - idle(); + void (*idle)(void) = pm_idle; + +#ifdef CONFIG_HOTPLUG_CPU + if (cpu_is_offline(smp_processor_id())) + cpu_die(); +#endif + if (!idle) + idle = default_idle; + tick_nohz_stop_sched_tick(); + while (!need_resched()) + idle(); + tick_nohz_restart_sched_tick(); preempt_enable_no_resched(); schedule(); preempt_disable(); |