4 * Copyright (c) 2023 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.
23 #include <libsyscommon/resource-manager.h>
24 #include <libsyscommon/resource-type.h>
25 #include <system/syscommon-plugin-deviced-power.h>
26 #include <system/syscommon-plugin-deviced-power-interface.h>
27 #include <system/syscommon-plugin-deviced-common-interface.h>
30 #include "power-suspend.h"
40 } resource_attr_data_t;
42 static int set_current_state(int resource_id, const struct syscommon_resman_resource_attribute *attr,
43 const void *data1, const void *data2, const void *data3, const void *data4,
44 int count1, int count2, int count3, int count4)
49 const void *user_data;
51 if (!data1 || !data2 || !data3 || !data4)
54 curr = *(uint64_t *) data1;
55 next = *(uint64_t *) data2;
56 reason = *(int *) data3;
57 user_data = *(const void **) data4;
59 power_request_change_state_strict(curr, next, reason, user_data);
64 static int set_tuple2_power_attr_data(int resource_id,
65 const struct syscommon_resman_resource_attribute *attr,
66 const void *data1, const void *data2, int count1, int count2)
72 case DEVICED_POWER_ATTR_TUPLE2_HISTORY_LOG:
74 enum syscommon_deviced_power_log_type type = *(enum syscommon_deviced_power_log_type *) data1;
75 int code = *(int *) data2;
77 pm_history_save(type, code);
90 static int get_power_attr_data(int resource_id,
91 const struct syscommon_resman_resource_attribute *attr, void *data)
94 resource_attr_data_t attr_data = { 0, };
100 case DEVICED_POWER_ATTR_UINT64_CURRENT_STATE:
102 attr_data.i32 = power_get_state();
105 case DEVICED_POWER_ATTR_INT_WAKEUP_REASON:
107 attr_data.i32 = power_get_wakeup_reason();
110 case DEVICED_POWER_ATTR_INT_VITAL_MODE:
112 attr_data.i32 = vital_mode();
123 switch (attr->type) {
124 case SYSCOMMON_RESMAN_DATA_TYPE_INT:
125 *(int32_t *) data = attr_data.i32;
127 case SYSCOMMON_RESMAN_DATA_TYPE_INT64:
128 *(int64_t *) data = attr_data.i64;
130 case SYSCOMMON_RESMAN_DATA_TYPE_UINT:
131 *(uint32_t *) data = attr_data.u32;
133 case SYSCOMMON_RESMAN_DATA_TYPE_UINT64:
134 *(uint64_t *) data = attr_data.u64;
136 case SYSCOMMON_RESMAN_DATA_TYPE_DOUBLE:
137 *(double *) data = attr_data.d;
139 case SYSCOMMON_RESMAN_DATA_TYPE_PTR:
140 *(void **) data = attr_data.p;
142 case SYSCOMMON_RESMAN_DATA_TYPE_BOOLEAN:
143 *(bool *) data = attr_data.b;
152 static int set_power_attr_data(int resource_id,
153 const struct syscommon_resman_resource_attribute *attr,
154 const void *data, int count)
160 case DEVICED_POWER_ATTR_INT_VITAL_MODE:
162 int mode = *(const int *) data;
163 vital_state_changed(mode);
174 * FIXME: After developing the power abstraction layer, this attribute should
175 * be fixed. Because the suspend-to-ram supports both echo-mem and wakelock
176 * style without any different external interface.
178 static int g_wakelock_counter;
179 static gboolean event_release_wakelock(gpointer data)
181 if (g_wakelock_counter < 0)
182 return G_SOURCE_REMOVE;
184 --g_wakelock_counter;
186 if (g_wakelock_counter == 0)
187 syscommon_notifier_emit_notify(DEVICED_NOTIFIER_EVENT_RELEASE_WAKELOCK, NULL);
189 return G_SOURCE_REMOVE;
192 static int set_wakelock(int resource_id, const struct syscommon_resman_resource_attribute *attr,
193 const void *data1, const void *data2, int count1, int count2)
198 if (!data1 || !data2)
201 event_id = *(uint64_t *) data1;
202 timeout = *(uint64_t *) data2;
207 ++g_wakelock_counter;
209 g_timeout_add_seconds(timeout, event_release_wakelock, (gpointer)(intptr_t) event_id);
211 if (g_wakelock_counter == 1)
212 syscommon_notifier_emit_notify(DEVICED_NOTIFIER_EVENT_ACQUIRE_WAKELOCK, NULL);
217 static const struct syscommon_resman_resource_attribute power_attrs[] = {
219 .name = "DEVICED_POWER_ATTR_UINT64_4_CURRENT_STATE",
220 .id = DEVICED_POWER_ATTR_UINT64_4_CURRENT_STATE,
221 .type = SYSCOMMON_RESMAN_DATA_TYPE_4_UINT64,
222 .flag = SYSCOMMON_RESMAN_RESOURCE_FLAG_PUBLIC,
224 .set_4_tuple = set_current_state,
225 .is_supported = syscommon_resman_resource_attr_supported_always,
228 .name = "DEVICED_POWER_ATTR_UINT64_CURRENT_STATE",
229 .id = DEVICED_POWER_ATTR_UINT64_CURRENT_STATE,
230 .type = SYSCOMMON_RESMAN_DATA_TYPE_UINT64,
231 .flag = SYSCOMMON_RESMAN_RESOURCE_FLAG_PUBLIC,
233 .get = get_power_attr_data,
234 .is_supported = syscommon_resman_resource_attr_supported_always,
237 .name = "DEVICED_POWER_ATTR_INT_WAKEUP_REASON",
238 .id = DEVICED_POWER_ATTR_INT_WAKEUP_REASON,
239 .type = SYSCOMMON_RESMAN_DATA_TYPE_INT,
240 .flag = SYSCOMMON_RESMAN_RESOURCE_FLAG_PUBLIC,
242 .get = get_power_attr_data,
243 .is_supported = syscommon_resman_resource_attr_supported_always,
246 .name = "DEVICED_POWER_ATTR_TUPLE2_WAKELOCK",
247 .id = DEVICED_POWER_ATTR_TUPLE2_WAKELOCK,
248 .type = SYSCOMMON_RESMAN_DATA_TYPE_2_UINT64,
249 .flag = SYSCOMMON_RESMAN_RESOURCE_FLAG_PUBLIC,
251 .set_2_tuple = set_wakelock,
252 .is_supported = syscommon_resman_resource_attr_supported_always,
255 .name = "DEVICED_POWER_ATTR_INT_VITAL_MODE",
256 .id = DEVICED_POWER_ATTR_INT_VITAL_MODE,
257 .type = SYSCOMMON_RESMAN_DATA_TYPE_INT,
258 .flag = SYSCOMMON_RESMAN_RESOURCE_FLAG_PUBLIC,
260 .get = get_power_attr_data,
261 .set = set_power_attr_data,
262 .is_supported = syscommon_resman_resource_attr_supported_always,
265 .name = "DEVICED_POWER_ATTR_TUPLE2_HISTORY_LOG",
266 .id = DEVICED_POWER_ATTR_TUPLE2_HISTORY_LOG,
267 .type = SYSCOMMON_RESMAN_DATA_TYPE_2_UINT64,
268 .flag = SYSCOMMON_RESMAN_RESOURCE_FLAG_PUBLIC,
270 .set_2_tuple = set_tuple2_power_attr_data,
271 .is_supported = syscommon_resman_resource_attr_supported_always,
276 static const struct syscommon_resman_resource_driver deviced_power_driver = {
278 .type = DEVICED_RESOURCE_TYPE_POWER,
279 .flag = SYSCOMMON_RESMAN_RESOURCE_DRIVER_FLAG_COUNT_ONLY_ONE,
280 .attrs = power_attrs,
281 .num_attrs = ARRAY_SIZE(power_attrs),
283 SYSCOMMON_RESMAN_RESOURCE_DRIVER_REGISTER(&deviced_power_driver);