From 6ce60b07e670e800c4c5cfe984ed5188e7a64135 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 30 Jan 2008 13:30:26 +0100 Subject: [PATCH] x86: unify mc146818rtc.h - prepare for sharing rtc code Unify mc146818rtc.h by adding the rtc_cmos_read/write functions to time_64.c. This is a preparatory patch to finaly share the rtc code, which is unsurprisingly similar. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- arch/x86/kernel/time_64.c | 21 +++++++ include/asm-x86/mc146818rtc.h | 98 +++++++++++++++++++++++++++++++- include/asm-x86/mc146818rtc_32.h | 97 ------------------------------- include/asm-x86/mc146818rtc_64.h | 29 ---------- 4 files changed, 116 insertions(+), 129 deletions(-) delete mode 100644 include/asm-x86/mc146818rtc_32.h delete mode 100644 include/asm-x86/mc146818rtc_64.h diff --git a/arch/x86/kernel/time_64.c b/arch/x86/kernel/time_64.c index 368b1942b3..0a01504586 100644 --- a/arch/x86/kernel/time_64.c +++ b/arch/x86/kernel/time_64.c @@ -69,6 +69,27 @@ unsigned long profile_pc(struct pt_regs *regs) } EXPORT_SYMBOL(profile_pc); +/* Routines for accessing the CMOS RAM/RTC. */ +unsigned char rtc_cmos_read(unsigned char addr) +{ + unsigned char val; + lock_cmos_prefix(addr); + outb_p(addr, RTC_PORT(0)); + val = inb_p(RTC_PORT(1)); + lock_cmos_suffix(addr); + return val; +} +EXPORT_SYMBOL(rtc_cmos_read); + +void rtc_cmos_write(unsigned char val, unsigned char addr) +{ + lock_cmos_prefix(addr); + outb_p(addr, RTC_PORT(0)); + outb_p(val, RTC_PORT(1)); + lock_cmos_suffix(addr); +} +EXPORT_SYMBOL(rtc_cmos_write); + /* * In order to set the CMOS clock precisely, set_rtc_mmss has to be called 500 * ms after the second nowtime has started, because when nowtime is written diff --git a/include/asm-x86/mc146818rtc.h b/include/asm-x86/mc146818rtc.h index 5c2bb66caf..9d39436df2 100644 --- a/include/asm-x86/mc146818rtc.h +++ b/include/asm-x86/mc146818rtc.h @@ -1,5 +1,97 @@ -#ifdef CONFIG_X86_32 -# include "mc146818rtc_32.h" +/* + * Machine dependent access functions for RTC registers. + */ +#ifndef _ASM_MC146818RTC_H +#define _ASM_MC146818RTC_H + +#include +#include +#include +#include + +#ifndef RTC_PORT +#define RTC_PORT(x) (0x70 + (x)) +#define RTC_ALWAYS_BCD 1 /* RTC operates in binary mode */ +#endif + +#if defined(CONFIG_X86_32) && defined(__HAVE_ARCH_CMPXCHG) +/* + * This lock provides nmi access to the CMOS/RTC registers. It has some + * special properties. It is owned by a CPU and stores the index register + * currently being accessed (if owned). The idea here is that it works + * like a normal lock (normally). However, in an NMI, the NMI code will + * first check to see if its CPU owns the lock, meaning that the NMI + * interrupted during the read/write of the device. If it does, it goes ahead + * and performs the access and then restores the index register. If it does + * not, it locks normally. + * + * Note that since we are working with NMIs, we need this lock even in + * a non-SMP machine just to mark that the lock is owned. + * + * This only works with compare-and-swap. There is no other way to + * atomically claim the lock and set the owner. + */ +#include +extern volatile unsigned long cmos_lock; + +/* + * All of these below must be called with interrupts off, preempt + * disabled, etc. + */ + +static inline void lock_cmos(unsigned char reg) +{ + unsigned long new; + new = ((smp_processor_id()+1) << 8) | reg; + for (;;) { + if (cmos_lock) { + cpu_relax(); + continue; + } + if (__cmpxchg(&cmos_lock, 0, new, sizeof(cmos_lock)) == 0) + return; + } +} + +static inline void unlock_cmos(void) +{ + cmos_lock = 0; +} +static inline int do_i_have_lock_cmos(void) +{ + return (cmos_lock >> 8) == (smp_processor_id()+1); +} +static inline unsigned char current_lock_cmos_reg(void) +{ + return cmos_lock & 0xff; +} +#define lock_cmos_prefix(reg) \ + do { \ + unsigned long cmos_flags; \ + local_irq_save(cmos_flags); \ + lock_cmos(reg) +#define lock_cmos_suffix(reg) \ + unlock_cmos(); \ + local_irq_restore(cmos_flags); \ + } while (0) #else -# include "mc146818rtc_64.h" +#define lock_cmos_prefix(reg) do {} while (0) +#define lock_cmos_suffix(reg) do {} while (0) +#define lock_cmos(reg) +#define unlock_cmos() +#define do_i_have_lock_cmos() 0 +#define current_lock_cmos_reg() 0 #endif + +/* + * The yet supported machines all access the RTC index register via + * an ISA port access but the way to access the date register differs ... + */ +#define CMOS_READ(addr) rtc_cmos_read(addr) +#define CMOS_WRITE(val, addr) rtc_cmos_write(val, addr) +unsigned char rtc_cmos_read(unsigned char addr); +void rtc_cmos_write(unsigned char val, unsigned char addr); + +#define RTC_IRQ 8 + +#endif /* _ASM_MC146818RTC_H */ diff --git a/include/asm-x86/mc146818rtc_32.h b/include/asm-x86/mc146818rtc_32.h deleted file mode 100644 index 1613b42eaf..0000000000 --- a/include/asm-x86/mc146818rtc_32.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Machine dependent access functions for RTC registers. - */ -#ifndef _ASM_MC146818RTC_H -#define _ASM_MC146818RTC_H - -#include -#include -#include -#include - -#ifndef RTC_PORT -#define RTC_PORT(x) (0x70 + (x)) -#define RTC_ALWAYS_BCD 1 /* RTC operates in binary mode */ -#endif - -#ifdef __HAVE_ARCH_CMPXCHG -/* - * This lock provides nmi access to the CMOS/RTC registers. It has some - * special properties. It is owned by a CPU and stores the index register - * currently being accessed (if owned). The idea here is that it works - * like a normal lock (normally). However, in an NMI, the NMI code will - * first check to see if its CPU owns the lock, meaning that the NMI - * interrupted during the read/write of the device. If it does, it goes ahead - * and performs the access and then restores the index register. If it does - * not, it locks normally. - * - * Note that since we are working with NMIs, we need this lock even in - * a non-SMP machine just to mark that the lock is owned. - * - * This only works with compare-and-swap. There is no other way to - * atomically claim the lock and set the owner. - */ -#include -extern volatile unsigned long cmos_lock; - -/* - * All of these below must be called with interrupts off, preempt - * disabled, etc. - */ - -static inline void lock_cmos(unsigned char reg) -{ - unsigned long new; - new = ((smp_processor_id()+1) << 8) | reg; - for (;;) { - if (cmos_lock) { - cpu_relax(); - continue; - } - if (__cmpxchg(&cmos_lock, 0, new, sizeof(cmos_lock)) == 0) - return; - } -} - -static inline void unlock_cmos(void) -{ - cmos_lock = 0; -} -static inline int do_i_have_lock_cmos(void) -{ - return (cmos_lock >> 8) == (smp_processor_id()+1); -} -static inline unsigned char current_lock_cmos_reg(void) -{ - return cmos_lock & 0xff; -} -#define lock_cmos_prefix(reg) \ - do { \ - unsigned long cmos_flags; \ - local_irq_save(cmos_flags); \ - lock_cmos(reg) -#define lock_cmos_suffix(reg) \ - unlock_cmos(); \ - local_irq_restore(cmos_flags); \ - } while (0) -#else -#define lock_cmos_prefix(reg) do {} while (0) -#define lock_cmos_suffix(reg) do {} while (0) -#define lock_cmos(reg) -#define unlock_cmos() -#define do_i_have_lock_cmos() 0 -#define current_lock_cmos_reg() 0 -#endif - -/* - * The yet supported machines all access the RTC index register via - * an ISA port access but the way to access the date register differs ... - */ -#define CMOS_READ(addr) rtc_cmos_read(addr) -#define CMOS_WRITE(val, addr) rtc_cmos_write(val, addr) -unsigned char rtc_cmos_read(unsigned char addr); -void rtc_cmos_write(unsigned char val, unsigned char addr); - -#define RTC_IRQ 8 - -#endif /* _ASM_MC146818RTC_H */ diff --git a/include/asm-x86/mc146818rtc_64.h b/include/asm-x86/mc146818rtc_64.h deleted file mode 100644 index d6e3009430..0000000000 --- a/include/asm-x86/mc146818rtc_64.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Machine dependent access functions for RTC registers. - */ -#ifndef _ASM_MC146818RTC_H -#define _ASM_MC146818RTC_H - -#include - -#ifndef RTC_PORT -#define RTC_PORT(x) (0x70 + (x)) -#define RTC_ALWAYS_BCD 1 /* RTC operates in binary mode */ -#endif - -/* - * The yet supported machines all access the RTC index register via - * an ISA port access but the way to access the date register differs ... - */ -#define CMOS_READ(addr) ({ \ -outb_p((addr),RTC_PORT(0)); \ -inb_p(RTC_PORT(1)); \ -}) -#define CMOS_WRITE(val, addr) ({ \ -outb_p((addr),RTC_PORT(0)); \ -outb_p((val),RTC_PORT(1)); \ -}) - -#define RTC_IRQ 8 - -#endif /* _ASM_MC146818RTC_H */ -- 2.39.5