.. | .. |
---|
38 | 38 | #define TIMER_CR (0x30) |
---|
39 | 39 | |
---|
40 | 40 | /* |
---|
| 41 | + * Control register set to clear for ast2600 only. |
---|
| 42 | + */ |
---|
| 43 | +#define AST2600_TIMER_CR_CLR (0x3c) |
---|
| 44 | + |
---|
| 45 | +/* |
---|
41 | 46 | * Control register (TMC30) bit fields for fttmr010/gemini/moxart timers. |
---|
42 | 47 | */ |
---|
43 | 48 | #define TIMER_1_CR_ENABLE BIT(0) |
---|
.. | .. |
---|
97 | 102 | bool is_aspeed; |
---|
98 | 103 | u32 t1_enable_val; |
---|
99 | 104 | struct clock_event_device clkevt; |
---|
| 105 | + int (*timer_shutdown)(struct clock_event_device *evt); |
---|
100 | 106 | #ifdef CONFIG_ARM |
---|
101 | 107 | struct delay_timer delay_timer; |
---|
102 | 108 | #endif |
---|
.. | .. |
---|
140 | 146 | u32 cr; |
---|
141 | 147 | |
---|
142 | 148 | /* Stop */ |
---|
143 | | - cr = readl(fttmr010->base + TIMER_CR); |
---|
144 | | - cr &= ~fttmr010->t1_enable_val; |
---|
145 | | - writel(cr, fttmr010->base + TIMER_CR); |
---|
| 149 | + fttmr010->timer_shutdown(evt); |
---|
146 | 150 | |
---|
147 | 151 | if (fttmr010->is_aspeed) { |
---|
148 | 152 | /* |
---|
.. | .. |
---|
160 | 164 | cr = readl(fttmr010->base + TIMER_CR); |
---|
161 | 165 | cr |= fttmr010->t1_enable_val; |
---|
162 | 166 | writel(cr, fttmr010->base + TIMER_CR); |
---|
| 167 | + |
---|
| 168 | + return 0; |
---|
| 169 | +} |
---|
| 170 | + |
---|
| 171 | +static int ast2600_timer_shutdown(struct clock_event_device *evt) |
---|
| 172 | +{ |
---|
| 173 | + struct fttmr010 *fttmr010 = to_fttmr010(evt); |
---|
| 174 | + |
---|
| 175 | + /* Stop */ |
---|
| 176 | + writel(fttmr010->t1_enable_val, fttmr010->base + AST2600_TIMER_CR_CLR); |
---|
163 | 177 | |
---|
164 | 178 | return 0; |
---|
165 | 179 | } |
---|
.. | .. |
---|
183 | 197 | u32 cr; |
---|
184 | 198 | |
---|
185 | 199 | /* Stop */ |
---|
186 | | - cr = readl(fttmr010->base + TIMER_CR); |
---|
187 | | - cr &= ~fttmr010->t1_enable_val; |
---|
188 | | - writel(cr, fttmr010->base + TIMER_CR); |
---|
| 200 | + fttmr010->timer_shutdown(evt); |
---|
189 | 201 | |
---|
190 | 202 | /* Setup counter start from 0 or ~0 */ |
---|
191 | 203 | writel(0, fttmr010->base + TIMER1_COUNT); |
---|
.. | .. |
---|
211 | 223 | u32 cr; |
---|
212 | 224 | |
---|
213 | 225 | /* Stop */ |
---|
214 | | - cr = readl(fttmr010->base + TIMER_CR); |
---|
215 | | - cr &= ~fttmr010->t1_enable_val; |
---|
216 | | - writel(cr, fttmr010->base + TIMER_CR); |
---|
| 226 | + fttmr010->timer_shutdown(evt); |
---|
217 | 227 | |
---|
218 | 228 | /* Setup timer to fire at 1/HZ intervals. */ |
---|
219 | 229 | if (fttmr010->is_aspeed) { |
---|
.. | .. |
---|
249 | 259 | return IRQ_HANDLED; |
---|
250 | 260 | } |
---|
251 | 261 | |
---|
252 | | -static int __init fttmr010_common_init(struct device_node *np, bool is_aspeed) |
---|
| 262 | +static irqreturn_t ast2600_timer_interrupt(int irq, void *dev_id) |
---|
| 263 | +{ |
---|
| 264 | + struct clock_event_device *evt = dev_id; |
---|
| 265 | + struct fttmr010 *fttmr010 = to_fttmr010(evt); |
---|
| 266 | + |
---|
| 267 | + writel(0x1, fttmr010->base + TIMER_INTR_STATE); |
---|
| 268 | + |
---|
| 269 | + evt->event_handler(evt); |
---|
| 270 | + return IRQ_HANDLED; |
---|
| 271 | +} |
---|
| 272 | + |
---|
| 273 | +static int __init fttmr010_common_init(struct device_node *np, |
---|
| 274 | + bool is_aspeed, |
---|
| 275 | + int (*timer_shutdown)(struct clock_event_device *), |
---|
| 276 | + irq_handler_t irq_handler) |
---|
253 | 277 | { |
---|
254 | 278 | struct fttmr010 *fttmr010; |
---|
255 | 279 | int irq; |
---|
.. | .. |
---|
350 | 374 | fttmr010->tick_rate); |
---|
351 | 375 | } |
---|
352 | 376 | |
---|
| 377 | + fttmr010->timer_shutdown = timer_shutdown; |
---|
| 378 | + |
---|
353 | 379 | /* |
---|
354 | 380 | * Setup clockevent timer (interrupt-driven) on timer 1. |
---|
355 | 381 | */ |
---|
.. | .. |
---|
357 | 383 | writel(0, fttmr010->base + TIMER1_LOAD); |
---|
358 | 384 | writel(0, fttmr010->base + TIMER1_MATCH1); |
---|
359 | 385 | writel(0, fttmr010->base + TIMER1_MATCH2); |
---|
360 | | - ret = request_irq(irq, fttmr010_timer_interrupt, IRQF_TIMER, |
---|
| 386 | + ret = request_irq(irq, irq_handler, IRQF_TIMER, |
---|
361 | 387 | "FTTMR010-TIMER1", &fttmr010->clkevt); |
---|
362 | 388 | if (ret) { |
---|
363 | 389 | pr_err("FTTMR010-TIMER1 no IRQ\n"); |
---|
.. | .. |
---|
370 | 396 | fttmr010->clkevt.features = CLOCK_EVT_FEAT_PERIODIC | |
---|
371 | 397 | CLOCK_EVT_FEAT_ONESHOT; |
---|
372 | 398 | fttmr010->clkevt.set_next_event = fttmr010_timer_set_next_event; |
---|
373 | | - fttmr010->clkevt.set_state_shutdown = fttmr010_timer_shutdown; |
---|
| 399 | + fttmr010->clkevt.set_state_shutdown = fttmr010->timer_shutdown; |
---|
374 | 400 | fttmr010->clkevt.set_state_periodic = fttmr010_timer_set_periodic; |
---|
375 | 401 | fttmr010->clkevt.set_state_oneshot = fttmr010_timer_set_oneshot; |
---|
376 | | - fttmr010->clkevt.tick_resume = fttmr010_timer_shutdown; |
---|
| 402 | + fttmr010->clkevt.tick_resume = fttmr010->timer_shutdown; |
---|
377 | 403 | fttmr010->clkevt.cpumask = cpumask_of(0); |
---|
378 | 404 | fttmr010->clkevt.irq = irq; |
---|
379 | 405 | clockevents_config_and_register(&fttmr010->clkevt, |
---|
.. | .. |
---|
404 | 430 | return ret; |
---|
405 | 431 | } |
---|
406 | 432 | |
---|
| 433 | +static __init int ast2600_timer_init(struct device_node *np) |
---|
| 434 | +{ |
---|
| 435 | + return fttmr010_common_init(np, true, |
---|
| 436 | + ast2600_timer_shutdown, |
---|
| 437 | + ast2600_timer_interrupt); |
---|
| 438 | +} |
---|
| 439 | + |
---|
407 | 440 | static __init int aspeed_timer_init(struct device_node *np) |
---|
408 | 441 | { |
---|
409 | | - return fttmr010_common_init(np, true); |
---|
| 442 | + return fttmr010_common_init(np, true, |
---|
| 443 | + fttmr010_timer_shutdown, |
---|
| 444 | + fttmr010_timer_interrupt); |
---|
410 | 445 | } |
---|
411 | 446 | |
---|
412 | 447 | static __init int fttmr010_timer_init(struct device_node *np) |
---|
413 | 448 | { |
---|
414 | | - return fttmr010_common_init(np, false); |
---|
| 449 | + return fttmr010_common_init(np, false, |
---|
| 450 | + fttmr010_timer_shutdown, |
---|
| 451 | + fttmr010_timer_interrupt); |
---|
415 | 452 | } |
---|
416 | 453 | |
---|
417 | 454 | TIMER_OF_DECLARE(fttmr010, "faraday,fttmr010", fttmr010_timer_init); |
---|
.. | .. |
---|
419 | 456 | TIMER_OF_DECLARE(moxart, "moxa,moxart-timer", fttmr010_timer_init); |
---|
420 | 457 | TIMER_OF_DECLARE(ast2400, "aspeed,ast2400-timer", aspeed_timer_init); |
---|
421 | 458 | TIMER_OF_DECLARE(ast2500, "aspeed,ast2500-timer", aspeed_timer_init); |
---|
| 459 | +TIMER_OF_DECLARE(ast2600, "aspeed,ast2600-timer", ast2600_timer_init); |
---|