aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/timers
diff options
context:
space:
mode:
authorMagnus Damm <damm@igel.co.jp>2009-04-30 00:09:26 -0400
committerPaul Mundt <lethal@linux-sh.org>2009-04-30 00:21:14 -0400
commitf425752fc66acf1d4e47970ea704ed7d31c14173 (patch)
tree84784c46f0cfa6ac555a499cce9826918ae0feba /arch/sh/kernel/timers
parent698aa99da5f5e2b4c666fd21ab77306f0225b8f5 (diff)
sh: remove old CMT driver
This patch removes the old CMT driver (CONFIG_SH_CMT/timer-cmt.c) As replacement, select the sh_cmt driver with CONFIG_SH_TIMER_CMT and configure timer channel using platform data. If multiple CMT channels are enabled using platform data, use the earlytimer parameter on the kernel command line to select channel. For instance, use "earlytimer=sh_cmt.0" to select the first channel. To verify which timer is being used, look at printouts or the timer irq count in /proc/interrupts. Signed-off-by: Magnus Damm <damm@igel.co.jp> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel/timers')
-rw-r--r--arch/sh/kernel/timers/Makefile1
-rw-r--r--arch/sh/kernel/timers/timer-cmt.c188
-rw-r--r--arch/sh/kernel/timers/timer.c3
3 files changed, 0 insertions, 192 deletions
diff --git a/arch/sh/kernel/timers/Makefile b/arch/sh/kernel/timers/Makefile
index 0b7f8577193f..1e9a104c2aee 100644
--- a/arch/sh/kernel/timers/Makefile
+++ b/arch/sh/kernel/timers/Makefile
@@ -6,6 +6,5 @@ obj-y := timer.o
6 6
7obj-$(CONFIG_SH_TMU) += timer-tmu.o 7obj-$(CONFIG_SH_TMU) += timer-tmu.o
8obj-$(CONFIG_SH_MTU2) += timer-mtu2.o 8obj-$(CONFIG_SH_MTU2) += timer-mtu2.o
9obj-$(CONFIG_SH_CMT) += timer-cmt.o
10 9
11obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += timer-broadcast.o 10obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += timer-broadcast.o
diff --git a/arch/sh/kernel/timers/timer-cmt.c b/arch/sh/kernel/timers/timer-cmt.c
deleted file mode 100644
index 9aa348658ae3..000000000000
--- a/arch/sh/kernel/timers/timer-cmt.c
+++ /dev/null
@@ -1,188 +0,0 @@
1/*
2 * arch/sh/kernel/timers/timer-cmt.c - CMT Timer Support
3 *
4 * Copyright (C) 2005 Yoshinori Sato
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10
11#include <linux/init.h>
12#include <linux/kernel.h>
13#include <linux/interrupt.h>
14#include <linux/seqlock.h>
15#include <asm/timer.h>
16#include <asm/rtc.h>
17#include <asm/io.h>
18#include <asm/irq.h>
19#include <asm/clock.h>
20
21#if defined(CONFIG_CPU_SUBTYPE_SH7619)
22#define CMT_CMSTR 0xf84a0070
23#define CMT_CMCSR_0 0xf84a0072
24#define CMT_CMCNT_0 0xf84a0074
25#define CMT_CMCOR_0 0xf84a0076
26#define CMT_CMCSR_1 0xf84a0078
27#define CMT_CMCNT_1 0xf84a007a
28#define CMT_CMCOR_1 0xf84a007c
29
30#define STBCR3 0xf80a0000
31#define cmt_clock_enable() do { ctrl_outb(ctrl_inb(STBCR3) & ~0x10, STBCR3); } while(0)
32#define CMT_CMCSR_INIT 0x0040
33#define CMT_CMCSR_CALIB 0x0000
34#elif defined(CONFIG_CPU_SUBTYPE_SH7203) || \
35 defined(CONFIG_CPU_SUBTYPE_SH7206) || \
36 defined(CONFIG_CPU_SUBTYPE_SH7263)
37#define CMT_CMSTR 0xfffec000
38#define CMT_CMCSR_0 0xfffec002
39#define CMT_CMCNT_0 0xfffec004
40#define CMT_CMCOR_0 0xfffec006
41
42#define STBCR4 0xfffe040c
43#define cmt_clock_enable() do { ctrl_outb(ctrl_inb(STBCR4) & ~0x04, STBCR4); } while(0)
44#define CMT_CMCSR_INIT 0x0040
45#define CMT_CMCSR_CALIB 0x0000
46#else
47#error "Unknown CPU SUBTYPE"
48#endif
49
50static unsigned long cmt_timer_get_offset(void)
51{
52 int count;
53 static unsigned short count_p = 0xffff; /* for the first call after boot */
54 static unsigned long jiffies_p = 0;
55
56 /*
57 * cache volatile jiffies temporarily; we have IRQs turned off.
58 */
59 unsigned long jiffies_t;
60
61 /* timer count may underflow right here */
62 count = ctrl_inw(CMT_CMCOR_0);
63 count -= ctrl_inw(CMT_CMCNT_0);
64
65 jiffies_t = jiffies;
66
67 /*
68 * avoiding timer inconsistencies (they are rare, but they happen)...
69 * there is one kind of problem that must be avoided here:
70 * 1. the timer counter underflows
71 */
72
73 if (jiffies_t == jiffies_p) {
74 if (count > count_p) {
75 /* the nutcase */
76 if (ctrl_inw(CMT_CMCSR_0) & 0x80) { /* Check CMF bit */
77 count -= LATCH;
78 } else {
79 printk("%s (): hardware timer problem?\n",
80 __func__);
81 }
82 }
83 } else
84 jiffies_p = jiffies_t;
85
86 count_p = count;
87
88 count = ((LATCH-1) - count) * TICK_SIZE;
89 count = (count + LATCH/2) / LATCH;
90
91 return count;
92}
93
94static irqreturn_t cmt_timer_interrupt(int irq, void *dev_id)
95{
96 unsigned long timer_status;
97
98 /* Clear CMF bit */
99 timer_status = ctrl_inw(CMT_CMCSR_0);
100 timer_status &= ~0x80;
101 ctrl_outw(timer_status, CMT_CMCSR_0);
102
103 handle_timer_tick();
104
105 return IRQ_HANDLED;
106}
107
108static struct irqaction cmt_irq = {
109 .name = "timer",
110 .handler = cmt_timer_interrupt,
111 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
112};
113
114static void cmt_clk_init(struct clk *clk)
115{
116 u8 divisor = CMT_CMCSR_INIT & 0x3;
117 ctrl_inw(CMT_CMCSR_0);
118 ctrl_outw(CMT_CMCSR_INIT, CMT_CMCSR_0);
119 clk->parent = clk_get(NULL, "module_clk");
120 clk->rate = clk->parent->rate / (8 << (divisor << 1));
121}
122
123static void cmt_clk_recalc(struct clk *clk)
124{
125 u8 divisor = ctrl_inw(CMT_CMCSR_0) & 0x3;
126 clk->rate = clk->parent->rate / (8 << (divisor << 1));
127}
128
129static struct clk_ops cmt_clk_ops = {
130 .init = cmt_clk_init,
131 .recalc = cmt_clk_recalc,
132};
133
134static struct clk cmt0_clk = {
135 .name = "cmt0_clk",
136 .ops = &cmt_clk_ops,
137};
138
139static int cmt_timer_start(void)
140{
141 ctrl_outw(ctrl_inw(CMT_CMSTR) | 0x01, CMT_CMSTR);
142 return 0;
143}
144
145static int cmt_timer_stop(void)
146{
147 ctrl_outw(ctrl_inw(CMT_CMSTR) & ~0x01, CMT_CMSTR);
148 return 0;
149}
150
151static int cmt_timer_init(void)
152{
153 unsigned long interval;
154
155 cmt_clock_enable();
156
157 setup_irq(CONFIG_SH_TIMER_IRQ, &cmt_irq);
158
159 cmt0_clk.parent = clk_get(NULL, "module_clk");
160
161 cmt_timer_stop();
162
163 interval = cmt0_clk.parent->rate / 8 / HZ;
164 printk(KERN_INFO "Interval = %ld\n", interval);
165
166 ctrl_outw(interval, CMT_CMCOR_0);
167
168 clk_register(&cmt0_clk);
169 clk_enable(&cmt0_clk);
170
171 cmt_timer_start();
172
173 return 0;
174}
175
176static struct sys_timer_ops cmt_timer_ops = {
177 .init = cmt_timer_init,
178 .start = cmt_timer_start,
179 .stop = cmt_timer_stop,
180#ifndef CONFIG_GENERIC_TIME
181 .get_offset = cmt_timer_get_offset,
182#endif
183};
184
185struct sys_timer cmt_timer = {
186 .name = "cmt",
187 .ops = &cmt_timer_ops,
188};
diff --git a/arch/sh/kernel/timers/timer.c b/arch/sh/kernel/timers/timer.c
index 4e7e747d1b69..f3bd1413d568 100644
--- a/arch/sh/kernel/timers/timer.c
+++ b/arch/sh/kernel/timers/timer.c
@@ -20,9 +20,6 @@ static struct sys_timer *sys_timers[] = {
20#ifdef CONFIG_SH_MTU2 20#ifdef CONFIG_SH_MTU2
21 &mtu2_timer, 21 &mtu2_timer,
22#endif 22#endif
23#ifdef CONFIG_SH_CMT
24 &cmt_timer,
25#endif
26 NULL, 23 NULL,
27}; 24};
28 25