@@ -42,15 +42,72 @@ static struct alarm_base {
42
42
clockid_t base_clockid ;
43
43
} alarm_bases [ALARM_NUMTYPE ];
44
44
45
+ /* freezer delta & lock used to handle clock_nanosleep triggered wakeups */
46
+ static ktime_t freezer_delta ;
47
+ static DEFINE_SPINLOCK (freezer_delta_lock );
48
+
45
49
#ifdef CONFIG_RTC_CLASS
46
50
/* rtc timer and device for setting alarm wakeups at suspend */
47
51
static struct rtc_timer rtctimer ;
48
52
static struct rtc_device * rtcdev ;
49
- #endif
53
+ static DEFINE_SPINLOCK ( rtcdev_lock );
50
54
51
- /* freezer delta & lock used to handle clock_nanosleep triggered wakeups */
52
- static ktime_t freezer_delta ;
53
- static DEFINE_SPINLOCK (freezer_delta_lock );
55
+ /**
56
+ * has_wakealarm - check rtc device has wakealarm ability
57
+ * @dev: current device
58
+ * @name_ptr: name to be returned
59
+ *
60
+ * This helper function checks to see if the rtc device can wake
61
+ * from suspend.
62
+ */
63
+ static int has_wakealarm (struct device * dev , void * name_ptr )
64
+ {
65
+ struct rtc_device * candidate = to_rtc_device (dev );
66
+
67
+ if (!candidate -> ops -> set_alarm )
68
+ return 0 ;
69
+ if (!device_may_wakeup (candidate -> dev .parent ))
70
+ return 0 ;
71
+
72
+ * (const char * * )name_ptr = dev_name (dev );
73
+ return 1 ;
74
+ }
75
+
76
+ /**
77
+ * alarmtimer_get_rtcdev - Return selected rtcdevice
78
+ *
79
+ * This function returns the rtc device to use for wakealarms.
80
+ * If one has not already been chosen, it checks to see if a
81
+ * functional rtc device is available.
82
+ */
83
+ static struct rtc_device * alarmtimer_get_rtcdev (void )
84
+ {
85
+ struct device * dev ;
86
+ char * str ;
87
+ unsigned long flags ;
88
+ struct rtc_device * ret ;
89
+
90
+ spin_lock_irqsave (& rtcdev_lock , flags );
91
+ if (!rtcdev ) {
92
+ /* Find an rtc device and init the rtc_timer */
93
+ dev = class_find_device (rtc_class , NULL , & str , has_wakealarm );
94
+ /* If we have a device then str is valid. See has_wakealarm() */
95
+ if (dev ) {
96
+ rtcdev = rtc_class_open (str );
97
+ /*
98
+ * Drop the reference we got in class_find_device,
99
+ * rtc_open takes its own.
100
+ */
101
+ put_device (dev );
102
+ rtc_timer_init (& rtctimer , NULL , NULL );
103
+ }
104
+ }
105
+ ret = rtcdev ;
106
+ spin_unlock_irqrestore (& rtcdev_lock , flags );
107
+
108
+ return ret ;
109
+ }
110
+ #endif
54
111
55
112
56
113
/**
@@ -166,15 +223,17 @@ static int alarmtimer_suspend(struct device *dev)
166
223
struct rtc_time tm ;
167
224
ktime_t min , now ;
168
225
unsigned long flags ;
226
+ struct rtc_device * rtc ;
169
227
int i ;
170
228
171
229
spin_lock_irqsave (& freezer_delta_lock , flags );
172
230
min = freezer_delta ;
173
231
freezer_delta = ktime_set (0 , 0 );
174
232
spin_unlock_irqrestore (& freezer_delta_lock , flags );
175
233
234
+ rtc = alarmtimer_get_rtcdev ();
176
235
/* If we have no rtcdev, just return */
177
- if (!rtcdev )
236
+ if (!rtc )
178
237
return 0 ;
179
238
180
239
/* Find the soonest timer to expire*/
@@ -199,12 +258,12 @@ static int alarmtimer_suspend(struct device *dev)
199
258
WARN_ON (min .tv64 < NSEC_PER_SEC );
200
259
201
260
/* Setup an rtc timer to fire that far in the future */
202
- rtc_timer_cancel (rtcdev , & rtctimer );
203
- rtc_read_time (rtcdev , & tm );
261
+ rtc_timer_cancel (rtc , & rtctimer );
262
+ rtc_read_time (rtc , & tm );
204
263
now = rtc_tm_to_ktime (tm );
205
264
now = ktime_add (now , min );
206
265
207
- rtc_timer_start (rtcdev , & rtctimer , now , ktime_set (0 , 0 ));
266
+ rtc_timer_start (rtc , & rtctimer , now , ktime_set (0 , 0 ));
208
267
209
268
return 0 ;
210
269
}
@@ -638,65 +697,3 @@ static int __init alarmtimer_init(void)
638
697
}
639
698
device_initcall (alarmtimer_init );
640
699
641
- #ifdef CONFIG_RTC_CLASS
642
- /**
643
- * has_wakealarm - check rtc device has wakealarm ability
644
- * @dev: current device
645
- * @name_ptr: name to be returned
646
- *
647
- * This helper function checks to see if the rtc device can wake
648
- * from suspend.
649
- */
650
- static int __init has_wakealarm (struct device * dev , void * name_ptr )
651
- {
652
- struct rtc_device * candidate = to_rtc_device (dev );
653
-
654
- if (!candidate -> ops -> set_alarm )
655
- return 0 ;
656
- if (!device_may_wakeup (candidate -> dev .parent ))
657
- return 0 ;
658
-
659
- * (const char * * )name_ptr = dev_name (dev );
660
- return 1 ;
661
- }
662
-
663
- /**
664
- * alarmtimer_init_late - Late initializing of alarmtimer code
665
- *
666
- * This function locates a rtc device to use for wakealarms.
667
- * Run as late_initcall to make sure rtc devices have been
668
- * registered.
669
- */
670
- static int __init alarmtimer_init_late (void )
671
- {
672
- struct device * dev ;
673
- char * str ;
674
-
675
- /* Find an rtc device and init the rtc_timer */
676
- dev = class_find_device (rtc_class , NULL , & str , has_wakealarm );
677
- /* If we have a device then str is valid. See has_wakealarm() */
678
- if (dev ) {
679
- rtcdev = rtc_class_open (str );
680
- /*
681
- * Drop the reference we got in class_find_device,
682
- * rtc_open takes its own.
683
- */
684
- put_device (dev );
685
- }
686
- if (!rtcdev ) {
687
- printk (KERN_WARNING "No RTC device found, ALARM timers will"
688
- " not wake from suspend" );
689
- }
690
- rtc_timer_init (& rtctimer , NULL , NULL );
691
-
692
- return 0 ;
693
- }
694
- #else
695
- static int __init alarmtimer_init_late (void )
696
- {
697
- printk (KERN_WARNING "Kernel not built with RTC support, ALARM timers"
698
- " will not wake from suspend" );
699
- return 0 ;
700
- }
701
- #endif
702
- late_initcall (alarmtimer_init_late );
0 commit comments