Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0
2 : /*
3 : * RTC subsystem, sysfs interface
4 : *
5 : * Copyright (C) 2005 Tower Technologies
6 : * Author: Alessandro Zummo <a.zummo@towertech.it>
7 : */
8 :
9 : #include <linux/module.h>
10 : #include <linux/rtc.h>
11 :
12 : #include "rtc-core.h"
13 :
14 : /* device attributes */
15 :
16 : /*
17 : * NOTE: RTC times displayed in sysfs use the RTC's timezone. That's
18 : * ideally UTC. However, PCs that also boot to MS-Windows normally use
19 : * the local time and change to match daylight savings time. That affects
20 : * attributes including date, time, since_epoch, and wakealarm.
21 : */
22 :
23 : static ssize_t
24 0 : name_show(struct device *dev, struct device_attribute *attr, char *buf)
25 : {
26 0 : return sprintf(buf, "%s %s\n", dev_driver_string(dev->parent),
27 0 : dev_name(dev->parent));
28 : }
29 : static DEVICE_ATTR_RO(name);
30 :
31 : static ssize_t
32 0 : date_show(struct device *dev, struct device_attribute *attr, char *buf)
33 : {
34 0 : ssize_t retval;
35 0 : struct rtc_time tm;
36 :
37 0 : retval = rtc_read_time(to_rtc_device(dev), &tm);
38 0 : if (retval)
39 : return retval;
40 :
41 0 : return sprintf(buf, "%ptRd\n", &tm);
42 : }
43 : static DEVICE_ATTR_RO(date);
44 :
45 : static ssize_t
46 0 : time_show(struct device *dev, struct device_attribute *attr, char *buf)
47 : {
48 0 : ssize_t retval;
49 0 : struct rtc_time tm;
50 :
51 0 : retval = rtc_read_time(to_rtc_device(dev), &tm);
52 0 : if (retval)
53 : return retval;
54 :
55 0 : return sprintf(buf, "%ptRt\n", &tm);
56 : }
57 : static DEVICE_ATTR_RO(time);
58 :
59 : static ssize_t
60 0 : since_epoch_show(struct device *dev, struct device_attribute *attr, char *buf)
61 : {
62 0 : ssize_t retval;
63 0 : struct rtc_time tm;
64 :
65 0 : retval = rtc_read_time(to_rtc_device(dev), &tm);
66 0 : if (retval == 0) {
67 0 : time64_t time;
68 :
69 0 : time = rtc_tm_to_time64(&tm);
70 0 : retval = sprintf(buf, "%lld\n", time);
71 : }
72 :
73 0 : return retval;
74 : }
75 : static DEVICE_ATTR_RO(since_epoch);
76 :
77 : static ssize_t
78 0 : max_user_freq_show(struct device *dev, struct device_attribute *attr, char *buf)
79 : {
80 0 : return sprintf(buf, "%d\n", to_rtc_device(dev)->max_user_freq);
81 : }
82 :
83 : static ssize_t
84 0 : max_user_freq_store(struct device *dev, struct device_attribute *attr,
85 : const char *buf, size_t n)
86 : {
87 0 : struct rtc_device *rtc = to_rtc_device(dev);
88 0 : unsigned long val;
89 0 : int err;
90 :
91 0 : err = kstrtoul(buf, 0, &val);
92 0 : if (err)
93 0 : return err;
94 :
95 0 : if (val >= 4096 || val == 0)
96 : return -EINVAL;
97 :
98 0 : rtc->max_user_freq = (int)val;
99 :
100 0 : return n;
101 : }
102 : static DEVICE_ATTR_RW(max_user_freq);
103 :
104 : /**
105 : * rtc_sysfs_show_hctosys - indicate if the given RTC set the system time
106 : * @dev: The device that the attribute belongs to.
107 : * @attr: The attribute being read.
108 : * @buf: The result buffer.
109 : *
110 : * buf is "1" if the system clock was set by this RTC at the last
111 : * boot or resume event.
112 : */
113 : static ssize_t
114 0 : hctosys_show(struct device *dev, struct device_attribute *attr, char *buf)
115 : {
116 : #ifdef CONFIG_RTC_HCTOSYS_DEVICE
117 0 : if (rtc_hctosys_ret == 0 &&
118 0 : strcmp(dev_name(&to_rtc_device(dev)->dev),
119 : CONFIG_RTC_HCTOSYS_DEVICE) == 0)
120 0 : return sprintf(buf, "1\n");
121 : #endif
122 0 : return sprintf(buf, "0\n");
123 : }
124 : static DEVICE_ATTR_RO(hctosys);
125 :
126 : static ssize_t
127 0 : wakealarm_show(struct device *dev, struct device_attribute *attr, char *buf)
128 : {
129 0 : ssize_t retval;
130 0 : time64_t alarm;
131 0 : struct rtc_wkalrm alm;
132 :
133 : /* Don't show disabled alarms. For uniformity, RTC alarms are
134 : * conceptually one-shot, even though some common RTCs (on PCs)
135 : * don't actually work that way.
136 : *
137 : * NOTE: RTC implementations where the alarm doesn't match an
138 : * exact YYYY-MM-DD HH:MM[:SS] date *must* disable their RTC
139 : * alarms after they trigger, to ensure one-shot semantics.
140 : */
141 0 : retval = rtc_read_alarm(to_rtc_device(dev), &alm);
142 0 : if (retval == 0 && alm.enabled) {
143 0 : alarm = rtc_tm_to_time64(&alm.time);
144 0 : retval = sprintf(buf, "%lld\n", alarm);
145 : }
146 :
147 0 : return retval;
148 : }
149 :
150 : static ssize_t
151 0 : wakealarm_store(struct device *dev, struct device_attribute *attr,
152 : const char *buf, size_t n)
153 : {
154 0 : ssize_t retval;
155 0 : time64_t now, alarm;
156 0 : time64_t push = 0;
157 0 : struct rtc_wkalrm alm;
158 0 : struct rtc_device *rtc = to_rtc_device(dev);
159 0 : const char *buf_ptr;
160 0 : int adjust = 0;
161 :
162 : /* Only request alarms that trigger in the future. Disable them
163 : * by writing another time, e.g. 0 meaning Jan 1 1970 UTC.
164 : */
165 0 : retval = rtc_read_time(rtc, &alm.time);
166 0 : if (retval < 0)
167 : return retval;
168 0 : now = rtc_tm_to_time64(&alm.time);
169 :
170 0 : buf_ptr = buf;
171 0 : if (*buf_ptr == '+') {
172 0 : buf_ptr++;
173 0 : if (*buf_ptr == '=') {
174 0 : buf_ptr++;
175 0 : push = 1;
176 : } else {
177 : adjust = 1;
178 : }
179 : }
180 0 : retval = kstrtos64(buf_ptr, 0, &alarm);
181 0 : if (retval)
182 : return retval;
183 0 : if (adjust)
184 0 : alarm += now;
185 0 : if (alarm > now || push) {
186 : /* Avoid accidentally clobbering active alarms; we can't
187 : * entirely prevent that here, without even the minimal
188 : * locking from the /dev/rtcN api.
189 : */
190 0 : retval = rtc_read_alarm(rtc, &alm);
191 0 : if (retval < 0)
192 : return retval;
193 0 : if (alm.enabled) {
194 0 : if (push) {
195 0 : push = rtc_tm_to_time64(&alm.time);
196 0 : alarm += push;
197 : } else
198 : return -EBUSY;
199 0 : } else if (push)
200 : return -EINVAL;
201 0 : alm.enabled = 1;
202 : } else {
203 0 : alm.enabled = 0;
204 :
205 : /* Provide a valid future alarm time. Linux isn't EFI,
206 : * this time won't be ignored when disabling the alarm.
207 : */
208 0 : alarm = now + 300;
209 : }
210 0 : rtc_time64_to_tm(alarm, &alm.time);
211 :
212 0 : retval = rtc_set_alarm(rtc, &alm);
213 0 : return (retval < 0) ? retval : n;
214 : }
215 : static DEVICE_ATTR_RW(wakealarm);
216 :
217 : static ssize_t
218 0 : offset_show(struct device *dev, struct device_attribute *attr, char *buf)
219 : {
220 0 : ssize_t retval;
221 0 : long offset;
222 :
223 0 : retval = rtc_read_offset(to_rtc_device(dev), &offset);
224 0 : if (retval == 0)
225 0 : retval = sprintf(buf, "%ld\n", offset);
226 :
227 0 : return retval;
228 : }
229 :
230 : static ssize_t
231 0 : offset_store(struct device *dev, struct device_attribute *attr,
232 : const char *buf, size_t n)
233 : {
234 0 : ssize_t retval;
235 0 : long offset;
236 :
237 0 : retval = kstrtol(buf, 10, &offset);
238 0 : if (retval == 0)
239 0 : retval = rtc_set_offset(to_rtc_device(dev), offset);
240 :
241 0 : return (retval < 0) ? retval : n;
242 : }
243 : static DEVICE_ATTR_RW(offset);
244 :
245 : static ssize_t
246 0 : range_show(struct device *dev, struct device_attribute *attr, char *buf)
247 : {
248 0 : return sprintf(buf, "[%lld,%llu]\n", to_rtc_device(dev)->range_min,
249 0 : to_rtc_device(dev)->range_max);
250 : }
251 : static DEVICE_ATTR_RO(range);
252 :
253 : static struct attribute *rtc_attrs[] = {
254 : &dev_attr_name.attr,
255 : &dev_attr_date.attr,
256 : &dev_attr_time.attr,
257 : &dev_attr_since_epoch.attr,
258 : &dev_attr_max_user_freq.attr,
259 : &dev_attr_hctosys.attr,
260 : &dev_attr_wakealarm.attr,
261 : &dev_attr_offset.attr,
262 : &dev_attr_range.attr,
263 : NULL,
264 : };
265 :
266 : /* The reason to trigger an alarm with no process watching it (via sysfs)
267 : * is its side effect: waking from a system state like suspend-to-RAM or
268 : * suspend-to-disk. So: no attribute unless that side effect is possible.
269 : * (Userspace may disable that mechanism later.)
270 : */
271 0 : static bool rtc_does_wakealarm(struct rtc_device *rtc)
272 : {
273 0 : if (!device_can_wakeup(rtc->dev.parent))
274 : return false;
275 :
276 0 : return rtc->ops->set_alarm != NULL;
277 : }
278 :
279 0 : static umode_t rtc_attr_is_visible(struct kobject *kobj,
280 : struct attribute *attr, int n)
281 : {
282 0 : struct device *dev = kobj_to_dev(kobj);
283 0 : struct rtc_device *rtc = to_rtc_device(dev);
284 0 : umode_t mode = attr->mode;
285 :
286 0 : if (attr == &dev_attr_wakealarm.attr) {
287 0 : if (!rtc_does_wakealarm(rtc))
288 0 : mode = 0;
289 0 : } else if (attr == &dev_attr_offset.attr) {
290 0 : if (!rtc->ops->set_offset)
291 0 : mode = 0;
292 0 : } else if (attr == &dev_attr_range.attr) {
293 0 : if (!(rtc->range_max - rtc->range_min))
294 0 : mode = 0;
295 : }
296 :
297 0 : return mode;
298 : }
299 :
300 : static struct attribute_group rtc_attr_group = {
301 : .is_visible = rtc_attr_is_visible,
302 : .attrs = rtc_attrs,
303 : };
304 :
305 : static const struct attribute_group *rtc_attr_groups[] = {
306 : &rtc_attr_group,
307 : NULL
308 : };
309 :
310 1 : const struct attribute_group **rtc_get_dev_attribute_groups(void)
311 : {
312 1 : return rtc_attr_groups;
313 : }
314 :
315 0 : int rtc_add_groups(struct rtc_device *rtc, const struct attribute_group **grps)
316 : {
317 0 : size_t old_cnt = 0, add_cnt = 0, new_cnt;
318 0 : const struct attribute_group **groups, **old;
319 :
320 0 : if (!grps)
321 : return -EINVAL;
322 :
323 0 : groups = rtc->dev.groups;
324 0 : if (groups)
325 0 : for (; *groups; groups++)
326 0 : old_cnt++;
327 :
328 0 : for (groups = grps; *groups; groups++)
329 0 : add_cnt++;
330 :
331 0 : new_cnt = old_cnt + add_cnt + 1;
332 0 : groups = devm_kcalloc(&rtc->dev, new_cnt, sizeof(*groups), GFP_KERNEL);
333 0 : if (!groups)
334 0 : return -ENOMEM;
335 0 : memcpy(groups, rtc->dev.groups, old_cnt * sizeof(*groups));
336 0 : memcpy(groups + old_cnt, grps, add_cnt * sizeof(*groups));
337 0 : groups[old_cnt + add_cnt] = NULL;
338 :
339 0 : old = rtc->dev.groups;
340 0 : rtc->dev.groups = groups;
341 0 : if (old && old != rtc_attr_groups)
342 0 : devm_kfree(&rtc->dev, old);
343 :
344 : return 0;
345 : }
346 : EXPORT_SYMBOL(rtc_add_groups);
347 :
348 0 : int rtc_add_group(struct rtc_device *rtc, const struct attribute_group *grp)
349 : {
350 0 : const struct attribute_group *groups[] = { grp, NULL };
351 :
352 0 : return rtc_add_groups(rtc, groups);
353 : }
354 : EXPORT_SYMBOL(rtc_add_group);
|