Skip to content

[drivers][core] 完善设备模型 #8384

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
362 changes: 236 additions & 126 deletions components/drivers/core/bus.c

Large diffs are not rendered by default.

325 changes: 317 additions & 8 deletions components/drivers/core/dm.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
* Copyright (c) 2006-2024, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
Expand All @@ -10,6 +10,10 @@

#include <rtthread.h>

#ifdef RT_USING_OFW
#include <drivers/ofw_io.h>
#include <drivers/ofw_irq.h>
#endif
#include <drivers/core/dm.h>

#ifdef RT_USING_SMP
Expand Down Expand Up @@ -56,10 +60,10 @@ struct prefix_track
int uid;
const char *prefix;
};
static struct rt_spinlock _prefix_nodes_lock;
static struct rt_spinlock _prefix_nodes_lock = { 0 };
static rt_list_t _prefix_nodes = RT_LIST_OBJECT_INIT(_prefix_nodes);

int rt_dm_set_dev_name_auto(rt_device_t dev, const char *prefix)
int rt_dm_dev_set_name_auto(rt_device_t dev, const char *prefix)
{
int uid = -1;
struct prefix_track *pt = RT_NULL;
Expand Down Expand Up @@ -104,17 +108,17 @@ int rt_dm_set_dev_name_auto(rt_device_t dev, const char *prefix)
rt_spin_unlock(&_prefix_nodes_lock);
}

return rt_dm_set_dev_name(dev, "%s%u", prefix, uid);
return rt_dm_dev_set_name(dev, "%s%u", prefix, uid);
}

int rt_dm_get_dev_name_id(rt_device_t dev)
int rt_dm_dev_get_name_id(rt_device_t dev)
{
int id = 0, len;
const char *name;

RT_ASSERT(dev != RT_NULL);

name = rt_dm_get_dev_name(dev);
name = rt_dm_dev_get_name(dev);
len = rt_strlen(name) - 1;
name += len;

Expand All @@ -137,7 +141,7 @@ int rt_dm_get_dev_name_id(rt_device_t dev)
return id;
}

int rt_dm_set_dev_name(rt_device_t dev, const char *format, ...)
int rt_dm_dev_set_name(rt_device_t dev, const char *format, ...)
{
int n;
va_list arg_ptr;
Expand All @@ -152,9 +156,314 @@ int rt_dm_set_dev_name(rt_device_t dev, const char *format, ...)
return n;
}

const char *rt_dm_get_dev_name(rt_device_t dev)
const char *rt_dm_dev_get_name(rt_device_t dev)
{
RT_ASSERT(dev != RT_NULL);

return dev->parent.name;
}

#ifdef RT_USING_OFW
#define ofw_api_call(name, ...) rt_ofw_##name(__VA_ARGS__)
#define ofw_api_call_ptr(name, ...) ofw_api_call(name, __VA_ARGS__)
#else
#define ofw_api_call(name, ...) (-RT_ENOSYS)
#define ofw_api_call_ptr(name, ...) RT_NULL
#endif

int rt_dm_dev_get_address_count(rt_device_t dev)
{
RT_ASSERT(dev != RT_NULL);

#ifdef RT_USING_OFW
if (dev->ofw_node)
{
return ofw_api_call(get_address_count, dev->ofw_node);
}
#endif

return -RT_ENOSYS;
}

rt_err_t rt_dm_dev_get_address(rt_device_t dev, int index,
rt_uint64_t *out_address, rt_uint64_t *out_size)
{
RT_ASSERT(dev != RT_NULL);

#ifdef RT_USING_OFW
if (dev->ofw_node)
{
return ofw_api_call(get_address, dev->ofw_node, index,
out_address, out_size);
}
#endif

return -RT_ENOSYS;
}

rt_err_t rt_dm_dev_get_address_by_name(rt_device_t dev, const char *name,
rt_uint64_t *out_address, rt_uint64_t *out_size)
{
RT_ASSERT(dev != RT_NULL);

#ifdef RT_USING_OFW
if (dev->ofw_node)
{
return ofw_api_call(get_address_by_name, dev->ofw_node, name,
out_address, out_size);
}
#endif

return -RT_ENOSYS;
}

int rt_dm_dev_get_address_array(rt_device_t dev, int nr, rt_uint64_t *out_regs)
{
RT_ASSERT(dev != RT_NULL);

#ifdef RT_USING_OFW
if (dev->ofw_node)
{
return ofw_api_call(get_address_array, dev->ofw_node, nr, out_regs);
}
#endif

return -RT_ENOSYS;
}

void *rt_dm_dev_iomap(rt_device_t dev, int index)
{
RT_ASSERT(dev != RT_NULL);

#ifdef RT_USING_OFW
if (dev->ofw_node)
{
return ofw_api_call_ptr(iomap, dev->ofw_node, index);
}
#endif

return RT_NULL;
}

void *rt_dm_dev_iomap_by_name(rt_device_t dev, const char *name)
{
RT_ASSERT(dev != RT_NULL);

#ifdef RT_USING_OFW
if (dev->ofw_node)
{
return ofw_api_call_ptr(iomap_by_name, dev->ofw_node, name);
}
#endif

return RT_NULL;
}

