aboutsummaryrefslogtreecommitdiffstats
path: root/arch/m68knommu/platform/5307/timers.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/m68knommu/platform/5307/timers.c')
-rw-r--r--arch/m68knommu/platform/5307/timers.c49
1 files changed, 23 insertions, 26 deletions
diff --git a/arch/m68knommu/platform/5307/timers.c b/arch/m68knommu/platform/5307/timers.c
index ef49596aa09c..83b8b89dfa09 100644
--- a/arch/m68knommu/platform/5307/timers.c
+++ b/arch/m68knommu/platform/5307/timers.c
@@ -14,6 +14,7 @@
14#include <linux/param.h> 14#include <linux/param.h>
15#include <linux/interrupt.h> 15#include <linux/interrupt.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <asm/io.h>
17#include <asm/irq.h> 18#include <asm/irq.h>
18#include <asm/traps.h> 19#include <asm/traps.h>
19#include <asm/machdep.h> 20#include <asm/machdep.h>
@@ -24,6 +25,11 @@
24/***************************************************************************/ 25/***************************************************************************/
25 26
26/* 27/*
28 * By default use timer1 as the system clock timer.
29 */
30#define TA(a) (MCF_MBAR + MCFTIMER_BASE1 + (a))
31
32/*
27 * Default the timer and vector to use for ColdFire. Some ColdFire 33 * Default the timer and vector to use for ColdFire. Some ColdFire
28 * CPU's and some boards may want different. Their sub-architecture 34 * CPU's and some boards may want different. Their sub-architecture
29 * startup code (in config.c) can change these if they want. 35 * startup code (in config.c) can change these if they want.
@@ -32,8 +38,6 @@ unsigned int mcf_timervector = 29;
32unsigned int mcf_profilevector = 31; 38unsigned int mcf_profilevector = 31;
33unsigned int mcf_timerlevel = 5; 39unsigned int mcf_timerlevel = 5;
34 40
35static volatile struct mcftimer *mcf_timerp;
36
37/* 41/*
38 * These provide the underlying interrupt vector support. 42 * These provide the underlying interrupt vector support.
39 * Unfortunately it is a little different on each ColdFire. 43 * Unfortunately it is a little different on each ColdFire.
@@ -46,20 +50,17 @@ extern int mcf_timerirqpending(int timer);
46void coldfire_tick(void) 50void coldfire_tick(void)
47{ 51{
48 /* Reset the ColdFire timer */ 52 /* Reset the ColdFire timer */
49 mcf_timerp->ter = MCFTIMER_TER_CAP | MCFTIMER_TER_REF; 53 __raw_writeb(MCFTIMER_TER_CAP | MCFTIMER_TER_REF, TA(MCFTIMER_TER));
50} 54}
51 55
52/***************************************************************************/ 56/***************************************************************************/
53 57
54void coldfire_timer_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)) 58void coldfire_timer_init(irqreturn_t (*handler)(int, void *, struct pt_regs *))
55{ 59{
56 /* Set up an internal TIMER as poll clock */ 60 __raw_writew(MCFTIMER_TMR_DISABLE, TA(MCFTIMER_TMR));
57 mcf_timerp = (volatile struct mcftimer *) (MCF_MBAR + MCFTIMER_BASE1); 61 __raw_writew(((MCF_BUSCLK / 16) / HZ), TA(MCFTIMER_TRR));
58 mcf_timerp->tmr = MCFTIMER_TMR_DISABLE; 62 __raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
59 63 MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, TA(MCFTIMER_TMR));
60 mcf_timerp->trr = (unsigned short) ((MCF_BUSCLK / 16) / HZ);
61 mcf_timerp->tmr = MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
62 MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE;
63 64
64 request_irq(mcf_timervector, handler, SA_INTERRUPT, "timer", NULL); 65 request_irq(mcf_timervector, handler, SA_INTERRUPT, "timer", NULL);
65 mcf_settimericr(1, mcf_timerlevel); 66 mcf_settimericr(1, mcf_timerlevel);
@@ -75,13 +76,8 @@ unsigned long coldfire_timer_offset(void)
75{ 76{
76 unsigned long trr, tcn, offset; 77 unsigned long trr, tcn, offset;
77 78
78 /* 79 tcn = __raw_readw(TA(MCFTIMER_TCN));
79 * The change to pointer and de-reference is to force the compiler 80 trr = __raw_readw(TA(MCFTIMER_TRR));
80 * to read the registers with a single 16bit access. Otherwise it
81 * does some crazy 8bit read combining.
82 */
83 tcn = *(&mcf_timerp->tcn);
84 trr = *(&mcf_timerp->trr);
85 offset = (tcn * (1000000 / HZ)) / trr; 81 offset = (tcn * (1000000 / HZ)) / trr;
86 82
87 /* Check if we just wrapped the counters and maybe missed a tick */ 83 /* Check if we just wrapped the counters and maybe missed a tick */
@@ -95,21 +91,23 @@ unsigned long coldfire_timer_offset(void)
95/***************************************************************************/ 91/***************************************************************************/
96 92
97/* 93/*
94 * By default use timer2 as the profiler clock timer.
95 */
96#define PA(a) (MCF_MBAR + MCFTIMER_BASE2 + (a))
97
98/*
98 * Choose a reasonably fast profile timer. Make it an odd value to 99 * Choose a reasonably fast profile timer. Make it an odd value to
99 * try and get good coverage of kernal operations. 100 * try and get good coverage of kernal operations.
100 */ 101 */
101#define PROFILEHZ 1013 102#define PROFILEHZ 1013
102 103
103static volatile struct mcftimer *mcf_proftp;
104
105/* 104/*
106 * Use the other timer to provide high accuracy profiling info. 105 * Use the other timer to provide high accuracy profiling info.
107 */ 106 */
108
109void coldfire_profile_tick(int irq, void *dummy, struct pt_regs *regs) 107void coldfire_profile_tick(int irq, void *dummy, struct pt_regs *regs)
110{ 108{
111 /* Reset ColdFire timer2 */ 109 /* Reset ColdFire timer2 */
112 mcf_proftp->ter = MCFTIMER_TER_CAP | MCFTIMER_TER_REF; 110 __raw_writeb(MCFTIMER_TER_CAP | MCFTIMER_TER_REF, PA(MCFTIMER_TER));
113 if (current->pid) 111 if (current->pid)
114 profile_tick(CPU_PROFILING, regs); 112 profile_tick(CPU_PROFILING, regs);
115} 113}
@@ -121,12 +119,11 @@ void coldfire_profile_init(void)
121 printk(KERN_INFO "PROFILE: lodging TIMER2 @ %dHz as profile timer\n", PROFILEHZ); 119 printk(KERN_INFO "PROFILE: lodging TIMER2 @ %dHz as profile timer\n", PROFILEHZ);
122 120
123 /* Set up TIMER 2 as high speed profile clock */ 121 /* Set up TIMER 2 as high speed profile clock */
124 mcf_proftp = (volatile struct mcftimer *) (MCF_MBAR + MCFTIMER_BASE2); 122 __raw_writew(MCFTIMER_TMR_DISABLE, PA(MCFTIMER_TMR));
125 mcf_proftp->tmr = MCFTIMER_TMR_DISABLE;
126 123
127 mcf_proftp->trr = (unsigned short) ((MCF_CLK / 16) / PROFILEHZ); 124 __raw_writew(((MCF_CLK / 16) / PROFILEHZ), PA(MCFTIMER_TRR));
128 mcf_proftp->tmr = MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 | 125 __raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
129 MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE; 126 MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, PA(MCFTIMER_TMR));
130 127
131 request_irq(mcf_profilevector, coldfire_profile_tick, 128 request_irq(mcf_profilevector, coldfire_profile_tick,
132 (SA_INTERRUPT | IRQ_FLG_FAST), "profile timer", NULL); 129 (SA_INTERRUPT | IRQ_FLG_FAST), "profile timer", NULL);