diff options
author | Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> | 2008-07-23 21:30:48 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-24 10:47:34 -0700 |
commit | 4cad4431fcd872a1b2efc093b0db6df943f5a898 (patch) | |
tree | 99849c4f20e0847eb1931f11ed4276a0308373bf /drivers | |
parent | 7e2a31da854dcf8324012a83a31b40bc11e52589 (diff) | |
download | lwn-4cad4431fcd872a1b2efc093b0db6df943f5a898.tar.gz lwn-4cad4431fcd872a1b2efc093b0db6df943f5a898.zip |
rtc-vr41xx: add irq_set_freq() and irq_set_state()
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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/rtc/rtc-vr41xx.c | 65 |
1 files changed, 34 insertions, 31 deletions
diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c index be9c70d0b193..884b635f028b 100644 --- a/drivers/rtc/rtc-vr41xx.c +++ b/drivers/rtc/rtc-vr41xx.c @@ -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); @@ -232,33 +258,6 @@ static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long 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: return put_user(epoch, (unsigned long __user *)arg); case RTC_EPOCH_SET: @@ -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); |