18
18
struct rtc_test_data {
19
19
struct rtc_device * rtc ;
20
20
time64_t offset ;
21
+ struct timer_list alarm ;
22
+ bool alarm_en ;
21
23
};
22
24
23
25
struct platform_device * pdev [MAX_RTC_TEST ];
24
26
25
- static int test_rtc_read_alarm (struct device * dev ,
26
- struct rtc_wkalrm * alrm )
27
+ static int test_rtc_read_alarm (struct device * dev , struct rtc_wkalrm * alrm )
27
28
{
29
+ struct rtc_test_data * rtd = dev_get_drvdata (dev );
30
+ time64_t alarm ;
31
+
32
+ alarm = (rtd -> alarm .expires - jiffies ) / HZ ;
33
+ alarm += ktime_get_real_seconds () + rtd -> offset ;
34
+
35
+ rtc_time64_to_tm (alarm , & alrm -> time );
36
+ alrm -> enabled = rtd -> alarm_en ;
37
+
28
38
return 0 ;
29
39
}
30
40
31
- static int test_rtc_set_alarm (struct device * dev ,
32
- struct rtc_wkalrm * alrm )
41
+ static int test_rtc_set_alarm (struct device * dev , struct rtc_wkalrm * alrm )
33
42
{
43
+ struct rtc_test_data * rtd = dev_get_drvdata (dev );
44
+ ktime_t timeout ;
45
+ u64 expires ;
46
+
47
+ timeout = rtc_tm_to_time64 (& alrm -> time ) - ktime_get_real_seconds ();
48
+ timeout -= rtd -> offset ;
49
+
50
+ del_timer (& rtd -> alarm );
51
+
52
+ expires = jiffies + timeout * HZ ;
53
+ if (expires > U32_MAX )
54
+ expires = U32_MAX ;
55
+
56
+ pr_err ("ABE: %s +%d %s\n" , __FILE__ , __LINE__ , __func__ );
57
+ rtd -> alarm .expires = expires ;
58
+
59
+ if (alrm -> enabled )
60
+ add_timer (& rtd -> alarm );
61
+
62
+ rtd -> alarm_en = alrm -> enabled ;
63
+
34
64
return 0 ;
35
65
}
36
66
@@ -54,6 +84,14 @@ static int test_rtc_set_mmss64(struct device *dev, time64_t secs)
54
84
55
85
static int test_rtc_alarm_irq_enable (struct device * dev , unsigned int enable )
56
86
{
87
+ struct rtc_test_data * rtd = dev_get_drvdata (dev );
88
+
89
+ rtd -> alarm_en = enable ;
90
+ if (enable )
91
+ add_timer (& rtd -> alarm );
92
+ else
93
+ del_timer (& rtd -> alarm );
94
+
57
95
return 0 ;
58
96
}
59
97
@@ -65,6 +103,13 @@ static const struct rtc_class_ops test_rtc_ops = {
65
103
.alarm_irq_enable = test_rtc_alarm_irq_enable ,
66
104
};
67
105
106
+ static void test_rtc_alarm_handler (struct timer_list * t )
107
+ {
108
+ struct rtc_test_data * rtd = from_timer (rtd , t , alarm );
109
+
110
+ rtc_update_irq (rtd -> rtc , 1 , RTC_AF | RTC_IRQF );
111
+ }
112
+
68
113
static ssize_t test_irq_show (struct device * dev ,
69
114
struct device_attribute * attr , char * buf )
70
115
{
@@ -111,6 +156,9 @@ static int test_probe(struct platform_device *plat_dev)
111
156
if (IS_ERR (rtd -> rtc ))
112
157
return PTR_ERR (rtd -> rtc );
113
158
159
+ timer_setup (& rtd -> alarm , test_rtc_alarm_handler , 0 );
160
+ rtd -> alarm .expires = 0 ;
161
+
114
162
return 0 ;
115
163
}
116
164
0 commit comments