mrst/vrtc: Avoid using cmos rtc ops
authorFeng Tang <feng.tang@intel.com>
Mon, 14 Feb 2011 16:13:32 +0000 (00:13 +0800)
committerThomas Gleixner <tglx@linutronix.de>
Mon, 14 Feb 2011 17:20:43 +0000 (18:20 +0100)
If we don't assign Moorestown specific wallclock init and ops function
the rtc/persisent clock code will use cmos rtc for access, this will
crash Moorestown in that the ioports are not present.

Also in vrtc driver, should avoid using cmos access to check UIP status.

[feng.tang@intel.com: use set_fixmap_offset_nocache() to simplify code]
Signed-off-by: Jacob Pan <jacob.jun.pan@linux.intel.com>
Signed-off-by: Feng Tang <feng.tang@intel.com>
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
arch/x86/platform/mrst/mrst.c
arch/x86/platform/mrst/vrtc.c
drivers/rtc/rtc-mrst.c

index fee0b4914e07ad494f82629ccc10dc0a1980879c..4c542c757cb4b5a48b11f80f3c3e64dbebc58a8a 100644 (file)
@@ -31,6 +31,7 @@
 #include <asm/apic.h>
 #include <asm/io_apic.h>
 #include <asm/mrst.h>
+#include <asm/mrst-vrtc.h>
 #include <asm/io.h>
 #include <asm/i8259.h>
 #include <asm/intel_scu_ipc.h>
@@ -294,6 +295,7 @@ void __init x86_mrst_early_setup(void)
 
        x86_platform.calibrate_tsc = mrst_calibrate_tsc;
        x86_platform.i8042_detect = mrst_i8042_detect;
+       x86_init.timers.wallclock_init = mrst_rtc_init;
        x86_init.pci.init = pci_mrst_init;
        x86_init.pci.fixup_irqs = x86_init_noop;
 
index 32cd7edd71a0fab9ce4a2ac0f43875855406beb5..04cf645feb92018edf96bf32779ea4dde274782f 100644 (file)
@@ -100,22 +100,14 @@ int vrtc_set_mmss(unsigned long nowtime)
 
 void __init mrst_rtc_init(void)
 {
-       unsigned long rtc_paddr;
-       void __iomem *virt_base;
+       unsigned long vrtc_paddr = sfi_mrtc_array[0].phys_addr;
 
        sfi_table_parse(SFI_SIG_MRTC, NULL, NULL, sfi_parse_mrtc);
-       if (!sfi_mrtc_num)
+       if (!sfi_mrtc_num || !vrtc_paddr)
                return;
 
-       rtc_paddr = sfi_mrtc_array[0].phys_addr;
-
-       /* vRTC's register address may not be page aligned */
-       set_fixmap_nocache(FIX_LNW_VRTC, rtc_paddr);
-
-       virt_base = (void __iomem *)__fix_to_virt(FIX_LNW_VRTC);
-       virt_base += rtc_paddr & ~PAGE_MASK;
-       vrtc_virt_base = virt_base;
-
+       vrtc_virt_base = (void __iomem *)set_fixmap_offset_nocache(FIX_LNW_VRTC,
+                                                               vrtc_paddr);
        x86_platform.get_wallclock = vrtc_get_time;
        x86_platform.set_wallclock = vrtc_set_mmss;
 }
index bcd0cf63eb166df6520e5e0c5beef3b6abaac75b..28e02e7580f4e213459d6f246bc292ed9b38e517 100644 (file)
@@ -62,6 +62,17 @@ static inline int is_intr(u8 rtc_intr)
        return rtc_intr & RTC_IRQMASK;
 }
 
+static inline unsigned char vrtc_is_updating(void)
+{
+       unsigned char uip;
+       unsigned long flags;
+
+       spin_lock_irqsave(&rtc_lock, flags);
+       uip = (vrtc_cmos_read(RTC_FREQ_SELECT) & RTC_UIP);
+       spin_unlock_irqrestore(&rtc_lock, flags);
+       return uip;
+}
+
 /*
  * rtc_time's year contains the increment over 1900, but vRTC's YEAR
  * register can't be programmed to value larger than 0x64, so vRTC
@@ -76,7 +87,7 @@ static int mrst_read_time(struct device *dev, struct rtc_time *time)
 {
        unsigned long flags;
 
-       if (rtc_is_updating())
+       if (vrtc_is_updating())
                mdelay(20);
 
        spin_lock_irqsave(&rtc_lock, flags);