Merge tag 'rtc-4.13' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux
[sfrench/cifs-2.6.git] / drivers / rtc / rtc-sysfs.c
1 /*
2  * RTC subsystem, sysfs interface
3  *
4  * Copyright (C) 2005 Tower Technologies
5  * Author: Alessandro Zummo <a.zummo@towertech.it>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10 */
11
12 #include <linux/module.h>
13 #include <linux/rtc.h>
14
15 #include "rtc-core.h"
16
17
18 /* device attributes */
19
20 /*
21  * NOTE:  RTC times displayed in sysfs use the RTC's timezone.  That's
22  * ideally UTC.  However, PCs that also boot to MS-Windows normally use
23  * the local time and change to match daylight savings time.  That affects
24  * attributes including date, time, since_epoch, and wakealarm.
25  */
26
27 static ssize_t
28 name_show(struct device *dev, struct device_attribute *attr, char *buf)
29 {
30         return sprintf(buf, "%s %s\n", dev_driver_string(dev->parent),
31                        dev_name(dev->parent));
32 }
33 static DEVICE_ATTR_RO(name);
34
35 static ssize_t
36 date_show(struct device *dev, struct device_attribute *attr, char *buf)
37 {
38         ssize_t retval;
39         struct rtc_time tm;
40
41         retval = rtc_read_time(to_rtc_device(dev), &tm);
42         if (retval == 0) {
43                 retval = sprintf(buf, "%04d-%02d-%02d\n",
44                         tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
45         }
46
47         return retval;
48 }
49 static DEVICE_ATTR_RO(date);
50
51 static ssize_t
52 time_show(struct device *dev, struct device_attribute *attr, char *buf)
53 {
54         ssize_t retval;
55         struct rtc_time tm;
56
57         retval = rtc_read_time(to_rtc_device(dev), &tm);
58         if (retval == 0) {
59                 retval = sprintf(buf, "%02d:%02d:%02d\n",
60                         tm.tm_hour, tm.tm_min, tm.tm_sec);
61         }
62
63         return retval;
64 }
65 static DEVICE_ATTR_RO(time);
66
67 static ssize_t
68 since_epoch_show(struct device *dev, struct device_attribute *attr, char *buf)
69 {
70         ssize_t retval;
71         struct rtc_time tm;
72
73         retval = rtc_read_time(to_rtc_device(dev), &tm);
74         if (retval == 0) {
75                 unsigned long time;
76                 rtc_tm_to_time(&tm, &time);
77                 retval = sprintf(buf, "%lu\n", time);
78         }
79
80         return retval;
81 }
82 static DEVICE_ATTR_RO(since_epoch);
83
84 static ssize_t
85 max_user_freq_show(struct device *dev, struct device_attribute *attr, char *buf)
86 {
87         return sprintf(buf, "%d\n", to_rtc_device(dev)->max_user_freq);
88 }
89
90 static ssize_t
91 max_user_freq_store(struct device *dev, struct device_attribute *attr,
92                 const char *buf, size_t n)
93 {
94         struct rtc_device *rtc = to_rtc_device(dev);
95         unsigned long val;
96         int err;
97
98         err = kstrtoul(buf, 0, &val);
99         if (err)
100                 return err;
101
102         if (val >= 4096 || val == 0)
103                 return -EINVAL;
104
105         rtc->max_user_freq = (int)val;
106
107         return n;
108 }
109 static DEVICE_ATTR_RW(max_user_freq);
110
111 /**
112  * rtc_sysfs_show_hctosys - indicate if the given RTC set the system time
113  *
114  * Returns 1 if the system clock was set by this RTC at the last
115  * boot or resume event.
116  */
117 static ssize_t
118 hctosys_show(struct device *dev, struct device_attribute *attr, char *buf)
119 {
120 #ifdef CONFIG_RTC_HCTOSYS_DEVICE
121         if (rtc_hctosys_ret == 0 &&
122                         strcmp(dev_name(&to_rtc_device(dev)->dev),
123                                 CONFIG_RTC_HCTOSYS_DEVICE) == 0)
124                 return sprintf(buf, "1\n");
125         else
126 #endif
127                 return sprintf(buf, "0\n");
128 }
129 static DEVICE_ATTR_RO(hctosys);
130
131 static ssize_t
132 wakealarm_show(struct device *dev, struct device_attribute *attr, char *buf)
133 {
134         ssize_t retval;
135         unsigned long alarm;
136         struct rtc_wkalrm alm;
137
138         /* Don't show disabled alarms.  For uniformity, RTC alarms are
139          * conceptually one-shot, even though some common RTCs (on PCs)
140          * don't actually work that way.
141          *
142          * NOTE: RTC implementations where the alarm doesn't match an
143          * exact YYYY-MM-DD HH:MM[:SS] date *must* disable their RTC
144          * alarms after they trigger, to ensure one-shot semantics.
145          */
146         retval = rtc_read_alarm(to_rtc_device(dev), &alm);
147         if (retval == 0 && alm.enabled) {
148                 rtc_tm_to_time(&alm.time, &alarm);
149                 retval = sprintf(buf, "%lu\n", alarm);
150         }
151
152         return retval;
153 }
154
155 static ssize_t
156 wakealarm_store(struct device *dev, struct device_attribute *attr,
157                 const char *buf, size_t n)
158 {
159         ssize_t retval;
160         unsigned long now, alarm;
161         unsigned long push = 0;
162         struct rtc_wkalrm alm;
163         struct rtc_device *rtc = to_rtc_device(dev);
164         const char *buf_ptr;
165         int adjust = 0;
166
167         /* Only request alarms that trigger in the future.  Disable them
168          * by writing another time, e.g. 0 meaning Jan 1 1970 UTC.
169          */
170         retval = rtc_read_time(rtc, &alm.time);
171         if (retval < 0)
172                 return retval;
173         rtc_tm_to_time(&alm.time, &now);
174
175         buf_ptr = buf;
176         if (*buf_ptr == '+') {
177                 buf_ptr++;
178                 if (*buf_ptr == '=') {
179                         buf_ptr++;
180                         push = 1;
181                 } else
182                         adjust = 1;
183         }
184         retval = kstrtoul(buf_ptr, 0, &alarm);
185         if (retval)
186                 return retval;
187         if (adjust) {
188                 alarm += now;
189         }
190         if (alarm > now || push) {
191                 /* Avoid accidentally clobbering active alarms; we can't
192                  * entirely prevent that here, without even the minimal
193                  * locking from the /dev/rtcN api.
194                  */
195                 retval = rtc_read_alarm(rtc, &alm);
196                 if (retval < 0)
197                         return retval;
198                 if (alm.enabled) {
199                         if (push) {
200                                 rtc_tm_to_time(&alm.time, &push);
201                                 alarm += push;
202                         } else
203                                 return -EBUSY;
204                 } else if (push)
205                         return -EINVAL;
206                 alm.enabled = 1;
207         } else {
208                 alm.enabled = 0;
209
210                 /* Provide a valid future alarm time.  Linux isn't EFI,
211                  * this time won't be ignored when disabling the alarm.
212                  */
213                 alarm = now + 300;
214         }
215         rtc_time_to_tm(alarm, &alm.time);
216
217         retval = rtc_set_alarm(rtc, &alm);
218         return (retval < 0) ? retval : n;
219 }
220 static DEVICE_ATTR_RW(wakealarm);
221
222 static ssize_t
223 offset_show(struct device *dev, struct device_attribute *attr, char *buf)
224 {
225         ssize_t retval;
226         long offset;
227
228         retval = rtc_read_offset(to_rtc_device(dev), &offset);
229         if (retval == 0)
230                 retval = sprintf(buf, "%ld\n", offset);
231
232         return retval;
233 }
234
235 static ssize_t
236 offset_store(struct device *dev, struct device_attribute *attr,
237              const char *buf, size_t n)
238 {
239         ssize_t retval;
240         long offset;
241
242         retval = kstrtol(buf, 10, &offset);
243         if (retval == 0)
244                 retval = rtc_set_offset(to_rtc_device(dev), offset);
245
246         return (retval < 0) ? retval : n;
247 }
248 static DEVICE_ATTR_RW(offset);
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         NULL,
260 };
261
262 /* The reason to trigger an alarm with no process watching it (via sysfs)
263  * is its side effect:  waking from a system state like suspend-to-RAM or
264  * suspend-to-disk.  So: no attribute unless that side effect is possible.
265  * (Userspace may disable that mechanism later.)
266  */
267 static bool rtc_does_wakealarm(struct rtc_device *rtc)
268 {
269         if (!device_can_wakeup(rtc->dev.parent))
270                 return false;
271
272         return rtc->ops->set_alarm != NULL;
273 }
274
275 static umode_t rtc_attr_is_visible(struct kobject *kobj,
276                                    struct attribute *attr, int n)
277 {
278         struct device *dev = container_of(kobj, struct device, kobj);
279         struct rtc_device *rtc = to_rtc_device(dev);
280         umode_t mode = attr->mode;
281
282         if (attr == &dev_attr_wakealarm.attr) {
283                 if (!rtc_does_wakealarm(rtc))
284                         mode = 0;
285         } else if (attr == &dev_attr_offset.attr) {
286                 if (!rtc->ops->set_offset)
287                         mode = 0;
288         }
289
290         return mode;
291 }
292
293 static struct attribute_group rtc_attr_group = {
294         .is_visible     = rtc_attr_is_visible,
295         .attrs          = rtc_attrs,
296 };
297
298 static const struct attribute_group *rtc_attr_groups[] = {
299         &rtc_attr_group,
300         NULL
301 };
302
303 const struct attribute_group **rtc_get_dev_attribute_groups(void)
304 {
305         return rtc_attr_groups;
306 }