mirror of
https://github.com/Divested-Mobile/DivestOS-Build.git
synced 2024-10-01 01:35:54 -04:00
245 lines
7.0 KiB
Diff
245 lines
7.0 KiB
Diff
|
From 9cb94dbd3fb2ea3d335865c3a600af96f4c0611d Mon Sep 17 00:00:00 2001
|
||
|
From: Tad <tad@spotco.us>
|
||
|
Date: Sat, 17 Oct 2015 20:52:02 -0400
|
||
|
Subject: [PATCH] Implement Quick Wakeup
|
||
|
|
||
|
---
|
||
|
arch/arm/configs/cyanogenmod_bacon_defconfig | 2 +
|
||
|
include/linux/quickwakeup.h | 46 ++++++++++++
|
||
|
kernel/power/Kconfig | 20 ++++--
|
||
|
kernel/power/Makefile | 1 +
|
||
|
kernel/power/quickwakeup.c | 104 +++++++++++++++++++++++++++
|
||
|
5 files changed, 167 insertions(+), 6 deletions(-)
|
||
|
create mode 100644 include/linux/quickwakeup.h
|
||
|
create mode 100644 kernel/power/quickwakeup.c
|
||
|
|
||
|
diff --git a/arch/arm/configs/cyanogenmod_bacon_defconfig b/arch/arm/configs/cyanogenmod_bacon_defconfig
|
||
|
index f8ab8c2..6698a71 100644
|
||
|
--- a/arch/arm/configs/cyanogenmod_bacon_defconfig
|
||
|
+++ b/arch/arm/configs/cyanogenmod_bacon_defconfig
|
||
|
@@ -3642,3 +3642,5 @@ CONFIG_NLATTR=y
|
||
|
# CONFIG_CORDIC is not set
|
||
|
CONFIG_QMI_ENCDEC=y
|
||
|
# CONFIG_QMI_ENCDEC_DEBUG is not set
|
||
|
+
|
||
|
+CONFIG_QUICK_WAKEUP=y
|
||
|
diff --git a/include/linux/quickwakeup.h b/include/linux/quickwakeup.h
|
||
|
new file mode 100644
|
||
|
index 0000000..000effa
|
||
|
--- /dev/null
|
||
|
+++ b/include/linux/quickwakeup.h
|
||
|
@@ -0,0 +1,46 @@
|
||
|
+/* include/linux/quickwakeup.h
|
||
|
+ *
|
||
|
+ * Copyright (C) 2014 Motorola Mobility LLC.
|
||
|
+ *
|
||
|
+ * 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 _QUICKWAKEUP_H_
|
||
|
+#define _QUICKWAKEUP_H_
|
||
|
+
|
||
|
+#ifdef __KERNEL__
|
||
|
+
|
||
|
+struct quickwakeup_ops {
|
||
|
+ struct list_head list;
|
||
|
+ char *name;
|
||
|
+ int (*qw_execute)(void *data);
|
||
|
+ int (*qw_check)(void *data);
|
||
|
+ int execute;
|
||
|
+ void *data; /* arbitrary data passed back to user */
|
||
|
+};
|
||
|
+
|
||
|
+#ifdef CONFIG_QUICK_WAKEUP
|
||
|
+
|
||
|
+int quickwakeup_register(struct quickwakeup_ops *ops);
|
||
|
+void quickwakeup_unregister(struct quickwakeup_ops *ops);
|
||
|
+bool quickwakeup_suspend_again(void);
|
||
|
+
|
||
|
+#else
|
||
|
+
|
||
|
+static inline int quickwakeup_register(struct quickwakeup_ops *ops) { return 0; };
|
||
|
+static inline void quickwakeup_unregister(struct quickwakeup_ops *ops) {};
|
||
|
+static inline bool quickwakeup_suspend_again(void) { return 0; };
|
||
|
+
|
||
|
+#endif /* CONFIG_QUICK_WAKEUP */
|
||
|
+
|
||
|
+#endif /* __KERNEL__ */
|
||
|
+
|
||
|
+#endif /* _QUICKWAKEUP_H_ */
|
||
|
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
|
||
|
index e536c8d..8006962 100644
|
||
|
--- a/kernel/power/Kconfig
|
||
|
+++ b/kernel/power/Kconfig
|
||
|
@@ -83,20 +83,20 @@ config PM_STD_PARTITION
|
||
|
default ""
|
||
|
---help---
|
||
|
The default resume partition is the partition that the suspend-
|
||
|
- to-disk implementation will look for a suspended disk image.
|
||
|
+ to-disk implementation will look for a suspended disk image.
|
||
|
|
||
|
- The partition specified here will be different for almost every user.
|
||
|
+ The partition specified here will be different for almost every user.
|
||
|
It should be a valid swap partition (at least for now) that is turned
|
||
|
- on before suspending.
|
||
|
+ on before suspending.
|
||
|
|
||
|
The partition specified can be overridden by specifying:
|
||
|
|
||
|
- resume=/dev/<other device>
|
||
|
+ resume=/dev/<other device>
|
||
|
|
||
|
- which will set the resume partition to the device specified.
|
||
|
+ which will set the resume partition to the device specified.
|
||
|
|
||
|
Note there is currently not a way to specify which device to save the
|
||
|
- suspended image to. It will simply pick the first available swap
|
||
|
+ suspended image to. It will simply pick the first available swap
|
||
|
device.
|
||
|
|
||
|
config PM_SLEEP
|
||
|
@@ -285,6 +285,14 @@ config SUSPEND_TIME
|
||
|
Prints the time spent in suspend in the kernel log, and
|
||
|
keeps statistics on the time spent in suspend in
|
||
|
/sys/kernel/debug/suspend_time
|
||
|
+
|
||
|
+config QUICK_WAKEUP
|
||
|
+ bool "Quick wakeup"
|
||
|
+ depends on SUSPEND
|
||
|
+ default n
|
||
|
+ ---help---
|
||
|
+ Allow kernel driver to do periodic jobs without resuming the full system
|
||
|
+ This option can increase battery life on android powered smartphone.
|
||
|
|
||
|
config DEDUCE_WAKEUP_REASONS
|
||
|
bool
|
||
|
diff --git a/kernel/power/Makefile b/kernel/power/Makefile
|
||
|
index 74c713b..e5bebbc 100644
|
||
|
--- a/kernel/power/Makefile
|
||
|
+++ b/kernel/power/Makefile
|
||
|
@@ -14,5 +14,6 @@ obj-$(CONFIG_PM_WAKELOCKS) += wakelock.o
|
||
|
obj-$(CONFIG_SUSPEND_TIME) += suspend_time.o
|
||
|
|
||
|
obj-$(CONFIG_MAGIC_SYSRQ) += poweroff.o
|
||
|
+obj-$(CONFIG_QUICK_WAKEUP) += quickwakeup.o
|
||
|
|
||
|
obj-$(CONFIG_SUSPEND) += wakeup_reason.o
|
||
|
diff --git a/kernel/power/quickwakeup.c b/kernel/power/quickwakeup.c
|
||
|
new file mode 100644
|
||
|
index 0000000..46f9dda
|
||
|
--- /dev/null
|
||
|
+++ b/kernel/power/quickwakeup.c
|
||
|
@@ -0,0 +1,104 @@
|
||
|
+/* kernel/power/quickwakeup.c
|
||
|
+ *
|
||
|
+ * Copyright (C) 2014 Motorola Mobility LLC.
|
||
|
+ *
|
||
|
+ * 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/kernel.h>
|
||
|
+#include <linux/list.h>
|
||
|
+#include <linux/mutex.h>
|
||
|
+#include <linux/quickwakeup.h>
|
||
|
+
|
||
|
+static LIST_HEAD(qw_head);
|
||
|
+static DEFINE_MUTEX(list_lock);
|
||
|
+
|
||
|
+int quickwakeup_register(struct quickwakeup_ops *ops)
|
||
|
+{
|
||
|
+ mutex_lock(&list_lock);
|
||
|
+ list_add(&ops->list, &qw_head);
|
||
|
+ mutex_unlock(&list_lock);
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+void quickwakeup_unregister(struct quickwakeup_ops *ops)
|
||
|
+{
|
||
|
+ mutex_lock(&list_lock);
|
||
|
+ list_del(&ops->list);
|
||
|
+ mutex_unlock(&list_lock);
|
||
|
+}
|
||
|
+
|
||
|
+static int quickwakeup_check(void)
|
||
|
+{
|
||
|
+ int check = 0;
|
||
|
+ struct quickwakeup_ops *index;
|
||
|
+
|
||
|
+ mutex_lock(&list_lock);
|
||
|
+
|
||
|
+ list_for_each_entry(index, &qw_head, list) {
|
||
|
+ int ret = index->qw_check(index->data);
|
||
|
+ index->execute = ret;
|
||
|
+ check |= ret;
|
||
|
+ pr_debug("%s: %s votes for %s\n", __func__, index->name,
|
||
|
+ ret ? "execute" : "dont care");
|
||
|
+ }
|
||
|
+
|
||
|
+ mutex_unlock(&list_lock);
|
||
|
+
|
||
|
+ return check;
|
||
|
+}
|
||
|
+
|
||
|
+/* return 1 => suspend again
|
||
|
+ return 0 => continue wakeup
|
||
|
+ */
|
||
|
+static int quickwakeup_execute(void)
|
||
|
+{
|
||
|
+ int suspend_again = 0;
|
||
|
+ int final_vote = 1;
|
||
|
+ struct quickwakeup_ops *index;
|
||
|
+
|
||
|
+ mutex_lock(&list_lock);
|
||
|
+
|
||
|
+ list_for_each_entry(index, &qw_head, list) {
|
||
|
+ if (index->execute) {
|
||
|
+ int ret = index->qw_execute(index->data);
|
||
|
+ index->execute = 0;
|
||
|
+ final_vote &= ret;
|
||
|
+ suspend_again = final_vote;
|
||
|
+ pr_debug("%s: %s votes for %s\n", __func__, index->name,
|
||
|
+ ret ? "suspend again" : "wakeup");
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ mutex_unlock(&list_lock);
|
||
|
+
|
||
|
+ pr_debug("%s: %s\n", __func__,
|
||
|
+ suspend_again ? "suspend again" : "wakeup");
|
||
|
+
|
||
|
+ return suspend_again;
|
||
|
+}
|
||
|
+
|
||
|
+/* return 1 => suspend again
|
||
|
+ return 0 => continue wakeup
|
||
|
+ */
|
||
|
+bool quickwakeup_suspend_again(void)
|
||
|
+{
|
||
|
+ int ret = 0;
|
||
|
+
|
||
|
+ if (quickwakeup_check())
|
||
|
+ ret = quickwakeup_execute();
|
||
|
+
|
||
|
+ pr_debug("%s- returning %d %s\n", __func__, ret,
|
||
|
+ ret ? "suspend again" : "wakeup");
|
||
|
+
|
||
|
+ return ret;
|
||
|
+}
|