All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC][PATCH 00/11] Android PM extensions
@ 2009-01-14  1:27 Arve Hjønnevåg
  2009-01-14  1:27 ` [PATCH 01/11] PM: Add wake lock api Arve Hjønnevåg
                   ` (2 more replies)
  0 siblings, 3 replies; 89+ messages in thread
From: Arve Hjønnevåg @ 2009-01-14  1:27 UTC (permalink / raw)
  To: linux-pm; +Cc: swetland

The following patch series adds two apis, wakelock and earlysuspend.
The Android platform uses the earlysuspend api to turn the screen
and some input devices on and off. The wakelock code determines when
to enter the full suspend state.

These apis could also be useful to other platforms where the goal is
to enter full suspend whenever possible.

--
Arve Hjønnevåg

_______________________________________________
linux-pm mailing list
linux-pm@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/linux-pm

^ permalink raw reply	[flat|nested] 89+ messages in thread

* [PATCH 01/11] PM: Add wake lock api.
  2009-01-14  1:27 [RFC][PATCH 00/11] Android PM extensions Arve Hjønnevåg
@ 2009-01-14  1:27 ` Arve Hjønnevåg
  2009-01-14  1:27   ` [PATCH 02/11] PM: Add early suspend api Arve Hjønnevåg
  2009-01-14  9:09   ` [PATCH 01/11] PM: Add wake lock api Nigel Cunningham
  2009-01-14  9:01 ` [RFC][PATCH 00/11] Android PM extensions Nigel Cunningham
  2009-01-28 19:31 ` Pavel Machek
  2 siblings, 2 replies; 89+ messages in thread
From: Arve Hjønnevåg @ 2009-01-14  1:27 UTC (permalink / raw)
  To: linux-pm; +Cc: swetland

Signed-off-by: Arve Hjønnevåg <arve@android.com>
---
 include/linux/wakelock.h |   91 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 91 insertions(+), 0 deletions(-)
 create mode 100755 include/linux/wakelock.h

diff --git a/include/linux/wakelock.h b/include/linux/wakelock.h
new file mode 100755
index 0000000..a096d24
--- /dev/null
+++ b/include/linux/wakelock.h
@@ -0,0 +1,91 @@
+/* include/linux/wakelock.h
+ *
+ * Copyright (C) 2007-2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _LINUX_WAKELOCK_H
+#define _LINUX_WAKELOCK_H
+
+#include <linux/list.h>
+#include <linux/ktime.h>
+
+/* A wake_lock prevents the system from entering suspend or other low power
+ * states when active. If the type is set to WAKE_LOCK_SUSPEND, the wake_lock
+ * prevents a full system suspend. If the type is WAKE_LOCK_IDLE, low power
+ * states that cause large interrupt latencies or that disable a set of
+ * interrupts will not entered from idle until the wake_locks are released.
+ */
+
+enum {
+	WAKE_LOCK_SUSPEND, /* Prevent suspend */
+	WAKE_LOCK_IDLE,    /* Prevent low power idle */
+	WAKE_LOCK_TYPE_COUNT
+};
+
+struct wake_lock {
+#ifdef CONFIG_HAS_WAKELOCK
+	struct list_head    link;
+	int                 flags;
+	const char         *name;
+	unsigned long       expires;
+#ifdef CONFIG_WAKELOCK_STAT
+	struct {
+		int             count;
+		int             expire_count;
+		int             wakeup_count;
+		ktime_t         total_time;
+		ktime_t         prevent_suspend_time;
+		ktime_t         max_time;
+		ktime_t         last_time;
+	} stat;
+#endif
+#endif
+};
+
+#ifdef CONFIG_HAS_WAKELOCK
+
+void wake_lock_init(struct wake_lock *lock, int type, const char *name);
+void wake_lock_destroy(struct wake_lock *lock);
+void wake_lock(struct wake_lock *lock);
+void wake_lock_timeout(struct wake_lock *lock, long timeout);
+void wake_unlock(struct wake_lock *lock);
+
+/* wake_lock_active returns a non-zero value if the wake_lock is currently
+ * locked. If the wake_lock has a timeout, it does not check the timeout
+ * but if the timeout had aready been checked it will return 0.
+ */
+int wake_lock_active(struct wake_lock *lock);
+
+/* has_wake_lock returns 0 if no wake locks of the specified type are active,
+ * and non-zero if one or more wake locks are held. Specifically it returns
+ * -1 if one or more wake locks with no timeout are active or the
+ * number of jiffies until all active wake locks time out.
+ */
+long has_wake_lock(int type);
+
+#else
+
+static inline void wake_lock_init(struct wake_lock *lock, int type,
+					const char *name) {}
+static inline void wake_lock_destroy(struct wake_lock *lock) {}
+static inline void wake_lock(struct wake_lock *lock) {}
+static inline void wake_lock_timeout(struct wake_lock *lock, long timeout) {}
+static inline void wake_unlock(struct wake_lock *lock) {}
+
+static inline int wake_lock_active(struct wake_lock *lock) { return 0; }
+static inline long has_wake_lock(int type) { return 0; }
+
+#endif
+
+#endif
+
-- 
1.6.1

_______________________________________________
linux-pm mailing list
linux-pm@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/linux-pm

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 02/11] PM: Add early suspend api.
  2009-01-14  1:27 ` [PATCH 01/11] PM: Add wake lock api Arve Hjønnevåg
@ 2009-01-14  1:27   ` Arve Hjønnevåg
  2009-01-14  1:27     ` [PATCH 03/11] PM: Implement wakelock api Arve Hjønnevåg
  2009-01-14  9:17     ` [PATCH 02/11] PM: Add early suspend api Nigel Cunningham
  2009-01-14  9:09   ` [PATCH 01/11] PM: Add wake lock api Nigel Cunningham
  1 sibling, 2 replies; 89+ messages in thread
From: Arve Hjønnevåg @ 2009-01-14  1:27 UTC (permalink / raw)
  To: linux-pm; +Cc: swetland

Signed-off-by: Arve Hjønnevåg <arve@android.com>
---
 include/linux/earlysuspend.h |   56 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 56 insertions(+), 0 deletions(-)
 create mode 100755 include/linux/earlysuspend.h

diff --git a/include/linux/earlysuspend.h b/include/linux/earlysuspend.h
new file mode 100755
index 0000000..8343b81
--- /dev/null
+++ b/include/linux/earlysuspend.h
@@ -0,0 +1,56 @@
+/* include/linux/earlysuspend.h
+ *
+ * Copyright (C) 2007-2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _LINUX_EARLYSUSPEND_H
+#define _LINUX_EARLYSUSPEND_H
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/list.h>
+#endif
+
+/* The early_suspend structure defines suspend and resume hooks to be called
+ * when the user visible sleep state of the system changes, and a level to
+ * control the order. They can be used to turn off the screen and input
+ * devices that are not used for wakeup.
+ * Suspend handlers are called in low to high level order, resume handlers are
+ * called in the opposite order. If, when calling register_early_suspend,
+ * the suspend handlers have already been called without a matching call to the
+ * resume handlers, the suspend handler will be called directly from
+ * register_early_suspend. This direct call can violate the normal level order.
+ */
+enum {
+	EARLY_SUSPEND_LEVEL_BLANK_SCREEN = 50,
+	EARLY_SUSPEND_LEVEL_STOP_DRAWING = 100,
+	EARLY_SUSPEND_LEVEL_DISABLE_FB = 150,
+};
+struct early_suspend {
+#ifdef CONFIG_HAS_EARLYSUSPEND
+	struct list_head link;
+	int level;
+	void (*suspend)(struct early_suspend *h);
+	void (*resume)(struct early_suspend *h);
+#endif
+};
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+void register_early_suspend(struct early_suspend *handler);
+void unregister_early_suspend(struct early_suspend *handler);
+#else
+#define register_early_suspend(handler) do { } while (0)
+#define unregister_early_suspend(handler) do { } while (0)
+#endif
+
+#endif
+
-- 
1.6.1

_______________________________________________
linux-pm mailing list
linux-pm@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/linux-pm

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 03/11] PM: Implement wakelock api.
  2009-01-14  1:27   ` [PATCH 02/11] PM: Add early suspend api Arve Hjønnevåg
@ 2009-01-14  1:27     ` Arve Hjønnevåg
  2009-01-14  1:27       ` [PATCH 04/11] PM: Implement early suspend api Arve Hjønnevåg
  2009-01-14  9:30       ` [PATCH 03/11] PM: Implement wakelock api Nigel Cunningham
  2009-01-14  9:17     ` [PATCH 02/11] PM: Add early suspend api Nigel Cunningham
  1 sibling, 2 replies; 89+ messages in thread
From: Arve Hjønnevåg @ 2009-01-14  1:27 UTC (permalink / raw)
  To: linux-pm; +Cc: swetland

Signed-off-by: Arve Hjønnevåg <arve@android.com>
---
 kernel/power/Kconfig    |   19 ++
 kernel/power/Makefile   |    1 +
 kernel/power/power.h    |    7 +
 kernel/power/wakelock.c |  598 +++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 625 insertions(+), 0 deletions(-)
 create mode 100644 kernel/power/wakelock.c

diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index 23bd4da..6e3da6e 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -116,6 +116,25 @@ config SUSPEND_FREEZER
 
 	  Turning OFF this setting is NOT recommended! If in doubt, say Y.
 
+config HAS_WAKELOCK
+	bool
+
+config WAKELOCK
+	bool "Wake lock"
+	depends on PM && RTC_CLASS
+	default n
+	select HAS_WAKELOCK
+	---help---
+	  Enable wakelocks. When user space request a sleep state the
+	  sleep request will be delayed until no wake locks are held.
+
+config WAKELOCK_STAT
+	bool "Wake lock stats"
+	depends on WAKELOCK
+	default y
+	---help---
+	  Report wake lock stats in /proc/wakelocks
+
 config HIBERNATION
 	bool "Hibernation (aka 'suspend to disk')"
 	depends on PM && SWAP && ARCH_HIBERNATION_POSSIBLE
diff --git a/kernel/power/Makefile b/kernel/power/Makefile
index 597823b..401ddfe 100644
--- a/kernel/power/Makefile
+++ b/kernel/power/Makefile
@@ -5,6 +5,7 @@ endif
 
 obj-y				:= main.o
 obj-$(CONFIG_PM_SLEEP)		+= process.o console.o
+obj-$(CONFIG_WAKELOCK)		+= wakelock.o
 obj-$(CONFIG_HIBERNATION)	+= swsusp.o disk.o snapshot.o swap.o user.o
 
 obj-$(CONFIG_MAGIC_SYSRQ)	+= poweroff.o
diff --git a/kernel/power/power.h b/kernel/power/power.h
index 46b5ec7..1527174 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -223,3 +223,10 @@ static inline void suspend_thaw_processes(void)
 {
 }
 #endif
+
+#ifdef CONFIG_WAKELOCK
+/* kernel/power/wakelock.c */
+extern struct workqueue_struct *suspend_work_queue;
+extern struct wake_lock main_wake_lock;
+extern suspend_state_t requested_suspend_state;
+#endif
diff --git a/kernel/power/wakelock.c b/kernel/power/wakelock.c
new file mode 100644
index 0000000..c9e22f9
--- /dev/null
+++ b/kernel/power/wakelock.c
@@ -0,0 +1,598 @@
+/* kernel/power/wakelock.c
+ *
+ * Copyright (C) 2005-2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+#include <linux/suspend.h>
+#include <linux/syscalls.h> /* sys_sync */
+#include <linux/wakelock.h>
+#ifdef CONFIG_WAKELOCK_STAT
+#include <linux/proc_fs.h>
+#endif
+#include "power.h"
+
+enum {
+	DEBUG_EXIT_SUSPEND = 1U << 0,
+	DEBUG_WAKEUP = 1U << 1,
+	DEBUG_SUSPEND = 1U << 2,
+	DEBUG_EXPIRE = 1U << 3,
+	DEBUG_WAKE_LOCK = 1U << 4,
+};
+static int debug_mask = DEBUG_EXIT_SUSPEND | DEBUG_WAKEUP;
+module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP);
+
+#define WAKE_LOCK_TYPE_MASK              (0x0f)
+#define WAKE_LOCK_INITIALIZED            (1U << 8)
+#define WAKE_LOCK_ACTIVE                 (1U << 9)
+#define WAKE_LOCK_AUTO_EXPIRE            (1U << 10)
+#define WAKE_LOCK_PREVENTING_SUSPEND     (1U << 11)
+
+static DEFINE_SPINLOCK(list_lock);
+static LIST_HEAD(inactive_locks);
+static struct list_head active_wake_locks[WAKE_LOCK_TYPE_COUNT];
+static int current_event_num;
+struct workqueue_struct *suspend_work_queue;
+struct wake_lock main_wake_lock;
+suspend_state_t requested_suspend_state = PM_SUSPEND_MEM;
+static struct wake_lock unknown_wakeup;
+
+#ifdef CONFIG_WAKELOCK_STAT
+static struct wake_lock deleted_wake_locks;
+static ktime_t last_sleep_time_update;
+static int wait_for_wakeup;
+
+int get_expired_time(struct wake_lock *lock, ktime_t *expire_time)
+{
+	struct timespec ts;
+	struct timespec kt;
+	struct timespec tomono;
+	struct timespec delta;
+	unsigned long seq;
+	long timeout;
+
+	if (!(lock->flags & WAKE_LOCK_AUTO_EXPIRE))
+		return 0;
+	do {
+		seq = read_seqbegin(&xtime_lock);
+		timeout = lock->expires - jiffies;
+		if (timeout > 0)
+			return 0;
+		kt = current_kernel_time();
+		tomono = wall_to_monotonic;
+	} while (read_seqretry(&xtime_lock, seq));
+	jiffies_to_timespec(-timeout, &delta);
+	set_normalized_timespec(&ts, kt.tv_sec + tomono.tv_sec - delta.tv_sec,
+				kt.tv_nsec + tomono.tv_nsec - delta.tv_nsec);
+	*expire_time = timespec_to_ktime(ts);
+	return 1;
+}
+
+
+static int print_lock_stat(char *buf, struct wake_lock *lock)
+{
+	int lock_count = lock->stat.count;
+	int expire_count = lock->stat.expire_count;
+	ktime_t active_time = ktime_set(0, 0);
+	ktime_t total_time = lock->stat.total_time;
+	ktime_t max_time = lock->stat.max_time;
+	ktime_t prevent_suspend_time = lock->stat.prevent_suspend_time;
+	if (lock->flags & WAKE_LOCK_ACTIVE) {
+		ktime_t now, add_time;
+		int expired = get_expired_time(lock, &now);
+		if (!expired)
+			now = ktime_get();
+		add_time = ktime_sub(now, lock->stat.last_time);
+		lock_count++;
+		if (!expired)
+			active_time = add_time;
+		else
+			expire_count++;
+		total_time = ktime_add(total_time, add_time);
+		if (lock->flags & WAKE_LOCK_PREVENTING_SUSPEND)
+			prevent_suspend_time = ktime_add(prevent_suspend_time,
+					ktime_sub(now, last_sleep_time_update));
+		if (add_time.tv64 > max_time.tv64)
+			max_time = add_time;
+	}
+
+	return sprintf(buf, "\"%s\"\t%d\t%d\t%d\t%lld\t%lld\t%lld\t%lld\t"
+		       "%lld\n", lock->name, lock_count, expire_count,
+		       lock->stat.wakeup_count, ktime_to_ns(active_time),
+		       ktime_to_ns(total_time),
+		       ktime_to_ns(prevent_suspend_time), ktime_to_ns(max_time),
+		       ktime_to_ns(lock->stat.last_time));
+}
+
+
+static int wakelocks_read_proc(char *page, char **start, off_t off,
+			       int count, int *eof, void *data)
+{
+	unsigned long irqflags;
+	struct wake_lock *lock;
+	int len = 0;
+	char *p = page;
+	int type;
+
+	spin_lock_irqsave(&list_lock, irqflags);
+
+	p += sprintf(p, "name\tcount\texpire_count\twake_count\tactive_since"
+		     "\ttotal_time\tsleep_time\tmax_time\tlast_change\n");
+	list_for_each_entry(lock, &inactive_locks, link) {
+		p += print_lock_stat(p, lock);
+	}
+	for (type = 0; type < WAKE_LOCK_TYPE_COUNT; type++) {
+		list_for_each_entry(lock, &active_wake_locks[type], link)
+			p += print_lock_stat(p, lock);
+	}
+	spin_unlock_irqrestore(&list_lock, irqflags);
+
+	*start = page + off;
+
+	len = p - page;
+	if (len > off)
+		len -= off;
+	else
+		len = 0;
+
+	return len < count ? len  : count;
+}
+
+static void wake_unlock_stat_locked(struct wake_lock *lock, int expired)
+{
+	ktime_t duration;
+	ktime_t now;
+	if (!(lock->flags & WAKE_LOCK_ACTIVE))
+		return;
+	if (get_expired_time(lock, &now))
+		expired = 1;
+	else
+		now = ktime_get();
+	lock->stat.count++;
+	if (expired)
+		lock->stat.expire_count++;
+	duration = ktime_sub(now, lock->stat.last_time);
+	lock->stat.total_time = ktime_add(lock->stat.total_time, duration);
+	if (ktime_to_ns(duration) > ktime_to_ns(lock->stat.max_time))
+		lock->stat.max_time = duration;
+	lock->stat.last_time = ktime_get();
+	if (lock->flags & WAKE_LOCK_PREVENTING_SUSPEND) {
+		duration = ktime_sub(now, last_sleep_time_update);
+		lock->stat.prevent_suspend_time = ktime_add(
+			lock->stat.prevent_suspend_time, duration);
+		lock->flags &= ~WAKE_LOCK_PREVENTING_SUSPEND;
+	}
+}
+
+static void update_sleep_wait_stats_locked(int done)
+{
+	struct wake_lock *lock;
+	ktime_t now, etime, elapsed, add;
+	int expired;
+
+	now = ktime_get();
+	elapsed = ktime_sub(now, last_sleep_time_update);
+	list_for_each_entry(lock, &active_wake_locks[WAKE_LOCK_SUSPEND], link) {
+		expired = get_expired_time(lock, &etime);
+		if (lock->flags & WAKE_LOCK_PREVENTING_SUSPEND) {
+			if (expired)
+				add = ktime_sub(etime, last_sleep_time_update);
+			else
+				add = elapsed;
+			lock->stat.prevent_suspend_time = ktime_add(
+				lock->stat.prevent_suspend_time, add);
+		}
+		if (done || expired)
+			lock->flags &= ~WAKE_LOCK_PREVENTING_SUSPEND;
+		else
+			lock->flags |= WAKE_LOCK_PREVENTING_SUSPEND;
+	}
+	last_sleep_time_update = now;
+}
+#endif
+
+
+static void expire_wake_lock(struct wake_lock *lock)
+{
+#ifdef CONFIG_WAKELOCK_STAT
+	wake_unlock_stat_locked(lock, 1);
+#endif
+	lock->flags &= ~(WAKE_LOCK_ACTIVE | WAKE_LOCK_AUTO_EXPIRE);
+	list_del(&lock->link);
+	list_add(&lock->link, &inactive_locks);
+	if (debug_mask & (DEBUG_WAKE_LOCK | DEBUG_EXPIRE))
+		pr_info("expired wake lock %s\n", lock->name);
+}
+
+static void print_active_locks(int type)
+{
+	unsigned long irqflags;
+	struct wake_lock *lock;
+
+	BUG_ON(type >= WAKE_LOCK_TYPE_COUNT);
+	spin_lock_irqsave(&list_lock, irqflags);
+	list_for_each_entry(lock, &active_wake_locks[type], link) {
+		if (lock->flags & WAKE_LOCK_AUTO_EXPIRE) {
+			long timeout = lock->expires - jiffies;
+			if (timeout <= 0)
+				pr_info("wake lock %s, expired\n", lock->name);
+			else
+				pr_info("active wake lock %s, time left %ld\n",
+					lock->name, timeout);
+		} else
+			pr_info("active wake lock %s\n", lock->name);
+	}
+	spin_unlock_irqrestore(&list_lock, irqflags);
+}
+
+static long has_wake_lock_locked(int type)
+{
+	struct wake_lock *lock, *n;
+	long max_timeout = 0;
+
+	BUG_ON(type >= WAKE_LOCK_TYPE_COUNT);
+	list_for_each_entry_safe(lock, n, &active_wake_locks[type], link) {
+		if (lock->flags & WAKE_LOCK_AUTO_EXPIRE) {
+			long timeout = lock->expires - jiffies;
+			if (timeout <= 0)
+				expire_wake_lock(lock);
+			else if (timeout > max_timeout)
+				max_timeout = timeout;
+		} else
+			return -1;
+	}
+	return max_timeout;
+}
+
+long has_wake_lock(int type)
+{
+	long ret;
+	unsigned long irqflags;
+	spin_lock_irqsave(&list_lock, irqflags);
+	ret = has_wake_lock_locked(type);
+	spin_unlock_irqrestore(&list_lock, irqflags);
+	return ret;
+}
+
+static void suspend(struct work_struct *work)
+{
+	int ret;
+	int entry_event_num;
+
+	if (has_wake_lock(WAKE_LOCK_SUSPEND)) {
+		if (debug_mask & DEBUG_SUSPEND)
+			pr_info("suspend: abort suspend\n");
+		return;
+	}
+
+	entry_event_num = current_event_num;
+	sys_sync();
+	if (debug_mask & DEBUG_SUSPEND)
+		pr_info("suspend: enter suspend\n");
+	ret = pm_suspend(requested_suspend_state);
+	if (debug_mask & DEBUG_EXIT_SUSPEND) {
+		struct timespec ts;
+		struct rtc_time tm;
+		getnstimeofday(&ts);
+		rtc_time_to_tm(ts.tv_sec, &tm);
+		pr_info("suspend: exit suspend, ret = %d "
+			"(%d-%02d-%02d %02d:%02d:%02d.%09lu UTC)\n", ret,
+			tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
+			tm.tm_hour, tm.tm_min, tm.tm_sec, ts.tv_nsec);
+	}
+	if (current_event_num == entry_event_num) {
+		if (debug_mask & DEBUG_SUSPEND)
+			pr_info("suspend: pm_suspend returned with no event\n");
+		wake_lock_timeout(&unknown_wakeup, HZ / 2);
+	}
+}
+static DECLARE_WORK(suspend_work, suspend);
+
+static void expire_wake_locks(unsigned long data)
+{
+	long has_lock;
+	unsigned long irqflags;
+	if (debug_mask & DEBUG_EXPIRE)
+		pr_info("expire_wake_locks: start\n");
+	if (debug_mask & DEBUG_SUSPEND)
+		print_active_locks(WAKE_LOCK_SUSPEND);
+	spin_lock_irqsave(&list_lock, irqflags);
+	has_lock = has_wake_lock_locked(WAKE_LOCK_SUSPEND);
+	if (debug_mask & DEBUG_EXPIRE)
+		pr_info("expire_wake_locks: done, has_lock %ld\n", has_lock);
+	if (has_lock == 0)
+		queue_work(suspend_work_queue, &suspend_work);
+	spin_unlock_irqrestore(&list_lock, irqflags);
+}
+static DEFINE_TIMER(expire_timer, expire_wake_locks, 0, 0);
+
+static int power_suspend_late(struct platform_device *pdev, pm_message_t state)
+{
+	int ret = has_wake_lock(WAKE_LOCK_SUSPEND) ? -EAGAIN : 0;
+#ifdef CONFIG_WAKELOCK_STAT
+	wait_for_wakeup = 1;
+#endif
+	if (debug_mask & DEBUG_SUSPEND)
+		pr_info("power_suspend_late return %d\n", ret);
+	return ret;
+}
+
+static struct platform_driver power_driver = {
+	.driver.name = "power",
+	.suspend_late = power_suspend_late,
+};
+static struct platform_device power_device = {
+	.name = "power",
+};
+
+void wake_lock_init(struct wake_lock *lock, int type, const char *name)
+{
+	unsigned long irqflags = 0;
+
+	if (name)
+		lock->name = name;
+	BUG_ON(!lock->name);
+
+	if (debug_mask & DEBUG_WAKE_LOCK)
+		pr_info("wake_lock_init name=%s\n", lock->name);
+#ifdef CONFIG_WAKELOCK_STAT
+	lock->stat.count = 0;
+	lock->stat.expire_count = 0;
+	lock->stat.wakeup_count = 0;
+	lock->stat.total_time = ktime_set(0, 0);
+	lock->stat.prevent_suspend_time = ktime_set(0, 0);
+	lock->stat.max_time = ktime_set(0, 0);
+	lock->stat.last_time = ktime_set(0, 0);
+#endif
+	lock->flags = (type & WAKE_LOCK_TYPE_MASK) | WAKE_LOCK_INITIALIZED;
+
+	INIT_LIST_HEAD(&lock->link);
+	spin_lock_irqsave(&list_lock, irqflags);
+	list_add(&lock->link, &inactive_locks);
+	spin_unlock_irqrestore(&list_lock, irqflags);
+}
+EXPORT_SYMBOL(wake_lock_init);
+
+void wake_lock_destroy(struct wake_lock *lock)
+{
+	unsigned long irqflags;
+	if (debug_mask & DEBUG_WAKE_LOCK)
+		pr_info("wake_lock_destroy name=%s\n", lock->name);
+	spin_lock_irqsave(&list_lock, irqflags);
+	lock->flags &= ~WAKE_LOCK_INITIALIZED;
+#ifdef CONFIG_WAKELOCK_STAT
+	if (lock->stat.count) {
+		deleted_wake_locks.stat.count += lock->stat.count;
+		deleted_wake_locks.stat.expire_count += lock->stat.expire_count;
+		deleted_wake_locks.stat.total_time =
+			ktime_add(deleted_wake_locks.stat.total_time,
+				  lock->stat.total_time);
+		deleted_wake_locks.stat.prevent_suspend_time =
+			ktime_add(deleted_wake_locks.stat.prevent_suspend_time,
+				  lock->stat.prevent_suspend_time);
+		deleted_wake_locks.stat.max_time =
+			ktime_add(deleted_wake_locks.stat.max_time,
+				  lock->stat.max_time);
+	}
+#endif
+	list_del(&lock->link);
+	spin_unlock_irqrestore(&list_lock, irqflags);
+}
+EXPORT_SYMBOL(wake_lock_destroy);
+
+static void wake_lock_internal(
+	struct wake_lock *lock, long timeout, int has_timeout)
+{
+	int type;
+	unsigned long irqflags;
+	long expire_in;
+
+	spin_lock_irqsave(&list_lock, irqflags);
+	type = lock->flags & WAKE_LOCK_TYPE_MASK;
+	BUG_ON(type >= WAKE_LOCK_TYPE_COUNT);
+	BUG_ON(!(lock->flags & WAKE_LOCK_INITIALIZED));
+#ifdef CONFIG_WAKELOCK_STAT
+	if (type == WAKE_LOCK_SUSPEND && wait_for_wakeup) {
+		if (debug_mask & DEBUG_WAKEUP)
+			pr_info("wakeup wake lock: %s\n", lock->name);
+		wait_for_wakeup = 0;
+		lock->stat.wakeup_count++;
+	}
+	if ((lock->flags & WAKE_LOCK_AUTO_EXPIRE) &&
+	    (long)(lock->expires - jiffies) <= 0) {
+		wake_unlock_stat_locked(lock, 0);
+		lock->stat.last_time = ktime_get();
+	}
+#endif
+	if (!(lock->flags & WAKE_LOCK_ACTIVE)) {
+		lock->flags |= WAKE_LOCK_ACTIVE;
+#ifdef CONFIG_WAKELOCK_STAT
+		lock->stat.last_time = ktime_get();
+#endif
+	}
+	list_del(&lock->link);
+	if (has_timeout) {
+		if (debug_mask & DEBUG_WAKE_LOCK)
+			pr_info("wake_lock: %s, type %d, timeout %ld.%03lu\n",
+				lock->name, type, timeout / HZ,
+				(timeout % HZ) * MSEC_PER_SEC / HZ);
+		lock->expires = jiffies + timeout;
+		lock->flags |= WAKE_LOCK_AUTO_EXPIRE;
+		list_add_tail(&lock->link, &active_wake_locks[type]);
+	} else {
+		if (debug_mask & DEBUG_WAKE_LOCK)
+			pr_info("wake_lock: %s, type %d\n", lock->name, type);
+		lock->expires = LONG_MAX;
+		lock->flags &= ~WAKE_LOCK_AUTO_EXPIRE;
+		list_add(&lock->link, &active_wake_locks[type]);
+	}
+	if (type == WAKE_LOCK_SUSPEND) {
+		current_event_num++;
+#ifdef CONFIG_WAKELOCK_STAT
+		if (lock == &main_wake_lock)
+			update_sleep_wait_stats_locked(1);
+		else if (!wake_lock_active(&main_wake_lock))
+			update_sleep_wait_stats_locked(0);
+#endif
+		if (has_timeout)
+			expire_in = has_wake_lock_locked(type);
+		else
+			expire_in = -1;
+		if (expire_in > 0) {
+			if (debug_mask & DEBUG_EXPIRE)
+				pr_info("wake_lock: %s, start expire timer, "
+					"%ld\n", lock->name, expire_in);
+			mod_timer(&expire_timer, jiffies + expire_in);
+		} else {
+			if (del_timer(&expire_timer))
+				if (debug_mask & DEBUG_EXPIRE)
+					pr_info("wake_lock: %s, stop expire "
+						"timer\n", lock->name);
+			if (expire_in == 0)
+				queue_work(suspend_work_queue, &suspend_work);
+		}
+	}
+	spin_unlock_irqrestore(&list_lock, irqflags);
+}
+
+void wake_lock(struct wake_lock *lock)
+{
+	wake_lock_internal(lock, 0, 0);
+}
+EXPORT_SYMBOL(wake_lock);
+
+void wake_lock_timeout(struct wake_lock *lock, long timeout)
+{
+	wake_lock_internal(lock, timeout, 1);
+}
+EXPORT_SYMBOL(wake_lock_timeout);
+
+void wake_unlock(struct wake_lock *lock)
+{
+	int type;
+	unsigned long irqflags;
+	spin_lock_irqsave(&list_lock, irqflags);
+	type = lock->flags & WAKE_LOCK_TYPE_MASK;
+#ifdef CONFIG_WAKELOCK_STAT
+	wake_unlock_stat_locked(lock, 0);
+#endif
+	if (debug_mask & DEBUG_WAKE_LOCK)
+		pr_info("wake_unlock: %s\n", lock->name);
+	lock->flags &= ~(WAKE_LOCK_ACTIVE | WAKE_LOCK_AUTO_EXPIRE);
+	list_del(&lock->link);
+	list_add(&lock->link, &inactive_locks);
+	if (type == WAKE_LOCK_SUSPEND) {
+		long has_lock = has_wake_lock_locked(type);
+		if (has_lock > 0) {
+			if (debug_mask & DEBUG_EXPIRE)
+				pr_info("wake_unlock: %s, start expire timer, "
+					"%ld\n", lock->name, has_lock);
+			mod_timer(&expire_timer, jiffies + has_lock);
+		} else {
+			if (del_timer(&expire_timer))
+				if (debug_mask & DEBUG_EXPIRE)
+					pr_info("wake_unlock: %s, stop expire "
+						"timer\n", lock->name);
+			if (has_lock == 0)
+				queue_work(suspend_work_queue, &suspend_work);
+		}
+		if (lock == &main_wake_lock) {
+			if (debug_mask & DEBUG_SUSPEND)
+				print_active_locks(WAKE_LOCK_SUSPEND);
+#ifdef CONFIG_WAKELOCK_STAT
+			update_sleep_wait_stats_locked(0);
+#endif
+		}
+	}
+	spin_unlock_irqrestore(&list_lock, irqflags);
+}
+EXPORT_SYMBOL(wake_unlock);
+
+int wake_lock_active(struct wake_lock *lock)
+{
+	return !!(lock->flags & WAKE_LOCK_ACTIVE);
+}
+EXPORT_SYMBOL(wake_lock_active);
+
+static int __init wakelocks_init(void)
+{
+	int ret;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(active_wake_locks); i++)
+		INIT_LIST_HEAD(&active_wake_locks[i]);
+
+#ifdef CONFIG_WAKELOCK_STAT
+	wake_lock_init(&deleted_wake_locks, WAKE_LOCK_SUSPEND,
+			"deleted_wake_locks");
+#endif
+	wake_lock_init(&main_wake_lock, WAKE_LOCK_SUSPEND, "main");
+	wake_lock(&main_wake_lock);
+	wake_lock_init(&unknown_wakeup, WAKE_LOCK_SUSPEND, "unknown_wakeups");
+
+	ret = platform_device_register(&power_device);
+	if (ret) {
+		pr_err("wakelocks_init: platform_device_register failed\n");
+		goto err_platform_device_register;
+	}
+	ret = platform_driver_register(&power_driver);
+	if (ret) {
+		pr_err("wakelocks_init: platform_driver_register failed\n");
+		goto err_platform_driver_register;
+	}
+
+	suspend_work_queue = create_singlethread_workqueue("suspend");
+	if (suspend_work_queue == NULL) {
+		ret = -ENOMEM;
+		goto err_suspend_work_queue;
+	}
+
+#ifdef CONFIG_WAKELOCK_STAT
+	create_proc_read_entry("wakelocks", S_IRUGO, NULL,
+				wakelocks_read_proc, NULL);
+#endif
+
+	return 0;
+
+err_suspend_work_queue:
+	platform_driver_unregister(&power_driver);
+err_platform_driver_register:
+	platform_device_unregister(&power_device);
+err_platform_device_register:
+	wake_lock_destroy(&unknown_wakeup);
+	wake_lock_destroy(&main_wake_lock);
+#ifdef CONFIG_WAKELOCK_STAT
+	wake_lock_destroy(&deleted_wake_locks);
+#endif
+	return ret;
+}
+
+static void  __exit wakelocks_exit(void)
+{
+#ifdef CONFIG_WAKELOCK_STAT
+	remove_proc_entry("wakelocks", NULL);
+#endif
+	destroy_workqueue(suspend_work_queue);
+	platform_driver_unregister(&power_driver);
+	platform_device_unregister(&power_device);
+	wake_lock_destroy(&unknown_wakeup);
+	wake_lock_destroy(&main_wake_lock);
+#ifdef CONFIG_WAKELOCK_STAT
+	wake_lock_destroy(&deleted_wake_locks);
+#endif
+}
+
+core_initcall(wakelocks_init);
+module_exit(wakelocks_exit);
-- 
1.6.1

_______________________________________________
linux-pm mailing list
linux-pm@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/linux-pm

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 04/11] PM: Implement early suspend api
  2009-01-14  1:27     ` [PATCH 03/11] PM: Implement wakelock api Arve Hjønnevåg
