diff options
| author | Greg Ungerer <gerg@snapgear.com> | 2003-05-25 07:37:05 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.transmeta.com> | 2003-05-25 07:37:05 -0700 |
| commit | b20143587149d5243ee4f17d2c8099a5d31fe1b6 (patch) | |
| tree | 57ccec13473d333c97c0a2f34422b12cddf6e47b | |
| parent | 572a7a8b9f2e42448d0b56202d8f86936aa821c3 (diff) | |
[PATCH] add pit timer for m68knommu/5282 CPU support
This code supports the PIT timer of the 5282 ColdFire.
This new timer device is completely different to the previous ColdFire
timer device.
| -rw-r--r-- | arch/m68knommu/platform/5282/pit.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/arch/m68knommu/platform/5282/pit.c b/arch/m68knommu/platform/5282/pit.c new file mode 100644 index 000000000000..d3bbca3fe1e9 --- /dev/null +++ b/arch/m68knommu/platform/5282/pit.c @@ -0,0 +1,86 @@ +/***************************************************************************/ + +/* + * pit.c -- Motorola ColdFire PIT timer. Currently this type of + * hardware timer only exists in the Motorola ColdFire + * 5282 CPU. + * + * Copyright (C) 1999-2003, Greg Ungerer (gerg@snapgear.com) + * Copyright (C) 2001-2003, SnapGear Inc. (www.snapgear.com) + * + */ + +/***************************************************************************/ + +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/param.h> +#include <linux/init.h> +#include <asm/irq.h> +#include <asm/coldfire.h> +#include <asm/mcfpit.h> +#include <asm/mcfsim.h> + +/***************************************************************************/ + +void coldfire_pit_tick(void) +{ + volatile struct mcfpit *tp; + + /* Reset the ColdFire timer */ + tp = (volatile struct mcfpit *) (MCF_IPSBAR + MCFPIT_BASE1); + tp->pcsr |= MCFPIT_PCSR_PIF; +} + +/***************************************************************************/ + +void coldfire_pit_init(void (*handler)(int, void *, struct pt_regs *)) +{ + volatile unsigned char *icrp; + volatile unsigned long *imrp; + volatile struct mcfpit *tp; + + request_irq(64+55, handler, SA_INTERRUPT, "ColdFire Timer", NULL); + + icrp = (volatile unsigned char *) (MCF_IPSBAR + MCFICM_INTC0 + + MCFINTC_ICR0 + MCFINT_PIT1); + *icrp = 0x2b; /* PIT1 with level 5, priority 3 */ + + imrp = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH); + *imrp &= ~(1 << (55 - 32)); + + /* Set up PIT timer 1 as poll clock */ + tp = (volatile struct mcfpit *) (MCF_IPSBAR + MCFPIT_BASE1); + tp->pcsr = MCFPIT_PCSR_DISABLE; + + tp->pmr = ((MCF_CLK / 2) / 64) / HZ; + tp->pcsr = MCFPIT_PCSR_EN | MCFPIT_PCSR_PIE | MCFPIT_PCSR_OVW | + MCFPIT_PCSR_RLD | MCFPIT_PCSR_CLK64; +} + +/***************************************************************************/ + +unsigned long coldfire_pit_offset(void) +{ + volatile struct mcfpit *tp; + volatile unsigned long *ipr; + unsigned long pmr, pcntr, offset; + + tp = (volatile struct mcfpit *) (MCF_IPSBAR + MCFPIT_BASE1); + ipr = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IPRH); + + pmr = tp->pmr; + pcntr = tp->pcntr; + + /* + * If we are still in the first half of the upcount and a + * timer interupt is pending, then add on a ticks worth of time. + */ + offset = ((pcntr * (1000000 / HZ)) / pmr); + if ((offset < (1000000 / HZ / 2)) && (*ipr & (1 << (55 - 32)))) + offset += 1000000 / HZ; + return offset; +} + +/***************************************************************************/ |
