diff options
| author | GUI <[email protected]> | 2024-05-30 15:30:40 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-05-30 15:30:40 +0800 |
| commit | e7cddf3a5275937b38f95afa7540fcc3fc7e5354 (patch) | |
| tree | 25bb3a1597a0118585e994e29286dc4734401486 /components/drivers/ofw | |
| parent | 2cbe8bdae01cdd2d8fc0c55f363a94f13fb11a47 (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.c | 87 |
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; |
