56 return (upper << 16) | lower;
67 .read = tc_get_cycles,
72 #ifdef CONFIG_GENERIC_CLOCKEVENTS
74 struct tc_clkevt_device {
75 struct clock_event_device clkevt;
80 static struct tc_clkevt_device *to_tc_clkevt(
struct clock_event_device *clkevt)
82 return container_of(clkevt,
struct tc_clkevt_device, clkevt);
92 static u32 timer_clock;
94 static void tc_mode(
enum clock_event_mode
m,
struct clock_event_device *
d)
96 struct tc_clkevt_device *tcd = to_tc_clkevt(d);
99 if (tcd->clkevt.mode == CLOCK_EVT_MODE_PERIODIC
100 || tcd->clkevt.mode == CLOCK_EVT_MODE_ONESHOT) {
111 case CLOCK_EVT_MODE_PERIODIC:
128 case CLOCK_EVT_MODE_ONESHOT:
145 static int tc_next_event(
unsigned long delta,
struct clock_event_device *d)
155 static struct tc_clkevt_device clkevt = {
158 .features = CLOCK_EVT_FEAT_PERIODIC
159 | CLOCK_EVT_FEAT_ONESHOT,
163 .set_next_event = tc_next_event,
175 dev->clkevt.event_handler(&dev->clkevt);
188 static void __init setup_clkevents(
struct atmel_tc *
tc,
int clk32k_divisor_idx)
190 struct clk *t2_clk = tc->
clk[2];
191 int irq = tc->
irq[2];
193 clkevt.regs = tc->
regs;
195 tc_irqaction.
dev_id = &clkevt;
197 timer_clock = clk32k_divisor_idx;
199 clkevt.clkevt.mult = div_sc(32768,
NSEC_PER_SEC, clkevt.clkevt.shift);
200 clkevt.clkevt.max_delta_ns
212 static void __init setup_clkevents(
struct atmel_tc *
tc,
int clk32k_divisor_idx)
219 static void __init tcb_setup_dual_chan(
struct atmel_tc *
tc,
int mck_divisor_idx)
247 static void __init tcb_setup_single_chan(
struct atmel_tc *tc,
int mck_divisor_idx)
261 static int __init tcb_clksrc_init(
void)
270 int best_divisor_idx = -1;
271 int clk32k_divisor_idx = -1;
276 pr_debug(
"can't alloc TC for clocksource\n");
287 for (i = 0; i < 5; i++) {
293 clk32k_divisor_idx =
i;
298 pr_debug(
"TC: %u / %-3u [%d] --> %u\n", rate, divisor, i, tmp);
299 if (best_divisor_idx > 0) {
300 if (tmp < 5 * 1000 * 1000)
304 best_divisor_idx =
i;
308 printk(bootinfo, clksrc.
name, CONFIG_ATMEL_TCB_CLKSRC_BLOCK,
309 divided_rate / 1000000,
310 ((divided_rate + 500000) % 1000000) / 1000);
314 clksrc.
read = tc_get_cycles32;
316 tcb_setup_single_chan(tc, best_divisor_idx);
323 tcb_setup_dual_chan(tc, best_divisor_idx);
327 clocksource_register_hz(&clksrc, divided_rate);
330 setup_clkevents(tc, clk32k_divisor_idx);