Merge branch 'devicetree/for-x86' of git://git.secretlab.ca/git/linux-2.6 into x86...
authorThomas Gleixner <tglx@linutronix.de>
Tue, 22 Feb 2011 17:24:26 +0000 (18:24 +0100)
committerThomas Gleixner <tglx@linutronix.de>
Tue, 22 Feb 2011 17:41:48 +0000 (18:41 +0100)
Reason: x86 devicetree support for ce4100 depends on those device tree
changes scheduled for .39.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
arch/x86/include/asm/x86_init.h
arch/x86/kernel/apb_timer.c
arch/x86/kernel/setup.c
arch/x86/kernel/x86_init.c
arch/x86/pci/ce4100.c
arch/x86/platform/mrst/mrst.c
arch/x86/platform/mrst/vrtc.c
drivers/rtc/rtc-mrst.c

index 64642ad019fb78e14ce26416db13c3d340d6507c..643ebf2e2ad8733ddbec5ca884ee21bf405c0226 100644 (file)
@@ -83,11 +83,13 @@ struct x86_init_paging {
  *                             boot cpu
  * @tsc_pre_init:              platform function called before TSC init
  * @timer_init:                        initialize the platform timer (default PIT/HPET)
+ * @wallclock_init:            init the wallclock device
  */
 struct x86_init_timers {
        void (*setup_percpu_clockev)(void);
        void (*tsc_pre_init)(void);
        void (*timer_init)(void);
+       void (*wallclock_init)(void);
 };
 
 /**
index 51ef31a89be92848ab65e7b148e6c6bdb0f192ea..671d5aad7a0c9999f662d7c404e55b1aac99d017 100644 (file)
@@ -508,64 +508,12 @@ static int apbt_next_event(unsigned long delta,
        return 0;
 }
 
-/*
- * APB timer clock is not in sync with pclk on Langwell, which translates to
- * unreliable read value caused by sampling error. the error does not add up
- * overtime and only happens when sampling a 0 as a 1 by mistake. so the time
- * would go backwards. the following code is trying to prevent time traveling
- * backwards. little bit paranoid.
- */
 static cycle_t apbt_read_clocksource(struct clocksource *cs)
 {
-       unsigned long t0, t1, t2;
-       static unsigned long last_read;
-
-bad_count:
-       t1 = apbt_readl(phy_cs_timer_id,
-                       APBTMR_N_CURRENT_VALUE);
-       t2 = apbt_readl(phy_cs_timer_id,
-                       APBTMR_N_CURRENT_VALUE);
-       if (unlikely(t1 < t2)) {
-               pr_debug("APBT: read current count error %lx:%lx:%lx\n",
-                        t1, t2, t2 - t1);
-               goto bad_count;
-       }
-       /*
-        * check against cached last read, makes sure time does not go back.
-        * it could be a normal rollover but we will do tripple check anyway
-        */
-       if (unlikely(t2 > last_read)) {
-               /* check if we have a normal rollover */
-               unsigned long raw_intr_status =
-                       apbt_readl_reg(APBTMRS_RAW_INT_STATUS);
-               /*
-                * cs timer interrupt is masked but raw intr bit is set if
-                * rollover occurs. then we read EOI reg to clear it.
-                */
-               if (raw_intr_status & (1 << phy_cs_timer_id)) {
-                       apbt_readl(phy_cs_timer_id, APBTMR_N_EOI);
-                       goto out;
-               }
-               pr_debug("APB CS going back %lx:%lx:%lx ",
-                        t2, last_read, t2 - last_read);
-bad_count_x3:
-               pr_debug("triple check enforced\n");
-               t0 = apbt_readl(phy_cs_timer_id,
-                               APBTMR_N_CURRENT_VALUE);
-               udelay(1);
-               t1 = apbt_readl(phy_cs_timer_id,
-                               APBTMR_N_CURRENT_VALUE);
-               udelay(1);
-               t2 = apbt_readl(phy_cs_timer_id,
-                               APBTMR_N_CURRENT_VALUE);
-               if ((t2 > t1) || (t1 > t0)) {
-                       printk(KERN_ERR "Error: APB CS tripple check failed\n");
-                       goto bad_count_x3;
-               }
-       }
-out:
-       last_read = t2;
-       return (cycle_t)~t2;
+       unsigned long current_count;
+
+       current_count = apbt_readl(phy_cs_timer_id, APBTMR_N_CURRENT_VALUE);
+       return (cycle_t)~current_count;
 }
 
 static int apbt_clocksource_register(void)
index d3cfe26c0252ab24aaae1481c8c297ac096e6c6d..ca2f10622a7918cb98bf89248748526112d153b5 100644 (file)
@@ -1066,6 +1066,8 @@ void __init setup_arch(char **cmdline_p)
 #endif
        x86_init.oem.banner();
 
+       x86_init.timers.wallclock_init();
+
        mcheck_init();
 
        local_irq_save(flags);
index ceb2911aa439dcb87ac0ef07a8d700f4a5a274e7..c11514e9128b53cf0b6ad66d844c7703a6a8523a 100644 (file)
@@ -70,6 +70,7 @@ struct x86_init_ops x86_init __initdata = {
                .setup_percpu_clockev   = setup_boot_APIC_clock,
                .tsc_pre_init           = x86_init_noop,
                .timer_init             = hpet_time_init,
+               .wallclock_init         = x86_init_noop,
        },
 
        .iommu = {
index 85b68ef5e80965a7fecf7e00d10b34439f8d34fb..c63c6d3dd8e81e7d7dabf4309308fe63d0d39b37 100644 (file)
@@ -254,7 +254,7 @@ int bridge_read(unsigned int devfn, int reg, int len, u32 *value)
 static int ce4100_conf_read(unsigned int seg, unsigned int bus,
                            unsigned int devfn, int reg, int len, u32 *value)
 {
-       int i, retval = 1;
+       int i;
 
        if (bus == 1) {
                for (i = 0; i < ARRAY_SIZE(bus1_fixups); i++) {
index ea6529e93c6fb2389282a78b78e739551a8f26eb..5c0207bf959bc4a8490347d775eba452c13f2684 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>
@@ -268,6 +269,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);