Commit 1df0a4711f6e93c1073dd82f6e7905748842e2b3

Authored by Bernie Thompson
Committed by Linus Torvalds
1 parent c67d96e317

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>

Showing 2 changed files with 19 additions and 8 deletions Side-by-side Diff

Documentation/rtc.txt
... ... @@ -153,9 +153,10 @@
153 153 time: RTC-provided time
154 154 wakealarm: The time at which the clock will generate a system wakeup
155 155 event. This is a one shot wakeup event, so must be reset
156   - after wake if a daily wakeup is required. Format is either
157   - seconds since the epoch or, if there's a leading +, seconds
158   - in the future.
  156 + after wake if a daily wakeup is required. Format is seconds since
  157 + the epoch by default, or if there's a leading +, seconds in the
  158 + future, or if there is a leading +=, seconds ahead of the current
  159 + alarm.
159 160  
160 161 IOCTL INTERFACE
161 162 ---------------
drivers/rtc/rtc-sysfs.c
... ... @@ -164,6 +164,7 @@
164 164 {
165 165 ssize_t retval;
166 166 unsigned long now, alarm;
  167 + unsigned long push = 0;
167 168 struct rtc_wkalrm alm;
168 169 struct rtc_device *rtc = to_rtc_device(dev);
169 170 char *buf_ptr;
170 171  
... ... @@ -180,13 +181,17 @@
180 181 buf_ptr = (char *)buf;
181 182 if (*buf_ptr == '+') {
182 183 buf_ptr++;
183   - adjust = 1;
  184 + if (*buf_ptr == '=') {
  185 + buf_ptr++;
  186 + push = 1;
  187 + } else
  188 + adjust = 1;
184 189 }
185 190 alarm = simple_strtoul(buf_ptr, NULL, 0);
186 191 if (adjust) {
187 192 alarm += now;
188 193 }
189   - if (alarm > now) {
  194 + if (alarm > now || push) {
190 195 /* Avoid accidentally clobbering active alarms; we can't
191 196 * entirely prevent that here, without even the minimal
192 197 * locking from the /dev/rtcN api.
... ... @@ -194,9 +199,14 @@
194 199 retval = rtc_read_alarm(rtc, &alm);
195 200 if (retval < 0)
196 201 return retval;
197   - if (alm.enabled)
198   - return -EBUSY;
199   -
  202 + if (alm.enabled) {
  203 + if (push) {
  204 + rtc_tm_to_time(&alm.time, &push);
  205 + alarm += push;
  206 + } else
  207 + return -EBUSY;
  208 + } else if (push)
  209 + return -EINVAL;
200 210 alm.enabled = 1;
201 211 } else {
202 212 alm.enabled = 0;