2 * linux/arch/arm/mach-footbridge/isa-timer.c
4 * Copyright (C) 1998 Russell King.
5 * Copyright (C) 1998 Phil Blundell
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>
13 #include <linux/spinlock.h>
14 #include <linux/timex.h>
17 #include <asm/i8253.h>
18 #include <asm/mach/time.h>
22 DEFINE_RAW_SPINLOCK(i8253_lock
);
24 static void pit_set_mode(enum clock_event_mode mode
,
25 struct clock_event_device
*evt
)
29 raw_local_irq_save(flags
);
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
);
38 case CLOCK_EVT_MODE_SHUTDOWN
:
39 case CLOCK_EVT_MODE_UNUSED
:
40 outb_p(0x30, PIT_MODE
);
45 case CLOCK_EVT_MODE_ONESHOT
:
46 case CLOCK_EVT_MODE_RESUME
:
49 local_irq_restore(flags
);
52 static int pit_set_next_event(unsigned long delta
,
53 struct clock_event_device
*evt
)
58 static struct clock_event_device pit_ce
= {
60 .features
= CLOCK_EVT_FEAT_PERIODIC
,
61 .set_mode
= pit_set_mode
,
62 .set_next_event
= pit_set_next_event
,
66 static irqreturn_t
pit_timer_interrupt(int irq
, void *dev_id
)
68 struct clock_event_device
*ce
= dev_id
;
69 ce
->event_handler(ce
);
73 static struct irqaction pit_timer_irq
= {
75 .handler
= pit_timer_interrupt
,
76 .flags
= IRQF_DISABLED
| IRQF_TIMER
| IRQF_IRQPOLL
,
80 static void __init
isa_timer_init(void)
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
);
87 clocksource_i8253_init();
89 setup_irq(pit_ce
.irq
, &pit_timer_irq
);
90 clockevents_register_device(&pit_ce
);
93 struct sys_timer isa_timer
= {
94 .init
= isa_timer_init
,