diff options
-rw-r--r-- | arch/mips/kernel/cevt-r4k.c | 25 | ||||
-rw-r--r-- | arch/mips/mips-boards/generic/time.c | 52 | ||||
-rw-r--r-- | arch/mips/mipssim/sim_time.c | 52 | ||||
-rw-r--r-- | include/asm-mips/time.h | 1 |
4 files changed, 63 insertions, 67 deletions
diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c index a59f67ff301e..bab935a3d74b 100644 --- a/arch/mips/kernel/cevt-r4k.c +++ b/arch/mips/kernel/cevt-r4k.c | |||
@@ -224,7 +224,7 @@ void __cpuinit mips_clockevent_init(void) | |||
224 | uint64_t mips_freq = mips_hpt_frequency; | 224 | uint64_t mips_freq = mips_hpt_frequency; |
225 | unsigned int cpu = smp_processor_id(); | 225 | unsigned int cpu = smp_processor_id(); |
226 | struct clock_event_device *cd; | 226 | struct clock_event_device *cd; |
227 | unsigned int irq = MIPS_CPU_IRQ_BASE + 7; | 227 | unsigned int irq; |
228 | 228 | ||
229 | if (!cpu_has_counter || !mips_hpt_frequency) | 229 | if (!cpu_has_counter || !mips_hpt_frequency) |
230 | return; | 230 | return; |
@@ -243,6 +243,15 @@ void __cpuinit mips_clockevent_init(void) | |||
243 | if (!c0_compare_int_usable()) | 243 | if (!c0_compare_int_usable()) |
244 | return; | 244 | return; |
245 | 245 | ||
246 | /* | ||
247 | * With vectored interrupts things are getting platform specific. | ||
248 | * get_c0_compare_int is a hook to allow a platform to return the | ||
249 | * interrupt number of it's liking. | ||
250 | */ | ||
251 | irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; | ||
252 | if (get_c0_compare_int) | ||
253 | irq = get_c0_compare_int(); | ||
254 | |||
246 | cd = &per_cpu(mips_clockevent_device, cpu); | 255 | cd = &per_cpu(mips_clockevent_device, cpu); |
247 | 256 | ||
248 | cd->name = "MIPS"; | 257 | cd->name = "MIPS"; |
@@ -267,13 +276,15 @@ void __cpuinit mips_clockevent_init(void) | |||
267 | 276 | ||
268 | clockevents_register_device(cd); | 277 | clockevents_register_device(cd); |
269 | 278 | ||
270 | if (!cp0_timer_irq_installed) { | 279 | if (!cp0_timer_irq_installed) |
280 | return; | ||
281 | |||
282 | cp0_timer_irq_installed = 1; | ||
283 | |||
271 | #ifdef CONFIG_MIPS_MT_SMTC | 284 | #ifdef CONFIG_MIPS_MT_SMTC |
272 | #define CPUCTR_IMASKBIT (0x100 << cp0_compare_irq) | 285 | #define CPUCTR_IMASKBIT (0x100 << cp0_compare_irq) |
273 | setup_irq_smtc(irq, &c0_compare_irqaction, CPUCTR_IMASKBIT); | 286 | setup_irq_smtc(irq, &c0_compare_irqaction, CPUCTR_IMASKBIT); |
274 | #else | 287 | #else |
275 | setup_irq(irq, &c0_compare_irqaction); | 288 | setup_irq(irq, &c0_compare_irqaction); |
276 | #endif /* CONFIG_MIPS_MT_SMTC */ | 289 | #endif |
277 | cp0_timer_irq_installed = 1; | ||
278 | } | ||
279 | } | 290 | } |
diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c index 9d6243a8c15a..f02ce6308e51 100644 --- a/arch/mips/mips-boards/generic/time.c +++ b/arch/mips/mips-boards/generic/time.c | |||
@@ -127,26 +127,6 @@ unsigned long read_persistent_clock(void) | |||
127 | return mc146818_get_cmos_time(); | 127 | return mc146818_get_cmos_time(); |
128 | } | 128 | } |
129 | 129 | ||
130 | void __init plat_time_init(void) | ||
131 | { | ||
132 | unsigned int est_freq; | ||
133 | |||
134 | /* Set Data mode - binary. */ | ||
135 | CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL); | ||
136 | |||
137 | est_freq = estimate_cpu_frequency(); | ||
138 | |||
139 | printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, | ||
140 | (est_freq%1000000)*100/1000000); | ||
141 | |||
142 | cpu_khz = est_freq / 1000; | ||
143 | |||
144 | mips_scroll_message(); | ||
145 | #ifdef CONFIG_I8253 /* Only Malta has a PIT */ | ||
146 | setup_pit_timer(); | ||
147 | #endif | ||
148 | } | ||
149 | |||
150 | void __init plat_perf_setup(void) | 130 | void __init plat_perf_setup(void) |
151 | { | 131 | { |
152 | cp0_perfcount_irq = -1; | 132 | cp0_perfcount_irq = -1; |
@@ -166,14 +146,13 @@ void __init plat_perf_setup(void) | |||
166 | } | 146 | } |
167 | } | 147 | } |
168 | 148 | ||
169 | void __init plat_timer_setup(struct irqaction *irq) | 149 | unsigned int __init get_c0_compare_int(void) |
170 | { | 150 | { |
171 | #ifdef MSC01E_INT_BASE | 151 | #ifdef MSC01E_INT_BASE |
172 | if (cpu_has_veic) { | 152 | if (cpu_has_veic) { |
173 | set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch); | 153 | set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch); |
174 | mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR; | 154 | mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR; |
175 | } | 155 | } else |
176 | else | ||
177 | #endif | 156 | #endif |
178 | { | 157 | { |
179 | if (cpu_has_vint) | 158 | if (cpu_has_vint) |
@@ -181,13 +160,26 @@ void __init plat_timer_setup(struct irqaction *irq) | |||
181 | mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; | 160 | mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; |
182 | } | 161 | } |
183 | 162 | ||
184 | #ifdef CONFIG_MIPS_MT_SMTC | 163 | return mips_cpu_timer_irq; |
185 | setup_irq_smtc(mips_cpu_timer_irq, irq, 0x100 << cp0_compare_irq); | 164 | } |
186 | #else | 165 | |
187 | setup_irq(mips_cpu_timer_irq, irq); | 166 | void __init plat_time_init(void) |
188 | #endif /* CONFIG_MIPS_MT_SMTC */ | 167 | { |
189 | #ifdef CONFIG_SMP | 168 | unsigned int est_freq; |
190 | set_irq_handler(mips_cpu_timer_irq, handle_percpu_irq); | 169 | |
170 | /* Set Data mode - binary. */ | ||
171 | CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL); | ||
172 | |||
173 | est_freq = estimate_cpu_frequency(); | ||
174 | |||
175 | printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, | ||
176 | (est_freq%1000000)*100/1000000); | ||
177 | |||
178 | cpu_khz = est_freq / 1000; | ||
179 | |||
180 | mips_scroll_message(); | ||
181 | #ifdef CONFIG_I8253 /* Only Malta has a PIT */ | ||
182 | setup_pit_timer(); | ||
191 | #endif | 183 | #endif |
192 | 184 | ||
193 | plat_perf_setup(); | 185 | plat_perf_setup(); |
diff --git a/arch/mips/mipssim/sim_time.c b/arch/mips/mipssim/sim_time.c index e7fa0d1078a3..bfaafa38846f 100644 --- a/arch/mips/mipssim/sim_time.c +++ b/arch/mips/mipssim/sim_time.c | |||
@@ -75,25 +75,6 @@ static unsigned int __init estimate_cpu_frequency(void) | |||
75 | return count; | 75 | return count; |
76 | } | 76 | } |
77 | 77 | ||
78 | void __init plat_time_init(void) | ||
79 | { | ||
80 | unsigned int est_freq, flags; | ||
81 | |||
82 | local_irq_save(flags); | ||
83 | |||
84 | /* Set Data mode - binary. */ | ||
85 | CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL); | ||
86 | |||
87 | est_freq = estimate_cpu_frequency(); | ||
88 | |||
89 | printk(KERN_INFO "CPU frequency %d.%02d MHz\n", est_freq / 1000000, | ||
90 | (est_freq % 1000000) * 100 / 1000000); | ||
91 | |||
92 | cpu_khz = est_freq / 1000; | ||
93 | |||
94 | local_irq_restore(flags); | ||
95 | } | ||
96 | |||
97 | static int mips_cpu_timer_irq; | 78 | static int mips_cpu_timer_irq; |
98 | 79 | ||
99 | static void mips_timer_dispatch(void) | 80 | static void mips_timer_dispatch(void) |
@@ -102,26 +83,37 @@ static void mips_timer_dispatch(void) | |||
102 | } | 83 | } |
103 | 84 | ||
104 | 85 | ||
105 | void __init plat_timer_setup(struct irqaction *irq) | 86 | unsigned __init get_c0_compare_int(void) |
106 | { | 87 | { |
88 | #ifdef MSC01E_INT_BASE | ||
107 | if (cpu_has_veic) { | 89 | if (cpu_has_veic) { |
108 | set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch); | 90 | set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch); |
109 | mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR; | 91 | mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR; |
110 | } else { | 92 | } else { |
93 | #endif | ||
111 | if (cpu_has_vint) | 94 | if (cpu_has_vint) |
112 | set_vi_handler(cp0_compare_irq, mips_timer_dispatch); | 95 | set_vi_handler(cp0_compare_irq, mips_timer_dispatch); |
113 | mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; | 96 | mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; |
114 | } | 97 | } |
115 | 98 | ||
116 | /* we are using the cpu counter for timer interrupts */ | 99 | return mips_cpu_timer_irq; |
117 | setup_irq(mips_cpu_timer_irq, irq); | 100 | } |
118 | 101 | ||
119 | #ifdef CONFIG_SMP | 102 | void __init plat_time_init(void) |
120 | /* irq_desc(riptor) is a global resource, when the interrupt overlaps | 103 | { |
121 | on seperate cpu's the first one tries to handle the second interrupt. | 104 | unsigned int est_freq, flags; |
122 | The effect is that the int remains disabled on the second cpu. | 105 | |
123 | Mark the interrupt with IRQ_PER_CPU to avoid any confusion */ | 106 | local_irq_save(flags); |
124 | irq_desc[mips_cpu_timer_irq].flags |= IRQ_PER_CPU; | 107 | |
125 | set_irq_handler(mips_cpu_timer_irq, handle_percpu_irq); | 108 | /* Set Data mode - binary. */ |
126 | #endif | 109 | CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL); |
110 | |||
111 | est_freq = estimate_cpu_frequency(); | ||
112 | |||
113 | printk(KERN_INFO "CPU frequency %d.%02d MHz\n", est_freq / 1000000, | ||
114 | (est_freq % 1000000) * 100 / 1000000); | ||
115 | |||
116 | cpu_khz = est_freq / 1000; | ||
117 | |||
118 | local_irq_restore(flags); | ||
127 | } | 119 | } |
diff --git a/include/asm-mips/time.h b/include/asm-mips/time.h index ce1e07a82aec..0a6bc7dc158e 100644 --- a/include/asm-mips/time.h +++ b/include/asm-mips/time.h | |||
@@ -77,6 +77,7 @@ extern int (*perf_irq)(void); | |||
77 | */ | 77 | */ |
78 | #ifdef CONFIG_CEVT_R4K | 78 | #ifdef CONFIG_CEVT_R4K |
79 | extern void mips_clockevent_init(void); | 79 | extern void mips_clockevent_init(void); |
80 | extern unsigned int __weak get_c0_compare_int(void); | ||
80 | #else | 81 | #else |
81 | static inline void mips_clockevent_init(void) | 82 | static inline void mips_clockevent_init(void) |
82 | { | 83 | { |