1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#undef DEBUG_TIMER
19
20#include <linux/errno.h>
21#include <linux/init.h>
22#include <linux/module.h>
23#include <linux/sched.h>
24#include <linux/kernel.h>
25#include <linux/param.h>
26#include <linux/string.h>
27#include <linux/mm.h>
28#include <linux/interrupt.h>
29#include <linux/profile.h>
30
31#include <asm/io.h>
32#include <asm/m32r.h>
33
34#include <asm/hw_irq.h>
35
36#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE)
37
38DEFINE_SPINLOCK(rtc_lock);
39
40#ifdef CONFIG_RTC_DRV_CMOS_MODULE
41EXPORT_SYMBOL(rtc_lock);
42#endif
43#endif
44
45#ifdef CONFIG_SMP
46extern void smp_local_timer_interrupt(void);
47#endif
48
49#define TICK_SIZE (tick_nsec / 1000)
50
51
52
53
54
55
56#define USECS_PER_JIFFY (1000000/HZ)
57
58static unsigned long latch;
59
60static u32 m32r_gettimeoffset(void)
61{
62 unsigned long elapsed_time = 0;
63
64#if defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_XNUX2) \
65 || defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_M32700) \
66 || defined(CONFIG_CHIP_OPSP) || defined(CONFIG_CHIP_M32104)
67#ifndef CONFIG_SMP
68
69 unsigned long count;
70
71
72 count = inl(M32R_MFT2CUT_PORTL);
73
74 if (inl(M32R_ICU_CR18_PORTL) & 0x00000100)
75 count = 0;
76
77 count = (latch - count) * TICK_SIZE;
78 elapsed_time = DIV_ROUND_CLOSEST(count, latch);
79
80
81#else
82 unsigned long count;
83 static unsigned long p_jiffies = -1;
84 static unsigned long p_count = 0;
85
86
87 count = inl(M32R_MFT2CUT_PORTL);
88
89 if (jiffies == p_jiffies && count > p_count)
90 count = 0;
91
92 p_jiffies = jiffies;
93 p_count = count;
94
95 count = (latch - count) * TICK_SIZE;
96 elapsed_time = DIV_ROUND_CLOSEST(count, latch);
97
98#endif
99#elif defined(CONFIG_CHIP_M32310)
100#warning do_gettimeoffse not implemented
101#else
102#error no chip configuration
103#endif
104
105 return elapsed_time * 1000;
106}
107
108
109
110
111
112static irqreturn_t timer_interrupt(int irq, void *dev_id)
113{
114#ifndef CONFIG_SMP
115 profile_tick(CPU_PROFILING);
116#endif
117 xtime_update(1);
118
119#ifndef CONFIG_SMP
120 update_process_times(user_mode(get_irq_regs()));
121#endif
122
123
124
125
126
127#ifdef CONFIG_SMP
128 smp_local_timer_interrupt();
129 smp_send_timer();
130#endif
131
132 return IRQ_HANDLED;
133}
134
135static struct irqaction irq0 = {
136 .handler = timer_interrupt,
137 .name = "MFT2",
138};
139
140void read_persistent_clock(struct timespec *ts)
141{
142 unsigned int epoch, year, mon, day, hour, min, sec;
143
144 sec = min = hour = day = mon = year = 0;
145 epoch = 0;
146
147 year = 23;
148 mon = 4;
149 day = 17;
150
151
152
153
154 if (year > 10 && year < 44)
155 epoch = 1980;
156 else if (year < 96)
157 epoch = 1952;
158 year += epoch;
159
160 ts->tv_sec = mktime(year, mon, day, hour, min, sec);
161 ts->tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
162}
163
164
165void __init time_init(void)
166{
167 arch_gettimeoffset = m32r_gettimeoffset;
168
169#if defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_XNUX2) \
170 || defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_M32700) \
171 || defined(CONFIG_CHIP_OPSP) || defined(CONFIG_CHIP_M32104)
172
173
174 setup_irq(M32R_IRQ_MFT2, &irq0);
175 {
176 unsigned long bus_clock;
177 unsigned short divide;
178
179 bus_clock = boot_cpu_data.bus_clock;
180 divide = boot_cpu_data.timer_divide;
181 latch = DIV_ROUND_CLOSEST(bus_clock/divide, HZ);
182
183 printk("Timer start : latch = %ld\n", latch);
184
185 outl((M32R_MFTMOD_CC_MASK | M32R_MFTMOD_TCCR \
186 |M32R_MFTMOD_CSSEL011), M32R_MFT2MOD_PORTL);
187 outl(latch, M32R_MFT2RLD_PORTL);
188 outl(latch, M32R_MFT2CUT_PORTL);
189 outl(0, M32R_MFT2CMPRLD_PORTL);
190 outl((M32R_MFTCR_MFT2MSK|M32R_MFTCR_MFT2EN), M32R_MFTCR_PORTL);
191 }
192
193#elif defined(CONFIG_CHIP_M32310)
194#warning time_init not implemented
195#else
196#error no chip configuration
197#endif
198}
199