1
2
3
4
5
6
7
8
9
10
11
12
13
14#include <linux/rtc.h>
15#include <linux/sched.h>
16#include <linux/module.h>
17#include <linux/log2.h>
18#include <linux/workqueue.h>
19
20static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer);
21static void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer);
22
23static int __rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm)
24{
25 int err;
26 if (!rtc->ops)
27 err = -ENODEV;
28 else if (!rtc->ops->read_time)
29 err = -EINVAL;
30 else {
31 memset(tm, 0, sizeof(struct rtc_time));
32 err = rtc->ops->read_time(rtc->dev.parent, tm);
33 }
34 return err;
35}
36
37int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm)
38{
39 int err;
40
41 err = mutex_lock_interruptible(&rtc->ops_lock);
42 if (err)
43 return err;
44
45 err = __rtc_read_time(rtc, tm);
46 mutex_unlock(&rtc->ops_lock);
47 return err;
48}
49EXPORT_SYMBOL_GPL(rtc_read_time);
50
51int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm)
52{
53 int err;
54
55 err = rtc_valid_tm(tm);
56 if (err != 0)
57 return err;
58
59 err = mutex_lock_interruptible(&rtc->ops_lock);
60 if (err)
61 return err;
62
63 if (!rtc->ops)
64 err = -ENODEV;
65 else if (rtc->ops->set_time)
66 err = rtc->ops->set_time(rtc->dev.parent, tm);
67 else if (rtc->ops->set_mmss) {
68 unsigned long secs;
69 err = rtc_tm_to_time(tm, &secs);
70 if (err == 0)
71 err = rtc->ops->set_mmss(rtc->dev.parent, secs);
72 } else
73 err = -EINVAL;
74
75 mutex_unlock(&rtc->ops_lock);
76
77 schedule_work(&rtc->irqwork);
78 return err;
79}
80EXPORT_SYMBOL_GPL(rtc_set_time);
81
82int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs)
83{
84 int err;
85
86 err = mutex_lock_interruptible(&rtc->ops_lock);
87 if (err)
88 return err;
89
90 if (!rtc->ops)
91 err = -ENODEV;
92 else if (rtc->ops->set_mmss)
93 err = rtc->ops->set_mmss(rtc->dev.parent, secs);
94 else if (rtc->ops->read_time && rtc->ops->set_time) {
95 struct rtc_time new, old;
96
97 err = rtc->ops->read_time(rtc->dev.parent, &old);
98 if (err == 0) {
99 rtc_time_to_tm(secs, &new);
100
101
102
103
104
105
106
107 if (!((old.tm_hour == 23 && old.tm_min == 59) ||
108 (new.tm_hour == 23 && new.tm_min == 59)))
109 err = rtc->ops->set_time(rtc->dev.parent,
110 &new);
111 }
112 }
113 else
114 err = -EINVAL;
115
116 mutex_unlock(&rtc->ops_lock);
117
118 schedule_work(&rtc->irqwork);
119
120 return err;
121}
122EXPORT_SYMBOL_GPL(rtc_set_mmss);
123
124static int rtc_read_alarm_internal(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
125{
126 int err;
127
128 err = mutex_lock_interruptible(&rtc->ops_lock);
129 if (err)
130 return err;
131
132 if (rtc->ops == NULL)
133 err = -ENODEV;
134 else if (!rtc->ops->read_alarm)
135 err = -EINVAL;
136 else {
137 memset(alarm, 0, sizeof(struct rtc_wkalrm));
138 err = rtc->ops->read_alarm(rtc->dev.parent, alarm);
139 }
140
141 mutex_unlock(&rtc->ops_lock);
142 return err;
143}
144
145int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
146{
147 int err;
148 struct rtc_time before, now;
149 int first_time = 1;
150 unsigned long t_now, t_alm;
151 enum { none, day, month, year } missing = none;
152 unsigned days;
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196 err = rtc_read_time(rtc, &before);
197 if (err < 0)
198 return err;
199 do {
200 if (!first_time)
201 memcpy(&before, &now, sizeof(struct rtc_time));
202 first_time = 0;
203
204
205 err = rtc_read_alarm_internal(rtc, alarm);
206 if (err)
207 return err;
208
209
210 if (rtc_valid_tm(&alarm->time) == 0)
211 return 0;
212
213
214 err = rtc_read_time(rtc, &now);
215 if (err < 0)
216 return err;
217
218
219 } while ( before.tm_min != now.tm_min
220 || before.tm_hour != now.tm_hour
221 || before.tm_mon != now.tm_mon
222 || before.tm_year != now.tm_year);
223
224
225
226
227 if (alarm->time.tm_sec == -1)
228 alarm->time.tm_sec = now.tm_sec;
229 if (alarm->time.tm_min == -1)
230 alarm->time.tm_min = now.tm_min;
231 if (alarm->time.tm_hour == -1)
232 alarm->time.tm_hour = now.tm_hour;
233
234
235 if (alarm->time.tm_mday < 1 || alarm->time.tm_mday > 31) {
236 alarm->time.tm_mday = now.tm_mday;
237 missing = day;
238 }
239 if ((unsigned)alarm->time.tm_mon >= 12) {
240 alarm->time.tm_mon = now.tm_mon;
241 if (missing == none)
242 missing = month;
243 }
244 if (alarm->time.tm_year == -1) {
245 alarm->time.tm_year = now.tm_year;
246 if (missing == none)
247 missing = year;
248 }
249
250
251
252
253 err = rtc_valid_tm(&alarm->time);
254 if (err)
255 goto done;
256
257
258 rtc_tm_to_time(&now, &t_now);
259 rtc_tm_to_time(&alarm->time, &t_alm);
260 if (t_now < t_alm)
261 goto done;
262
263 switch (missing) {
264
265
266
267
268
269
270 case day:
271 dev_dbg(&rtc->dev, "alarm rollover: %s\n", "day");
272 t_alm += 24 * 60 * 60;
273 rtc_time_to_tm(t_alm, &alarm->time);
274 break;
275
276
277
278
279
280
281 case month:
282 dev_dbg(&rtc->dev, "alarm rollover: %s\n", "month");
283 do {
284 if (alarm->time.tm_mon < 11)
285 alarm->time.tm_mon++;
286 else {
287 alarm->time.tm_mon = 0;
288 alarm->time.tm_year++;
289 }
290 days = rtc_month_days(alarm->time.tm_mon,
291 alarm->time.tm_year);
292 } while (days < alarm->time.tm_mday);
293 break;
294
295
296 case year:
297 dev_dbg(&rtc->dev, "alarm rollover: %s\n", "year");
298 do {
299 alarm->time.tm_year++;
300 } while (!is_leap_year(alarm->time.tm_year + 1900)
301 && rtc_valid_tm(&alarm->time) != 0);
302 break;
303
304 default:
305 dev_warn(&rtc->dev, "alarm rollover not handled\n");
306 }
307
308 err = rtc_valid_tm(&alarm->time);
309
310done:
311 if (err) {
312 dev_warn(&rtc->dev, "invalid alarm value: %d-%d-%d %d:%d:%d\n",
313 alarm->time.tm_year + 1900, alarm->time.tm_mon + 1,
314 alarm->time.tm_mday, alarm->time.tm_hour, alarm->time.tm_min,
315 alarm->time.tm_sec);
316 }
317
318 return err;
319}
320
321int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
322{
323 int err;
324
325 err = mutex_lock_interruptible(&rtc->ops_lock);
326 if (err)
327 return err;
328 if (rtc->ops == NULL)
329 err = -ENODEV;
330 else if (!rtc->ops->read_alarm)
331 err = -EINVAL;
332 else {
333 memset(alarm, 0, sizeof(struct rtc_wkalrm));
334 alarm->enabled = rtc->aie_timer.enabled;
335 alarm->time = rtc_ktime_to_tm(rtc->aie_timer.node.expires);
336 }
337 mutex_unlock(&rtc->ops_lock);
338
339 return err;
340}
341EXPORT_SYMBOL_GPL(rtc_read_alarm);
342
343static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
344{
345 struct rtc_time tm;
346 long now, scheduled;
347 int err;
348
349 err = rtc_valid_tm(&alarm->time);
350 if (err)
351 return err;
352 rtc_tm_to_time(&alarm->time, &scheduled);
353
354
355 err = __rtc_read_time(rtc, &tm);
356 rtc_tm_to_time(&tm, &now);
357 if (scheduled <= now)
358 return -ETIME;
359
360
361
362
363
364
365
366 if (!rtc->ops)
367 err = -ENODEV;
368 else if (!rtc->ops->set_alarm)
369 err = -EINVAL;
370 else
371 err = rtc->ops->set_alarm(rtc->dev.parent, alarm);
372
373 return err;
374}
375
376int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
377{
378 int err;
379
380 err = rtc_valid_tm(&alarm->time);
381 if (err != 0)
382 return err;
383
384 err = mutex_lock_interruptible(&rtc->ops_lock);
385 if (err)
386 return err;
387 if (rtc->aie_timer.enabled) {
388 rtc_timer_remove(rtc, &rtc->aie_timer);
389 }
390 rtc->aie_timer.node.expires = rtc_tm_to_ktime(alarm->time);
391 rtc->aie_timer.period = ktime_set(0, 0);
392 if (alarm->enabled) {
393 err = rtc_timer_enqueue(rtc, &rtc->aie_timer);
394 }
395 mutex_unlock(&rtc->ops_lock);
396 return err;
397}
398EXPORT_SYMBOL_GPL(rtc_set_alarm);
399
400
401int rtc_initialize_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
402{
403 int err;
404 struct rtc_time now;
405
406 err = rtc_valid_tm(&alarm->time);
407 if (err != 0)
408 return err;
409
410 err = rtc_read_time(rtc, &now);
411 if (err)
412 return err;
413
414 err = mutex_lock_interruptible(&rtc->ops_lock);
415 if (err)
416 return err;
417
418 rtc->aie_timer.node.expires = rtc_tm_to_ktime(alarm->time);
419 rtc->aie_timer.period = ktime_set(0, 0);
420
421
422 if (alarm->enabled && (rtc_tm_to_ktime(now).tv64 <
423 rtc->aie_timer.node.expires.tv64)) {
424
425 rtc->aie_timer.enabled = 1;
426 timerqueue_add(&rtc->timerqueue, &rtc->aie_timer.node);
427 }
428 mutex_unlock(&rtc->ops_lock);
429 return err;
430}
431EXPORT_SYMBOL_GPL(rtc_initialize_alarm);
432
433
434
435int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled)
436{
437 int err = mutex_lock_interruptible(&rtc->ops_lock);
438 if (err)
439 return err;
440
441 if (rtc->aie_timer.enabled != enabled) {
442 if (enabled)
443 err = rtc_timer_enqueue(rtc, &rtc->aie_timer);
444 else
445 rtc_timer_remove(rtc, &rtc->aie_timer);
446 }
447
448 if (err)
449 ;
450 else if (!rtc->ops)
451 err = -ENODEV;
452 else if (!rtc->ops->alarm_irq_enable)
453 err = -EINVAL;
454 else
455 err = rtc->ops->alarm_irq_enable(rtc->dev.parent, enabled);
456
457 mutex_unlock(&rtc->ops_lock);
458 return err;
459}
460EXPORT_SYMBOL_GPL(rtc_alarm_irq_enable);
461
462int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled)
463{
464 int err = mutex_lock_interruptible(&rtc->ops_lock);
465 if (err)
466 return err;
467
468#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
469 if (enabled == 0 && rtc->uie_irq_active) {
470 mutex_unlock(&rtc->ops_lock);
471 return rtc_dev_update_irq_enable_emul(rtc, 0);
472 }
473#endif
474
475 if (rtc->uie_rtctimer.enabled == enabled)
476 goto out;
477
478 if (rtc->uie_unsupported) {
479 err = -EINVAL;
480 goto out;
481 }
482
483 if (enabled) {
484 struct rtc_time tm;
485 ktime_t now, onesec;
486
487 __rtc_read_time(rtc, &tm);
488 onesec = ktime_set(1, 0);
489 now = rtc_tm_to_ktime(tm);
490 rtc->uie_rtctimer.node.expires = ktime_add(now, onesec);
491 rtc->uie_rtctimer.period = ktime_set(1, 0);
492 err = rtc_timer_enqueue(rtc, &rtc->uie_rtctimer);
493 } else
494 rtc_timer_remove(rtc, &rtc->uie_rtctimer);
495
496out:
497 mutex_unlock(&rtc->ops_lock);
498#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
499
500
501
502
503
504
505 if (err == -EINVAL)
506 err = rtc_dev_update_irq_enable_emul(rtc, enabled);
507#endif
508 return err;
509
510}
511EXPORT_SYMBOL_GPL(rtc_update_irq_enable);
512
513
514
515
516
517
518
519
520
521
522
523void rtc_handle_legacy_irq(struct rtc_device *rtc, int num, int mode)
524{
525 unsigned long flags;
526
527
528 spin_lock_irqsave(&rtc->irq_lock, flags);
529 rtc->irq_data = (rtc->irq_data + (num << 8)) | (RTC_IRQF|mode);
530 spin_unlock_irqrestore(&rtc->irq_lock, flags);
531
532
533 spin_lock_irqsave(&rtc->irq_task_lock, flags);
534 if (rtc->irq_task)
535 rtc->irq_task->func(rtc->irq_task->private_data);
536 spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
537
538 wake_up_interruptible(&rtc->irq_queue);
539 kill_fasync(&rtc->async_queue, SIGIO, POLL_IN);
540}
541
542
543
544
545
546
547
548
549void rtc_aie_update_irq(void *private)
550{
551 struct rtc_device *rtc = (struct rtc_device *)private;
552 rtc_handle_legacy_irq(rtc, 1, RTC_AF);
553}
554
555
556
557
558
559
560
561
562void rtc_uie_update_irq(void *private)
563{
564 struct rtc_device *rtc = (struct rtc_device *)private;
565 rtc_handle_legacy_irq(rtc, 1, RTC_UF);
566}
567
568
569
570
571
572
573
574
575
576
577enum hrtimer_restart rtc_pie_update_irq(struct hrtimer *timer)
578{
579 struct rtc_device *rtc;
580 ktime_t period;
581 int count;
582 rtc = container_of(timer, struct rtc_device, pie_timer);
583
584 period = ktime_set(0, NSEC_PER_SEC/rtc->irq_freq);
585 count = hrtimer_forward_now(timer, period);
586
587 rtc_handle_legacy_irq(rtc, count, RTC_PF);
588
589 return HRTIMER_RESTART;
590}
591
592
593
594
595
596
597
598
599void rtc_update_irq(struct rtc_device *rtc,
600 unsigned long num, unsigned long events)
601{
602 pm_stay_awake(rtc->dev.parent);
603 schedule_work(&rtc->irqwork);
604}
605EXPORT_SYMBOL_GPL(rtc_update_irq);
606
607static int __rtc_match(struct device *dev, const void *data)
608{
609 const char *name = data;
610
611 if (strcmp(dev_name(dev), name) == 0)
612 return 1;
613 return 0;
614}
615
616struct rtc_device *rtc_class_open(const char *name)
617{
618 struct device *dev;
619 struct rtc_device *rtc = NULL;
620
621 dev = class_find_device(rtc_class, NULL, name, __rtc_match);
622 if (dev)
623 rtc = to_rtc_device(dev);
624
625 if (rtc) {
626 if (!try_module_get(rtc->owner)) {
627 put_device(dev);
628 rtc = NULL;
629 }
630 }
631
632 return rtc;
633}
634EXPORT_SYMBOL_GPL(rtc_class_open);
635
636void rtc_class_close(struct rtc_device *rtc)
637{
638 module_put(rtc->owner);
639 put_device(&rtc->dev);
640}
641EXPORT_SYMBOL_GPL(rtc_class_close);
642
643int rtc_irq_register(struct rtc_device *rtc, struct rtc_task *task)
644{
645 int retval = -EBUSY;
646
647 if (task == NULL || task->func == NULL)
648 return -EINVAL;
649
650
651 if (test_and_set_bit_lock(RTC_DEV_BUSY, &rtc->flags))
652 return -EBUSY;
653
654 spin_lock_irq(&rtc->irq_task_lock);
655 if (rtc->irq_task == NULL) {
656 rtc->irq_task = task;
657 retval = 0;
658 }
659 spin_unlock_irq(&rtc->irq_task_lock);
660
661 clear_bit_unlock(RTC_DEV_BUSY, &rtc->flags);
662
663 return retval;
664}
665EXPORT_SYMBOL_GPL(rtc_irq_register);
666
667void rtc_irq_unregister(struct rtc_device *rtc, struct rtc_task *task)
668{
669 spin_lock_irq(&rtc->irq_task_lock);
670 if (rtc->irq_task == task)
671 rtc->irq_task = NULL;
672 spin_unlock_irq(&rtc->irq_task_lock);
673}
674EXPORT_SYMBOL_GPL(rtc_irq_unregister);
675
676static int rtc_update_hrtimer(struct rtc_device *rtc, int enabled)
677{
678
679
680
681
682
683
684
685
686
687
688 if (hrtimer_try_to_cancel(&rtc->pie_timer) < 0)
689 return -1;
690
691 if (enabled) {
692 ktime_t period = ktime_set(0, NSEC_PER_SEC / rtc->irq_freq);
693
694 hrtimer_start(&rtc->pie_timer, period, HRTIMER_MODE_REL);
695 }
696 return 0;
697}
698
699
700
701
702
703
704
705
706
707
708
709int rtc_irq_set_state(struct rtc_device *rtc, struct rtc_task *task, int enabled)
710{
711 int err = 0;
712 unsigned long flags;
713
714retry:
715 spin_lock_irqsave(&rtc->irq_task_lock, flags);
716 if (rtc->irq_task != NULL && task == NULL)
717 err = -EBUSY;
718 if (rtc->irq_task != task)
719 err = -EACCES;
720 if (!err) {
721 if (rtc_update_hrtimer(rtc, enabled) < 0) {
722 spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
723 cpu_relax();
724 goto retry;
725 }
726 rtc->pie_enabled = enabled;
727 }
728 spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
729 return err;
730}
731EXPORT_SYMBOL_GPL(rtc_irq_set_state);
732
733
734
735
736
737
738
739
740
741
742
743int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq)
744{
745 int err = 0;
746 unsigned long flags;
747
748 if (freq <= 0 || freq > RTC_MAX_FREQ)
749 return -EINVAL;
750retry:
751 spin_lock_irqsave(&rtc->irq_task_lock, flags);
752 if (rtc->irq_task != NULL && task == NULL)
753 err = -EBUSY;
754 if (rtc->irq_task != task)
755 err = -EACCES;
756 if (!err) {
757 rtc->irq_freq = freq;
758 if (rtc->pie_enabled && rtc_update_hrtimer(rtc, 1) < 0) {
759 spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
760 cpu_relax();
761 goto retry;
762 }
763 }
764 spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
765 return err;
766}
767EXPORT_SYMBOL_GPL(rtc_irq_set_freq);
768
769
770
771
772
773
774
775
776
777
778
779
780
781static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer)
782{
783 timer->enabled = 1;
784 timerqueue_add(&rtc->timerqueue, &timer->node);
785 if (&timer->node == timerqueue_getnext(&rtc->timerqueue)) {
786 struct rtc_wkalrm alarm;
787 int err;
788 alarm.time = rtc_ktime_to_tm(timer->node.expires);
789 alarm.enabled = 1;
790 err = __rtc_set_alarm(rtc, &alarm);
791 if (err == -ETIME)
792 schedule_work(&rtc->irqwork);
793 else if (err) {
794 timerqueue_del(&rtc->timerqueue, &timer->node);
795 timer->enabled = 0;
796 return err;
797 }
798 }
799 return 0;
800}
801
802static void rtc_alarm_disable(struct rtc_device *rtc)
803{
804 if (!rtc->ops || !rtc->ops->alarm_irq_enable)
805 return;
806
807 rtc->ops->alarm_irq_enable(rtc->dev.parent, false);
808}
809
810
811
812
813
814
815
816
817
818
819
820
821
822static void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer)
823{
824 struct timerqueue_node *next = timerqueue_getnext(&rtc->timerqueue);
825 timerqueue_del(&rtc->timerqueue, &timer->node);
826 timer->enabled = 0;
827 if (next == &timer->node) {
828 struct rtc_wkalrm alarm;
829 int err;
830 next = timerqueue_getnext(&rtc->timerqueue);
831 if (!next) {
832 rtc_alarm_disable(rtc);
833 return;
834 }
835 alarm.time = rtc_ktime_to_tm(next->expires);
836 alarm.enabled = 1;
837 err = __rtc_set_alarm(rtc, &alarm);
838 if (err == -ETIME)
839 schedule_work(&rtc->irqwork);
840 }
841}
842
843
844
845
846
847
848
849
850
851
852
853void rtc_timer_do_work(struct work_struct *work)
854{
855 struct rtc_timer *timer;
856 struct timerqueue_node *next;
857 ktime_t now;
858 struct rtc_time tm;
859
860 struct rtc_device *rtc =
861 container_of(work, struct rtc_device, irqwork);
862
863 mutex_lock(&rtc->ops_lock);
864again:
865 pm_relax(rtc->dev.parent);
866 __rtc_read_time(rtc, &tm);
867 now = rtc_tm_to_ktime(tm);
868 while ((next = timerqueue_getnext(&rtc->timerqueue))) {
869 if (next->expires.tv64 > now.tv64)
870 break;
871
872
873 timer = container_of(next, struct rtc_timer, node);
874 timerqueue_del(&rtc->timerqueue, &timer->node);
875 timer->enabled = 0;
876 if (timer->task.func)
877 timer->task.func(timer->task.private_data);
878
879
880 if (ktime_to_ns(timer->period)) {
881 timer->node.expires = ktime_add(timer->node.expires,
882 timer->period);
883 timer->enabled = 1;
884 timerqueue_add(&rtc->timerqueue, &timer->node);
885 }
886 }
887
888
889 if (next) {
890 struct rtc_wkalrm alarm;
891 int err;
892 alarm.time = rtc_ktime_to_tm(next->expires);
893 alarm.enabled = 1;
894 err = __rtc_set_alarm(rtc, &alarm);
895 if (err == -ETIME)
896 goto again;
897 } else
898 rtc_alarm_disable(rtc);
899
900 mutex_unlock(&rtc->ops_lock);
901}
902
903
904
905
906
907
908
909
910
911void rtc_timer_init(struct rtc_timer *timer, void (*f)(void* p), void* data)
912{
913 timerqueue_init(&timer->node);
914 timer->enabled = 0;
915 timer->task.func = f;
916 timer->task.private_data = data;
917}
918
919
920
921
922
923
924
925
926
927int rtc_timer_start(struct rtc_device *rtc, struct rtc_timer* timer,
928 ktime_t expires, ktime_t period)
929{
930 int ret = 0;
931 mutex_lock(&rtc->ops_lock);
932 if (timer->enabled)
933 rtc_timer_remove(rtc, timer);
934
935 timer->node.expires = expires;
936 timer->period = period;
937
938 ret = rtc_timer_enqueue(rtc, timer);
939
940 mutex_unlock(&rtc->ops_lock);
941 return ret;
942}
943
944
945
946
947
948
949
950int rtc_timer_cancel(struct rtc_device *rtc, struct rtc_timer* timer)
951{
952 int ret = 0;
953 mutex_lock(&rtc->ops_lock);
954 if (timer->enabled)
955 rtc_timer_remove(rtc, timer);
956 mutex_unlock(&rtc->ops_lock);
957 return ret;
958}
959
960
961