diff options
Diffstat (limited to 'arch/mips/dec')
-rw-r--r-- | arch/mips/dec/ioasic-irq.c | 8 | ||||
-rw-r--r-- | arch/mips/dec/time.c | 22 |
2 files changed, 27 insertions, 3 deletions
diff --git a/arch/mips/dec/ioasic-irq.c b/arch/mips/dec/ioasic-irq.c index 824e08c73798..4b3e3a4375a6 100644 --- a/arch/mips/dec/ioasic-irq.c +++ b/arch/mips/dec/ioasic-irq.c @@ -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, diff --git a/arch/mips/dec/time.c b/arch/mips/dec/time.c index 56ebc7f2bede..1914e56f0d96 100644 --- a/arch/mips/dec/time.c +++ b/arch/mips/dec/time.c @@ -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]); } |