aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-s3c.c
diff options
context:
space:
mode:
authorBen Dooks <ben-linux@fluff.org>2008-07-24 00:30:45 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-24 13:47:34 -0400
commit773be7ee97c11fbb6b8a912a58b268dbe8a6a3fe (patch)
treed550b52722b2fd26afb33ee05486e06778411f1c /drivers/rtc/rtc-s3c.c
parent4cd0c5c40b64ef9fd94fb8382dade2fd28f2b935 (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/rtc/rtc-s3c.c')
-rw-r--r--drivers/rtc/rtc-s3c.c83
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;
36static void __iomem *s3c_rtc_base; 36static void __iomem *s3c_rtc_base;
37static int s3c_rtc_alarmno = NO_IRQ; 37static int s3c_rtc_alarmno = NO_IRQ;
38static int s3c_rtc_tickno = NO_IRQ; 38static int s3c_rtc_tickno = NO_IRQ;
39static int s3c_rtc_freq = 1;
40 39
41static DEFINE_SPINLOCK(s3c_rtc_pie_lock); 40static DEFINE_SPINLOCK(s3c_rtc_pie_lock);
42static 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
77static void s3c_rtc_setpie(int to) 75static 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
93static void s3c_rtc_setfreq(int freq) 93static 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
285static 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
329static int s3c_rtc_proc(struct device *dev, struct seq_file *seq) 280static 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)
382static const struct rtc_class_ops s3c_rtcops = { 330static 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