|
@@ -54,6 +54,24 @@
|
|
|
* wakeup events internally (unless they are disabled), keeping
|
|
|
* their hardware in low power modes whenever they're unused. This
|
|
|
* saves runtime power, without requiring system-wide sleep states.
|
|
|
+ *
|
|
|
+ * async - Report/change current async suspend setting for the device
|
|
|
+ *
|
|
|
+ * Asynchronous suspend and resume of the device during system-wide power
|
|
|
+ * state transitions can be enabled by writing "enabled" to this file.
|
|
|
+ * Analogously, if "disabled" is written to this file, the device will be
|
|
|
+ * suspended and resumed synchronously.
|
|
|
+ *
|
|
|
+ * All devices have one of the following two values for power/async:
|
|
|
+ *
|
|
|
+ * + "enabled\n" to permit the asynchronous suspend/resume of the device;
|
|
|
+ * + "disabled\n" to forbid it;
|
|
|
+ *
|
|
|
+ * NOTE: It generally is unsafe to permit the asynchronous suspend/resume
|
|
|
+ * of a device unless it is certain that all of the PM dependencies of the
|
|
|
+ * device are known to the PM core. However, for some devices this
|
|
|
+ * attribute is set to "enabled" by bus type code or device drivers and in
|
|
|
+ * that cases it should be safe to leave the default value.
|
|
|
*/
|
|
|
|
|
|
static const char enabled[] = "enabled";
|
|
@@ -125,12 +143,43 @@ wake_store(struct device * dev, struct device_attribute *attr,
|
|
|
|
|
|
static DEVICE_ATTR(wakeup, 0644, wake_show, wake_store);
|
|
|
|
|
|
+#ifdef CONFIG_PM_SLEEP_ADVANCED_DEBUG
|
|
|
+static ssize_t async_show(struct device *dev, struct device_attribute *attr,
|
|
|
+ char *buf)
|
|
|
+{
|
|
|
+ return sprintf(buf, "%s\n",
|
|
|
+ device_async_suspend_enabled(dev) ? enabled : disabled);
|
|
|
+}
|
|
|
+
|
|
|
+static ssize_t async_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 enabled - 1 && strncmp(buf, enabled, len) == 0)
|
|
|
+ device_enable_async_suspend(dev);
|
|
|
+ else if (len == sizeof disabled - 1 && strncmp(buf, disabled, len) == 0)
|
|
|
+ device_disable_async_suspend(dev);
|
|
|
+ else
|
|
|
+ return -EINVAL;
|
|
|
+ return n;
|
|
|
+}
|
|
|
+
|
|
|
+static DEVICE_ATTR(async, 0644, async_show, async_store);
|
|
|
+#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,
|
|
|
+#endif
|
|
|
NULL,
|
|
|
};
|
|
|
static struct attribute_group pm_attr_group = {
|