@ 2009-01-14  1:27       ` Arve Hjønnevåg
  2009-01-14  1:27         ` [PATCH 05/11] PM: Enable early suspend through /sys/power/state Arve Hjønnevåg
  2009-01-14  9:48         ` [PATCH 04/11] PM: Implement early suspend api Nigel Cunningham
  2009-01-14  9:30       ` [PATCH 03/11] PM: Implement wakelock api Nigel Cunningham
  1 sibling, 2 replies; 89+ messages in thread
From: Arve Hjønnevåg @ 2009-01-14  1:27 UTC (permalink / raw)
  To: linux-pm; +Cc: swetland

Signed-off-by: Arve Hjønnevåg <arve@android.com>
---
 kernel/power/Kconfig        |   12 +++
 kernel/power/Makefile       |    1 +
 kernel/power/earlysuspend.c |  178 +++++++++++++++++++++++++++++++++++++++++++
 kernel/power/power.h        |    6 ++
 4 files changed, 197 insertions(+), 0 deletions(-)
 create mode 100644 kernel/power/earlysuspend.c

diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index 6e3da6e..50690d8 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -119,6 +119,9 @@ config SUSPEND_FREEZER
 config HAS_WAKELOCK
 	bool
 
+config HAS_EARLYSUSPEND
+	bool
+
 config WAKELOCK
 	bool "Wake lock"
 	depends on PM && RTC_CLASS
@@ -135,6 +138,15 @@ config WAKELOCK_STAT
 	---help---
 	  Report wake lock stats in /proc/wakelocks
 
+config EARLYSUSPEND
+	bool "Early suspend"
+	depends on WAKELOCK
+	default y
+	select HAS_EARLYSUSPEND
+	---help---
+	  Call early suspend handlers when the user requested sleep state
+	  changes.
+
 config HIBERNATION
 	bool "Hibernation (aka 'suspend to disk')"
 	depends on PM && SWAP && ARCH_HIBERNATION_POSSIBLE
diff --git a/kernel/power/Makefile b/kernel/power/Makefile
index 401ddfe..f0f7b15 100644
--- a/kernel/power/Makefile
+++ b/kernel/power/Makefile
@@ -6,6 +6,7 @@ endif
 obj-y				:= main.o
 obj-$(CONFIG_PM_SLEEP)		+= process.o console.o
 obj-$(CONFIG_WAKELOCK)		+= wakelock.o
+obj-$(CONFIG_EARLYSUSPEND)	+= earlysuspend.o
 obj-$(CONFIG_HIBERNATION)	+= swsusp.o disk.o snapshot.o swap.o user.o
 
 obj-$(CONFIG_MAGIC_SYSRQ)	+= poweroff.o
diff --git a/kernel/power/earlysuspend.c b/kernel/power/earlysuspend.c
new file mode 100644
index 0000000..84bed51
--- /dev/null
+++ b/kernel/power/earlysuspend.c
@@ -0,0 +1,178 @@
+/* kernel/power/earlysuspend.c
+ *
+ * Copyright (C) 2005-2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/earlysuspend.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/rtc.h>
+#include <linux/syscalls.h> /* sys_sync */
+#include <linux/wakelock.h>
+#include <linux/workqueue.h>
+
+#include "power.h"
+
+enum {
+	DEBUG_USER_STATE = 1U << 0,
+	DEBUG_SUSPEND = 1U << 2,
+};
+static int debug_mask = DEBUG_USER_STATE;
+module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP);
+
+static DEFINE_MUTEX(early_suspend_lock);
+static LIST_HEAD(early_suspend_handlers);
+static void early_suspend(struct work_struct *work);
+static void late_resume(struct work_struct *work);
+static DECLARE_WORK(early_suspend_work, early_suspend);
+static DECLARE_WORK(late_resume_work, late_resume);
+static DEFINE_SPINLOCK(state_lock);
+enum {
+	SUSPEND_REQUESTED = 0x1,
+	SUSPENDED = 0x2,
+	SUSPEND_REQUESTED_AND_SUSPENDED = SUSPEND_REQUESTED | SUSPENDED,
+};
+static int state;
+
+void register_early_suspend(struct early_suspend *handler)
+{
+	struct list_head *pos;
+
+	mutex_lock(&early_suspend_lock);
+	list_for_each(pos, &early_suspend_handlers) {
+		struct early_suspend *e;
+		e = list_entry(pos, struct early_suspend, link);
+		if (e->level > handler->level)
+			break;
+	}
+	list_add_tail(&handler->link, pos);
+	if ((state & SUSPENDED) && handler->suspend)
+		handler->suspend(handler);
+	mutex_unlock(&early_suspend_lock);
+}
+EXPORT_SYMBOL(register_early_suspend);
+
+void unregister_early_suspend(struct early_suspend *handler)
+{
+	mutex_lock(&early_suspend_lock);
+	list_del(&handler->link);
+	mutex_unlock(&early_suspend_lock);
+}
+EXPORT_SYMBOL(unregister_early_suspend);
+
+static void early_suspend(struct work_struct *work)
+{
+	struct early_suspend *pos;
+	unsigned long irqflags;
+	int abort = 0;
+
+	mutex_lock(&early_suspend_lock);
+	spin_lock_irqsave(&state_lock, irqflags);
+	if (state == SUSPEND_REQUESTED)
+		state |= SUSPENDED;
+	else
+		abort = 1;
+	spin_unlock_irqrestore(&state_lock, irqflags);
+
+	if (abort) {
+		if (debug_mask & DEBUG_SUSPEND)
+			pr_info("early_suspend: abort, state %d\n", state);
+		mutex_unlock(&early_suspend_lock);
+		goto abort;
+	}
+
+	if (debug_mask & DEBUG_SUSPEND)
+		pr_info("early_suspend: call handlers\n");
+	list_for_each_entry(pos, &early_suspend_handlers, link) {
+		if (pos->suspend != NULL)
+			pos->suspend(pos);
+	}
+	mutex_unlock(&early_suspend_lock);
+
+	if (debug_mask & DEBUG_SUSPEND)
+		pr_info("early_suspend: sync\n");
+
+	sys_sync();
+abort:
+	spin_lock_irqsave(&state_lock, irqflags);
+	if (state == SUSPEND_REQUESTED_AND_SUSPENDED)
+		wake_unlock(&main_wake_lock);
+	spin_unlock_irqrestore(&state_lock, irqflags);
+}
+
+static void late_resume(struct work_struct *work)
+{
+	struct early_suspend *pos;
+	unsigned long irqflags;
+	int abort = 0;
+
+	mutex_lock(&early_suspend_lock);
+	spin_lock_irqsave(&state_lock, irqflags);
+	if (state == SUSPENDED)
+		state &= ~SUSPENDED;
+	else
+		abort = 1;
+	spin_unlock_irqrestore(&state_lock, irqflags);
+
+	if (abort) {
+		if (debug_mask & DEBUG_SUSPEND)
+			pr_info("late_resume: abort, state %d\n", state);
+		goto abort;
+	}
+	if (debug_mask & DEBUG_SUSPEND)
+		pr_info("late_resume: call handlers\n");
+	list_for_each_entry_reverse(pos, &early_suspend_handlers, link)
+		if (pos->resume != NULL)
+			pos->resume(pos);
+	if (debug_mask & DEBUG_SUSPEND)
+		pr_info("late_resume: done\n");
+abort:
+	mutex_unlock(&early_suspend_lock);
+}
+
+void request_suspend_state(suspend_state_t new_state)
+{
+	unsigned long irqflags;
+	int old_sleep;
+
+	spin_lock_irqsave(&state_lock, irqflags);
+	old_sleep = state & SUSPEND_REQUESTED;
+	if (debug_mask & DEBUG_USER_STATE) {
+		struct timespec ts;
+		struct rtc_time tm;
+		getnstimeofday(&ts);
+		rtc_time_to_tm(ts.tv_sec, &tm);
+		pr_info("request_suspend_state: %s (%d->%d) at %lld "
+			"(%d-%02d-%02d %02d:%02d:%02d.%09lu UTC)\n",
+			new_state != PM_SUSPEND_ON ? "sleep" : "wakeup",
+			requested_suspend_state, new_state,
+			ktime_to_ns(ktime_get()),
+			tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
+			tm.tm_hour, tm.tm_min, tm.tm_sec, ts.tv_nsec);
+	}
+	if (!old_sleep && new_state != PM_SUSPEND_ON) {
+		state |= SUSPEND_REQUESTED;
+		queue_work(suspend_work_queue, &early_suspend_work);
+	} else if (old_sleep && new_state == PM_SUSPEND_ON) {
+		state &= ~SUSPEND_REQUESTED;
+		wake_lock(&main_wake_lock);
+		queue_work(suspend_work_queue, &late_resume_work);
+	}
+	requested_suspend_state = new_state;
+	spin_unlock_irqrestore(&state_lock, irqflags);
+}
+
+suspend_state_t get_suspend_state(void)
+{
+	return requested_suspend_state;
+}
diff --git a/kernel/power/power.h b/kernel/power/power.h
index 1527174..7ce9637 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -230,3 +230,9 @@ extern struct workqueue_struct *suspend_work_queue;
 extern struct wake_lock main_wake_lock;
 extern suspend_state_t requested_suspend_state;
 #endif
+
+#ifdef CONFIG_EARLYSUSPEND
+/* kernel/power/earlysuspend.c */
+void request_suspend_state(suspend_state_t state);
+suspend_state_t get_suspend_state(void);
+#endif
-- 
1.6.1

_______________________________________________
linux-pm mailing list
linux-pm@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/linux-pm

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 05/11] PM: Enable early suspend through /sys/power/state
  2009-01-14  1:27       ` [PATCH 04/11] PM: Implement early suspend api Arve Hjønnevåg
@ 2009-01-14  1:27         ` Arve Hjønnevåg
  2009-01-14  1:27           ` [PATCH 06/11] PM: Add user-space wake lock api Arve Hjønnevåg
  2009-01-28 19:34           ` [PATCH 05/11] PM: Enable early suspend through /sys/power/state Pavel Machek
  2009-01-14  9:48         ` [PATCH 04/11] PM: Implement early suspend api Nigel Cunningham
  1 sibling, 2 replies; 89+ messages in thread
From: Arve Hjønnevåg @ 2009-01-14  1:27 UTC (permalink / raw)
  To: linux-pm; +Cc: swetland

If EARLYSUSPEND is enabled then writes to /sys/power/state no longer
blocks, and the kernel will try to enter the requested state every
time no wakelocks are held. Write "on" to resume normal operation.

Signed-off-by: Arve Hjønnevåg <arve@android.com>
---
 kernel/power/main.c |   14 ++++++++++++++
 1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/kernel/power/main.c b/kernel/power/main.c
index 2399888..f2139ca 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -388,6 +388,9 @@ static void suspend_finish(void)
 
 
 static const char * const pm_states[PM_SUSPEND_MAX] = {
+#ifdef CONFIG_EARLYSUSPEND
+	[PM_SUSPEND_ON]		= "on",
+#endif
 	[PM_SUSPEND_STANDBY]	= "standby",
 	[PM_SUSPEND_MEM]	= "mem",
 };
@@ -505,7 +508,11 @@ static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr,
 			   const char *buf, size_t n)
 {
 #ifdef CONFIG_SUSPEND
+#ifdef CONFIG_EARLYSUSPEND
+	suspend_state_t state = PM_SUSPEND_ON;
+#else
 	suspend_state_t state = PM_SUSPEND_STANDBY;
+#endif
 	const char * const *s;
 #endif
 	char *p;
@@ -527,8 +534,15 @@ static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr,
 			break;
 	}
 	if (state < PM_SUSPEND_MAX && *s)
+#ifdef CONFIG_EARLYSUSPEND
+		if (state == PM_SUSPEND_ON || valid_state(state)) {
+			error = 0;
+			request_suspend_state(state);
+		}
+#else
 		error = enter_state(state);
 #endif
+#endif
 
  Exit:
 	return error ? error : n;
-- 
1.6.1

_______________________________________________
linux-pm mailing list
linux-pm@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/linux-pm

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 06/11] PM: Add user-space wake lock api.
  2009-01-14  1:27         ` [PATCH 05/11] PM: Enable early suspend through /sys/power/state Arve Hjønnevåg
@ 2009-01-14  1:27           ` Arve Hjønnevåg
  2009-01-14  1:27             ` [PATCH 07/11] PM: wakelock: Abort task freezing if a wake lock is held Arve Hjønnevåg
  2009-01-30 12:43             ` [PATCH 06/11] PM: Add user-space wake lock api Uli Luckas
  2009-01-28 19:34           ` [PATCH 05/11] PM: Enable early suspend through /sys/power/state Pavel Machek
  1 sibling, 2 replies; 89+ messages in thread
From: Arve Hjønnevåg @ 2009-01-14  1:27 UTC (permalink / raw)
  To: linux-pm; +Cc: swetland

This adds /sys/power/wake_lock and /sys/power/wake_unlock.
Writing a string to wake_lock creates a wake lock the
first time is sees a string and locks it. Optionally, the
string can be followed by a timeout.
To unlock the wake lock, write the same string to wake_unlock.

Signed-off-by: Arve Hjønnevåg <arve@android.com>
---
 kernel/power/Kconfig        |   10 ++
 kernel/power/Makefile       |    1 +
 kernel/power/main.c         |    9 ++
 kernel/power/power.h        |   11 ++
 kernel/power/userwakelock.c |  218 +++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 249 insertions(+), 0 deletions(-)
 create mode 100644 kernel/power/userwakelock.c

diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index 50690d8..dd6910d 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -138,6 +138,16 @@ config WAKELOCK_STAT
 	---help---
 	  Report wake lock stats in /proc/wakelocks
 
+config USER_WAKELOCK
+	bool "Userspace wake locks"
+	depends on WAKELOCK
+	default y
+	---help---
+	  User-space wake lock api. Write "lockname" or "lockname timeout"
+	  to /sys/power/wake_lock lock and if needed create a wake lock.
+	  Write "lockname" to /sys/power/wake_unlock to unlock a user wake
+	  lock.
+
 config EARLYSUSPEND
 	bool "Early suspend"
 	depends on WAKELOCK
diff --git a/kernel/power/Makefile b/kernel/power/Makefile
index f0f7b15..4d838cd 100644
--- a/kernel/power/Makefile
+++ b/kernel/power/Makefile
@@ -6,6 +6,7 @@ endif
 obj-y				:= main.o
 obj-$(CONFIG_PM_SLEEP)		+= process.o console.o
 obj-$(CONFIG_WAKELOCK)		+= wakelock.o
+obj-$(CONFIG_USER_WAKELOCK)	+= userwakelock.o
 obj-$(CONFIG_EARLYSUSPEND)	+= earlysuspend.o
 obj-$(CONFIG_HIBERNATION)	+= swsusp.o disk.o snapshot.o swap.o user.o
 
diff --git a/kernel/power/main.c b/kernel/power/main.c
index f2139ca..587f881 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -575,6 +575,11 @@ pm_trace_store(struct kobject *kobj, struct kobj_attribute *attr,
 power_attr(pm_trace);
 #endif /* CONFIG_PM_TRACE */
 
+#ifdef CONFIG_USER_WAKELOCK
+power_attr(wake_lock);
+power_attr(wake_unlock);
+#endif
+
 static struct attribute * g[] = {
 	&state_attr.attr,
 #ifdef CONFIG_PM_TRACE
@@ -583,6 +588,10 @@ static struct attribute * g[] = {
 #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PM_DEBUG)
 	&pm_test_attr.attr,
 #endif
+#ifdef CONFIG_USER_WAKELOCK
+	&wake_lock_attr.attr,
+	&wake_unlock_attr.attr,
+#endif
 	NULL,
 };
 
diff --git a/kernel/power/power.h b/kernel/power/power.h
index 7ce9637..d1b19fc 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -231,6 +231,17 @@ extern struct wake_lock main_wake_lock;
 extern suspend_state_t requested_suspend_state;
 #endif
 
+#ifdef CONFIG_USER_WAKELOCK
+ssize_t wake_lock_show(struct kobject *kobj, struct kobj_attribute *attr,
+			char *buf);
+ssize_t wake_lock_store(struct kobject *kobj, struct kobj_attribute *attr,
+			const char *buf, size_t n);
+ssize_t wake_unlock_show(struct kobject *kobj, struct kobj_attribute *attr,
+			char *buf);
+ssize_t  wake_unlock_store(struct kobject *kobj, struct kobj_attribute *attr,
+			const char *buf, size_t n);
+#endif
+
 #ifdef CONFIG_EARLYSUSPEND
 /* kernel/power/earlysuspend.c */
 void request_suspend_state(suspend_state_t state);
diff --git a/kernel/power/userwakelock.c b/kernel/power/userwakelock.c
new file mode 100644
index 0000000..d7242d9
--- /dev/null
+++ b/kernel/power/userwakelock.c
@@ -0,0 +1,218 @@
+/* kernel/power/userwakelock.c
+ *
+ * Copyright (C) 2005-2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/ctype.h>
+#include <linux/module.h>
+#include <linux/wakelock.h>
+
+#include "power.h"
+
+enum {
+	DEBUG_FAILURE	= BIT(0),
+	DEBUG_ERROR	= BIT(1),
+	DEBUG_NEW	= BIT(2),
+	DEBUG_ACCESS	= BIT(3),
+	DEBUG_LOOKUP	= BIT(4),
+};
+static int debug_mask = DEBUG_FAILURE;
+module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP);
+
+static DEFINE_MUTEX(tree_lock);
+
+struct user_wake_lock {
+	struct rb_node		node;
+	struct wake_lock	wake_lock;
+	char			name[0];
+};
+struct rb_root user_wake_locks;
+
+static struct user_wake_lock *lookup_wake_lock_name(
+	const char *buf, int allocate, long *timeoutptr)
+{
+	struct rb_node **p = &user_wake_locks.rb_node;
+	struct rb_node *parent = NULL;
+	struct user_wake_lock *l;
+	int diff;
+	u64 timeout;
+	int name_len;
+	const char *arg;
+
+	/* Find length of lock name and start of optional timeout string */
+	arg = buf;
+	while (*arg && !isspace(*arg))
+		arg++;
+	name_len = arg - buf;
+	if (!name_len)
+		goto bad_arg;
+	while (isspace(*arg))
+		arg++;
+
+	/* Process timeout string */
+	if (timeoutptr && *arg) {
+		timeout = simple_strtoull(arg, (char **)&arg, 0);
+		while (isspace(*arg))
+			arg++;
+		if (*arg)
+			goto bad_arg;
+		/* convert timeout from nanoseconds to jiffies > 0 */
+		timeout += (NSEC_PER_SEC / HZ) - 1;
+		do_div(timeout, (NSEC_PER_SEC / HZ));
+		if (timeout <= 0)
+			timeout = 1;
+		*timeoutptr = timeout;
+	} else if (*arg)
+		goto bad_arg;
+	else if (timeoutptr)
+		*timeoutptr = 0;
+
+	/* Lookup wake lock in rbtree */
+	while (*p) {
+		parent = *p;
+		l = rb_entry(parent, struct user_wake_lock, node);
+		diff = strncmp(buf, l->name, name_len);
+		if (!diff && l->name[name_len])
+			diff = -1;
+		if (debug_mask & DEBUG_ERROR)
+			pr_info("lookup_wake_lock_name: compare %.*s %s %d\n",
+				name_len, buf, l->name, diff);
+
+		if (diff < 0)
+			p = &(*p)->rb_left;
+		else if (diff > 0)
+			p = &(*p)->rb_right;
+		else
+			return l;
+	}
+
+	/* Allocate and add new wakelock to rbtree */
+	if (!allocate) {
+		if (debug_mask & DEBUG_ERROR)
+			pr_info("lookup_wake_lock_name: %.*s not found\n",
+				name_len, buf);
+		return ERR_PTR(-EINVAL);
+	}
+	l = kzalloc(sizeof(*l) + name_len + 1, GFP_KERNEL);
+	if (l == NULL) {
+		if (debug_mask & DEBUG_FAILURE)
+			pr_err("lookup_wake_lock_name: failed to allocate "
+				"memory for %.*s\n", name_len, buf);
+		return ERR_PTR(-ENOMEM);
+	}
+	memcpy(l->name, buf, name_len);
+	if (debug_mask & DEBUG_NEW)
+		pr_info("lookup_wake_lock_name: new wake lock %s\n", l->name);
+	wake_lock_init(&l->wake_lock, WAKE_LOCK_SUSPEND, l->name);
+	rb_link_node(&l->node, parent, p);
+	rb_insert_color(&l->node, &user_wake_locks);
+	return l;
+
+bad_arg:
+	if (debug_mask & DEBUG_ERROR)
+		pr_info("lookup_wake_lock_name: wake lock, %.*s, bad arg, %s\n",
+			name_len, buf, arg);
+	return ERR_PTR(-EINVAL);
+}
+
+ssize_t wake_lock_show(
+	struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+{
+	char *s = buf;
+	char *end = buf + PAGE_SIZE;
+	struct rb_node *n;
+	struct user_wake_lock *l;
+
+	mutex_lock(&tree_lock);
+
+	for (n = rb_first(&user_wake_locks); n != NULL; n = rb_next(n)) {
+		l = rb_entry(n, struct user_wake_lock, node);
+		if (wake_lock_active(&l->wake_lock))
+			s += scnprintf(s, end - s, "%s ", l->name);
+	}
+	s += scnprintf(s, end - s, "\n");
+
+	mutex_unlock(&tree_lock);
+	return (s - buf);
+}
+
+ssize_t wake_lock_store(
+	struct kobject *kobj, struct kobj_attribute *attr,
+	const char *buf, size_t n)
+{
+	long timeout;
+	struct user_wake_lock *l;
+
+	mutex_lock(&tree_lock);
+	l = lookup_wake_lock_name(buf, 1, &timeout);
+	if (IS_ERR(l)) {
+		n = PTR_ERR(l);
+		goto bad_name;
+	}
+
+	if (debug_mask & DEBUG_ACCESS)
+		pr_info("wake_lock_store: %s, timeout %ld\n", l->name, timeout);
+
+	if (timeout)
+		wake_lock_timeout(&l->wake_lock, timeout);
+	else
+		wake_lock(&l->wake_lock);
+bad_name:
+	mutex_unlock(&tree_lock);
+	return n;
+}
+
+
+ssize_t wake_unlock_show(
+	struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+{
+	char *s = buf;
+	char *end = buf + PAGE_SIZE;
+	struct rb_node *n;
+	struct user_wake_lock *l;
+
+	mutex_lock(&tree_lock);
+
+	for (n = rb_first(&user_wake_locks); n != NULL; n = rb_next(n)) {
+		l = rb_entry(n, struct user_wake_lock, node);
+		if (!wake_lock_active(&l->wake_lock))
+			s += scnprintf(s, end - s, "%s ", l->name);
+	}
+	s += scnprintf(s, end - s, "\n");
+
+	mutex_unlock(&tree_lock);
+	return (s - buf);
+}
+
+ssize_t wake_unlock_store(
+	struct kobject *kobj, struct kobj_attribute *attr,
+	const char *buf, size_t n)
+{
+	struct user_wake_lock *l;
+
+	mutex_lock(&tree_lock);
+	l = lookup_wake_lock_name(buf, 0, NULL);
+	if (IS_ERR(l)) {
+		n = PTR_ERR(l);
+		goto not_found;
+	}
+
+	if (debug_mask & DEBUG_ACCESS)
+		pr_info("wake_unlock_store: %s\n", l->name);
+
+	wake_unlock(&l->wake_lock);
+not_found:
+	mutex_unlock(&tree_lock);
+	return n;
+}
+
-- 
1.6.1

_______________________________________________
linux-pm mailing list
linux-pm@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/linux-pm

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 07/11] PM: wakelock: Abort task freezing if a wake lock is held.
  2009-01-14  1:27           ` [PATCH 06/11] PM: Add user-space wake lock api Arve Hjønnevåg
@ 2009-01-14  1:27             ` Arve Hjønnevåg
  2009-01-14  1:27               ` [PATCH 08/11] PM: earlysuspend: Add console switch when user requested sleep state changes Arve Hjønnevåg
  2009-01-30 12:43             ` [PATCH 06/11] PM: Add user-space wake lock api Uli Luckas
  1 sibling, 1 reply; 89+ messages in thread
From: Arve Hjønnevåg @ 2009-01-14  1:27 UTC (permalink / raw)
  To: linux-pm; +Cc: swetland

Avoids a problem where the device sometimes hangs for 20 seconds
before the screen is turned on.

Signed-off-by: Arve Hjønnevåg <arve@android.com>
---
 kernel/power/process.c |   22 +++++++++++++++++-----
 1 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/kernel/power/process.c b/kernel/power/process.c
index ca63401..8388d01 100644
--- a/kernel/power/process.c
+++ b/kernel/power/process.c
@@ -13,6 +13,7 @@
 #include <linux/module.h>
 #include <linux/syscalls.h>
 #include <linux/freezer.h>
+#include <linux/wakelock.h>
 
 /* 
  * Timeout for stopping processes
@@ -36,6 +37,7 @@ static int try_to_freeze_tasks(bool sig_only)
 	struct timeval start, end;
 	u64 elapsed_csecs64;
 	unsigned int elapsed_csecs;
+	unsigned int wakeup = 0;
 
 	do_gettimeofday(&start);
 
@@ -62,6 +64,10 @@ static int try_to_freeze_tasks(bool sig_only)
 		} while_each_thread(g, p);
 		read_unlock(&tasklist_lock);
 		yield();			/* Yield is okay here */
+		if (todo && has_wake_lock(WAKE_LOCK_SUSPEND)) {
+			wakeup = 1;
+			break;
+		}
 		if (time_after(jiffies, end_time))
 			break;
 	} while (todo);
@@ -77,11 +83,17 @@ static int try_to_freeze_tasks(bool sig_only)
 		 * and caller must call thaw_processes() if something fails),
 		 * but it cleans up leftover PF_FREEZE requests.
 		 */
-		printk("\n");
-		printk(KERN_ERR "Freezing of tasks failed after %d.%02d seconds "
-				"(%d tasks refusing to freeze):\n",
-				elapsed_csecs / 100, elapsed_csecs % 100, todo);
-		show_state();
+		if (wakeup) {
+			printk("\n");
+			printk(KERN_ERR "Freezing of %s aborted\n",
+					sig_only ? "user space " : "tasks ");
+		} else {
+			printk("\n");
+			printk(KERN_ERR "Freezing of tasks failed after %d.%02d seconds "
+					"(%d tasks refusing to freeze):\n",
+					elapsed_csecs / 100, elapsed_csecs % 100, todo);
+			show_state();
+		}
 		read_lock(&tasklist_lock);
 		do_each_thread(g, p) {
 			task_lock(p);
-- 
1.6.1

_______________________________________________
linux-pm mailing list
linux-pm@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/linux-pm

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 08/11] PM: earlysuspend: Add console switch when user requested sleep state changes.
  2009-01-14  1:27             ` [PATCH 07/11] PM: wakelock: Abort task freezing if a wake lock is held Arve Hjønnevåg
@ 2009-01-14  1:27               ` Arve Hjønnevåg
  2009-01-14  1:27                 ` [PATCH 09/11] PM: earlysuspend: Removing dependence on console Arve Hjønnevåg
  0 siblings, 1 reply; 89+ messages in thread
From: Arve Hjønnevåg @ 2009-01-14  1:27 UTC (permalink / raw)
  To: linux-pm; +Cc: swetland

Signed-off-by: Arve Hjønnevåg <arve@android.com>
---
 kernel/power/Kconfig               |   17 ++++++++
 kernel/power/Makefile              |    1 +
 kernel/power/consoleearlysuspend.c |   78 ++++++++++++++++++++++++++++++++++++
 3 files changed, 96 insertions(+), 0 deletions(-)
 create mode 100644 kernel/power/consoleearlysuspend.c

diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index dd6910d..36e442f 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -157,6 +157,23 @@ config EARLYSUSPEND
 	  Call early suspend handlers when the user requested sleep state
 	  changes.
 
+choice
+	prompt "User-space screen access"
+	default CONSOLE_EARLYSUSPEND
+	depends on HAS_EARLYSUSPEND
+
+	config NO_USER_SPACE_SCREEN_ACCESS_CONTROL
+		bool "None"
+
+	config CONSOLE_EARLYSUSPEND
+		bool "Console switch on early-suspend"
+		depends on HAS_EARLYSUSPEND && VT
+		---help---
+		  Register early suspend handler to perform a console switch to
+		  when user-space should stop drawing to the screen and a switch
+		  back when it should resume.
+endchoice
+
 config HIBERNATION
 	bool "Hibernation (aka 'suspend to disk')"
 	depends on PM && SWAP && ARCH_HIBERNATION_POSSIBLE
diff --git a/kernel/power/Makefile b/kernel/power/Makefile
index 4d838cd..5b74133 100644
--- a/kernel/power/Makefile
+++ b/kernel/power/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_PM_SLEEP)		+= process.o console.o
 obj-$(CONFIG_WAKELOCK)		+= wakelock.o
 obj-$(CONFIG_USER_WAKELOCK)	+= userwakelock.o
 obj-$(CONFIG_EARLYSUSPEND)	+= earlysuspend.o
+obj-$(CONFIG_CONSOLE_EARLYSUSPEND)	+= consoleearlysuspend.o
 obj-$(CONFIG_HIBERNATION)	+= swsusp.o disk.o snapshot.o swap.o user.o
 
 obj-$(CONFIG_MAGIC_SYSRQ)	+= poweroff.o
diff --git a/kernel/power/consoleearlysuspend.c b/kernel/power/consoleearlysuspend.c
new file mode 100644
index 0000000..a8befb4
--- /dev/null
+++ b/kernel/power/consoleearlysuspend.c
@@ -0,0 +1,78 @@
+/* kernel/power/consoleearlysuspend.c
+ *
+ * Copyright (C) 2005-2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/console.h>
+#include <linux/earlysuspend.h>
+#include <linux/kbd_kern.h>
+#include <linux/module.h>
+#include <linux/vt_kern.h>
+#include <linux/wait.h>
+
+#define EARLY_SUSPEND_CONSOLE	(MAX_NR_CONSOLES-1)
+
+static int orig_fgconsole;
+static void console_early_suspend(struct early_suspend *h)
+{
+	acquire_console_sem();
+	orig_fgconsole = fg_console;
+	if (vc_allocate(EARLY_SUSPEND_CONSOLE))
+		goto err;
+	if (set_console(EARLY_SUSPEND_CONSOLE))
+		goto err;
+	release_console_sem();
+
+	if (vt_waitactive(EARLY_SUSPEND_CONSOLE))
+		pr_warning("console_early_suspend: Can't switch VCs.\n");
+	return;
+err:
+	pr_warning("console_early_suspend: Can't set console\n");
+	release_console_sem();
+}
+
+static void console_late_resume(struct early_suspend *h)
+{
+	int ret;
+	acquire_console_sem();
+	ret = set_console(orig_fgconsole);
+	release_console_sem();
+	if (ret) {
+		pr_warning("console_late_resume: Can't set console.\n");
+		return;
+	}
+
+	if (vt_waitactive(orig_fgconsole))
+		pr_warning("console_late_resume: Can't switch VCs.\n");
+}
+
+static struct early_suspend console_early_suspend_desc = {
+	.level = EARLY_SUSPEND_LEVEL_STOP_DRAWING,
+	.suspend = console_early_suspend,
+	.resume = console_late_resume,
+};
+
+static int __init console_early_suspend_init(void)
+{
+	register_early_suspend(&console_early_suspend_desc);
+	return 0;
+}
+
+static void  __exit console_early_suspend_exit(void)
+{
+	unregister_early_suspend(&console_early_suspend_desc);
+}
+
+module_init(console_early_suspend_init);
+module_exit(console_early_suspend_exit);
+
-- 
1.6.1

_______________________________________________
linux-pm mailing list
linux-pm@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/linux-pm

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 09/11] PM: earlysuspend: Removing dependence on console.
  2009-01-14  1:27               ` [PATCH 08/11] PM: earlysuspend: Add console switch when user requested sleep state changes Arve Hjønnevåg
