diff options
Diffstat (limited to 'drivers/rtc/rtc-sysfs.c')
-rw-r--r-- | drivers/rtc/rtc-sysfs.c | 20 |
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; |