diff options
Diffstat (limited to 'drivers/rtc/rtc-sa1100.c')
-rw-r--r-- | drivers/rtc/rtc-sa1100.c | 187 |
1 files changed, 66 insertions, 121 deletions
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c index e4a44b641702..0b40bb88a884 100644 --- a/drivers/rtc/rtc-sa1100.c +++ b/drivers/rtc/rtc-sa1100.c | |||
@@ -39,11 +39,10 @@ | |||
39 | #include <mach/regs-ost.h> | 39 | #include <mach/regs-ost.h> |
40 | #endif | 40 | #endif |
41 | 41 | ||
42 | #define RTC_DEF_DIVIDER 32768 - 1 | 42 | #define RTC_DEF_DIVIDER (32768 - 1) |
43 | #define RTC_DEF_TRIM 0 | 43 | #define RTC_DEF_TRIM 0 |
44 | 44 | ||
45 | static unsigned long rtc_freq = 1024; | 45 | static const unsigned long RTC_FREQ = 1024; |
46 | static unsigned long timer_freq; | ||
47 | static struct rtc_time rtc_alarm; | 46 | static struct rtc_time rtc_alarm; |
48 | static DEFINE_SPINLOCK(sa1100_rtc_lock); | 47 | static DEFINE_SPINLOCK(sa1100_rtc_lock); |
49 | 48 | ||
@@ -61,7 +60,8 @@ static inline int rtc_periodic_alarm(struct rtc_time *tm) | |||
61 | * Calculate the next alarm time given the requested alarm time mask | 60 | * Calculate the next alarm time given the requested alarm time mask |
62 | * and the current time. | 61 | * and the current time. |
63 | */ | 62 | */ |
64 | static void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, struct rtc_time *alrm) | 63 | static void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, |
64 | struct rtc_time *alrm) | ||
65 | { | 65 | { |
66 | unsigned long next_time; | 66 | unsigned long next_time; |
67 | unsigned long now_time; | 67 | unsigned long now_time; |
@@ -116,7 +116,23 @@ static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id) | |||
116 | rtsr = RTSR; | 116 | rtsr = RTSR; |
117 | /* clear interrupt sources */ | 117 | /* clear interrupt sources */ |
118 | RTSR = 0; | 118 | RTSR = 0; |
119 | RTSR = (RTSR_AL | RTSR_HZ) & (rtsr >> 2); | 119 | /* Fix for a nasty initialization problem the in SA11xx RTSR register. |
120 | * See also the comments in sa1100_rtc_probe(). */ | ||
121 | if (rtsr & (RTSR_ALE | RTSR_HZE)) { | ||
122 | /* This is the original code, before there was the if test | ||
123 | * above. This code does not clear interrupts that were not | ||
124 | * enabled. */ | ||
125 | RTSR = (RTSR_AL | RTSR_HZ) & (rtsr >> 2); | ||
126 | } else { | ||
127 | /* For some reason, it is possible to enter this routine | ||
128 | * without interruptions enabled, it has been tested with | ||
129 | * several units (Bug in SA11xx chip?). | ||
130 | * | ||
131 | * This situation leads to an infinite "loop" of interrupt | ||
132 | * routine calling and as a result the processor seems to | ||
133 | * lock on its first call to open(). */ | ||
134 | RTSR = RTSR_AL | RTSR_HZ; | ||
135 | } | ||
120 | 136 | ||
121 | /* clear alarm interrupt if it has occurred */ | 137 | /* clear alarm interrupt if it has occurred */ |
122 | if (rtsr & RTSR_AL) | 138 | if (rtsr & RTSR_AL) |
@@ -139,80 +155,29 @@ static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id) | |||
139 | return IRQ_HANDLED; | 155 | return IRQ_HANDLED; |
140 | } | 156 | } |
141 | 157 | ||
142 | static int rtc_timer1_count; | ||
143 | |||
144 | static irqreturn_t timer1_interrupt(int irq, void *dev_id) | ||
145 | { | ||
146 | struct platform_device *pdev = to_platform_device(dev_id); | ||
147 | struct rtc_device *rtc = platform_get_drvdata(pdev); | ||
148 | |||
149 | /* | ||
150 | * If we match for the first time, rtc_timer1_count will be 1. | ||
151 | * Otherwise, we wrapped around (very unlikely but | ||
152 | * still possible) so compute the amount of missed periods. | ||
153 | * The match reg is updated only when the data is actually retrieved | ||
154 | * to avoid unnecessary interrupts. | ||
155 | */ | ||
156 | OSSR = OSSR_M1; /* clear match on timer1 */ | ||
157 | |||
158 | rtc_update_irq(rtc, rtc_timer1_count, RTC_PF | RTC_IRQF); | ||
159 | |||
160 | if (rtc_timer1_count == 1) | ||
161 | rtc_timer1_count = (rtc_freq * ((1 << 30) / (timer_freq >> 2))); | ||
162 | |||
163 | return IRQ_HANDLED; | ||
164 | } | ||
165 | |||
166 | static int sa1100_rtc_read_callback(struct device *dev, int data) | ||
167 | { | ||
168 | if (data & RTC_PF) { | ||
169 | /* interpolate missed periods and set match for the next */ | ||
170 | unsigned long period = timer_freq / rtc_freq; | ||
171 | unsigned long oscr = OSCR; | ||
172 | unsigned long osmr1 = OSMR1; | ||
173 | unsigned long missed = (oscr - osmr1)/period; | ||
174 | data += missed << 8; | ||
175 | OSSR = OSSR_M1; /* clear match on timer 1 */ | ||
176 | OSMR1 = osmr1 + (missed + 1)*period; | ||
177 | /* Ensure we didn't miss another match in the mean time. | ||
178 | * Here we compare (match - OSCR) 8 instead of 0 -- | ||
179 | * see comment in pxa_timer_interrupt() for explanation. | ||
180 | */ | ||
181 | while( (signed long)((osmr1 = OSMR1) - OSCR) <= 8 ) { | ||
182 | data += 0x100; | ||
183 | OSSR = OSSR_M1; /* clear match on timer 1 */ | ||
184 | OSMR1 = osmr1 + period; | ||
185 | } | ||
186 | } | ||
187 | return data; | ||
188 | } | ||
189 | |||
190 | static int sa1100_rtc_open(struct device *dev) | 158 | static int sa1100_rtc_open(struct device *dev) |
191 | { | 159 | { |
192 | int ret; | 160 | int ret; |
161 | struct platform_device *plat_dev = to_platform_device(dev); | ||
162 | struct rtc_device *rtc = platform_get_drvdata(plat_dev); | ||
193 | 163 | ||
194 | ret = request_irq(IRQ_RTC1Hz, sa1100_rtc_interrupt, IRQF_DISABLED, | 164 | ret = request_irq(IRQ_RTC1Hz, sa1100_rtc_interrupt, IRQF_DISABLED, |
195 | "rtc 1Hz", dev); | 165 | "rtc 1Hz", dev); |
196 | if (ret) { | 166 | if (ret) { |
197 | dev_err(dev, "IRQ %d already in use.\n", IRQ_RTC1Hz); | 167 | dev_err(dev, "IRQ %d already in use.\n", IRQ_RTC1Hz); |
198 | goto fail_ui; | 168 | goto fail_ui; |
199 | } | 169 | } |
200 | ret = request_irq(IRQ_RTCAlrm, sa1100_rtc_interrupt, IRQF_DISABLED, | 170 | ret = request_irq(IRQ_RTCAlrm, sa1100_rtc_interrupt, IRQF_DISABLED, |
201 | "rtc Alrm", dev); | 171 | "rtc Alrm", dev); |
202 | if (ret) { | 172 | if (ret) { |
203 | dev_err(dev, "IRQ %d already in use.\n", IRQ_RTCAlrm); | 173 | dev_err(dev, "IRQ %d already in use.\n", IRQ_RTCAlrm); |
204 | goto fail_ai; | 174 | goto fail_ai; |
205 | } | 175 | } |
206 | ret = request_irq(IRQ_OST1, timer1_interrupt, IRQF_DISABLED, | 176 | rtc->max_user_freq = RTC_FREQ; |
207 | "rtc timer", dev); | 177 | rtc_irq_set_freq(rtc, NULL, RTC_FREQ); |
208 | if (ret) { | 178 | |
209 | dev_err(dev, "IRQ %d already in use.\n", IRQ_OST1); | ||
210 | goto fail_pi; | ||
211 | } | ||
212 | return 0; | 179 | return 0; |
213 | 180 | ||
214 | fail_pi: | ||
215 | free_irq(IRQ_RTCAlrm, dev); | ||
216 | fail_ai: | 181 | fail_ai: |
217 | free_irq(IRQ_RTC1Hz, dev); | 182 | free_irq(IRQ_RTC1Hz, dev); |
218 | fail_ui: | 183 | fail_ui: |
@@ -227,57 +192,19 @@ static void sa1100_rtc_release(struct device *dev) | |||
227 | OSSR = OSSR_M1; | 192 | OSSR = OSSR_M1; |
228 | spin_unlock_irq(&sa1100_rtc_lock); | 193 | spin_unlock_irq(&sa1100_rtc_lock); |
229 | 194 | ||
230 | free_irq(IRQ_OST1, dev); | ||
231 | free_irq(IRQ_RTCAlrm, dev); | 195 | free_irq(IRQ_RTCAlrm, dev); |
232 | free_irq(IRQ_RTC1Hz, dev); | 196 | free_irq(IRQ_RTC1Hz, dev); |
233 | } | 197 | } |
234 | 198 | ||
235 | 199 | static int sa1100_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | |
236 | static int sa1100_rtc_ioctl(struct device *dev, unsigned int cmd, | ||
237 | unsigned long arg) | ||
238 | { | 200 | { |
239 | switch(cmd) { | 201 | spin_lock_irq(&sa1100_rtc_lock); |
240 | case RTC_AIE_OFF: | 202 | if (enabled) |
241 | spin_lock_irq(&sa1100_rtc_lock); | ||
242 | RTSR &= ~RTSR_ALE; | ||
243 | spin_unlock_irq(&sa1100_rtc_lock); | ||
244 | return 0; | ||
245 | case RTC_AIE_ON: | ||
246 | spin_lock_irq(&sa1100_rtc_lock); | ||
247 | RTSR |= RTSR_ALE; | 203 | RTSR |= RTSR_ALE; |
248 | spin_unlock_irq(&sa1100_rtc_lock); | 204 | else |
249 | return 0; | 205 | RTSR &= ~RTSR_ALE; |
250 | case RTC_UIE_OFF: | 206 | spin_unlock_irq(&sa1100_rtc_lock); |
251 | spin_lock_irq(&sa1100_rtc_lock); | 207 | return 0; |
252 | RTSR &= ~RTSR_HZE; | ||
253 | spin_unlock_irq(&sa1100_rtc_lock); | ||
254 | return 0; | ||
255 | case RTC_UIE_ON: | ||
256 | spin_lock_irq(&sa1100_rtc_lock); | ||
257 | RTSR |= RTSR_HZE; | ||
258 | spin_unlock_irq(&sa1100_rtc_lock); | ||
259 | return 0; | ||
260 | case RTC_PIE_OFF: | ||
261 | spin_lock_irq(&sa1100_rtc_lock); | ||
262 | OIER &= ~OIER_E1; | ||
263 | spin_unlock_irq(&sa1100_rtc_lock); | ||
264 | return 0; | ||
265 | case RTC_PIE_ON: | ||
266 | spin_lock_irq(&sa1100_rtc_lock); | ||
267 | OSMR1 = timer_freq / rtc_freq + OSCR; | ||
268 | OIER |= OIER_E1; | ||
269 | rtc_timer1_count = 1; | ||
270 | spin_unlock_irq(&sa1100_rtc_lock); | ||
271 | return 0; | ||
272 | case RTC_IRQP_READ: | ||
273 | return put_user(rtc_freq, (unsigned long *)arg); | ||
274 | case RTC_IRQP_SET: | ||
275 | if (arg < 1 || arg > timer_freq) | ||
276 | return -EINVAL; | ||
277 | rtc_freq = arg; | ||
278 | return 0; | ||
279 | } | ||
280 | return -ENOIOCTLCMD; | ||
281 | } | 208 | } |
282 | 209 | ||
283 | static int sa1100_rtc_read_time(struct device *dev, struct rtc_time *tm) | 210 | static int sa1100_rtc_read_time(struct device *dev, struct rtc_time *tm) |
@@ -327,34 +254,27 @@ static int sa1100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
327 | 254 | ||
328 | static int sa1100_rtc_proc(struct device *dev, struct seq_file *seq) | 255 | static int sa1100_rtc_proc(struct device *dev, struct seq_file *seq) |
329 | { | 256 | { |
330 | seq_printf(seq, "trim/divider\t: 0x%08x\n", (u32) RTTR); | 257 | seq_printf(seq, "trim/divider\t\t: 0x%08x\n", (u32) RTTR); |
331 | seq_printf(seq, "update_IRQ\t: %s\n", | 258 | seq_printf(seq, "RTSR\t\t\t: 0x%08x\n", (u32)RTSR); |
332 | (RTSR & RTSR_HZE) ? "yes" : "no"); | ||
333 | seq_printf(seq, "periodic_IRQ\t: %s\n", | ||
334 | (OIER & OIER_E1) ? "yes" : "no"); | ||
335 | seq_printf(seq, "periodic_freq\t: %ld\n", rtc_freq); | ||
336 | 259 | ||
337 | return 0; | 260 | return 0; |
338 | } | 261 | } |
339 | 262 | ||
340 | static const struct rtc_class_ops sa1100_rtc_ops = { | 263 | static const struct rtc_class_ops sa1100_rtc_ops = { |
341 | .open = sa1100_rtc_open, | 264 | .open = sa1100_rtc_open, |
342 | .read_callback = sa1100_rtc_read_callback, | ||
343 | .release = sa1100_rtc_release, | 265 | .release = sa1100_rtc_release, |
344 | .ioctl = sa1100_rtc_ioctl, | ||
345 | .read_time = sa1100_rtc_read_time, | 266 | .read_time = sa1100_rtc_read_time, |
346 | .set_time = sa1100_rtc_set_time, | 267 | .set_time = sa1100_rtc_set_time, |
347 | .read_alarm = sa1100_rtc_read_alarm, | 268 | .read_alarm = sa1100_rtc_read_alarm, |
348 | .set_alarm = sa1100_rtc_set_alarm, | 269 | .set_alarm = sa1100_rtc_set_alarm, |
349 | .proc = sa1100_rtc_proc, | 270 | .proc = sa1100_rtc_proc, |
271 | .alarm_irq_enable = sa1100_rtc_alarm_irq_enable, | ||
350 | }; | 272 | }; |
351 | 273 | ||
352 | static int sa1100_rtc_probe(struct platform_device *pdev) | 274 | static int sa1100_rtc_probe(struct platform_device *pdev) |
353 | { | 275 | { |
354 | struct rtc_device *rtc; | 276 | struct rtc_device *rtc; |
355 | 277 | ||
356 | timer_freq = get_clock_tick_rate(); | ||
357 | |||
358 | /* | 278 | /* |
359 | * According to the manual we should be able to let RTTR be zero | 279 | * According to the manual we should be able to let RTTR be zero |
360 | * and then a default diviser for a 32.768KHz clock is used. | 280 | * and then a default diviser for a 32.768KHz clock is used. |
@@ -364,7 +284,8 @@ static int sa1100_rtc_probe(struct platform_device *pdev) | |||
364 | */ | 284 | */ |
365 | if (RTTR == 0) { | 285 | if (RTTR == 0) { |
366 | RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16); | 286 | RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16); |
367 | dev_warn(&pdev->dev, "warning: initializing default clock divider/trim value\n"); | 287 | dev_warn(&pdev->dev, "warning: " |
288 | "initializing default clock divider/trim value\n"); | ||
368 | /* The current RTC value probably doesn't make sense either */ | 289 | /* The current RTC value probably doesn't make sense either */ |
369 | RCNR = 0; | 290 | RCNR = 0; |
370 | } | 291 | } |
@@ -372,13 +293,37 @@ static int sa1100_rtc_probe(struct platform_device *pdev) | |||
372 | device_init_wakeup(&pdev->dev, 1); | 293 | device_init_wakeup(&pdev->dev, 1); |
373 | 294 | ||
374 | rtc = rtc_device_register(pdev->name, &pdev->dev, &sa1100_rtc_ops, | 295 | rtc = rtc_device_register(pdev->name, &pdev->dev, &sa1100_rtc_ops, |
375 | THIS_MODULE); | 296 | THIS_MODULE); |
376 | 297 | ||
377 | if (IS_ERR(rtc)) | 298 | if (IS_ERR(rtc)) |
378 | return PTR_ERR(rtc); | 299 | return PTR_ERR(rtc); |
379 | 300 | ||
380 | platform_set_drvdata(pdev, rtc); | 301 | platform_set_drvdata(pdev, rtc); |
381 | 302 | ||
303 | /* Fix for a nasty initialization problem the in SA11xx RTSR register. | ||
304 | * See also the comments in sa1100_rtc_interrupt(). | ||
305 | * | ||
306 | * Sometimes bit 1 of the RTSR (RTSR_HZ) will wake up 1, which means an | ||
307 | * interrupt pending, even though interrupts were never enabled. | ||
308 | * In this case, this bit it must be reset before enabling | ||
309 | * interruptions to avoid a nonexistent interrupt to occur. | ||
310 | * | ||
311 | * In principle, the same problem would apply to bit 0, although it has | ||
312 | * never been observed to happen. | ||
313 | * | ||
314 | * This issue is addressed both here and in sa1100_rtc_interrupt(). | ||
315 | * If the issue is not addressed here, in the times when the processor | ||
316 | * wakes up with the bit set there will be one spurious interrupt. | ||
317 | * | ||
318 | * The issue is also dealt with in sa1100_rtc_interrupt() to be on the | ||
319 | * safe side, once the condition that lead to this strange | ||
320 | * initialization is unknown and could in principle happen during | ||
321 | * normal processing. | ||
322 | * | ||
323 | * Notice that clearing bit 1 and 0 is accomplished by writting ONES to | ||
324 | * the corresponding bits in RTSR. */ | ||
325 | RTSR = RTSR_AL | RTSR_HZ; | ||
326 | |||
382 | return 0; | 327 | return 0; |
383 | } | 328 | } |
384 | 329 | ||
@@ -386,7 +331,7 @@ static int sa1100_rtc_remove(struct platform_device *pdev) | |||
386 | { | 331 | { |
387 | struct rtc_device *rtc = platform_get_drvdata(pdev); | 332 | struct rtc_device *rtc = platform_get_drvdata(pdev); |
388 | 333 | ||
389 | if (rtc) | 334 | if (rtc) |
390 | rtc_device_unregister(rtc); | 335 | rtc_device_unregister(rtc); |
391 | 336 | ||
392 | return 0; | 337 | return 0; |