@ 2009-01-14  1:27                 ` Arve Hjønnevåg
  2009-01-14  1:27                   ` [PATCH 10/11] Input: Hold wake lock while event queue is not empty Arve Hjønnevåg
  0 siblings, 1 reply; 89+ messages in thread
From: Arve Hjønnevåg @ 2009-01-14  1:27 UTC (permalink / raw)
  To: linux-pm; +Cc: Rebecca Schultz, swetland

From: Rebecca Schultz <rschultz@google.com>

Rather than signaling a full update of the display from userspace via a
console switch, this patch introduces 2 files int /sys/power,
wait_for_fb_sleep and wait_for_fb_wake.  Reading these files will block
until the requested state has been entered.  When a read from
wait_for_fb_sleep returns userspace should stop drawing.  When
wait_for_fb_wake returns, it should do a full update.  If either are called
when the fb driver is already in the requested state, they will return
immediately.

Signed-off-by: Rebecca Schultz <rschultz@google.com>
Signed-off-by: Arve Hjønnevåg <arve@android.com>
---
 kernel/power/Kconfig          |    9 +++
 kernel/power/Makefile         |    1 +
 kernel/power/fbearlysuspend.c |  153 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 163 insertions(+), 0 deletions(-)
 create mode 100644 kernel/power/fbearlysuspend.c

diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index 36e442f..015e6ae 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -159,6 +159,7 @@ config EARLYSUSPEND
 
 choice
 	prompt "User-space screen access"
+	default FB_EARLYSUSPEND if !FRAMEBUFFER_CONSOLE
 	default CONSOLE_EARLYSUSPEND
 	depends on HAS_EARLYSUSPEND
 
@@ -172,6 +173,14 @@ choice
 		  Register early suspend handler to perform a console switch to
 		  when user-space should stop drawing to the screen and a switch
 		  back when it should resume.
+
+	config FB_EARLYSUSPEND
+		bool "Sysfs interface"
+		depends on HAS_EARLYSUSPEND
+		---help---
+		  Register early suspend handler that notifies and waits for
+		  user-space through sysfs when user-space should stop drawing
+		  to the screen and notifies user-space when it should resume.
 endchoice
 
 config HIBERNATION
diff --git a/kernel/power/Makefile b/kernel/power/Makefile
index 5b74133..7b8b2cc 100644
--- a/kernel/power/Makefile
+++ b/kernel/power/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_WAKELOCK)		+= wakelock.o
 obj-$(CONFIG_USER_WAKELOCK)	+= userwakelock.o
 obj-$(CONFIG_EARLYSUSPEND)	+= earlysuspend.o
 obj-$(CONFIG_CONSOLE_EARLYSUSPEND)	+= consoleearlysuspend.o
+obj-$(CONFIG_FB_EARLYSUSPEND)	+= fbearlysuspend.o
 obj-$(CONFIG_HIBERNATION)	+= swsusp.o disk.o snapshot.o swap.o user.o
 
 obj-$(CONFIG_MAGIC_SYSRQ)	+= poweroff.o
diff --git a/kernel/power/fbearlysuspend.c b/kernel/power/fbearlysuspend.c
new file mode 100644
index 0000000..1513765
--- /dev/null
+++ b/kernel/power/fbearlysuspend.c
@@ -0,0 +1,153 @@
+/* kernel/power/fbearlysuspend.c
+ *
+ * Copyright (C) 2005-2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/earlysuspend.h>
+#include <linux/module.h>
+#include <linux/wait.h>
+
+#include "power.h"
+
+static wait_queue_head_t fb_state_wq;
+static DEFINE_SPINLOCK(fb_state_lock);
+static enum {
+	FB_STATE_STOPPED_DRAWING,
+	FB_STATE_REQUEST_STOP_DRAWING,
+	FB_STATE_DRAWING_OK,
+} fb_state;
+
+/* tell userspace to stop drawing, wait for it to stop */
+static void stop_drawing_early_suspend(struct early_suspend *h)
+{
+	int ret;
+	unsigned long irq_flags;
+
+	spin_lock_irqsave(&fb_state_lock, irq_flags);
+	fb_state = FB_STATE_REQUEST_STOP_DRAWING;
+	spin_unlock_irqrestore(&fb_state_lock, irq_flags);
+
+	wake_up_all(&fb_state_wq);
+	ret = wait_event_timeout(fb_state_wq,
+				 fb_state == FB_STATE_STOPPED_DRAWING,
+				 HZ);
+	if (unlikely(fb_state != FB_STATE_STOPPED_DRAWING))
+		pr_warning("stop_drawing_early_suspend: timeout waiting for "
+			   "userspace to stop drawing\n");
+}
+
+/* tell userspace to start drawing */
+static void start_drawing_late_resume(struct early_suspend *h)
+{
+	unsigned long irq_flags;
+
+	spin_lock_irqsave(&fb_state_lock, irq_flags);
+	fb_state = FB_STATE_DRAWING_OK;
+	spin_unlock_irqrestore(&fb_state_lock, irq_flags);
+	wake_up(&fb_state_wq);
+}
+
+static struct early_suspend stop_drawing_early_suspend_desc = {
+	.level = EARLY_SUSPEND_LEVEL_STOP_DRAWING,
+	.suspend = stop_drawing_early_suspend,
+	.resume = start_drawing_late_resume,
+};
+
+static ssize_t wait_for_fb_sleep_show(struct kobject *kobj,
+				      struct kobj_attribute *attr, char *buf)
+{
+	char *s = buf;
+	int ret;
+
+	ret = wait_event_interruptible(fb_state_wq,
+				       fb_state != FB_STATE_DRAWING_OK);
+	if (ret && fb_state == FB_STATE_DRAWING_OK)
+		return ret;
+	else
+		s += sprintf(buf, "sleeping");
+	return s - buf;
+}
+
+static ssize_t wait_for_fb_wake_show(struct kobject *kobj,
+				     struct kobj_attribute *attr, char *buf)
+{
+	char *s = buf;
+	int ret;
+	unsigned long irq_flags;
+
+	spin_lock_irqsave(&fb_state_lock, irq_flags);
+	if (fb_state == FB_STATE_REQUEST_STOP_DRAWING) {
+		fb_state = FB_STATE_STOPPED_DRAWING;
+		wake_up(&fb_state_wq);
+	}
+	spin_unlock_irqrestore(&fb_state_lock, irq_flags);
+
+	ret = wait_event_interruptible(fb_state_wq,
+				       fb_state == FB_STATE_DRAWING_OK);
+	if (ret && fb_state != FB_STATE_DRAWING_OK)
+		return ret;
+	else
+		s += sprintf(buf, "awake");
+
+	return s - buf;
+}
+
+#define power_ro_attr(_name) \
+static struct kobj_attribute _name##_attr = {	\
+	.attr	= {				\
+		.name = __stringify(_name),	\
+		.mode = 0444,			\
+	},					\
+	.show	= _name##_show,			\
+	.store	= NULL,		\
+}
+
+power_ro_attr(wait_for_fb_sleep);
+power_ro_attr(wait_for_fb_wake);
+
+static struct attribute *g[] = {
+	&wait_for_fb_sleep_attr.attr,
+	&wait_for_fb_wake_attr.attr,
+	NULL,
+};
+
+static struct attribute_group attr_group = {
+	.attrs = g,
+};
+
+static int __init android_power_init(void)
+{
+	int ret;
+
+	init_waitqueue_head(&fb_state_wq);
+	fb_state = FB_STATE_DRAWING_OK;
+
+	ret = sysfs_create_group(power_kobj, &attr_group);
+	if (ret) {
+		pr_err("android_power_init: sysfs_create_group failed\n");
+		return ret;
+	}
+
+	register_early_suspend(&stop_drawing_early_suspend_desc);
+	return 0;
+}
+
+static void  __exit android_power_exit(void)
+{
+	unregister_early_suspend(&stop_drawing_early_suspend_desc);
+	sysfs_remove_group(power_kobj, &attr_group);
+}
+
+module_init(android_power_init);
+module_exit(android_power_exit);
+
-- 
1.6.1

_______________________________________________
linux-pm mailing list
linux-pm@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/linux-pm

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 10/11] Input: Hold wake lock while event queue is not empty.
  2009-01-14  1:27                 ` [PATCH 09/11] PM: earlysuspend: Removing dependence on console Arve Hjønnevåg
@ 2009-01-14  1:27                   ` Arve Hjønnevåg
  2009-01-14  1:27                     ` [PATCH 11/11] ledtrig-sleep: Add led trigger for sleep debugging Arve Hjønnevåg
  0 siblings, 1 reply; 89+ messages in thread
From: Arve Hjønnevåg @ 2009-01-14  1:27 UTC (permalink / raw)
  To: linux-pm; +Cc: swetland

Allows userspace code to process input events while
the device appears to be asleep.

Signed-off-by: Arve Hjønnevåg <arve@android.com>
---
 drivers/input/evdev.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index ed8baa0..e24050b 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -19,6 +19,7 @@
 #include <linux/input.h>
 #include <linux/major.h>
 #include <linux/device.h>
+#include <linux/wakelock.h>
 #include "input-compat.h"
 
 struct evdev {
@@ -43,6 +44,7 @@ struct evdev_client {
 	struct fasync_struct *fasync;
 	struct evdev *evdev;
 	struct list_head node;
+	struct wake_lock wake_lock;
 };
 
 static struct evdev *evdev_table[EVDEV_MINORS];
@@ -55,6 +57,7 @@ static void evdev_pass_event(struct evdev_client *client,
 	 * Interrupts are disabled, just acquire the lock
 	 */
 	spin_lock(&client->buffer_lock);
+	wake_lock_timeout(&client->wake_lock, 5 * HZ);
 	client->buffer[client->head++] = *event;
 	client->head &= EVDEV_BUFFER_SIZE - 1;
 	spin_unlock(&client->buffer_lock);
@@ -236,6 +239,7 @@ static int evdev_release(struct inode *inode, struct file *file)
 	mutex_unlock(&evdev->mutex);
 
 	evdev_detach_client(evdev, client);
+	wake_lock_destroy(&client->wake_lock);
 	kfree(client);
 
 	evdev_close_device(evdev);
@@ -272,6 +276,7 @@ static int evdev_open(struct inode *inode, struct file *file)
 	}
 
 	spin_lock_init(&client->buffer_lock);
+	wake_lock_init(&client->wake_lock, WAKE_LOCK_SUSPEND, "evdev");
 	client->evdev = evdev;
 	evdev_attach_client(evdev, client);
 
@@ -335,6 +340,8 @@ static int evdev_fetch_next_event(struct evdev_client *client,
 	if (have_event) {
 		*event = client->buffer[client->tail++];
 		client->tail &= EVDEV_BUFFER_SIZE - 1;
+		if (client->head == client->tail)
+			wake_unlock(&client->wake_lock);
 	}
 
 	spin_unlock_irq(&client->buffer_lock);
-- 
1.6.1

_______________________________________________
linux-pm mailing list
linux-pm@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/linux-pm

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 11/11] ledtrig-sleep: Add led trigger for sleep debugging.
  2009-01-14  1:27                   ` [PATCH 10/11] Input: Hold wake lock while event queue is not empty Arve Hjønnevåg
@ 2009-01-14  1:27                     ` Arve Hjønnevåg
  0 siblings, 0 replies; 89+ messages in thread
From: Arve Hjønnevåg @ 2009-01-14  1:27 UTC (permalink / raw)
  To: linux-pm; +Cc: swetland

Signed-off-by: Brian Swetland <swetland@google.com>
Signed-off-by: Arve Hjønnevåg <arve@android.com>
---
 drivers/leds/Kconfig         |    6 +++
 drivers/leds/Makefile        |    1 +
 drivers/leds/ledtrig-sleep.c |   80 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 87 insertions(+), 0 deletions(-)
 create mode 100644 drivers/leds/ledtrig-sleep.c

diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index a4a1ae2..2d555a3 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -230,4 +230,10 @@ config LEDS_TRIGGER_DEFAULT_ON
 	  This allows LEDs to be initialised in the ON state.
 	  If unsure, say Y.
 
+config LEDS_TRIGGER_SLEEP
+	tristate "LED Sleep Mode Trigger"
+	depends on LEDS_TRIGGERS && HAS_EARLYSUSPEND
+	help
+	  This turns LEDs on when the screen is off but the cpu still running.
+
 endif # NEW_LEDS
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index bc247cb..e259998 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -32,3 +32,4 @@ obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK)	+= ledtrig-ide-disk.o
 obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT)	+= ledtrig-heartbeat.o
 obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT)	+= ledtrig-backlight.o
 obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON)	+= ledtrig-default-on.o
+obj-$(CONFIG_LEDS_TRIGGER_SLEEP)	+= ledtrig-sleep.o
diff --git a/drivers/leds/ledtrig-sleep.c b/drivers/leds/ledtrig-sleep.c
new file mode 100644
index 0000000..f164042
--- /dev/null
+++ b/drivers/leds/ledtrig-sleep.c
@@ -0,0 +1,80 @@
+/* drivers/leds/ledtrig-sleep.c
+ *
+ * Copyright (C) 2007 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/earlysuspend.h>
+#include <linux/leds.h>
+#include <linux/suspend.h>
+
+static int ledtrig_sleep_pm_callback(struct notifier_block *nfb,
+					unsigned long action,
+					void *ignored);
+
+DEFINE_LED_TRIGGER(ledtrig_sleep)
+static struct notifier_block ledtrig_sleep_pm_notifier = {
+	.notifier_call = ledtrig_sleep_pm_callback,
+	.priority = 0,
+};
+
+static void ledtrig_sleep_early_suspend(struct early_suspend *h)
+{
+	led_trigger_event(ledtrig_sleep, LED_FULL);
+}
+
+static void ledtrig_sleep_early_resume(struct early_suspend *h)
+{
+	led_trigger_event(ledtrig_sleep, LED_OFF);
+}
+
+static struct early_suspend ledtrig_sleep_early_suspend_handler = {
+	.suspend = ledtrig_sleep_early_suspend,
+	.resume = ledtrig_sleep_early_resume,
+};
+
+static int ledtrig_sleep_pm_callback(struct notifier_block *nfb,
+					unsigned long action,
+					void *ignored)
+{
+	switch (action) {
+	case PM_HIBERNATION_PREPARE:
+	case PM_SUSPEND_PREPARE:
+		led_trigger_event(ledtrig_sleep, LED_OFF);
+		return NOTIFY_OK;
+	case PM_POST_HIBERNATION:
+	case PM_POST_SUSPEND:
+		led_trigger_event(ledtrig_sleep, LED_FULL);
+		return NOTIFY_OK;
+	}
+
+	return NOTIFY_DONE;
+}
+
+static int __init ledtrig_sleep_init(void)
+{
+	led_trigger_register_simple("sleep", &ledtrig_sleep);
+	register_pm_notifier(&ledtrig_sleep_pm_notifier);
+	register_early_suspend(&ledtrig_sleep_early_suspend_handler);
+	return 0;
+}
+
+static void __exit ledtrig_sleep_exit(void)
+{
+	unregister_early_suspend(&ledtrig_sleep_early_suspend_handler);
+	unregister_pm_notifier(&ledtrig_sleep_pm_notifier);
+	led_trigger_unregister_simple(ledtrig_sleep);
+}
+
+module_init(ledtrig_sleep_init);
+module_exit(ledtrig_sleep_exit);
+
-- 
1.6.1

_______________________________________________
linux-pm mailing list
linux-pm@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/linux-pm

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-01-14  1:27 [RFC][PATCH 00/11] Android PM extensions Arve Hjønnevåg
  2009-01-14  1:27 ` [PATCH 01/11] PM: Add wake lock api Arve Hjønnevåg
@ 2009-01-14  9:01 ` Nigel Cunningham
  2009-01-15  0:10   ` Arve Hjønnevåg
  2009-01-15  4:42   ` Arve Hjønnevåg
  2009-01-28 19:31 ` Pavel Machek
  2 siblings, 2 replies; 89+ messages in thread
From: Nigel Cunningham @ 2009-01-14  9:01 UTC (permalink / raw)
  To: Arve Hjønnevåg; +Cc: swetland, linux-pm

Hi Arve.

On Tue, 2009-01-13 at 17:27 -0800, Arve Hjønnevåg wrote:
> The following patch series adds two apis, wakelock and earlysuspend.
> The Android platform uses the earlysuspend api to turn the screen
> and some input devices on and off. The wakelock code determines when
> to enter the full suspend state.
> 
> These apis could also be useful to other platforms where the goal is
> to enter full suspend whenever possible.

A few general comments:

Would you be able to provide some more documentation? In particular, I'm
wondering what's 'early' about earlysuspend. It might also be good to
something to Documentation/power explaining what the apis are, when/how
they're supposed to be used and such like.

In the Kconfig files, I'm also missing the point to HAS_EARLYSUSPEND and
HAS_WAKELOCK - they're bools that depends only on  and WAKELOCK
respectively, so shouldn't you be able to just use the later symbols in
ifdefs?

There are a few inlined #ifdefs (#ifdef CONFIG_WAKELOCK_STAT, eg) - the
convention as I understand it is to keep #ifdefs out of .c files as much
as possible, #ifdef'ing functions in header files instead.

Regards,

Nigel

_______________________________________________
linux-pm mailing list
linux-pm@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/linux-pm

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 01/11] PM: Add wake lock api.
  2009-01-14  1:27 ` [PATCH 01/11] PM: Add wake lock api Arve Hjønnevåg
  2009-01-14  1:27   ` [PATCH 02/11] PM: Add early suspend api Arve Hjønnevåg
@ 2009-01-14  9:09   ` Nigel Cunningham
  2009-01-14 23:07     ` Arve Hjønnevåg
  1 sibling, 1 reply; 89+ messages in thread
From: Nigel Cunningham @ 2009-01-14  9:09 UTC (permalink / raw)
  To: Arve Hjønnevåg; +Cc: swetland, linux-pm

Hi.

On Tue, 2009-01-13 at 17:27 -0800, Arve Hjønnevåg wrote:
> Signed-off-by: Arve Hjønnevåg <arve@android.com>
> ---
>  include/linux/wakelock.h |   91 ++++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 91 insertions(+), 0 deletions(-)
>  create mode 100755 include/linux/wakelock.h
> 
> diff --git a/include/linux/wakelock.h b/include/linux/wakelock.h
> new file mode 100755
> index 0000000..a096d24
> --- /dev/null
> +++ b/include/linux/wakelock.h
> @@ -0,0 +1,91 @@
> +/* include/linux/wakelock.h
> + *
> + * Copyright (C) 2007-2008 Google, Inc.
> + *
> + * This software is licensed under the terms of the GNU General Public
> + * License version 2, as published by the Free Software Foundation, and
> + * may be copied, distributed, and modified under those terms.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + */
> +
> +#ifndef _LINUX_WAKELOCK_H
> +#define _LINUX_WAKELOCK_H
> +
> +#include <linux/list.h>
> +#include <linux/ktime.h>
> +
> +/* A wake_lock prevents the system from entering suspend or other low power
> + * states when active. If the type is set to WAKE_LOCK_SUSPEND, the wake_lock
> + * prevents a full system suspend. If the type is WAKE_LOCK_IDLE, low power

Does this include hibernation? If so, you might like to say 'sleep'
instead of suspend.

> + * states that cause large interrupt latencies or that disable a set of
> + * interrupts will not entered from idle until the wake_locks are released.

This makes me wonder if 'wake_locks' is an appropriate name - you're
locking against sleeping rather than waking.

> + */
> +
> +enum {
> +	WAKE_LOCK_SUSPEND, /* Prevent suspend */
> +	WAKE_LOCK_IDLE,    /* Prevent low power idle */
> +	WAKE_LOCK_TYPE_COUNT
> +};
> +
> +struct wake_lock {
> +#ifdef CONFIG_HAS_WAKELOCK
> +	struct list_head    link;
> +	int                 flags;
> +	const char         *name;
> +	unsigned long       expires;
> +#ifdef CONFIG_WAKELOCK_STAT
> +	struct {
> +		int             count;
> +		int             expire_count;
> +		int             wakeup_count;
> +		ktime_t         total_time;
> +		ktime_t         prevent_suspend_time;
> +		ktime_t         max_time;
> +		ktime_t         last_time;
> +	} stat;
> +#endif
> +#endif
> +};

If CONFIG_HAS_WAKELOCK and CONFIG_WAKELOCK_STAT are both off, you've got
an empty struct wake_lock definition. It wouldn't have any users, would
it? (And therefore doesn't need to be defined at all).

> +
> +#ifdef CONFIG_HAS_WAKELOCK
> +
> +void wake_lock_init(struct wake_lock *lock, int type, const char *name);
> +void wake_lock_destroy(struct wake_lock *lock);
> +void wake_lock(struct wake_lock *lock);
> +void wake_lock_timeout(struct wake_lock *lock, long timeout);
> +void wake_unlock(struct wake_lock *lock);
> +
> +/* wake_lock_active returns a non-zero value if the wake_lock is currently
> + * locked. If the wake_lock has a timeout, it does not check the timeout
> + * but if the timeout had aready been checked it will return 0.

s/aready/already/

What does it mean for the timeout to already have been checked? Is that
the same as the timeout having already expired?

> + */
> +int wake_lock_active(struct wake_lock *lock);
> +
> +/* has_wake_lock returns 0 if no wake locks of the specified type are active,
> + * and non-zero if one or more wake locks are held. Specifically it returns
> + * -1 if one or more wake locks with no timeout are active or the
> + * number of jiffies until all active wake locks time out.
> + */
> +long has_wake_lock(int type);
> +
> +#else
> +
> +static inline void wake_lock_init(struct wake_lock *lock, int type,
> +					const char *name) {}
> +static inline void wake_lock_destroy(struct wake_lock *lock) {}
> +static inline void wake_lock(struct wake_lock *lock) {}
> +static inline void wake_lock_timeout(struct wake_lock *lock, long timeout) {}
> +static inline void wake_unlock(struct wake_lock *lock) {}
> +
> +static inline int wake_lock_active(struct wake_lock *lock) { return 0; }
> +static inline long has_wake_lock(int type) { return 0; }
> +
> +#endif
> +
> +#endif
> +

Regards,

Nigel

_______________________________________________
linux-pm mailing list
linux-pm@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/linux-pm

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 02/11] PM: Add early suspend api.
  2009-01-14  1:27   ` [PATCH 02/11] PM: Add early suspend api Arve Hjønnevåg
  2009-01-14  1:27     ` [PATCH 03/11] PM: Implement wakelock api Arve Hjønnevåg
@ 2009-01-14  9:17     ` Nigel Cunningham
  2009-01-14 23:18       ` Arve Hjønnevåg
  1 sibling, 1 reply; 89+ messages in thread
From: Nigel Cunningham @ 2009-01-14  9:17 UTC (permalink / raw)
  To: Arve Hjønnevåg; +Cc: swetland, linux-pm

Hi.

On Tue, 2009-01-13 at 17:27 -0800, Arve Hjønnevåg wrote:
> Signed-off-by: Arve Hjønnevåg <arve@android.com>
> ---
>  include/linux/earlysuspend.h |   56 ++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 56 insertions(+), 0 deletions(-)
>  create mode 100755 include/linux/earlysuspend.h
> 
> diff --git a/include/linux/earlysuspend.h b/include/linux/earlysuspend.h
> new file mode 100755
> index 0000000..8343b81
> --- /dev/null
> +++ b/include/linux/earlysuspend.h
> @@ -0,0 +1,56 @@
> +/* include/linux/earlysuspend.h
> + *
> + * Copyright (C) 2007-2008 Google, Inc.
> + *
> + * This software is licensed under the terms of the GNU General Public
> + * License version 2, as published by the Free Software Foundation, and
> + * may be copied, distributed, and modified under those terms.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + */
> +
> +#ifndef _LINUX_EARLYSUSPEND_H
> +#define _LINUX_EARLYSUSPEND_H
> +
> +#ifdef CONFIG_HAS_EARLYSUSPEND
> +#include <linux/list.h>
> +#endif

Just #include anyway - it doesn't matter if it doesn't get used in some
circumstances.

> +
> +/* The early_suspend structure defines suspend and resume hooks to be called
> + * when the user visible sleep state of the system changes, and a level to
> + * control the order. They can be used to turn off the screen and input
> + * devices that are not used for wakeup.
> + * Suspend handlers are called in low to high level order, resume handlers are
> + * called in the opposite order. If, when calling register_early_suspend,
> + * the suspend handlers have already been called without a matching call to the
> + * resume handlers, the suspend handler will be called directly from
> + * register_early_suspend. This direct call can violate the normal level order.
> + */

Registering can happen while we're suspending and resuming? That
potential variation in ordering sounds dangerous as far as opportunities
for race conditions goes.

> +enum {
> +	EARLY_SUSPEND_LEVEL_BLANK_SCREEN = 50,
> +	EARLY_SUSPEND_LEVEL_STOP_DRAWING = 100,
> +	EARLY_SUSPEND_LEVEL_DISABLE_FB = 150,
> +};
> +struct early_suspend {
> +#ifdef CONFIG_HAS_EARLYSUSPEND
> +	struct list_head link;
> +	int level;
> +	void (*suspend)(struct early_suspend *h);
> +	void (*resume)(struct early_suspend *h);

Could these functions ever potentially fail in way that you'd want
callers to know? If so, you might want a non void return value.

> +#endif
> +};
> +
> +#ifdef CONFIG_HAS_EARLYSUSPEND
> +void register_early_suspend(struct early_suspend *handler);
> +void unregister_early_suspend(struct early_suspend *handler);
> +#else
> +#define register_early_suspend(handler) do { } while (0)
> +#define unregister_early_suspend(handler) do { } while (0)
> +#endif
> +
> +#endif
> +

Regards,

Nigel

_______________________________________________
linux-pm mailing list
linux-pm@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/linux-pm

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 03/11] PM: Implement wakelock api.
  2009-01-14  1:27     ` [PATCH 03/11] PM: Implement wakelock api Arve Hjønnevåg
  2009-01-14  1:27       ` [PATCH 04/11] PM: Implement early suspend api Arve Hjønnevåg
@ 2009-01-14  9:30       ` Nigel Cunningham
  2009-01-14 23:28         ` Arve Hjønnevåg
  1 sibling, 1 reply; 89+ messages in thread
From: Nigel Cunningham @ 2009-01-14  9:30 UTC (permalink / raw)
  To: Arve Hjønnevåg; +Cc: swetland, linux-pm

Hi again.

Just one comment here - you're adding new procfs entries. IIRC, sysfs is
strongly preferred now.

Regards,

Nigel

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 04/11] PM: Implement early suspend api
  2009-01-14  1:27       ` [PATCH 04/11] PM: Implement early suspend api Arve Hjønnevåg
  2009-01-14  1:27         ` [PATCH 05/11] PM: Enable early suspend through /sys/power/state Arve Hjønnevåg
@ 2009-01-14  9:48         ` Nigel Cunningham
  2009-01-14 23:57           ` Arve Hjønnevåg
  1 sibling, 1 reply; 89+ messages in thread
From: Nigel Cunningham @ 2009-01-14  9:48 UTC (permalink / raw)
  To: Arve Hjønnevåg; +Cc: swetland, linux-pm

Hi.

On Tue, 2009-01-13 at 17:27 -0800, Arve Hjønnevåg wrote:
> Signed-off-by: Arve Hjønnevåg <arve@android.com>
> ---
>  kernel/power/Kconfig        |   12 +++
>  kernel/power/Makefile       |    1 +
>  kernel/power/earlysuspend.c |  178 +++++++++++++++++++++++++++++++++++++++++++
>  kernel/power/power.h        |    6 ++
>  4 files changed, 197 insertions(+), 0 deletions(-)
>  create mode 100644 kernel/power/earlysuspend.c
> 
> diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
> index 6e3da6e..50690d8 100644
> --- a/kernel/power/Kconfig
> +++ b/kernel/power/Kconfig
> @@ -119,6 +119,9 @@ config SUSPEND_FREEZER
>  config HAS_WAKELOCK
>  	bool
>  
> +config HAS_EARLYSUSPEND
> +	bool
> +
>  config WAKELOCK
>  	bool "Wake lock"
>  	depends on PM && RTC_CLASS
> @@ -135,6 +138,15 @@ config WAKELOCK_STAT
>  	---help---
>  	  Report wake lock stats in /proc/wakelocks
>  
> +config EARLYSUSPEND
> +	bool "Early suspend"
> +	depends on WAKELOCK
> +	default y
> +	select HAS_EARLYSUSPEND
> +	---help---
> +	  Call early suspend handlers when the user requested sleep state
> +	  changes.
> +
>  config HIBERNATION
>  	bool "Hibernation (aka 'suspend to disk')"
>  	depends on PM && SWAP && ARCH_HIBERNATION_POSSIBLE
> diff --git a/kernel/power/Makefile b/kernel/power/Makefile
> index 401ddfe..f0f7b15 100644
> --- a/kernel/power/Makefile
> +++ b/kernel/power/Makefile
> @@ -6,6 +6,7 @@ endif
>  obj-y				:= main.o
>  obj-$(CONFIG_PM_SLEEP)		+= process.o console.o
>  obj-$(CONFIG_WAKELOCK)		+= wakelock.o
> +obj-$(CONFIG_EARLYSUSPEND)	+= earlysuspend.o
>  obj-$(CONFIG_HIBERNATION)	+= swsusp.o disk.o snapshot.o swap.o user.o
>  
>  obj-$(CONFIG_MAGIC_SYSRQ)	+= poweroff.o
> diff --git a/kernel/power/earlysuspend.c b/kernel/power/earlysuspend.c
> new file mode 100644
> index 0000000..84bed51
> --- /dev/null
> +++ b/kernel/power/earlysuspend.c
> @@ -0,0 +1,178 @@
> +/* kernel/power/earlysuspend.c
> + *
> + * Copyright (C) 2005-2008 Google, Inc.
> + *
> + * This software is licensed under the terms of the GNU General Public
> + * License version 2, as published by the Free Software Foundation, and
> + * may be copied, distributed, and modified under those terms.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + */
> +
> +#include <linux/earlysuspend.h>
> +#include <linux/module.h>
> +#include <linux/mutex.h>
> +#include <linux/rtc.h>
> +#include <linux/syscalls.h> /* sys_sync */
> +#include <linux/wakelock.h>
> +#include <linux/workqueue.h>
> +
> +#include "power.h"
> +
> +enum {
> +	DEBUG_USER_STATE = 1U << 0,
> +	DEBUG_SUSPEND = 1U << 2,
> +};

Is there a reason DEBUG_SUSPEND isn't 1U << 1? If so, it might be good
to document that here.

