diff options
author | Ben Dooks <ben-linux@fluff.org> | 2008-07-24 00:30:45 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-24 13:47:34 -0400 |
commit | 773be7ee97c11fbb6b8a912a58b268dbe8a6a3fe (patch) | |
tree | d550b52722b2fd26afb33ee05486e06778411f1c /drivers | |
parent | 4cd0c5c40b64ef9fd94fb8382dade2fd28f2b935 (diff) |
rtc: rtc-s3c: update IRQ handling
The rtc-s3c.c driver has been using its own ioctl() handling to deal with
alarm and periodic interrupts to handle what should now be done with the
rtc core code.
Change to using the .irq_set_freq and .irq_set_state driver entries and
remove the .ioctl handling.
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Acked-by: Alessandro Zummo <a.zummo@towertech.it>
Cc: David Brownell <david-b@pacbell.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/rtc/rtc-s3c.c | 83 |
1 files changed, 16 insertions, 67 deletions
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index b81ba7020d92..54b1ebb01502 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c | |||
@@ -36,10 +36,8 @@ static struct resource *s3c_rtc_mem; | |||
36 | static void __iomem *s3c_rtc_base; | 36 | static void __iomem *s3c_rtc_base; |
37 | static int s3c_rtc_alarmno = NO_IRQ; | 37 | static int s3c_rtc_alarmno = NO_IRQ; |
38 | static int s3c_rtc_tickno = NO_IRQ; | 38 | static int s3c_rtc_tickno = NO_IRQ; |
39 | static int s3c_rtc_freq = 1; | ||
40 | 39 | ||
41 | static DEFINE_SPINLOCK(s3c_rtc_pie_lock); | 40 | static DEFINE_SPINLOCK(s3c_rtc_pie_lock); |
42 | static unsigned int tick_count; | ||
43 | 41 | ||
44 | /* IRQ Handlers */ | 42 | /* IRQ Handlers */ |
45 | 43 | ||
@@ -55,7 +53,7 @@ static irqreturn_t s3c_rtc_tickirq(int irq, void *id) | |||
55 | { | 53 | { |
56 | struct rtc_device *rdev = id; | 54 | struct rtc_device *rdev = id; |
57 | 55 | ||
58 | rtc_update_irq(rdev, tick_count++, RTC_PF | RTC_IRQF); | 56 | rtc_update_irq(rdev, 1, RTC_PF | RTC_IRQF); |
59 | return IRQ_HANDLED; | 57 | return IRQ_HANDLED; |
60 | } | 58 | } |
61 | 59 | ||
@@ -74,35 +72,37 @@ static void s3c_rtc_setaie(int to) | |||
74 | writeb(tmp, s3c_rtc_base + S3C2410_RTCALM); | 72 | writeb(tmp, s3c_rtc_base + S3C2410_RTCALM); |
75 | } | 73 | } |
76 | 74 | ||
77 | static void s3c_rtc_setpie(int to) | 75 | static int s3c_rtc_setpie(struct device *dev, int enabled) |
78 | { | 76 | { |
79 | unsigned int tmp; | 77 | unsigned int tmp; |
80 | 78 | ||
81 | pr_debug("%s: pie=%d\n", __func__, to); | 79 | pr_debug("%s: pie=%d\n", __func__, enabled); |
82 | 80 | ||
83 | spin_lock_irq(&s3c_rtc_pie_lock); | 81 | spin_lock_irq(&s3c_rtc_pie_lock); |
84 | tmp = readb(s3c_rtc_base + S3C2410_TICNT) & ~S3C2410_TICNT_ENABLE; | 82 | tmp = readb(s3c_rtc_base + S3C2410_TICNT) & ~S3C2410_TICNT_ENABLE; |
85 | 83 | ||
86 | if (to) | 84 | if (enabled) |
87 | tmp |= S3C2410_TICNT_ENABLE; | 85 | tmp |= S3C2410_TICNT_ENABLE; |
88 | 86 | ||
89 | writeb(tmp, s3c_rtc_base + S3C2410_TICNT); | 87 | writeb(tmp, s3c_rtc_base + S3C2410_TICNT); |
90 | spin_unlock_irq(&s3c_rtc_pie_lock); | 88 | spin_unlock_irq(&s3c_rtc_pie_lock); |
89 | |||
90 | return 0; | ||
91 | } | 91 | } |
92 | 92 | ||
93 | static void s3c_rtc_setfreq(int freq) | 93 | static int s3c_rtc_setfreq(struct device *dev, int freq) |
94 | { | 94 | { |
95 | unsigned int tmp; | 95 | unsigned int tmp; |
96 | 96 | ||
97 | spin_lock_irq(&s3c_rtc_pie_lock); | 97 | spin_lock_irq(&s3c_rtc_pie_lock); |
98 | tmp = readb(s3c_rtc_base + S3C2410_TICNT) & S3C2410_TICNT_ENABLE; | ||
99 | |||
100 | s3c_rtc_freq = freq; | ||
101 | 98 | ||
99 | tmp = readb(s3c_rtc_base + S3C2410_TICNT) & S3C2410_TICNT_ENABLE; | ||
102 | tmp |= (128 / freq)-1; | 100 | tmp |= (128 / freq)-1; |
103 | 101 | ||
104 | writeb(tmp, s3c_rtc_base + S3C2410_TICNT); | 102 | writeb(tmp, s3c_rtc_base + S3C2410_TICNT); |
105 | spin_unlock_irq(&s3c_rtc_pie_lock); | 103 | spin_unlock_irq(&s3c_rtc_pie_lock); |
104 | |||
105 | return 0; | ||
106 | } | 106 | } |
107 | 107 | ||
108 | /* Time read/write */ | 108 | /* Time read/write */ |
@@ -267,12 +267,7 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
267 | 267 | ||
268 | writeb(alrm_en, base + S3C2410_RTCALM); | 268 | writeb(alrm_en, base + S3C2410_RTCALM); |
269 | 269 | ||
270 | if (0) { | 270 | s3c_rtc_setaie(alrm->enabled); |
271 | alrm_en = readb(base + S3C2410_RTCALM); | ||
272 | alrm_en &= ~S3C2410_RTCALM_ALMEN; | ||
273 | writeb(alrm_en, base + S3C2410_RTCALM); | ||
274 | disable_irq_wake(s3c_rtc_alarmno); | ||
275 | } | ||
276 | 271 | ||
277 | if (alrm->enabled) | 272 | if (alrm->enabled) |
278 | enable_irq_wake(s3c_rtc_alarmno); | 273 | enable_irq_wake(s3c_rtc_alarmno); |
@@ -282,59 +277,12 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
282 | return 0; | 277 | return 0; |
283 | } | 278 | } |
284 | 279 | ||
285 | static int s3c_rtc_ioctl(struct device *dev, | ||
286 | unsigned int cmd, unsigned long arg) | ||
287 | { | ||
288 | unsigned int ret = -ENOIOCTLCMD; | ||
289 | |||
290 | switch (cmd) { | ||
291 | case RTC_AIE_OFF: | ||
292 | case RTC_AIE_ON: | ||
293 | s3c_rtc_setaie((cmd == RTC_AIE_ON) ? 1 : 0); | ||
294 | ret = 0; | ||
295 | break; | ||
296 | |||
297 | case RTC_PIE_OFF: | ||
298 | case RTC_PIE_ON: | ||
299 | tick_count = 0; | ||
300 | s3c_rtc_setpie((cmd == RTC_PIE_ON) ? 1 : 0); | ||
301 | ret = 0; | ||
302 | break; | ||
303 | |||
304 | case RTC_IRQP_READ: | ||
305 | ret = put_user(s3c_rtc_freq, (unsigned long __user *)arg); | ||
306 | break; | ||
307 | |||
308 | case RTC_IRQP_SET: | ||
309 | if (!is_power_of_2(arg)) { | ||
310 | ret = -EINVAL; | ||
311 | goto exit; | ||
312 | } | ||
313 | |||
314 | pr_debug("s3c2410_rtc: setting frequency %ld\n", arg); | ||
315 | |||
316 | s3c_rtc_setfreq(arg); | ||
317 | ret = 0; | ||
318 | break; | ||
319 | |||
320 | case RTC_UIE_ON: | ||
321 | case RTC_UIE_OFF: | ||
322 | ret = -EINVAL; | ||
323 | } | ||
324 | |||
325 | exit: | ||
326 | return ret; | ||
327 | } | ||
328 | |||
329 | static int s3c_rtc_proc(struct device *dev, struct seq_file *seq) | 280 | static int s3c_rtc_proc(struct device *dev, struct seq_file *seq) |
330 | { | 281 | { |
331 | unsigned int ticnt = readb(s3c_rtc_base + S3C2410_TICNT); | 282 | unsigned int ticnt = readb(s3c_rtc_base + S3C2410_TICNT); |
332 | 283 | ||
333 | seq_printf(seq, "periodic_IRQ\t: %s\n", | 284 | seq_printf(seq, "periodic_IRQ\t: %s\n", |
334 | (ticnt & S3C2410_TICNT_ENABLE) ? "yes" : "no" ); | 285 | (ticnt & S3C2410_TICNT_ENABLE) ? "yes" : "no" ); |
335 | |||
336 | seq_printf(seq, "periodic_freq\t: %d\n", s3c_rtc_freq); | ||
337 | |||
338 | return 0; | 286 | return 0; |
339 | } | 287 | } |
340 | 288 | ||
@@ -374,7 +322,7 @@ static void s3c_rtc_release(struct device *dev) | |||
374 | 322 | ||
375 | /* do not clear AIE here, it may be needed for wake */ | 323 | /* do not clear AIE here, it may be needed for wake */ |
376 | 324 | ||
377 | s3c_rtc_setpie(0); | 325 | s3c_rtc_setpie(dev, 0); |
378 | free_irq(s3c_rtc_alarmno, rtc_dev); | 326 | free_irq(s3c_rtc_alarmno, rtc_dev); |
379 | free_irq(s3c_rtc_tickno, rtc_dev); | 327 | free_irq(s3c_rtc_tickno, rtc_dev); |
380 | } | 328 | } |
@@ -382,11 +330,12 @@ static void s3c_rtc_release(struct device *dev) | |||
382 | static const struct rtc_class_ops s3c_rtcops = { | 330 | static const struct rtc_class_ops s3c_rtcops = { |
383 | .open = s3c_rtc_open, | 331 | .open = s3c_rtc_open, |
384 | .release = s3c_rtc_release, | 332 | .release = s3c_rtc_release, |
385 | .ioctl = s3c_rtc_ioctl, | ||
386 | .read_time = s3c_rtc_gettime, | 333 | .read_time = s3c_rtc_gettime, |
387 | .set_time = s3c_rtc_settime, | 334 | .set_time = s3c_rtc_settime, |
388 | .read_alarm = s3c_rtc_getalarm, | 335 | .read_alarm = s3c_rtc_getalarm, |
389 | .set_alarm = s3c_rtc_setalarm, | 336 | .set_alarm = s3c_rtc_setalarm, |
337 | .irq_set_freq = s3c_rtc_setfreq, | ||
338 | .irq_set_state = s3c_rtc_setpie, | ||
390 | .proc = s3c_rtc_proc, | 339 | .proc = s3c_rtc_proc, |
391 | }; | 340 | }; |
392 | 341 | ||
@@ -437,7 +386,7 @@ static int __devexit s3c_rtc_remove(struct platform_device *dev) | |||
437 | platform_set_drvdata(dev, NULL); | 386 | platform_set_drvdata(dev, NULL); |
438 | rtc_device_unregister(rtc); | 387 | rtc_device_unregister(rtc); |
439 | 388 | ||
440 | s3c_rtc_setpie(0); | 389 | s3c_rtc_setpie(&dev->dev, 0); |
441 | s3c_rtc_setaie(0); | 390 | s3c_rtc_setaie(0); |
442 | 391 | ||
443 | iounmap(s3c_rtc_base); | 392 | iounmap(s3c_rtc_base); |
@@ -504,7 +453,7 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev) | |||
504 | pr_debug("s3c2410_rtc: RTCCON=%02x\n", | 453 | pr_debug("s3c2410_rtc: RTCCON=%02x\n", |
505 | readb(s3c_rtc_base + S3C2410_RTCCON)); | 454 | readb(s3c_rtc_base + S3C2410_RTCCON)); |
506 | 455 | ||
507 | s3c_rtc_setfreq(s3c_rtc_freq); | 456 | s3c_rtc_setfreq(&pdev->dev, 1); |
508 | 457 | ||
509 | /* register RTC and exit */ | 458 | /* register RTC and exit */ |
510 | 459 | ||