blob: a2ae5e9521378d6adbee4e01d39e7843819c305a [file] [log] [blame]
Yoshinori Satoe0b0f9e2008-10-15 22:01:16 -07001/*
2 * linux/arch/h8300/kernel/timer/itu.c
3 *
4 * Yoshinori Sato <ysato@users.sourcefoge.jp>
5 *
6 * ITU Timer Handler
7 *
8 */
9
10#include <linux/errno.h>
11#include <linux/sched.h>
12#include <linux/kernel.h>
13#include <linux/param.h>
14#include <linux/string.h>
15#include <linux/mm.h>
16#include <linux/interrupt.h>
17#include <linux/init.h>
18#include <linux/timex.h>
19
20#include <asm/segment.h>
21#include <asm/io.h>
22#include <asm/irq.h>
23#include <asm/regs306x.h>
24
25#if CONFIG_H8300_ITU_CH == 0
26#define ITUBASE 0xffff64
27#define ITUIRQ 24
28#elif CONFIG_H8300_ITU_CH == 1
29#define ITUBASE 0xffff6e
30#define ITUIRQ 28
31#elif CONFIG_H8300_ITU_CH == 2
32#define ITUBASE 0xffff78
33#define ITUIRQ 32
34#elif CONFIG_H8300_ITU_CH == 3
35#define ITUBASE 0xffff82
36#define ITUIRQ 36
37#elif CONFIG_H8300_ITU_CH == 4
38#define ITUBASE 0xffff92
39#define ITUIRQ 40
40#else
41#error Unknown timer channel.
42#endif
43
44#define TCR 0
45#define TIOR 1
46#define TIER 2
47#define TSR 3
48#define TCNT 4
49#define GRA 6
50#define GRB 8
51
52static irqreturn_t timer_interrupt(int irq, void *dev_id)
53{
54 h8300_timer_tick();
55 ctrl_bclr(IMFA, ITUBASE + TSR);
56 return IRQ_HANDLED;
57}
58
59static struct irqaction itu_irq = {
60 .name = "itu",
61 .handler = timer_interrupt,
62 .flags = IRQF_DISABLED | IRQF_TIMER,
Yoshinori Satoe0b0f9e2008-10-15 22:01:16 -070063};
64
65static const int __initdata divide_rate[] = {1, 2, 4, 8};
66
67void __init h8300_timer_setup(void)
68{
69 unsigned int div;
70 unsigned int cnt;
71
72 calc_param(cnt, div, divide_rate, 0x10000);
73
74 setup_irq(ITUIRQ, &itu_irq);
75
Uwe Kleine-König421f91d2010-06-11 12:17:00 +020076 /* initialize timer */
Yoshinori Satoe0b0f9e2008-10-15 22:01:16 -070077 ctrl_outb(0, TSTR);
78 ctrl_outb(CCLR0 | div, ITUBASE + TCR);
79 ctrl_outb(0x01, ITUBASE + TIER);
80 ctrl_outw(cnt, ITUBASE + GRA);
81 ctrl_bset(CONFIG_H8300_ITU_CH, TSTR);
82}