diff options
Diffstat (limited to 'arch/m68knommu/platform/5307/pit.c')
-rw-r--r-- | arch/m68knommu/platform/5307/pit.c | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/arch/m68knommu/platform/5307/pit.c b/arch/m68knommu/platform/5307/pit.c new file mode 100644 index 000000000000..a9b2c2e7e280 --- /dev/null +++ b/arch/m68knommu/platform/5307/pit.c | |||
@@ -0,0 +1,88 @@ | |||
1 | /***************************************************************************/ | ||
2 | |||
3 | /* | ||
4 | * pit.c -- Motorola ColdFire PIT timer. Currently this type of | ||
5 | * hardware timer only exists in the Motorola ColdFire | ||
6 | * 5270/5271 and 5282 CPUs. | ||
7 | * | ||
8 | * Copyright (C) 1999-2004, Greg Ungerer (gerg@snapgear.com) | ||
9 | * Copyright (C) 2001-2004, SnapGear Inc. (www.snapgear.com) | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | /***************************************************************************/ | ||
14 | |||
15 | #include <linux/config.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/sched.h> | ||
18 | #include <linux/param.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <asm/irq.h> | ||
22 | #include <asm/coldfire.h> | ||
23 | #include <asm/mcfpit.h> | ||
24 | #include <asm/mcfsim.h> | ||
25 | |||
26 | /***************************************************************************/ | ||
27 | |||
28 | void coldfire_pit_tick(void) | ||
29 | { | ||
30 | volatile struct mcfpit *tp; | ||
31 | |||
32 | /* Reset the ColdFire timer */ | ||
33 | tp = (volatile struct mcfpit *) (MCF_IPSBAR + MCFPIT_BASE1); | ||
34 | tp->pcsr |= MCFPIT_PCSR_PIF; | ||
35 | } | ||
36 | |||
37 | /***************************************************************************/ | ||
38 | |||
39 | void coldfire_pit_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)) | ||
40 | { | ||
41 | volatile unsigned char *icrp; | ||
42 | volatile unsigned long *imrp; | ||
43 | volatile struct mcfpit *tp; | ||
44 | |||
45 | request_irq(MCFINT_VECBASE + MCFINT_PIT1, handler, SA_INTERRUPT, | ||
46 | "ColdFire Timer", NULL); | ||
47 | |||
48 | icrp = (volatile unsigned char *) (MCF_IPSBAR + MCFICM_INTC0 + | ||
49 | MCFINTC_ICR0 + MCFINT_PIT1); | ||
50 | *icrp = 0x2b; /* PIT1 with level 5, priority 3 */ | ||
51 | |||
52 | imrp = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH); | ||
53 | *imrp &= ~(1 << (MCFINT_PIT1 - 32)); | ||
54 | |||
55 | /* Set up PIT timer 1 as poll clock */ | ||
56 | tp = (volatile struct mcfpit *) (MCF_IPSBAR + MCFPIT_BASE1); | ||
57 | tp->pcsr = MCFPIT_PCSR_DISABLE; | ||
58 | |||
59 | tp->pmr = ((MCF_CLK / 2) / 64) / HZ; | ||
60 | tp->pcsr = MCFPIT_PCSR_EN | MCFPIT_PCSR_PIE | MCFPIT_PCSR_OVW | | ||
61 | MCFPIT_PCSR_RLD | MCFPIT_PCSR_CLK64; | ||
62 | } | ||
63 | |||
64 | /***************************************************************************/ | ||
65 | |||
66 | unsigned long coldfire_pit_offset(void) | ||
67 | { | ||
68 | volatile struct mcfpit *tp; | ||
69 | volatile unsigned long *ipr; | ||
70 | unsigned long pmr, pcntr, offset; | ||
71 | |||
72 | tp = (volatile struct mcfpit *) (MCF_IPSBAR + MCFPIT_BASE1); | ||
73 | ipr = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IPRH); | ||
74 | |||
75 | pmr = *(&tp->pmr); | ||
76 | pcntr = *(&tp->pcntr); | ||
77 | |||
78 | /* | ||
79 | * If we are still in the first half of the upcount and a | ||
80 | * timer interupt is pending, then add on a ticks worth of time. | ||
81 | */ | ||
82 | offset = ((pmr - pcntr) * (1000000 / HZ)) / pmr; | ||
83 | if ((offset < (1000000 / HZ / 2)) && (*ipr & (1 << (MCFINT_PIT1 - 32)))) | ||
84 | offset += 1000000 / HZ; | ||
85 | return offset; | ||
86 | } | ||
87 | |||
88 | /***************************************************************************/ | ||