aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/Kconfig12
-rw-r--r--drivers/rtc/class.c1
-rw-r--r--drivers/rtc/interface.c64
3 files changed, 41 insertions, 36 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 4941cade319f..cdd97192dc69 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -97,18 +97,6 @@ config RTC_INTF_DEV
97 97
98 If unsure, say Y. 98 If unsure, say Y.
99 99
100config RTC_INTF_DEV_UIE_EMUL
101 bool "RTC UIE emulation on dev interface"
102 depends on RTC_INTF_DEV
103 help
104 Provides an emulation for RTC_UIE if the underlying rtc chip
105 driver does not expose RTC_UIE ioctls. Those requests generate
106 once-per-second update interrupts, used for synchronization.
107
108 The emulation code will read the time from the hardware
109 clock several times per second, please enable this option
110 only if you know that you really need it.
111
112config RTC_DRV_TEST 100config RTC_DRV_TEST
113 tristate "Test driver/device" 101 tristate "Test driver/device"
114 help 102 help
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
index 9583cbcc6b79..c404b61386bf 100644
--- a/drivers/rtc/class.c
+++ b/drivers/rtc/class.c
@@ -143,6 +143,7 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev,
143 rtc->id = id; 143 rtc->id = id;
144 rtc->ops = ops; 144 rtc->ops = ops;
145 rtc->owner = owner; 145 rtc->owner = owner;
146 rtc->irq_freq = 1;
146 rtc->max_user_freq = 64; 147 rtc->max_user_freq = 64;
147 rtc->dev.parent = dev; 148 rtc->dev.parent = dev;
148 rtc->dev.class = rtc_class; 149 rtc->dev.class = rtc_class;
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index 90384b9f6b2c..a0c01967244d 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -16,6 +16,9 @@
16#include <linux/log2.h> 16#include <linux/log2.h>
17#include <linux/workqueue.h> 17#include <linux/workqueue.h>
18 18
19static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer);
20static void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer);
21
19static int __rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm) 22static int __rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm)
20{ 23{
21 int err; 24 int err;
@@ -120,12 +123,18 @@ int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
120 err = mutex_lock_interruptible(&rtc->ops_lock); 123 err = mutex_lock_interruptible(&rtc->ops_lock);
121 if (err) 124 if (err)
122 return err; 125 return err;
123 alarm->enabled = rtc->aie_timer.enabled; 126 if (rtc->ops == NULL)
124 if (alarm->enabled) 127 err = -ENODEV;
128 else if (!rtc->ops->read_alarm)
129 err = -EINVAL;
130 else {
131 memset(alarm, 0, sizeof(struct rtc_wkalrm));
132 alarm->enabled = rtc->aie_timer.enabled;
125 alarm->time = rtc_ktime_to_tm(rtc->aie_timer.node.expires); 133 alarm->time = rtc_ktime_to_tm(rtc->aie_timer.node.expires);
134 }
126 mutex_unlock(&rtc->ops_lock); 135 mutex_unlock(&rtc->ops_lock);
127 136
128 return 0; 137 return err;
129} 138}
130EXPORT_SYMBOL_GPL(rtc_read_alarm); 139EXPORT_SYMBOL_GPL(rtc_read_alarm);
131 140
@@ -175,16 +184,14 @@ int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
175 return err; 184 return err;
176 if (rtc->aie_timer.enabled) { 185 if (rtc->aie_timer.enabled) {
177 rtc_timer_remove(rtc, &rtc->aie_timer); 186 rtc_timer_remove(rtc, &rtc->aie_timer);
178 rtc->aie_timer.enabled = 0;
179 } 187 }
180 rtc->aie_timer.node.expires = rtc_tm_to_ktime(alarm->time); 188 rtc->aie_timer.node.expires = rtc_tm_to_ktime(alarm->time);
181 rtc->aie_timer.period = ktime_set(0, 0); 189 rtc->aie_timer.period = ktime_set(0, 0);
182 if (alarm->enabled) { 190 if (alarm->enabled) {
183 rtc->aie_timer.enabled = 1; 191 err = rtc_timer_enqueue(rtc, &rtc->aie_timer);
184 rtc_timer_enqueue(rtc, &rtc->aie_timer);
185 } 192 }
186 mutex_unlock(&rtc->ops_lock); 193 mutex_unlock(&rtc->ops_lock);
187 return 0; 194 return err;
188} 195}
189EXPORT_SYMBOL_GPL(rtc_set_alarm); 196EXPORT_SYMBOL_GPL(rtc_set_alarm);
190 197
@@ -195,15 +202,15 @@ int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled)
195 return err; 202 return err;
196 203
197 if (rtc->aie_timer.enabled != enabled) { 204 if (rtc->aie_timer.enabled != enabled) {
198 if (enabled) { 205 if (enabled)
199 rtc->aie_timer.enabled = 1; 206 err = rtc_timer_enqueue(rtc, &rtc->aie_timer);
200 rtc_timer_enqueue(rtc, &rtc->aie_timer); 207 else
201 } else {
202 rtc_timer_remove(rtc, &rtc->aie_timer); 208 rtc_timer_remove(rtc, &rtc->aie_timer);
203 rtc->aie_timer.enabled = 0;
204 }
205 } 209 }
206 210
211 if (err)
212 return err;
213
207 if (!rtc->ops) 214 if (!rtc->ops)
208 err = -ENODEV; 215 err = -ENODEV;
209 else if (!rtc->ops->alarm_irq_enable) 216 else if (!rtc->ops->alarm_irq_enable)
@@ -235,12 +242,9 @@ int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled)
235 now = rtc_tm_to_ktime(tm); 242 now = rtc_tm_to_ktime(tm);
236 rtc->uie_rtctimer.node.expires = ktime_add(now, onesec); 243 rtc->uie_rtctimer.node.expires = ktime_add(now, onesec);
237 rtc->uie_rtctimer.period = ktime_set(1, 0); 244 rtc->uie_rtctimer.period = ktime_set(1, 0);
238 rtc->uie_rtctimer.enabled = 1; 245 err = rtc_timer_enqueue(rtc, &rtc->uie_rtctimer);
239 rtc_timer_enqueue(rtc, &rtc->uie_rtctimer); 246 } else
240 } else {
241 rtc_timer_remove(rtc, &rtc->uie_rtctimer); 247 rtc_timer_remove(rtc, &rtc->uie_rtctimer);
242 rtc->uie_rtctimer.enabled = 0;
243 }
244 248
245out: 249out:
246 mutex_unlock(&rtc->ops_lock); 250 mutex_unlock(&rtc->ops_lock);
@@ -460,6 +464,9 @@ int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq)
460 int err = 0; 464 int err = 0;
461 unsigned long flags; 465 unsigned long flags;
462 466
467 if (freq <= 0)
468 return -EINVAL;
469
463 spin_lock_irqsave(&rtc->irq_task_lock, flags); 470 spin_lock_irqsave(&rtc->irq_task_lock, flags);
464 if (rtc->irq_task != NULL && task == NULL) 471 if (rtc->irq_task != NULL && task == NULL)
465 err = -EBUSY; 472 err = -EBUSY;
@@ -488,10 +495,13 @@ EXPORT_SYMBOL_GPL(rtc_irq_set_freq);
488 * Enqueues a timer onto the rtc devices timerqueue and sets 495 * Enqueues a timer onto the rtc devices timerqueue and sets
489 * the next alarm event appropriately. 496 * the next alarm event appropriately.
490 * 497 *
498 * Sets the enabled bit on the added timer.
499 *
491 * Must hold ops_lock for proper serialization of timerqueue 500 * Must hold ops_lock for proper serialization of timerqueue
492 */ 501 */
493void rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer) 502static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer)
494{ 503{
504 timer->enabled = 1;
495 timerqueue_add(&rtc->timerqueue, &timer->node); 505 timerqueue_add(&rtc->timerqueue, &timer->node);
496 if (&timer->node == timerqueue_getnext(&rtc->timerqueue)) { 506 if (&timer->node == timerqueue_getnext(&rtc->timerqueue)) {
497 struct rtc_wkalrm alarm; 507 struct rtc_wkalrm alarm;
@@ -501,7 +511,13 @@ void rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer)
501 err = __rtc_set_alarm(rtc, &alarm); 511 err = __rtc_set_alarm(rtc, &alarm);
502 if (err == -ETIME) 512 if (err == -ETIME)
503 schedule_work(&rtc->irqwork); 513 schedule_work(&rtc->irqwork);
514 else if (err) {
515 timerqueue_del(&rtc->timerqueue, &timer->node);
516 timer->enabled = 0;
517 return err;
518 }
504 } 519 }
520 return 0;
505} 521}
506 522
507/** 523/**
@@ -512,13 +528,15 @@ void rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer)
512 * Removes a timer onto the rtc devices timerqueue and sets 528 * Removes a timer onto the rtc devices timerqueue and sets
513 * the next alarm event appropriately. 529 * the next alarm event appropriately.
514 * 530 *
531 * Clears the enabled bit on the removed timer.
532 *
515 * Must hold ops_lock for proper serialization of timerqueue 533 * Must hold ops_lock for proper serialization of timerqueue
516 */ 534 */
517void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer) 535static void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer)
518{ 536{
519 struct timerqueue_node *next = timerqueue_getnext(&rtc->timerqueue); 537 struct timerqueue_node *next = timerqueue_getnext(&rtc->timerqueue);
520 timerqueue_del(&rtc->timerqueue, &timer->node); 538 timerqueue_del(&rtc->timerqueue, &timer->node);
521 539 timer->enabled = 0;
522 if (next == &timer->node) { 540 if (next == &timer->node) {
523 struct rtc_wkalrm alarm; 541 struct rtc_wkalrm alarm;
524 int err; 542 int err;
@@ -626,8 +644,7 @@ int rtc_timer_start(struct rtc_device *rtc, struct rtc_timer* timer,
626 timer->node.expires = expires; 644 timer->node.expires = expires;
627 timer->period = period; 645 timer->period = period;
628 646
629 timer->enabled = 1; 647 ret = rtc_timer_enqueue(rtc, timer);
630 rtc_timer_enqueue(rtc, timer);
631 648
632 mutex_unlock(&rtc->ops_lock); 649 mutex_unlock(&rtc->ops_lock);
633 return ret; 650 return ret;
@@ -645,7 +662,6 @@ int rtc_timer_cancel(struct rtc_device *rtc, struct rtc_timer* timer)
645 mutex_lock(&rtc->ops_lock); 662 mutex_lock(&rtc->ops_lock);
646 if (timer->enabled) 663 if (timer->enabled)
647 rtc_timer_remove(rtc, timer); 664 rtc_timer_remove(rtc, timer);
648 timer->enabled = 0;
649 mutex_unlock(&rtc->ops_lock); 665 mutex_unlock(&rtc->ops_lock);
650 return ret; 666 return ret;
651} 667}