2 * PASS (Power Aware System Service) - CPU Resource Driver
4 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the License);
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
20 * @file resource-cpu.c
27 #include <hal/hal-power.h>
29 #include <util/common.h>
30 #include <util/devices.h>
33 #include <libsyscommon/resource-manager.h>
34 #include <libsyscommon/resource-type.h>
35 #include <libsyscommon/resource-device.h>
37 #include <resource-monitor/resource-monitor.h>
44 static int cpu_get_value_from_hal_power(struct syscommon_resman_resource *res,
45 const struct syscommon_resman_resource_attribute *attr,
48 struct cpu_context *ctx;
49 int *val = (int *)data;
52 if (!res || !attr || !data)
55 ctx = syscommon_resman_get_resource_privdata(res);
59 if (!ctx->device_name) {
60 _E("%s: CPU_CTRL_CLUSTER_ID is not yet initialized\n",
61 syscommon_resman_get_resource_name(res));
65 type = syscommon_resman_get_resource_type(res);
68 case CPU_ATTR_CUR_FREQ:
69 _val = hal_power_dvfs_get_curr_freq(type, ctx->device_name);
71 case CPU_ATTR_MIN_FREQ:
72 _val = hal_power_dvfs_get_min_freq(type, ctx->device_name);
74 case CPU_ATTR_MAX_FREQ:
75 _val = hal_power_dvfs_get_max_freq(type, ctx->device_name);
77 case CPU_ATTR_AVAILABLE_MIN_FREQ:
78 _val = hal_power_dvfs_get_available_min_freq(type, ctx->device_name);
80 case CPU_ATTR_AVAILABLE_MAX_FREQ:
81 _val = hal_power_dvfs_get_available_max_freq(type, ctx->device_name);
95 static int cpu_get_string_value(struct syscommon_resman_resource *res,
96 const struct syscommon_resman_resource_attribute *attr,
99 struct cpu_context *ctx;
100 char *buf = (char *)data;
103 if (!res || !attr || !data)
106 ctx = syscommon_resman_get_resource_privdata(res);
110 if (!ctx->device_name) {
111 _E("%s: CPU_CTRL_CLUSTER_ID is not yet initialized\n",
112 syscommon_resman_get_resource_name(res));
117 case CPU_ATTR_CUR_GOVERNOR:
118 val = hal_power_dvfs_get_curr_governor(syscommon_resman_get_resource_type(res),
119 ctx->device_name, buf);
124 strncpy(buf, ctx->device_name, BUFF_MAX);
131 static const struct syscommon_resman_resource_attribute cpu_attrs[] = {
133 .name = "CPU_ATTR_CUR_FREQ",
134 .id = CPU_ATTR_CUR_FREQ,
135 .type = SYSCOMMON_RESMAN_DATA_TYPE_INT,
136 .flag = SYSCOMMON_RESMAN_RESOURCE_ATTR_FLAG_PUBLIC,
138 .get = cpu_get_value_from_hal_power,
141 .name = "CPU_ATTR_MIN_FREQ",
142 .id = CPU_ATTR_MIN_FREQ,
143 .type = SYSCOMMON_RESMAN_DATA_TYPE_INT,
144 .flag = SYSCOMMON_RESMAN_RESOURCE_ATTR_FLAG_PUBLIC,
146 .get = cpu_get_value_from_hal_power,
149 .name = "CPU_ATTR_MAX_FREQ",
150 .id = CPU_ATTR_MAX_FREQ,
151 .type = SYSCOMMON_RESMAN_DATA_TYPE_INT,
152 .flag = SYSCOMMON_RESMAN_RESOURCE_ATTR_FLAG_PUBLIC,
154 .get = cpu_get_value_from_hal_power,
157 .name = "CPU_ATTR_AVAILABLE_MIN_FREQ",
158 .id = CPU_ATTR_AVAILABLE_MIN_FREQ,
159 .type = SYSCOMMON_RESMAN_DATA_TYPE_INT,
160 .flag = SYSCOMMON_RESMAN_RESOURCE_ATTR_FLAG_PUBLIC,
162 .get = cpu_get_value_from_hal_power,
165 .name = "CPU_ATTR_AVAILABLE_MAX_FREQ",
166 .id = CPU_ATTR_AVAILABLE_MAX_FREQ,
167 .type = SYSCOMMON_RESMAN_DATA_TYPE_INT,
168 .flag = SYSCOMMON_RESMAN_RESOURCE_ATTR_FLAG_PUBLIC,
170 .get = cpu_get_value_from_hal_power,
173 .name = "CPU_ATTR_CUR_GOVERNOR",
174 .id = CPU_ATTR_CUR_GOVERNOR,
175 .type = SYSCOMMON_RESMAN_DATA_TYPE_STRING,
176 .flag = SYSCOMMON_RESMAN_RESOURCE_ATTR_FLAG_PUBLIC,
178 .get = cpu_get_string_value,
181 .name = "CPU_ATTR_NAME",
183 .type = SYSCOMMON_RESMAN_DATA_TYPE_STRING,
184 .flag = SYSCOMMON_RESMAN_RESOURCE_ATTR_FLAG_PUBLIC,
186 .get = cpu_get_string_value,
191 static int cpu_setup_cluster_id(struct syscommon_resman_resource *res,
192 const struct syscommon_resman_resource_control *ctrl,
195 struct cpu_context *ctx;
196 const struct syscommon_resman_resource_device *device;
197 int resource_index = (int)(intptr_t)data;
202 ctx = syscommon_resman_get_resource_privdata(res);
206 device = syscommon_resman_find_resource_device(syscommon_resman_get_resource_type(res), resource_index);
208 _E("Not available resource: type: %s, index: %d\n",
209 syscommon_resman_get_resource_name(res), resource_index);
213 if (ctx->device_name)
214 free(ctx->device_name);
216 ctx->device_name = g_strdup(device->name);
217 ctx->index = resource_index;
222 static const struct syscommon_resman_resource_control cpu_ctrls[] = {
224 .name = "CPU_CTRL_CLUSTER_ID",
225 .id = CPU_CTRL_CLUSTER_ID,
227 .set = cpu_setup_cluster_id,
232 static int cpu_create(struct syscommon_resman_resource *res)
234 struct cpu_context *ctx = syscommon_resman_get_resource_privdata(res);
236 ctx = calloc(1, sizeof(struct cpu_context));
240 syscommon_resman_set_resource_privdata(res, ctx);
245 static void cpu_delete(struct syscommon_resman_resource *res)
247 struct cpu_context *ctx;
252 ctx = syscommon_resman_get_resource_privdata(res);
256 if (ctx->device_name) {
257 free(ctx->device_name);
258 ctx->device_name = NULL;
262 syscommon_resman_set_resource_privdata(res, NULL);
265 static const struct syscommon_resman_resource_driver cpu_resource_driver = {
267 .type = RESOURCE_TYPE_CPU,
269 .num_attrs = ARRAY_SIZE(cpu_attrs),
271 .num_ctrls = ARRAY_SIZE(cpu_ctrls),
273 .create = cpu_create,
274 .delete = cpu_delete,
277 SYSCOMMON_RESMAN_RESOURCE_DRIVER_REGISTER(&cpu_resource_driver)