mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-10-02 14:23:19 +08:00
@@ -30,6 +30,5 @@ rsource "ktime/Kconfig"
|
||||
rsource "clk/Kconfig"
|
||||
rsource "hwtimer/Kconfig"
|
||||
rsource "usb/Kconfig"
|
||||
rsource "fdt/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
||||
+2
-200
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
@@ -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
Reference in New Issue
Block a user