> +static int debug_mask = DEBUG_USER_STATE;
> +module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP);
> +
> +static DEFINE_MUTEX(early_suspend_lock);
> +static LIST_HEAD(early_suspend_handlers);
> +static void early_suspend(struct work_struct *work);
> +static void late_resume(struct work_struct *work);
> +static DECLARE_WORK(early_suspend_work, early_suspend);
> +static DECLARE_WORK(late_resume_work, late_resume);
> +static DEFINE_SPINLOCK(state_lock);
> +enum {
> +	SUSPEND_REQUESTED = 0x1,
> +	SUSPENDED = 0x2,
> +	SUSPEND_REQUESTED_AND_SUSPENDED = SUSPEND_REQUESTED | SUSPENDED,
> +};
> +static int state;
> +
> +void register_early_suspend(struct early_suspend *handler)
> +{
> +	struct list_head *pos;
> +
> +	mutex_lock(&early_suspend_lock);
> +	list_for_each(pos, &early_suspend_handlers) {
> +		struct early_suspend *e;
> +		e = list_entry(pos, struct early_suspend, link);

list_for_each_entry?

> +		if (e->level > handler->level)
> +			break;
> +	}
> +	list_add_tail(&handler->link, pos);
> +	if ((state & SUSPENDED) && handler->suspend)
> +		handler->suspend(handler);
> +	mutex_unlock(&early_suspend_lock);
> +}
> +EXPORT_SYMBOL(register_early_suspend);
> +
> +void unregister_early_suspend(struct early_suspend *handler)
> +{
> +	mutex_lock(&early_suspend_lock);
> +	list_del(&handler->link);
> +	mutex_unlock(&early_suspend_lock);
> +}
> +EXPORT_SYMBOL(unregister_early_suspend);
> +
> +static void early_suspend(struct work_struct *work)
> +{
> +	struct early_suspend *pos;
> +	unsigned long irqflags;
> +	int abort = 0;
> +
> +	mutex_lock(&early_suspend_lock);
> +	spin_lock_irqsave(&state_lock, irqflags);
> +	if (state == SUSPEND_REQUESTED)
> +		state |= SUSPENDED;
> +	else
> +		abort = 1;
> +	spin_unlock_irqrestore(&state_lock, irqflags);
> +
> +	if (abort) {
> +		if (debug_mask & DEBUG_SUSPEND)
> +			pr_info("early_suspend: abort, state %d\n", state);
> +		mutex_unlock(&early_suspend_lock);
> +		goto abort;
> +	}
> +
> +	if (debug_mask & DEBUG_SUSPEND)
> +		pr_info("early_suspend: call handlers\n");
> +	list_for_each_entry(pos, &early_suspend_handlers, link) {
> +		if (pos->suspend != NULL)

Just "if (pos->suspend)" is sufficient.

> +			pos->suspend(pos);
> +	}
> +	mutex_unlock(&early_suspend_lock);
> +
> +	if (debug_mask & DEBUG_SUSPEND)
> +		pr_info("early_suspend: sync\n");
> +
> +	sys_sync();

Why the sync here?

> +abort:
> +	spin_lock_irqsave(&state_lock, irqflags);
> +	if (state == SUSPEND_REQUESTED_AND_SUSPENDED)
> +		wake_unlock(&main_wake_lock);
> +	spin_unlock_irqrestore(&state_lock, irqflags);
> +}
> +
> +static void late_resume(struct work_struct *work)
> +{
> +	struct early_suspend *pos;
> +	unsigned long irqflags;
> +	int abort = 0;
> +
> +	mutex_lock(&early_suspend_lock);
> +	spin_lock_irqsave(&state_lock, irqflags);
> +	if (state == SUSPENDED)
> +		state &= ~SUSPENDED;

Why not just say state = 0?

> +	else
> +		abort = 1;
> +	spin_unlock_irqrestore(&state_lock, irqflags);
> +
> +	if (abort) {
> +		if (debug_mask & DEBUG_SUSPEND)
> +			pr_info("late_resume: abort, state %d\n", state);
> +		goto abort;
> +	}
> +	if (debug_mask & DEBUG_SUSPEND)
> +		pr_info("late_resume: call handlers\n");
> +	list_for_each_entry_reverse(pos, &early_suspend_handlers, link)
> +		if (pos->resume != NULL)

if (pos->resume)

> +			pos->resume(pos);
> +	if (debug_mask & DEBUG_SUSPEND)
> +		pr_info("late_resume: done\n");
> +abort:
> +	mutex_unlock(&early_suspend_lock);
> +}
> +
> +void request_suspend_state(suspend_state_t new_state)
> +{
> +	unsigned long irqflags;
> +	int old_sleep;
> +
> +	spin_lock_irqsave(&state_lock, irqflags);
> +	old_sleep = state & SUSPEND_REQUESTED;
> +	if (debug_mask & DEBUG_USER_STATE) {
> +		struct timespec ts;
> +		struct rtc_time tm;
> +		getnstimeofday(&ts);
> +		rtc_time_to_tm(ts.tv_sec, &tm);
> +		pr_info("request_suspend_state: %s (%d->%d) at %lld "
> +			"(%d-%02d-%02d %02d:%02d:%02d.%09lu UTC)\n",
> +			new_state != PM_SUSPEND_ON ? "sleep" : "wakeup",
> +			requested_suspend_state, new_state,
> +			ktime_to_ns(ktime_get()),
> +			tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
> +			tm.tm_hour, tm.tm_min, tm.tm_sec, ts.tv_nsec);
> +	}
> +	if (!old_sleep && new_state != PM_SUSPEND_ON) {
> +		state |= SUSPEND_REQUESTED;
> +		queue_work(suspend_work_queue, &early_suspend_work);
> +	} else if (old_sleep && new_state == PM_SUSPEND_ON) {
> +		state &= ~SUSPEND_REQUESTED;
> +		wake_lock(&main_wake_lock);
> +		queue_work(suspend_work_queue, &late_resume_work);
> +	}
> +	requested_suspend_state = new_state;
> +	spin_unlock_irqrestore(&state_lock, irqflags);
> +}
> +
> +suspend_state_t get_suspend_state(void)
> +{
> +	return requested_suspend_state;
> +}
> diff --git a/kernel/power/power.h b/kernel/power/power.h
> index 1527174..7ce9637 100644
> --- a/kernel/power/power.h
> +++ b/kernel/power/power.h
> @@ -230,3 +230,9 @@ extern struct workqueue_struct *suspend_work_queue;
>  extern struct wake_lock main_wake_lock;
>  extern suspend_state_t requested_suspend_state;
>  #endif
> +
> +#ifdef CONFIG_EARLYSUSPEND
> +/* kernel/power/earlysuspend.c */
> +void request_suspend_state(suspend_state_t state);
> +suspend_state_t get_suspend_state(void);
> +#endif
> -- 
> 1.6.1

Regards,

Nigel

_______________________________________________
linux-pm mailing list
linux-pm@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/linux-pm

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 01/11] PM: Add wake lock api.
  2009-01-14  9:09   ` [PATCH 01/11] PM: Add wake lock api Nigel Cunningham
@ 2009-01-14 23:07     ` Arve Hjønnevåg
  0 siblings, 0 replies; 89+ messages in thread
From: Arve Hjønnevåg @ 2009-01-14 23:07 UTC (permalink / raw)
  To: Nigel Cunningham; +Cc: swetland, linux-pm

On Wed, Jan 14, 2009 at 1:09 AM, Nigel Cunningham
<ncunningham@crca.org.au> wrote:
>> +/* A wake_lock prevents the system from entering suspend or other low power
>> + * states when active. If the type is set to WAKE_LOCK_SUSPEND, the wake_lock
>> + * prevents a full system suspend. If the type is WAKE_LOCK_IDLE, low power
>
> Does this include hibernation? If so, you might like to say 'sleep'
> instead of suspend.
>

Not as it is currently implemented, but it probably should. The main
reason I avoid saying 'sleep' is that we enter cpu sleep modes from
idle as well.

>> + * states that cause large interrupt latencies or that disable a set of
>> + * interrupts will not entered from idle until the wake_locks are released.
>
> This makes me wonder if 'wake_locks' is an appropriate name - you're
> locking against sleeping rather than waking.
>

It depends on how you look at it. We lock the system in the wake
state, or we lock against the suspend/sleep state. I have also seen
the term sleep vote used for a very similar mechanism, but I don't
like this either as a sleep vote is a veto against sleep.
I initially called it a suspend lock, then wake lock in user space.
Wake lock is the term that stuck so I changed the kernel api to use
it.

>
> If CONFIG_HAS_WAKELOCK and CONFIG_WAKELOCK_STAT are both off, you've got
> an empty struct wake_lock definition. It wouldn't have any users, would
> it? (And therefore doesn't need to be defined at all).
>

I do this to avoid #ifdefs on CONFIG_HAS_WAKELOCK in the drivers.

>> +/* wake_lock_active returns a non-zero value if the wake_lock is currently
>> + * locked. If the wake_lock has a timeout, it does not check the timeout
>> + * but if the timeout had aready been checked it will return 0.
>
> s/aready/already/
>
> What does it mean for the timeout to already have been checked? Is that
> the same as the timeout having already expired?
>

What I meant was that the wake lock had been checked and deactivated
from another code-path, after the timeout expired.


-- 
Arve Hjønnevåg

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 02/11] PM: Add early suspend api.
  2009-01-14  9:17     ` [PATCH 02/11] PM: Add early suspend api Nigel Cunningham
@ 2009-01-14 23:18       ` Arve Hjønnevåg
  0 siblings, 0 replies; 89+ messages in thread
From: Arve Hjønnevåg @ 2009-01-14 23:18 UTC (permalink / raw)
  To: Nigel Cunningham; +Cc: swetland, linux-pm

On Wed, Jan 14, 2009 at 1:17 AM, Nigel Cunningham
<ncunningham@crca.org.au> wrote:
>> +
>> +/* The early_suspend structure defines suspend and resume hooks to be called
>> + * when the user visible sleep state of the system changes, and a level to
>> + * control the order. They can be used to turn off the screen and input
>> + * devices that are not used for wakeup.
>> + * Suspend handlers are called in low to high level order, resume handlers are
>> + * called in the opposite order. If, when calling register_early_suspend,
>> + * the suspend handlers have already been called without a matching call to the
>> + * resume handlers, the suspend handler will be called directly from
>> + * register_early_suspend. This direct call can violate the normal level order.
>> + */
>
> Registering can happen while we're suspending and resuming? That
> potential variation in ordering sounds dangerous as far as opportunities
> for race conditions goes.
>

Yes, but there is no time limit on how long the system is in the early
suspend state. This direct call at least allows a driver to rely on
suspend being called before resume.

>> +struct early_suspend {
>> +#ifdef CONFIG_HAS_EARLYSUSPEND
>> +     struct list_head link;
>> +     int level;
>> +     void (*suspend)(struct early_suspend *h);
>> +     void (*resume)(struct early_suspend *h);
>
> Could these functions ever potentially fail in way that you'd want
> callers to know? If so, you might want a non void return value.
>

They are not allowed to fail. These calls inform drivers that the user
visible sleep state has changed.

-- 
Arve Hjønnevåg

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 03/11] PM: Implement wakelock api.
  2009-01-14  9:30       ` [PATCH 03/11] PM: Implement wakelock api Nigel Cunningham
@ 2009-01-14 23:28         ` Arve Hjønnevåg
  0 siblings, 0 replies; 89+ messages in thread
From: Arve Hjønnevåg @ 2009-01-14 23:28 UTC (permalink / raw)
  To: Nigel Cunningham; +Cc: swetland, linux-pm

On Wed, Jan 14, 2009 at 1:30 AM, Nigel Cunningham
<ncunningham@crca.org.au> wrote:
> Just one comment here - you're adding new procfs entries. IIRC, sysfs is
> strongly preferred now.

I'm adding one procfs entry for stats/debugging information. The sysfs
rules do not allow this type of data so procfs seemed like the best
fit.

-- 
Arve Hjønnevåg

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 04/11] PM: Implement early suspend api
  2009-01-14  9:48         ` [PATCH 04/11] PM: Implement early suspend api Nigel Cunningham
@ 2009-01-14 23:57           ` Arve Hjønnevåg
  0 siblings, 0 replies; 89+ messages in thread
From: Arve Hjønnevåg @ 2009-01-14 23:57 UTC (permalink / raw)
  To: Nigel Cunningham; +Cc: swetland, linux-pm

On Wed, Jan 14, 2009 at 1:48 AM, Nigel Cunningham
<ncunningham@crca.org.au> wrote:
>> +enum {
>> +     DEBUG_USER_STATE = 1U << 0,
>> +     DEBUG_SUSPEND = 1U << 2,
>> +};
>
> Is there a reason DEBUG_SUSPEND isn't 1U << 1? If so, it might be good
> to document that here.
>

No. I missed it when separating the wake lock and early suspend code.

>> +     if (debug_mask & DEBUG_SUSPEND)
>> +             pr_info("early_suspend: sync\n");
>> +
>> +     sys_sync();
>
> Why the sync here?

At this point the device appears to asleep to the user but wakelocks
can prevent full suspend (which also calls sys_sync).

>> +     if (state == SUSPENDED)
>> +             state &= ~SUSPENDED;
>
> Why not just say state = 0?
>
Only the SUSPENDED bit may be modified here, but in this case state = 0 is safe.


-- 
Arve Hjønnevåg

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-01-14  9:01 ` [RFC][PATCH 00/11] Android PM extensions Nigel Cunningham
@ 2009-01-15  0:10   ` Arve Hjønnevåg
  2009-01-15  4:42   ` Arve Hjønnevåg
  1 sibling, 0 replies; 89+ messages in thread
From: Arve Hjønnevåg @ 2009-01-15  0:10 UTC (permalink / raw)
  To: Nigel Cunningham; +Cc: swetland, linux-pm

On Wed, Jan 14, 2009 at 1:01 AM, Nigel Cunningham
<ncunningham@crca.org.au> wrote:
> Would you be able to provide some more documentation? In particular, I'm
> wondering what's 'early' about earlysuspend. It might also be good to
> something to Documentation/power explaining what the apis are, when/how
> they're supposed to be used and such like.

I called it earlysuspend since it a prerequisite for entering the
normal suspend state. It is really the user visible suspend state.

> In the Kconfig files, I'm also missing the point to HAS_EARLYSUSPEND and
> HAS_WAKELOCK - they're bools that depends only on  and WAKELOCK
> respectively, so shouldn't you be able to just use the later symbols in
> ifdefs?

I initially had provided the wakelock and earlysuspend apis on top of
the android_power driver then added the current implementation. If
there is no interest in allowing multiple implementations of the api,
can can remove these.

> There are a few inlined #ifdefs (#ifdef CONFIG_WAKELOCK_STAT, eg) - the
> convention as I understand it is to keep #ifdefs out of .c files as much
> as possible, #ifdef'ing functions in header files instead.

I would not want to move these to the (existing) header file as they
are private to the wakelock implementation, but I could add some some
helper functions in a single #ifdef block.

-- 
Arve Hjønnevåg

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-01-14  9:01 ` [RFC][PATCH 00/11] Android PM extensions Nigel Cunningham
  2009-01-15  0:10   ` Arve Hjønnevåg
@ 2009-01-15  4:42   ` Arve Hjønnevåg
  2009-01-15 15:08     ` Alan Stern
  1 sibling, 1 reply; 89+ messages in thread
From: Arve Hjønnevåg @ 2009-01-15  4:42 UTC (permalink / raw)
  To: Nigel Cunningham; +Cc: swetland, linux-pm

On Wed, Jan 14, 2009 at 1:01 AM, Nigel Cunningham
<ncunningham@crca.org.au> wrote:
> Would you be able to provide some more documentation?

Would something like this help:
Documentation/power/wakelocks.txt

Wakelocks
=========

A wake_lock prevents the system from entering suspend or other low power
states when active. If the type is set to WAKE_LOCK_SUSPEND, the wake_lock
prevents a full system suspend. If the type is WAKE_LOCK_IDLE, low power
states that cause large interrupt latencies or that disable a set of
interrupts will not entered from idle until the wake_locks are released.


Driver API
==========

A driver can use the wakelock api by adding a wakelock variable to its state
and calling wake_lock_init. For instance:
struct state {
        struct wakelock wakelock;
}

init() {
        wake_lock_init(&state->wakelock, WAKE_LOCK_SUSPEND, "wakelockname");
}

Before freeing the memory wake_lock_destroy must be called:

uninit() {
        wake_lock_destroy(&state->wakelock);
}

When the driver determines that it needs to run (usually in an interrupt
handler) it calls wake_lock:
        wake_lock(&state->wakelock);

When it no longer needs to run it calls wake_unlock:
        wake_unlock(&state->wakelock);

It can also call wake_lock_timeout to release the wakelock after a delay:
        wake_lock_timeout(&state->wakelock, HZ);

This works whether the wake_lock is already held or not. It is useful if the
driver woke up other parts of the system that does not use wakelocks but
still need to run. Avoid this when possible, since it will waste power
if the timeout is long or may fail to finish needed work if the timeout is
short.


User-space API
==============

Write "lockname" or "lockname timeout" to /sys/power/wake_lock lock and if
needed create a wake lock. The timeout here is specified nanoseconds.
Write "lockname" to /sys/power/wake_unlock to unlock a user wake lock.

Do not use randomly generated wakelock names as there is no api to free
a userspace wakelock.



-- 
Arve Hjønnevåg

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-01-15  4:42   ` Arve Hjønnevåg
@ 2009-01-15 15:08     ` Alan Stern
  2009-01-15 20:34       ` Arve Hjønnevåg
  2009-01-29 13:04       ` Pavel Machek
  0 siblings, 2 replies; 89+ messages in thread
From: Alan Stern @ 2009-01-15 15:08 UTC (permalink / raw)
  To: Arve Hjønnevåg; +Cc: swetland, Nigel Cunningham, linux-pm

6~On Wed, 14 Jan 2009, Arve Hjønnevåg wrote:

> On Wed, Jan 14, 2009 at 1:01 AM, Nigel Cunningham
> <ncunningham@crca.org.au> wrote:
> > Would you be able to provide some more documentation?
> 
> Would something like this help:
> Documentation/power/wakelocks.txt
> 
> Wakelocks
> =========
> 
> A wake_lock prevents the system from entering suspend or other low power
> states when active. If the type is set to WAKE_LOCK_SUSPEND, the wake_lock
> prevents a full system suspend. If the type is WAKE_LOCK_IDLE, low power
> states that cause large interrupt latencies or that disable a set of
> interrupts will not entered from idle until the wake_locks are released.

Apart from the grammatical errors in this document and the
over-engineering it describes, the writeup is terribly ambiguous.  
What do you mean by "prevents a full system suspend"?  Does it mean
that attempts to suspend the system will fail?  Or will they just
block until all these locks are released?

Is there in fact any reason to add a new way for drivers to prevent a 
full system suspend?  They can already cause a suspend to fail by 
returning an error from their suspend method, or cause a suspend to 
block by sleeping in their suspend method.

Alan Stern

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-01-15 15:08     ` Alan Stern
@ 2009-01-15 20:34       ` Arve Hjønnevåg
  2009-01-29 13:04       ` Pavel Machek
  1 sibling, 0 replies; 89+ messages in thread
From: Arve Hjønnevåg @ 2009-01-15 20:34 UTC (permalink / raw)
  To: Alan Stern; +Cc: swetland, Nigel Cunningham, linux-pm

On Thu, Jan 15, 2009 at 7:08 AM, Alan Stern <stern@rowland.harvard.edu> wrote:
> What do you mean by "prevents a full system suspend"?  Does it mean
> that attempts to suspend the system will fail?  Or will they just
> block until all these locks are released?

When you release the last wakelock, the wakelock code will attempt to
suspend. Holding a wakelock prevents this, and it also will abort
suspend for you if the system is in the middle of suspending drivers.

> Is there in fact any reason to add a new way for drivers to prevent a
> full system suspend?  They can already cause a suspend to fail by
> returning an error from their suspend method, or cause a suspend to
> block by sleeping in their suspend method.

Returning an error would from suspend works to some degree, but it
provides no indication of when to retry the suspend operation. Also
each suspend attempt will freeze and thaw every process in the system
so it is not a good way to ensure that userspace code gets to run.
Sleeping in the suspend method will also prevent a wakeup so it is
only usable for short delays. Wakelocks can be held for hours if
needed.

-- 
Arve Hjønnevåg

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-01-14  1:27 [RFC][PATCH 00/11] Android PM extensions Arve Hjønnevåg
  2009-01-14  1:27 ` [PATCH 01/11] PM: Add wake lock api Arve Hjønnevåg
  2009-01-14  9:01 ` [RFC][PATCH 00/11] Android PM extensions Nigel Cunningham
@ 2009-01-28 19:31 ` Pavel Machek
  2 siblings, 0 replies; 89+ messages in thread
From: Pavel Machek @ 2009-01-28 19:31 UTC (permalink / raw)
  To: Arve Hj??nnev??g; +Cc: swetland, linux-pm

On Tue 2009-01-13 17:27:45, Arve Hj??nnev??g wrote:
> The following patch series adds two apis, wakelock and earlysuspend.
> The Android platform uses the earlysuspend api to turn the screen
> and some input devices on and off. The wakelock code determines when
> to enter the full suspend state.
> 
> These apis could also be useful to other platforms where the goal is
> to enter full suspend whenever possible.

'sleepy linux'. Thanks for doing this.
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 05/11] PM: Enable early suspend through /sys/power/state
  2009-01-14  1:27         ` [PATCH 05/11] PM: Enable early suspend through /sys/power/state Arve Hjønnevåg
  2009-01-14  1:27           ` [PATCH 06/11] PM: Add user-space wake lock api Arve Hjønnevåg
@ 2009-01-28 19:34           ` Pavel Machek
  2009-01-31  3:13             ` Arve Hjønnevåg
  1 sibling, 1 reply; 89+ messages in thread
From: Pavel Machek @ 2009-01-28 19:34 UTC (permalink / raw)
  To: Arve Hj??nnev??g; +Cc: swetland, linux-pm

Hi!

> If EARLYSUSPEND is enabled then writes to /sys/power/state no longer
> blocks, and the kernel will try to enter the requested state every
> time no wakelocks are held. Write "on" to resume normal operation.

No, please don't break compatibility like this. You changed semantics
of 'mem'...

Just add another two states, for example "auto-mem" and
"auto-standby", and make them enter mem/standby when required.

Ok, you'll need "on", too... for canceling... 

> @@ -388,6 +388,9 @@ static void suspend_finish(void)
>  
>  
>  static const char * const pm_states[PM_SUSPEND_MAX] = {
> +#ifdef CONFIG_EARLYSUSPEND
> +	[PM_SUSPEND_ON]		= "on",
> +#endif
>  	[PM_SUSPEND_STANDBY]	= "standby",
>  	[PM_SUSPEND_MEM]	= "mem",
>  };
> @@ -505,7 +508,11 @@ static ssize_t state_store(struct kobject
>  *kobj, struct kobj_attribute *attr,

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-01-15 15:08     ` Alan Stern
  2009-01-15 20:34       ` Arve Hjønnevåg
@ 2009-01-29 13:04       ` Pavel Machek
  2009-01-30  1:16         ` Arve Hjønnevåg
  1 sibling, 1 reply; 89+ messages in thread
From: Pavel Machek @ 2009-01-29 13:04 UTC (permalink / raw)
  To: Alan Stern; +Cc: swetland, Nigel Cunningham, linux-pm

On Thu 2009-01-15 10:08:51, Alan Stern wrote:
> 6~On Wed, 14 Jan 2009, Arve Hj?nnev?g wrote:
> 
> > On Wed, Jan 14, 2009 at 1:01 AM, Nigel Cunningham
> > <ncunningham@crca.org.au> wrote:
> > > Would you be able to provide some more documentation?
> > 
> > Would something like this help:
> > Documentation/power/wakelocks.txt
> > 
> > Wakelocks
> > =========
> > 
> > A wake_lock prevents the system from entering suspend or other low power
> > states when active. If the type is set to WAKE_LOCK_SUSPEND, the wake_lock
> > prevents a full system suspend. If the type is WAKE_LOCK_IDLE, low power
> > states that cause large interrupt latencies or that disable a set of
> > interrupts will not entered from idle until the wake_locks are released.
> 
> Apart from the grammatical errors in this document and the
> over-engineering it describes, the writeup is terribly ambiguous.  
> What do you mean by "prevents a full system suspend"?  Does it mean
> that attempts to suspend the system will fail?  Or will they just
> block until all these locks are released?
 
AFAICT, this is something very different. It is attempt to do
autosuspend right. Imagine burning cd... right now you can suspend,
and it will just stop the burn.

Wakelocks code allows you to tell the machine 'feel free to suspend
when you have nothing to do'... so the machine will burn the cd and
then suspend.

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-01-29 13:04       ` Pavel Machek
@ 2009-01-30  1:16         ` Arve Hjønnevåg
  2009-01-30  3:27           ` Alan Stern
  2009-01-30  9:08           ` Pavel Machek
  0 siblings, 2 replies; 89+ messages in thread
From: Arve Hjønnevåg @ 2009-01-30  1:16 UTC (permalink / raw)
  To: Pavel Machek; +Cc: swetland, Nigel Cunningham, linux-pm

On Thu, Jan 29, 2009 at 5:04 AM, Pavel Machek <pavel@ucw.cz> wrote:
> AFAICT, this is something very different. It is attempt to do
> autosuspend right. Imagine burning cd... right now you can suspend,
> and it will just stop the burn.
>
> Wakelocks code allows you to tell the machine 'feel free to suspend
> when you have nothing to do'... so the machine will burn the cd and
> then suspend.
>

Yes, wakelocks solves this problem, but our auto-suspend code is all
in user-space so the kernel would not have to be involved in that
particular example.

I added an example to the document that may help illustrate why we
added wakelock support in the kernel:

---
Documentation/power/wakelocks.txt
Wakelocks
=========

A wakelock prevents the system from entering suspend or other low-power
states when active. If the type is set to WAKE_LOCK_SUSPEND, the wakelock
prevents a full system suspend. If the type is WAKE_LOCK_IDLE, low-power
states that cause large interrupt latencies or that disable a set of
interrupts will not be entered from idle until the wakelocks are released.

Wakelocks can be used to allow user-space to decide which keys should wake
the system. The sequence of events can look like this:
- The Keypad driver gets an interrupt. It then locks the keypad-scan wakelock
  and starts scanning the keypad.
- The keypad-scan code detects a key change and reports it to the input-event
  driver.
- The input-event driver sees the key change, enqueues an event, and locks
  the input-event-queue wakelock.
- The keypad-scan code detects that no keys are held and unlocks the
  keypad-scan wakelock.
- The user-space input-event thread returns from select/poll, locks the
  process-input-events wakelock and then calls read in the input-event device.
- The input-event driver dequeues the key-event and, since the queue is now
  empty, it unlocks the input-event-queue wakelock.
- The user-space input-event thread returns from read. It determines that the
  key should not wake up the system, releases the process-input-events
  wakelock and calls select or poll.

                 Key pressed   Key released
                     |             |
keypad-scan          ++++++++++++++++++
input-event-queue        +++          +++
process-input-events       +++          +++


Driver API
==========

A driver can use the wakelock api by adding a wakelock variable to its state
and calling wake_lock_init. For instance:
struct state {
        struct wakelock wakelock;
}

init() {
        wake_lock_init(&state->wakelock, WAKE_LOCK_SUSPEND, "wakelockname");
}

Before freeing the memory, wake_lock_destroy must be called:

uninit() {
        wake_lock_destroy(&state->wakelock);
}

When the driver determines that it needs to run (usually in an interrupt
handler) it calls wake_lock:
        wake_lock(&state->wakelock);

When it no longer needs to run it calls wake_unlock:
        wake_unlock(&state->wakelock);

It can also call wake_lock_timeout to release the wakelock after a delay:
        wake_lock_timeout(&state->wakelock, HZ);

This works whether the wakelock is already held or not. It is useful if the
driver woke up other parts of the system that do not use wakelocks but
still need to run. Avoid this when possible, since it will waste power
if the timeout is long or may fail to finish needed work if the timeout is
short.


User-space API
==============

Write "lockname" or "lockname timeout" to /sys/power/wake_lock lock and if
needed create a wakelock. The timeout here is specified nanoseconds.
Write "lockname" to /sys/power/wake_unlock to unlock a user wakelock.

Do not use randomly generated wakelock names as there is no api to free
a user-space wakelock.


-- 
Arve Hjønnevåg

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-01-30  1:16         ` Arve Hjønnevåg
@ 2009-01-30  3:27           ` Alan Stern
  2009-01-30  4:40             ` Arve Hjønnevåg
  2009-01-30  9:08           ` Pavel Machek
  1 sibling, 1 reply; 89+ messages in thread
From: Alan Stern @ 2009-01-30  3:27 UTC (permalink / raw)
  To: Arve Hjønnevåg; +Cc: swetland, Nigel Cunningham, linux-pm

On Thu, 29 Jan 2009, Arve Hjønnevåg wrote:

> Documentation/power/wakelocks.txt
> Wakelocks
> =========
> 
> A wakelock prevents the system from entering suspend or other low-power
> states when active.

I wish your writing was clearer.  "when active" could mean "when the 
system is active" or "when the wakelock is active".  Try to be less 
ambiguous.  For example: "When a wakelock is locked, it blocks the 
system from entering suspend or other low-power states."

> If the type is set to WAKE_LOCK_SUSPEND, the wakelock
> prevents a full system suspend. If the type is WAKE_LOCK_IDLE, low-power
> states that cause large interrupt latencies or that disable a set of
> interrupts will not be entered from idle until the wakelocks are released.

Here you talk about "will not be entered from idle", whereas above you 
mention "when active".  So which is it?  Does a wakelock affect an 
active system or an idle system?

> Wakelocks can be used to allow user-space to decide which keys should wake
> the system. The sequence of events can look like this:

> - The Keypad driver gets an interrupt. It then locks the keypad-scan wakelock
>   and starts scanning the keypad.

Is the system asleep to begin with?  If it is, how does the keypad 
driver get this interrupt unless the system first wakes up?

Conversely, what happens if the PM core has just started a system
suspend?  Does locking the wakelock force the suspend to be aborted?

> - The keypad-scan code detects a key change and reports it to the input-event
>   driver.
> - The input-event driver sees the key change, enqueues an event, and locks
>   the input-event-queue wakelock.
> - The keypad-scan code detects that no keys are held and unlocks the
>   keypad-scan wakelock.

What use is the keypad-scan wakelock?  Isn't the fact that the keypad
driver's interrupt handler is running already sufficient to prevent or
delay a system suspend?

> - The user-space input-event thread returns from select/poll, locks the
>   process-input-events wakelock and then calls read in the input-event device.
> - The input-event driver dequeues the key-event and, since the queue is now
>   empty, it unlocks the input-event-queue wakelock.

Does the input-event-queue wakelock always prevent the system from 
suspending whenever the input queue is nonempty?  Does that mean if I 
type ahead while a program is running, I can't suspend the computer 
until the program processes the keystrokes?

Does the wakelock mechanism distinguish between suspend or power-state
transitions that happen automatically and transitions requested
directly by userspace?  This would be a little more understandable if
the wakelocks only prevent the system from suspending itself and don't
prevent me from suspending the system.

> - The user-space input-event thread returns from read. It determines that the
>   key should not wake up the system, releases the process-input-events
>   wakelock and calls select or poll.

This makes no sense.  If the system wasn't asleep to begin with, how 
could the key wake it up?  And if the system _was_ asleep to begin 
with, how could all of this happen without waking the system up?

Alan Stern

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-01-30  3:27           ` Alan Stern
@ 2009-01-30  4:40             ` Arve Hjønnevåg
  2009-01-30  6:04               ` Arve Hjønnevåg
                                 ` (2 more replies)
  0 siblings, 3 replies; 89+ messages in thread
From: Arve Hjønnevåg @ 2009-01-30  4:40 UTC (permalink / raw)
  To: Alan Stern; +Cc: swetland, Nigel Cunningham, linux-pm

On Thu, Jan 29, 2009 at 7:27 PM, Alan Stern <stern@rowland.harvard.edu> wrote:
> On Thu, 29 Jan 2009, Arve Hjønnevåg wrote:
>> A wakelock prevents the system from entering suspend or other low-power
>> states when active.
>
> I wish your writing was clearer.  "when active" could mean "when the
> system is active" or "when the wakelock is active".  Try to be less
> ambiguous.  For example: "When a wakelock is locked, it blocks the
> system from entering suspend or other low-power states."

OK.

>> If the type is set to WAKE_LOCK_SUSPEND, the wakelock
>> prevents a full system suspend. If the type is WAKE_LOCK_IDLE, low-power
>> states that cause large interrupt latencies or that disable a set of
>> interrupts will not be entered from idle until the wakelocks are released.
>
> Here you talk about "will not be entered from idle", whereas above you
> mention "when active".  So which is it?  Does a wakelock affect an
> active system or an idle system?

Most of the document refers to wakelocks of type WAKE_LOCK_SUSPEND. If
create a wakelock of type WAKE_LOCK_IDLE affects the idle power state
instead.

>> - The Keypad driver gets an interrupt. It then locks the keypad-scan wakelock
>>   and starts scanning the keypad.
>
> Is the system asleep to begin with?  If it is, how does the keypad
> driver get this interrupt unless the system first wakes up?

It may have been. If it was, wake up should be for the interrupt using
the existing set_irq_wake call.

> Conversely, what happens if the PM core has just started a system
> suspend?  Does locking the wakelock force the suspend to be aborted?

Yes, assuming is has not already suspended all the drivers and
disabled interrupts.

>
>> - The keypad-scan code detects a key change and reports it to the input-event
>>   driver.
>> - The input-event driver sees the key change, enqueues an event, and locks
>>   the input-event-queue wakelock.
>> - The keypad-scan code detects that no keys are held and unlocks the
>>   keypad-scan wakelock.
>
> What use is the keypad-scan wakelock?  Isn't the fact that the keypad
> driver's interrupt handler is running already sufficient to prevent or
> delay a system suspend?

Once you hold one key down, you cannot get another interrupt if you
press another key on the same input line. The driver uses a timer to
scan the keypad matrix until all keys are released. A key on a
dedicated input with both rising and falling edge detect interrupt
would not need this wakelock.

>> - The user-space input-event thread returns from select/poll, locks the
>>   process-input-events wakelock and then calls read in the input-event device.
>> - The input-event driver dequeues the key-event and, since the queue is now
>>   empty, it unlocks the input-event-queue wakelock.
>
> Does the input-event-queue wakelock always prevent the system from
> suspending whenever the input queue is nonempty?

Yes.

> Does that mean if I
> type ahead while a program is running, I can't suspend the computer
> until the program processes the keystrokes?

The actual suspend will not happen until all the keys are processed,
but user-space can turn the screen off at any time.

> Does the wakelock mechanism distinguish between suspend or power-state
> transitions that happen automatically and transitions requested
> directly by userspace?

No.

> This would be a little more understandable if
> the wakelocks only prevent the system from suspending itself and don't
> prevent me from suspending the system.

When the user decides to suspend, we use the early-suspend api to tell
the kernel to turn of the screen and possibly some other devices.
Wakelocks are useful without early-suspend, but it must always enter
suspend when the last wakelock is unlocked.

>
>> - The user-space input-event thread returns from read. It determines that the
>>   key should not wake up the system, releases the process-input-events
>>   wakelock and calls select or poll.
>
> This makes no sense.  If the system wasn't asleep to begin with, how
> could the key wake it up?  And if the system _was_ asleep to begin
> with, how could all of this happen without waking the system up?

What I mean here is that the screen turns on and the system does not
immediately go back to sleep. The user-space framework has its own
idea of whether the system is awake or not. I can change this to
"fully wake up" or "turn on the screen".

-- 
Arve Hjønnevåg

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-01-30  4:40             ` Arve Hjønnevåg
@ 2009-01-30  6:04               ` Arve Hjønnevåg
  2009-02-02 11:49                 ` Pavel Machek
  2009-01-30  9:11               ` Pavel Machek
  2009-01-30 15:13               ` Alan Stern
  2 siblings, 1 reply; 89+ messages in thread
