aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/sibyte/sb1250/time.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/sibyte/sb1250/time.c')
-rw-r--r--arch/mips/sibyte/sb1250/time.c104
1 files changed, 25 insertions, 79 deletions
diff --git a/arch/mips/sibyte/sb1250/time.c b/arch/mips/sibyte/sb1250/time.c
index fe11fed8e0d7..9ef54628bc9c 100644
--- a/arch/mips/sibyte/sb1250/time.c
+++ b/arch/mips/sibyte/sb1250/time.c
@@ -100,6 +100,7 @@ static void sibyte_set_mode(enum clock_event_mode mode,
100 break; 100 break;
101 101
102 case CLOCK_EVT_MODE_UNUSED: /* shuddup gcc */ 102 case CLOCK_EVT_MODE_UNUSED: /* shuddup gcc */
103 case CLOCK_EVT_MODE_RESUME:
103 ; 104 ;
104 } 105 }
105} 106}
@@ -144,79 +145,7 @@ static struct irqaction sibyte_irqaction = {
144 .name = "timer", 145 .name = "timer",
145}; 146};
146 147
147/* 148void __cpuinit sb1250_clockevent_init(void)
148 * The general purpose timer ticks at 1 Mhz independent if
149 * the rest of the system
150 */
151static void sibyte_set_mode(enum clock_event_mode mode,
152 struct clock_event_device *evt)
153{
154 unsigned int cpu = smp_processor_id();
155 void __iomem *timer_cfg, *timer_init;
156
157 timer_cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
158 timer_init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));
159
160 switch (mode) {
161 case CLOCK_EVT_MODE_PERIODIC:
162 __raw_writeq(0, timer_cfg);
163 __raw_writeq((V_SCD_TIMER_FREQ / HZ) - 1, timer_init);
164 __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
165 timer_cfg);
166 break;
167
168 case CLOCK_EVT_MODE_ONESHOT:
169 /* Stop the timer until we actually program a shot */
170 case CLOCK_EVT_MODE_SHUTDOWN:
171 __raw_writeq(0, timer_cfg);
172 break;
173
174 case CLOCK_EVT_MODE_UNUSED: /* shuddup gcc */
175 ;
176 }
177}
178
179static int
180sibyte_next_event(unsigned long delta, struct clock_event_device *evt)
181{
182 unsigned int cpu = smp_processor_id();
183 void __iomem *timer_cfg, *timer_init;
184
185 timer_cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
186 timer_init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));
187
188 __raw_writeq(0, timer_cfg);
189 __raw_writeq(delta, timer_init);
190 __raw_writeq(M_SCD_TIMER_ENABLE, timer_cfg);
191
192 return 0;
193}
194
195struct clock_event_device sibyte_hpt_clockevent = {
196 .name = "sb1250-counter",
197 .features = CLOCK_EVT_FEAT_PERIODIC,
198 .set_mode = sibyte_set_mode,
199 .set_next_event = sibyte_next_event,
200 .shift = 32,
201 .irq = 0,
202};
203
204static irqreturn_t sibyte_counter_handler(int irq, void *dev_id)
205{
206 struct clock_event_device *cd = &sibyte_hpt_clockevent;
207
208 cd->event_handler(cd);
209
210 return IRQ_HANDLED;
211}
212
213static struct irqaction sibyte_irqaction = {
214 .handler = sibyte_counter_handler,
215 .flags = IRQF_DISABLED | IRQF_PERCPU,
216 .name = "timer",
217};
218
219static void __init sb1250_clockevent_init(void)
220{ 149{
221 struct clock_event_device *cd = &sibyte_hpt_clockevent; 150 struct clock_event_device *cd = &sibyte_hpt_clockevent;
222 unsigned int cpu = smp_processor_id(); 151 unsigned int cpu = smp_processor_id();
@@ -249,12 +178,6 @@ static void __init sb1250_clockevent_init(void)
249 clockevents_register_device(cd); 178 clockevents_register_device(cd);
250} 179}
251 180
252void __init plat_time_init(void)
253{
254 sb1250_clocksource_init();
255 sb1250_clockevent_init();
256}
257
258/* 181/*
259 * The HPT is free running from SB1250_HPT_VALUE down to 0 then starts over 182 * The HPT is free running from SB1250_HPT_VALUE down to 0 then starts over
260 * again. 183 * again.
@@ -267,3 +190,26 @@ static cycle_t sb1250_hpt_read(void)
267 190
268 return SB1250_HPT_VALUE - count; 191 return SB1250_HPT_VALUE - count;
269} 192}
193
194struct clocksource bcm1250_clocksource = {
195 .name = "MIPS",
196 .rating = 200,
197 .read = sb1250_hpt_read,
198 .mask = CLOCKSOURCE_MASK(32),
199 .shift = 32,
200 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
201};
202
203void __init sb1250_clocksource_init(void)
204{
205 struct clocksource *cs = &bcm1250_clocksource;
206
207 clocksource_set_clock(cs, V_SCD_TIMER_FREQ);
208 clocksource_register(cs);
209}
210
211void __init plat_time_init(void)
212{
213 sb1250_clocksource_init();
214 sb1250_clockevent_init();
215}