summaryrefslogtreecommitdiff
path: root/components/drivers/ofw
diff options
context:
space:
mode:
authorGUI <[email protected]>2024-05-30 15:30:40 +0800
committerGitHub <[email protected]>2024-05-30 15:30:40 +0800
commite7cddf3a5275937b38f95afa7540fcc3fc7e5354 (patch)
tree25bb3a1597a0118585e994e29286dc4734401486 /components/drivers/ofw
parent2cbe8bdae01cdd2d8fc0c55f363a94f13fb11a47 (diff)
[Feature] Support simple power domain API (#9005)
* [Feature] Power domain for device 1.Support device power on/off. 2.Support attach/detach device. 3.Support power domain driver api. Signed-off-by: GuEe-GUI <[email protected]> * [DM/platform] Enhanced platform bus 1.Add power domain for device. 2.Support `remove` and `shutdown` bus interface. Signed-off-by: GuEe-GUI <[email protected]> --------- Signed-off-by: GuEe-GUI <[email protected]>
Diffstat (limited to 'components/drivers/ofw')
-rw-r--r--components/drivers/ofw/ofw.c87
1 files changed, 87 insertions, 0 deletions
diff --git a/components/drivers/ofw/ofw.c b/components/drivers/ofw/ofw.c
index 1f30bd98f9..d09fb4e7ca 100644
--- a/components/drivers/ofw/ofw.c
+++ b/components/drivers/ofw/ofw.c
@@ -60,6 +60,93 @@ struct rt_ofw_stub *rt_ofw_stub_probe_range(struct rt_ofw_node *np,
return (struct rt_ofw_stub *)stub;
}
+struct ofw_obj_cmp_list
+{
+ const char *cells_name;
+ const char *obj_name;
+ rt_size_t obj_size;
+};
+
+static const struct ofw_obj_cmp_list ofw_obj_cmp_list[] =
+{
+ { "#power-domain-cells", RT_POWER_DOMAIN_PROXY_OBJ_NAME, sizeof(struct rt_dm_power_domain_proxy) },
+ { "#power-domain-cells", RT_POWER_DOMAIN_OBJ_NAME, sizeof(struct rt_dm_power_domain) },
+};
+
+static struct rt_object *ofw_parse_object(struct rt_ofw_node *np, const char *cells_name)
+{
+ const struct ofw_obj_cmp_list *item;
+ struct rt_object *obj = rt_ofw_data(np), *ret_obj = RT_NULL;
+ RT_BITMAP_DECLARE(idx_mask, RT_ARRAY_SIZE(ofw_obj_cmp_list)) = {};
+
+ for (int i = 0; i < RT_ARRAY_SIZE(ofw_obj_cmp_list); ++i)
+ {
+ item = &ofw_obj_cmp_list[i];
+
+ if (!rt_ofw_prop_read_bool(np, item->cells_name))
+ {
+ rt_bitmap_set_bit(idx_mask, i);
+ }
+ }
+
+ while (!ret_obj)
+ {
+ int i = 0;
+
+ /* Is print ? */
+ if (!((rt_uint32_t)(obj->name[0] - 0x20) < 0x5f))
+ {
+ break;
+ }
+
+ rt_bitmap_for_each_clear_bit(idx_mask, i, RT_ARRAY_SIZE(ofw_obj_cmp_list))
+ {
+ item = &ofw_obj_cmp_list[i];
+
+ if (!rt_strcmp(item->cells_name, cells_name))
+ {
+ ret_obj = obj;
+ break;
+ }
+
+ if (!rt_strncmp(item->obj_name, obj->name, RT_NAME_MAX))
+ {
+ obj = (struct rt_object *)((rt_ubase_t)obj + item->obj_size);
+ break;
+ }
+ }
+
+ if (i >= RT_ARRAY_SIZE(ofw_obj_cmp_list))
+ {
+ LOG_E("Invalid rt_object = %s", obj->name);
+
+ break;
+ }
+ }
+
+ return ret_obj;
+}
+
+struct rt_object *rt_ofw_parse_object(struct rt_ofw_node *np, const char *obj_name, const char *cells_name)
+{
+ struct rt_object *obj = RT_NULL, *test_obj;
+
+ if (np && (test_obj = rt_ofw_data(np)) && cells_name)
+ {
+ /* The composite object is rare, so we try to find this object as much as possible at once. */
+ if (obj_name && rt_strcmp(test_obj->name, obj_name))
+ {
+ obj = test_obj;
+ }
+ else
+ {
+ obj = ofw_parse_object(np, cells_name);
+ }
+ }
+
+ return obj;
+}
+
static const char *ofw_console_serial_find(char *dst_con, struct rt_ofw_node *np)
{
rt_object_t rt_obj = RT_NULL;