From: Arve Hjønnevåg @ 2009-01-30  6:04 UTC (permalink / raw)
  To: Alan Stern; +Cc: swetland, Nigel Cunningham, linux-pm

Documentation/power/wakelocks.txt (version 3)
Wakelocks
=========

A locked wakelock, depending on its type, prevents the system from entering
suspend or other low-power states. When creating a wakelock, you can select
if it prevents suspend or low-power idle states.  If the type is set to
WAKE_LOCK_SUSPEND, the wakelock prevents a full system suspend. If the type
is WAKE_LOCK_IDLE, low-power states that cause large interrupt latencies, or
that disable a set of interrupts, will not be entered from idle until the
wakelocks are released. Unless the type is specified, this document refers
to wakelocks with the type set to WAKE_LOCK_SUSPEND.

If the suspend operation has already started when locking a wakelock, it will
abort the suspend operation as long it has not already reached the suspend_late
stage. This means that locking a wakelock from an interrupt handler or a
freezeable thread always works, but if you lock a wakelock from a suspend_late
handler you must also return an error from that handler to abort suspend.

Wakelocks can be used to allow user-space to decide which keys should wake the
full system up and turn the screen on. Use set_irq_wake or a platform specific
api to make sure the keypad interrupt wakes up the cpu. Once the keypad driver
has resumed, the sequence of events can look like this:
- The Keypad driver gets an interrupt. It then locks the keypad-scan wakelock
  and starts scanning the keypad matrix.
- The keypad-scan code detects a key change and reports it to the input-event
  driver.
- The input-event driver sees the key change, enqueues an event, and locks
  the input-event-queue wakelock.
- The keypad-scan code detects that no keys are held and unlocks the
  keypad-scan wakelock.
- The user-space input-event thread returns from select/poll, locks the
  process-input-events wakelock and then calls read in the input-event device.
- The input-event driver dequeues the key-event and, since the queue is now
  empty, it unlocks the input-event-queue wakelock.
- The user-space input-event thread returns from read. It determines that the
  key should not wake up the full system, releases the process-input-events
  wakelock and calls select or poll.

                 Key pressed   Key released
                     |             |
keypad-scan          ++++++++++++++++++
input-event-queue        +++          +++
process-input-events       +++          +++


Driver API
==========

A driver can use the wakelock api by adding a wakelock variable to its state
and calling wake_lock_init. For instance:
struct state {
        struct wakelock wakelock;
}

init() {
        wake_lock_init(&state->wakelock, WAKE_LOCK_SUSPEND, "wakelockname");
}

Before freeing the memory, wake_lock_destroy must be called:

uninit() {
        wake_lock_destroy(&state->wakelock);
}

When the driver determines that it needs to run (usually in an interrupt
handler) it calls wake_lock:
        wake_lock(&state->wakelock);

When it no longer needs to run it calls wake_unlock:
        wake_unlock(&state->wakelock);

It can also call wake_lock_timeout to release the wakelock after a delay:
        wake_lock_timeout(&state->wakelock, HZ);

This works whether the wakelock is already held or not. It is useful if the
driver woke up other parts of the system that do not use wakelocks but
still need to run. Avoid this when possible, since it will waste power
if the timeout is long or may fail to finish needed work if the timeout is
short.


User-space API
==============

Write "lockname" or "lockname timeout" to /sys/power/wake_lock lock and if
needed create a wakelock. The timeout here is specified nanoseconds.
Write "lockname" to /sys/power/wake_unlock to unlock a user wakelock.

Do not use randomly generated wakelock names as there is no api to free
a user-space wakelock.



-- 
Arve Hjønnevåg

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-01-30  1:16         ` Arve Hjønnevåg
  2009-01-30  3:27           ` Alan Stern
@ 2009-01-30  9:08           ` Pavel Machek
  2009-01-30  9:25             ` Brian Swetland
  1 sibling, 1 reply; 89+ messages in thread
From: Pavel Machek @ 2009-01-30  9:08 UTC (permalink / raw)
  To: Arve Hj?nnev?g; +Cc: swetland, Nigel Cunningham, linux-pm

> On Thu, Jan 29, 2009 at 5:04 AM, Pavel Machek <pavel@ucw.cz> wrote:
> > AFAICT, this is something very different. It is attempt to do
> > autosuspend right. Imagine burning cd... right now you can suspend,
> > and it will just stop the burn.
> >
> > Wakelocks code allows you to tell the machine 'feel free to suspend
> > when you have nothing to do'... so the machine will burn the cd and
> > then suspend.
> >
> 
> Yes, wakelocks solves this problem, but our auto-suspend code is all
> in user-space so the kernel would not have to be involved in that
> particular example.
> 
> I added an example to the document that may help illustrate why we
> added wakelock support in the kernel:
> 
> ---
> Documentation/power/wakelocks.txt
> Wakelocks
> =========
> 
> A wakelock prevents the system from entering suspend or other low-power
> states when active. If the type is set to WAKE_LOCK_SUSPEND, the wakelock
> prevents a full system suspend. If the type is WAKE_LOCK_IDLE, low-power
> states that cause large interrupt latencies or that disable a set of
> interrupts will not be entered from idle until the wakelocks are released.
> 
> Wakelocks can be used to allow user-space to decide which keys should wake
> the system. The sequence of events can look like this:
> - The Keypad driver gets an interrupt. It then locks the keypad-scan wakelock
>   and starts scanning the keypad.
> - The keypad-scan code detects a key change and reports it to the input-event
>   driver.
> - The input-event driver sees the key change, enqueues an event, and locks
>   the input-event-queue wakelock.
> - The keypad-scan code detects that no keys are held and unlocks the
>   keypad-scan wakelock.
> - The user-space input-event thread returns from select/poll, locks the
>   process-input-events wakelock and then calls read in the input-event device.
> - The input-event driver dequeues the key-event and, since the queue is now
>   empty, it unlocks the input-event-queue wakelock.
> - The user-space input-event thread returns from read. It determines that the
>   key should not wake up the system, releases the process-input-events
>   wakelock and calls select or poll.

I don't get it. So you are running userspace while system is
suspended? 
								Pavel

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-01-30  4:40             ` Arve Hjønnevåg
  2009-01-30  6:04               ` Arve Hjønnevåg
@ 2009-01-30  9:11               ` Pavel Machek
  2009-01-30 12:34                 ` Uli Luckas
  2009-01-30 15:13               ` Alan Stern
  2 siblings, 1 reply; 89+ messages in thread
From: Pavel Machek @ 2009-01-30  9:11 UTC (permalink / raw)
  To: Arve Hj?nnev?g; +Cc: swetland, Nigel Cunningham, linux-pm


> >> - The user-space input-event thread returns from read. It determines that the
> >>   key should not wake up the system, releases the process-input-events
> >>   wakelock and calls select or poll.
> >
> > This makes no sense.  If the system wasn't asleep to begin with, how
> > could the key wake it up?  And if the system _was_ asleep to begin
> > with, how could all of this happen without waking the system up?
> 
> What I mean here is that the screen turns on and the system does not
> immediately go back to sleep. The user-space framework has its own
> idea of whether the system is awake or not. I can change this to
> "fully wake up" or "turn on the screen".

"turn on the screen", please. (But I still don't quite get it; screen
should be at full control of userspace, so why is kernel interaction needed?)
									Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-01-30  9:08           ` Pavel Machek
@ 2009-01-30  9:25             ` Brian Swetland
  0 siblings, 0 replies; 89+ messages in thread
From: Brian Swetland @ 2009-01-30  9:25 UTC (permalink / raw)
  To: Pavel Machek; +Cc: Nigel Cunningham, linux-pm

[Pavel Machek <pavel@ucw.cz>]
> > On Thu, Jan 29, 2009 at 5:04 AM, Pavel Machek <pavel@ucw.cz> wrote:
> > > AFAICT, this is something very different. It is attempt to do
> > > autosuspend right. Imagine burning cd... right now you can suspend,
> > > and it will just stop the burn.
> > >
> > > Wakelocks code allows you to tell the machine 'feel free to suspend
> > > when you have nothing to do'... so the machine will burn the cd and
> > > then suspend.
...
> 
> I don't get it. So you are running userspace while system is
> suspended? 

The general idea is that we aggressively try to be suspended as much as
possible.  Typically this means that when the display is turned off
(after the user inactivity timeout, managed from a userspace process),
suspend is requested.

If work is being done that requires the system to keep running, a
wakelock is held, preventing suspend from happening.

If suspend happens, but we resume due to a wakeup interrupt (for
example, user pressing a key), a wakelock is typically acquired during
the interrupt handler (which is called while we're resuming) and
arranged to be held until the event is delivered to userspace.  The
userspace code which receives events acquires a wakelock before draining
the queue (after select returns, before reading, etc) so that it keeps
the system awake until the event is processed.

In many cases the system pretty rapidly drops wakelocks and returns to
suspend state.

Brian

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-01-30  9:11               ` Pavel Machek
@ 2009-01-30 12:34                 ` Uli Luckas
  2009-02-02 11:46                   ` Pavel Machek
  0 siblings, 1 reply; 89+ messages in thread
From: Uli Luckas @ 2009-01-30 12:34 UTC (permalink / raw)
  To: linux-pm; +Cc: swetland, Nigel Cunningham

On Friday, 30. January 2009, Pavel Machek wrote:
> > >> - The user-space input-event thread returns from read. It determines
> > >> that the key should not wake up the system, releases the
> > >> process-input-events wakelock and calls select or poll.
> > >
> > > This makes no sense.  If the system wasn't asleep to begin with, how
> > > could the key wake it up?  And if the system _was_ asleep to begin
> > > with, how could all of this happen without waking the system up?
> >
> > What I mean here is that the screen turns on and the system does not
> > immediately go back to sleep. The user-space framework has its own
> > idea of whether the system is awake or not. I can change this to
> > "fully wake up" or "turn on the screen".
>
> "turn on the screen", please. (But I still don't quite get it; screen
> should be at full control of userspace, so why is kernel interaction
> needed?) Pavel
>
Turning on the screen is only on thing userspace can do. What exactly happens 
is beyon the scope of the kernel interface.
The right term is probably something like "break out of auto-suspend" or "wake 
from auto suspend".
 

-- 

------- ROAD ...the handyPC Company - - -  ) ) )

Uli Luckas
Head of Software Development

ROAD GmbH
Bennigsenstr. 14 | 12159 Berlin | Germany
fon: +49 (30) 230069 - 62 | fax: +49 (30) 230069 - 69
url: www.road.de

Amtsgericht Charlottenburg: HRB 96688 B
Managing director: Hans-Peter Constien

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 06/11] PM: Add user-space wake lock api.
  2009-01-14  1:27           ` [PATCH 06/11] PM: Add user-space wake lock api Arve Hjønnevåg
  2009-01-14  1:27             ` [PATCH 07/11] PM: wakelock: Abort task freezing if a wake lock is held Arve Hjønnevåg
@ 2009-01-30 12:43             ` Uli Luckas
  2009-01-31  0:17               ` Arve Hjønnevåg
  2009-01-31  7:24               ` Brian Swetland
  1 sibling, 2 replies; 89+ messages in thread
From: Uli Luckas @ 2009-01-30 12:43 UTC (permalink / raw)
  To: linux-pm; +Cc: swetland

On Wednesday, 14. January 2009, Arve Hjønnevåg wrote:
> This adds /sys/power/wake_lock and /sys/power/wake_unlock.
> Writing a string to wake_lock creates a wake lock the
> first time is sees a string and locks it. Optionally, the
> string can be followed by a timeout.
> To unlock the wake lock, write the same string to wake_unlock.
What happens if a process takes a lock and then dies?
Instead of using sysfs, how about using a device for this purpose which the 
caller has to keep open as long as they want to hold the lock.

Uli

-- 

------- ROAD ...the handyPC Company - - -  ) ) )

Uli Luckas
Head of Software Development

ROAD GmbH
Bennigsenstr. 14 | 12159 Berlin | Germany
fon: +49 (30) 230069 - 62 | fax: +49 (30) 230069 - 69
url: www.road.de

Amtsgericht Charlottenburg: HRB 96688 B
Managing director: Hans-Peter Constien
_______________________________________________
linux-pm mailing list
linux-pm@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/linux-pm

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-01-30  4:40             ` Arve Hjønnevåg
  2009-01-30  6:04               ` Arve Hjønnevåg
  2009-01-30  9:11               ` Pavel Machek
@ 2009-01-30 15:13               ` Alan Stern
  2009-01-31  0:02                 ` Arve Hjønnevåg
  2009-01-31  7:47                 ` Brian Swetland
  2 siblings, 2 replies; 89+ messages in thread
From: Alan Stern @ 2009-01-30 15:13 UTC (permalink / raw)
  To: Arve Hjønnevåg; +Cc: swetland, Nigel Cunningham, linux-pm

On Thu, 29 Jan 2009, Arve Hjønnevåg wrote:

> > Does the input-event-queue wakelock always prevent the system from
> > suspending whenever the input queue is nonempty?
> 
> Yes.
> 
> > Does that mean if I
> > type ahead while a program is running, I can't suspend the computer
> > until the program processes the keystrokes?
> 
> The actual suspend will not happen until all the keys are processed,
> but user-space can turn the screen off at any time.

Okay, this is slowly getting clearer.

Personally, I think we need to be able to suspend computers even when 
there are some unconsumed type-ahead characters in the input buffer.  
But that's merely an implementation detail.

> > Does the wakelock mechanism distinguish between suspend or power-state
> > transitions that happen automatically and transitions requested
> > directly by userspace?
> 
> No.

And I think this is a big mistake.  It makes sense to have locks for
blocking auto suspend, but it does not make sense to prevent the user
from putting his own computer to sleep.

For example: Suppose some program happens to hold a wakelock, perhaps 
because of a simple bug, when the user closes the laptop lid and throws 
the laptop into a backpack.  We don't want the computer to remain awake 
under those circumstances!

In fact, it would be a good idea to inform drivers (by passing a 
particular pm_message_t argument to the suspend method) whether a 
particular suspend was initiated by the user or as an auto suspend.  In 
some cases a driver might very well want to allow one while preventing 
the other.

> When the user decides to suspend, we use the early-suspend api to tell
> the kernel to turn of the screen and possibly some other devices.
> Wakelocks are useful without early-suspend, but it must always enter
> suspend when the last wakelock is unlocked.

Wakelocks and early-suspend are separate issues.  Let's consider only
wakelocks.

> >> - The user-space input-event thread returns from read. It determines that the
> >>   key should not wake up the system, releases the process-input-events
> >>   wakelock and calls select or poll.
> >
> > This makes no sense.  If the system wasn't asleep to begin with, how
> > could the key wake it up?  And if the system _was_ asleep to begin
> > with, how could all of this happen without waking the system up?
> 
> What I mean here is that the screen turns on and the system does not
> immediately go back to sleep. The user-space framework has its own
> idea of whether the system is awake or not. I can change this to
> "fully wake up" or "turn on the screen".

So what this example really shows is how wakelocks can be used to
prevent auto suspend from kicking back in the moment a keystroke is
received, before userspace has even had a chance to decide whether or
not to turn auto suspend off.  That's how you should describe it -- not
as a way of preventing keystrokes from waking the system up.

In fact, you have made the discussion very confusing by using the same
terms ("suspend", "wake up", and so) for at least three different
concepts: full system suspend, early-suspend, and this new userspace
framework's idea of suspend.  Not to mention this other notion of
turning off the screen (and perhaps a few other devices) while leaving
the system as a whole running.  In the future, please use different
words when talking about different concepts.

Alan Stern

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-01-30 15:13               ` Alan Stern
@ 2009-01-31  0:02                 ` Arve Hjønnevåg
  2009-01-31 16:19                   ` Alan Stern
  2009-01-31  7:47                 ` Brian Swetland
  1 sibling, 1 reply; 89+ messages in thread
From: Arve Hjønnevåg @ 2009-01-31  0:02 UTC (permalink / raw)
  To: Alan Stern; +Cc: swetland, Nigel Cunningham, linux-pm

On Fri, Jan 30, 2009 at 7:13 AM, Alan Stern <stern@rowland.harvard.edu> wrote:
> Personally, I think we need to be able to suspend computers even when
> there are some unconsumed type-ahead characters in the input buffer.
> But that's merely an implementation detail.

For us, the key that will turn the screen back on could be in this buffer.

>> > Does the wakelock mechanism distinguish between suspend or power-state
>> > transitions that happen automatically and transitions requested
>> > directly by userspace?
>>
>> No.
>
> And I think this is a big mistake.  It makes sense to have locks for
> blocking auto suspend, but it does not make sense to prevent the user
> from putting his own computer to sleep.

If we go to sleep while the keypad wakelock is locked, then the keypad
can no longer wake the system up. Note that this is specific to a
keypad driver that scans the keypad matrix in software. A keyboard
that generates an interrupt on every key change does not need its own
wakelock.

Also, consider the case where the user presses the power button to go
to sleep. Before this sleep request has finished a phone call comes
in. The driver gets an interrupt, enqueues the message and locks a
wakelock to make sure user-space gets a chance to process the message.
If we ignore this wakelock, the phone will either not ring at all, or
it will ring later when the device wakes up for some other reason.

There is a class of applications where we do want the behaviour you
describe, but so far all of them also require the screen to stay on.
This is handled entirely by our user-space framework which also has
other options (like keeping the keypad backlight on).

> For example: Suppose some program happens to hold a wakelock, perhaps
> because of a simple bug, when the user closes the laptop lid and throws
> the laptop into a backpack.  We don't want the computer to remain awake
> under those circumstances!

If the program hold the wakelock because of a bug we don't want the
computer on, but if it operating correctly we do. Since we don't have
a good way to detect if the program locked the wakelock because of a
bug, we assume it is correct and honor the request. We have debugging
interfaces to report how often and for how long wakelocks are locked.
We also do not allow applications to use wakelocks unless they have
the required permission.

> In fact, it would be a good idea to inform drivers (by passing a
> particular pm_message_t argument to the suspend method) whether a
> particular suspend was initiated by the user or as an auto suspend.  In
> some cases a driver might very well want to allow one while preventing
> the other.

I'm not sure this would be useful. We don't have any drivers that only
need their wakelock to prevent auto suspend. And, every pm_suspend
call is the result of unlocking the last wakelock.

>> >> - The user-space input-event thread returns from read. It determines that the
>> >>   key should not wake up the system, releases the process-input-events
>> >>   wakelock and calls select or poll.
>> >
>> > This makes no sense.  If the system wasn't asleep to begin with, how
>> > could the key wake it up?  And if the system _was_ asleep to begin
>> > with, how could all of this happen without waking the system up?
>>
>> What I mean here is that the screen turns on and the system does not
>> immediately go back to sleep. The user-space framework has its own
>> idea of whether the system is awake or not. I can change this to
>> "fully wake up" or "turn on the screen".
>
> So what this example really shows is how wakelocks can be used to
> prevent auto suspend from kicking back in the moment a keystroke is
> received, before userspace has even had a chance to decide whether or
> not to turn auto suspend off.  That's how you should describe it -- not
> as a way of preventing keystrokes from waking the system up.

I was trying to show that user-space decides which keys allow the
system to wake up. From the kernels point of view, every key causes a
wakeup, but if user-space decides that the key should not wake the
system, the system will go back to sleep as soon as possible (when all
wakelocks are unlocked).

> In fact, you have made the discussion very confusing by using the same
> terms ("suspend", "wake up", and so) for at least three different
> concepts: full system suspend, early-suspend, and this new userspace
> framework's idea of suspend.  Not to mention this other notion of
> turning off the screen (and perhaps a few other devices) while leaving
> the system as a whole running.  In the future, please use different
> words when talking about different concepts.

The user-space notion of suspend matches the early-suspend state. I
consider early-suspend another stage, not a different concept. The
difference between early-suspend and suspend is similar to the
difference between device suspend and sysdev suspend. What would you
call the the first stage of suspend that we have added?

-- 
Arve Hjønnevåg

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 06/11] PM: Add user-space wake lock api.
  2009-01-30 12:43             ` [PATCH 06/11] PM: Add user-space wake lock api Uli Luckas
@ 2009-01-31  0:17               ` Arve Hjønnevåg
  2009-01-31  7:24               ` Brian Swetland
  1 sibling, 0 replies; 89+ messages in thread
From: Arve Hjønnevåg @ 2009-01-31  0:17 UTC (permalink / raw)
  To: Uli Luckas; +Cc: swetland, linux-pm

On Fri, Jan 30, 2009 at 4:43 AM, Uli Luckas <u.luckas@road.de> wrote:
> On Wednesday, 14. January 2009, Arve Hjønnevåg wrote:
>> This adds /sys/power/wake_lock and /sys/power/wake_unlock.
>> Writing a string to wake_lock creates a wake lock the
>> first time is sees a string and locks it. Optionally, the
>> string can be followed by a timeout.
>> To unlock the wake lock, write the same string to wake_unlock.
> What happens if a process takes a lock and then dies?

The lock will be held until the process restarts and unlocks it. We
only use this interface directly from processes that are started (and
restarted) from init. Applications use the user space api which talks
to our system process. If an application dies the system process is
notified and (userspace) wakelocks are deleted.

> Instead of using sysfs, how about using a device for this purpose which the
> caller has to keep open as long as they want to hold the lock.

If you want to use wakelocks directly from applications, that makes
sense, but I'm not sure we also want to remove this interface.

-- 
Arve Hjønnevåg

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 05/11] PM: Enable early suspend through /sys/power/state
  2009-01-28 19:34           ` [PATCH 05/11] PM: Enable early suspend through /sys/power/state Pavel Machek
@ 2009-01-31  3:13             ` Arve Hjønnevåg
  2009-01-31 15:49               ` Alan Stern
  2009-02-02 11:45               ` Pavel Machek
  0 siblings, 2 replies; 89+ messages in thread
From: Arve Hjønnevåg @ 2009-01-31  3:13 UTC (permalink / raw)
  To: Pavel Machek; +Cc: swetland, linux-pm

On Wed, Jan 28, 2009 at 11:34 AM, Pavel Machek <pavel@ucw.cz> wrote:
> Hi!
>
>> If EARLYSUSPEND is enabled then writes to /sys/power/state no longer
>> blocks, and the kernel will try to enter the requested state every
>> time no wakelocks are held. Write "on" to resume normal operation.
>
> No, please don't break compatibility like this. You changed semantics
> of 'mem'...
>
> Just add another two states, for example "auto-mem" and
> "auto-standby", and make them enter mem/standby when required.
>

What would you want to happen if someone writes "mem"? If we just call
enter_state, it will fail and return an error if a wakelock is locked.
We can call request_suspend_state and then wait for another thread to
write "on", but this still requires user-space changes to work
correctly. If the goal is to allow the kernel to be compiled with
wakelock and early suspend support while preserving the old behaviour
if wakelocks are not used, then the first option is better.

-- 
Arve Hjønnevåg

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 06/11] PM: Add user-space wake lock api.
  2009-01-30 12:43             ` [PATCH 06/11] PM: Add user-space wake lock api Uli Luckas
  2009-01-31  0:17               ` Arve Hjønnevåg
@ 2009-01-31  7:24               ` Brian Swetland
  1 sibling, 0 replies; 89+ messages in thread
From: Brian Swetland @ 2009-01-31  7:24 UTC (permalink / raw)
  To: Uli Luckas; +Cc: linux-pm

[Uli Luckas <u.luckas@road.de>]
> On Wednesday, 14. January 2009, Arve Hjønnevåg wrote:
> > This adds /sys/power/wake_lock and /sys/power/wake_unlock.
> > Writing a string to wake_lock creates a wake lock the
> > first time is sees a string and locks it. Optionally, the
> > string can be followed by a timeout.
> > To unlock the wake lock, write the same string to wake_unlock.
>
> What happens if a process takes a lock and then dies?
> Instead of using sysfs, how about using a device for this purpose which the 
> caller has to keep open as long as they want to hold the lock.

On the android platform this is not a concern since only the system
server manages wakelocks directly and processes use a higher level
wakelock api in userspace that is remoted and handles this situation
(the system server knows when a process dies and can clean up).

For more general usage, the fd model does sound nicer, allowing
cleanup-on-exit, etc.  Arve -- is there a reason we went with sysfs?

Brian

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-01-30 15:13               ` Alan Stern
  2009-01-31  0:02                 ` Arve Hjønnevåg
@ 2009-01-31  7:47                 ` Brian Swetland
  2009-01-31 15:41                   ` Alan Stern
  1 sibling, 1 reply; 89+ messages in thread
From: Brian Swetland @ 2009-01-31  7:47 UTC (permalink / raw)
  To: Alan Stern; +Cc: Nigel Cunningham, linux-pm

[Alan Stern <stern@rowland.harvard.edu>]
> > > Does the wakelock mechanism distinguish between suspend or power-state
> > > transitions that happen automatically and transitions requested
> > > directly by userspace?
> > 
> > No.
> 
> And I think this is a big mistake.  It makes sense to have locks for
> blocking auto suspend, but it does not make sense to prevent the user
> from putting his own computer to sleep.
> 
> For example: Suppose some program happens to hold a wakelock, perhaps 
> because of a simple bug, when the user closes the laptop lid and throws 
> the laptop into a backpack.  We don't want the computer to remain awake 
> under those circumstances!

It depends on the particular "computer" and the problem you're solving.

Imagine the computer in question is a cellphone which is going to need
to wake up when a call comes in to do traditional cellphone things, like
ring, bring up the incall UI (so the user can answer/cancel), etc.

Or perhaps it's an always-connected data device that might get remote
messages (IM notifications, contacts/email sync, etc) over the network
while it's "asleep" that need some processing.

Bad usage of wakelocks can certainly lead to poor battery life, but
there are definitely situations where you might want to operate in a
mode where the user considers the device "asleep" but it may still wake
up to handle certain tasks.

Brian

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-01-31  7:47                 ` Brian Swetland
@ 2009-01-31 15:41                   ` Alan Stern
  2009-01-31 18:39                     ` Rafael J. Wysocki
  2009-01-31 22:41                     ` Arve Hjønnevåg
  0 siblings, 2 replies; 89+ messages in thread
From: Alan Stern @ 2009-01-31 15:41 UTC (permalink / raw)
  To: Brian Swetland; +Cc: Nigel Cunningham, linux-pm

On Fri, 30 Jan 2009, Brian Swetland wrote:

> [Alan Stern <stern@rowland.harvard.edu>]
> > > > Does the wakelock mechanism distinguish between suspend or power-state
> > > > transitions that happen automatically and transitions requested
> > > > directly by userspace?
> > > 
> > > No.
> > 
> > And I think this is a big mistake.  It makes sense to have locks for
> > blocking auto suspend, but it does not make sense to prevent the user
> > from putting his own computer to sleep.
> > 
> > For example: Suppose some program happens to hold a wakelock, perhaps 
> > because of a simple bug, when the user closes the laptop lid and throws 
> > the laptop into a backpack.  We don't want the computer to remain awake 
> > under those circumstances!
> 
> It depends on the particular "computer" and the problem you're solving.

I disagree.

> Imagine the computer in question is a cellphone which is going to need
> to wake up when a call comes in to do traditional cellphone things, like
> ring, bring up the incall UI (so the user can answer/cancel), etc.

Yes.  So what?  Nothing I said prevents the computer from waking up 
when a call comes in.  What I said was that when the user tells the 
computer to suspend (e.g., by writing "mem" to /sys/power/state), the 
computer should suspend even if some wakelocks are still locked.

> Or perhaps it's an always-connected data device that might get remote
> messages (IM notifications, contacts/email sync, etc) over the network
> while it's "asleep" that need some processing.

By "asleep", do you mean something other than suspended?  If you do 
then you have misunderstood me.  I'm talking about a true suspend -- 
that is, the suspend routines in drivers/base/power/main.c have run, 
everything is in a low-power state or turned off, and the CPU isn't 
running.

Obviously the computer can't do any processing when it is suspended.  
The only thing it can do is resume.  And a resume can be initiated by a
wide variety of signals, including such things as receipt of a network 
packet or a phone call.

> Bad usage of wakelocks can certainly lead to poor battery life, but
> there are definitely situations where you might want to operate in a
> mode where the user considers the device "asleep" but it may still wake
> up to handle certain tasks.

I don't care what the user thinks; I care about what the kernel 
actually does.  If the user wants to delude himself into thinking the 
computer is "asleep" while the kernel is still running, that's his 
problem.

Alan Stern

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 05/11] PM: Enable early suspend through /sys/power/state
  2009-01-31  3:13             ` Arve Hjønnevåg
