xref: /optee_os/core/include/kernel/dt_driver.h (revision 279bfce83bac403aa516516574af9ca403d31290)
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: TEE_ERROR_BUSY is target
38  *	device is not yet initialized, otherwise any other compliant code.
39  *
40  * Return a device opaque reference, e.g. a struct clk pointer for a clock
41  * driver, or NULL if not found in which case @res provides the error code.
42  */
43 typedef void *(*get_of_device_func)(struct dt_driver_phandle_args *parg,
44 				    void *data, TEE_Result *res);
45 
46 /**
47  * dt_driver_register_provider - Register a driver provider
48  *
49  * @fdt: Device tree to work on
50  * @nodeoffset: Node offset in the FDT
51  * @get_of_device: Function to match the devicetree with a device instance
52  * @data: Data which will be passed to the @get_of_device callback
53  * @type: Driver type
54  *
55  * @get_of_device returns a void *. Driver provider is expected to
56  * include a shim helper to cast to device reference into provider driver
57  * target structure reference (e.g (struct clk *) for clock devices).
58  */
59 TEE_Result dt_driver_register_provider(const void *fdt, int nodeoffset,
60 				       get_of_device_func get_of_device,
61 				       void *data, enum dt_driver_type type);
62 
63 /*
64  * dt_driver_device_from_node_idx_prop - Return a device instance based on a
65  *	property name and FDT information
66  *
67  * @prop_name: DT property name, e.g. "clocks" for clock resources
68  * @fdt: FDT base address
69  * @nodeoffset: node offset in the FDT
70  * @prop_idx: index of the phandle data in the property
71  * @res: Output result code of the operation: TEE_ERROR_BUSY is target
72  *	device is not yet initialized, otherwise any other compliant code.
73  *
74  * Return a device opaque reference, e.g. a struct clk pointer for a clock
75  * driver, or NULL if not found in which case @res provides the error code.
76  */
77 void *dt_driver_device_from_node_idx_prop(const char *prop_name,
78 					  const void *fdt, int nodeoffset,
79 					  unsigned int prop_idx,
80 					  TEE_Result *res);
81 
82 /*
83  * Return driver provider reference from its node offset value in the FDT
84  */
85 struct dt_driver_provider *dt_driver_get_provider_by_node(int nodeoffset);
86 
87 /*
88  * Return driver provider reference from its phandle value in the FDT
89  */
90 struct dt_driver_provider *dt_driver_get_provider_by_phandle(uint32_t phandle);
91 
92 /*
93  * Return number cells used for phandle arguments by a driver provider
94  */
95 unsigned int dt_driver_provider_cells(struct dt_driver_provider *prv);
96 
97 /*
98  * dt_driver_probe_device_by_node - Probe matching driver to create a device
99  *	from a FDT node
100  *
101  * @fdt: FDT base address
102  * @nodeoffset: Node byte offset from FDT base
103  * @type: Target driver to match or DT_DRIVER_ANY
104  *
105  * Read the dt_driver database. Compatible list is looked up in the order
106  * of the FDT "compatible" property list. @type can be used to probe only
107  * specific drivers.
108  *
109  */
110 TEE_Result dt_driver_probe_device_by_node(const void *fdt, int nodeoffset,
111 					  enum dt_driver_type type);
112 
113 /*
114  * Get cells count of a device node given its dt_driver type
115  *
116  * @fdt: FDT base address
117  * @nodeoffset: Node offset on the FDT for the device
118  * @type: One of the supported DT_DRIVER_* value.
119  *
120  * Currently supports type DT_DRIVER_CLK.
121  * Return a positive cell count value (>= 0) or a negative FDT_ error code
122  */
123 int fdt_get_dt_driver_cells(const void *fdt, int nodeoffset,
124 			    enum dt_driver_type type);
125 
126 /*
127  * Called by bus like nodes to propose a node for dt_driver probing
128  *
129  * @fdt: FDT base address
130  * @nodeoffset: Node offset on the FDT for the device
131  */
132 TEE_Result dt_driver_maybe_add_probe_node(const void *fdt, int nodeoffset);
133 #endif /* __DT_DRIVER_H */
134