Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 15 Sep 2013 21:45:52 +0000 (17:45 -0400)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 15 Sep 2013 21:45:52 +0000 (17:45 -0400)
Pull MIPS fixes from Ralf Baechle:
 "These are four patches for three construction sites:

   - Fix register decoding for the combination of multi-core processors
     and multi-threading.

   - Two more fixes that are part of the ongoing DECstation resurrection
     work.  One of these touches a DECstation-only network driver.

   - Finally Markos' trivial build fix for the AP/SP support.

  (With this applied now all MIPS defconfigs are building again)"

* 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus:
  MIPS: kernel: vpe: Make vpe_attrs an array of pointers.
  MIPS: Fix SMP core calculations when using MT support.
  MIPS: DECstation I/O ASIC DMA interrupt handling fix
  MIPS: DECstation HRT initialization rearrangement

arch/mips/dec/ioasic-irq.c
arch/mips/dec/time.c
arch/mips/include/asm/dec/ioasic.h
arch/mips/kernel/csrc-ioasic.c
arch/mips/kernel/smp-cmp.c
arch/mips/kernel/vpe.c
drivers/net/ethernet/amd/declance.c

index 824e08c..4b3e3a4 100644 (file)
@@ -51,6 +51,14 @@ static struct irq_chip ioasic_irq_type = {
        .irq_unmask = unmask_ioasic_irq,
 };
 
+void clear_ioasic_dma_irq(unsigned int irq)
+{
+       u32 sir;
+
+       sir = ~(1 << (irq - ioasic_irq_base));
+       ioasic_write(IO_REG_SIR, sir);
+}
+
 static struct irq_chip ioasic_dma_irq_type = {
        .name = "IO-ASIC-DMA",
        .irq_ack = ack_ioasic_irq,
index 56ebc7f..1914e56 100644 (file)
@@ -125,12 +125,16 @@ int rtc_mips_set_mmss(unsigned long nowtime)
 
 void __init plat_time_init(void)
 {
+       int ioasic_clock = 0;
        u32 start, end;
        int i = HZ / 8;
 
        /* Set up the rate of periodic DS1287 interrupts. */
        ds1287_set_base_clock(HZ);
 
+       /* On some I/O ASIC systems we have the I/O ASIC's counter.  */
+       if (IOASIC)
+               ioasic_clock = dec_ioasic_clocksource_init() == 0;
        if (cpu_has_counter) {
                ds1287_timer_state();
                while (!ds1287_timer_state())
@@ -147,9 +151,21 @@ void __init plat_time_init(void)
                mips_hpt_frequency = (end - start) * 8;
                printk(KERN_INFO "MIPS counter frequency %dHz\n",
                        mips_hpt_frequency);
-       } else if (IOASIC)
-               /* For pre-R4k systems we use the I/O ASIC's counter.  */
-               dec_ioasic_clocksource_init();
+
+               /*
+                * All R4k DECstations suffer from the CP0 Count erratum,
+                * so we can't use the timer as a clock source, and a clock
+                * event both at a time.  An accurate wall clock is more
+                * important than a high-precision interval timer so only
+                * use the timer as a clock source, and not a clock event
+                * if there's no I/O ASIC counter available to serve as a
+                * clock source.
+                */
+               if (!ioasic_clock) {
+                       init_r4k_clocksource();
+                       mips_hpt_frequency = 0;
+               }
+       }
 
        ds1287_clockevent_init(dec_interrupt[DEC_IRQ_RTC]);
 }
index 98badd6..a6e505a 100644 (file)
@@ -31,8 +31,10 @@ static inline u32 ioasic_read(unsigned int reg)
        return ioasic_base[reg / 4];
 }
 
+extern void clear_ioasic_dma_irq(unsigned int irq);
+
 extern void init_ioasic_irqs(int base);
 
-extern void dec_ioasic_clocksource_init(void);
+extern int dec_ioasic_clocksource_init(void);
 
 #endif /* __ASM_DEC_IOASIC_H */
index 87e88fe..6cbbf6e 100644 (file)
@@ -37,7 +37,7 @@ static struct clocksource clocksource_dec = {
        .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
-void __init dec_ioasic_clocksource_init(void)
+int __init dec_ioasic_clocksource_init(void)
 {
        unsigned int freq;
        u32 start, end;
@@ -56,8 +56,14 @@ void __init dec_ioasic_clocksource_init(void)
        end = dec_ioasic_hpt_read(&clocksource_dec);
 
        freq = (end - start) * 8;
+
+       /* An early revision of the I/O ASIC didn't have the counter.  */
+       if (!freq)
+               return -ENXIO;
+
        printk(KERN_INFO "I/O ASIC clock frequency %dHz\n", freq);
 
        clocksource_dec.rating = 200 + freq / 10000000;
        clocksource_register_hz(&clocksource_dec, freq);
+       return 0;
 }
index c2e5d74..5969f1e 100644 (file)
@@ -99,7 +99,9 @@ static void cmp_init_secondary(void)
 
        c->core = (read_c0_ebase() >> 1) & 0x1ff;
 #if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_MIPS_MT_SMTC)
-       c->vpe_id = (read_c0_tcbind() >> TCBIND_CURVPE_SHIFT) & TCBIND_CURVPE;
+       if (cpu_has_mipsmt)
+               c->vpe_id = (read_c0_tcbind() >> TCBIND_CURVPE_SHIFT) &
+                       TCBIND_CURVPE;
 #endif
 #ifdef CONFIG_MIPS_MT_SMTC
        c->tc_id  = (read_c0_tcbind() & TCBIND_CURTC) >> TCBIND_CURTC_SHIFT;
@@ -177,9 +179,16 @@ void __init cmp_smp_setup(void)
        }
 
        if (cpu_has_mipsmt) {
-               unsigned int nvpe, mvpconf0 = read_c0_mvpconf0();
+               unsigned int nvpe = 1;
+#ifdef CONFIG_MIPS_MT_SMP
+               unsigned int mvpconf0 = read_c0_mvpconf0();
+
+               nvpe = ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1;
+#elif defined(CONFIG_MIPS_MT_SMTC)
+               unsigned int mvpconf0 = read_c0_mvpconf0();
 
                nvpe = ((mvpconf0 & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT) + 1;
+#endif
                smp_num_siblings = nvpe;
        }
        pr_info("Detected %i available secondary CPU(s)\n", ncpu);
index faf84c5..59b2b3c 100644 (file)
@@ -1368,7 +1368,7 @@ out_einval:
 }
 static DEVICE_ATTR_RW(ntcs);
 
-static struct attribute vpe_attrs[] = {
+static struct attribute *vpe_attrs[] = {
        &dev_attr_kill.attr,
        &dev_attr_ntcs.attr,
        NULL,
index 3d86ffe..94edc9c 100644 (file)
@@ -725,6 +725,7 @@ static irqreturn_t lance_dma_merr_int(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
 
+       clear_ioasic_dma_irq(irq);
        printk(KERN_ERR "%s: DMA error\n", dev->name);
        return IRQ_HANDLED;
 }