diff options
author | Omprakash Dhyade <odhyade@codeaurora.org> | 2014-08-24 21:32:38 -0700 |
---|---|---|
committer | Iliyan Malchev <malchev@google.com> | 2014-09-02 20:08:59 -0700 |
commit | 4f7ef69436beb05de28ca7a54d60cdf9eea63d61 (patch) | |
tree | f71d0082a3a095111d2e7c7ce7563788c181ff55 /power | |
parent | 0e5cd855662ae24b0a716c9ecd07a1fa4fc76e62 (diff) | |
download | shamu-4f7ef69436beb05de28ca7a54d60cdf9eea63d61.tar.gz |
PowerHal: Add perflock usage to power hal
-- Add perflock usage to power hal.
-- Add touch boost, encoder boost and low power mode hints. Also, make 2 cores
online by default when display is ON , while 1 core online when display is
OFF.
-- Modify mpdecision, system_server and media sepolicy files required for the
communication.
Change-Id: Idb8958a634a8c8c4b63f7f73a6e1074c845752c0
Signed-off-by: Iliyan Malchev <malchev@google.com>
Diffstat (limited to 'power')
-rw-r--r-- | power/power_shamu.c | 244 |
1 files changed, 243 insertions, 1 deletions
diff --git a/power/power_shamu.c b/power/power_shamu.c index 63da2ece..2dfd3601 100644 --- a/power/power_shamu.c +++ b/power/power_shamu.c @@ -16,9 +16,16 @@ #include <errno.h> #include <string.h> #include <sys/types.h> +#include <sys/stat.h> +#include <sys/socket.h> #include <sys/un.h> #include <fcntl.h> #include <dlfcn.h> +#include <cutils/uevent.h> +#include <errno.h> +#include <sys/poll.h> +#include <pthread.h> +#include <linux/netlink.h> #include <stdlib.h> #include <stdbool.h> @@ -29,6 +36,29 @@ #include <hardware/power.h> #define TOUCH_INTERACTIVE_PATH "/sys/bus/i2c/devices/1-004a/tsp" +#define STATE_ON "state=1" +#define STATE_OFF "state=0" +#define STATE_HDR_ON "state=2" +#define STATE_HDR_OFF "state=3" +#define MAX_LENGTH 50 +#define BOOST_SOCKET "/dev/socket/mpdecision/pb" +static int client_sockfd; +static struct sockaddr_un client_addr; +static int last_state = -1; + +static void socket_init() +{ + if (!client_sockfd) { + client_sockfd = socket(PF_UNIX, SOCK_DGRAM, 0); + if (client_sockfd < 0) { + ALOGE("%s: failed to open: %s", __func__, strerror(errno)); + return; + } + memset(&client_addr, 0, sizeof(struct sockaddr_un)); + client_addr.sun_family = AF_UNIX; + snprintf(client_addr.sun_path, UNIX_PATH_MAX, BOOST_SOCKET); + } +} static int sysfs_write(const char *path, char *s) { @@ -57,18 +87,230 @@ static int sysfs_write(const char *path, char *s) static void power_init(__attribute__((unused)) struct power_module *module) { ALOGI("%s", __func__); + socket_init(); +} + +static void sync_thread(int off) +{ + int rc; + pid_t client; + char data[MAX_LENGTH]; + + if (client_sockfd < 0) { + ALOGE("%s: boost socket not created", __func__); + return; + } + + client = getpid(); + + if (!off) { + snprintf(data, MAX_LENGTH, "2:%d", client); + rc = sendto(client_sockfd, data, strlen(data), 0, + (const struct sockaddr *)&client_addr, sizeof(struct sockaddr_un)); + } else { + snprintf(data, MAX_LENGTH, "3:%d", client); + rc = sendto(client_sockfd, data, strlen(data), 0, + (const struct sockaddr *)&client_addr, sizeof(struct sockaddr_un)); + } + + if (rc < 0) { + ALOGE("%s: failed to send: %s", __func__, strerror(errno)); + } +} + +static void coresonline(int off) +{ + int rc; + pid_t client; + char data[MAX_LENGTH]; + + if (client_sockfd < 0) { + ALOGE("%s: boost socket not created", __func__); + return; + } + + client = getpid(); + + if (!off) { + snprintf(data, MAX_LENGTH, "8:%d", client); + rc = sendto(client_sockfd, data, strlen(data), 0, (const struct sockaddr *)&client_addr, sizeof(struct sockaddr_un)); + } else { + snprintf(data, MAX_LENGTH, "7:%d", client); + rc = sendto(client_sockfd, data, strlen(data), 0, (const struct sockaddr *)&client_addr, sizeof(struct sockaddr_un)); + } + + if (rc < 0) { + ALOGE("%s: failed to send: %s", __func__, strerror(errno)); + } +} + +static void enc_boost(int off) +{ + int rc; + pid_t client; + char data[MAX_LENGTH]; + + if (client_sockfd < 0) { + ALOGE("%s: boost socket not created", __func__); + return; + } + + client = getpid(); + + if (!off) { + snprintf(data, MAX_LENGTH, "5:%d", client); + rc = sendto(client_sockfd, data, strlen(data), 0, + (const struct sockaddr *)&client_addr, sizeof(struct sockaddr_un)); + } else { + snprintf(data, MAX_LENGTH, "6:%d", client); + rc = sendto(client_sockfd, data, strlen(data), 0, + (const struct sockaddr *)&client_addr, sizeof(struct sockaddr_un)); + } + + if (rc < 0) { + ALOGE("%s: failed to send: %s", __func__, strerror(errno)); + } +} + +static void process_video_encode_hint(void *metadata) +{ + + socket_init(); + + if (client_sockfd < 0) { + ALOGE("%s: boost socket not created", __func__); + return; + } + + if (metadata) { + if (!strncmp(metadata, STATE_ON, sizeof(STATE_ON))) { + /* Video encode started */ + sync_thread(1); + enc_boost(1); + } else if (!strncmp(metadata, STATE_OFF, sizeof(STATE_OFF))) { + /* Video encode stopped */ + sync_thread(0); + enc_boost(0); + } else if (!strncmp(metadata, STATE_HDR_ON, sizeof(STATE_HDR_ON))) { + /* HDR usecase started */ + } else if (!strncmp(metadata, STATE_HDR_OFF, sizeof(STATE_HDR_OFF))) { + /* HDR usecase stopped */ + }else + return; + } else { + return; + } +} + + +static void touch_boost() +{ + int rc, fd; + pid_t client; + char data[MAX_LENGTH]; + char buf[MAX_LENGTH]; + + if (client_sockfd < 0) { + ALOGE("%s: boost socket not created", __func__); + return; + } + + client = getpid(); + + snprintf(data, MAX_LENGTH, "1:%d", client); + rc = sendto(client_sockfd, data, strlen(data), 0, + (const struct sockaddr *)&client_addr, sizeof(struct sockaddr_un)); + if (rc < 0) { + ALOGE("%s: failed to send: %s", __func__, strerror(errno)); + } +} + +static void low_power(int on) +{ + int rc; + pid_t client; + char data[MAX_LENGTH]; + + if (client_sockfd < 0) { + ALOGE("%s: boost socket not created", __func__); + return; + } + + client = getpid(); + + if (on) { + snprintf(data, MAX_LENGTH, "10:%d", client); + rc = sendto(client_sockfd, data, strlen(data), 0, (const struct sockaddr *)&client_addr, sizeof(struct sockaddr_un)); + if (rc < 0) { + ALOGE("%s: failed to send: %s", __func__, strerror(errno)); + } + } else { + snprintf(data, MAX_LENGTH, "9:%d", client); + rc = sendto(client_sockfd, data, strlen(data), 0, (const struct sockaddr *)&client_addr, sizeof(struct sockaddr_un)); + if (rc < 0) { + ALOGE("%s: failed to send: %s", __func__, strerror(errno)); + } + } +} + +static void process_low_power_hint(void* data) +{ + int on = (long) data; + if (client_sockfd < 0) { + ALOGE("%s: boost socket not created", __func__); + return; + } + + low_power(on); } static void power_set_interactive(__attribute__((unused)) struct power_module *module, int on) { - ALOGV("%s %s", __func__, (on ? "ON" : "OFF")); sysfs_write(TOUCH_INTERACTIVE_PATH, on ? "AUTO" : "ON"); + + if (last_state == -1) { + last_state = on; + } else { + if (last_state == on) + return; + else + last_state = on; + } + + ALOGV("%s %s", __func__, (on ? "ON" : "OFF")); + if (on) { + coresonline(0); + sync_thread(0); + touch_boost(); + } else { + sync_thread(1); + coresonline(1); + } } static void power_hint( __attribute__((unused)) struct power_module *module, __attribute__((unused)) power_hint_t hint, __attribute__((unused)) void *data) { + switch (hint) { + case POWER_HINT_INTERACTION: + ALOGV("POWER_HINT_INTERACTION"); + touch_boost(); + break; +#if 0 + case POWER_HINT_VSYNC: + ALOGV("POWER_HINT_VSYNC %s", (data ? "ON" : "OFF")); + break; +#endif + case POWER_HINT_VIDEO_ENCODE: + process_video_encode_hint(data); + break; + case POWER_HINT_LOW_POWER: + process_low_power_hint(data); + break; + default: + break; + } } static struct hw_module_methods_t power_module_methods = { |