Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs...
[pandora-kernel.git] / arch / arm / mach-footbridge / isa-timer.c
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 };