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