@ 2009-01-31 15:49               ` Alan Stern
  2009-02-02 11:44                 ` Pavel Machek
  2009-02-02 11:45               ` Pavel Machek
  1 sibling, 1 reply; 89+ messages in thread
From: Alan Stern @ 2009-01-31 15:49 UTC (permalink / raw)
  To: Arve Hjønnevåg; +Cc: swetland, linux-pm

On Fri, 30 Jan 2009, Arve Hjønnevåg wrote:

> > No, please don't break compatibility like this. You changed semantics
> > of 'mem'...
> >
> > Just add another two states, for example "auto-mem" and
> > "auto-standby", and make them enter mem/standby when required.
> >
> 
> What would you want to happen if someone writes "mem"? If we just call
> enter_state, it will fail and return an error if a wakelock is locked.
> We can call request_suspend_state and then wait for another thread to
> write "on", but this still requires user-space changes to work
> correctly. If the goal is to allow the kernel to be compiled with
> wakelock and early suspend support while preserving the old behaviour
> if wakelocks are not used, then the first option is better.

This is exactly what I am complaining about in another thread.  The 
code should be written so that when the user writes "mem", the system 
goes into suspend even if some wakelocks are locked.

Alan Stern

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-01-31  0:02                 ` Arve Hjønnevåg
@ 2009-01-31 16:19                   ` Alan Stern
  2009-01-31 23:28                     ` Arve Hjønnevåg
  2009-02-02 10:42                     ` Uli Luckas
  0 siblings, 2 replies; 89+ messages in thread
From: Alan Stern @ 2009-01-31 16:19 UTC (permalink / raw)
  To: Arve Hjønnevåg; +Cc: swetland, Nigel Cunningham, linux-pm

On Fri, 30 Jan 2009, Arve Hjønnevåg wrote:

> On Fri, Jan 30, 2009 at 7:13 AM, Alan Stern <stern@rowland.harvard.edu> wrote:
> > Personally, I think we need to be able to suspend computers even when
> > there are some unconsumed type-ahead characters in the input buffer.
> > But that's merely an implementation detail.
> 
> For us, the key that will turn the screen back on could be in this buffer.

Why do you have this fixation on the screen?  Forget about the screen 
and consider the system as a whole.

If the keyboard is enabled for wakeup, then typing a key _will_ wake 
the system up from suspend -- provided the key was typed after the 
system went to sleep.  It's silly to think that a key which was typed 
before the computer was suspended should cause it to wake up.


> > And I think this is a big mistake.  It makes sense to have locks for
> > blocking auto suspend, but it does not make sense to prevent the user
> > from putting his own computer to sleep.
> 
> If we go to sleep while the keypad wakelock is locked, then the keypad
> can no longer wake the system up. Note that this is specific to a
> keypad driver that scans the keypad matrix in software. A keyboard
> that generates an interrupt on every key change does not need its own
> wakelock.

Are you sure about this?  IIRC, you said earlier that your keyboard
generates an interrupt on a key press only when no other keys are
already pressed.  Okay -- so imagine the system suspends while a key is
pressed.  Pressing another key won't generate an interrupt and hence
won't wake up the system.  But releasing all the keys and then pressing
one _will_ generate an interrupt and so will wake up the system.  I
don't see any problem with this.

> Also, consider the case where the user presses the power button to go
> to sleep. Before this sleep request has finished a phone call comes
> in. The driver gets an interrupt, enqueues the message and locks a
> wakelock to make sure user-space gets a chance to process the message.
> If we ignore this wakelock, the phone will either not ring at all, or
> it will ring later when the device wakes up for some other reason.

For situations like this, the driver can simply refuse to suspend.  You 
don't need to use a wakelock.

In fact, if you did use a wakelock the behavior would be very strange.  
The user presses the power button, an instant later a call comes in, 
the device doesn't go to sleep, the user answers the call, and as soon 
as he hangs up (perhaps 10 minutes later) the wakelock is released and 
the device immediately goes to sleep!  Not what the user would expect.

> There is a class of applications where we do want the behaviour you
> describe, but so far all of them also require the screen to stay on.

Again this fixation with the screen.  Forget about the screen!

> This is handled entirely by our user-space framework which also has
> other options (like keeping the keypad backlight on).
> 
> > For example: Suppose some program happens to hold a wakelock, perhaps
> > because of a simple bug, when the user closes the laptop lid and throws
> > the laptop into a backpack.  We don't want the computer to remain awake
> > under those circumstances!
> 
> If the program hold the wakelock because of a bug we don't want the
> computer on, but if it operating correctly we do.

_I_ don't.  I want my device to suspend itself when I tell it to.  
Nothing is more annoying than a machine that doesn't turn itself off 
when told to do so.

> Since we don't have
> a good way to detect if the program locked the wakelock because of a
> bug, we assume it is correct and honor the request. We have debugging
> interfaces to report how often and for how long wakelocks are locked.
> We also do not allow applications to use wakelocks unless they have
> the required permission.

I admit that in a properly-operating system there won't be any 
wakelocks held because of bugs.  But there might be wakelocks held for 
other reasons, and I don't want _them_ to interfere when I suspend the 
machine either.

> > In fact, it would be a good idea to inform drivers (by passing a
> > particular pm_message_t argument to the suspend method) whether a
> > particular suspend was initiated by the user or as an auto suspend.  In
> > some cases a driver might very well want to allow one while preventing
> > the other.
> 
> I'm not sure this would be useful. We don't have any drivers that only
> need their wakelock to prevent auto suspend.

Maybe you do but you don't realize it.  :-)  And even if you don't, 
maybe other people do.

> And, every pm_suspend
> call is the result of unlocking the last wakelock.

Not true.  What if all the wakelocks are already unlocked when the user 
writes "mem" to /sys/power/state?


> > So what this example really shows is how wakelocks can be used to
> > prevent auto suspend from kicking back in the moment a keystroke is
> > received, before userspace has even had a chance to decide whether or
> > not to turn auto suspend off.  That's how you should describe it -- not
> > as a way of preventing keystrokes from waking the system up.
> 
> I was trying to show that user-space decides which keys allow the
> system to wake up. From the kernels point of view, every key causes a
> wakeup, but if user-space decides that the key should not wake the
> system, the system will go back to sleep as soon as possible (when all
> wakelocks are unlocked).

This paragraph is an excellent example of the muddiness of your 
thinking.  Userspace does _not_ decide which keys allow the system to 
wake up.  _All_ keys cause the system to wake up; userspace then 
decides which ones should cause the system to go right back into 
suspend.

But you don't need wakelocks to do this.  You can get the same effect
without them, just by running a program that writes "mem" (not
"auto-mem"!) to /sys/power/state whenever it sees a keystroke it
doesn't like.  So this example does not illustrate the power of
wakelocks.

> The user-space notion of suspend matches the early-suspend state.

Then call it "early-suspend"!  Don't call it "suspend" or "the 
user-space notion of suspend".

>  I
> consider early-suspend another stage, not a different concept. The
> difference between early-suspend and suspend is similar to the
> difference between device suspend and sysdev suspend. What would you
> call the the first stage of suspend that we have added?

"Early-suspend" is an okay name.  However I have the impression that
you want to prolong the early-suspend stage, and sometimes even go back
to full power directly from early-suspend.  There's nothing wrong with 
that; just make it clear that this is what you're doing.

In fact, I get the impression that much of what you're talking about 
has to do with providing ways to short-circuit a complete suspend and 
go directly from early-suspend back to full power.

Alan Stern

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-01-31 15:41                   ` Alan Stern
@ 2009-01-31 18:39                     ` Rafael J. Wysocki
  2009-01-31 18:54                       ` Igor Stoppa
                                         ` (2 more replies)
  2009-01-31 22:41                     ` Arve Hjønnevåg
  1 sibling, 3 replies; 89+ messages in thread
From: Rafael J. Wysocki @ 2009-01-31 18:39 UTC (permalink / raw)
  To: linux-pm; +Cc: Brian Swetland, Nigel Cunningham

Sorry for being late to the party, I had more urgent things to take care of.

On Saturday 31 January 2009, Alan Stern wrote:
> On Fri, 30 Jan 2009, Brian Swetland wrote:
> 
> > [Alan Stern <stern@rowland.harvard.edu>]
> > > > > Does the wakelock mechanism distinguish between suspend or power-state
> > > > > transitions that happen automatically and transitions requested
> > > > > directly by userspace?
> > > > 
> > > > No.
> > > 
> > > And I think this is a big mistake.  It makes sense to have locks for
> > > blocking auto suspend, but it does not make sense to prevent the user
> > > from putting his own computer to sleep.
> > > 
> > > For example: Suppose some program happens to hold a wakelock, perhaps 
> > > because of a simple bug, when the user closes the laptop lid and throws 
> > > the laptop into a backpack.  We don't want the computer to remain awake 
> > > under those circumstances!
> > 
> > It depends on the particular "computer" and the problem you're solving.
> 
> I disagree.

Yeah.

However, I think that what we are used to call a sleep (or suspend) state is
really a power off state for cell phone people.  So lets define what we're
talking about.

Sleep states (suspend to RAM, hibernation) are the states of the whole system
in which no instructions are executed by the processor(s).  The difference
between a sleep state and the power off state is that in a sleep state we have
some application context saved (in memory or in a storage device) and
(in principle) after the system goes back to the working state, the
applications can continue doing do whatever they had been doing before the
system was put into the sleep state.

If instructions are executed by the processor(s), the system is in the working
state.

> > Imagine the computer in question is a cellphone which is going to need
> > to wake up when a call comes in to do traditional cellphone things, like
> > ring, bring up the incall UI (so the user can answer/cancel), etc.
> 
> Yes.  So what?  Nothing I said prevents the computer from waking up 
> when a call comes in.  What I said was that when the user tells the 
> computer to suspend (e.g., by writing "mem" to /sys/power/state), the 
> computer should suspend even if some wakelocks are still locked.

Agreed.

There should be well defined set of signals that can wake up the system
from the sleep state and the user should be able to control them.
 
> > Or perhaps it's an always-connected data device that might get remote
> > messages (IM notifications, contacts/email sync, etc) over the network
> > while it's "asleep" that need some processing.
> 
> By "asleep", do you mean something other than suspended?  If you do 
> then you have misunderstood me.  I'm talking about a true suspend -- 
> that is, the suspend routines in drivers/base/power/main.c have run, 
> everything is in a low-power state or turned off, and the CPU isn't 
> running.
> 
> Obviously the computer can't do any processing when it is suspended.  
> The only thing it can do is resume.  And a resume can be initiated by a
> wide variety of signals, including such things as receipt of a network 
> packet or a phone call.
> 
> > Bad usage of wakelocks can certainly lead to poor battery life, but
> > there are definitely situations where you might want to operate in a
> > mode where the user considers the device "asleep" but it may still wake
> > up to handle certain tasks.
> 
> I don't care what the user thinks; I care about what the kernel 
> actually does.  If the user wants to delude himself into thinking the 
> computer is "asleep" while the kernel is still running, that's his 
> problem.

Well, I think that sleep states are not really useful in cell phones.  Useful
is the ability to put all devices into low power states separately and as
needed (eg. after a period of inactivity).  IOW, the system as a whole is
in the working state, but some parts of the hardware may be in low power states
(even all of the I/O devices may be in low power states).  That may very well
look "asleep" from the user point of view, but it is not a sleep state.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-01-31 18:39                     ` Rafael J. Wysocki
@ 2009-01-31 18:54                       ` Igor Stoppa
  2009-02-01  1:04                       ` Arve Hjønnevåg
  2009-02-02 11:55                       ` Pavel Machek
  2 siblings, 0 replies; 89+ messages in thread
From: Igor Stoppa @ 2009-01-31 18:54 UTC (permalink / raw)
  To: ext Rafael J. Wysocki; +Cc: Brian Swetland, linux-pm, Nigel Cunningham

Hi,
On Sat, 2009-01-31 at 19:39 +0100, ext Rafael J. Wysocki wrote:

> Well, I think that sleep states are not really useful in cell phones.
> Useful
> is the ability to put all devices into low power states separately and
> as
> needed (eg. after a period of inactivity).  IOW, the system as a whole
> is
> in the working state, but some parts of the hardware may be in low
> power states
> (even all of the I/O devices may be in low power states).  That may
> very well
> look "asleep" from the user point of view, but it is not a sleep
> state.

yup

it's very depressing that several years after we released the Nokia 770,
in the far 2005, people are still talking about these basic concepts.

And while it can be somehow excused for what concerns the x86 world of
laptops, it's even more depressing that such discussion surfaces in
relation to Android.

-- 

Cheers, Igor

---

Igor Stoppa
Maemo Software - Nokia Devices R&D - Helsinki

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-01-31 15:41                   ` Alan Stern
  2009-01-31 18:39                     ` Rafael J. Wysocki
@ 2009-01-31 22:41                     ` Arve Hjønnevåg
  2009-01-31 23:20                       ` Rafael J. Wysocki
  1 sibling, 1 reply; 89+ messages in thread
From: Arve Hjønnevåg @ 2009-01-31 22:41 UTC (permalink / raw)
  To: Alan Stern; +Cc: Brian Swetland, Nigel Cunningham, linux-pm

On Sat, Jan 31, 2009 at 7:41 AM, Alan Stern <stern@rowland.harvard.edu> wrote:
> On Fri, 30 Jan 2009, Brian Swetland wrote:
>> Imagine the computer in question is a cellphone which is going to need
>> to wake up when a call comes in to do traditional cellphone things, like
>> ring, bring up the incall UI (so the user can answer/cancel), etc.
>
> Yes.  So what?  Nothing I said prevents the computer from waking up
> when a call comes in.  What I said was that when the user tells the
> computer to suspend (e.g., by writing "mem" to /sys/power/state), the
> computer should suspend even if some wakelocks are still locked.

But this could prevent the phone from ringing. What if the user-space
code that is responsible for playing the ringtone has been notified
that a call is coming in and starts reading the audio file with the
ringtone. At the same, the user, unaware that someone is calling,
presses the power button. If we ignore the wakelock in this situation,
the phone will not ring.

-- 
Arve Hjønnevåg

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-01-31 22:41                     ` Arve Hjønnevåg
@ 2009-01-31 23:20                       ` Rafael J. Wysocki
  2009-01-31 23:32                         ` Arve Hjønnevåg
  2009-02-02 11:56                         ` Pavel Machek
  0 siblings, 2 replies; 89+ messages in thread
From: Rafael J. Wysocki @ 2009-01-31 23:20 UTC (permalink / raw)
  To: linux-pm; +Cc: Brian Swetland, Nigel Cunningham

On Saturday 31 January 2009, Arve Hjønnevåg wrote:
> On Sat, Jan 31, 2009 at 7:41 AM, Alan Stern <stern@rowland.harvard.edu> wrote:
> > On Fri, 30 Jan 2009, Brian Swetland wrote:
> >> Imagine the computer in question is a cellphone which is going to need
> >> to wake up when a call comes in to do traditional cellphone things, like
> >> ring, bring up the incall UI (so the user can answer/cancel), etc.
> >
> > Yes.  So what?  Nothing I said prevents the computer from waking up
> > when a call comes in.  What I said was that when the user tells the
> > computer to suspend (e.g., by writing "mem" to /sys/power/state), the
> > computer should suspend even if some wakelocks are still locked.
> 
> But this could prevent the phone from ringing. What if the user-space
> code that is responsible for playing the ringtone has been notified
> that a call is coming in and starts reading the audio file with the
> ringtone. At the same, the user, unaware that someone is calling,
> presses the power button. If we ignore the wakelock in this situation,
> the phone will not ring.

What if the user decides to power off the phone and a call comes in at the
same time?

Rafael

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-01-31 16:19                   ` Alan Stern
@ 2009-01-31 23:28                     ` Arve Hjønnevåg
  2009-02-02 10:42                     ` Uli Luckas
  1 sibling, 0 replies; 89+ messages in thread
From: Arve Hjønnevåg @ 2009-01-31 23:28 UTC (permalink / raw)
  To: Alan Stern; +Cc: swetland, Nigel Cunningham, linux-pm

On Sat, Jan 31, 2009 at 8:19 AM, Alan Stern <stern@rowland.harvard.edu> wrote:
> On Fri, 30 Jan 2009, Arve Hjønnevåg wrote:
>> On Fri, Jan 30, 2009 at 7:13 AM, Alan Stern <stern@rowland.harvard.edu> wrote:
>> > Personally, I think we need to be able to suspend computers even when
>> > there are some unconsumed type-ahead characters in the input buffer.
>> > But that's merely an implementation detail.
>>
>> For us, the key that will turn the screen back on could be in this buffer.
>
> Why do you have this fixation on the screen?  Forget about the screen
> and consider the system as a whole.
>
> If the keyboard is enabled for wakeup, then typing a key _will_ wake
> the system up from suspend -- provided the key was typed after the
> system went to sleep.  It's silly to think that a key which was typed
> before the computer was suspended should cause it to wake up.

Only if you ignore the screen state. If the screen is off and the user
presses the power button, I expect it to turn on, not off.

>> If we go to sleep while the keypad wakelock is locked, then the keypad
>> can no longer wake the system up. Note that this is specific to a
>> keypad driver that scans the keypad matrix in software. A keyboard
>> that generates an interrupt on every key change does not need its own
>> wakelock.
>
> Are you sure about this?  IIRC, you said earlier that your keyboard
> generates an interrupt on a key press only when no other keys are
> already pressed.  Okay -- so imagine the system suspends while a key is
> pressed.  Pressing another key won't generate an interrupt and hence
> won't wake up the system.  But releasing all the keys and then pressing
> one _will_ generate an interrupt and so will wake up the system.  I
> don't see any problem with this.

A keypad matrix as outputs and inputs. To get an interrupt when any
key is pressed, all the output are driven and the interrupt is enabled
on the input. When you get this interrupt you turn off the interrupt
and stop driving all the outputs. Instead you drive one output, wait
for some settle time, and then read the inputs. If you go to sleep in
this state, no key will every wake the system up.

That said, if the interrupt is edge triggered, it is possible to
implement the behaviour you describe. You can pretend no keys are held
when the driver's suspend hook is called and start driving all the
output.

>> Also, consider the case where the user presses the power button to go
>> to sleep. Before this sleep request has finished a phone call comes
>> in. The driver gets an interrupt, enqueues the message and locks a
>> wakelock to make sure user-space gets a chance to process the message.
>> If we ignore this wakelock, the phone will either not ring at all, or
>> it will ring later when the device wakes up for some other reason.
>
> For situations like this, the driver can simply refuse to suspend.  You
> don't need to use a wakelock.

How is this better than using a wakelock? Is I understand you
correctly, that would mean that the user pressed the power button, and
instead of entering suspend as soon as all wakelocks are unlocked, you
don't enter suspend at all.

Also, when should the driver stop refusing suspend? As soon as it has
delivered a message to user-space? After some delay? When do you try
to enter suspend again after a driver refused a request?

> In fact, if you did use a wakelock the behavior would be very strange.
> The user presses the power button, an instant later a call comes in,
> the device doesn't go to sleep, the user answers the call, and as soon
> as he hangs up (perhaps 10 minutes later) the wakelock is released and
> the device immediately goes to sleep!  Not what the user would expect.

Normally when the user presses a key, the auto off timer in userspace
gets reset. This prevents the system from going back to sleep
immediately.

>
>> There is a class of applications where we do want the behaviour you
>> describe, but so far all of them also require the screen to stay on.
>
> Again this fixation with the screen.  Forget about the screen!
>
>> This is handled entirely by our user-space framework which also has
>> other options (like keeping the keypad backlight on).
>>
>> > For example: Suppose some program happens to hold a wakelock, perhaps
>> > because of a simple bug, when the user closes the laptop lid and throws
>> > the laptop into a backpack.  We don't want the computer to remain awake
>> > under those circumstances!
>>
>> If the program hold the wakelock because of a bug we don't want the
>> computer on, but if it operating correctly we do.
>
> _I_ don't.  I want my device to suspend itself when I tell it to.
> Nothing is more annoying than a machine that doesn't turn itself off
> when told to do so.
>
>> Since we don't have
>> a good way to detect if the program locked the wakelock because of a
>> bug, we assume it is correct and honor the request. We have debugging
>> interfaces to report how often and for how long wakelocks are locked.
>> We also do not allow applications to use wakelocks unless they have
>> the required permission.
>
> I admit that in a properly-operating system there won't be any
> wakelocks held because of bugs.  But there might be wakelocks held for
> other reasons, and I don't want _them_ to interfere when I suspend the
> machine either.

But the purpose of wakelocks is to interfere with suspend. I keep
bringing up the screen state, because it is the state that is visible
to the user on our device. If the screen is off we enter suspend
whenever possible, if the screen is on we do not.

>> And, every pm_suspend
>> call is the result of unlocking the last wakelock.
>
> Not true.  What if all the wakelocks are already unlocked when the user
> writes "mem" to /sys/power/state?

In the current implementation, early-suspend handlers are called, then
the "main" wakelock is unlocked.

>> > So what this example really shows is how wakelocks can be used to
>> > prevent auto suspend from kicking back in the moment a keystroke is
>> > received, before userspace has even had a chance to decide whether or
>> > not to turn auto suspend off.  That's how you should describe it -- not
>> > as a way of preventing keystrokes from waking the system up.
>>
>> I was trying to show that user-space decides which keys allow the
>> system to wake up. From the kernels point of view, every key causes a
>> wakeup, but if user-space decides that the key should not wake the
>> system, the system will go back to sleep as soon as possible (when all
>> wakelocks are unlocked).
>
> This paragraph is an excellent example of the muddiness of your
> thinking.  Userspace does _not_ decide which keys allow the system to
> wake up.  _All_ keys cause the system to wake up; userspace then
> decides which ones should cause the system to go right back into
> suspend.
>
> But you don't need wakelocks to do this.  You can get the same effect
> without them, just by running a program that writes "mem" (not
> "auto-mem"!) to /sys/power/state whenever it sees a keystroke it
> doesn't like.  So this example does not illustrate the power of
> wakelocks.

That would not work very well. All threads would be frozen, some
drivers suspended, the driver that knows that there are more keys in
the queue rejects suspend, and the process is reversed.

>> The user-space notion of suspend matches the early-suspend state.
>
> Then call it "early-suspend"!  Don't call it "suspend" or "the
> user-space notion of suspend".

I was trying to keep the wakelock discussion separate from the
early-suspend. Perhaps this was a mistake.

>>  I
>> consider early-suspend another stage, not a different concept. The
>> difference between early-suspend and suspend is similar to the
>> difference between device suspend and sysdev suspend. What would you
>> call the the first stage of suspend that we have added?
>
> "Early-suspend" is an okay name.  However I have the impression that
> you want to prolong the early-suspend stage, and sometimes even go back
> to full power directly from early-suspend.  There's nothing wrong with
> that; just make it clear that this is what you're doing.
>
> In fact, I get the impression that much of what you're talking about
> has to do with providing ways to short-circuit a complete suspend and
> go directly from early-suspend back to full power.

Yes we go from fully awake to early suspend and back to fully awake,
and we also go from fully suspended to early-suspend and back to fully
suspended.

-- 
Arve Hjønnevåg

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-01-31 23:20                       ` Rafael J. Wysocki
@ 2009-01-31 23:32                         ` Arve Hjønnevåg
  2009-02-01  0:18                           ` Rafael J. Wysocki
  2009-02-02 11:56                         ` Pavel Machek
  1 sibling, 1 reply; 89+ messages in thread
From: Arve Hjønnevåg @ 2009-01-31 23:32 UTC (permalink / raw)
  To: Rafael J. Wysocki; +Cc: Brian Swetland, linux-pm, Nigel Cunningham

On Sat, Jan 31, 2009 at 3:20 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> On Saturday 31 January 2009, Arve Hjønnevåg wrote:
>> But this could prevent the phone from ringing. What if the user-space
>> code that is responsible for playing the ringtone has been notified
>> that a call is coming in and starts reading the audio file with the
>> ringtone. At the same, the user, unaware that someone is calling,
>> presses the power button. If we ignore the wakelock in this situation,
>> the phone will not ring.
>
> What if the user decides to power off the phone and a call comes in at the
> same time?

If you are talking about a shutdown, not sleep, then the phone just
turns off. The phone is not expected to ring when it is turned off so
there is no point in delaying shutdown.

-- 
Arve Hjønnevåg

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-01-31 23:32                         ` Arve Hjønnevåg
@ 2009-02-01  0:18                           ` Rafael J. Wysocki
  2009-02-01  1:17                             ` Arve Hjønnevåg
  0 siblings, 1 reply; 89+ messages in thread
From: Rafael J. Wysocki @ 2009-02-01  0:18 UTC (permalink / raw)
  To: Arve Hjønnevåg; +Cc: Brian Swetland, linux-pm, Nigel Cunningham

On Sunday 01 February 2009, Arve Hjønnevåg wrote:
> On Sat, Jan 31, 2009 at 3:20 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> > On Saturday 31 January 2009, Arve Hjønnevåg wrote:
> >> But this could prevent the phone from ringing. What if the user-space
> >> code that is responsible for playing the ringtone has been notified
> >> that a call is coming in and starts reading the audio file with the
> >> ringtone. At the same, the user, unaware that someone is calling,
> >> presses the power button. If we ignore the wakelock in this situation,
> >> the phone will not ring.
> >
> > What if the user decides to power off the phone and a call comes in at the
> > same time?
> 
> If you are talking about a shutdown, not sleep, then the phone just
> turns off. The phone is not expected to ring when it is turned off so
> there is no point in delaying shutdown.

If the user forcibly puts the device into suspend, it's very much like powering
off.  The kernel shouldn't prevent that from happening unless in error
conditions.

If incoming calls are supposed to wake up the system, then there are two
possibilities:
- the already started suspend sequence may be aborted and the system may be put
  into the low power state,
- the system may be suspended and then immediately woken up.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-01-31 18:39                     ` Rafael J. Wysocki
  2009-01-31 18:54                       ` Igor Stoppa
@ 2009-02-01  1:04                       ` Arve Hjønnevåg
  2009-02-02 11:55                       ` Pavel Machek
  2 siblings, 0 replies; 89+ messages in thread
From: Arve Hjønnevåg @ 2009-02-01  1:04 UTC (permalink / raw)
  To: Rafael J. Wysocki; +Cc: Brian Swetland, linux-pm, Nigel Cunningham

On Sat, Jan 31, 2009 at 10:39 AM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> However, I think that what we are used to call a sleep (or suspend) state is
> really a power off state for cell phone people.

No, our power off state is the same as on the desktop. We do use the
power key to enter and exit sleep, but you can configure a desktop
system to do this as well.

> Sleep states (suspend to RAM, hibernation) are the states of the whole system
> in which no instructions are executed by the processor(s).  The difference
> between a sleep state and the power off state is that in a sleep state we have
> some application context saved (in memory or in a storage device) and
> (in principle) after the system goes back to the working state, the
> applications can continue doing do whatever they had been doing before the
> system was put into the sleep state.

On many arm processors there is also a big difference in what events
can take you out of the power-off state versus the sleep-state. On
some systems only the power button or the charger can turn the system
back on after power-off while a number of external and internal
interrupts can take the cpu out of the deep-sleep-state.


> Well, I think that sleep states are not really useful in cell phones.  Useful
> is the ability to put all devices into low power states separately and as
> needed (eg. after a period of inactivity).  IOW, the system as a whole is
> in the working state, but some parts of the hardware may be in low power states
> (even all of the I/O devices may be in low power states).  That may very well
> look "asleep" from the user point of view, but it is not a sleep state.

That may be true for single-core phones, but for dual core phones we
get significant power savings by doing a full suspend on the core that
runs Linux. On the system we currently have, we can enter the same
hardware state from idle as we can from suspend. But, on an idle
system with the radio is off, there are enough periodic timers to
double the average power draw. On a previous system the power draw
from idle was not even close to the power draw from suspend.

-- 
Arve Hjønnevåg

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-02-01  0:18                           ` Rafael J. Wysocki
@ 2009-02-01  1:17                             ` Arve Hjønnevåg
  2009-02-01  1:32                               ` Rafael J. Wysocki
  0 siblings, 1 reply; 89+ messages in thread
From: Arve Hjønnevåg @ 2009-02-01  1:17 UTC (permalink / raw)
  To: Rafael J. Wysocki; +Cc: Brian Swetland, linux-pm, Nigel Cunningham

On Sat, Jan 31, 2009 at 4:18 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> If the user forcibly puts the device into suspend, it's very much like powering
> off.  The kernel shouldn't prevent that from happening unless in error
> conditions.

No, when the phone is powered off, it is not expected to ring. When it
is suspended it is expected to ring.

> If incoming calls are supposed to wake up the system, then there are two
> possibilities:
> - the already started suspend sequence may be aborted and the system may be put
>  into the low power state,

I assume you mean high power state not low power state, or does low
power state mean early-suspend state. If so, locking a wakelock will
accomplish this.

> - the system may be suspended and then immediately woken up.

If you mean this as a general strategy, and not a specific outcome,
then it does not always work (for the reasons I have already stated).

-- 
Arve Hjønnevåg

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-02-01  1:17                             ` Arve Hjønnevåg
@ 2009-02-01  1:32                               ` Rafael J. Wysocki
  2009-02-01  2:14                                 ` Arve Hjønnevåg
  0 siblings, 1 reply; 89+ messages in thread
From: Rafael J. Wysocki @ 2009-02-01  1:32 UTC (permalink / raw)
  To: Arve Hjønnevåg; +Cc: Brian Swetland, linux-pm, Nigel Cunningham

On Sunday 01 February 2009, Arve Hjønnevåg wrote:
> On Sat, Jan 31, 2009 at 4:18 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> > If the user forcibly puts the device into suspend, it's very much like powering
> > off.  The kernel shouldn't prevent that from happening unless in error
> > conditions.
> 
> No, when the phone is powered off, it is not expected to ring. When it
> is suspended it is expected to ring.
> 
> > If incoming calls are supposed to wake up the system, then there are two
> > possibilities:
> > - the already started suspend sequence may be aborted and the system may be put
> >  into the low power state,
> 
> I assume you mean high power state not low power state, or does low
> power state mean early-suspend state. If so, locking a wakelock will
> accomplish this.

Actually, I meant the working state.  Aborting suspend sequence always means
go back to the working state.

Also, I think the device that detected the incoming call should abort the
suspend sequence by refusing to suspend.

> > - the system may be suspended and then immediately woken up.
> 
> If you mean this as a general strategy, and not a specific outcome,
> then it does not always work (for the reasons I have already stated).

I meant a specific outcome.

It may be impossible to abort suspend if the call comes in sufficiently
late.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-02-01  1:32                               ` Rafael J. Wysocki
@ 2009-02-01  2:14                                 ` Arve Hjønnevåg
  2009-02-01 12:30                                   ` Rafael J. Wysocki
  0 siblings, 1 reply; 89+ messages in thread
From: Arve Hjønnevåg @ 2009-02-01  2:14 UTC (permalink / raw)
  To: Rafael J. Wysocki; +Cc: Brian Swetland, linux-pm, Nigel Cunningham

On Sat, Jan 31, 2009 at 5:32 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
>> > If incoming calls are supposed to wake up the system, then there are two
>> > possibilities:
>> > - the already started suspend sequence may be aborted and the system may be put
>> >  into the low power state,
>>
>> I assume you mean high power state not low power state, or does low
>> power state mean early-suspend state. If so, locking a wakelock will
>> accomplish this.
>
> Actually, I meant the working state.  Aborting suspend sequence always means
> go back to the working state.
>
> Also, I think the device that detected the incoming call should abort the
> suspend sequence by refusing to suspend.
>
>> > - the system may be suspended and then immediately woken up.
>>
>> If you mean this as a general strategy, and not a specific outcome,
>> then it does not always work (for the reasons I have already stated).
>
> I meant a specific outcome.
>
> It may be impossible to abort suspend if the call comes in sufficiently
> late.

In that case, why are you against using wakelocks to abort the suspend
sequence? It covers the case where the driver knows that a call is
coming in, without any confusion about when the abort condition
clears. And, it avoids the overhead of freezing every process for an
operation that is doomed to fail.

-- 
Arve Hjønnevåg

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-02-01  2:14                                 ` Arve Hjønnevåg
@ 2009-02-01 12:30                                   ` Rafael J. Wysocki
  2009-02-01 14:03                                     ` Woodruff, Richard
  2009-02-01 17:43                                     ` Alan Stern
  0 siblings, 2 replies; 89+ messages in thread
From: Rafael J. Wysocki @ 2009-02-01 12:30 UTC (permalink / raw)
  To: Arve Hjønnevåg; +Cc: Brian Swetland, linux-pm, Nigel Cunningham

On Sunday 01 February 2009, Arve Hjønnevåg wrote:
> On Sat, Jan 31, 2009 at 5:32 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> >> > If incoming calls are supposed to wake up the system, then there are two
> >> > possibilities:
> >> > - the already started suspend sequence may be aborted and the system may be put
> >> >  into the low power state,
> >>
> >> I assume you mean high power state not low power state, or does low
> >> power state mean early-suspend state. If so, locking a wakelock will
> >> accomplish this.
> >
> > Actually, I meant the working state.  Aborting suspend sequence always means
> > go back to the working state.
> >
> > Also, I think the device that detected the incoming call should abort the
> > suspend sequence by refusing to suspend.
> >
> >> > - the system may be suspended and then immediately woken up.
> >>
> >> If you mean this as a general strategy, and not a specific outcome,
> >> then it does not always work (for the reasons I have already stated).
> >
> > I meant a specific outcome.
> >
> > It may be impossible to abort suspend if the call comes in sufficiently
> > late.
> 
> In that case, why are you against using wakelocks to abort the suspend
> sequence? It covers the case where the driver knows that a call is
> coming in, without any confusion about when the abort condition
> clears. And, it avoids the overhead of freezing every process for an
> operation that is doomed to fail.

I'm not really against (yet), I'm only trying to clearly understand the
benefit.

The problem pointed out by Alan is real, the user expects the system to suspend
as soon as the button is pressed and wakelocks may get in the way.

Your example is also good, but I think the problem in your example (phone
call coming in while suspending) may be resolved without wakelocks.  Moreover,
it is a general problem of a wake-up event coming in while suspending and
it requires a general solution independent of wakelocks.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-02-01 12:30                                   ` Rafael J. Wysocki
@ 2009-02-01 14:03                                     ` Woodruff, Richard
  2009-02-01 17:43                                     ` Alan Stern
  1 sibling, 0 replies; 89+ messages in thread
