1 /* SPDX-License-Identifier: BSD-2-Clause */ 2 /* 3 * Copyright (c) 2021, Linaro Limited 4 * Copyright (c) 2021, Bootlin 5 * Copyright (c) 2021, STMicroelectronics 6 */ 7 8 #ifndef __KERNEL_DT_DRIVER_H 9 #define __KERNEL_DT_DRIVER_H 10 11 #include <kernel/dt.h> 12 #include <stdint.h> 13 #include <sys/queue.h> 14 #include <tee_api_types.h> 15 16 /* 17 * Type indentifiers for registered device drivers consumer can query 18 * 19 * DT_DRIVER_NOTYPE Generic type for when no generic FDT parsing is supported 20 * DT_DRIVER_UART UART driver currently designed for console means 21 * DT_DRIVER_CLK Clock controller using generic clock DT bindings 22 * DT_DRIVER_RSTCTRL Reset controller using generic reset DT bindings 23 * DT_DRIVER_I2C I2C bus controller using generic I2C bus DT bindings 24 * DT_DRIVER_GPIO GPIO controller using generic GPIO DT bindings 25 * DT_DRIVER_PINCTRL Pin controller using generic reset DT bindings 26 * DT_DRIVER_INTERRUPT Interrupt controller using generic DT bindings 27 * DT_DRIVER_REGULATOR Voltage regulator controller using generic DT bindings 28 * DT_DRIVER_NVMEM NVMEM controller using generic NVMEM DT bindings 29 * DT_DRIVER_FIREWALL Firewall controller using generic DT bindings 30 */ 31 enum dt_driver_type { 32 DT_DRIVER_NOTYPE, 33 DT_DRIVER_UART, 34 DT_DRIVER_CLK, 35 DT_DRIVER_RSTCTRL, 36 DT_DRIVER_I2C, 37 DT_DRIVER_GPIO, 38 DT_DRIVER_PINCTRL, 39 DT_DRIVER_INTERRUPT, 40 DT_DRIVER_REGULATOR, 41 DT_DRIVER_NVMEM, 42 DT_DRIVER_FIREWALL, 43 }; 44 45 /* 46 * dt_driver_probe_func - Callback probe function for a driver. 47 * 48 * @fdt: FDT base address 49 * @nodeoffset: Offset of the node in the FDT 50 * @compat_data: Data registered for the compatible that probed the device 51 * 52 * Return TEE_SUCCESS on successful probe, 53 * TEE_ERROR_DEFER_DRIVER_INIT if probe must be deferred 54 * TEE_ERROR_ITEM_NOT_FOUND when no driver matched node's compatible string 55 * Any other TEE_ERROR_* compliant code. 56 */ 57 typedef TEE_Result (*dt_driver_probe_func)(const void *fdt, int nodeoffset, 58 const void *compat_data); 59 60 /* 61 * Driver instance registered to be probed on compatible node found in the DT. 62 * 63 * @name: Driver name 64 * @type: Drive type 65 * @match_table: Compatible matching identifiers, null terminated 66 * @driver: Driver private reference or NULL 67 * @probe: Probe callback (see dt_driver_probe_func) or NULL 68 */ 69 struct dt_driver { 70 const char *name; 71 enum dt_driver_type type; 72 const struct dt_device_match *match_table; /* null-terminated */ 73 const void *driver; 74 TEE_Result (*probe)(const void *fdt, int node, const void *compat_data); 75 }; 76 77 #define DEFINE_DT_DRIVER(name) \ 78 SCATTERED_ARRAY_DEFINE_PG_ITEM(dt_drivers, struct dt_driver) 79 80 #define for_each_dt_driver(drv) \ 81 for (drv = SCATTERED_ARRAY_BEGIN(dt_drivers, struct dt_driver); \ 82 drv < SCATTERED_ARRAY_END(dt_drivers, struct dt_driver); \ 83 drv++) 84 85 /* Opaque reference to DT driver device provider instance */ 86 struct dt_driver_provider; 87 88 /** 89 * struct dt_pargs - Devicetree phandle arguments 90 * @fdt: Device-tree to work on 91 * @phandle_node: Node pointed by the specifier phandle 92 * @args_count: Count of cells for the device 93 * @args: Device consumer specifiers 94 */ 95 struct dt_pargs { 96 const void *fdt; 97 int phandle_node; 98 int args_count; 99 uint32_t args[]; 100 }; 101 102 /* 103 * get_of_device_func - Callback function for returning a driver private 104 * instance based on a FDT phandle with possible arguments and the 105 * registered dt_driver private data reference. 106 * 107 * @parg: phandle argument(s) referencing the device in the FDT. 108 * @data: driver private data registered in struct dt_driver. 109 * @device_ref: output device reference upon success, e.g. a struct clk 110 * pointer for a clock driver. 111 * 112 * Return code: 113 * TEE_SUCCESS in case of success 114 * TEE_ERROR_DEFER_DRIVER_INIT if device driver is not yet initialized 115 * Any TEE_Result compliant code in case of error. 116 */ 117 typedef TEE_Result (*get_of_device_func)(struct dt_pargs *parg, void *data, 118 void *device_ref); 119 120 /** 121 * dt_driver_register_provider - Register a driver provider 122 * 123 * @fdt: Device tree to work on 124 * @nodeoffset: Node offset in the FDT 125 * @get_of_device: Function to match the devicetree with a device instance 126 * @data: Data which will be passed to the @get_of_device callback 127 * @type: Driver type 128 * 129 * @get_of_device returns a void *. Driver provider is expected to 130 * include a shim helper to cast to device reference into provider driver 131 * target structure reference (e.g (struct clk *) for clock devices). 132 */ 133 TEE_Result dt_driver_register_provider(const void *fdt, int nodeoffset, 134 get_of_device_func get_of_device, 135 void *data, enum dt_driver_type type); 136 137 /* 138 * dt_driver_device_from_node_idx_prop - Return a device instance based on a 139 * property name and FDT information 140 * 141 * @prop_name: DT property name, e.g. "clocks" for clock resources 142 * @fdt: FDT base address 143 * @nodeoffset: node offset in the FDT 144 * @prop_idx: index of the phandle data in the property 145 * @type: Driver type 146 * @device_ref: output device opaque reference upon support, for example 147 * a struct clk pointer for a clock driver. 148 149 * Return code: 150 * TEE_SUCCESS in case of success, 151 * TEE_ERROR_DEFER_DRIVER_INIT if device driver is not yet initialized 152 * TEE_ERROR_ITEM_NOT_FOUND if @prop_name does not match a property's name 153 * or @prop_idx does not match any index in @prop_name phandle list 154 * Any TEE_Result compliant code in case of error. 155 */ 156 TEE_Result dt_driver_device_from_node_idx_prop(const char *prop_name, 157 const void *fdt, int nodeoffset, 158 unsigned int prop_idx, 159 enum dt_driver_type type, 160 void *device_ref); 161 162 /* 163 * dt_driver_device_from_parent - Return a device instance based on the parent. 164 * This is mainly used for the devices that are children of a controller 165 * such as I2C, SPI and so on. 166 * 167 * @fdt: FDT base address 168 * @nodeoffset: node offset in the FDT 169 * @type: Driver type 170 * @device_ref: output device opaque reference upon success, for example 171 * a struct i2c_dev pointer for a I2C bus driver 172 * 173 * Return code: 174 * TEE_SUCCESS in case of success, 175 * TEE_ERROR_DEFER_DRIVER_INIT if device driver is not yet initialized 176 * Any TEE_Result compliant code in case of error. 177 */ 178 TEE_Result dt_driver_device_from_parent(const void *fdt, int nodeoffset, 179 enum dt_driver_type type, 180 void *device_ref); 181 182 /* 183 * dt_driver_device_from_node_idx_prop_phandle() - Same as 184 * dt_driver_device_from_node_idx_prop() but phandle is not the first 185 * cells in property @prop_name but is passed as an argument. 186 * 187 * This function is used for DT bindings as "interrupts" property where the 188 * property carries the interrupt information but not the interrupt controller 189 * phandle which is found in a specific property (here "interrupt-parent"). 190 */ 191 TEE_Result dt_driver_device_from_node_idx_prop_phandle(const char *prop_name, 192 const void *fdt, 193 int nodeoffs, 194 unsigned int prop_index, 195 enum dt_driver_type type, 196 uint32_t phandle, 197 void *device_ref); 198 199 /* 200 * dt_driver_get_crypto() - Request crypto support for driver initialization 201 * 202 * Return TEE_SUCCESS if cryptography services are initialized, otherwise return 203 * TEE_ERROR_DEFER_DRIVER_INIT. 204 */ 205 TEE_Result dt_driver_get_crypto(void); 206 207 #ifdef CFG_DT 208 /* Inform DT driver probe sequence that core crypto support is initialized */ 209 void dt_driver_crypt_init_complete(void); 210 #else 211 static inline void dt_driver_crypt_init_complete(void) {} 212 #endif 213 214 /* 215 * Return driver provider reference from its node offset value in the FDT 216 */ 217 struct dt_driver_provider * 218 dt_driver_get_provider_by_node(int nodeoffset, enum dt_driver_type type); 219 220 /* 221 * Return driver provider reference from its phandle value in the FDT 222 */ 223 struct dt_driver_provider * 224 dt_driver_get_provider_by_phandle(uint32_t phandle, enum dt_driver_type type); 225 226 /* 227 * Return number cells used for phandle arguments by a driver provider 228 */ 229 unsigned int dt_driver_provider_cells(struct dt_driver_provider *prv); 230 231 /* 232 * Return provider private data registered by dt_driver_register_provider() 233 */ 234 void *dt_driver_provider_priv_data(struct dt_driver_provider *prv); 235 236 /* 237 * dt_driver_probe_device_by_node - Probe matching driver to create a device 238 * from a FDT node 239 * 240 * @fdt: FDT base address 241 * @nodeoffset: Node byte offset from FDT base 242 * @type: Target driver to match or DT_DRIVER_ANY 243 * 244 * Read the dt_driver database. Compatible list is looked up in the order 245 * of the FDT "compatible" property list. @type can be used to probe only 246 * specific drivers. 247 * 248 */ 249 TEE_Result dt_driver_probe_device_by_node(const void *fdt, int nodeoffset, 250 enum dt_driver_type type); 251 252 /* 253 * Get cells count of a device node given its dt_driver type 254 * 255 * @fdt: FDT base address 256 * @nodeoffset: Node offset on the FDT for the device 257 * @type: One of the supported DT_DRIVER_* value. 258 * 259 * Return a positive cell count value (>= 0) or a negative FDT_ error code 260 */ 261 int fdt_get_dt_driver_cells(const void *fdt, int nodeoffset, 262 enum dt_driver_type type); 263 264 /* 265 * Called by bus like nodes to propose a node for dt_driver probing 266 * 267 * @fdt: FDT base address 268 * @nodeoffset: Node offset on the FDT for the device 269 */ 270 TEE_Result dt_driver_maybe_add_probe_node(const void *fdt, int nodeoffset); 271 272 #ifdef CFG_DT_DRIVER_EMBEDDED_TEST 273 /* 274 * Return TEE_ERROR_NOT_IMPLEMENTED if test are not implemented 275 * otherwise return TEE_ERROR_GENERIC if some test has failed 276 * otherwise return TEE_SUCCESS (tests succeed or skipped) 277 */ 278 TEE_Result dt_driver_test_status(void); 279 #else 280 static inline TEE_Result dt_driver_test_status(void) 281 { 282 return TEE_ERROR_NOT_IMPLEMENTED; 283 } 284 #endif 285 #endif /* __KERNEL_DT_DRIVER_H */ 286