diff --git a/power/include/samsung_power.h b/power/include/samsung_power.h index a33d8028..3cbf841b 100644 --- a/power/include/samsung_power.h +++ b/power/include/samsung_power.h @@ -25,9 +25,14 @@ * device tree. */ -#define CPU0_SYSFS_PATH "/sys/devices/system/cpu/cpu0" -#define CPU4_SYSFS_PATH "/sys/devices/system/cpu/cpu4" -#define CPU0_INTERACTIVE_PATH "/sys/devices/system/cpu/cpu0/cpufreq/interactive" -#define CPU4_INTERACTIVE_PATH "/sys/devices/system/cpu/cpu4/cpufreq/interactive" +static const char* CPU_SYSFS_PATHS[2] = { + "/sys/devices/system/cpu/cpu0", + "/sys/devices/system/cpu/cpu4" +}; + +static const char* CPU_INTERACTIVE_PATHS[2] = { + "/sys/devices/system/cpu/cpu0/cpufreq/interactive", + "/sys/devices/system/cpu/cpu4/cpufreq/interactive" +}; #endif // SAMSUNG_POWER_H diff --git a/power/power.c b/power/power.c index 99fd443a..7b61748d 100644 --- a/power/power.c +++ b/power/power.c @@ -28,7 +28,6 @@ #include #include -#include #define LOG_TAG "SamsungPowerHAL" /* #define LOG_NDEBUG 0 */ @@ -40,26 +39,25 @@ #include "samsung_power.h" -#define BOOST_PATH CPU0_INTERACTIVE_PATH "/boost" -#define BOOSTPULSE_PATH CPU0_INTERACTIVE_PATH "/boostpulse" -#define CPU0_IO_IS_BUSY_PATH CPU0_INTERACTIVE_PATH "/io_is_busy" -#define CPU4_IO_IS_BUSY_PATH CPU4_INTERACTIVE_PATH "/io_is_busy" -#define CPU0_HISPEED_FREQ_PATH CPU0_INTERACTIVE_PATH "/hispeed_freq" -#define CPU4_HISPEED_FREQ_PATH CPU4_INTERACTIVE_PATH "/hispeed_freq" +#define BOOST_PATH "/boost" +#define BOOSTPULSE_PATH "/boostpulse" -#define CPU0_MAX_FREQ_PATH CPU0_SYSFS_PATH "/cpufreq/scaling_max_freq" -#define CPU4_MAX_FREQ_PATH CPU4_SYSFS_PATH "/cpufreq/scaling_max_freq" +#define IO_IS_BUSY_PATH "/io_is_busy" +#define HISPEED_FREQ_PATH "/hispeed_freq" -#define ARRAY_SIZE(a) sizeof(a) / sizeof(a[0]) +#define MAX_FREQ_PATH "/cpufreq/scaling_max_freq" + +#define CLUSTER_COUNT ARRAY_SIZE(CPU_SYSFS_PATHS) +#define PARAM_MAXLEN 10 + +#define ARRAY_SIZE(a) sizeof(a) / sizeof(a[0]) struct samsung_power_module { struct power_module base; pthread_mutex_t lock; int boostpulse_fd; - char cpu0_hispeed_freq[10]; - char cpu0_max_freq[10]; - char cpu4_hispeed_freq[10]; - char cpu4_max_freq[10]; + char hispeed_freqs[CLUSTER_COUNT][PARAM_MAXLEN]; + char max_freqs[CLUSTER_COUNT][PARAM_MAXLEN]; char* touchscreen_power_path; char* touchkey_power_path; }; @@ -134,16 +132,60 @@ static void sysfs_write(const char *path, char *s) close(fd); } +static void cpu_sysfs_read(const char *param, char s[CLUSTER_COUNT][PARAM_MAXLEN]) +{ + char path[PATH_MAX]; + + for (unsigned int i = 0; i < ARRAY_SIZE(CPU_SYSFS_PATHS); i++) { + sprintf(path, "%s%s", CPU_SYSFS_PATHS[i], param); + sysfs_read(path, s[i], PARAM_MAXLEN); + } +} + +static void cpu_sysfs_write(const char *param, char s[CLUSTER_COUNT][PARAM_MAXLEN]) +{ + char path[PATH_MAX]; + + for (unsigned int i = 0; i < ARRAY_SIZE(CPU_SYSFS_PATHS); i++) { + sprintf(path, "%s%s", CPU_SYSFS_PATHS[i], param); + sysfs_write(path, s[i]); + } +} + +static void cpu_interactive_read(const char *param, char s[CLUSTER_COUNT][PARAM_MAXLEN]) +{ + char path[PATH_MAX]; + + for (unsigned int i = 0; i < ARRAY_SIZE(CPU_INTERACTIVE_PATHS); i++) { + sprintf(path, "%s%s", CPU_INTERACTIVE_PATHS[i], param); + sysfs_read(path, s[i], PARAM_MAXLEN); + } +} + +static void cpu_interactive_write(const char *param, char s[CLUSTER_COUNT][PARAM_MAXLEN]) +{ + char path[PATH_MAX]; + + for (unsigned int i = 0; i < ARRAY_SIZE(CPU_INTERACTIVE_PATHS); i++) { + sprintf(path, "%s%s", CPU_INTERACTIVE_PATHS[i], param); + sysfs_write(path, s[i]); + } +} + static void boost(int32_t duration_us) { int fd; + char path[PATH_MAX]; if (duration_us <= 0) return; - fd = open(BOOST_PATH, O_WRONLY); + // the boost node is only valid for the LITTLE cluster + sprintf(path, "%s%s", CPU_INTERACTIVE_PATHS[0], BOOST_PATH); + + fd = open(path, O_WRONLY); if (fd < 0) { - ALOGE("Error opening %s", BOOST_PATH); + ALOGE("Error opening %s", path); return; } @@ -156,9 +198,14 @@ static void boost(int32_t duration_us) static void boostpulse_open(struct samsung_power_module *samsung_pwr) { - samsung_pwr->boostpulse_fd = open(BOOSTPULSE_PATH, O_WRONLY); + char path[PATH_MAX]; + + // the boostpulse node is only valid for the LITTLE cluster + sprintf(path, "%s%s", CPU_INTERACTIVE_PATHS[0], BOOSTPULSE_PATH); + + samsung_pwr->boostpulse_fd = open(path, O_WRONLY); if (samsung_pwr->boostpulse_fd < 0) { - ALOGE("Error opening %s: %s\n", BOOSTPULSE_PATH, strerror(errno)); + ALOGE("Error opening %s: %s\n", path, strerror(errno)); } } @@ -172,7 +219,8 @@ static void send_boostpulse(int boostpulse_fd) len = write(boostpulse_fd, "1", 1); if (len < 0) { - ALOGE("Error writing to %s: %s", BOOSTPULSE_PATH, strerror(errno)); + ALOGE("Error writing to %s%s: %s", CPU_INTERACTIVE_PATHS[0], BOOSTPULSE_PATH, + strerror(errno)); } } @@ -184,7 +232,6 @@ static void set_power_profile(struct samsung_power_module *samsung_pwr, int profile) { int rc; - struct stat sb; if (profile < 0 || profile >= PROFILE_MAX) { return; @@ -199,34 +246,19 @@ static void set_power_profile(struct samsung_power_module *samsung_pwr, switch (profile) { case PROFILE_POWER_SAVE: // Grab value set by init.*.rc - sysfs_read(CPU0_HISPEED_FREQ_PATH, samsung_pwr->cpu0_hispeed_freq, - sizeof(samsung_pwr->cpu0_hispeed_freq)); + cpu_interactive_read(HISPEED_FREQ_PATH, samsung_pwr->hispeed_freqs); // Limit to hispeed freq - sysfs_write(CPU0_MAX_FREQ_PATH, samsung_pwr->cpu0_hispeed_freq); - rc = stat(CPU4_MAX_FREQ_PATH, &sb); - if (rc == 0) { - sysfs_read(CPU4_HISPEED_FREQ_PATH, samsung_pwr->cpu4_hispeed_freq, - sizeof(samsung_pwr->cpu4_hispeed_freq)); - sysfs_write(CPU4_MAX_FREQ_PATH, samsung_pwr->cpu4_hispeed_freq); - } + cpu_sysfs_write(MAX_FREQ_PATH, samsung_pwr->hispeed_freqs); ALOGV("%s: set powersave mode", __func__); break; case PROFILE_BALANCED: // Restore normal max freq - sysfs_write(CPU0_MAX_FREQ_PATH, samsung_pwr->cpu0_max_freq); - rc = stat(CPU4_MAX_FREQ_PATH, &sb); - if (rc == 0) { - sysfs_write(CPU4_MAX_FREQ_PATH, samsung_pwr->cpu4_max_freq); - } + cpu_sysfs_write(MAX_FREQ_PATH, samsung_pwr->max_freqs); ALOGV("%s: set balanced mode", __func__); break; case PROFILE_HIGH_PERFORMANCE: // Restore normal max freq - sysfs_write(CPU0_MAX_FREQ_PATH, samsung_pwr->cpu0_max_freq); - rc = stat(CPU4_MAX_FREQ_PATH, &sb); - if (rc == 0) { - sysfs_write(CPU4_MAX_FREQ_PATH, samsung_pwr->cpu4_max_freq); - } + cpu_sysfs_write(MAX_FREQ_PATH, samsung_pwr->max_freqs); ALOGV("%s: set performance mode", __func__); break; default: @@ -311,25 +343,8 @@ static void find_input_nodes(struct samsung_power_module *samsung_pwr, char *dir static void init_cpufreqs(struct samsung_power_module *samsung_pwr) { - int rc; - struct stat sb; - - sysfs_read(CPU0_HISPEED_FREQ_PATH, samsung_pwr->cpu0_hispeed_freq, - sizeof(samsung_pwr->cpu0_hispeed_freq)); - sysfs_read(CPU0_MAX_FREQ_PATH, samsung_pwr->cpu0_max_freq, - sizeof(samsung_pwr->cpu0_max_freq)); - ALOGV("%s: CPU 0 hispeed freq: %s", __func__, samsung_pwr->cpu0_hispeed_freq); - ALOGV("%s: CPU 0 max freq: %s", __func__, samsung_pwr->cpu0_max_freq); - - rc = stat(CPU4_HISPEED_FREQ_PATH, &sb); - if (rc == 0) { - sysfs_read(CPU4_HISPEED_FREQ_PATH, samsung_pwr->cpu4_hispeed_freq, - sizeof(samsung_pwr->cpu4_hispeed_freq)); - sysfs_read(CPU4_MAX_FREQ_PATH, samsung_pwr->cpu4_max_freq, - sizeof(samsung_pwr->cpu4_max_freq)); - ALOGV("%s: CPU 4 hispeed freq: %s", __func__, samsung_pwr->cpu4_hispeed_freq); - ALOGV("%s: CPU 4 max freq: %s", __func__, samsung_pwr->cpu4_max_freq); - } + cpu_interactive_read(HISPEED_FREQ_PATH, samsung_pwr->hispeed_freqs); + cpu_sysfs_read(MAX_FREQ_PATH, samsung_pwr->max_freqs); } static void init_touch_input_power_path(struct samsung_power_module *samsung_pwr) @@ -376,11 +391,12 @@ static void samsung_power_init(struct power_module *module) static void samsung_power_set_interactive(struct power_module *module, int on) { struct samsung_power_module *samsung_pwr = (struct samsung_power_module *) module; - struct stat sb; int panel_brightness; char button_state[2]; int rc; static bool touchkeys_blocked = false; + char ON[CLUSTER_COUNT][PARAM_MAXLEN] = {"1", "1"}; + char OFF[CLUSTER_COUNT][PARAM_MAXLEN] = {"0", "0"}; ALOGV("power_set_interactive: %d", on); @@ -432,11 +448,7 @@ static void samsung_power_set_interactive(struct power_module *module, int on) } out: - sysfs_write(CPU0_IO_IS_BUSY_PATH, on ? "1" : "0"); - rc = stat(CPU4_IO_IS_BUSY_PATH, &sb); - if (rc == 0) { - sysfs_write(CPU4_IO_IS_BUSY_PATH, on ? "1" : "0"); - } + cpu_interactive_write(IO_IS_BUSY_PATH, on ? ON : OFF); ALOGV("power_set_interactive: %d done", on); }