All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Brownell <david-b@pacbell.net>
To: linux-pm@lists.osdl.org
Cc: Alessandro Zummo <alessandro.zummo@towertech.it>,
	"linux-acpi@vger" <linux-acpi@vger.kernel.org>,
	Pavel Machek <pavel@ucw.cz>, Zhang Rui <rui.zhang@intel.com>,
	Paul Sokolovsky <pmiscml@gmail.com>
Subject: Re: [linux-pm] [PATCH 3/6] [-mm]: ACPI: duplicate ACPI sleep "alarm" attribute in	sysfs
Date: Sun, 7 Jan 2007 19:44:58 -0800	[thread overview]
Message-ID: <200701071944.59470.david-b@pacbell.net> (raw)
In-Reply-To: <20070107111859.GB4792@ucw.cz>

On Sunday 07 January 2007 3:19 am, Pavel Machek wrote:
> 
> > Create /sys/power/alarm.
> > The way it works is exactly the same as /proc/acpi/alarm.
> > I.e. "#echo yyyy-mm-dd hh-mm-ss >/sys/power/alarm" supports existing absolute time.
> > And "#echo +yyyy-mm-dd hh-mm-ss >/sys/power/alarm" supports a duration.
> 
> NAK. /proc/acpi/alarm is a mess, and this just moves it to /sysfs.
> 'One value per file', please.

Sort of like the appended patch, instead ... which doesn't need to know a
thing about ACPI.  This is what I suggested in response to an earlier patch
from Paul Sokolovsky.

- Dave


================	CUT HERE
This adds a new "wakealarm" sysfs attribute to RTC class devices which
support alarm operations and are wakeup-capable:

 - It reads as either empty, or the scheduled alarm time as seconds
   since the POSIX epoch.  (That time may already have passed, since
   nothing currently enforces one-shot alarm semantics...)

 - It can be written with an alarm time in the future, again seconds
   since the POSIX epoch, which enables the alarm.

 - It can be written with an alarm time not in the future (such as 0,
   the start of the POSIX epoch) to disable the alarm.

Usage examples, after "cd /sys/class/rtc/rtcN":

    alarm after 45 minutes:
	# echo $(( $(cat since_epoch) + 45 * 60 )) > wakealarm
    alarm next tuesday evening (using GNU date):
	# date -d '10pm tuesday' "+%s" > wakealarm
    disable alarm:
    	# echo 0 > wakealarm

This resembles the /proc/acpi/alarm file in that nothing happens when
the alarm triggers ... except possibly waking the system from sleep.
It's also like that in a nasty way:  not much can be done to prevent
one task from clobbering another task's alarm settings.

It differs from that file in that there's no in-kernel date parser.

Note that a few RTCs ignore rtc_wkalrm.enabled when setting alarms, or
aren't set up correctly, so they won't yet behave with this attribute.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>

Index: g26/drivers/rtc/rtc-sysfs.c
===================================================================
--- g26.orig/drivers/rtc/rtc-sysfs.c	2007-01-07 19:34:50.000000000 -0800
+++ g26/drivers/rtc/rtc-sysfs.c	2007-01-07 19:34:52.000000000 -0800
@@ -78,6 +78,92 @@ static struct attribute_group rtc_attr_g
 	.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 __devinit rtc_sysfs_add_device(struct class_device *class_dev,
 					struct class_interface *class_intf)
 {
@@ -87,8 +173,18 @@ static int __devinit rtc_sysfs_add_devic
 
 	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;
 }
@@ -96,6 +192,9 @@ static int __devinit rtc_sysfs_add_devic
 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);
 }
 

  reply	other threads:[~2007-01-08  3:45 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-01-06 11:35 [PATCH 3/6] [-mm]: ACPI: duplicate ACPI sleep "alarm" attribute in sysfs Zhang Rui
2007-01-06 22:42 ` David Brownell
2007-01-07  5:57   ` [linux-pm] " Matthew Garrett
2007-01-08  2:31     ` David Brownell
2007-01-08 10:10       ` Matthew Garrett
2007-01-08 20:39         ` David Brownell
2007-01-08 20:43           ` Matthew Garrett
2007-01-08 21:15             ` David Brownell
2007-01-08 10:13       ` Zhang Rui
2007-01-08 20:46         ` David Brownell
2007-01-07 11:19 ` Pavel Machek
2007-01-08  3:44   ` David Brownell [this message]
2007-01-08 11:36     ` Pavel Machek
2007-01-08 20:35       ` David Brownell
2007-01-25  4:21     ` Len Brown
2007-01-25  9:39       ` [linux-pm] " David Brownell
2007-01-25 19:47       ` Pavel Machek
2007-01-25 23:12         ` Len Brown
2007-01-25 23:28           ` Nigel Cunningham
2007-01-26  0:33           ` David Brownell
2007-01-26 17:07           ` Pavel Machek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200701071944.59470.david-b@pacbell.net \
    --to=david-b@pacbell.net \
    --cc=alessandro.zummo@towertech.it \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-pm@lists.osdl.org \
    --cc=pavel@ucw.cz \
    --cc=pmiscml@gmail.com \
    --cc=rui.zhang@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.