diff options
| author | Zhao Wei Liew <zhaoweiliew@gmail.com> | 2016-02-10 20:43:58 +0800 |
|---|---|---|
| committer | Zhao Wei Liew <zhaoweiliew@gmail.com> | 2016-02-15 17:46:56 +0800 |
| commit | c90ea633243ede292da55e6b32d42993b7ba0ba8 (patch) | |
| tree | 0978ea0e40ff0e1c3344e94788b61e4cd9db233d | |
| parent | 9479d592a4cd156574d15936fd0045de7d1689c2 (diff) | |
flo: Use cpufreq limit driver to limit frequencies
Previously, the PowerHAL was using the standard scaling_[min|max]_freq
interfaces to limit CPU maximum and minimum frequencies during
low power mode in order to conserve power.
However, the CPU cores on flo lose their min/max frequencies on
every hotplug, rendering this interface useless. Switch to the
cpufreq_limit driver to fix this issue.
This switch also allows us to remove all the unneeded uevent code,
simplifying the code.
Change-Id: I478bcb745046dde0caf226e46fa1e875f7fafc2c
| -rw-r--r-- | init.flo.rc | 4 | ||||
| -rw-r--r-- | power/power_flo.c | 133 |
2 files changed, 10 insertions, 127 deletions
diff --git a/init.flo.rc b/init.flo.rc index ac3fdbc..4a72ad6 100644 --- a/init.flo.rc +++ b/init.flo.rc @@ -116,6 +116,10 @@ on boot write /proc/sys/net/core/rmem_max 2097152 write /proc/sys/net/core/wmem_max 2097152 + # CPUFreq limit + chown system system /sys/kernel/cpufreq_limit/limited_max_freq + chown system system /sys/kernel/cpufreq_limit/limited_min_freq + # msm specific files that need to be created on /data on post-fs-data chown system system /dev/wcnss_wlan diff --git a/power/power_flo.c b/power/power_flo.c index c4112af..dad9491 100644 --- a/power/power_flo.c +++ b/power/power_flo.c @@ -21,7 +21,6 @@ #include <sys/un.h> #include <fcntl.h> #include <dlfcn.h> -#include <cutils/uevent.h> #include <errno.h> #include <sys/poll.h> #include <pthread.h> @@ -41,33 +40,17 @@ #define MAX_LENGTH 50 #define BOOST_SOCKET "/dev/socket/pb" -#define UEVENT_MSG_LEN 2048 -#define TOTAL_CPUS 4 -#define RETRY_TIME_CHANGING_FREQ 20 -#define SLEEP_USEC_BETWN_RETRY 200 #define LOW_POWER_MAX_FREQ 1026000 #define LOW_POWER_MIN_FREQ 384000 #define NORMAL_MAX_FREQ 1512000 -#define UEVENT_STRING "online@/devices/system/cpu/" + +#define MAX_FREQ_LIMIT_PATH "/sys/kernel/cpufreq_limit/limited_max_freq" +#define MIN_FREQ_LIMIT_PATH "/sys/kernel/cpufreq_limit/limited_min_freq" static int client_sockfd; static struct sockaddr_un client_addr; static int last_state = -1; -static struct pollfd pfd; -static char *cpu_path_min[] = { - "/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq", - "/sys/devices/system/cpu/cpu1/cpufreq/scaling_min_freq", - "/sys/devices/system/cpu/cpu2/cpufreq/scaling_min_freq", - "/sys/devices/system/cpu/cpu3/cpufreq/scaling_min_freq", -}; -static char *cpu_path_max[] = { - "/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq", - "/sys/devices/system/cpu/cpu1/cpufreq/scaling_max_freq", - "/sys/devices/system/cpu/cpu2/cpufreq/scaling_max_freq", - "/sys/devices/system/cpu/cpu3/cpufreq/scaling_max_freq", -}; -static bool freq_set[TOTAL_CPUS]; static bool low_power_mode = false; static pthread_mutex_t low_power_mode_lock = PTHREAD_MUTEX_INITIALIZER; @@ -108,104 +91,10 @@ static int sysfs_write(const char *path, char *s) return 0; } -static int uevent_event() -{ - char msg[UEVENT_MSG_LEN]; - char *cp; - int n, cpu, ret, retry = RETRY_TIME_CHANGING_FREQ; - - n = recv(pfd.fd, msg, UEVENT_MSG_LEN, MSG_DONTWAIT); - if (n <= 0) { - return -1; - } - if (n >= UEVENT_MSG_LEN) { /* overflow -- discard */ - return -1; - } - - cp = msg; - - if (strstr(cp, UEVENT_STRING)) { - n = strlen(cp); - errno = 0; - cpu = strtol(cp + n - 1, NULL, 10); - - if (errno == EINVAL || errno == ERANGE || cpu < 0 || cpu >= TOTAL_CPUS) { - return -1; - } - - pthread_mutex_lock(&low_power_mode_lock); - if (low_power_mode && !freq_set[cpu]) { - while (retry) { - sysfs_write(cpu_path_min[cpu], LOW_POWER_MIN_FREQ); - ret = sysfs_write(cpu_path_max[cpu], LOW_POWER_MAX_FREQ); - if (!ret) { - freq_set[cpu] = true; - break; - } - usleep(SLEEP_USEC_BETWN_RETRY); - retry--; - } - } else if (!low_power_mode && freq_set[cpu]) { - while (retry) { - ret = sysfs_write(cpu_path_max[cpu], NORMAL_MAX_FREQ); - if (!ret) { - freq_set[cpu] = false; - break; - } - usleep(SLEEP_USEC_BETWN_RETRY); - retry--; - } - } - pthread_mutex_unlock(&low_power_mode_lock); - } - return 0; -} - -void *thread_uevent(__attribute__((unused)) void *x) -{ - while (1) { - int nevents, ret; - - nevents = poll(&pfd, 1, -1); - - if (nevents == -1) { - if (errno == EINTR) - continue; - ALOGE("powerhal: thread_uevent: poll_wait failed\n"); - break; - } - ret = uevent_event(); - if (ret < 0) - ALOGE("Error processing the uevent event"); - } - return NULL; -} - -static void uevent_init() -{ - struct sockaddr_nl client; - pthread_t tid; - pfd.fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT); - - if (pfd.fd < 0) { - ALOGE("%s: failed to open: %s", __func__, strerror(errno)); - return; - } - memset(&client, 0, sizeof(struct sockaddr_nl)); - pthread_create(&tid, NULL, thread_uevent, NULL); - client.nl_family = AF_NETLINK; - client.nl_pid = tid; - client.nl_groups = -1; - pfd.events = POLLIN; - bind(pfd.fd, (void *)&client, sizeof(struct sockaddr_nl)); - return; -} - static void power_init(__attribute__((unused)) struct power_module *module) { ALOGI("%s", __func__); socket_init(); - uevent_init(); } static void sync_thread(int off) @@ -346,21 +235,11 @@ static void power_hint( __attribute__((unused)) struct power_module *module, pthread_mutex_lock(&low_power_mode_lock); if (data) { low_power_mode = true; - for (cpu = 0; cpu < TOTAL_CPUS; cpu++) { - sysfs_write(cpu_path_min[cpu], LOW_POWER_MIN_FREQ); - ret = sysfs_write(cpu_path_max[cpu], LOW_POWER_MAX_FREQ); - if (!ret) { - freq_set[cpu] = true; - } - } + sysfs_write(MIN_FREQ_LIMIT_PATH, LOW_POWER_MIN_FREQ); + sysfs_write(MAX_FREQ_LIMIT_PATH, LOW_POWER_MAX_FREQ); } else { low_power_mode = false; - for (cpu = 0; cpu < TOTAL_CPUS; cpu++) { - ret = sysfs_write(cpu_path_max[cpu], NORMAL_MAX_FREQ); - if (!ret) { - freq_set[cpu] = false; - } - } + sysfs_write(MAX_FREQ_LIMIT_PATH, NORMAL_MAX_FREQ); } pthread_mutex_unlock(&low_power_mode_lock); break; |
