resource: Operate based on resource id
[platform/core/system/pass.git] / src / resource / resource-bus.c
1 /*
2  * PASS (Power Aware System Service) - Memory Bus Resource Driver
3  *
4  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
5  *
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
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  */
18
19 /**
20  * @file        resource-bus.c
21  * @brief       TBD
22  * @ingroup     TBD
23  */
24
25 #include <glib.h>
26
27 #include <hal/hal-power.h>
28
29 #include <util/common.h>
30 #include <util/devices.h>
31 #include <util/log.h>
32 #include <libsyscommon/resource-manager.h>
33 #include <libsyscommon/resource-type.h>
34 #include <libsyscommon/resource-device.h>
35
36 #include <resource-monitor/resource-monitor.h>
37
38 struct bus_context {
39         char *device_name;
40         int index;
41 };
42
43 static int bus_get_value_from_hal_power(int resource_id,
44                                 const struct syscommon_resman_resource_attribute *attr,
45                                 void *data)
46 {
47         struct bus_context *ctx;
48         int type;
49         int *val = (int *)data;
50         int _val;
51
52         if (resource_id < 0 || !attr || !data)
53                 return -EINVAL;
54
55         ctx = syscommon_resman_get_resource_privdata(resource_id);
56         if (!ctx)
57                 return -EINVAL;
58
59         if (!ctx->device_name) {
60                 _E("%s: BUS_CTRL_DEVICE_ID is not yet initialized\n",
61                                         syscommon_resman_get_resource_name(resource_id));
62                 return -EINVAL;
63         }
64
65         type = syscommon_resman_get_resource_type(resource_id);
66
67         switch (attr->id) {
68         case BUS_ATTR_CUR_FREQ:
69                 _val = hal_power_dvfs_get_curr_freq(type, ctx->device_name);
70                 break;
71         case BUS_ATTR_MIN_FREQ:
72                 _val = hal_power_dvfs_get_min_freq(type, ctx->device_name);
73                 break;
74         case BUS_ATTR_MAX_FREQ:
75                 _val = hal_power_dvfs_get_max_freq(type, ctx->device_name);
76                 break;
77         case BUS_ATTR_AVAILABLE_MIN_FREQ:
78                 _val = hal_power_dvfs_get_available_min_freq(type, ctx->device_name);
79                 break;
80         case BUS_ATTR_AVAILABLE_MAX_FREQ:
81                 _val = hal_power_dvfs_get_available_max_freq(type, ctx->device_name);
82                 break;
83         default:
84                 return -EINVAL;
85         }
86
87         if (_val < 0)
88                 return -EINVAL;
89
90         *val = _val;
91
92         return 0;
93 }
94
95 static int bus_get_string_value(int resource_id,
96                                 const struct syscommon_resman_resource_attribute *attr,
97                                 void *data)
98 {
99         struct bus_context *ctx;
100         char *buf = (char *)data;
101         int val;
102
103         if (resource_id < 0 || !attr || !data)
104                 return -EINVAL;
105
106         ctx = syscommon_resman_get_resource_privdata(resource_id);
107         if (!ctx)
108                 return -EINVAL;
109
110         if (!ctx->device_name) {
111                 _E("%s: BUS_CTRL_DEVICE_ID is not yet initialized\n",
112                                         syscommon_resman_get_resource_name(resource_id));
113                 return -EINVAL;
114         }
115
116         switch (attr->id) {
117         case BUS_ATTR_CUR_GOVERNOR:
118                 val = hal_power_dvfs_get_curr_governor(syscommon_resman_get_resource_type(resource_id),
119                                                         ctx->device_name, buf);
120                 if (val < 0)
121                         return -EINVAL;
122                 break;
123         case BUS_ATTR_NAME:
124                 strncpy(buf, ctx->device_name, BUFF_MAX);
125                 break;
126         }
127
128         return 0;
129 }
130
131 static const struct syscommon_resman_resource_attribute bus_attrs[] = {
132         {
133                 .name   = "BUS_ATTR_CUR_FREQ",
134                 .id     = BUS_ATTR_CUR_FREQ,
135                 .type   = SYSCOMMON_RESMAN_DATA_TYPE_INT,
136                 .flag   = SYSCOMMON_RESMAN_RESOURCE_ATTR_FLAG_PUBLIC,
137                 .ops    = {
138                         .get = bus_get_value_from_hal_power,
139                 },
140         }, {
141                 .name   = "BUS_ATTR_MIN_FREQ",
142                 .id     = BUS_ATTR_MIN_FREQ,
143                 .type   = SYSCOMMON_RESMAN_DATA_TYPE_INT,
144                 .flag   = SYSCOMMON_RESMAN_RESOURCE_ATTR_FLAG_PUBLIC,
145                 .ops    = {
146                         .get = bus_get_value_from_hal_power,
147                 },
148         }, {
149                 .name   = "BUS_ATTR_MAX_FREQ",
150                 .id     = BUS_ATTR_MAX_FREQ,
151                 .type   = SYSCOMMON_RESMAN_DATA_TYPE_INT,
152                 .flag   = SYSCOMMON_RESMAN_RESOURCE_ATTR_FLAG_PUBLIC,
153                 .ops    = {
154                         .get = bus_get_value_from_hal_power,
155                 }
156         }, {
157                 .name   = "BUS_ATTR_AVAILABLE_MIN_FREQ",
158                 .id     = BUS_ATTR_AVAILABLE_MIN_FREQ,
159                 .type   = SYSCOMMON_RESMAN_DATA_TYPE_INT,
160                 .flag   = SYSCOMMON_RESMAN_RESOURCE_ATTR_FLAG_PUBLIC,
161                 .ops    = {
162                         .get = bus_get_value_from_hal_power,
163                 }
164         }, {
165                 .name   = "BUS_ATTR_AVAILABLE_MAX_FREQ",
166                 .id     = BUS_ATTR_AVAILABLE_MAX_FREQ,
167                 .type   = SYSCOMMON_RESMAN_DATA_TYPE_INT,
168                 .flag   = SYSCOMMON_RESMAN_RESOURCE_ATTR_FLAG_PUBLIC,
169                 .ops    = {
170                         .get = bus_get_value_from_hal_power,
171                 }
172         }, {
173                 .name   = "BUS_ATTR_CUR_GOVERNOR",
174                 .id     = BUS_ATTR_CUR_GOVERNOR,
175                 .type   = SYSCOMMON_RESMAN_DATA_TYPE_STRING,
176                 .flag   = SYSCOMMON_RESMAN_RESOURCE_ATTR_FLAG_PUBLIC,
177                 .ops    = {
178                         .get = bus_get_string_value,
179                 }
180         }, {
181                 .name   = "BUS_ATTR_NAME",
182                 .id     = BUS_ATTR_NAME,
183                 .type   = SYSCOMMON_RESMAN_DATA_TYPE_STRING,
184                 .flag   = SYSCOMMON_RESMAN_RESOURCE_ATTR_FLAG_PUBLIC,
185                 .ops    = {
186                         .get = bus_get_string_value,
187                 }
188         },
189 };
190
191 static int bus_setup_device_id(int resource_id,
192                                 const struct syscommon_resman_resource_control *ctrl,
193                                 const void *data)
194 {
195         struct bus_context *ctx;
196         const struct syscommon_resman_resource_device *device;
197         int device_id = (int)(intptr_t)data;
198
199         if (resource_id < 0 || !ctrl)
200                 return -EINVAL;
201
202         ctx = syscommon_resman_get_resource_privdata(resource_id);
203         if (!ctx)
204                 return -EINVAL;
205
206         device = syscommon_resman_find_resource_device(syscommon_resman_get_resource_type(resource_id), device_id);
207         if (!device) {
208                 _E("Not available resource: type: %s, index: %d\n",
209                                 syscommon_resman_get_resource_name(resource_id), device_id);
210                 return -EINVAL;
211         }
212
213         if (ctx->device_name)
214                 free(ctx->device_name);
215
216         ctx->device_name = g_strdup(device->name);
217         ctx->index = device_id;
218
219         return 0;
220 }
221
222 static const struct syscommon_resman_resource_control bus_ctrls[] = {
223         {
224                 .name = "BUS_CTRL_DEVICE_ID",
225                 .id = BUS_CTRL_DEVICE_ID,
226                 .ops = {
227                         .set = bus_setup_device_id,
228                 },
229         },
230 };
231
232 static int bus_create(int resource_id)
233 {
234         struct bus_context *ctx;
235
236         ctx = calloc(1, sizeof(struct bus_context));
237         if (!ctx)
238                 return -ENOMEM;
239
240         syscommon_resman_set_resource_privdata(resource_id, ctx);
241
242         return 0;
243 }
244
245 static void bus_delete(int resource_id)
246 {
247         struct bus_context *ctx;
248
249         if (resource_id < 0)
250                 return;
251
252         ctx = syscommon_resman_get_resource_privdata(resource_id);
253         if (!ctx)
254                 return;
255
256         if (ctx->device_name) {
257                 free(ctx->device_name);
258                 ctx->device_name = NULL;
259         }
260         free(ctx);
261         syscommon_resman_set_resource_privdata(resource_id, NULL);
262 }
263
264 static const struct syscommon_resman_resource_driver bus_resource_driver = {
265         .name           = "BUS",
266         .type           = RESOURCE_TYPE_BUS,
267         .attrs          = bus_attrs,
268         .num_attrs      = ARRAY_SIZE(bus_attrs),
269         .ctrls          = bus_ctrls,
270         .num_ctrls      = ARRAY_SIZE(bus_ctrls),
271         .ops            = {
272                 .create = bus_create,
273                 .delete = bus_delete,
274         },
275 };
276 SYSCOMMON_RESMAN_RESOURCE_DRIVER_REGISTER(&bus_resource_driver)