1 // SPDX-License-Identifier: GPL-2.0
3 * linux/arch/h8300/kernel/cpu/timer/timer8.c
5 * Yoshinori Sato <ysato@users.sourcefoge.jp>
11 #include <linux/errno.h>
12 #include <linux/kernel.h>
13 #include <linux/interrupt.h>
14 #include <linux/init.h>
15 #include <linux/clockchips.h>
16 #include <linux/clk.h>
19 #include <linux/of_address.h>
20 #include <linux/of_irq.h>
31 #define FLAG_STARTED (1 << 3)
35 #define bset(b, a) iowrite8(ioread8(a) | (1 << (b)), (a))
36 #define bclr(b, a) iowrite8(ioread8(a) & ~(1 << (b)), (a))
39 struct clock_event_device ced
;
40 void __iomem
*mapbase
;
45 static irqreturn_t
timer8_interrupt(int irq
, void *dev_id
)
47 struct timer8_priv
*p
= dev_id
;
49 if (clockevent_state_oneshot(&p
->ced
))
50 iowrite16be(0x0000, p
->mapbase
+ _8TCR
);
52 p
->ced
.event_handler(&p
->ced
);
54 bclr(CMFA
, p
->mapbase
+ _8TCSR
);
59 static void timer8_set_next(struct timer8_priv
*p
, unsigned long delta
)
62 pr_warn("delta out of range\n");
63 bclr(CMIEA
, p
->mapbase
+ _8TCR
);
64 iowrite16be(delta
, p
->mapbase
+ TCORA
);
65 iowrite16be(0x0000, p
->mapbase
+ _8TCNT
);
66 bclr(CMFA
, p
->mapbase
+ _8TCSR
);
67 bset(CMIEA
, p
->mapbase
+ _8TCR
);
70 static int timer8_enable(struct timer8_priv
*p
)
72 iowrite16be(0xffff, p
->mapbase
+ TCORA
);
73 iowrite16be(0x0000, p
->mapbase
+ _8TCNT
);
74 iowrite16be(0x0c02, p
->mapbase
+ _8TCR
);
79 static int timer8_start(struct timer8_priv
*p
)
83 if ((p
->flags
& FLAG_STARTED
))
86 ret
= timer8_enable(p
);
88 p
->flags
|= FLAG_STARTED
;
93 static void timer8_stop(struct timer8_priv
*p
)
95 iowrite16be(0x0000, p
->mapbase
+ _8TCR
);
98 static inline struct timer8_priv
*ced_to_priv(struct clock_event_device
*ced
)
100 return container_of(ced
, struct timer8_priv
, ced
);
103 static void timer8_clock_event_start(struct timer8_priv
*p
, unsigned long delta
)
106 timer8_set_next(p
, delta
);
109 static int timer8_clock_event_shutdown(struct clock_event_device
*ced
)
111 timer8_stop(ced_to_priv(ced
));
115 static int timer8_clock_event_periodic(struct clock_event_device
*ced
)
117 struct timer8_priv
*p
= ced_to_priv(ced
);
119 pr_info("%s: used for periodic clock events\n", ced
->name
);
121 timer8_clock_event_start(p
, (p
->rate
+ HZ
/2) / HZ
);
126 static int timer8_clock_event_oneshot(struct clock_event_device
*ced
)
128 struct timer8_priv
*p
= ced_to_priv(ced
);
130 pr_info("%s: used for oneshot clock events\n", ced
->name
);
132 timer8_clock_event_start(p
, 0x10000);
137 static int timer8_clock_event_next(unsigned long delta
,
138 struct clock_event_device
*ced
)
140 struct timer8_priv
*p
= ced_to_priv(ced
);
142 BUG_ON(!clockevent_state_oneshot(ced
));
143 timer8_set_next(p
, delta
- 1);
148 static struct timer8_priv timer8_priv
= {
150 .name
= "h8300_8timer",
151 .features
= CLOCK_EVT_FEAT_PERIODIC
| CLOCK_EVT_FEAT_ONESHOT
,
153 .set_next_event
= timer8_clock_event_next
,
154 .set_state_shutdown
= timer8_clock_event_shutdown
,
155 .set_state_periodic
= timer8_clock_event_periodic
,
156 .set_state_oneshot
= timer8_clock_event_oneshot
,
160 static int __init
h8300_8timer_init(struct device_node
*node
)
166 clk
= of_clk_get(node
, 0);
168 pr_err("failed to get clock for clockevent\n");
173 base
= of_iomap(node
, 0);
175 pr_err("failed to map registers for clockevent\n");
180 irq
= irq_of_parse_and_map(node
, 0);
182 pr_err("failed to get irq for clockevent\n");
186 timer8_priv
.mapbase
= base
;
188 timer8_priv
.rate
= clk_get_rate(clk
) / SCALE
;
189 if (!timer8_priv
.rate
) {
190 pr_err("Failed to get rate for the clocksource\n");
194 if (request_irq(irq
, timer8_interrupt
, IRQF_TIMER
,
195 timer8_priv
.ced
.name
, &timer8_priv
) < 0) {
196 pr_err("failed to request irq %d for clockevent\n", irq
);
200 clockevents_config_and_register(&timer8_priv
.ced
,
201 timer8_priv
.rate
, 1, 0x0000ffff);
211 TIMER_OF_DECLARE(h8300_8bit
, "renesas,8bit-timer", h8300_8timer_init
);