From: Woodruff, Richard @ 2009-02-01 14:03 UTC (permalink / raw)
  To: Rafael J. Wysocki, Arve Hjønnevåg
  Cc: Brian Swetland, linux-pm, Nigel Cunningham

> > In that case, why are you against using wakelocks to abort the suspend
> > sequence? It covers the case where the driver knows that a call is
> > coming in, without any confusion about when the abort condition
> > clears. And, it avoids the overhead of freezing every process for an
> > operation that is doomed to fail.
>
> I'm not really against (yet), I'm only trying to clearly understand the
> benefit.
>
> The problem pointed out by Alan is real, the user expects the system to
> suspend
> as soon as the button is pressed and wakelocks may get in the way.
>
> Your example is also good, but I think the problem in your example (phone
> call coming in while suspending) may be resolved without wakelocks.  Moreover,
> it is a general problem of a wake-up event coming in while suspending and
> it requires a general solution independent of wakelocks.

What is being done is automatic very aggressive use of suspend. This is not a button press by the user.  As the same end mechanism is used (plumbing and end suspend call in driver) people are worried about semantics.

At the driver level it might be viewed as a constraint frame work which allows veto of the system-auto-suspend.  It provides a short circuits of the suspend before it gets very far.

There is a summed user space input point which allows user space to have a vote.  The upper level user space coordination prior to summed kernel interface is interesting.

At the kernel level if you work really really hard and use actively timers I think cpuidle and pm_qos can get you a similar aggressive sleep. However, there are many 'bad' drivers and it's a lot easier to re-use the suspend path. Being told to sleep is something drivers know, but doing it automatically and interfaces around that is not.  For OMAP3 we fixed up all drivers make cpuidle work and also keep traditional suspend.  This has been hard but possible.

While it is possible to fix kernel space doing the same to user space can be very hard. User space is much bigger and badness there can sink all your work in the kernel. What is good about android-system-auto-suspend here is that the freezer will stop a lot of bad processes in their tracks. To stop breakages in user space you can do the preferred thing and fix the code to be smart which could be hard/impossible or raise and lower a wakelock.  The wake lock is easier by comparison.

Any corrections by android experts are welcome.

Regards,
Richard W.

BTW, yes, the screen state is very import event in system power management on a cell phone.  When it blanks you move into a time where you can be very aggressive.  At this point a lot of timers (like user activity) and the like are expired.  You can do things which were not valid before as they would disrupt user experience.  Embedded people will use this as a critical point of reference as it's a pivot point.

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-02-01 12:30                                   ` Rafael J. Wysocki
  2009-02-01 14:03                                     ` Woodruff, Richard
@ 2009-02-01 17:43                                     ` Alan Stern
  2009-02-01 19:27                                       ` Woodruff, Richard
  2009-02-02 11:00                                       ` Uli Luckas
  1 sibling, 2 replies; 89+ messages in thread
From: Alan Stern @ 2009-02-01 17:43 UTC (permalink / raw)
  To: Rafael J. Wysocki; +Cc: Brian Swetland, Nigel Cunningham, linux-pm

On Sun, 1 Feb 2009, Rafael J. Wysocki wrote:

> > In that case, why are you against using wakelocks to abort the suspend
> > sequence? It covers the case where the driver knows that a call is
> > coming in, without any confusion about when the abort condition
> > clears. And, it avoids the overhead of freezing every process for an
> > operation that is doomed to fail.
> 
> I'm not really against (yet), I'm only trying to clearly understand the
> benefit.
> 
> The problem pointed out by Alan is real, the user expects the system to suspend
> as soon as the button is pressed and wakelocks may get in the way.
> 
> Your example is also good, but I think the problem in your example (phone
> call coming in while suspending) may be resolved without wakelocks.  Moreover,
> it is a general problem of a wake-up event coming in while suspending and
> it requires a general solution independent of wakelocks.

I'm beginning to get the impression that we're really talking about two 
different kinds of suspend here.  They can be described as 
"high-priority suspend" and "low-priority suspend".

A high-priority suspend occurs when userspace writes "mem" to 
/sys/power/state.  It should override wakelock settings and put the 
system to sleep as soon as possible (subject to abort by drivers, of 
course, but they better have a pretty good reason for aborting).

A low-priority suspend is what Arve has been talking about; it occurs
when the user pushes the phone's "power" button or the auto-suspend
mechanism activates.  It is subject to blocking by wakelocks, and there
should also be a way (although I don't recall seeing it described) to
cancel a low-priority suspend request while it is waiting for a
wakelock to be released.

The idea behind these low-priority suspends is that there are certain 
activities which should be atomic with respect to suspends, that is, 
the system should not normally be allowed to suspend while the activity 
is taking place.  These are things that last longer than a single 
interrupt handler.  Examples we have seen include waiting for all key 
presses to be released (because the keypad can't be enabled for wakeup 
if any keys are pressed) or waiting for a userspace process to finish 
playing a ring tone.

If a high-priority suspend occurs while some keys are pressed, the
keypad driver has a few possible courses of action: abort the suspend,
re-enable the interrupt circuitry, or disable keypad wakeups.  I'm not
sure which would be best; the issue probably won't arise much.  
Similarly, a high-priority suspend while a ring tone is being played
should cause the system to go to sleep right in the middle of playing.

Normally we would expect that on a desktop or laptop, the only source
of low-priority suspend requests would be the auto-suspend code.  On a
phone or other embedded device, we would not expect to see any
high-priority suspend requests under normal circumstances.  But of 
course there could always be exceptions, if someone wanted them.


Early-suspend seems to be a completely different matter.  In fact it 
isn't a suspend state at all, as far as I understand it.  It's more 
like what you get simply by doing a runtime suspend on some collection 
of devices.  I don't see that the kernel needs to treat it as a special 
state, and in might be possible to have a user program manage the whole 
thing -- provided the drivers in question implement runtime power 
management (as USB has done).

Alan Stern

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-02-01 17:43                                     ` Alan Stern
@ 2009-02-01 19:27                                       ` Woodruff, Richard
  2009-02-02 11:00                                       ` Uli Luckas
  1 sibling, 0 replies; 89+ messages in thread
From: Woodruff, Richard @ 2009-02-01 19:27 UTC (permalink / raw)
  To: Alan Stern, Rafael J. Wysocki; +Cc: Brian Swetland, Nigel Cunningham, linux-pm

> Early-suspend seems to be a completely different matter.  In fact it
> isn't a suspend state at all, as far as I understand it.  It's more
> like what you get simply by doing a runtime suspend on some collection
> of devices.  I don't see that the kernel needs to treat it as a special
> state, and in might be possible to have a user program manage the whole
> thing -- provided the drivers in question implement runtime power
> management (as USB has done).

The bit of use I saw was a few devices were broken out from the global suspend chain (display and some input).  They were effetely controlled from user space activity timers. The 'early_suspend' was sequenced before the global suspend call. Effectively this created a partial idle state where some drivers were down and others up. Also, the drivers on early_suspend might resume with out a global suspend. They also were not registered on global chain.

The upside of this from my point of view was the drivers on early suspend chain were high latency drivers. If they were linked into the global suspend chain they would drive up cost of frequent suspend substantially (a 60Hz or slower LCD DMA re-sync on both directions is costly, more so for some slow SPI-GPS kind of device). One example might be some periodic task wakes up to check the battery level then re-sleeps. On the resume side you don't want to restart the display system to do this. Since it is on a separate early-suspend-chain it doesn't wake until a later re-activated user space issues the wake if it needs to be.

Personally I still like an on-demand architecture for kernel space where drivers are coming up and down independently per control and data flow.  But this is harder. Splitting suspend seems to be an ok tradeoff for this problem.  Anyway, they don't conflict, you just use fewer or no kernel wake locks.  The user space ones are still around to help control the wild west up there.

This kind of system suspend seems good for power optimization at the user input speed time scale (hundreds of mS). It probably is too heavy to get really good power for constant active mode power like an mp3. At the current time scale the best you could hope for is DVFS with this. Doing DPS (dynamic-power-switching) to shut down individual blocks during playback, this seems like it would be to slow unless you had groups of independent 'early_suspend' device chains.

A mix of cpuidle + wakelock-aggressive-system-suspend should provide decent coverage for power states.

Again, I'll defer to android experts.

Regards,
Richard W.

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-01-31 16:19                   ` Alan Stern
  2009-01-31 23:28                     ` Arve Hjønnevåg
@ 2009-02-02 10:42                     ` Uli Luckas
  2009-02-02 15:05                       ` Alan Stern
  1 sibling, 1 reply; 89+ messages in thread
From: Uli Luckas @ 2009-02-02 10:42 UTC (permalink / raw)
  To: linux-pm; +Cc: swetland, Nigel Cunningham


[-- Attachment #1.1: Type: text/plain, Size: 2369 bytes --]

On Saturday, 31. January 2009, Alan Stern wrote:
> > Also, consider the case where the user presses the power button to go
> > to sleep. Before this sleep request has finished a phone call comes
> > in. The driver gets an interrupt, enqueues the message and locks a
> > wakelock to make sure user-space gets a chance to process the message.
> > If we ignore this wakelock, the phone will either not ring at all, or
> > it will ring later when the device wakes up for some other reason.
>
> For situations like this, the driver can simply refuse to suspend.  You
> don't need to use a wakelock.
>
> In fact, if you did use a wakelock the behavior would be very strange.  
> The user presses the power button, an instant later a call comes in,
> the device doesn't go to sleep, the user answers the call, and as soon
> as he hangs up (perhaps 10 minutes later) the wakelock is released and
> the device immediately goes to sleep!  Not what the user would expect.
Hi Alan,
we have had a (userspace) wake-lock implementation on our handyPC devices for 
a couple of years now. So maybe I can shed some light.

The above quote underlines pretty well, where Arve's and your ideas of 
eraly-suspend and wake-locks diverge. And why you are missunderstanding each 
other.
Arve is always talking about "blanking the screen" because that's what the 
users sees. From the user's perspective the device is "suspended" as soon as 
his user interfaces vanishes. That's probably also why his notions 
of "suspend" and "wake" are not alway following a strict definition. 
If the device stays blanked while the user has his 10 min phone conversation, 
then he won't even notice wether the device suspends or not after the call. 
This is the idea. The user does not care for anything they can't see.

Arve is not talking about a laptop that needs to sleep befor it's ventilation 
slot are covered. He is talking about a phone that could well do with only 
blanking it's screen. Except it want's to save battery when ever possible.


Uli

-- 

------- ROAD ...the handyPC Company - - -  ) ) )

Uli Luckas
Head of Software Development

ROAD GmbH
Bennigsenstr. 14 | 12159 Berlin | Germany
fon: +49 (30) 230069 - 62 | fax: +49 (30) 230069 - 69
url: www.road.de

Amtsgericht Charlottenburg: HRB 96688 B
Managing director: Hans-Peter Constien

[-- Attachment #1.2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-02-01 17:43                                     ` Alan Stern
  2009-02-01 19:27                                       ` Woodruff, Richard
@ 2009-02-02 11:00                                       ` Uli Luckas
  2009-02-02 15:09                                         ` Alan Stern
  1 sibling, 1 reply; 89+ messages in thread
From: Uli Luckas @ 2009-02-02 11:00 UTC (permalink / raw)
  To: linux-pm; +Cc: Brian Swetland, Nigel Cunningham

On Sunday, 1. February 2009, Alan Stern wrote:
> Early-suspend seems to be a completely different matter.  In fact it
> isn't a suspend state at all, as far as I understand it.  It's more
> like what you get simply by doing a runtime suspend on some collection
> of devices.  I don't see that the kernel needs to treat it as a special
> state, and in might be possible to have a user program manage the whole
> thing -- provided the drivers in question implement runtime power
> management (as USB has done).
>
> Alan Stern

Except you always want early-suspend and auto-suspend at the same time. The 
idea is, if all display of system states is off (early-suspend), we can 
enable or disable the cpu at will (auto-suspend) because nobody will notice. 

Uli


-- 

------- ROAD ...the handyPC Company - - -  ) ) )

Uli Luckas
Head of Software Development

ROAD GmbH
Bennigsenstr. 14 | 12159 Berlin | Germany
fon: +49 (30) 230069 - 62 | fax: +49 (30) 230069 - 69
url: www.road.de

Amtsgericht Charlottenburg: HRB 96688 B
Managing director: Hans-Peter Constien

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 05/11] PM: Enable early suspend through /sys/power/state
  2009-01-31 15:49               ` Alan Stern
@ 2009-02-02 11:44                 ` Pavel Machek
  0 siblings, 0 replies; 89+ messages in thread
From: Pavel Machek @ 2009-02-02 11:44 UTC (permalink / raw)
  To: Alan Stern; +Cc: swetland, linux-pm

On Sat 2009-01-31 10:49:16, Alan Stern wrote:
> On Fri, 30 Jan 2009, Arve Hj?nnev?g wrote:
> 
> > > No, please don't break compatibility like this. You changed semantics
> > > of 'mem'...
> > >
> > > Just add another two states, for example "auto-mem" and
> > > "auto-standby", and make them enter mem/standby when required.
> > >
> > 
> > What would you want to happen if someone writes "mem"? If we just call
> > enter_state, it will fail and return an error if a wakelock is locked.
> > We can call request_suspend_state and then wait for another thread to
> > write "on", but this still requires user-space changes to work
> > correctly. If the goal is to allow the kernel to be compiled with
> > wakelock and early suspend support while preserving the old behaviour
> > if wakelocks are not used, then the first option is better.
> 
> This is exactly what I am complaining about in another thread.  The 
> code should be written so that when the user writes "mem", the system 
> goes into suspend even if some wakelocks are locked.

Yes please.
									Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 05/11] PM: Enable early suspend through /sys/power/state
  2009-01-31  3:13             ` Arve Hjønnevåg
  2009-01-31 15:49               ` Alan Stern
@ 2009-02-02 11:45               ` Pavel Machek
  2009-02-02 22:36                 ` Arve Hjønnevåg
  1 sibling, 1 reply; 89+ messages in thread
From: Pavel Machek @ 2009-02-02 11:45 UTC (permalink / raw)
  To: Arve Hj?nnev?g; +Cc: swetland, linux-pm

On Fri 2009-01-30 19:13:32, Arve Hj?nnev?g wrote:
> On Wed, Jan 28, 2009 at 11:34 AM, Pavel Machek <pavel@ucw.cz> wrote:
> > Hi!
> >
> >> If EARLYSUSPEND is enabled then writes to /sys/power/state no longer
> >> blocks, and the kernel will try to enter the requested state every
> >> time no wakelocks are held. Write "on" to resume normal operation.
> >
> > No, please don't break compatibility like this. You changed semantics
> > of 'mem'...
> >
> > Just add another two states, for example "auto-mem" and
> > "auto-standby", and make them enter mem/standby when required.
> >
> 
> What would you want to happen if someone writes "mem"? If we just call
> enter_state, it will fail and return an error if a wakelock is
> locked.

That would be fine. And ignoring wakelocks in this case would be even better.

> We can call request_suspend_state and then wait for another thread to
> write "on", but this still requires user-space changes to work
> correctly. If the goal is to allow the kernel to be compiled with
> wakelock and early suspend support while preserving the old behaviour
> if wakelocks are not used, then the first option is better.

Yes, goal is that compiling in  wakelock / early suspend support has
no effect on existing functionality.
									Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-01-30 12:34                 ` Uli Luckas
@ 2009-02-02 11:46                   ` Pavel Machek
  0 siblings, 0 replies; 89+ messages in thread
From: Pavel Machek @ 2009-02-02 11:46 UTC (permalink / raw)
  To: Uli Luckas; +Cc: swetland, linux-pm, Nigel Cunningham

On Fri 2009-01-30 13:34:02, Uli Luckas wrote:
> On Friday, 30. January 2009, Pavel Machek wrote:
> > > >> - The user-space input-event thread returns from read. It determines
> > > >> that the key should not wake up the system, releases the
> > > >> process-input-events wakelock and calls select or poll.
> > > >
> > > > This makes no sense.  If the system wasn't asleep to begin with, how
> > > > could the key wake it up?  And if the system _was_ asleep to begin
> > > > with, how could all of this happen without waking the system up?
> > >
> > > What I mean here is that the screen turns on and the system does not
> > > immediately go back to sleep. The user-space framework has its own
> > > idea of whether the system is awake or not. I can change this to
> > > "fully wake up" or "turn on the screen".
> >
> > "turn on the screen", please. (But I still don't quite get it; screen
> > should be at full control of userspace, so why is kernel interaction
> > needed?) Pavel
> >
> Turning on the screen is only on thing userspace can do. What exactly happens 
> is beyon the scope of the kernel interface.
> The right term is probably something like "break out of auto-suspend" or "wake 
> from auto suspend".

I guess I'm missing big parts of the picture here. It would be nice to
document how it all works together... somewhere.
									Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-01-30  6:04               ` Arve Hjønnevåg
@ 2009-02-02 11:49                 ` Pavel Machek
  0 siblings, 0 replies; 89+ messages in thread
From: Pavel Machek @ 2009-02-02 11:49 UTC (permalink / raw)
  To: Arve Hj?nnev?g; +Cc: swetland, Nigel Cunningham, linux-pm

Hi!

> User-space API
> ==============
> 
> Write "lockname" or "lockname timeout" to /sys/power/wake_lock lock and if
> needed create a wakelock. The timeout here is specified nanoseconds.
> Write "lockname" to /sys/power/wake_unlock to unlock a user wakelock.
> 
> Do not use randomly generated wakelock names as there is no api to free
> a user-space wakelock.

Do you have some examples of user wakelocks?

The API is quite ugly; creating objects by writing to file.

If userspace does not want system to suspend, could it simply write
"on" to /sys/power/state ?
									Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-01-31 18:39                     ` Rafael J. Wysocki
  2009-01-31 18:54                       ` Igor Stoppa
  2009-02-01  1:04                       ` Arve Hjønnevåg
@ 2009-02-02 11:55                       ` Pavel Machek
  2 siblings, 0 replies; 89+ messages in thread
From: Pavel Machek @ 2009-02-02 11:55 UTC (permalink / raw)
  To: Rafael J. Wysocki; +Cc: Brian Swetland, linux-pm, Nigel Cunningham

Hi!

> However, I think that what we are used to call a sleep (or suspend) state is
> really a power off state for cell phone people.  So lets define what we're
> talking about.
> 
> Sleep states (suspend to RAM, hibernation) are the states of the whole system
> in which no instructions are executed by the processor(s).  The
> difference

s/processor(s)/CPU/.

Even in PC, you have keyboard controller running while sleeping. On
cellphone, you have some kind of pmu chip + GSM chip running. So
cellphone actually _is_ useful even when CPU is sleeping.

> between a sleep state and the power off state is that in a sleep state we have
> some application context saved (in memory or in a storage device) and
> (in principle) after the system goes back to the working state, the
> applications can continue doing do whatever they had been doing before the
> system was put into the sleep state.
> 
> If instructions are executed by the processor(s), the system is in the working
> state.

ACK.

> Well, I think that sleep states are not really useful in cell phones.  Useful
> is the ability to put all devices into low power states separately and as
> needed (eg. after a period of inactivity).  IOW, the system as a
> whole is

No, it does not work like that. Cellphone with sleeping CPU
(suspended-to-RAM) is still very useful.
									Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-01-31 23:20                       ` Rafael J. Wysocki
  2009-01-31 23:32                         ` Arve Hjønnevåg
@ 2009-02-02 11:56                         ` Pavel Machek
  2009-02-02 12:38                           ` Uli Luckas
  1 sibling, 1 reply; 89+ messages in thread
From: Pavel Machek @ 2009-02-02 11:56 UTC (permalink / raw)
  To: Rafael J. Wysocki; +Cc: Brian Swetland, linux-pm, Nigel Cunningham

On Sun 2009-02-01 00:20:04, Rafael J. Wysocki wrote:
> On Saturday 31 January 2009, Arve Hj?nnev?g wrote:
> > On Sat, Jan 31, 2009 at 7:41 AM, Alan Stern <stern@rowland.harvard.edu> wrote:
> > > On Fri, 30 Jan 2009, Brian Swetland wrote:
> > >> Imagine the computer in question is a cellphone which is going to need
> > >> to wake up when a call comes in to do traditional cellphone things, like
> > >> ring, bring up the incall UI (so the user can answer/cancel), etc.
> > >
> > > Yes.  So what?  Nothing I said prevents the computer from waking up
> > > when a call comes in.  What I said was that when the user tells the
> > > computer to suspend (e.g., by writing "mem" to /sys/power/state), the
> > > computer should suspend even if some wakelocks are still locked.
> > 
> > But this could prevent the phone from ringing. What if the user-space
> > code that is responsible for playing the ringtone has been notified
> > that a call is coming in and starts reading the audio file with the
> > ringtone. At the same, the user, unaware that someone is calling,
> > presses the power button. If we ignore the wakelock in this situation,
> > the phone will not ring.

Yes, you don't want to write "mem" to /sys/power/state on android. You
want to write something like "auto-mem" there.

> What if the user decides to power off the phone and a call comes in at the
> same time?

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-02-02 11:56                         ` Pavel Machek
@ 2009-02-02 12:38                           ` Uli Luckas
  0 siblings, 0 replies; 89+ messages in thread
From: Uli Luckas @ 2009-02-02 12:38 UTC (permalink / raw)
  To: linux-pm; +Cc: Brian Swetland, Nigel Cunningham

On Monday, 2. February 2009, Pavel Machek wrote:
> On Sun 2009-02-01 00:20:04, Rafael J. Wysocki wrote:
> > On Saturday 31 January 2009, Arve Hj?nnev?g wrote:
> > > On Sat, Jan 31, 2009 at 7:41 AM, Alan Stern <stern@rowland.harvard.edu> 
wrote:
> > > > On Fri, 30 Jan 2009, Brian Swetland wrote:
> > > >> Imagine the computer in question is a cellphone which is going to
> > > >> need to wake up when a call comes in to do traditional cellphone
> > > >> things, like ring, bring up the incall UI (so the user can
> > > >> answer/cancel), etc.
> > > >
> > > > Yes.  So what?  Nothing I said prevents the computer from waking up
> > > > when a call comes in.  What I said was that when the user tells the
> > > > computer to suspend (e.g., by writing "mem" to /sys/power/state), the
> > > > computer should suspend even if some wakelocks are still locked.
> > >
> > > But this could prevent the phone from ringing. What if the user-space
> > > code that is responsible for playing the ringtone has been notified
> > > that a call is coming in and starts reading the audio file with the
> > > ringtone. At the same, the user, unaware that someone is calling,
> > > presses the power button. If we ignore the wakelock in this situation,
> > > the phone will not ring.
>
> Yes, you don't want to write "mem" to /sys/power/state on android. You
> want to write something like "auto-mem" there.
>
ACK.
Don't change the way "mem" works. Just don't use it if it does the wrong thing 
on android.

Uli


-- 

------- ROAD ...the handyPC Company - - -  ) ) )

Uli Luckas
Head of Software Development

ROAD GmbH
Bennigsenstr. 14 | 12159 Berlin | Germany
fon: +49 (30) 230069 - 62 | fax: +49 (30) 230069 - 69
url: www.road.de

Amtsgericht Charlottenburg: HRB 96688 B
Managing director: Hans-Peter Constien

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-02-02 10:42                     ` Uli Luckas
@ 2009-02-02 15:05                       ` Alan Stern
  2009-02-02 16:15                         ` Uli Luckas
  0 siblings, 1 reply; 89+ messages in thread
From: Alan Stern @ 2009-02-02 15:05 UTC (permalink / raw)
  To: Uli Luckas; +Cc: swetland, linux-pm, Nigel Cunningham

On Mon, 2 Feb 2009, Uli Luckas wrote:

> Hi Alan,
> we have had a (userspace) wake-lock implementation on our handyPC devices for 
> a couple of years now. So maybe I can shed some light.
> 
> The above quote underlines pretty well, where Arve's and your ideas of 
> eraly-suspend and wake-locks diverge. And why you are missunderstanding each 
> other.
> Arve is always talking about "blanking the screen" because that's what the 
> users sees. From the user's perspective the device is "suspended" as soon as 
> his user interfaces vanishes. That's probably also why his notions 
> of "suspend" and "wake" are not alway following a strict definition. 

And that's partly why I have been complaining about the things he 
writes.  To a kernel programmer, "suspend" has a very specific meaning, 
quite different from what it might mean to a user.  When Arve posts on 
a kernel-oriented mailing list, he should use such words in a way his 
readers will understand.

> If the device stays blanked while the user has his 10 min phone conversation, 
> then he won't even notice wether the device suspends or not after the call. 
> This is the idea. The user does not care for anything they can't see.
> 
> Arve is not talking about a laptop that needs to sleep befor it's ventilation 
> slot are covered. He is talking about a phone that could well do with only 
> blanking it's screen. Except it want's to save battery when ever possible.

The problem is that he's talking about making changes to a kernel that 
will be installed in all sorts of machines, from phones all the way up 
to supercomputers.  When you do this, you have to broaden your point of 
view -- your code has to run correctly in all of these settings.

Alan Stern

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-02-02 11:00                                       ` Uli Luckas
@ 2009-02-02 15:09                                         ` Alan Stern
  2009-02-02 16:24                                           ` Uli Luckas
                                                             ` (2 more replies)
  0 siblings, 3 replies; 89+ messages in thread
From: Alan Stern @ 2009-02-02 15:09 UTC (permalink / raw)
  To: Uli Luckas; +Cc: Brian Swetland, linux-pm, Nigel Cunningham

On Mon, 2 Feb 2009, Uli Luckas wrote:

> On Sunday, 1. February 2009, Alan Stern wrote:
> > Early-suspend seems to be a completely different matter.  In fact it
> > isn't a suspend state at all, as far as I understand it.  It's more
> > like what you get simply by doing a runtime suspend on some collection
> > of devices.  I don't see that the kernel needs to treat it as a special
> > state, and in might be possible to have a user program manage the whole
> > thing -- provided the drivers in question implement runtime power
> > management (as USB has done).
> >
> > Alan Stern
> 
> Except you always want early-suspend and auto-suspend at the same time. The 
> idea is, if all display of system states is off (early-suspend), we can 
> enable or disable the cpu at will (auto-suspend) because nobody will notice. 

Why should the kernel have to get involved?  Why can't userspace manage 
both early-suspend and auto-suspend?

That is, consider the following: Userspace initiates an early-suspend
by using a runtime PM interface to turn off the screen and some other
devices.  After a short time, if they are still off, then userspace can
initiate an auto-suspend by writing "auto-mem" to /sys/power/state.

All the kernel would need to know is the difference between
auto-suspend and normal suspend: one respects wakelocks and the other
doesn't.

Alan Stern

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-02-02 15:05                       ` Alan Stern
@ 2009-02-02 16:15                         ` Uli Luckas
  2009-02-02 16:35                           ` Alan Stern
  2009-02-03 20:15                           ` Pavel Machek
  0 siblings, 2 replies; 89+ messages in thread
From: Uli Luckas @ 2009-02-02 16:15 UTC (permalink / raw)
  To: Alan Stern; +Cc: swetland, linux-pm, Nigel Cunningham

On Monday, 2. February 2009, Alan Stern wrote:
> On Mon, 2 Feb 2009, Uli Luckas wrote:
> > Hi Alan,
> > we have had a (userspace) wake-lock implementation on our handyPC devices
> > for a couple of years now. So maybe I can shed some light.
> >
> > The above quote underlines pretty well, where Arve's and your ideas of
> > eraly-suspend and wake-locks diverge. And why you are missunderstanding
> > each other.
> > Arve is always talking about "blanking the screen" because that's what
> > the users sees. From the user's perspective the device is "suspended" as
> > soon as his user interfaces vanishes. That's probably also why his
> > notions of "suspend" and "wake" are not alway following a strict
> > definition.
>
> And that's partly why I have been complaining about the things he
> writes.  To a kernel programmer, "suspend" has a very specific meaning,
> quite different from what it might mean to a user.  When Arve posts on
> a kernel-oriented mailing list, he should use such words in a way his
> readers will understand.
>
Full Ack

> > If the device stays blanked while the user has his 10 min phone
> > conversation, then he won't even notice wether the device suspends or not
> > after the call. This is the idea. The user does not care for anything
> > they can't see.
> >
> > Arve is not talking about a laptop that needs to sleep befor it's
> > ventilation slot are covered. He is talking about a phone that could well
> > do with only blanking it's screen. Except it want's to save battery when
> > ever possible.
>
> The problem is that he's talking about making changes to a kernel that
> will be installed in all sorts of machines, from phones all the way up
> to supercomputers.  When you do this, you have to broaden your point of
> view -- your code has to run correctly in all of these settings.
>
Well, it should not interfere with any of these settings. And I think it is 
understood by now that we has to take back the semantic change of "echo mem 
> /sys/power/state"

On the other hand, I think it is quite reasonable to have aditional suspend 
mechanisms on a phone then you have on a super computer. Obviously you don't 
want the supercomputer to suspend everytime nobody is watching :-)

Uli


-- 

------- ROAD ...the handyPC Company - - -  ) ) )

Uli Luckas
Head of Software Development

ROAD GmbH
Bennigsenstr. 14 | 12159 Berlin | Germany
fon: +49 (30) 230069 - 62 | fax: +49 (30) 230069 - 69
url: www.road.de

Amtsgericht Charlottenburg: HRB 96688 B
Managing director: Hans-Peter Constien

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-02-02 15:09                                         ` Alan Stern
@ 2009-02-02 16:24                                           ` Uli Luckas
  2009-02-02 21:47                                           ` Nigel Cunningham
  2009-02-02 23:10                                           ` Arve Hjønnevåg
  2 siblings, 0 replies; 89+ messages in thread
From: Uli Luckas @ 2009-02-02 16:24 UTC (permalink / raw)
  To: linux-pm; +Cc: Brian Swetland, Nigel Cunningham

On Monday, 2. February 2009, Alan Stern wrote:
> On Mon, 2 Feb 2009, Uli Luckas wrote:
> > On Sunday, 1. February 2009, Alan Stern wrote:
> > > Early-suspend seems to be a completely different matter.  In fact it
> > > isn't a suspend state at all, as far as I understand it.  It's more
> > > like what you get simply by doing a runtime suspend on some collection
> > > of devices.  I don't see that the kernel needs to treat it as a special
> > > state, and in might be possible to have a user program manage the whole
> > > thing -- provided the drivers in question implement runtime power
> > > management (as USB has done).
> > >
> > > Alan Stern
> >
> > Except you always want early-suspend and auto-suspend at the same time.
> > The idea is, if all display of system states is off (early-suspend), we
> > can enable or disable the cpu at will (auto-suspend) because nobody will
> > notice.
>
> Why should the kernel have to get involved?  Why can't userspace manage
> both early-suspend and auto-suspend?
>
> That is, consider the following: Userspace initiates an early-suspend
> by using a runtime PM interface to turn off the screen and some other
> devices.  After a short time, if they are still off, then userspace can
> initiate an auto-suspend by writing "auto-mem" to /sys/power/state.
>
> All the kernel would need to know is the difference between
> auto-suspend and normal suspend: one respects wakelocks and the other
> doesn't.
>
Actually i don't know. Arve?
Things would get a lot less complex if we could leave the early suspend stuff 
out of the kernel.

