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