OSDN Git Service

Allow to disable offlining of non-boot CPUs
[android-x86/hardware-x86power.git] / power.c
1 /*
2  *
3  * Copyright (C) 2016 The Android-x86 Open Source Project
4  *
5  * Licensed under the GNU General Public License Version 2 or later.
6  * You may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.gnu.org/licenses/gpl.html
10  *
11  *
12  */
13 #include <errno.h>
14 #include <string.h>
15 #include <sys/types.h>
16 #include <sys/stat.h>
17 #include <fcntl.h>
18
19 #define LOG_TAG "PowerHAL"
20 #include <utils/Log.h>
21
22 #include <hardware/hardware.h>
23 #include <hardware/power.h>
24 #include <cutils/properties.h>
25 #include <cutils/probe_module.h>
26
27 extern int delete_module(const char *, unsigned int);
28
29 #define SYS_CPU "/sys/devices/system/cpu"
30 #define CPU_ONLINE "1"
31 #define CPU_OFFLINE "0"
32
33 #define UNUSED __attribute__((__unused__))
34
35 static void set_nonboot_cpu_state(const char *state)
36 {
37     static int cpu_n_fd;
38     char p[PATH_MAX];
39     int cpu_n;
40
41     for (cpu_n = 1; ; cpu_n++) {
42         snprintf(p, PATH_MAX, SYS_CPU "/cpu%d/online", cpu_n);
43         cpu_n_fd = open(p, O_RDWR);
44         if (cpu_n_fd < 0) {
45             return;
46         }
47         ALOGV("Set CPU%d_online state %s ", cpu_n, state);
48         write(cpu_n_fd, state, 1);
49         close(cpu_n_fd);
50     }
51 }
52
53 static void power_init(struct power_module *module UNUSED)
54 {
55 }
56
57 static void power_set_interactive(struct power_module *module UNUSED, int on)
58 {
59     char mod[PROPERTY_VALUE_MAX];
60     if (!property_get_bool("wlan.no-unload-driver", 0)
61             && property_get("wlan.modname", mod, NULL)) {
62         if (on) {
63             if (insmod_by_dep(mod, "", NULL, 0, NULL)) {
64                 ALOGE("insmod %s failed", mod);
65             } else {
66                 ALOGD("reload %s OK", mod);
67             }
68         } else {
69             if (delete_module(mod, O_NONBLOCK)) {
70                 ALOGE("rmmod %s failed", mod);
71             } else {
72                 ALOGD("unload %s OK", mod);
73             }
74         }
75     }
76
77     if (property_get_bool("power.nonboot-cpu-off", 1)) {
78         set_nonboot_cpu_state(on ? CPU_ONLINE : CPU_OFFLINE);
79     }
80 }
81
82 static void power_hint(struct power_module *module UNUSED, power_hint_t hint, void *data UNUSED)
83 {
84     switch (hint) {
85     default:
86         break;
87     }
88 }
89
90 static struct hw_module_methods_t power_module_methods = {
91     .open = NULL,
92 };
93
94 struct power_module HAL_MODULE_INFO_SYM = {
95     .common = {
96         .tag = HARDWARE_MODULE_TAG,
97         .module_api_version = POWER_MODULE_API_VERSION_0_2,
98         .hal_api_version = HARDWARE_HAL_API_VERSION,
99         .id = POWER_HARDWARE_MODULE_ID,
100         .name = "x86 Power HAL",
101         .author = "The Android-x86 Project",
102         .methods = &power_module_methods,
103     },
104
105     .init = power_init,
106     .setInteractive = power_set_interactive,
107     .powerHint = power_hint,
108 };