blob: 03171bbc066a7da56108a0faca44c8243c25c35e [file] [log] [blame]
Anurag Singh9cec85b2012-09-04 21:46:24 -07001/*
Ananth Raghavan Subramaniane432dbf2017-03-24 16:30:12 -07002 * Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
Anurag Singh9cec85b2012-09-04 21:46:24 -07003 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 * * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer in the documentation and/or other materials provided
12 * with the distribution.
Duy Truong70222452013-02-10 06:35:11 -080013 * * Neither the name of The Linux Foundation nor the names of its
Anurag Singh9cec85b2012-09-04 21:46:24 -070014 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
Anurag Singh6ec12062012-10-02 09:59:01 -070030#define LOG_NIDEBUG 0
31
Anurag Singh9cec85b2012-09-04 21:46:24 -070032#include <errno.h>
33#include <string.h>
34#include <sys/types.h>
35#include <sys/stat.h>
36#include <fcntl.h>
37#include <dlfcn.h>
38#include <stdlib.h>
39
40#define LOG_TAG "QCOM PowerHAL"
Anurag Singh9cec85b2012-09-04 21:46:24 -070041#include <utils/Log.h>
Anurag Singh9cec85b2012-09-04 21:46:24 -070042#include <hardware/hardware.h>
43#include <hardware/power.h>
44
Anurag Singh6ec12062012-10-02 09:59:01 -070045#include "utils.h"
Anurag Singh9cec85b2012-09-04 21:46:24 -070046#include "metadata-defs.h"
Anurag Singh6ec12062012-10-02 09:59:01 -070047#include "hint-data.h"
48#include "performance.h"
Anurag Singh057806b2013-04-16 16:53:45 -070049#include "power-common.h"
Anurag Singh9cec85b2012-09-04 21:46:24 -070050
Anurag Singh6f64e9f2012-10-09 16:08:38 -070051static int saved_dcvs_cpu0_slack_max = -1;
52static int saved_dcvs_cpu0_slack_min = -1;
53static int saved_mpdecision_slack_max = -1;
54static int saved_mpdecision_slack_min = -1;
55static int saved_interactive_mode = -1;
56static int slack_node_rw_failed = 0;
Anurag Singhb15323a2013-06-08 16:55:44 -070057static int display_hint_sent;
Zhoulu Luo3b1fbdb2013-12-06 16:32:10 -080058int display_boost;
Anurag Singh9cec85b2012-09-04 21:46:24 -070059
Ananth Raghavan Subramanian65a6a062017-03-21 16:26:20 -070060static int power_device_open(const hw_module_t* module, const char* name,
61 hw_device_t** device);
62
Anurag Singh9cec85b2012-09-04 21:46:24 -070063static struct hw_module_methods_t power_module_methods = {
Ananth Raghavan Subramanian65a6a062017-03-21 16:26:20 -070064 .open = power_device_open,
Anurag Singh9cec85b2012-09-04 21:46:24 -070065};
66
Anurag Singh6ec12062012-10-02 09:59:01 -070067static void power_init(struct power_module *module)
Anurag Singh9cec85b2012-09-04 21:46:24 -070068{
69 ALOGI("QCOM power HAL initing.");
Zhoulu Luo3b1fbdb2013-12-06 16:32:10 -080070
71 int fd;
72 char buf[10] = {0};
73
74 fd = open("/sys/devices/soc0/soc_id", O_RDONLY);
75 if (fd >= 0) {
76 if (read(fd, buf, sizeof(buf) - 1) == -1) {
77 ALOGW("Unable to read soc_id");
78 } else {
79 int soc_id = atoi(buf);
Dilip Gudlurf18fc4c2014-01-15 14:24:45 -080080 if (soc_id == 194 || (soc_id >= 208 && soc_id <= 218) || soc_id == 178) {
Zhoulu Luo3b1fbdb2013-12-06 16:32:10 -080081 display_boost = 1;
82 }
83 }
84 close(fd);
85 }
Anurag Singh9cec85b2012-09-04 21:46:24 -070086}
87
Anurag Singh6ec12062012-10-02 09:59:01 -070088static void process_video_decode_hint(void *metadata)
89{
90 char governor[80];
91 struct video_decode_metadata_t video_decode_metadata;
Anurag Singh9cec85b2012-09-04 21:46:24 -070092
Anurag Singh6ec12062012-10-02 09:59:01 -070093 if (get_scaling_governor(governor, sizeof(governor)) == -1) {
94 ALOGE("Can't obtain scaling governor.");
Anurag Singh9cec85b2012-09-04 21:46:24 -070095
Anurag Singh6ec12062012-10-02 09:59:01 -070096 return;
Anurag Singh9cec85b2012-09-04 21:46:24 -070097 }
98
Anurag Singh6ec12062012-10-02 09:59:01 -070099 if (metadata) {
100 ALOGI("Processing video decode hint. Metadata: %s", (char *)metadata);
101 }
102
103 /* Initialize encode metadata struct fields. */
104 memset(&video_decode_metadata, 0, sizeof(struct video_decode_metadata_t));
105 video_decode_metadata.state = -1;
106 video_decode_metadata.hint_id = DEFAULT_VIDEO_DECODE_HINT_ID;
107
108 if (metadata) {
109 if (parse_video_decode_metadata((char *)metadata, &video_decode_metadata) ==
110 -1) {
111 ALOGE("Error occurred while parsing metadata.");
112 return;
113 }
114 } else {
115 return;
116 }
117
118 if (video_decode_metadata.state == 1) {
Anurag Singh4ce3b942012-12-14 10:23:03 -0800119 if ((strncmp(governor, ONDEMAND_GOVERNOR, strlen(ONDEMAND_GOVERNOR)) == 0) &&
120 (strlen(governor) == strlen(ONDEMAND_GOVERNOR))) {
Vince Leungf72adfb2013-05-03 15:13:29 -0700121 int resource_values[] = {THREAD_MIGRATION_SYNC_OFF};
122
123 perform_hint_action(video_decode_metadata.hint_id,
124 resource_values, sizeof(resource_values)/sizeof(resource_values[0]));
Anurag Singh4ce3b942012-12-14 10:23:03 -0800125 } else if ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) &&
126 (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) {
Vince Leungf72adfb2013-05-03 15:13:29 -0700127 int resource_values[] = {TR_MS_30, HISPEED_LOAD_90, HS_FREQ_1026, THREAD_MIGRATION_SYNC_OFF};
Anurag Singh6ec12062012-10-02 09:59:01 -0700128
129 perform_hint_action(video_decode_metadata.hint_id,
130 resource_values, sizeof(resource_values)/sizeof(resource_values[0]));
131 }
132 } else if (video_decode_metadata.state == 0) {
Anurag Singh4ce3b942012-12-14 10:23:03 -0800133 if ((strncmp(governor, ONDEMAND_GOVERNOR, strlen(ONDEMAND_GOVERNOR)) == 0) &&
134 (strlen(governor) == strlen(ONDEMAND_GOVERNOR))) {
135 } else if ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) &&
136 (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) {
Anurag Singh6ec12062012-10-02 09:59:01 -0700137 undo_hint_action(video_decode_metadata.hint_id);
138 }
139 }
Anurag Singh9cec85b2012-09-04 21:46:24 -0700140}
141
142static void process_video_encode_hint(void *metadata)
143{
Anurag Singh9cec85b2012-09-04 21:46:24 -0700144 char governor[80];
145 struct video_encode_metadata_t video_encode_metadata;
146
147 if (get_scaling_governor(governor, sizeof(governor)) == -1) {
148 ALOGE("Can't obtain scaling governor.");
149
150 return;
151 }
152
153 /* Initialize encode metadata struct fields. */
Anurag Singh6ec12062012-10-02 09:59:01 -0700154 memset(&video_encode_metadata, 0, sizeof(struct video_encode_metadata_t));
Anurag Singh9cec85b2012-09-04 21:46:24 -0700155 video_encode_metadata.state = -1;
Anurag Singh6ec12062012-10-02 09:59:01 -0700156 video_encode_metadata.hint_id = DEFAULT_VIDEO_ENCODE_HINT_ID;
Anurag Singh9cec85b2012-09-04 21:46:24 -0700157
158 if (metadata) {
Anurag Singh6ec12062012-10-02 09:59:01 -0700159 if (parse_video_encode_metadata((char *)metadata, &video_encode_metadata) ==
Anurag Singh9cec85b2012-09-04 21:46:24 -0700160 -1) {
161 ALOGE("Error occurred while parsing metadata.");
162 return;
163 }
164 } else {
165 return;
166 }
167
Anurag Singh6ec12062012-10-02 09:59:01 -0700168 if (video_encode_metadata.state == 1) {
Anurag Singh4ce3b942012-12-14 10:23:03 -0800169 if ((strncmp(governor, ONDEMAND_GOVERNOR, strlen(ONDEMAND_GOVERNOR)) == 0) &&
170 (strlen(governor) == strlen(ONDEMAND_GOVERNOR))) {
Vince Leungf72adfb2013-05-03 15:13:29 -0700171 int resource_values[] = {IO_BUSY_OFF, SAMPLING_DOWN_FACTOR_1, THREAD_MIGRATION_SYNC_OFF};
Anurag Singh9cec85b2012-09-04 21:46:24 -0700172
Anurag Singh6ec12062012-10-02 09:59:01 -0700173 perform_hint_action(video_encode_metadata.hint_id,
174 resource_values, sizeof(resource_values)/sizeof(resource_values[0]));
Anurag Singh4ce3b942012-12-14 10:23:03 -0800175 } else if ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) &&
176 (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) {
Anurag Singh6cda91c2013-12-18 18:24:14 -0800177 int resource_values[] = {TR_MS_30, HISPEED_LOAD_90, HS_FREQ_1026, THREAD_MIGRATION_SYNC_OFF,
178 INTERACTIVE_IO_BUSY_OFF};
Anurag Singh9cec85b2012-09-04 21:46:24 -0700179
Anurag Singh6ec12062012-10-02 09:59:01 -0700180 perform_hint_action(video_encode_metadata.hint_id,
181 resource_values, sizeof(resource_values)/sizeof(resource_values[0]));
182 }
183 } else if (video_encode_metadata.state == 0) {
Anurag Singh4ce3b942012-12-14 10:23:03 -0800184 if ((strncmp(governor, ONDEMAND_GOVERNOR, strlen(ONDEMAND_GOVERNOR)) == 0) &&
185 (strlen(governor) == strlen(ONDEMAND_GOVERNOR))) {
Anurag Singh6ec12062012-10-02 09:59:01 -0700186 undo_hint_action(video_encode_metadata.hint_id);
Anurag Singh4ce3b942012-12-14 10:23:03 -0800187 } else if ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) &&
188 (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) {
Anurag Singh6ec12062012-10-02 09:59:01 -0700189 undo_hint_action(video_encode_metadata.hint_id);
Anurag Singh9cec85b2012-09-04 21:46:24 -0700190 }
191 }
192}
193
194int __attribute__ ((weak)) power_hint_override(struct power_module *module, power_hint_t hint,
195 void *data)
196{
Anurag Singh057806b2013-04-16 16:53:45 -0700197 return HINT_NONE;
Anurag Singh9cec85b2012-09-04 21:46:24 -0700198}
199
Ajay Dudani5e676802015-04-07 23:56:52 -0700200/* Declare function before use */
201void interaction(int duration, int num_args, int opt_list[]);
202
Anurag Singh9cec85b2012-09-04 21:46:24 -0700203static void power_hint(struct power_module *module, power_hint_t hint,
204 void *data)
205{
206 /* Check if this hint has been overridden. */
Anurag Singh057806b2013-04-16 16:53:45 -0700207 if (power_hint_override(module, hint, data) == HINT_HANDLED) {
Anurag Singh9cec85b2012-09-04 21:46:24 -0700208 /* The power_hint has been handled. We can skip the rest. */
209 return;
210 }
211
212 switch(hint) {
213 case POWER_HINT_VSYNC:
214 break;
Ananth Raghavan Subramaniane432dbf2017-03-24 16:30:12 -0700215 case POWER_HINT_SUSTAINED_PERFORMANCE:
216 ALOGI("Sustained perf power hint not handled in power_hint_override");
217 break;
218 case POWER_HINT_VR_MODE:
219 ALOGI("VR mode power hint not handled in power_hint_override");
220 break;
Anurag Singh9cec85b2012-09-04 21:46:24 -0700221 case POWER_HINT_INTERACTION:
Vince Leung699c1bc2013-08-14 17:40:36 -0700222 {
223 int resources[] = {0x702, 0x20F, 0x30F};
224 int duration = 3000;
225
226 interaction(duration, sizeof(resources)/sizeof(resources[0]), resources);
227 }
Anurag Singh9cec85b2012-09-04 21:46:24 -0700228 break;
229 case POWER_HINT_VIDEO_ENCODE:
230 process_video_encode_hint(data);
231 break;
Anurag Singh6ec12062012-10-02 09:59:01 -0700232 case POWER_HINT_VIDEO_DECODE:
233 process_video_decode_hint(data);
234 break;
Anurag Singh9cec85b2012-09-04 21:46:24 -0700235 }
236}
237
Anurag Singh6ec12062012-10-02 09:59:01 -0700238int __attribute__ ((weak)) set_interactive_override(struct power_module *module, int on)
239{
Anurag Singh057806b2013-04-16 16:53:45 -0700240 return HINT_NONE;
Anurag Singh6ec12062012-10-02 09:59:01 -0700241}
242
243void set_interactive(struct power_module *module, int on)
Anurag Singh9cec85b2012-09-04 21:46:24 -0700244{
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700245 char governor[80];
246 char tmp_str[NODE_MAX];
Anurag Singh6ec12062012-10-02 09:59:01 -0700247 struct video_encode_metadata_t video_encode_metadata;
Krishna Vanka42c06e12016-08-29 16:38:54 +0530248 int rc = 0;
Anurag Singh6ec12062012-10-02 09:59:01 -0700249
Balamurugan Thanikachalam930f9ae2017-07-11 14:42:21 +0530250 if (!on) {
251 /* Send Display OFF hint to perf HAL */
252 perf_hint_enable(VENDOR_HINT_DISPLAY_OFF, 0);
253 } else {
254 /* Send Display ON hint to perf HAL */
255 perf_hint_enable(VENDOR_HINT_DISPLAY_ON, 0);
256 }
257
Anurag Singh057806b2013-04-16 16:53:45 -0700258 if (set_interactive_override(module, on) == HINT_HANDLED) {
Anurag Singh6ec12062012-10-02 09:59:01 -0700259 return;
260 }
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700261
Anurag Singhb15323a2013-06-08 16:55:44 -0700262 ALOGI("Got set_interactive hint");
Anurag Singhfe93c1d2012-11-21 15:15:56 -0800263
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700264 if (get_scaling_governor(governor, sizeof(governor)) == -1) {
Anurag Singh6ec12062012-10-02 09:59:01 -0700265 ALOGE("Can't obtain scaling governor.");
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700266
267 return;
268 }
269
Anurag Singh6ec12062012-10-02 09:59:01 -0700270 if (!on) {
271 /* Display off. */
Anurag Singh4ce3b942012-12-14 10:23:03 -0800272 if ((strncmp(governor, ONDEMAND_GOVERNOR, strlen(ONDEMAND_GOVERNOR)) == 0) &&
273 (strlen(governor) == strlen(ONDEMAND_GOVERNOR))) {
Vince Leungf72adfb2013-05-03 15:13:29 -0700274 int resource_values[] = {DISPLAY_OFF, MS_500, THREAD_MIGRATION_SYNC_OFF};
Anurag Singh10918c12012-11-09 17:35:20 -0800275
Anurag Singhb15323a2013-06-08 16:55:44 -0700276 if (!display_hint_sent) {
277 perform_hint_action(DISPLAY_STATE_HINT_ID,
278 resource_values, sizeof(resource_values)/sizeof(resource_values[0]));
279 display_hint_sent = 1;
280 }
Anurag Singh4ce3b942012-12-14 10:23:03 -0800281 } else if ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) &&
282 (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) {
Dilip Gudlur2eae2662014-02-25 12:32:37 -0800283 int resource_values[] = {TR_MS_50, THREAD_MIGRATION_SYNC_OFF};
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700284
Anurag Singhb15323a2013-06-08 16:55:44 -0700285 if (!display_hint_sent) {
286 perform_hint_action(DISPLAY_STATE_HINT_ID,
287 resource_values, sizeof(resource_values)/sizeof(resource_values[0]));
288 display_hint_sent = 1;
289 }
Anurag Singh4ce3b942012-12-14 10:23:03 -0800290 } else if ((strncmp(governor, MSMDCVS_GOVERNOR, strlen(MSMDCVS_GOVERNOR)) == 0) &&
291 (strlen(governor) == strlen(MSMDCVS_GOVERNOR))) {
Anurag Singh6ec12062012-10-02 09:59:01 -0700292 if (saved_interactive_mode == 1){
293 /* Display turned off. */
294 if (sysfs_read(DCVS_CPU0_SLACK_MAX_NODE, tmp_str, NODE_MAX - 1)) {
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700295 if (!slack_node_rw_failed) {
Anurag Singh6ec12062012-10-02 09:59:01 -0700296 ALOGE("Failed to read from %s", DCVS_CPU0_SLACK_MAX_NODE);
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700297 }
298
299 rc = 1;
Anurag Singh6ec12062012-10-02 09:59:01 -0700300 } else {
301 saved_dcvs_cpu0_slack_max = atoi(tmp_str);
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700302 }
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700303
Anurag Singh6ec12062012-10-02 09:59:01 -0700304 if (sysfs_read(DCVS_CPU0_SLACK_MIN_NODE, tmp_str, NODE_MAX - 1)) {
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700305 if (!slack_node_rw_failed) {
Anurag Singh6ec12062012-10-02 09:59:01 -0700306 ALOGE("Failed to read from %s", DCVS_CPU0_SLACK_MIN_NODE);
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700307 }
308
309 rc = 1;
Anurag Singh6ec12062012-10-02 09:59:01 -0700310 } else {
311 saved_dcvs_cpu0_slack_min = atoi(tmp_str);
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700312 }
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700313
Anurag Singh6ec12062012-10-02 09:59:01 -0700314 if (sysfs_read(MPDECISION_SLACK_MAX_NODE, tmp_str, NODE_MAX - 1)) {
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700315 if (!slack_node_rw_failed) {
Anurag Singh6ec12062012-10-02 09:59:01 -0700316 ALOGE("Failed to read from %s", MPDECISION_SLACK_MAX_NODE);
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700317 }
318
319 rc = 1;
Anurag Singh6ec12062012-10-02 09:59:01 -0700320 } else {
321 saved_mpdecision_slack_max = atoi(tmp_str);
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700322 }
323
Anurag Singh6ec12062012-10-02 09:59:01 -0700324 if (sysfs_read(MPDECISION_SLACK_MIN_NODE, tmp_str, NODE_MAX - 1)) {
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700325 if(!slack_node_rw_failed) {
Anurag Singh6ec12062012-10-02 09:59:01 -0700326 ALOGE("Failed to read from %s", MPDECISION_SLACK_MIN_NODE);
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700327 }
328
329 rc = 1;
Anurag Singh6ec12062012-10-02 09:59:01 -0700330 } else {
331 saved_mpdecision_slack_min = atoi(tmp_str);
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700332 }
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700333
Anurag Singh6ec12062012-10-02 09:59:01 -0700334 /* Write new values. */
335 if (saved_dcvs_cpu0_slack_max != -1) {
336 snprintf(tmp_str, NODE_MAX, "%d", 10 * saved_dcvs_cpu0_slack_max);
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700337
Anurag Singh6ec12062012-10-02 09:59:01 -0700338 if (sysfs_write(DCVS_CPU0_SLACK_MAX_NODE, tmp_str) != 0) {
339 if (!slack_node_rw_failed) {
340 ALOGE("Failed to write to %s", DCVS_CPU0_SLACK_MAX_NODE);
341 }
342
343 rc = 1;
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700344 }
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700345 }
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700346
Anurag Singh4ce3b942012-12-14 10:23:03 -0800347 if (saved_dcvs_cpu0_slack_min != -1) {
Anurag Singh6ec12062012-10-02 09:59:01 -0700348 snprintf(tmp_str, NODE_MAX, "%d", 10 * saved_dcvs_cpu0_slack_min);
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700349
Anurag Singh6ec12062012-10-02 09:59:01 -0700350 if (sysfs_write(DCVS_CPU0_SLACK_MIN_NODE, tmp_str) != 0) {
351 if(!slack_node_rw_failed) {
352 ALOGE("Failed to write to %s", DCVS_CPU0_SLACK_MIN_NODE);
353 }
354
355 rc = 1;
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700356 }
Anurag Singh6ec12062012-10-02 09:59:01 -0700357 }
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700358
Anurag Singh6ec12062012-10-02 09:59:01 -0700359 if (saved_mpdecision_slack_max != -1) {
360 snprintf(tmp_str, NODE_MAX, "%d", 10 * saved_mpdecision_slack_max);
361
362 if (sysfs_write(MPDECISION_SLACK_MAX_NODE, tmp_str) != 0) {
363 if(!slack_node_rw_failed) {
364 ALOGE("Failed to write to %s", MPDECISION_SLACK_MAX_NODE);
365 }
366
367 rc = 1;
368 }
369 }
370
371 if (saved_mpdecision_slack_min != -1) {
372 snprintf(tmp_str, NODE_MAX, "%d", 10 * saved_mpdecision_slack_min);
373
374 if (sysfs_write(MPDECISION_SLACK_MIN_NODE, tmp_str) != 0) {
375 if(!slack_node_rw_failed) {
376 ALOGE("Failed to write to %s", MPDECISION_SLACK_MIN_NODE);
377 }
378
379 rc = 1;
380 }
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700381 }
382 }
Anurag Singh6ec12062012-10-02 09:59:01 -0700383
384 slack_node_rw_failed = rc;
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700385 }
Anurag Singh6ec12062012-10-02 09:59:01 -0700386 } else {
387 /* Display on. */
Anurag Singh4ce3b942012-12-14 10:23:03 -0800388 if ((strncmp(governor, ONDEMAND_GOVERNOR, strlen(ONDEMAND_GOVERNOR)) == 0) &&
389 (strlen(governor) == strlen(ONDEMAND_GOVERNOR))) {
Anurag Singh10918c12012-11-09 17:35:20 -0800390 undo_hint_action(DISPLAY_STATE_HINT_ID);
Anurag Singhb15323a2013-06-08 16:55:44 -0700391 display_hint_sent = 0;
Anurag Singh4ce3b942012-12-14 10:23:03 -0800392 } else if ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) &&
393 (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) {
Anurag Singh6ec12062012-10-02 09:59:01 -0700394 undo_hint_action(DISPLAY_STATE_HINT_ID);
Anurag Singhb15323a2013-06-08 16:55:44 -0700395 display_hint_sent = 0;
Anurag Singh4ce3b942012-12-14 10:23:03 -0800396 } else if ((strncmp(governor, MSMDCVS_GOVERNOR, strlen(MSMDCVS_GOVERNOR)) == 0) &&
397 (strlen(governor) == strlen(MSMDCVS_GOVERNOR))) {
Anurag Singh6ec12062012-10-02 09:59:01 -0700398 if (saved_interactive_mode == -1 || saved_interactive_mode == 0) {
399 /* Display turned on. Restore if possible. */
400 if (saved_dcvs_cpu0_slack_max != -1) {
401 snprintf(tmp_str, NODE_MAX, "%d", saved_dcvs_cpu0_slack_max);
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700402
Anurag Singh6ec12062012-10-02 09:59:01 -0700403 if (sysfs_write(DCVS_CPU0_SLACK_MAX_NODE, tmp_str) != 0) {
404 if (!slack_node_rw_failed) {
405 ALOGE("Failed to write to %s", DCVS_CPU0_SLACK_MAX_NODE);
406 }
407
408 rc = 1;
409 }
410 }
411
Anurag Singh4ce3b942012-12-14 10:23:03 -0800412 if (saved_dcvs_cpu0_slack_min != -1) {
Anurag Singh6ec12062012-10-02 09:59:01 -0700413 snprintf(tmp_str, NODE_MAX, "%d", saved_dcvs_cpu0_slack_min);
414
415 if (sysfs_write(DCVS_CPU0_SLACK_MIN_NODE, tmp_str) != 0) {
416 if (!slack_node_rw_failed) {
417 ALOGE("Failed to write to %s", DCVS_CPU0_SLACK_MIN_NODE);
418 }
419
420 rc = 1;
421 }
422 }
423
424 if (saved_mpdecision_slack_max != -1) {
425 snprintf(tmp_str, NODE_MAX, "%d", saved_mpdecision_slack_max);
426
427 if (sysfs_write(MPDECISION_SLACK_MAX_NODE, tmp_str) != 0) {
428 if (!slack_node_rw_failed) {
429 ALOGE("Failed to write to %s", MPDECISION_SLACK_MAX_NODE);
430 }
431
432 rc = 1;
433 }
434 }
435
436 if (saved_mpdecision_slack_min != -1) {
437 snprintf(tmp_str, NODE_MAX, "%d", saved_mpdecision_slack_min);
438
439 if (sysfs_write(MPDECISION_SLACK_MIN_NODE, tmp_str) != 0) {
440 if (!slack_node_rw_failed) {
441 ALOGE("Failed to write to %s", MPDECISION_SLACK_MIN_NODE);
442 }
443
444 rc = 1;
445 }
446 }
447 }
448
449 slack_node_rw_failed = rc;
450 }
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700451 }
452
453 saved_interactive_mode = !!on;
Anurag Singh9cec85b2012-09-04 21:46:24 -0700454}
455
Ananth Raghavan Subramanian65a6a062017-03-21 16:26:20 -0700456static int power_device_open(const hw_module_t* module, const char* name,
457 hw_device_t** device)
458{
459 int status = -EINVAL;
460 if (module && name && device) {
461 if (!strcmp(name, POWER_HARDWARE_MODULE_ID)) {
462 power_module_t *dev = (power_module_t *)malloc(sizeof(*dev));
Ananth Raghavan Subramanian65a6a062017-03-21 16:26:20 -0700463
464 if(dev) {
Ananth Raghavan Subramaniand427e352017-07-19 20:26:49 -0700465 memset(dev, 0, sizeof(*dev));
466
467 if(dev) {
468 /* initialize the fields */
469 dev->common.module_api_version = POWER_MODULE_API_VERSION_0_2;
470 dev->common.tag = HARDWARE_DEVICE_TAG;
471 dev->init = power_init;
472 dev->powerHint = power_hint;
473 dev->setInteractive = set_interactive;
474 /* At the moment we support 0.2 APIs */
475 dev->setFeature = NULL,
476 dev->get_number_of_platform_modes = NULL,
477 dev->get_platform_low_power_stats = NULL,
478 dev->get_voter_list = NULL,
479 *device = (hw_device_t*)dev;
480 status = 0;
481 } else {
482 status = -ENOMEM;
483 }
484 }
485 else {
Ananth Raghavan Subramanian65a6a062017-03-21 16:26:20 -0700486 status = -ENOMEM;
487 }
488 }
489 }
490
491 return status;
492}
493
Anurag Singh9cec85b2012-09-04 21:46:24 -0700494struct power_module HAL_MODULE_INFO_SYM = {
495 .common = {
496 .tag = HARDWARE_MODULE_TAG,
497 .module_api_version = POWER_MODULE_API_VERSION_0_2,
498 .hal_api_version = HARDWARE_HAL_API_VERSION,
499 .id = POWER_HARDWARE_MODULE_ID,
500 .name = "QCOM Power HAL",
501 .author = "Qualcomm",
502 .methods = &power_module_methods,
503 },
504
505 .init = power_init,
506 .powerHint = power_hint,
507 .setInteractive = set_interactive,
508};