diff options
-rw-r--r-- | arch/mips/dec/time.c | 22 | ||||
-rw-r--r-- | arch/mips/include/asm/dec/ioasic.h | 2 | ||||
-rw-r--r-- | arch/mips/kernel/csrc-ioasic.c | 8 |
3 files changed, 27 insertions, 5 deletions
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) | |||
125 | 125 | ||
126 | void __init plat_time_init(void) | 126 | void __init plat_time_init(void) |
127 | { | 127 | { |
128 | int ioasic_clock = 0; | ||
128 | u32 start, end; | 129 | u32 start, end; |
129 | int i = HZ / 8; | 130 | int i = HZ / 8; |
130 | 131 | ||
131 | /* Set up the rate of periodic DS1287 interrupts. */ | 132 | /* Set up the rate of periodic DS1287 interrupts. */ |
132 | ds1287_set_base_clock(HZ); | 133 | ds1287_set_base_clock(HZ); |
133 | 134 | ||
135 | /* On some I/O ASIC systems we have the I/O ASIC's counter. */ | ||
136 | if (IOASIC) | ||
137 | ioasic_clock = dec_ioasic_clocksource_init() == 0; | ||
134 | if (cpu_has_counter) { | 138 | if (cpu_has_counter) { |
135 | ds1287_timer_state(); | 139 | ds1287_timer_state(); |
136 | while (!ds1287_timer_state()) | 140 | while (!ds1287_timer_state()) |
@@ -147,9 +151,21 @@ void __init plat_time_init(void) | |||
147 | mips_hpt_frequency = (end - start) * 8; | 151 | mips_hpt_frequency = (end - start) * 8; |
148 | printk(KERN_INFO "MIPS counter frequency %dHz\n", | 152 | printk(KERN_INFO "MIPS counter frequency %dHz\n", |
149 | mips_hpt_frequency); | 153 | mips_hpt_frequency); |
150 | } else if (IOASIC) | 154 | |
151 | /* For pre-R4k systems we use the I/O ASIC's counter. */ | 155 | /* |
152 | dec_ioasic_clocksource_init(); | 156 | * All R4k DECstations suffer from the CP0 Count erratum, |
157 | * so we can't use the timer as a clock source, and a clock | ||
158 | * event both at a time. An accurate wall clock is more | ||
159 | * important than a high-precision interval timer so only | ||
160 | * use the timer as a clock source, and not a clock event | ||
161 | * if there's no I/O ASIC counter available to serve as a | ||
162 | * clock source. | ||
163 | */ | ||
164 | if (!ioasic_clock) { | ||
165 | init_r4k_clocksource(); | ||
166 | mips_hpt_frequency = 0; | ||
167 | } | ||
168 | } | ||
153 | 169 | ||
154 | ds1287_clockevent_init(dec_interrupt[DEC_IRQ_RTC]); | 170 | ds1287_clockevent_init(dec_interrupt[DEC_IRQ_RTC]); |
155 | } | 171 | } |
diff --git a/arch/mips/include/asm/dec/ioasic.h b/arch/mips/include/asm/dec/ioasic.h index 98badd6bf22d..be4d62a5a10e 100644 --- a/arch/mips/include/asm/dec/ioasic.h +++ b/arch/mips/include/asm/dec/ioasic.h | |||
@@ -33,6 +33,6 @@ static inline u32 ioasic_read(unsigned int reg) | |||
33 | 33 | ||
34 | extern void init_ioasic_irqs(int base); | 34 | extern void init_ioasic_irqs(int base); |
35 | 35 | ||
36 | extern void dec_ioasic_clocksource_init(void); | 36 | extern int dec_ioasic_clocksource_init(void); |
37 | 37 | ||
38 | #endif /* __ASM_DEC_IOASIC_H */ | 38 | #endif /* __ASM_DEC_IOASIC_H */ |
diff --git a/arch/mips/kernel/csrc-ioasic.c b/arch/mips/kernel/csrc-ioasic.c index 87e88feb4a25..6cbbf6e106b9 100644 --- a/arch/mips/kernel/csrc-ioasic.c +++ b/arch/mips/kernel/csrc-ioasic.c | |||
@@ -37,7 +37,7 @@ static struct clocksource clocksource_dec = { | |||
37 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | 37 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
38 | }; | 38 | }; |
39 | 39 | ||
40 | void __init dec_ioasic_clocksource_init(void) | 40 | int __init dec_ioasic_clocksource_init(void) |
41 | { | 41 | { |
42 | unsigned int freq; | 42 | unsigned int freq; |
43 | u32 start, end; | 43 | u32 start, end; |
@@ -56,8 +56,14 @@ void __init dec_ioasic_clocksource_init(void) | |||
56 | end = dec_ioasic_hpt_read(&clocksource_dec); | 56 | end = dec_ioasic_hpt_read(&clocksource_dec); |
57 | 57 | ||
58 | freq = (end - start) * 8; | 58 | freq = (end - start) * 8; |
59 | |||
60 | /* An early revision of the I/O ASIC didn't have the counter. */ | ||
61 | if (!freq) | ||
62 | return -ENXIO; | ||
63 | |||
59 | printk(KERN_INFO "I/O ASIC clock frequency %dHz\n", freq); | 64 | printk(KERN_INFO "I/O ASIC clock frequency %dHz\n", freq); |
60 | 65 | ||
61 | clocksource_dec.rating = 200 + freq / 10000000; | 66 | clocksource_dec.rating = 200 + freq / 10000000; |
62 | clocksource_register_hz(&clocksource_dec, freq); | 67 | clocksource_register_hz(&clocksource_dec, freq); |
68 | return 0; | ||
63 | } | 69 | } |