aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-sysfs.c
diff options
context:
space:
mode:
authorBernie Thompson <bhthompson@chromium.org>2013-07-03 18:07:03 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-07-03 19:07:54 -0400
commit1df0a4711f6e93c1073dd82f6e7905748842e2b3 (patch)
tree4a885c99a414d23d5be468b75aa8ea68109d1081 /drivers/rtc/rtc-sysfs.c
parentc67d96e317510e63e8a24d3a5742dd47b21c3340 (diff)
rtc: add ability to push out an existing wakealarm using sysfs
This adds the ability for the rtc sysfs code to handle += characters at the beginning of a wakealarm setting string. This will allow the user to attempt to push out an existing wakealarm by a provided amount. In the case that the += characters are provided but the alarm is not active -EINVAL is returned. his is useful, at least for my purposes in suspend/resume testing. The basic test goes something like: 1. Set a wake alarm from userspace 5 seconds in the future 2. Start the suspend process (echo mem > /sys/power/state) 3. After ~2.5 seconds if userspace is still running (using another thread to check this), move the wake alarm 5 more seconds If the "move" involves an unset of the wakealarm then there's a period of time where the system is midway through suspending but has no wake alarm. It will get stuck. We'd rather not remove the "move" since the idea is to avoid a cancelled suspend when the alarm fires _during_ suspend. It is difficult for the test to tell the difference between a suspend that was cancelled because the alarm fired too early and a suspend that was Signed-off-by: Bernie Thompson <bhthompson@chromium.org> Cc: Alessandro Zummo <a.zummo@towertech.it> Cc: Doug Anderson <dianders@chromium.org> Cc: "Rafael J. Wysocki" <rjw@sisk.pl> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/rtc/rtc-sysfs.c')
-rw-r--r--drivers/rtc/rtc-sysfs.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/drivers/rtc/rtc-sysfs.c b/drivers/rtc/rtc-sysfs.c
index b70e2bb63645..4b26f8672b2d 100644
--- a/drivers/rtc/rtc-sysfs.c
+++ b/drivers/rtc/rtc-sysfs.c
@@ -164,6 +164,7 @@ rtc_sysfs_set_wakealarm(struct device *dev, struct device_attribute *attr,
164{ 164{
165 ssize_t retval; 165 ssize_t retval;
166 unsigned long now, alarm; 166 unsigned long now, alarm;
167 unsigned long push = 0;
167 struct rtc_wkalrm alm; 168 struct rtc_wkalrm alm;
168 struct rtc_device *rtc = to_rtc_device(dev); 169 struct rtc_device *rtc = to_rtc_device(dev);
169 char *buf_ptr; 170 char *buf_ptr;
@@ -180,13 +181,17 @@ rtc_sysfs_set_wakealarm(struct device *dev, struct device_attribute *attr,
180 buf_ptr = (char *)buf; 181 buf_ptr = (char *)buf;
181 if (*buf_ptr == '+') { 182 if (*buf_ptr == '+') {
182 buf_ptr++; 183 buf_ptr++;
183 adjust = 1; 184 if (*buf_ptr == '=') {
185 buf_ptr++;
186 push = 1;
187 } else
188 adjust = 1;
184 } 189 }
185 alarm = simple_strtoul(buf_ptr, NULL, 0); 190 alarm = simple_strtoul(buf_ptr, NULL, 0);
186 if (adjust) { 191 if (adjust) {
187 alarm += now; 192 alarm += now;
188 } 193 }
189 if (alarm > now) { 194 if (alarm > now || push) {
190 /* Avoid accidentally clobbering active alarms; we can't 195 /* Avoid accidentally clobbering active alarms; we can't
191 * entirely prevent that here, without even the minimal 196 * entirely prevent that here, without even the minimal
192 * locking from the /dev/rtcN api. 197 * locking from the /dev/rtcN api.
@@ -194,9 +199,14 @@ rtc_sysfs_set_wakealarm(struct device *dev, struct device_attribute *attr,
194 retval = rtc_read_alarm(rtc, &alm); 199 retval = rtc_read_alarm(rtc, &alm);
195 if (retval < 0) 200 if (retval < 0)
196 return retval; 201 return retval;
197 if (alm.enabled) 202 if (alm.enabled) {
198 return -EBUSY; 203 if (push) {
199 204 rtc_tm_to_time(&alm.time, &push);
205 alarm += push;
206 } else
207 return -EBUSY;
208 } else if (push)
209 return -EINVAL;
200 alm.enabled = 1; 210 alm.enabled = 1;
201 } else { 211 } else {
202 alm.enabled = 0; 212 alm.enabled = 0;