Uli

-- 

------- ROAD ...the handyPC Company - - -  ) ) )

Uli Luckas
Head of Software Development

ROAD GmbH
Bennigsenstr. 14 | 12159 Berlin | Germany
fon: +49 (30) 230069 - 62 | fax: +49 (30) 230069 - 69
url: www.road.de

Amtsgericht Charlottenburg: HRB 96688 B
Managing director: Hans-Peter Constien

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-02-02 16:15                         ` Uli Luckas
@ 2009-02-02 16:35                           ` Alan Stern
  2009-02-03 20:15                           ` Pavel Machek
  1 sibling, 0 replies; 89+ messages in thread
From: Alan Stern @ 2009-02-02 16:35 UTC (permalink / raw)
  To: Uli Luckas; +Cc: swetland, linux-pm, Nigel Cunningham

On Mon, 2 Feb 2009, Uli Luckas wrote:

> Well, it should not interfere with any of these settings. And I think it is 
> understood by now that we has to take back the semantic change of "echo mem 
> > /sys/power/state"
> 
> On the other hand, I think it is quite reasonable to have aditional suspend 
> mechanisms on a phone then you have on a super computer. Obviously you don't 
> want the supercomputer to suspend everytime nobody is watching :-)

Agreed.

Alan Stern

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-02-02 15:09                                         ` Alan Stern
  2009-02-02 16:24                                           ` Uli Luckas
@ 2009-02-02 21:47                                           ` Nigel Cunningham
  2009-02-02 23:21                                             ` Arve Hjønnevåg
  2009-02-02 23:10                                           ` Arve Hjønnevåg
  2 siblings, 1 reply; 89+ messages in thread
From: Nigel Cunningham @ 2009-02-02 21:47 UTC (permalink / raw)
  To: Alan Stern; +Cc: Brian Swetland, linux-pm, Uli Luckas

Hi.

On Mon, 2009-02-02 at 10:09 -0500, Alan Stern wrote:
> On Mon, 2 Feb 2009, Uli Luckas wrote:
> 
> > On Sunday, 1. February 2009, Alan Stern wrote:
> > > Early-suspend seems to be a completely different matter.  In fact it
> > > isn't a suspend state at all, as far as I understand it.  It's more
> > > like what you get simply by doing a runtime suspend on some collection
> > > of devices.  I don't see that the kernel needs to treat it as a special
> > > state, and in might be possible to have a user program manage the whole
> > > thing -- provided the drivers in question implement runtime power
> > > management (as USB has done).
> > >
> > > Alan Stern
> > 
> > Except you always want early-suspend and auto-suspend at the same time. The 
> > idea is, if all display of system states is off (early-suspend), we can 
> > enable or disable the cpu at will (auto-suspend) because nobody will notice. 
> 
> Why should the kernel have to get involved?  Why can't userspace manage 
> both early-suspend and auto-suspend?
> 
> That is, consider the following: Userspace initiates an early-suspend
> by using a runtime PM interface to turn off the screen and some other
> devices.  After a short time, if they are still off, then userspace can
> initiate an auto-suspend by writing "auto-mem" to /sys/power/state.
> 
> All the kernel would need to know is the difference between
> auto-suspend and normal suspend: one respects wakelocks and the other
> doesn't.

It sounds to me like all of this stuff is just power management of
individual devices, which should be done through the sysfs interface and
completely unrelated to /sys/power/state. I'm putting the talk about
suspending the CPU in this box too because it sounds like the desire is
to stop the CPU without necessarily suspending other devices such as
transmitters - sort of a CPU freq state where the frequency is 0.

That said, if suspend to ram is what they really want for 'auto-mem',
what you're suggesting sounds good to me.

Regards,

Nigel

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 05/11] PM: Enable early suspend through /sys/power/state
  2009-02-02 11:45               ` Pavel Machek
@ 2009-02-02 22:36                 ` Arve Hjønnevåg
  0 siblings, 0 replies; 89+ messages in thread
From: Arve Hjønnevåg @ 2009-02-02 22:36 UTC (permalink / raw)
  To: Pavel Machek; +Cc: swetland, linux-pm

On Mon, Feb 2, 2009 at 3:45 AM, Pavel Machek <pavel@ucw.cz> wrote:
> Yes, goal is that compiling in  wakelock / early suspend support has
> no effect on existing functionality.

OK. I think I'll just print a warning and disable wakelock support if
user-space writes to /sys/power/state when wakelock support is
compiled in. A wakelock aware power manager in user-space can use an
always non-blocking interface (e.g. /sys/power/request_state) instead.

-- 
Arve Hjønnevåg

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-02-02 15:09                                         ` Alan Stern
  2009-02-02 16:24                                           ` Uli Luckas
  2009-02-02 21:47                                           ` Nigel Cunningham
@ 2009-02-02 23:10                                           ` Arve Hjønnevåg
  2009-02-03  3:27                                             ` Alan Stern
  2 siblings, 1 reply; 89+ messages in thread
From: Arve Hjønnevåg @ 2009-02-02 23:10 UTC (permalink / raw)
  To: Alan Stern; +Cc: Brian Swetland, linux-pm, Uli Luckas, Nigel Cunningham

On Mon, Feb 2, 2009 at 7:09 AM, Alan Stern <stern@rowland.harvard.edu> wrote:
> On Mon, 2 Feb 2009, Uli Luckas wrote:
>> Except you always want early-suspend and auto-suspend at the same time. The
>> idea is, if all display of system states is off (early-suspend), we can
>> enable or disable the cpu at will (auto-suspend) because nobody will notice.
>
> Why should the kernel have to get involved?  Why can't userspace manage
> both early-suspend and auto-suspend?

The kernel does not need to be involved in early-suspend. We use
early-suspend as a simple way to shut down the framebuffer and some
input devices.
If by auto-suspend you mean suspend after user inactivity (usually
after a number of seconds or minutes), then the kernel does not need
to be involved, but if you mean suspending when all wakelocks are
unlocked, the kernel needs to be involved to avoid delays. If the last
wakelock to be unlocked is a kernel wakelock, then user-space would
not know that it needs to re-attempt suspend.

> That is, consider the following: Userspace initiates an early-suspend
> by using a runtime PM interface to turn off the screen and some other
> devices.  After a short time, if they are still off, then userspace can
> initiate an auto-suspend by writing "auto-mem" to /sys/power/state.

Why do you want a delay?
Also, what do you mean by a runtime PM interface?

> All the kernel would need to know is the difference between
> auto-suspend and normal suspend: one respects wakelocks and the other
> doesn't.

If by normal suspend you mean what is supported in the kernel now,
then OK. We can support existing userspace code by ignoring wakelocks.
My intention was that you only enable the WAKELOCK config option when
using it, but I agree that it is better to allow the kernel to be
built with support for both modes.

What do you think should happen if user-space tries to use both interfaces?

-- 
Arve Hjønnevåg

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-02-02 21:47                                           ` Nigel Cunningham
@ 2009-02-02 23:21                                             ` Arve Hjønnevåg
  2009-02-02 23:51                                               ` Nigel Cunningham
  2009-02-04 13:25                                               ` Pavel Machek
  0 siblings, 2 replies; 89+ messages in thread
From: Arve Hjønnevåg @ 2009-02-02 23:21 UTC (permalink / raw)
  To: Nigel Cunningham; +Cc: Brian Swetland, linux-pm, Uli Luckas

On Mon, Feb 2, 2009 at 1:47 PM, Nigel Cunningham
<ncunningham@crca.org.au> wrote:
> It sounds to me like all of this stuff is just power management of
> individual devices, which should be done through the sysfs interface and
> completely unrelated to /sys/power/state.

It is easier for us to add a hook to the individual drivers than to
maintain a list of devices in user-space. Also, last time I checked,
the only way to disable individual devices was through a deprecated
interface. Is there a new way to do this?

> I'm putting the talk about
> suspending the CPU in this box too because it sounds like the desire is
> to stop the CPU without necessarily suspending other devices such as
> transmitters - sort of a CPU freq state where the frequency is 0.

Is this different from idle?

> That said, if suspend to ram is what they really want for 'auto-mem',
> what you're suggesting sounds good to me.

Suspend gives us two advantages over idle. All threads are frozen
which means that an app that is using too much cpu time no longer
drains the battery. And, the monotonic clock stops.

-- 
Arve Hjønnevåg

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-02-02 23:21                                             ` Arve Hjønnevåg
@ 2009-02-02 23:51                                               ` Nigel Cunningham
  2009-02-03  0:08                                                 ` Arve Hjønnevåg
  2009-02-04 13:25                                               ` Pavel Machek
  1 sibling, 1 reply; 89+ messages in thread
From: Nigel Cunningham @ 2009-02-02 23:51 UTC (permalink / raw)
  To: Arve Hjønnevåg; +Cc: Brian Swetland, linux-pm, Uli Luckas

Hi.

On Mon, 2009-02-02 at 15:21 -0800, Arve Hjønnevåg wrote:
> On Mon, Feb 2, 2009 at 1:47 PM, Nigel Cunningham
> <ncunningham@crca.org.au> wrote:
> > It sounds to me like all of this stuff is just power management of
> > individual devices, which should be done through the sysfs interface and
> > completely unrelated to /sys/power/state.
> 
> It is easier for us to add a hook to the individual drivers than to
> maintain a list of devices in user-space. Also, last time I checked,
> the only way to disable individual devices was through a deprecated
> interface. Is there a new way to do this?

Not as far as I know, but I understood that we weren't focusing on what
currently exists, but on what ought to exist to properly support what
you're after, in a generic enough way to be useful to others as well.

> > I'm putting the talk about
> > suspending the CPU in this box too because it sounds like the desire is
> > to stop the CPU without necessarily suspending other devices such as
> > transmitters - sort of a CPU freq state where the frequency is 0.
> 
> Is this different from idle?

Well, I'm imagining a state that is more than just idle - where, as you
say, processes don't run until some sort of wakeup event occurs.

> > That said, if suspend to ram is what they really want for 'auto-mem',
> > what you're suggesting sounds good to me.
> 
> Suspend gives us two advantages over idle. All threads are frozen
> which means that an app that is using too much cpu time no longer
> drains the battery. And, the monotonic clock stops.

Do you want to leave any devices on while in this state? If not, okay -
suspend to ram sounds right. If yes, I think you want to take
leave /sys/power/disk alone and go along the lines of run-time power
management instead.

Regards,

Nigel

_______________________________________________
linux-pm mailing list
linux-pm@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/linux-pm

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-02-02 23:51                                               ` Nigel Cunningham
@ 2009-02-03  0:08                                                 ` Arve Hjønnevåg
  0 siblings, 0 replies; 89+ messages in thread
From: Arve Hjønnevåg @ 2009-02-03  0:08 UTC (permalink / raw)
  To: Nigel Cunningham; +Cc: Brian Swetland, linux-pm, Uli Luckas

On Mon, Feb 2, 2009 at 3:51 PM, Nigel Cunningham
<ncunningham@crca.org.au> wrote:
>> It is easier for us to add a hook to the individual drivers than to
>> maintain a list of devices in user-space. Also, last time I checked,
>> the only way to disable individual devices was through a deprecated
>> interface. Is there a new way to do this?
>
> Not as far as I know, but I understood that we weren't focusing on what
> currently exists, but on what ought to exist to properly support what
> you're after, in a generic enough way to be useful to others as well.

Early-suspend was easier to add to the kernel, and easier for us to
use from user-space.

> Well, I'm imagining a state that is more than just idle - where, as you
> say, processes don't run until some sort of wakeup event occurs.

You are describing suspend.

>> Suspend gives us two advantages over idle. All threads are frozen
>> which means that an app that is using too much cpu time no longer
>> drains the battery. And, the monotonic clock stops.
>
> Do you want to leave any devices on while in this state? If not, okay -
> suspend to ram sounds right. If yes, I think you want to take
> leave /sys/power/disk alone and go along the lines of run-time power
> management instead.

I don't think leaving a device on should prevent us from using
suspend. Wakeup from suspend is already supported. If wakeup is
enabled for a device, it needs to be in a power state that can support
wakeup (whether this is its lowest power state or not).

-- 
Arve Hjønnevåg

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-02-02 23:10                                           ` Arve Hjønnevåg
@ 2009-02-03  3:27                                             ` Alan Stern
  2009-02-03  4:18                                               ` Arve Hjønnevåg
  0 siblings, 1 reply; 89+ messages in thread
From: Alan Stern @ 2009-02-03  3:27 UTC (permalink / raw)
  To: Arve Hjønnevåg
  Cc: Brian Swetland, linux-pm, Uli Luckas, Nigel Cunningham

On Mon, 2 Feb 2009, Arve Hjønnevåg wrote:

> On Mon, Feb 2, 2009 at 7:09 AM, Alan Stern <stern@rowland.harvard.edu> wrote:
> > On Mon, 2 Feb 2009, Uli Luckas wrote:
> >> Except you always want early-suspend and auto-suspend at the same time. The
> >> idea is, if all display of system states is off (early-suspend), we can
> >> enable or disable the cpu at will (auto-suspend) because nobody will notice.
> >
> > Why should the kernel have to get involved?  Why can't userspace manage
> > both early-suspend and auto-suspend?
> 
> The kernel does not need to be involved in early-suspend. We use
> early-suspend as a simple way to shut down the framebuffer and some
> input devices.
> If by auto-suspend you mean suspend after user inactivity (usually
> after a number of seconds or minutes), then the kernel does not need
> to be involved, but if you mean suspending when all wakelocks are
> unlocked, the kernel needs to be involved to avoid delays. If the last
> wakelock to be unlocked is a kernel wakelock, then user-space would
> not know that it needs to re-attempt suspend.

I meant both: suspending after user inactivity when all wakelocks are 
unlocked.

If you'd like a way for the kernel to communicate to userspace that the
last wakelock has been unlocked, you could use a signal or a select.
But the simplest way would be to make a process block on reading a
sysfs file until the last wakelock is released.

> > That is, consider the following: Userspace initiates an early-suspend
> > by using a runtime PM interface to turn off the screen and some other
> > devices.  After a short time, if they are still off, then userspace can
> > initiate an auto-suspend by writing "auto-mem" to /sys/power/state.
> 
> Why do you want a delay?

I thought you wanted one.  If you don't then okay, don't use a delay.

> Also, what do you mean by a runtime PM interface?

I'm making a distinction between system PM and runtime (also known as 
dynamic) PM.  With system PM the entire system goes into a low-power 
state -- that's what we mean when we talk about suspend or hibernation.  
With runtime PM the system as a whole remains running while selected 
devices are individually put into a low-power state.

For example, right now Linux will put a USB host controller into a
low-power state if no USB devices are plugged into it.  This runtime PM
interface is described in Documentation/usb/power-management.txt.  You
might want to use some of those mechanisms for controlling your
devices.

> > All the kernel would need to know is the difference between
> > auto-suspend and normal suspend: one respects wakelocks and the other
> > doesn't.
> 
> If by normal suspend you mean what is supported in the kernel now,
> then OK. We can support existing userspace code by ignoring wakelocks.
> My intention was that you only enable the WAKELOCK config option when
> using it, but I agree that it is better to allow the kernel to be
> built with support for both modes.
> 
> What do you think should happen if user-space tries to use both interfaces?

For example, if one process tries to start an auto-suspend, and at the 
same time another process writes "mem" to /sys/power/state?  Then the 
second process should take precedence and the system should go into 
suspend.  When it wakes up again, the first process would still be 
waiting for an auto-suspend to occur.  I suppose the details don't 
matter much because it's not likely to crop up often.

Alan Stern

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-02-03  3:27                                             ` Alan Stern
@ 2009-02-03  4:18                                               ` Arve Hjønnevåg
  2009-02-03 20:30                                                 ` Alan Stern
  2009-02-04 13:29                                                 ` Pavel Machek
  0 siblings, 2 replies; 89+ messages in thread
From: Arve Hjønnevåg @ 2009-02-03  4:18 UTC (permalink / raw)
  To: Alan Stern; +Cc: Brian Swetland, linux-pm, Uli Luckas, Nigel Cunningham

On Mon, Feb 2, 2009 at 7:27 PM, Alan Stern <stern@rowland.harvard.edu> wrote:
> If you'd like a way for the kernel to communicate to userspace that the
> last wakelock has been unlocked, you could use a signal or a select.
> But the simplest way would be to make a process block on reading a
> sysfs file until the last wakelock is released.

I do not want the kernel to communicate to userspace that the last
wakelock has been unlocked, I want it to suspend right away. I was
answering your question about why the kernel needs to be involved. Yes
I could add a notification that tells user-space to suspend again, but
it would not offer any additional functionality over my current
solution.

>> Also, what do you mean by a runtime PM interface?
>
> I'm making a distinction between system PM and runtime (also known as
> dynamic) PM.  With system PM the entire system goes into a low-power
> state -- that's what we mean when we talk about suspend or hibernation.
> With runtime PM the system as a whole remains running while selected
> devices are individually put into a low-power state.
>
> For example, right now Linux will put a USB host controller into a
> low-power state if no USB devices are plugged into it.  This runtime PM
> interface is described in Documentation/usb/power-management.txt.  You
> might want to use some of those mechanisms for controlling your
> devices.

OK, but I don't think this affects our use of wakelocks.

> For example, if one process tries to start an auto-suspend, and at the
> same time another process writes "mem" to /sys/power/state?  Then the
> second process should take precedence and the system should go into
> suspend.  When it wakes up again, the first process would still be
> waiting for an auto-suspend to occur.  I suppose the details don't
> matter much because it's not likely to crop up often.

I'll make a change to make any write to /sys/power/state disable
wakelocks. I'll probably also add a config option to remove
/sys/power/state.

Before I post another patch series I have a few questions:
- Should I merge the wakelock and early-suspend api patches with their
implementations? (I initially implemented the api on top of the old
android_power driver, but we not longer use this)
- Once wakelocks are disabled by writing to /sys/power/state, is there
any demand for re-enabling wakelock support?
- Are there any objections to using /sys/power/request_state to
specify the state to enter when all wakelocks unlocked.

-- 
Arve Hjønnevåg

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-02-02 16:15                         ` Uli Luckas
  2009-02-02 16:35                           ` Alan Stern
@ 2009-02-03 20:15                           ` Pavel Machek
  1 sibling, 0 replies; 89+ messages in thread
From: Pavel Machek @ 2009-02-03 20:15 UTC (permalink / raw)
  To: Uli Luckas; +Cc: swetland, linux-pm, Nigel Cunningham


> > The problem is that he's talking about making changes to a kernel that
> > will be installed in all sorts of machines, from phones all the way up
> > to supercomputers.  When you do this, you have to broaden your point of
> > view -- your code has to run correctly in all of these settings.
> >
> Well, it should not interfere with any of these settings. And I think it is 
> understood by now that we has to take back the semantic change of "echo mem 
> > /sys/power/state"
> 
> On the other hand, I think it is quite reasonable to have aditional suspend 
> mechanisms on a phone then you have on a super computer. Obviously you don't 
> want the supercomputer to suspend everytime nobody is watching :-)

Actually you'd like your supercomputer to turn on wake-on-lan then
sleep when noone is watching (and there are no pending jobs). 'green
datacenter' is popular buzzword ;-).

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-02-03  4:18                                               ` Arve Hjønnevåg
@ 2009-02-03 20:30                                                 ` Alan Stern
  2009-02-04 13:29                                                 ` Pavel Machek
  1 sibling, 0 replies; 89+ messages in thread
From: Alan Stern @ 2009-02-03 20:30 UTC (permalink / raw)
  To: Arve Hjønnevåg
  Cc: Brian Swetland, linux-pm, Uli Luckas, Nigel Cunningham

On Mon, 2 Feb 2009, Arve Hjønnevåg wrote:

> >> Also, what do you mean by a runtime PM interface?
> >
> > I'm making a distinction between system PM and runtime (also known as
> > dynamic) PM.  With system PM the entire system goes into a low-power
> > state -- that's what we mean when we talk about suspend or hibernation.
> > With runtime PM the system as a whole remains running while selected
> > devices are individually put into a low-power state.
> >
> > For example, right now Linux will put a USB host controller into a
> > low-power state if no USB devices are plugged into it.  This runtime PM
> > interface is described in Documentation/usb/power-management.txt.  You
> > might want to use some of those mechanisms for controlling your
> > devices.
> 
> OK, but I don't think this affects our use of wakelocks.

No, but it might very well affect your implementation of early-suspend.

> I'll make a change to make any write to /sys/power/state disable
> wakelocks. I'll probably also add a config option to remove
> /sys/power/state.
> 
> Before I post another patch series I have a few questions:
> - Should I merge the wakelock and early-suspend api patches with their
> implementations? (I initially implemented the api on top of the old
> android_power driver, but we not longer use this)

It depends how big the patches are.  If they're not too large, go ahead 
and merge the API patch with the implementation.  But if they're 
difficult to read because they are rather big, keep them separate.

> - Once wakelocks are disabled by writing to /sys/power/state, is there
> any demand for re-enabling wakelock support?

I don't know.  You might as well re-enable it as soon as the system 
resumes.

> - Are there any objections to using /sys/power/request_state to
> specify the state to enter when all wakelocks unlocked.

Okay with me.

Alan Stern

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-02-02 23:21                                             ` Arve Hjønnevåg
  2009-02-02 23:51                                               ` Nigel Cunningham
@ 2009-02-04 13:25                                               ` Pavel Machek
  1 sibling, 0 replies; 89+ messages in thread
From: Pavel Machek @ 2009-02-04 13:25 UTC (permalink / raw)
  To: Arve Hj?nnev?g; +Cc: Brian Swetland, Nigel Cunningham, Uli Luckas, linux-pm

Hi!

> <ncunningham@crca.org.au> wrote:
> > It sounds to me like all of this stuff is just power management of
> > individual devices, which should be done through the sysfs interface and
> > completely unrelated to /sys/power/state.
> 
> It is easier for us to add a hook to the individual drivers than to
> maintain a list of devices in user-space. Also, last time I checked,
> the only way to disable individual devices was through a deprecated
> interface. Is there a new way to do this?

No, but we need one, sooner or later. I'd say that implementing nice
device power management would be better than early-suspend hack.

> > That said, if suspend to ram is what they really want for 'auto-mem',
> > what you're suggesting sounds good to me.
> 
> Suspend gives us two advantages over idle. All threads are frozen
> which means that an app that is using too much cpu time no longer
> drains the battery. And, the monotonic clock stops.

SIGSTOP should be the right tool if some application uses too much
cycles...


-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-02-03  4:18                                               ` Arve Hjønnevåg
  2009-02-03 20:30                                                 ` Alan Stern
@ 2009-02-04 13:29                                                 ` Pavel Machek
  1 sibling, 0 replies; 89+ messages in thread
From: Pavel Machek @ 2009-02-04 13:29 UTC (permalink / raw)
  To: Arve Hj?nnev?g; +Cc: Brian Swetland, linux-pm, Uli Luckas, Nigel Cunningham


> > For example, if one process tries to start an auto-suspend, and at the
> > same time another process writes "mem" to /sys/power/state?  Then the
> > second process should take precedence and the system should go into
> > suspend.  When it wakes up again, the first process would still be
> > waiting for an auto-suspend to occur.  I suppose the details don't
> > matter much because it's not likely to crop up often.
> 
> I'll make a change to make any write to /sys/power/state disable
> wakelocks. I'll probably also add a config option to remove
> /sys/power/state.
> 
> Before I post another patch series I have a few questions:
> - Should I merge the wakelock and early-suspend api patches with their
> implementations? (I initially implemented the api on top of the old
> android_power driver, but we not longer use this)

I think so.

> - Once wakelocks are disabled by writing to /sys/power/state, is there
> any demand for re-enabling wakelock support?

I do not think wakelocks should be disabled. They should probably be
ignored for echo mem > state, but disabling them sounds wrong.

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [RFC][PATCH 00/11] Android PM extensions
  2009-02-05  2:50 Arve Hjønnevåg
@ 2009-02-06 23:51 ` Rafael J. Wysocki
  0 siblings, 0 replies; 89+ messages in thread
From: Rafael J. Wysocki @ 2009-02-06 23:51 UTC (permalink / raw)
  To: Arve Hjønnevåg; +Cc: ncunningham, u.luckas, swetland, linux-pm

On Thursday 05 February 2009, Arve Hjønnevåg wrote:
> The following patch series adds two apis, wakelock and earlysuspend.
> The Android platform uses the earlysuspend api to turn the screen
> and some input devices on and off. The wakelock code determines when
> to enter the full suspend state. 
> 
> These apis could also be useful to other platforms where the goal is
> to enter full suspend whenever possible.
> 
> This is the second version posted to linux-pm. The main change from the first
> version is that it no longer reuses /sys/power/state for the non-blocking
> interface.

Unfortunately, I haven't had the time to review the patches in detail yet.

I'll do that as soon as I can.

Thanks,
Rafael
_______________________________________________
linux-pm mailing list
linux-pm@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/linux-pm

^ permalink raw reply	[flat|nested] 89+ messages in thread

* [RFC][PATCH 00/11] Android PM extensions
@ 2009-02-05  2:50 Arve Hjønnevåg
  2009-02-06 23:51 ` Rafael J. Wysocki
  0 siblings, 1 reply; 89+ messages in thread
From: Arve Hjønnevåg @ 2009-02-05  2:50 UTC (permalink / raw)
  To: linux-pm; +Cc: ncunningham, u.luckas, swetland

The following patch series adds two apis, wakelock and earlysuspend.
The Android platform uses the earlysuspend api to turn the screen
and some input devices on and off. The wakelock code determines when
to enter the full suspend state. 

These apis could also be useful to other platforms where the goal is
to enter full suspend whenever possible.

This is the second version posted to linux-pm. The main change from the first
version is that it no longer reuses /sys/power/state for the non-blocking
interface.

--
Arve Hjønnevåg

_______________________________________________
linux-pm mailing list
linux-pm@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/linux-pm

^ permalink raw reply	[flat|nested] 89+ messages in thread

end of thread, other threads:[~2009-02-06 23:51 UTC | newest]

Thread overview: 89+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-01-14  1:27 [RFC][PATCH 00/11] Android PM extensions Arve Hjønnevåg
2009-01-14  1:27 ` [PATCH 01/11] PM: Add wake lock api Arve Hjønnevåg
2009-01-14  1:27   ` [PATCH 02/11] PM: Add early suspend api Arve Hjønnevåg
2009-01-14  1:27     ` [PATCH 03/11] PM: Implement wakelock api Arve Hjønnevåg
2009-01-14  1:27       ` [PATCH 04/11] PM: Implement early suspend api Arve Hjønnevåg
2009-01-14  1:27         ` [PATCH 05/11] PM: Enable early suspend through /sys/power/state Arve Hjønnevåg
2009-01-14  1:27           ` [PATCH 06/11] PM: Add user-space wake lock api Arve Hjønnevåg
2009-01-14  1:27             ` [PATCH 07/11] PM: wakelock: Abort task freezing if a wake lock is held Arve Hjønnevåg
2009-01-14  1:27               ` [PATCH 08/11] PM: earlysuspend: Add console switch when user requested sleep state changes Arve Hjønnevåg
2009-01-14  1:27                 ` [PATCH 09/11] PM: earlysuspend: Removing dependence on console Arve Hjønnevåg
2009-01-14  1:27                   ` [PATCH 10/11] Input: Hold wake lock while event queue is not empty Arve Hjønnevåg
2009-01-14  1:27                     ` [PATCH 11/11] ledtrig-sleep: Add led trigger for sleep debugging Arve Hjønnevåg
2009-01-30 12:43             ` [PATCH 06/11] PM: Add user-space wake lock api Uli Luckas
2009-01-31  0:17               ` Arve Hjønnevåg
2009-01-31  7:24               ` Brian Swetland
2009-01-28 19:34           ` [PATCH 05/11] PM: Enable early suspend through /sys/power/state Pavel Machek
2009-01-31  3:13             ` Arve Hjønnevåg
2009-01-31 15:49               ` Alan Stern
2009-02-02 11:44                 ` Pavel Machek
2009-02-02 11:45               ` Pavel Machek
2009-02-02 22:36                 ` Arve Hjønnevåg
2009-01-14  9:48         ` [PATCH 04/11] PM: Implement early suspend api Nigel Cunningham
2009-01-14 23:57           ` Arve Hjønnevåg
2009-01-14  9:30       ` [PATCH 03/11] PM: Implement wakelock api Nigel Cunningham
2009-01-14 23:28         ` Arve Hjønnevåg
2009-01-14  9:17     ` [PATCH 02/11] PM: Add early suspend api Nigel Cunningham
2009-01-14 23:18       ` Arve Hjønnevåg
2009-01-14  9:09   ` [PATCH 01/11] PM: Add wake lock api Nigel Cunningham
2009-01-14 23:07     ` Arve Hjønnevåg
2009-01-14  9:01 ` [RFC][PATCH 00/11] Android PM extensions Nigel Cunningham
2009-01-15  0:10   ` Arve Hjønnevåg
2009-01-15  4:42   ` Arve Hjønnevåg
2009-01-15 15:08     ` Alan Stern
2009-01-15 20:34       ` Arve Hjønnevåg
2009-01-29 13:04       ` Pavel Machek
2009-01-30  1:16         ` Arve Hjønnevåg
2009-01-30  3:27           ` Alan Stern
2009-01-30  4:40             ` Arve Hjønnevåg
2009-01-30  6:04               ` Arve Hjønnevåg
2009-02-02 11:49                 ` Pavel Machek
2009-01-30  9:11               ` Pavel Machek
2009-01-30 12:34                 ` Uli Luckas
2009-02-02 11:46                   ` Pavel Machek
2009-01-30 15:13               ` Alan Stern
2009-01-31  0:02                 ` Arve Hjønnevåg
2009-01-31 16:19                   ` Alan Stern
2009-01-31 23:28                     ` Arve Hjønnevåg
2009-02-02 10:42                     ` Uli Luckas
2009-02-02 15:05                       ` Alan Stern
2009-02-02 16:15                         ` Uli Luckas
2009-02-02 16:35                           ` Alan Stern
2009-02-03 20:15                           ` Pavel Machek
2009-01-31  7:47                 ` Brian Swetland
2009-01-31 15:41                   ` Alan Stern
2009-01-31 18:39                     ` Rafael J. Wysocki
2009-01-31 18:54                       ` Igor Stoppa
2009-02-01  1:04                       ` Arve Hjønnevåg
2009-02-02 11:55                       ` Pavel Machek
2009-01-31 22:41                     ` Arve Hjønnevåg
2009-01-31 23:20                       ` Rafael J. Wysocki
2009-01-31 23:32                         ` Arve Hjønnevåg
2009-02-01  0:18                           ` Rafael J. Wysocki
2009-02-01  1:17                             ` Arve Hjønnevåg
2009-02-01  1:32                               ` Rafael J. Wysocki
2009-02-01  2:14                                 ` Arve Hjønnevåg
2009-02-01 12:30                                   ` Rafael J. Wysocki
2009-02-01 14:03                                     ` Woodruff, Richard
2009-02-01 17:43                                     ` Alan Stern
2009-02-01 19:27                                       ` Woodruff, Richard
2009-02-02 11:00                                       ` Uli Luckas
2009-02-02 15:09                                         ` Alan Stern
2009-02-02 16:24                                           ` Uli Luckas
2009-02-02 21:47                                           ` Nigel Cunningham
2009-02-02 23:21                                             ` Arve Hjønnevåg
2009-02-02 23:51                                               ` Nigel Cunningham
2009-02-03  0:08                                                 ` Arve Hjønnevåg
2009-02-04 13:25                                               ` Pavel Machek
2009-02-02 23:10                                           ` Arve Hjønnevåg
2009-02-03  3:27                                             ` Alan Stern
2009-02-03  4:18                                               ` Arve Hjønnevåg
2009-02-03 20:30                                                 ` Alan Stern
2009-02-04 13:29                                                 ` Pavel Machek
2009-02-02 11:56                         ` Pavel Machek
2009-02-02 12:38                           ` Uli Luckas
2009-01-30  9:08           ` Pavel Machek
2009-01-30  9:25             ` Brian Swetland
2009-01-28 19:31 ` Pavel Machek
2009-02-05  2:50 Arve Hjønnevåg
2009-02-06 23:51 ` Rafael J. Wysocki

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.