Root/target/linux/goldfish/patches-2.6.30/0072-PM-earlysuspend-Removing-dependence-on-console.patch

1From ba801aa66e869f1f9f9d3a1610a2165baa024e4b Mon Sep 17 00:00:00 2001
2From: Rebecca Schultz <rschultz@google.com>
3Date: Thu, 17 Jul 2008 18:14:55 -0700
4Subject: [PATCH 072/134] PM: earlysuspend: Removing dependence on console.
5MIME-Version: 1.0
6Content-Type: text/plain; charset=utf-8
7Content-Transfer-Encoding: 8bit
8
9Rather than signaling a full update of the display from userspace via a
10console switch, this patch introduces 2 files int /sys/power,
11wait_for_fb_sleep and wait_for_fb_wake. Reading these files will block
12until the requested state has been entered. When a read from
13wait_for_fb_sleep returns userspace should stop drawing. When
14wait_for_fb_wake returns, it should do a full update. If either are called
15when the fb driver is already in the requested state, they will return
16immediately.
17
18Signed-off-by: Rebecca Schultz <rschultz@google.com>
19Signed-off-by: Arve Hjønnevåg <arve@android.com>
20---
21 kernel/power/Kconfig | 9 +++
22 kernel/power/Makefile | 1 +
23 kernel/power/fbearlysuspend.c | 153 +++++++++++++++++++++++++++++++++++++++++
24 3 files changed, 163 insertions(+), 0 deletions(-)
25 create mode 100644 kernel/power/fbearlysuspend.c
26
27--- a/kernel/power/Kconfig
28+++ b/kernel/power/Kconfig
29@@ -159,6 +159,7 @@ config EARLYSUSPEND
30 
31 choice
32     prompt "User-space screen access"
33+ default FB_EARLYSUSPEND if !FRAMEBUFFER_CONSOLE
34     default CONSOLE_EARLYSUSPEND
35     depends on HAS_EARLYSUSPEND
36 
37@@ -172,6 +173,14 @@ choice
38           Register early suspend handler to perform a console switch to
39           when user-space should stop drawing to the screen and a switch
40           back when it should resume.
41+
42+ config FB_EARLYSUSPEND
43+ bool "Sysfs interface"
44+ depends on HAS_EARLYSUSPEND
45+ ---help---
46+ Register early suspend handler that notifies and waits for
47+ user-space through sysfs when user-space should stop drawing
48+ to the screen and notifies user-space when it should resume.
49 endchoice
50 
51 config HIBERNATION
52--- a/kernel/power/Makefile
53+++ b/kernel/power/Makefile
54@@ -10,6 +10,7 @@ obj-$(CONFIG_WAKELOCK) += wakelock.o
55 obj-$(CONFIG_USER_WAKELOCK) += userwakelock.o
56 obj-$(CONFIG_EARLYSUSPEND) += earlysuspend.o
57 obj-$(CONFIG_CONSOLE_EARLYSUSPEND) += consoleearlysuspend.o
58+obj-$(CONFIG_FB_EARLYSUSPEND) += fbearlysuspend.o
59 obj-$(CONFIG_HIBERNATION) += swsusp.o disk.o snapshot.o swap.o user.o
60 
61 obj-$(CONFIG_MAGIC_SYSRQ) += poweroff.o
62--- /dev/null
63+++ b/kernel/power/fbearlysuspend.c
64@@ -0,0 +1,153 @@
65+/* kernel/power/fbearlysuspend.c
66+ *
67+ * Copyright (C) 2005-2008 Google, Inc.
68+ *
69+ * This software is licensed under the terms of the GNU General Public
70+ * License version 2, as published by the Free Software Foundation, and
71+ * may be copied, distributed, and modified under those terms.
72+ *
73+ * This program is distributed in the hope that it will be useful,
74+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
75+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
76+ * GNU General Public License for more details.
77+ *
78+ */
79+
80+#include <linux/earlysuspend.h>
81+#include <linux/module.h>
82+#include <linux/wait.h>
83+
84+#include "power.h"
85+
86+static wait_queue_head_t fb_state_wq;
87+static DEFINE_SPINLOCK(fb_state_lock);
88+static enum {
89+ FB_STATE_STOPPED_DRAWING,
90+ FB_STATE_REQUEST_STOP_DRAWING,
91+ FB_STATE_DRAWING_OK,
92+} fb_state;
93+
94+/* tell userspace to stop drawing, wait for it to stop */
95+static void stop_drawing_early_suspend(struct early_suspend *h)
96+{
97+ int ret;
98+ unsigned long irq_flags;
99+
100+ spin_lock_irqsave(&fb_state_lock, irq_flags);
101+ fb_state = FB_STATE_REQUEST_STOP_DRAWING;
102+ spin_unlock_irqrestore(&fb_state_lock, irq_flags);
103+
104+ wake_up_all(&fb_state_wq);
105+ ret = wait_event_timeout(fb_state_wq,
106+ fb_state == FB_STATE_STOPPED_DRAWING,
107+ HZ);
108+ if (unlikely(fb_state != FB_STATE_STOPPED_DRAWING))
109+ pr_warning("stop_drawing_early_suspend: timeout waiting for "
110+ "userspace to stop drawing\n");
111+}
112+
113+/* tell userspace to start drawing */
114+static void start_drawing_late_resume(struct early_suspend *h)
115+{
116+ unsigned long irq_flags;
117+
118+ spin_lock_irqsave(&fb_state_lock, irq_flags);
119+ fb_state = FB_STATE_DRAWING_OK;
120+ spin_unlock_irqrestore(&fb_state_lock, irq_flags);
121+ wake_up(&fb_state_wq);
122+}
123+
124+static struct early_suspend stop_drawing_early_suspend_desc = {
125+ .level = EARLY_SUSPEND_LEVEL_STOP_DRAWING,
126+ .suspend = stop_drawing_early_suspend,
127+ .resume = start_drawing_late_resume,
128+};
129+
130+static ssize_t wait_for_fb_sleep_show(struct kobject *kobj,
131+ struct kobj_attribute *attr, char *buf)
132+{
133+ char *s = buf;
134+ int ret;
135+
136+ ret = wait_event_interruptible(fb_state_wq,
137+ fb_state != FB_STATE_DRAWING_OK);
138+ if (ret && fb_state == FB_STATE_DRAWING_OK)
139+ return ret;
140+ else
141+ s += sprintf(buf, "sleeping");
142+ return s - buf;
143+}
144+
145+static ssize_t wait_for_fb_wake_show(struct kobject *kobj,
146+ struct kobj_attribute *attr, char *buf)
147+{
148+ char *s = buf;
149+ int ret;
150+ unsigned long irq_flags;
151+
152+ spin_lock_irqsave(&fb_state_lock, irq_flags);
153+ if (fb_state == FB_STATE_REQUEST_STOP_DRAWING) {
154+ fb_state = FB_STATE_STOPPED_DRAWING;
155+ wake_up(&fb_state_wq);
156+ }
157+ spin_unlock_irqrestore(&fb_state_lock, irq_flags);
158+
159+ ret = wait_event_interruptible(fb_state_wq,
160+ fb_state == FB_STATE_DRAWING_OK);
161+ if (ret && fb_state != FB_STATE_DRAWING_OK)
162+ return ret;
163+ else
164+ s += sprintf(buf, "awake");
165+
166+ return s - buf;
167+}
168+
169+#define power_ro_attr(_name) \
170+static struct kobj_attribute _name##_attr = { \
171+ .attr = { \
172+ .name = __stringify(_name), \
173+ .mode = 0444, \
174+ }, \
175+ .show = _name##_show, \
176+ .store = NULL, \
177+}
178+
179+power_ro_attr(wait_for_fb_sleep);
180+power_ro_attr(wait_for_fb_wake);
181+
182+static struct attribute *g[] = {
183+ &wait_for_fb_sleep_attr.attr,
184+ &wait_for_fb_wake_attr.attr,
185+ NULL,
186+};
187+
188+static struct attribute_group attr_group = {
189+ .attrs = g,
190+};
191+
192+static int __init android_power_init(void)
193+{
194+ int ret;
195+
196+ init_waitqueue_head(&fb_state_wq);
197+ fb_state = FB_STATE_DRAWING_OK;
198+
199+ ret = sysfs_create_group(power_kobj, &attr_group);
200+ if (ret) {
201+ pr_err("android_power_init: sysfs_create_group failed\n");
202+ return ret;
203+ }
204+
205+ register_early_suspend(&stop_drawing_early_suspend_desc);
206+ return 0;
207+}
208+
209+static void __exit android_power_exit(void)
210+{
211+ unregister_early_suspend(&stop_drawing_early_suspend_desc);
212+ sysfs_remove_group(power_kobj, &attr_group);
213+}
214+
215+module_init(android_power_init);
216+module_exit(android_power_exit);
217+
218

Archive Download this file



interactive