diff mbox

[RFC,11/14] rtc: switch to get/set rtc time to efi functions if CMOS RTC Not Present git set.

Message ID 1387439515-8926-12-git-send-email-jlee@suse.com (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

Chun-Yi Lee Dec. 19, 2013, 7:51 a.m. UTC
When CMOS RTC Not Present git set in FADT, system should not access CMOS
interface for time. This patch move get/set rtc time function from CMOS
to EFI runtime on x86_64 machine. And, it also set the BUG_ON check in
rtc_cmos_read/write function to avoid access it.

Signed-off-by: Lee, Chun-Yi <jlee@suse.com>
---
 arch/x86/kernel/rtc.c     |    8 ++++++++
 include/asm-generic/rtc.h |   22 ++++++++++++++++++++++
 2 files changed, 30 insertions(+), 0 deletions(-)
diff mbox

Patch

diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c
index 9b6c568..a54cd09 100644
--- a/arch/x86/kernel/rtc.c
+++ b/arch/x86/kernel/rtc.c
@@ -117,6 +117,10 @@  unsigned char rtc_cmos_read(unsigned char addr)
 {
 	unsigned char val;
 
+	BUG_ON(acpi_gbl_FADT.header.revision >= 5 &&
+	       acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_CMOS_RTC &&
+	       addr <= RTC_YEAR);
+
 	lock_cmos_prefix(addr);
 	outb(addr, RTC_PORT(0));
 	val = inb(RTC_PORT(1));
@@ -128,6 +132,10 @@  EXPORT_SYMBOL(rtc_cmos_read);
 
 void rtc_cmos_write(unsigned char val, unsigned char addr)
 {
+	BUG_ON(acpi_gbl_FADT.header.revision >= 5 &&
+	       acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_CMOS_RTC &&
+	       addr <= RTC_YEAR);
+
 	lock_cmos_prefix(addr);
 	outb(addr, RTC_PORT(0));
 	outb(val, RTC_PORT(1));
diff --git a/include/asm-generic/rtc.h b/include/asm-generic/rtc.h
index fa86f24..4ba8aa6 100644
--- a/include/asm-generic/rtc.h
+++ b/include/asm-generic/rtc.h
@@ -16,6 +16,8 @@ 
 #include <linux/rtc.h>
 #include <linux/bcd.h>
 #include <linux/delay.h>
+#include <linux/efi.h>
+#include <linux/acpi.h>
 
 #define RTC_PIE 0x40		/* periodic interrupt enable */
 #define RTC_AIE 0x20		/* alarm interrupt enable */
@@ -51,6 +53,16 @@  static inline unsigned int __get_rtc_time(struct rtc_time *time)
 	unsigned int real_year;
 #endif
 
+	if (acpi_gbl_FADT.header.revision >= 5 &&
+	    acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_CMOS_RTC) {
+#if defined(CONFIG_EFI) && defined(CONFIG_X86_64)
+		printk_once(KERN_INFO "efi: get rtc time by EFI\n");
+		return efi_read_time(time);
+#else
+		BUG();
+#endif
+	}
+
 	/*
 	 * read RTC once any update in progress is done. The update
 	 * can take just over 2ms. We wait 20ms. There is no need to
@@ -123,6 +135,16 @@  static inline int __set_rtc_time(struct rtc_time *time)
 	unsigned int real_yrs, leap_yr;
 #endif
 
+	if (acpi_gbl_FADT.header.revision >= 5 &&
+	    acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_CMOS_RTC) {
+#if defined(CONFIG_EFI) && defined(CONFIG_X86_64)
+		printk_once(KERN_INFO "efi: set rtc time by EFI\n");
+		return efi_set_time(time);
+#else
+		BUG();
+#endif
+	}
+
 	yrs = time->tm_year;
 	mon = time->tm_mon + 1;   /* tm_mon starts at zero */
 	day = time->tm_mday;