[components][drivers]legacy fdt (#9062)

* legacy fdt

* update fdt
This commit is contained in:
zms123456
2024-06-19 19:48:35 +08:00
committed by GitHub
parent 7250301d3e
commit 3b1ce1e4b6
36 changed files with 379 additions and 217 deletions
-1
View File
@@ -30,6 +30,5 @@ rsource "ktime/Kconfig"
rsource "clk/Kconfig"
rsource "hwtimer/Kconfig"
rsource "usb/Kconfig"
rsource "fdt/Kconfig"
endmenu
View File
File diff suppressed because it is too large Load Diff
+15
View File
@@ -0,0 +1,15 @@
config RT_USING_FDT
bool "Using fdt legacy version"
default n
if RT_USING_FDT
config RT_USING_FDTLIB
bool "Using fdt lib for device drivers"
default y
config RT_USING_FDT_FWNODE
bool "Using fdt fwnode for device drivers"
default n
config FDT_USING_DEBUG
bool "Using fdt debug function "
default n
endif
+125
View File
@@ -0,0 +1,125 @@
#ifndef __DTB_FWNODE_H__
#define __DTB_FWNODE_H__
#include "libfdt_env.h"
#include <rtthread.h>
#include <stdint.h>
#include <stdbool.h>
struct fwnode_operations;
struct rt_device;
#define FWNODE_FLAG_LINKS_ADDED 0x01
#define FWNODE_FLAG_NOT_DEVICE 0x02
#define FWNODE_FLAG_INITIALIZED 0x04
#define NR_FWNODE_REFERENCE_ARGS 8
struct fwnode_handle
{
struct fwnode_handle *secondary;
const struct fwnode_operations *ops;
struct rt_device *dev;
struct rt_list_node suppliers;
struct rt_list_node consumers;
uint8_t flags;
};
struct fwnode_link
{
struct fwnode_handle *supplier;
struct rt_list_node s_hook;
struct fwnode_handle *consumer;
struct rt_list_node c_hook;
};
struct fwnode_endpoint
{
unsigned int port;
unsigned int id;
const struct fwnode_handle *local_fwnode;
};
struct fwnode_reference_args
{
struct fwnode_handle *fwnode;
unsigned int nargs;
uint64_t args[NR_FWNODE_REFERENCE_ARGS];
};
struct fwnode_operations
{
struct fwnode_handle *(*get)(struct fwnode_handle *fwnode);
void (*put)(struct fwnode_handle *fwnode);
bool (*device_is_available)(const struct fwnode_handle *fwnode);
const void *(*device_get_match_data)(const struct fwnode_handle *fwnode,
const struct rt_device *dev);
bool (*property_present)(const struct fwnode_handle *fwnode,
const char *propname);
int (*property_read_int_array)(const struct fwnode_handle *fwnode,
const char *propname,
unsigned int elem_size, void *val,
size_t nval);
int (*property_read_string_array)(const struct fwnode_handle *fwnode_handle,
const char *propname, const char **val,
size_t nval);
const char *(*get_name)(const struct fwnode_handle *fwnode);
const char *(*get_name_prefix)(const struct fwnode_handle *fwnode);
struct fwnode_handle *(*get_parent)(const struct fwnode_handle *fwnode);
struct fwnode_handle *(*get_next_child_node)(const struct fwnode_handle *fwnode,
struct fwnode_handle *child);
struct fwnode_handle *(*get_named_child_node)(const struct fwnode_handle *fwnode,
const char *name);
int (*get_reference_args)(const struct fwnode_handle *fwnode,
const char *prop, const char *nargs_prop,
unsigned int nargs, unsigned int index,
struct fwnode_reference_args *args);
struct fwnode_handle *(*graph_get_next_endpoint)(const struct fwnode_handle *fwnode,
struct fwnode_handle *prev);
struct fwnode_handle *(*graph_get_remote_endpoint)(const struct fwnode_handle *fwnode);
struct fwnode_handle *(*graph_get_port_parent)(struct fwnode_handle *fwnode);
int (*graph_parse_endpoint)(const struct fwnode_handle *fwnode,
struct fwnode_endpoint *endpoint);
int (*add_links)(struct fwnode_handle *fwnode);
};
#define fwnode_has_op(fwnode, op) \
((fwnode) && (fwnode)->ops && (fwnode)->ops->op)
#define fwnode_call_int_op(fwnode, op, ...) \
(fwnode ? (fwnode_has_op(fwnode, op) ? (fwnode)->ops->op(fwnode, ##__VA_ARGS__) : -ENXIO) : -EINVAL)
#define fwnode_call_bool_op(fwnode, op, ...) \
(fwnode_has_op(fwnode, op) ? (fwnode)->ops->op(fwnode, ##__VA_ARGS__) : false)
#define fwnode_call_ptr_op(fwnode, op, ...) \
(fwnode_has_op(fwnode, op) ? (fwnode)->ops->op(fwnode, ##__VA_ARGS__) : NULL)
#define fwnode_call_void_op(fwnode, op, ...) \
do \
{ \
if (fwnode_has_op(fwnode, op)) \
(fwnode)->ops->op(fwnode, ##__VA_ARGS__); \
} while (false)
#define get_dev_from_fwnode(fwnode) ((fwnode)->dev)
static inline void fwnode_init(struct fwnode_handle *fwnode,
const struct fwnode_operations *ops)
{
fwnode->ops = ops;
rt_list_init(&fwnode->consumers);
rt_list_init(&fwnode->suppliers);
}
static inline void fwnode_dev_initialized(struct fwnode_handle *fwnode,
bool initialized)
{
if (!fwnode)
return;
if (initialized)
fwnode->flags |= FWNODE_FLAG_INITIALIZED;
else
fwnode->flags &= ~FWNODE_FLAG_INITIALIZED;
}
#endif //__DTB_FWNODE_H__
@@ -10,6 +10,10 @@
#include <rtthread.h>
#include <stdint.h>
#ifdef RT_USING_FDT_FWNODE
#include "dtb_fwnode.h"
#endif
//#define RT_DTB_DEBUG
#ifdef RT_DTB_DEBUG
#define debug(fmt, args...) rt_kprintf(fmt, ##args)
@@ -17,9 +21,9 @@
#define debug(fmt, args...)
#endif
#define ERR_PTR(err) ((void *)((long)(err)))
#define PTR_ERR(ptr) ((long)(ptr))
#define IS_ERR(ptr) ((unsigned long)(ptr) > (unsigned long)(-1000))
#define DTB_ERR_PTR(err) ((void *)((long)(err)))
#define DTB_PTR_ERR(ptr) ((long)(ptr))
#define DTB_IS_ERR(ptr) ((unsigned long)(ptr) > (unsigned long)(-1000))
#define DEV_ROOT_NODE_ADDR_CELLS_DEFAULT 2
#define DEV_ROOT_NODE_SIZE_CELLS_DEFAULT 1
@@ -71,7 +75,10 @@ struct dtb_node
const char *path;
phandle handle;
int level;
#ifdef RT_USING_FDT_FWNODE
struct fwnode_handle fwnode;
unsigned long _flags;
#endif
struct dtb_property *properties;
struct dtb_node *parent;
struct dtb_node *child;
@@ -382,4 +389,12 @@ int dtb_node_irq_count(struct dtb_node *dev);
dtb_node_valid(node); \
node = dtb_node_next_subnode(node))
#ifdef RT_USING_FDT_FWNODE
extern const struct fwnode_operations of_fwnode_ops;
static inline void dtb_fwnode_init(struct dtb_node *node)
{
fwnode_init(&node->fwnode, &of_fwnode_ops);
}
#endif
#endif /* RT_FDT_H__ */
@@ -28,11 +28,11 @@ static void *dtb_node_find_property_value_of_size(const struct dtb_node *dn,
struct dtb_property *prop = dtb_node_get_dtb_node_property(dn, propname, NULL);
if (!prop)
return ERR_PTR(-EINVAL);
return DTB_ERR_PTR(-EINVAL);
if (!prop->value)
return ERR_PTR(-ENODATA);
return DTB_ERR_PTR(-ENODATA);
if (len > prop->size)
return ERR_PTR(-EOVERFLOW);
return DTB_ERR_PTR(-EOVERFLOW);
return prop->value;
}
@@ -44,10 +44,10 @@ int dtb_node_read_u32(const struct dtb_node *dn, const char *propname, uint32_t
if (!dn)
return -EINVAL;
val = dtb_node_find_property_value_of_size(dn, propname, sizeof(*outp));
if (IS_ERR(val))
if (DTB_IS_ERR(val))
{
debug("(not found)\n");
return PTR_ERR(val);
return DTB_PTR_ERR(val);
}
*outp = fdt32_to_cpu(*val);
@@ -72,8 +72,8 @@ int dtb_node_read_u32_array(const struct dtb_node *dn, const char *propname,
val = dtb_node_find_property_value_of_size(dn, propname,
sz * sizeof(*out_values));
if (IS_ERR(val))
return PTR_ERR(val);
if (DTB_IS_ERR(val))
return DTB_PTR_ERR(val);
debug("size %zd, val:%d\n", sz, *val);
while (sz--)
@@ -110,10 +110,10 @@ int dtb_node_read_u32_index(const struct dtb_node *dn, const char *propname,
val = dtb_node_find_property_value_of_size(dn, propname,
sizeof(*outp) * (index + 1));
if (IS_ERR(val))
if (DTB_IS_ERR(val))
{
debug("(not found)\n");
return PTR_ERR(val);
return DTB_PTR_ERR(val);
}
*outp = fdt32_to_cpu(val[index]);
@@ -130,10 +130,10 @@ int dtb_node_read_u64(const struct dtb_node *dn, const char *propname, uint64_t
if (!dn)
return -EINVAL;
val = dtb_node_find_property_value_of_size(dn, propname, sizeof(*outp));
if (IS_ERR(val))
if (DTB_IS_ERR(val))
{
debug("(not found)\n");
return PTR_ERR(val);
return DTB_PTR_ERR(val);
}
*outp = fdt64_to_cpu(*val);
@@ -69,6 +69,10 @@ static int _dtb_node_get_dtb_nodes_list(struct dtb_node *dtb_node_head, struct d
int pathname_sz;
int node_name_sz;
#ifdef RT_USING_FDT_FWNODE
dtb_fwnode_init(dtb_node_head);
#endif
/* caller alrealy checked current_fdt */
if ((root_off = fdt_path_offset(current_fdt, pathname)) >= 0)
{
@@ -113,7 +117,9 @@ static int _dtb_node_get_dtb_nodes_list(struct dtb_node *dtb_node_head, struct d
{
return FDT_RET_NO_MEMORY;
}
#ifdef RT_USING_FDT_FWNODE
dtb_fwnode_init(dtb_node);
#endif
fdt_exec_status = _dtb_node_get_dtb_properties_list(dtb_node->properties, node_off);
if (fdt_exec_status == FDT_RET_GET_EMPTY)
{
File diff suppressed because it is too large Load Diff