rtc-vr41xx: add irq_set_freq() and irq_set_state()
authorYoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
Thu, 24 Jul 2008 04:30:48 +0000 (21:30 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 24 Jul 2008 17:47:34 +0000 (10:47 -0700)
Implement the ioctls RTC_PIE_ON, RTC_PIE_OFF, RTC_IRQP_SET and
RTC_IRQP_READ in the standard RTC way.

Thanks Dave for noticing it.

Signed-off-by: Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
Cc: David Brownell <david-b@pacbell.net>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Alessandro Zummo <a.zummo@towertech.it>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
drivers/rtc/rtc-vr41xx.c

index be9c70d0b193d2210ff3611728e1cafae133a961..884b635f028b792ee9b9afef8954345b4375e24a 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  Driver for NEC VR4100 series Real Time Clock unit.
  *
- *  Copyright (C) 2003-2006  Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
+ *  Copyright (C) 2003-2008  Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -34,7 +34,7 @@
 
 MODULE_AUTHOR("Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>");
 MODULE_DESCRIPTION("NEC VR4100 series RTC driver");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
 
 /* RTC 1 registers */
 #define ETIMELREG              0x00
@@ -82,7 +82,6 @@ static unsigned long epoch = 1970;    /* Jan 1 1970 00:00:00 */
 
 static DEFINE_SPINLOCK(rtc_lock);
 static char rtc_name[] = "RTC";
-static unsigned long periodic_frequency;
 static unsigned long periodic_count;
 static unsigned int alarm_enabled;
 static int aie_irq = -1;
@@ -207,10 +206,37 @@ static int vr41xx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
        return 0;
 }
 
-static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
+static int vr41xx_rtc_irq_set_freq(struct device *dev, int freq)
 {
        unsigned long count;
 
+       count = RTC_FREQUENCY;
+       do_div(count, freq);
+
+       periodic_count = count;
+
+       spin_lock_irq(&rtc_lock);
+
+       rtc1_write(RTCL1LREG, count);
+       rtc1_write(RTCL1HREG, count >> 16);
+
+       spin_unlock_irq(&rtc_lock);
+
+       return 0;
+}
+
+static int vr41xx_rtc_irq_set_state(struct device *dev, int enabled)
+{
+       if (enabled)
+               enable_irq(pie_irq);
+       else
+               disable_irq(pie_irq);
+
+       return 0;
+}
+
+static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
+{
        switch (cmd) {
        case RTC_AIE_ON:
                spin_lock_irq(&rtc_lock);
@@ -230,33 +256,6 @@ static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long
                        alarm_enabled = 0;
                }
 
-               spin_unlock_irq(&rtc_lock);
-               break;
-       case RTC_PIE_ON:
-               enable_irq(pie_irq);
-               break;
-       case RTC_PIE_OFF:
-               disable_irq(pie_irq);
-               break;
-       case RTC_IRQP_READ:
-               return put_user(periodic_frequency, (unsigned long __user *)arg);
-               break;
-       case RTC_IRQP_SET:
-               if (arg > MAX_PERIODIC_RATE)
-                       return -EINVAL;
-
-               periodic_frequency = arg;
-
-               count = RTC_FREQUENCY;
-               do_div(count, arg);
-
-               periodic_count = count;
-
-               spin_lock_irq(&rtc_lock);
-
-               rtc1_write(RTCL1LREG, count);
-               rtc1_write(RTCL1HREG, count >> 16);
-
                spin_unlock_irq(&rtc_lock);
                break;
        case RTC_EPOCH_READ:
@@ -309,6 +308,8 @@ static const struct rtc_class_ops vr41xx_rtc_ops = {
        .set_time       = vr41xx_rtc_set_time,
        .read_alarm     = vr41xx_rtc_read_alarm,
        .set_alarm      = vr41xx_rtc_set_alarm,
+       .irq_set_freq   = vr41xx_rtc_irq_set_freq,
+       .irq_set_state  = vr41xx_rtc_irq_set_state,
 };
 
 static int __devinit rtc_probe(struct platform_device *pdev)
@@ -346,6 +347,8 @@ static int __devinit rtc_probe(struct platform_device *pdev)
                goto err_iounmap_all;
        }
 
+       rtc->max_user_freq = MAX_PERIODIC_RATE;
+
        spin_lock_irq(&rtc_lock);
 
        rtc1_write(ECMPLREG, 0);