From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1764513AbXGOQL5 (ORCPT ); Sun, 15 Jul 2007 12:11:57 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1762277AbXGOQFR (ORCPT ); Sun, 15 Jul 2007 12:05:17 -0400 Received: from www.osadl.org ([213.239.205.134]:42532 "EHLO mail.tglx.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1762284AbXGOQFF (ORCPT ); Sun, 15 Jul 2007 12:05:05 -0400 Message-Id: <20070715155541.378002848@inhelltoy.tec.linutronix.de> References: <20070715155510.341941668@inhelltoy.tec.linutronix.de> User-Agent: quilt/0.46-1 Date: Sun, 15 Jul 2007 16:10:57 -0000 From: Thomas Gleixner To: LKML Cc: Ingo Molnar , Andrew Morton , Andi Kleen Subject: [patch-mm 16/33] i386: hpet add x8664 bits Content-Disposition: inline; filename=i386-hpet-add-x8664-hpet-bits.patch Sender: linux-kernel-owner@vger.kernel.org X-Mailing-List: linux-kernel@vger.kernel.org Add the x8664 specific bits (mapping) to share the hpet code later. Move the reserve_platform_timer call to late init. This is necessary for x86_64, as hpet enable() is called before memory is setup. i386 calls it in late_time_init, but it does not hurt to do it later for both. Pull in the x8664 hpet disable command line option as well. Signed-off-by: Thomas Gleixner --- arch/i386/kernel/hpet.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) Index: linux-2.6.22-rc6-mm/arch/i386/kernel/hpet.c =================================================================== --- linux-2.6.22-rc6-mm.orig/arch/i386/kernel/hpet.c 2007-07-15 17:39:01.000000000 +0200 +++ linux-2.6.22-rc6-mm/arch/i386/kernel/hpet.c 2007-07-15 17:48:49.000000000 +0200 @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -23,6 +24,10 @@ unsigned long hpet_address; static void __iomem *hpet_virt_address; +/* Temporary hack. Cleanup after x86_64 clock events conversion */ +#undef hpet_readl +#undef hpet_writel + static inline unsigned long hpet_readl(unsigned long a) { return readl(hpet_virt_address + a); @@ -33,6 +38,24 @@ static inline void hpet_writel(unsigned writel(d, hpet_virt_address + a); } +#ifdef CONFIG_X86_64 + +#include + +static inline void hpet_set_mapping(void) +{ + set_fixmap_nocache(FIX_HPET_BASE, hpet_address); + __set_fixmap(VSYSCALL_HPET, hpet_address, PAGE_KERNEL_VSYSCALL_NOCACHE); + hpet_virt_address = (void __iomem *)fix_to_virt(FIX_HPET_BASE); +} + +static inline void hpet_clear_mapping(void) +{ + hpet_virt_address = NULL; +} + +#else + static inline void hpet_set_mapping(void) { hpet_virt_address = ioremap_nocache(hpet_address, HPET_MMAP_SIZE); @@ -43,6 +66,7 @@ static inline void hpet_clear_mapping(vo iounmap(hpet_virt_address); hpet_virt_address = NULL; } +#endif /* * HPET command line enable / disable @@ -59,6 +83,13 @@ static int __init hpet_setup(char* str) } __setup("hpet=", hpet_setup); +static int __init disable_hpet(char *str) +{ + boot_hpet_disable = 1; + return 1; +} +__setup("nohpet", disable_hpet); + static inline int is_hpet_capable(void) { return (!boot_hpet_disable && hpet_address); @@ -225,6 +256,13 @@ static cycle_t read_hpet(void) return (cycle_t)hpet_readl(HPET_COUNTER); } +#ifdef CONFIG_X86_64 +static cycle_t __vsyscall_fn vread_hpet(void) +{ + return readl((const void __iomem *)fix_to_virt(VSYSCALL_HPET) + 0xf0); +} +#endif + static struct clocksource clocksource_hpet = { .name = "hpet", .rating = 250, @@ -233,6 +271,9 @@ static struct clocksource clocksource_hp .shift = HPET_SHIFT, .flags = CLOCK_SOURCE_IS_CONTINUOUS, .resume = hpet_start_counter, +#ifdef CONFIG_X86_64 + .vread = vread_hpet, +#endif }; /* @@ -331,7 +372,6 @@ int __init hpet_enable(void) if (id & HPET_ID_LEGSUP) { hpet_enable_int(); - hpet_reserve_platform_timers(id); /* * Start hpet with the boot cpu mask and make it * global after the IO_APIC has been initialized. @@ -349,6 +389,22 @@ out_nohpet: return 0; } +/* + * Needs to be late, as the reserve_timer code calls kalloc ! + * + * Not a problem on i386 as hpet_enable is called from late_time_init, + * but on x86_64 it is necessary ! + */ +static __init int hpet_late_init(void) +{ + if (!is_hpet_capable()) + return -ENODEV; + + hpet_reserve_platform_timers(hpet_readl(HPET_ID)); + return 0; +} +fs_initcall(hpet_late_init); + #ifdef CONFIG_HPET_EMULATE_RTC /* HPET in LegacyReplacement Mode eats up RTC interrupt line. When, HPET --