xref: /linux/arch/arm/mach-footbridge/isa-timer.c (revision 74d83b7eedab14e4b963a2220ff76f98fa6d4cb8)
1 /*
2  *  linux/arch/arm/mach-footbridge/isa-timer.c
3  *
4  *  Copyright (C) 1998 Russell King.
5  *  Copyright (C) 1998 Phil Blundell
6  */
7 #include <linux/clockchips.h>
8 #include <linux/clocksource.h>
9 #include <linux/init.h>
10 #include <linux/interrupt.h>
11 #include <linux/irq.h>
12 #include <linux/io.h>
13 #include <linux/spinlock.h>
14 #include <linux/timex.h>
15 
16 #include <asm/irq.h>
17 #include <asm/i8253.h>
18 #include <asm/mach/time.h>
19 
20 #include "common.h"
21 
22 DEFINE_RAW_SPINLOCK(i8253_lock);
23 
24 static void pit_set_mode(enum clock_event_mode mode,
25 	struct clock_event_device *evt)
26 {
27 	unsigned long flags;
28 
29 	raw_local_irq_save(flags);
30 
31 	switch (mode) {
32 	case CLOCK_EVT_MODE_PERIODIC:
33 		outb_p(0x34, PIT_MODE);
34 		outb_p(PIT_LATCH & 0xff, PIT_CH0);
35 		outb_p(PIT_LATCH >> 8, PIT_CH0);
36 		break;
37 
38 	case CLOCK_EVT_MODE_SHUTDOWN:
39 	case CLOCK_EVT_MODE_UNUSED:
40 		outb_p(0x30, PIT_MODE);
41 		outb_p(0, PIT_CH0);
42 		outb_p(0, PIT_CH0);
43 		break;
44 
45 	case CLOCK_EVT_MODE_ONESHOT:
46 	case CLOCK_EVT_MODE_RESUME:
47 		break;
48 	}
49 	local_irq_restore(flags);
50 }
51 
52 static int pit_set_next_event(unsigned long delta,
53 	struct clock_event_device *evt)
54 {
55 	return 0;
56 }
57 
58 static struct clock_event_device pit_ce = {
59 	.name		= "pit",
60 	.features	= CLOCK_EVT_FEAT_PERIODIC,
61 	.set_mode	= pit_set_mode,
62 	.set_next_event	= pit_set_next_event,
63 	.shift		= 32,
64 };
65 
66 static irqreturn_t pit_timer_interrupt(int irq, void *dev_id)
67 {
68 	struct clock_event_device *ce = dev_id;
69 	ce->event_handler(ce);
70 	return IRQ_HANDLED;
71 }
72 
73 static struct irqaction pit_timer_irq = {
74 	.name		= "pit",
75 	.handler	= pit_timer_interrupt,
76 	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
77 	.dev_id		= &pit_ce,
78 };
79 
80 static void __init isa_timer_init(void)
81 {
82 	pit_ce.cpumask = cpumask_of(smp_processor_id());
83 	pit_ce.mult = div_sc(PIT_TICK_RATE, NSEC_PER_SEC, pit_ce.shift);
84 	pit_ce.max_delta_ns = clockevent_delta2ns(0x7fff, &pit_ce);
85 	pit_ce.min_delta_ns = clockevent_delta2ns(0x000f, &pit_ce);
86 
87 	clocksource_i8253_init();
88 
89 	setup_irq(pit_ce.irq, &pit_timer_irq);
90 	clockevents_register_device(&pit_ce);
91 }
92 
93 struct sys_timer isa_timer = {
94 	.init		= isa_timer_init,
95 };
96