diff options
| author | Mister Oyster <oysterized@gmail.com> | 2017-12-23 16:12:06 +0100 |
|---|---|---|
| committer | Mister Oyster <oysterized@gmail.com> | 2017-12-23 16:12:06 +0100 |
| commit | bb00e47528381b308f65c97419f986b3d9f96610 (patch) | |
| tree | a5a58d8c12a0605f1b4194ff0d00a294f9c710e5 | |
| parent | f8a374368b1060297fb0fd1aad95531d97d8505e (diff) | |
patches: add earlysuspend support patch
| -rw-r--r-- | patches/system/core/0003-libsuspend-Add-earlysuspend-support.patch | 276 |
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 + |
