diff options
author | Greg Ungerer <gerg@snapgear.com> | 2006-06-25 20:33:10 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-25 20:43:33 -0400 |
commit | 0b7ac8e479f311f8ef15fbea3f849dded9f3ccd9 (patch) | |
tree | d84b81667b7db390d704137b40903e5079f05e53 | |
parent | c88b36e2c828c78c51e90002351f9d9068b75dec (diff) |
[PATCH] m68knommu: read/write register access for ColdFire core timer
Modify the m68knommu/ColdFire core timer code to use register offsets
with raw_read/raw_write access, instead of a mapped struct.
Signed-off-by: Greg Ungerer <gerg@uclinux.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | arch/m68knommu/platform/5307/timers.c | 49 | ||||
-rw-r--r-- | include/asm-m68knommu/mcftimer.h | 30 |
2 files changed, 36 insertions, 43 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; | |||
32 | unsigned int mcf_profilevector = 31; | 38 | unsigned int mcf_profilevector = 31; |
33 | unsigned int mcf_timerlevel = 5; | 39 | unsigned int mcf_timerlevel = 5; |
34 | 40 | ||
35 | static 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); | |||
46 | void coldfire_tick(void) | 50 | void 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 | ||
54 | void coldfire_timer_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)) | 58 | void 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 | ||
103 | static 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 | |||
109 | void coldfire_profile_tick(int irq, void *dummy, struct pt_regs *regs) | 107 | void 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); |
diff --git a/include/asm-m68knommu/mcftimer.h b/include/asm-m68knommu/mcftimer.h index 68bf33ac10d1..6f4d796e03db 100644 --- a/include/asm-m68knommu/mcftimer.h +++ b/include/asm-m68knommu/mcftimer.h | |||
@@ -3,7 +3,7 @@ | |||
3 | /* | 3 | /* |
4 | * mcftimer.h -- ColdFire internal TIMER support defines. | 4 | * mcftimer.h -- ColdFire internal TIMER support defines. |
5 | * | 5 | * |
6 | * (C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com) | 6 | * (C) Copyright 1999-2006, Greg Ungerer <gerg@snapgear.com> |
7 | * (C) Copyright 2000, Lineo Inc. (www.lineo.com) | 7 | * (C) Copyright 2000, Lineo Inc. (www.lineo.com) |
8 | */ | 8 | */ |
9 | 9 | ||
@@ -27,6 +27,11 @@ | |||
27 | #elif defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407) | 27 | #elif defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407) |
28 | #define MCFTIMER_BASE1 0x140 /* Base address of TIMER1 */ | 28 | #define MCFTIMER_BASE1 0x140 /* Base address of TIMER1 */ |
29 | #define MCFTIMER_BASE2 0x180 /* Base address of TIMER2 */ | 29 | #define MCFTIMER_BASE2 0x180 /* Base address of TIMER2 */ |
30 | #elif defined(CONFIG_M532x) | ||
31 | #define MCFTIMER_BASE1 0xfc070000 /* Base address of TIMER1 */ | ||
32 | #define MCFTIMER_BASE2 0xfc074000 /* Base address of TIMER2 */ | ||
33 | #define MCFTIMER_BASE3 0xfc078000 /* Base address of TIMER3 */ | ||
34 | #define MCFTIMER_BASE4 0xfc07c000 /* Base address of TIMER4 */ | ||
30 | #endif | 35 | #endif |
31 | 36 | ||
32 | 37 | ||
@@ -34,23 +39,14 @@ | |||
34 | * Define the TIMER register set addresses. | 39 | * Define the TIMER register set addresses. |
35 | */ | 40 | */ |
36 | #define MCFTIMER_TMR 0x00 /* Timer Mode reg (r/w) */ | 41 | #define MCFTIMER_TMR 0x00 /* Timer Mode reg (r/w) */ |
37 | #define MCFTIMER_TRR 0x02 /* Timer Reference (r/w) */ | 42 | #define MCFTIMER_TRR 0x04 /* Timer Reference (r/w) */ |
38 | #define MCFTIMER_TCR 0x04 /* Timer Capture reg (r/w) */ | 43 | #define MCFTIMER_TCR 0x08 /* Timer Capture reg (r/w) */ |
39 | #define MCFTIMER_TCN 0x06 /* Timer Counter reg (r/w) */ | 44 | #define MCFTIMER_TCN 0x0C /* Timer Counter reg (r/w) */ |
45 | #if defined(CONFIG_M532x) | ||
46 | #define MCFTIMER_TER 0x03 /* Timer Event reg (r/w) */ | ||
47 | #else | ||
40 | #define MCFTIMER_TER 0x11 /* Timer Event reg (r/w) */ | 48 | #define MCFTIMER_TER 0x11 /* Timer Event reg (r/w) */ |
41 | 49 | #endif | |
42 | struct mcftimer { | ||
43 | unsigned short tmr; /* Timer Mode reg (r/w) */ | ||
44 | unsigned short reserved1; | ||
45 | unsigned short trr; /* Timer Reference (r/w) */ | ||
46 | unsigned short reserved2; | ||
47 | unsigned short tcr; /* Timer Capture reg (r/w) */ | ||
48 | unsigned short reserved3; | ||
49 | unsigned short tcn; /* Timer Counter reg (r/w) */ | ||
50 | unsigned short reserved4; | ||
51 | unsigned char reserved5; | ||
52 | unsigned char ter; /* Timer Event reg (r/w) */ | ||
53 | } __attribute__((packed)); | ||
54 | 50 | ||
55 | /* | 51 | /* |
56 | * Bit definitions for the Timer Mode Register (TMR). | 52 | * Bit definitions for the Timer Mode Register (TMR). |