xref: /optee_os/core/include/kernel/dt_driver.h (revision 92d75aefed568a557dbd9152d749a4bc320fa9f2)
1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3  * Copyright (c) 2021, Linaro Limited
4  * Copyright (c) 2021, Bootlin
5  * Copyright (c) 2021, Linaro Limited
6  * Copyright (c) 2021, STMicroelectronics
7  */
8 
9 #ifndef __DT_DRIVER_H
10 #define __DT_DRIVER_H
11 
12 #include <kernel/dt.h>
13 #include <stdint.h>
14 #include <sys/queue.h>
15 #include <tee_api_types.h>
16 
17 /* Opaque reference to DT driver device provider instance */
18 struct dt_driver_provider;
19 
20 /**
21  * struct dt_driver_phandle_args - Devicetree phandle arguments
22  * @fdt: Device-tree to work on
23  * @phandle_node: Node pointed by the specifier phandle
24  * @args_count: Count of cells for the device
25  * @args: Device consumer specifiers
26  */
27 struct dt_driver_phandle_args {
28 	const void *fdt;
29 	int phandle_node;
30 	int args_count;
31 	uint32_t args[];
32 };
33 
34 /*
35  * get_of_device_func - Callback function for returning a driver private
36  *	instance based on a FDT phandle with possible arguments and the
37  *	registered dt_driver private data reference.
38  *
39  * @parg: phandle argument(s) referencing the device in the FDT.
40  * @data: driver private data registered in struct dt_driver.
41  * @res: Output result code of the operation:
42  *	TEE_SUCCESS in case of success
43  *	TEE_ERROR_DEFER_DRIVER_INIT if device driver is not yet initialized
44  *	Any TEE_Result compliant code in case of error.
45  *
46  * Return a device opaque reference, e.g. a struct clk pointer for a clock
47  * driver, or NULL if not found in which case @res provides the error code.
48  */
49 typedef void *(*get_of_device_func)(struct dt_driver_phandle_args *parg,
50 				    void *data, TEE_Result *res);
51 
52 /**
53  * dt_driver_register_provider - Register a driver provider
54  *
55  * @fdt: Device tree to work on
56  * @nodeoffset: Node offset in the FDT
57  * @get_of_device: Function to match the devicetree with a device instance
58  * @data: Data which will be passed to the @get_of_device callback
59  * @type: Driver type
60  *
61  * @get_of_device returns a void *. Driver provider is expected to
62  * include a shim helper to cast to device reference into provider driver
63  * target structure reference (e.g (struct clk *) for clock devices).
64  */
65 TEE_Result dt_driver_register_provider(const void *fdt, int nodeoffset,
66 				       get_of_device_func get_of_device,
67 				       void *data, enum dt_driver_type type);
68 
69 /*
70  * dt_driver_device_from_node_idx_prop - Return a device instance based on a
71  *	property name and FDT information
72  *
73  * @prop_name: DT property name, e.g. "clocks" for clock resources
74  * @fdt: FDT base address
75  * @nodeoffset: node offset in the FDT
76  * @prop_idx: index of the phandle data in the property
77  * @type: Driver type
78  * @res: Output result code of the operation:
79  *	TEE_SUCCESS in case of success
80  *	TEE_ERROR_DEFER_DRIVER_INIT if device driver is not yet initialized
81  *	TEE_ERROR_ITEM_NOT_FOUND if prop_name does not match a property's name
82  *	Any TEE_Result compliant code in case of error.
83  *
84  * Return a device opaque reference, e.g. a struct clk pointer for a clock
85  * driver, or NULL if not found in which case @res provides the error code.
86  */
87 void *dt_driver_device_from_node_idx_prop(const char *prop_name,
88 					  const void *fdt, int nodeoffset,
89 					  unsigned int prop_idx,
90 					  enum dt_driver_type type,
91 					  TEE_Result *res);
92 
93 /*
94  * dt_driver_device_from_parent - Return a device instance based on the parent.
95  *	This is mainly used for the devices that are children of a controller
96  *	such as I2C, SPI and so on.
97  *
98  * @fdt: FDT base address
99  * @nodeoffset: node offset in the FDT
100  * @type: Driver type
101  * @res: Output result code of the operation:
102  *	TEE_SUCCESS in case of success
103  *	TEE_ERROR_DEFER_DRIVER_INIT if device driver is not yet initialized
104  *	Any TEE_Result compliant code in case of error.
105  *
106  * Return a device opaque reference, e.g. a struct i2c_dev pointer for a I2C bus
107  * driver, or NULL if not found in which case @res provides the error code.
108  */
109 void *dt_driver_device_from_parent(const void *fdt, int nodeoffset,
110 				   enum dt_driver_type type, TEE_Result *res);
111 
112 /*
113  * dt_driver_get_crypto() - Request crypto support for driver initialization
114  *
115  * Return TEE_SUCCESS if cryptography services are initialized, otherwise return
116  * TEE_ERROR_DEFER_DRIVER_INIT.
117  */
118 TEE_Result dt_driver_get_crypto(void);
119 
120 #ifdef CFG_DT
121 /* Inform DT driver probe sequence that core crypto support is initialized */
122 void dt_driver_crypt_init_complete(void);
123 #else
124 static inline void dt_driver_crypt_init_complete(void) {}
125 #endif
126 
127 /*
128  * Return driver provider reference from its node offset value in the FDT
129  */
130 struct dt_driver_provider *
131 dt_driver_get_provider_by_node(int nodeoffset, enum dt_driver_type type);
132 
133 /*
134  * Return driver provider reference from its phandle value in the FDT
135  */
136 struct dt_driver_provider *
137 dt_driver_get_provider_by_phandle(uint32_t phandle, enum dt_driver_type type);
138 
139 /*
140  * Return number cells used for phandle arguments by a driver provider
141  */
142 unsigned int dt_driver_provider_cells(struct dt_driver_provider *prv);
143 
144 /*
145  * dt_driver_probe_device_by_node - Probe matching driver to create a device
146  *	from a FDT node
147  *
148  * @fdt: FDT base address
149  * @nodeoffset: Node byte offset from FDT base
150  * @type: Target driver to match or DT_DRIVER_ANY
151  *
152  * Read the dt_driver database. Compatible list is looked up in the order
153  * of the FDT "compatible" property list. @type can be used to probe only
154  * specific drivers.
155  *
156  */
157 TEE_Result dt_driver_probe_device_by_node(const void *fdt, int nodeoffset,
158 					  enum dt_driver_type type);
159 
160 /*
161  * Get cells count of a device node given its dt_driver type
162  *
163  * @fdt: FDT base address
164  * @nodeoffset: Node offset on the FDT for the device
165  * @type: One of the supported DT_DRIVER_* value.
166  *
167  * Return a positive cell count value (>= 0) or a negative FDT_ error code
168  */
169 int fdt_get_dt_driver_cells(const void *fdt, int nodeoffset,
170 			    enum dt_driver_type type);
171 
172 /*
173  * Called by bus like nodes to propose a node for dt_driver probing
174  *
175  * @fdt: FDT base address
176  * @nodeoffset: Node offset on the FDT for the device
177  */
178 TEE_Result dt_driver_maybe_add_probe_node(const void *fdt, int nodeoffset);
179 
180 #ifdef CFG_DT_DRIVER_EMBEDDED_TEST
181 /*
182  * Return TEE_ERROR_NOT_IMPLEMENTED if test are not implemented
183  * otherwise return TEE_ERROR_GENERIC if some test has failed
184  * otherwise return TEE_SUCCESS (tests succeed or skipped)
185  */
186 TEE_Result dt_driver_test_status(void);
187 #else
188 static inline TEE_Result dt_driver_test_status(void)
189 {
190 	return TEE_ERROR_NOT_IMPLEMENTED;
191 }
192 #endif
193 
194 #endif /* __DT_DRIVER_H */
195