int rt_dm_dev_get_irq_count(rt_device_t dev)
{
RT_ASSERT(dev != RT_NULL);

#ifdef RT_USING_OFW
if (dev->ofw_node)
{
return ofw_api_call(get_irq_count, dev->ofw_node);
}
#endif

return -RT_ENOSYS;
}

int rt_dm_dev_get_irq(rt_device_t dev, int index)
{
RT_ASSERT(dev != RT_NULL);

#ifdef RT_USING_OFW
if (dev->ofw_node)
{
return ofw_api_call(get_irq, dev->ofw_node, index);
}
#endif

return -RT_ENOSYS;
}

int rt_dm_dev_get_irq_by_name(rt_device_t dev, const char *name)
{
RT_ASSERT(dev != RT_NULL);

#ifdef RT_USING_OFW
if (dev->ofw_node)
{
return ofw_api_call(get_irq_by_name, dev->ofw_node, name);
}
#endif

return -RT_ENOSYS;
}

void rt_dm_dev_bind_fwdata(rt_device_t dev, void *fw_np, void *data)
{
RT_ASSERT(dev != RT_NULL);

#ifdef RT_USING_OFW
if (!dev->ofw_node && fw_np)
{
dev->ofw_node = fw_np;
rt_ofw_data(fw_np) = data;
}

if (dev->ofw_node == RT_NULL)
{
rt_kprintf("[%s:%s] line=%d ofw_node is NULL\r\n", __FILE__, __func__, __LINE__);
return;
}

rt_ofw_data(dev->ofw_node) = data;
#endif
}

void rt_dm_dev_unbind_fwdata(rt_device_t dev, void *fw_np)
{
RT_ASSERT(dev!= RT_NULL);

#ifdef RT_USING_OFW
void *dev_fw_np;

if (!dev->ofw_node && fw_np)
{
dev_fw_np = fw_np;
rt_ofw_data(fw_np) = RT_NULL;
}

if (dev_fw_np == RT_NULL)
{
rt_kprintf("[%s:%s] line=%d dev_fw_np is NULL\r\n", __FILE__, __func__, __LINE__);
return;
}

rt_ofw_data(dev_fw_np) = RT_NULL;
#endif
}

int rt_dm_dev_prop_read_u8_array_index(rt_device_t dev, const char *propname,
int index, int nr, rt_uint8_t *out_values)
{
RT_ASSERT(dev != RT_NULL);

#ifdef RT_UISNG_OFW
if (dev->ofw_node)
{
return ofw_api_call(prop_read_u8_array_index, dev->ofw_node, propname,
index, nr, out_value);
}
#endif

return -RT_ENOSYS;
}

int rt_dm_dev_prop_read_u16_array_index(rt_device_t dev, const char *propname,
int index, int nr, rt_uint16_t *out_values)
{
RT_ASSERT(dev != RT_NULL);

#ifdef RT_USING_OFW
if (dev->ofw_node)
{
return ofw_api_call(prop_read_u16_array_index, dev->ofw_node, propname,
index, nr, out_values);
}
#endif

return -RT_ENOSYS;
}

int rt_dm_dev_prop_read_u32_array_index(rt_device_t dev, const char *propname,
int index, int nr, rt_uint32_t *out_values)
{
RT_ASSERT(dev != RT_NULL);

#ifdef RT_USING_OFW
if (dev->ofw_node)
{
return ofw_api_call(prop_read_u32_array_index, dev->ofw_node, propname,
index, nr, out_values);
}
#endif

return -RT_ENOSYS;
}

int rt_dm_dev_prop_read_u64_array_index(rt_device_t dev, const char *propname,
int index, int nr, rt_uint64_t *out_values)
{
RT_ASSERT(dev != RT_NULL);

#ifdef RT_USING_OFW
if (dev->ofw_node)
{
return ofw_api_call(prop_read_u64_array_index, dev->ofw_node, propname,
index, nr, out_values);
}
#endif

return -RT_ENOSYS;
}

int rt_dm_dev_prop_read_string_array_index(rt_device_t dev, const char *propname,
int index, int nr, const char **out_strings)
{
RT_ASSERT(dev != RT_NULL);

#ifdef RT_USING_OFW
if (dev->ofw_node)
{
return ofw_api_call(prop_read_string_array_index, dev->ofw_node, propname,
index, nr, out_strings);
}
#endif

return -RT_ENOSYS;
}

int rt_dm_dev_prop_count_of_size(rt_device_t dev, const char *propname, int size)
{
RT_ASSERT(dev != RT_NULL);

#ifdef RT_USING_OFW
if (dev->ofw_node)
{
return ofw_api_call(prop_count_of_size, dev->ofw_node, propname, size);
}
#endif

return -RT_ENOSYS;
}

int rt_dm_dev_prop_index_of_string(rt_device_t dev, const char *propname, const char *string)
{
RT_ASSERT(dev != RT_NULL);

#ifdef RT_USING_OFW
if (dev->ofw_node)
{
return ofw_api_call(prop_index_of_string, dev->ofw_node, propname, string);
}
#endif

return -RT_ENOSYS;
}

rt_bool_t rt_dm_dev_prop_read_bool(rt_device_t dev, const char *propname)
{
RT_ASSERT(dev != RT_NULL);

#ifdef RT_USING_OFW
if (dev->ofw_node)
{
return ofw_api_call(prop_read_bool, dev->ofw_node, propname);
}
#endif

return RT_FALSE;
}

Loading