aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc
diff options
context:
space:
mode:
authorYoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>2008-07-24 00:30:48 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-24 13:47:34 -0400
commit4cad4431fcd872a1b2efc093b0db6df943f5a898 (patch)
tree99849c4f20e0847eb1931f11ed4276a0308373bf /drivers/rtc
parent7e2a31da854dcf8324012a83a31b40bc11e52589 (diff)
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/rtc')
-rw-r--r--drivers/rtc/rtc-vr41xx.c65
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 @@
1/* 1/*
2 * Driver for NEC VR4100 series Real Time Clock unit. 2 * Driver for NEC VR4100 series Real Time Clock unit.
3 * 3 *
4 * Copyright (C) 2003-2006 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> 4 * Copyright (C) 2003-2008 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
@@ -34,7 +34,7 @@
34 34
35MODULE_AUTHOR("Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>"); 35MODULE_AUTHOR("Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>");
36MODULE_DESCRIPTION("NEC VR4100 series RTC driver"); 36MODULE_DESCRIPTION("NEC VR4100 series RTC driver");
37MODULE_LICENSE("GPL"); 37MODULE_LICENSE("GPL v2");
38 38
39/* RTC 1 registers */ 39/* RTC 1 registers */
40#define ETIMELREG 0x00 40#define ETIMELREG 0x00
@@ -82,7 +82,6 @@ static unsigned long epoch = 1970; /* Jan 1 1970 00:00:00 */
82 82
83static DEFINE_SPINLOCK(rtc_lock); 83static DEFINE_SPINLOCK(rtc_lock);
84static char rtc_name[] = "RTC"; 84static char rtc_name[] = "RTC";
85static unsigned long periodic_frequency;
86static unsigned long periodic_count; 85static unsigned long periodic_count;
87static unsigned int alarm_enabled; 86static unsigned int alarm_enabled;
88static int aie_irq = -1; 87static int aie_irq = -1;
@@ -207,10 +206,37 @@ static int vr41xx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
207 return 0; 206 return 0;
208} 207}
209 208
210static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) 209static int vr41xx_rtc_irq_set_freq(struct device *dev, int freq)
211{ 210{
212 unsigned long count; 211 unsigned long count;
213 212
213 count = RTC_FREQUENCY;
214 do_div(count, freq);
215
216 periodic_count = count;
217
218 spin_lock_irq(&rtc_lock);
219
220 rtc1_write(RTCL1LREG, count);
221 rtc1_write(RTCL1HREG, count >> 16);
222
223 spin_unlock_irq(&rtc_lock);
224
225 return 0;
226}
227
228static int vr41xx_rtc_irq_set_state(struct device *dev, int enabled)
229{
230 if (enabled)
231 enable_irq(pie_irq);
232 else
233 disable_irq(pie_irq);
234
235 return 0;
236}
237
238static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
239{
214 switch (cmd) { 240 switch (cmd) {
215 case RTC_AIE_ON: 241 case RTC_AIE_ON:
216 spin_lock_irq(&rtc_lock); 242 spin_lock_irq(&rtc_lock);
@@ -232,33 +258,6 @@ static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long
232 258
233 spin_unlock_irq(&rtc_lock); 259 spin_unlock_irq(&rtc_lock);
234 break; 260 break;
235 case RTC_PIE_ON:
236 enable_irq(pie_irq);
237 break;
238 case RTC_PIE_OFF:
239 disable_irq(pie_irq);
240 break;
241 case RTC_IRQP_READ:
242 return put_user(periodic_frequency, (unsigned long __user *)arg);
243 break;
244 case RTC_IRQP_SET:
245 if (arg > MAX_PERIODIC_RATE)
246 return -EINVAL;
247
248 periodic_frequency = arg;
249
250 count = RTC_FREQUENCY;
251 do_div(count, arg);
252
253 periodic_count = count;
254
255 spin_lock_irq(&rtc_lock);
256
257 rtc1_write(RTCL1LREG, count);
258 rtc1_write(RTCL1HREG, count >> 16);
259
260 spin_unlock_irq(&rtc_lock);
261 break;
262 case RTC_EPOCH_READ: 261 case RTC_EPOCH_READ:
263 return put_user(epoch, (unsigned long __user *)arg); 262 return put_user(epoch, (unsigned long __user *)arg);
264 case RTC_EPOCH_SET: 263 case RTC_EPOCH_SET:
@@ -309,6 +308,8 @@ static const struct rtc_class_ops vr41xx_rtc_ops = {
309 .set_time = vr41xx_rtc_set_time, 308 .set_time = vr41xx_rtc_set_time,
310 .read_alarm = vr41xx_rtc_read_alarm, 309 .read_alarm = vr41xx_rtc_read_alarm,
311 .set_alarm = vr41xx_rtc_set_alarm, 310 .set_alarm = vr41xx_rtc_set_alarm,
311 .irq_set_freq = vr41xx_rtc_irq_set_freq,
312 .irq_set_state = vr41xx_rtc_irq_set_state,
312}; 313};
313 314
314static int __devinit rtc_probe(struct platform_device *pdev) 315static int __devinit rtc_probe(struct platform_device *pdev)
@@ -346,6 +347,8 @@ static int __devinit rtc_probe(struct platform_device *pdev)
346 goto err_iounmap_all; 347 goto err_iounmap_all;
347 } 348 }
348 349
350 rtc->max_user_freq = MAX_PERIODIC_RATE;
351
349 spin_lock_irq(&rtc_lock); 352 spin_lock_irq(&rtc_lock);
350 353
351 rtc1_write(ECMPLREG, 0); 354 rtc1_write(ECMPLREG, 0);