Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 47934
b: refs/heads/master
c: 3925a5c
h: refs/heads/master
v: v3
  • Loading branch information
David Brownell authored and Linus Torvalds committed Feb 12, 2007
1 parent 280d980 commit 8d57f6b
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 802245611adea5e5877d8c5d9a20f94d8131bfdd
refs/heads/master: 3925a5ce44330767f7f0de5c58c6a797009f0f75
103 changes: 101 additions & 2 deletions trunk/drivers/rtc/rtc-sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,92 @@ static struct attribute_group rtc_attr_group = {
.attrs = rtc_attrs,
};


static ssize_t
rtc_sysfs_show_wakealarm(struct class_device *dev, char *buf)
{
ssize_t retval;
unsigned long alarm;
struct rtc_wkalrm alm;

/* Don't show disabled alarms; but the RTC could leave the
* alarm enabled after it's already triggered. Alarms are
* conceptually one-shot, even though some common hardware
* (PCs) doesn't actually work that way.
*
* REVISIT maybe we should require RTC implementations to
* disable the RTC alarm after it triggers, for uniformity.
*/
retval = rtc_read_alarm(dev, &alm);
if (retval == 0 && alm.enabled) {
rtc_tm_to_time(&alm.time, &alarm);
retval = sprintf(buf, "%lu\n", alarm);
}

return retval;
}

static ssize_t
rtc_sysfs_set_wakealarm(struct class_device *dev, const char *buf, size_t n)
{
ssize_t retval;
unsigned long now, alarm;
struct rtc_wkalrm alm;

/* Only request alarms that trigger in the future. Disable them
* by writing another time, e.g. 0 meaning Jan 1 1970 UTC.
*/
retval = rtc_read_time(dev, &alm.time);
if (retval < 0)
return retval;
rtc_tm_to_time(&alm.time, &now);

alarm = simple_strtoul(buf, NULL, 0);
if (alarm > now) {
/* Avoid accidentally clobbering active alarms; we can't
* entirely prevent that here, without even the minimal
* locking from the /dev/rtcN api.
*/
retval = rtc_read_alarm(dev, &alm);
if (retval < 0)
return retval;
if (alm.enabled)
return -EBUSY;

alm.enabled = 1;
} else {
alm.enabled = 0;

/* Provide a valid future alarm time. Linux isn't EFI,
* this time won't be ignored when disabling the alarm.
*/
alarm = now + 300;
}
rtc_time_to_tm(alarm, &alm.time);

retval = rtc_set_alarm(dev, &alm);
return (retval < 0) ? retval : n;
}
static const CLASS_DEVICE_ATTR(wakealarm, S_IRUGO | S_IWUSR,
rtc_sysfs_show_wakealarm, rtc_sysfs_set_wakealarm);


/* The reason to trigger an alarm with no process watching it (via sysfs)
* is its side effect: waking from a system state like suspend-to-RAM or
* suspend-to-disk. So: no attribute unless that side effect is possible.
* (Userspace may disable that mechanism later.)
*/
static inline int rtc_does_wakealarm(struct class_device *class_dev)
{
struct rtc_device *rtc;

if (!device_can_wakeup(class_dev->dev))
return 0;
rtc = to_rtc_device(class_dev);
return rtc->ops->set_alarm != NULL;
}


static int rtc_sysfs_add_device(struct class_device *class_dev,
struct class_interface *class_intf)
{
Expand All @@ -87,15 +173,28 @@ static int rtc_sysfs_add_device(struct class_device *class_dev,

err = sysfs_create_group(&class_dev->kobj, &rtc_attr_group);
if (err)
dev_err(class_dev->dev,
"failed to create sysfs attributes\n");
dev_err(class_dev->dev, "failed to create %s\n",
"sysfs attributes");
else if (rtc_does_wakealarm(class_dev)) {
/* not all RTCs support both alarms and wakeup */
err = class_device_create_file(class_dev,
&class_device_attr_wakealarm);
if (err) {
dev_err(class_dev->dev, "failed to create %s\n",
"alarm attribute");
sysfs_remove_group(&class_dev->kobj, &rtc_attr_group);
}
}

return err;
}

static void rtc_sysfs_remove_device(struct class_device *class_dev,
struct class_interface *class_intf)
{
if (rtc_does_wakealarm(class_dev))
class_device_remove_file(class_dev,
&class_device_attr_wakealarm);
sysfs_remove_group(&class_dev->kobj, &rtc_attr_group);
}

Expand Down

0 comments on commit 8d57f6b

Please sign in to comment.