xref: /optee_os/core/include/kernel/dt_driver.h (revision d8b14b46af9d2c7cee7f875e389e1a659bd123da)
1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3  * Copyright (c) 2021, Linaro Limited
4  * Copyright (c) 2021, Bootlin
5  */
6 
7 #ifndef __DT_DRIVER_H
8 #define __DT_DRIVER_H
9 
10 #include <kernel/dt.h>
11 #include <stdint.h>
12 #include <sys/queue.h>
13 #include <tee_api_types.h>
14 
15 /* Opaque reference to DT driver device provider instance */
16 struct dt_driver_provider;
17 
18 /**
19  * struct dt_driver_phandle_args - Devicetree phandle arguments
20  * @args_count: Count of cells for the device
21  * @args: Device consumer specifiers
22  */
23 struct dt_driver_phandle_args {
24 	int args_count;
25 	uint32_t args[];
26 };
27 
28 /*
29  * get_of_device_func - Callback function for returning a driver private
30  *	instance based on a FDT phandle with possible arguments and the
31  *	registered dt_driver private data reference.
32  *
33  * @parg: phandle argument(s) referencing the device in the FDT.
34  * @data: driver private data registered in struct dt_driver.
35  * @res: Output result code of the operation: TEE_ERROR_BUSY is target
36  *	device is not yet initialized, otherwise any other compliant code.
37  *
38  * Return a device opaque reference, e.g. a struct clk pointer for a clock
39  * driver, or NULL if not found in which case @res provides the error code.
40  */
41 typedef void *(*get_of_device_func)(struct dt_driver_phandle_args *parg,
42 				    void *data, TEE_Result *res);
43 
44 /**
45  * dt_driver_register_provider - Register a driver provider
46  *
47  * @fdt: Device tree to work on
48  * @nodeoffset: Node offset in the FDT
49  * @get_of_device: Function to match the devicetree with a device instance
50  * @data: Data which will be passed to the @get_of_device callback
51  * @type: Driver type
52  *
53  * @get_of_device returns a void *. Driver provider is expected to
54  * include a shim helper to cast to device reference into provider driver
55  * target structure reference (e.g (struct clk *) for clock devices).
56  */
57 TEE_Result dt_driver_register_provider(const void *fdt, int nodeoffset,
58 				       get_of_device_func get_of_device,
59 				       void *data, enum dt_driver_type type);
60 
61 /*
62  * dt_driver_device_from_node_idx_prop - Return a device instance based on a
63  *	property name and FDT information
64  *
65  * @prop_name: DT property name, e.g. "clocks" for clock resources
66  * @fdt: FDT base address
67  * @nodeoffset: node offset in the FDT
68  * @prop_idx: index of the phandle data in the property
69  * @res: Output result code of the operation: TEE_ERROR_BUSY is target
70  *	device is not yet initialized, otherwise any other compliant code.
71  *
72  * Return a device opaque reference, e.g. a struct clk pointer for a clock
73  * driver, or NULL if not found in which case @res provides the error code.
74  */
75 void *dt_driver_device_from_node_idx_prop(const char *prop_name,
76 					  const void *fdt, int nodeoffset,
77 					  unsigned int prop_idx,
78 					  TEE_Result *res);
79 
80 /*
81  * Return driver provider reference from its node offset value in the FDT
82  */
83 struct dt_driver_provider *dt_driver_get_provider_by_node(int nodeoffset);
84 
85 /*
86  * Return driver provider reference from its phandle value in the FDT
87  */
88 struct dt_driver_provider *dt_driver_get_provider_by_phandle(uint32_t phandle);
89 
90 /*
91  * Return number cells used for phandle arguments by a driver provider
92  */
93 unsigned int dt_driver_provider_cells(struct dt_driver_provider *prv);
94 
95 /*
96  * dt_driver_probe_device_by_node - Probe matching driver to create a device
97  *	from a FDT node
98  *
99  * @fdt: FDT base address
100  * @nodeoffset: Node byte offset from FDT base
101  * @type: Target driver to match or DT_DRIVER_ANY
102  *
103  * Read the dt_driver database. Compatible list is looked up in the order
104  * of the FDT "compatible" property list. @type can be used to probe only
105  * specific drivers.
106  *
107  */
108 TEE_Result dt_driver_probe_device_by_node(const void *fdt, int nodeoffset,
109 					  enum dt_driver_type type);
110 
111 /*
112  * Get cells count of a device node given its dt_driver type
113  *
114  * @fdt: FDT base address
115  * @nodeoffset: Node offset on the FDT for the device
116  * @type: One of the supported DT_DRIVER_* value.
117  *
118  * Currently supports type DT_DRIVER_CLK.
119  * Return a positive cell count value (>= 0) or a negative FDT_ error code
120  */
121 int fdt_get_dt_driver_cells(const void *fdt, int nodeoffset,
122 			    enum dt_driver_type type);
123 #endif /* __DT_DRIVER_H */
124