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