From: "Rafael J. Wysocki" <rjw@sisk.pl>
To: pm list <linux-pm@lists.linux-foundation.org>
Cc: LKML <linux-kernel@vger.kernel.org>,
Jesse Barnes <jbarnes@virtuousgeek.org>,
Matthew Garrett <mjg59@srcf.ucam.org>,
Alan Stern <stern@rowland.harvard.edu>, Greg KH <greg@kroah.com>
Subject: [PATCH 1/2] PM / Runtime: Add sysfs switch for disabling device run-time PM (rev. 2)
Date: Thu, 21 Jan 2010 23:59:38 +0100 [thread overview]
Message-ID: <201001212359.38886.rjw@sisk.pl> (raw)
In-Reply-To: <201001212357.46483.rjw@sisk.pl>
From: Rafael J. Wysocki <rjw@sisk.pl>
Add new device sysfs attribute, power/control, allowing the user
space to block the run-time power management of devices. If this
attribute is set to "on", the driver of the device won't be able to power
manage it at run time (without breaking the rules) and the device will
always be in the full power state (except when the entire system goes
into a sleep state).
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
---
drivers/base/power/power.h | 4 +++
drivers/base/power/runtime.c | 43 ++++++++++++++++++++++++++++++++++++
drivers/base/power/sysfs.c | 50 +++++++++++++++++++++++++++++++++++++++++++
include/linux/pm.h | 1
4 files changed, 98 insertions(+)
Index: linux-2.6/drivers/base/power/power.h
===================================================================
--- linux-2.6.orig/drivers/base/power/power.h
+++ linux-2.6/drivers/base/power/power.h
@@ -2,11 +2,15 @@
extern void pm_runtime_init(struct device *dev);
extern void pm_runtime_remove(struct device *dev);
+extern void pm_runtime_allow(struct device *dev);
+extern void pm_runtime_forbid(struct device *dev);
#else /* !CONFIG_PM_RUNTIME */
static inline void pm_runtime_init(struct device *dev) {}
static inline void pm_runtime_remove(struct device *dev) {}
+static inline void pm_runtime_allow(struct device *dev) {}
+static inline void pm_runtime_forbid(struct device *dev) {}
#endif /* !CONFIG_PM_RUNTIME */
Index: linux-2.6/drivers/base/power/sysfs.c
===================================================================
--- linux-2.6.orig/drivers/base/power/sysfs.c
+++ linux-2.6/drivers/base/power/sysfs.c
@@ -7,6 +7,21 @@
#include "power.h"
/*
+ * control - Report/change current runtime PM setting of the device
+ *
+ * Runtime power management of a device can be blocked with the help of
+ * this attribute. All devices have one of the following two values for
+ * the power/control file:
+ *
+ * + "auto\n" to allow the device to be power managed at run time;
+ * + "on\n" to prevent the device from being power managed at run time;
+ *
+ * The default for all devices is "auto", which means that devices may be
+ * subject to automatic power management, depending on their drivers.
+ * Changing this attribute to "on" prevents the driver from power managing
+ * the device at run time. Doing that while the device is suspended causes
+ * it to be woken up.
+ *
* wakeup - Report/change current wakeup option for device
*
* Some devices support "wakeup" events, which are hardware signals
@@ -59,6 +74,38 @@
static const char enabled[] = "enabled";
static const char disabled[] = "disabled";
+#ifdef CONFIG_PM_RUNTIME
+static const char ctrl_auto[] = "auto";
+static const char ctrl_on[] = "on";
+
+static ssize_t control_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%s\n",
+ dev->power.runtime_auto ? ctrl_auto : ctrl_on);
+}
+
+static ssize_t control_store(struct device * dev, struct device_attribute *attr,
+ const char * buf, size_t n)
+{
+ char *cp;
+ int len = n;
+
+ cp = memchr(buf, '\n', n);
+ if (cp)
+ len = cp - buf;
+ if (len == sizeof ctrl_auto - 1 && strncmp(buf, ctrl_auto, len) == 0)
+ pm_runtime_allow(dev);
+ else if (len == sizeof ctrl_on - 1 && strncmp(buf, ctrl_on, len) == 0)
+ pm_runtime_forbid(dev);
+ else
+ return -EINVAL;
+ return n;
+}
+
+static DEVICE_ATTR(control, 0644, control_show, control_store);
+#endif
+
static ssize_t
wake_show(struct device * dev, struct device_attribute *attr, char * buf)
{
@@ -123,6 +170,9 @@ static DEVICE_ATTR(async, 0644, async_sh
#endif /* CONFIG_PM_SLEEP_ADVANCED_DEBUG */
static struct attribute * power_attrs[] = {
+#ifdef CONFIG_PM_RUNTIME
+ &dev_attr_control.attr,
+#endif
&dev_attr_wakeup.attr,
#ifdef CONFIG_PM_SLEEP_ADVANCED_DEBUG
&dev_attr_async.attr,
Index: linux-2.6/include/linux/pm.h
===================================================================
--- linux-2.6.orig/include/linux/pm.h
+++ linux-2.6/include/linux/pm.h
@@ -433,6 +433,7 @@ struct dev_pm_info {
unsigned int request_pending:1;
unsigned int deferred_resume:1;
unsigned int run_wake:1;
+ unsigned int runtime_auto:1;
enum rpm_request request;
enum rpm_status runtime_status;
int runtime_error;
Index: linux-2.6/drivers/base/power/runtime.c
===================================================================
--- linux-2.6.orig/drivers/base/power/runtime.c
+++ linux-2.6/drivers/base/power/runtime.c
@@ -1011,6 +1011,48 @@ void pm_runtime_enable(struct device *de
EXPORT_SYMBOL_GPL(pm_runtime_enable);
/**
+ * pm_runtime_forbid - Block run-time PM of a device.
+ * @dev: Device to handle.
+ *
+ * Increase the device's usage count and clear its power.runtime_auto flag,
+ * so that it cannot be suspended at run time until pm_runtime_allow() is called
+ * for it.
+ */
+void pm_runtime_forbid(struct device *dev)
+{
+ spin_lock_irq(&dev->power.lock);
+ if (!dev->power.runtime_auto)
+ goto out;
+
+ dev->power.runtime_auto = false;
+ atomic_inc(&dev->power.usage_count);
+ __pm_runtime_resume(dev, false);
+
+ out:
+ spin_unlock_irq(&dev->power.lock);
+}
+
+/**
+ * pm_runtime_allow - Unblock run-time PM of a device.
+ * @dev: Device to handle.
+ *
+ * Decrease the device's usage count and set its power.runtime_auto flag.
+ */
+void pm_runtime_allow(struct device *dev)
+{
+ spin_lock_irq(&dev->power.lock);
+ if (dev->power.runtime_auto)
+ goto out;
+
+ dev->power.runtime_auto = true;
+ if (atomic_dec_and_test(&dev->power.usage_count))
+ __pm_runtime_idle(dev);
+
+ out:
+ spin_unlock_irq(&dev->power.lock);
+}
+
+/**
* pm_runtime_init - Initialize run-time PM fields in given device object.
* @dev: Device object to initialize.
*/
@@ -1028,6 +1070,7 @@ void pm_runtime_init(struct device *dev)
atomic_set(&dev->power.child_count, 0);
pm_suspend_ignore_children(dev, false);
+ dev->power.runtime_auto = true;
dev->power.request_pending = false;
dev->power.request = RPM_REQ_NONE;
next prev parent reply other threads:[~2010-01-21 23:01 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-01-18 0:29 [RFC][PATCH] PM / Runtime: Add sysfs switch for disabling device run-time PM Rafael J. Wysocki
2010-01-18 16:10 ` Alan Stern
2010-01-18 22:25 ` [Update][RFC][PATCH] " Rafael J. Wysocki
2010-01-19 15:40 ` Alan Stern
2010-01-19 20:32 ` Rafael J. Wysocki
2010-01-19 23:27 ` Rafael J. Wysocki
2010-01-20 15:09 ` Alan Stern
2010-01-20 21:09 ` Rafael J. Wysocki
2010-01-20 21:37 ` Alan Stern
2010-01-20 22:17 ` Rafael J. Wysocki
2010-01-20 2:51 ` [RFC][PATCH] " Greg KH
2010-01-20 20:55 ` Rafael J. Wysocki
2010-01-20 22:50 ` Greg KH
2010-01-21 22:57 ` [PATCH 0/2] " Rafael J. Wysocki
2010-01-21 22:59 ` Rafael J. Wysocki [this message]
2010-01-22 3:02 ` [PATCH 1/2] PM / Runtime: Add sysfs switch for disabling device run-time PM (rev. 2) Alan Stern
2010-01-22 20:56 ` Rafael J. Wysocki
2010-01-22 22:45 ` Alan Stern
2010-01-22 22:55 ` Rafael J. Wysocki
2010-01-23 3:22 ` Alan Stern
2010-01-23 12:14 ` Rafael J. Wysocki
2010-01-23 15:20 ` Alan Stern
2010-01-23 20:08 ` Rafael J. Wysocki
2010-02-04 22:46 ` Pavel Machek
2010-02-04 23:08 ` Rafael J. Wysocki
2010-02-05 6:27 ` Pavel Machek
2010-02-05 15:19 ` Alan Stern
2010-02-05 8:03 ` [linux-pm] " Nigel Cunningham
2010-01-21 23:00 ` [PATCH 2/2] PM: Document device power attributes in sysfs Rafael J. Wysocki
2010-01-24 15:56 [PATCH 1/2] PM / Runtime: Add sysfs switch for disabling device run-time PM (rev. 2) Jesse Barnes
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=201001212359.38886.rjw@sisk.pl \
--to=rjw@sisk.pl \
--cc=greg@kroah.com \
--cc=jbarnes@virtuousgeek.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@lists.linux-foundation.org \
--cc=mjg59@srcf.ucam.org \
--cc=stern@rowland.harvard.edu \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®