xref: /optee_os/core/include/kernel/dt_driver.h (revision ef20efc4448ce8a83ed420834b47b07e379545bb)
1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3  * Copyright (c) 2021, Linaro Limited
4  * Copyright (c) 2021, Bootlin
5  */
6 
7 #ifndef __DT_DRIVER_H
8 #define __DT_DRIVER_H
9 
10 #include <kernel/dt.h>
11 #include <stdint.h>
12 #include <sys/queue.h>
13 #include <tee_api_types.h>
14 
15 /**
16  * struct dt_driver_phandle_args - Devicetree phandle arguments
17  * @args_count: Count of cells for the device
18  * @args: Device consumer specifiers
19  */
20 struct dt_driver_phandle_args {
21 	int args_count;
22 	uint32_t args[];
23 };
24 
25 /*
26  * get_of_device_func - Callback function for returning a driver private
27  *	instance based on a FDT phandle with possible arguments and the
28  *	registered dt_driver private data reference.
29  *
30  * @parg: phandle argument(s) referencing the device in the FDT.
31  * @data: driver private data registered in struct dt_driver.
32  *
33  * Return a device opaque reference, e.g. a struct clk pointer for a clock
34  * driver, or NULL if not found.
35  */
36 typedef void *(*get_of_device_func)(struct dt_driver_phandle_args *parg,
37 				    void *data);
38 
39 /*
40  * struct dt_driver_provider - DT related info on probed device
41  *
42  * Saves information on the probed device so that device
43  * drivers can get resources from DT phandle and related arguments.
44  *
45  * @nodeoffset: Node offset of device referenced in the FDT
46  * @type: One of DT_DRIVER_* or DT_DRIVER_NOTYPE.
47  * @provider_cells: Cells count in the FDT used by the driver's references
48  * @get_of_device: Function to get driver's device ref from phandle data
49  * @priv_data: Driver private data passed as @get_of_device argument
50  * @link: Reference in DT driver providers list
51  */
52 struct dt_driver_provider {
53 	int nodeoffset;
54 	enum dt_driver_type type;
55 	unsigned int provider_cells;
56 	uint32_t phandle;
57 	get_of_device_func get_of_device;
58 	void *priv_data;
59 	SLIST_ENTRY(dt_driver_provider) link;
60 };
61 
62 SLIST_HEAD(dt_driver_prov_list, dt_driver_provider);
63 extern struct dt_driver_prov_list dt_driver_provider_list;
64 
65 /**
66  * dt_driver_register_provider - Register a driver provider
67  *
68  * @fdt: Device tree to work on
69  * @nodeoffset: Node offset in the FDT
70  * @get_of_device: Function to match the devicetree with a device instance
71  * @data: Data which will be passed to the @get_of_device callback
72  * @type: Driver type
73  *
74  * @get_of_device returns a void *. Driver provider is expected to
75  * include a shim helper to cast to device reference into provider driver
76  * target structure reference (e.g (struct clk *) for clock devices).
77  */
78 TEE_Result dt_driver_register_provider(const void *fdt, int nodeoffset,
79 				       get_of_device_func get_of_device,
80 				       void *data, enum dt_driver_type type);
81 
82 /*
83  * dt_driver_device_from_node_idx_prop - Return a device instance based on a
84  *	property name and FDT information
85  *
86  * @prop_name: DT property name, e.g. "clocks" for clock resources
87  * @fdt: FDT base address
88  * @nodeoffset: node offset in the FDT
89  * @prop_idx: index of the phandle data in the property
90  *
91  * Return a device opaque reference, e.g. a struct clk pointer for a clock
92  * driver, or NULL if not found.
93  */
94 void *dt_driver_device_from_node_idx_prop(const char *prop_name,
95 					  const void *fdt, int nodeoffset,
96 					  unsigned int prop_idx);
97 
98 /*
99  * Return driver provider reference from its node offset value in the FDT
100  */
101 struct dt_driver_provider *dt_driver_get_provider_by_node(int nodeoffset);
102 
103 /*
104  * Return driver provider reference from its phandle value in the FDT
105  */
106 struct dt_driver_provider *dt_driver_get_provider_by_phandle(uint32_t phandle);
107 
108 /*
109  * Return number cells used for phandle arguments by a driver provider
110  */
111 unsigned int dt_driver_provider_cells(struct dt_driver_provider *prv);
112 
113 /*
114  * dt_driver_probe_device_by_node - Probe matching driver to create a device
115  *	from a FDT node
116  *
117  * @fdt: FDT base address
118  * @nodeoffset: Node byte offset from FDT base
119  * @type: Target driver to match or DT_DRIVER_ANY
120  *
121  * Read the dt_driver database. Compatible list is looked up in the order
122  * of the FDT "compatible" property list. @type can be used to probe only
123  * specific drivers.
124  *
125  */
126 TEE_Result dt_driver_probe_device_by_node(const void *fdt, int nodeoffset,
127 					  enum dt_driver_type type);
128 
129 /*
130  * Get cells count of a device node given its dt_driver type
131  *
132  * @fdt: FDT base address
133  * @nodeoffset: Node offset on the FDT for the device
134  * @type: One of the supported DT_DRIVER_* value.
135  *
136  * Currently supports type DT_DRIVER_CLK.
137  * Return a positive cell count value (>= 0) or a negative FDT_ error code
138  */
139 int fdt_get_dt_driver_cells(const void *fdt, int nodeoffset,
140 			    enum dt_driver_type type);
141 #endif /* __DT_DRIVER_H */
142