summaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/time_64.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2007-10-12 23:04:07 +0200
committerThomas Gleixner <tglx@inhelltoy.tec.linutronix.de>2007-10-12 23:04:07 +0200
commitb8ce33590687888ebb900d09557b8807c4539022 (patch)
tree0e51543c7d4febff8ff6ad7660268bea2035f9ce /arch/x86/kernel/time_64.c
parentba7eda4c60e1d070b2f6586d42719ec1d5302d3b (diff)
x86_64: convert to clock events
Finally switch to the clockevents code. Share code with i386 for hpet and PIT. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Chris Wright <chrisw@sous-sol.org> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
Diffstat (limited to 'arch/x86/kernel/time_64.c')
-rw-r--r--arch/x86/kernel/time_64.c107
1 files changed, 13 insertions, 94 deletions
diff --git a/arch/x86/kernel/time_64.c b/arch/x86/kernel/time_64.c
index d899216e01c..7781df1d50e 100644
--- a/arch/x86/kernel/time_64.c
+++ b/arch/x86/kernel/time_64.c
@@ -28,6 +28,8 @@
#include <linux/cpu.h>
#include <linux/kallsyms.h>
#include <linux/acpi.h>
+#include <linux/clockchips.h>
+
#ifdef CONFIG_ACPI
#include <acpi/achware.h> /* for PM timer frequency */
#include <acpi/acpi_bus.h>
@@ -46,12 +48,8 @@
#include <asm/nmi.h>
#include <asm/vgtod.h>
-static char *timename = NULL;
-
DEFINE_SPINLOCK(rtc_lock);
EXPORT_SYMBOL(rtc_lock);
-DEFINE_SPINLOCK(i8253_lock);
-EXPORT_SYMBOL(i8253_lock);
volatile unsigned long __jiffies __section_jiffies = INITIAL_JIFFIES;
@@ -194,6 +192,13 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
+static irqreturn_t timer_event_interrupt(int irq, void *dev_id)
+{
+ global_clock_event->event_handler(global_clock_event);
+
+ return IRQ_HANDLED;
+}
+
unsigned long read_persistent_clock(void)
{
unsigned int year, mon, day, hour, min, sec;
@@ -291,42 +296,8 @@ static unsigned int __init tsc_calibrate_cpu_khz(void)
return pmc_now * tsc_khz / (tsc_now - tsc_start);
}
-static void __pit_init(int val, u8 mode)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&i8253_lock, flags);
- outb_p(mode, PIT_MODE);
- outb_p(val & 0xff, PIT_CH0); /* LSB */
- outb_p(val >> 8, PIT_CH0); /* MSB */
- spin_unlock_irqrestore(&i8253_lock, flags);
-}
-
-void __init pit_init(void)
-{
- __pit_init(LATCH, 0x34); /* binary, mode 2, LSB/MSB, ch 0 */
-}
-
-void pit_stop_interrupt(void)
-{
- __pit_init(0, 0x30); /* mode 0 */
-}
-
-void stop_timer_interrupt(void)
-{
- char *name;
- if (hpet_address) {
- name = "HPET";
- hpet_timer_stop_set_go(0);
- } else {
- name = "PIT";
- pit_stop_interrupt();
- }
- printk(KERN_INFO "timer: %s interrupt stopped.\n", name);
-}
-
static struct irqaction irq0 = {
- .handler = timer_interrupt,
+ .handler = timer_event_interrupt,
.flags = IRQF_DISABLED | IRQF_IRQPOLL | IRQF_NOBALANCING,
.mask = CPU_MASK_NONE,
.name = "timer"
@@ -334,20 +305,10 @@ static struct irqaction irq0 = {
void __init time_init(void)
{
- if (nohpet)
- hpet_address = 0;
-
- if (hpet_arch_init())
- hpet_address = 0;
+ if (!hpet_enable())
+ setup_pit_timer();
- if (hpet_use_timer) {
- /* set tick_nsec to use the proper rate for HPET */
- tick_nsec = TICK_NSEC_HPET;
- timename = "HPET";
- } else {
- pit_init();
- timename = "PIT";
- }
+ setup_irq(0, &irq0);
tsc_calibrate();
@@ -369,46 +330,4 @@ void __init time_init(void)
printk(KERN_INFO "time.c: Detected %d.%03d MHz processor.\n",
cpu_khz / 1000, cpu_khz % 1000);
init_tsc_clocksource();
-
- setup_irq(0, &irq0);
-}
-
-/*
- * sysfs support for the timer.
- */
-
-static int timer_suspend(struct sys_device *dev, pm_message_t state)
-{
- return 0;
}
-
-static int timer_resume(struct sys_device *dev)
-{
- if (hpet_address)
- hpet_reenable();
- else
- i8254_timer_resume();
- return 0;
-}
-
-static struct sysdev_class timer_sysclass = {
- .resume = timer_resume,
- .suspend = timer_suspend,
- set_kset_name("timer"),
-};
-
-/* XXX this sysfs stuff should probably go elsewhere later -john */
-static struct sys_device device_timer = {
- .id = 0,
- .cls = &timer_sysclass,
-};
-
-static int time_init_device(void)
-{
- int error = sysdev_class_register(&timer_sysclass);
- if (!error)
- error = sysdev_register(&device_timer);
- return error;
-}
-
-device_initcall(time_init_device);