diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2011-08-09 19:12:34 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2012-09-14 11:47:42 +0200 |
commit | 58f3457f4f03313a7bab58f36382d57048fbe1c1 (patch) | |
tree | 9662cc78ea52a8a2efb9c3dc4b8d8a0e011f47b2 /include | |
parent | b2a13798a6c68c03ef87fbfdf66f2a942edebabd (diff) | |
download | barebox-58f3457f4f03313a7bab58f36382d57048fbe1c1.tar.gz barebox-58f3457f4f03313a7bab58f36382d57048fbe1c1.tar.xz |
of: add devicetree probing support
This adds code to probe devices from a devicetree. Most helper
functions are directly imported from Linux.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'include')
-rw-r--r-- | include/driver.h | 10 | ||||
-rw-r--r-- | include/of.h | 104 |
2 files changed, 114 insertions, 0 deletions
diff --git a/include/driver.h b/include/driver.h index 40b76c18a0..705e7d99f2 100644 --- a/include/driver.h +++ b/include/driver.h @@ -25,6 +25,7 @@ #include <linux/list.h> #include <linux/ioport.h> +#include <of.h> #define MAX_DRIVER_NAME 32 #define FORMAT_DRIVER_NAME_ID "%s%d" @@ -106,6 +107,9 @@ struct device_d { struct list_head cdevs; struct platform_device_id *id_entry; + struct device_node *device_node; + + struct of_device_id *of_id_entry; }; /** @brief Describes a driver present in the system */ @@ -128,6 +132,7 @@ struct driver_d { struct bus_type *bus; struct platform_device_id *id_table; + struct of_device_id *of_compatible; }; /*@}*/ /* do not delete, doxygen relevant */ @@ -432,5 +437,10 @@ int devfs_add_partition(const char *devname, loff_t offset, loff_t size, int flags, const char *name); int devfs_del_partition(const char *name); +#define DRV_OF_COMPAT(compat) \ + IS_ENABLED(CONFIG_OFDEVICE) ? (compat) : NULL + +int dev_get_drvdata(struct device_d *dev, unsigned long *data); + #endif /* DRIVER_H */ diff --git a/include/of.h b/include/of.h index 609b3b587b..762df9d24c 100644 --- a/include/of.h +++ b/include/of.h @@ -2,6 +2,8 @@ #define __OF_H #include <fdt.h> +#include <errno.h> +#include <asm/byteorder.h> extern struct fdt_header *barebox_fdt; @@ -19,4 +21,106 @@ void do_fixup_by_path_u32(struct fdt_header *fdt, const char *path, const char * u32 val, int create); int fdt_get_path_or_create(struct fdt_header *fdt, const char *path); +#define OF_BAD_ADDR ((u64)-1) + +typedef u32 phandle; + +struct property { + char *name; + int length; + void *value; + struct list_head list; +}; + +struct device_node { + char *name; + char *full_name; + + struct list_head properties; + struct device_node *parent; + struct list_head children; + struct list_head parent_list; + struct list_head list; + struct resource *resource; + struct device_d *device; + struct list_head phandles; + phandle phandle; +}; + +struct of_device_id { + char *compatible; + unsigned long data; +}; + +struct driver_d; + +int of_match(struct device_d *dev, struct driver_d *drv); + +struct property *of_find_property(const struct device_node *node, const char *name); + +struct device_node *of_find_node_by_path(const char *path); + +struct fdt_header *fdt_get_tree(void); + +#define device_node_for_nach_child(node, child) \ + list_for_each_entry(child, &node->children, parent_list) + +/* Helper to read a big number; size is in cells (not bytes) */ +static inline u64 of_read_number(const __be32 *cell, int size) +{ + u64 r = 0; + while (size--) + r = (r << 32) | be32_to_cpu(*(cell++)); + return r; +} + +int of_property_read_u32_array(const struct device_node *np, + const char *propname, u32 *out_values, + size_t sz); + +static inline int of_property_read_u32(const struct device_node *np, + const char *propname, + u32 *out_value) +{ + return of_property_read_u32_array(np, propname, out_value, 1); +} + +const void *of_get_property(const struct device_node *np, const char *name, + int *lenp); + +int of_parse_phandles_with_args(struct device_node *np, const char *list_name, + const char *cells_name, int index, + struct device_node **out_node, + const void **out_args); + +int of_get_named_gpio(struct device_node *np, + const char *propname, int index); + +struct device_node *of_find_node_by_phandle(phandle phandle); +void of_print_property(const void *data, int len); + +int of_machine_is_compatible(const char *compat); + +#define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1 +#define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 1 + +void of_print_nodes(struct device_node *node, int indent); +int of_probe(void); +int of_parse_dtb(struct fdt_header *fdt); + +#ifdef CONFIG_OFDEVICE +struct device_node *of_get_root_node(void); +int of_alias_get_id(struct device_node *np, const char *stem); +#else +static inline struct device_node *of_get_root_node(void) +{ + return NULL; +} + +static inline int of_alias_get_id(struct device_node *np, const char *stem) +{ + return -ENOENT; +} +#endif + #endif /* __OF_H */ |