From ca71c0031b8c26fa202d4fb18811112d3f86794e Mon Sep 17 00:00:00 2001 From: Andi Kleen <ak@muc.de> Date: Tue, 19 Oct 2004 18:11:14 -0700 Subject: [PATCH] [PATCH] x86_64: intialize hpet char driver Initialize HPET char driver Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org> --- arch/x86_64/Kconfig | 3 ++- arch/x86_64/kernel/time.c | 50 +++++++++++++++++++++++++++++++++++++++ include/asm-x86_64/hpet.h | 3 +++ 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index cb3fc95258e4..d660dcfe31e5 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig @@ -72,7 +72,8 @@ config HPET_TIMER If unsure, say Y. config HPET_EMULATE_RTC - def_bool HPET_TIMER && RTC=y + bool "Provide RTC interrupt" + depends on HPET_TIMER && RTC=y config GENERIC_ISA_DMA bool diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c index 289b81dae486..d7b6d48cfb78 100644 --- a/arch/x86_64/kernel/time.c +++ b/arch/x86_64/kernel/time.c @@ -34,6 +34,7 @@ #include <asm/hpet.h> #include <asm/sections.h> #include <linux/cpufreq.h> +#include <linux/hpet.h> #ifdef CONFIG_X86_LOCAL_APIC #include <asm/apic.h> #endif @@ -726,6 +727,55 @@ static unsigned int __init pit_calibrate_tsc(void) return (end - start) / 50; } +#ifdef CONFIG_HPET +static __init int late_hpet_init(void) +{ + struct hpet_data hd; + unsigned int ntimer; + + if (!vxtime.hpet_address) + return -1; + + memset(&hd, 0, sizeof (hd)); + + ntimer = hpet_readl(HPET_ID); + ntimer = (ntimer & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT; + ntimer++; + + /* + * Register with driver. + * Timer0 and Timer1 is used by platform. + */ + hd.hd_address = (void *)fix_to_virt(FIX_HPET_BASE); + hd.hd_nirqs = ntimer; + hd.hd_flags = HPET_DATA_PLATFORM; + hpet_reserve_timer(&hd, 0); +#ifdef CONFIG_HPET_EMULATE_RTC + hpet_reserve_timer(&hd, 1); +#endif + hd.hd_irq[0] = HPET_LEGACY_8254; + hd.hd_irq[1] = HPET_LEGACY_RTC; + if (ntimer > 2) { + struct hpet *hpet; + struct hpet_timer *timer; + int i; + + hpet = (struct hpet *) fix_to_virt(FIX_HPET_BASE); + + for (i = 2, timer = &hpet->hpet_timers[2]; i < ntimer; + timer++, i++) + hd.hd_irq[i] = (timer->hpet_config & + Tn_INT_ROUTE_CNF_MASK) >> + Tn_INT_ROUTE_CNF_SHIFT; + + } + + hpet_alloc(&hd); + return 0; +} +fs_initcall(late_hpet_init); +#endif + static int hpet_init(void) { unsigned int cfg, id; diff --git a/include/asm-x86_64/hpet.h b/include/asm-x86_64/hpet.h index 08ee1e7ce3a4..1facdec69cfb 100644 --- a/include/asm-x86_64/hpet.h +++ b/include/asm-x86_64/hpet.h @@ -28,12 +28,15 @@ #define HPET_ID_LEGSUP 0x00008000 #define HPET_ID_NUMBER 0x00001f00 #define HPET_ID_REV 0x000000ff +#define HPET_ID_NUMBER_SHIFT 8 #define HPET_ID_VENDOR_SHIFT 16 #define HPET_ID_VENDOR_8086 0x8086 #define HPET_CFG_ENABLE 0x001 #define HPET_CFG_LEGACY 0x002 +#define HPET_LEGACY_8254 2 +#define HPET_LEGACY_RTC 8 #define HPET_TN_ENABLE 0x004 #define HPET_TN_PERIODIC 0x008 -- 2.30.9