2 * linux/arch/h8300/kernel/cpu/timer/timer8.c
4 * Yoshinori Sato <ysato@users.sourcefoge.jp>
10 #include <linux/errno.h>
11 #include <linux/sched.h>
12 #include <linux/kernel.h>
13 #include <linux/interrupt.h>
14 #include <linux/init.h>
15 #include <linux/platform_device.h>
16 #include <linux/slab.h>
17 #include <linux/clocksource.h>
18 #include <linux/clockchips.h>
19 #include <linux/module.h>
23 #include <asm/timer.h>
31 #define FLAG_REPROGRAM (1 << 0)
32 #define FLAG_SKIPEVENT (1 << 1)
33 #define FLAG_IRQCONTEXT (1 << 2)
34 #define FLAG_STARTED (1 << 3)
43 struct platform_device *pdev;
46 struct clocksource cs;
47 struct clock_event_device ced;
49 struct irqaction irqaction;
50 unsigned long mapbase;
52 unsigned long total_cycles;
53 unsigned int cs_enabled;
60 static const int div_rate[] = {8, 64, 8192};
62 static unsigned long timer8_get_counter(struct timer8_priv *p)
64 unsigned long v1, v2, v3;
67 o1 = ctrl_inb(p->mapbase + _8TCSR) & 0x20;
69 /* Make sure the timer value is stable. Stolen from acpi_pm.c */
72 v1 = ctrl_inw(p->mapbase + _8TCNT);
73 v2 = ctrl_inw(p->mapbase + _8TCNT);
74 v3 = ctrl_inw(p->mapbase + _8TCNT);
75 o1 = ctrl_inb(p->mapbase + _8TCSR) & 0x20;
76 } while (unlikely((o1 != o2) || (v1 > v2 && v1 < v3)
77 || (v2 > v3 && v2 < v1) || (v3 > v1 && v3 < v2)));
83 static irqreturn_t timer8_interrupt(int irq, void *dev_id)
85 struct timer8_priv *p = dev_id;
88 case H8300_TMR8_CLKSRC:
89 ctrl_outb(ctrl_inb(p->mapbase + _8TCSR) & ~0x20,
91 p->total_cycles += 0x10000;
93 case H8300_TMR8_CLKEVTDEV:
94 ctrl_outb(ctrl_inb(p->mapbase + _8TCSR) & ~0x40,
96 p->flags |= FLAG_IRQCONTEXT;
97 ctrl_outw(p->tcora, p->mapbase + TCORA);
98 if (!(p->flags & FLAG_SKIPEVENT)) {
99 if (p->clk.ced.mode == CLOCK_EVT_MODE_ONESHOT)
100 ctrl_outw(0x0000, p->mapbase + _8TCR);
101 p->clk.ced.event_handler(&p->clk.ced);
103 p->flags &= ~(FLAG_SKIPEVENT | FLAG_IRQCONTEXT);
110 static inline struct timer8_priv *cs_to_priv(struct clocksource *cs)
112 return container_of(cs, struct timer8_priv, clk.cs);
115 static cycle_t timer8_clocksource_read(struct clocksource *cs)
117 struct timer8_priv *p = cs_to_priv(cs);
118 unsigned long flags, raw;
121 raw_spin_lock_irqsave(&p->lock, flags);
122 value = p->total_cycles;
123 raw = timer8_get_counter(p);
124 raw_spin_unlock_irqrestore(&p->lock, flags);
129 static int timer8_clocksource_enable(struct clocksource *cs)
131 struct timer8_priv *p = cs_to_priv(cs);
133 WARN_ON(p->cs_enabled);
136 ctrl_outw(0, p->mapbase + _8TCNT);
137 ctrl_outw(0x2400 | p->div, p->mapbase + _8TCR);
139 p->cs_enabled = true;
143 static void timer8_clocksource_disable(struct clocksource *cs)
145 struct timer8_priv *p = cs_to_priv(cs);
147 WARN_ON(!p->cs_enabled);
149 ctrl_outb(0, p->mapbase + _8TCR);
150 p->cs_enabled = false;
153 static void timer8_set_next(struct timer8_priv *p, unsigned long delta)
158 raw_spin_lock_irqsave(&p->lock, flags);
159 if (delta >= 0x10000)
160 dev_warn(&p->pdev->dev, "delta out of range\n");
161 now = timer8_get_counter(p);
163 ctrl_outb(ctrl_inb(p->mapbase + _8TCR) | 0x40, p->mapbase + _8TCR);
165 ctrl_outw(delta, p->mapbase + TCORA);
167 ctrl_outw(now + 1, p->mapbase + TCORA);
169 raw_spin_unlock_irqrestore(&p->lock, flags);
172 static int timer8_enable(struct timer8_priv *p)
174 p->rate = get_cpu_clock() / div_rate[p->div];
175 ctrl_outw(0xffff, p->mapbase + TCORA);
176 ctrl_outw(0x0000, p->mapbase + _8TCNT);
177 ctrl_outw(0x0c01, p->mapbase + _8TCR);
182 static int timer8_start(struct timer8_priv *p)
187 raw_spin_lock_irqsave(&p->lock, flags);
189 if (!(p->flags & FLAG_STARTED))
190 ret = timer8_enable(p);
194 p->flags |= FLAG_STARTED;
197 raw_spin_unlock_irqrestore(&p->lock, flags);
202 static void timer8_stop(struct timer8_priv *p)
206 raw_spin_lock_irqsave(&p->lock, flags);
208 ctrl_outw(0x0000, p->mapbase + _8TCR);
210 raw_spin_unlock_irqrestore(&p->lock, flags);
213 static inline struct timer8_priv *ced_to_priv(struct clock_event_device *ced)
215 return container_of(ced, struct timer8_priv, clk.ced);
218 static void timer8_clock_event_start(struct timer8_priv *p, int periodic)
220 struct clock_event_device *ced = &p->clk.ced;
225 ced->mult = div_sc(p->rate, NSEC_PER_SEC, ced->shift);
226 ced->max_delta_ns = clockevent_delta2ns(0xffff, ced);
227 ced->min_delta_ns = clockevent_delta2ns(0x0001, ced);
229 timer8_set_next(p, periodic?(p->rate + HZ/2) / HZ:0x10000);
232 static void timer8_clock_event_mode(enum clock_event_mode mode,
233 struct clock_event_device *ced)
235 struct timer8_priv *p = ced_to_priv(ced);
238 case CLOCK_EVT_MODE_PERIODIC:
239 dev_info(&p->pdev->dev, "used for periodic clock events\n");
241 timer8_clock_event_start(p, PERIODIC);
243 case CLOCK_EVT_MODE_ONESHOT:
244 dev_info(&p->pdev->dev, "used for oneshot clock events\n");
246 timer8_clock_event_start(p, ONESHOT);
248 case CLOCK_EVT_MODE_SHUTDOWN:
249 case CLOCK_EVT_MODE_UNUSED:
257 static int timer8_clock_event_next(unsigned long delta,
258 struct clock_event_device *ced)
260 struct timer8_priv *p = ced_to_priv(ced);
262 BUG_ON(ced->mode != CLOCK_EVT_MODE_ONESHOT);
263 timer8_set_next(p, delta - 1);
270 static int __init timer8_setup(struct timer8_priv *p,
271 struct platform_device *pdev)
273 struct h8300_timer8_config *cfg = dev_get_platdata(&pdev->dev);
274 struct resource *res;
278 memset(p, 0, sizeof(*p));
281 res = platform_get_resource(p->pdev, IORESOURCE_MEM, 0);
283 dev_err(&p->pdev->dev, "failed to get I/O memory\n");
287 irq[CMI] = platform_get_irq(p->pdev, CMI);
288 irq[OVI] = platform_get_irq(p->pdev, OVI);
289 if (irq[CMI] < 0 || irq[OVI] < 0) {
290 dev_err(&p->pdev->dev, "failed to get irq\n");
294 p->mapbase = res->start;
296 p->irqaction.name = dev_name(&p->pdev->dev);
297 p->irqaction.handler = timer8_interrupt;
298 p->irqaction.dev_id = p;
299 p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER;
304 case H8300_TMR8_CLKSRC:
305 p->clk.cs.name = pdev->name;
306 p->clk.cs.rating = cfg->rating;
307 p->clk.cs.read = timer8_clocksource_read;
308 p->clk.cs.enable = timer8_clocksource_enable;
309 p->clk.cs.disable = timer8_clocksource_disable;
310 p->clk.cs.mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8);
311 p->clk.cs.flags = CLOCK_SOURCE_IS_CONTINUOUS;
313 ret = setup_irq(irq[OVI], &p->irqaction);
315 dev_err(&p->pdev->dev,
316 "failed to request irq %d\n", irq[OVI]);
319 clocksource_register_hz(&p->clk.cs,
320 get_cpu_clock() / div_rate[p->div]);
322 case H8300_TMR8_CLKEVTDEV:
323 p->clk.ced.name = pdev->name;
324 p->clk.ced.features = CLOCK_EVT_FEAT_PERIODIC |
325 CLOCK_EVT_FEAT_ONESHOT;
326 p->clk.ced.rating = cfg->rating;
327 p->clk.ced.cpumask = cpumask_of(0);
328 p->clk.ced.set_next_event = timer8_clock_event_next;
329 p->clk.ced.set_mode = timer8_clock_event_mode;
331 ret = setup_irq(irq[CMI], &p->irqaction);
333 dev_err(&p->pdev->dev,
334 "failed to request irq %d\n", irq[CMI]);
337 clockevents_register_device(&p->clk.ced);
340 platform_set_drvdata(pdev, p);
345 static int timer8_probe(struct platform_device *pdev)
347 struct timer8_priv *p = platform_get_drvdata(pdev);
350 dev_info(&pdev->dev, "kept as earlytimer\n");
354 p = kmalloc(sizeof(*p), GFP_KERNEL);
356 dev_err(&pdev->dev, "failed to allocate driver data"
361 return timer8_setup(p, pdev);
364 static int timer8_remove(struct platform_device *pdev)
369 static struct platform_driver timer8_driver = {
370 .probe = timer8_probe,
371 .remove = timer8_remove,
373 .name = "h8300-8timer",
377 static int __init timer8_init(void)
379 return platform_driver_register(&timer8_driver);
382 static void __exit timer8_exit(void)
384 platform_driver_unregister(&timer8_driver);
387 early_platform_init("earlytimer", &timer8_driver);
388 subsys_initcall(timer8_init);
389 module_exit(timer8_exit);
390 MODULE_AUTHOR("Yoshinori Sato");
391 MODULE_DESCRIPTION("H8/300 8bit Timer Driver");
392 MODULE_LICENSE("GPL v2");