aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMister Oyster <oysterized@gmail.com>2017-12-23 16:12:06 +0100
committerMister Oyster <oysterized@gmail.com>2017-12-23 16:12:06 +0100
commitbb00e47528381b308f65c97419f986b3d9f96610 (patch)
treea5a58d8c12a0605f1b4194ff0d00a294f9c710e5
parentf8a374368b1060297fb0fd1aad95531d97d8505e (diff)
patches: add earlysuspend support patch
-rw-r--r--patches/system/core/0003-libsuspend-Add-earlysuspend-support.patch276
1 files changed, 276 insertions, 0 deletions
diff --git a/patches/system/core/0003-libsuspend-Add-earlysuspend-support.patch b/patches/system/core/0003-libsuspend-Add-earlysuspend-support.patch
new file mode 100644
index 0000000..4e22e91
--- /dev/null
+++ b/patches/system/core/0003-libsuspend-Add-earlysuspend-support.patch
@@ -0,0 +1,276 @@
+From eacabb641ecad972106d5adb099ba5368882cf05 Mon Sep 17 00:00:00 2001
+From: danielhk <daniel.p6800@gmail.com>
+Date: Sat, 23 Dec 2017 12:50:50 +0800
+Subject: [PATCH] libsuspend:Add earlysuspend support
+
+Old kernels require earlysusupend support.
+---
+ libsuspend/Android.bp | 1 +
+ libsuspend/autosuspend.c | 13 ++
+ libsuspend/autosuspend_earlysuspend.c | 218 ++++++++++++++++++++++++++++++++++
+ 3 files changed, 232 insertions(+)
+ create mode 100644 libsuspend/autosuspend_earlysuspend.c
+
+diff --git a/libsuspend/Android.bp b/libsuspend/Android.bp
+index 130800ed8..40e753332 100644
+--- a/libsuspend/Android.bp
++++ b/libsuspend/Android.bp
+@@ -6,6 +6,7 @@ cc_library {
+
+ srcs: [
+ "autosuspend.c",
++ "autosuspend_earlysuspend.c",
+ "autosuspend_wakeup_count.c",
+ ],
+ export_include_dirs: ["include"],
+diff --git a/libsuspend/autosuspend.c b/libsuspend/autosuspend.c
+index 96e1c10d0..54730c293 100644
+--- a/libsuspend/autosuspend.c
++++ b/libsuspend/autosuspend.c
+@@ -34,6 +34,19 @@ static int autosuspend_init(void)
+ return 0;
+ }
+
++ autosuspend_ops = autosuspend_earlysuspend_init();
++ if (autosuspend_ops) {
++ goto out;
++ }
++
++/* Remove autosleep so userspace can manager suspend/resume and keep stats */
++#if 0
++ autosuspend_ops = autosuspend_autosleep_init();
++ if (autosuspend_ops) {
++ goto out;
++ }
++#endif
++
+ autosuspend_ops = autosuspend_wakeup_count_init();
+ if (autosuspend_ops) {
+ goto out;
+diff --git a/libsuspend/autosuspend_earlysuspend.c b/libsuspend/autosuspend_earlysuspend.c
+new file mode 100644
+index 000000000..579de5227
+--- /dev/null
++++ b/libsuspend/autosuspend_earlysuspend.c
+@@ -0,0 +1,218 @@
++/*
++ * Copyright (C) 2012 The Android Open Source Project
++ *
++ * Licensed under the Apache License, Version 2.0 (the "License");
++ * you may not use this file except in compliance with the License.
++ * You may obtain a copy of the License at
++ *
++ * http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the License for the specific language governing permissions and
++ * limitations under the License.
++ */
++
++#include <errno.h>
++#include <fcntl.h>
++#include <pthread.h>
++#include <stdbool.h>
++#include <stddef.h>
++#include <string.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <unistd.h>
++
++#define LOG_TAG "libsuspend"
++#include <log/log.h>
++
++#include "autosuspend_ops.h"
++
++#define EARLYSUSPEND_SYS_POWER_STATE "/sys/power/state"
++#define EARLYSUSPEND_WAIT_FOR_FB_SLEEP "/sys/power/wait_for_fb_sleep"
++#define EARLYSUSPEND_WAIT_FOR_FB_WAKE "/sys/power/wait_for_fb_wake"
++
++static int sPowerStatefd;
++static const char *pwr_state_mem = "mem";
++static const char *pwr_state_on = "on";
++static pthread_t earlysuspend_thread;
++static pthread_mutex_t earlysuspend_mutex = PTHREAD_MUTEX_INITIALIZER;
++static pthread_cond_t earlysuspend_cond = PTHREAD_COND_INITIALIZER;
++static bool wait_for_earlysuspend;
++static enum {
++ EARLYSUSPEND_ON,
++ EARLYSUSPEND_MEM,
++} earlysuspend_state = EARLYSUSPEND_ON;
++
++int wait_for_fb_wake(void)
++{
++ int err = 0;
++ char buf;
++ int fd = TEMP_FAILURE_RETRY(open(EARLYSUSPEND_WAIT_FOR_FB_WAKE, O_RDONLY, 0));
++ // if the file doesn't exist, the error will be caught in read() below
++ err = TEMP_FAILURE_RETRY(read(fd, &buf, 1));
++ ALOGE_IF(err < 0,
++ "*** ANDROID_WAIT_FOR_FB_WAKE failed (%s)", strerror(errno));
++ close(fd);
++ return err < 0 ? err : 0;
++}
++
++static int wait_for_fb_sleep(void)
++{
++ int err = 0;
++ char buf;
++ int fd = TEMP_FAILURE_RETRY(open(EARLYSUSPEND_WAIT_FOR_FB_SLEEP, O_RDONLY, 0));
++ // if the file doesn't exist, the error will be caught in read() below
++ err = TEMP_FAILURE_RETRY(read(fd, &buf, 1));
++ ALOGE_IF(err < 0,
++ "*** ANDROID_WAIT_FOR_FB_SLEEP failed (%s)", strerror(errno));
++ close(fd);
++ return err < 0 ? err : 0;
++}
++
++static void *earlysuspend_thread_func(void __unused *arg)
++{
++ while (1) {
++ if (wait_for_fb_sleep()) {
++ ALOGE("Failed reading wait_for_fb_sleep, exiting earlysuspend thread\n");
++ return NULL;
++ }
++ pthread_mutex_lock(&earlysuspend_mutex);
++ earlysuspend_state = EARLYSUSPEND_MEM;
++ pthread_cond_signal(&earlysuspend_cond);
++ pthread_mutex_unlock(&earlysuspend_mutex);
++
++ if (wait_for_fb_wake()) {
++ ALOGE("Failed reading wait_for_fb_wake, exiting earlysuspend thread\n");
++ return NULL;
++ }
++ pthread_mutex_lock(&earlysuspend_mutex);
++ earlysuspend_state = EARLYSUSPEND_ON;
++ pthread_cond_signal(&earlysuspend_cond);
++ pthread_mutex_unlock(&earlysuspend_mutex);
++ }
++}
++static int autosuspend_earlysuspend_enable(void)
++{
++ char buf[80];
++ int ret;
++
++ ALOGV("autosuspend_earlysuspend_enable\n");
++
++ ret = write(sPowerStatefd, pwr_state_mem, strlen(pwr_state_mem));
++ if (ret < 0) {
++ strerror_r(errno, buf, sizeof(buf));
++ ALOGE("Error writing to %s: %s\n", EARLYSUSPEND_SYS_POWER_STATE, buf);
++ goto err;
++ }
++
++ if (wait_for_earlysuspend) {
++ pthread_mutex_lock(&earlysuspend_mutex);
++ while (earlysuspend_state != EARLYSUSPEND_MEM) {
++ pthread_cond_wait(&earlysuspend_cond, &earlysuspend_mutex);
++ }
++ pthread_mutex_unlock(&earlysuspend_mutex);
++ }
++
++ ALOGV("autosuspend_earlysuspend_enable done\n");
++
++ return 0;
++
++err:
++ return ret;
++}
++
++static int autosuspend_earlysuspend_disable(void)
++{
++ char buf[80];
++ int ret;
++
++ ALOGV("autosuspend_earlysuspend_disable\n");
++
++ ret = TEMP_FAILURE_RETRY(write(sPowerStatefd, pwr_state_on, strlen(pwr_state_on)));
++ if (ret < 0) {
++ strerror_r(errno, buf, sizeof(buf));
++ ALOGE("Error writing to %s: %s\n", EARLYSUSPEND_SYS_POWER_STATE, buf);
++ goto err;
++ }
++
++ if (wait_for_earlysuspend) {
++ pthread_mutex_lock(&earlysuspend_mutex);
++ while (earlysuspend_state != EARLYSUSPEND_ON) {
++ pthread_cond_wait(&earlysuspend_cond, &earlysuspend_mutex);
++ }
++ pthread_mutex_unlock(&earlysuspend_mutex);
++ }
++
++ ALOGV("autosuspend_earlysuspend_disable done\n");
++
++ return 0;
++
++err:
++ return ret;
++}
++
++struct autosuspend_ops autosuspend_earlysuspend_ops = {
++ .enable = autosuspend_earlysuspend_enable,
++ .disable = autosuspend_earlysuspend_disable,
++};
++
++void start_earlysuspend_thread(void)
++{
++ char buf[80];
++ int ret;
++
++ ret = access(EARLYSUSPEND_WAIT_FOR_FB_SLEEP, F_OK);
++ if (ret < 0) {
++ return;
++ }
++
++ ret = access(EARLYSUSPEND_WAIT_FOR_FB_WAKE, F_OK);
++ if (ret < 0) {
++ return;
++ }
++
++ wait_for_fb_wake();
++
++ ALOGI("Starting early suspend unblocker thread\n");
++ ret = pthread_create(&earlysuspend_thread, NULL, earlysuspend_thread_func, NULL);
++ if (ret) {
++ strerror_r(errno, buf, sizeof(buf));
++ ALOGE("Error creating thread: %s\n", buf);
++ return;
++ }
++
++ wait_for_earlysuspend = true;
++}
++
++struct autosuspend_ops *autosuspend_earlysuspend_init(void)
++{
++ char buf[80];
++ int ret;
++
++ sPowerStatefd = TEMP_FAILURE_RETRY(open(EARLYSUSPEND_SYS_POWER_STATE, O_RDWR));
++
++ if (sPowerStatefd < 0) {
++ strerror_r(errno, buf, sizeof(buf));
++ ALOGW("Error opening %s: %s\n", EARLYSUSPEND_SYS_POWER_STATE, buf);
++ return NULL;
++ }
++
++ ret = TEMP_FAILURE_RETRY(write(sPowerStatefd, "on", 2));
++ if (ret < 0) {
++ strerror_r(errno, buf, sizeof(buf));
++ ALOGW("Error writing 'on' to %s: %s\n", EARLYSUSPEND_SYS_POWER_STATE, buf);
++ goto err_write;
++ }
++
++ ALOGI("Selected early suspend\n");
++
++ start_earlysuspend_thread();
++
++ return &autosuspend_earlysuspend_ops;
++
++err_write:
++ close(sPowerStatefd);
++ return NULL;
++}
+--
+2.11.0
+