aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/mips/kernel/cevt-r4k.c25
-rw-r--r--arch/mips/mips-boards/generic/time.c52
-rw-r--r--arch/mips/mipssim/sim_time.c52
-rw-r--r--include/asm-mips/time.h1
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
130void __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
150void __init plat_perf_setup(void) 130void __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
169void __init plat_timer_setup(struct irqaction *irq) 149unsigned 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); 166void __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
78void __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
97static int mips_cpu_timer_irq; 78static int mips_cpu_timer_irq;
98 79
99static void mips_timer_dispatch(void) 80static void mips_timer_dispatch(void)
@@ -102,26 +83,37 @@ static void mips_timer_dispatch(void)
102} 83}
103 84
104 85
105void __init plat_timer_setup(struct irqaction *irq) 86unsigned __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 102void __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
79extern void mips_clockevent_init(void); 79extern void mips_clockevent_init(void);
80extern unsigned int __weak get_c0_compare_int(void);
80#else 81#else
81static inline void mips_clockevent_init(void) 82static inline void mips_clockevent_init(void)
82{ 83{