xref: /optee_os/core/include/drivers/clk_dt.h (revision 32b3180828fa15a49ccc86ecb4be9d274c140c89)
1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3  * Copyright (c) 2021, Bootlin
4  */
5 
6 #ifndef __DRIVERS_CLK_DT_H
7 #define __DRIVERS_CLK_DT_H
8 
9 #include <kernel/dt_driver.h>
10 #include <scattered_array.h>
11 #include <stdint.h>
12 #include <sys/queue.h>
13 
14 /**
15  * CLK_DT_DECLARE - Declare a clock driver
16  * @__name: Clock driver name
17  * @__compat: Compatible string
18  * @__probe: Clock probe function
19  */
20 #define CLK_DT_DECLARE(__name, __compat, __probe) \
21 	static const struct dt_device_match __name ## _match_table[] = { \
22 		{ .compatible = __compat }, \
23 		{ } \
24 	}; \
25 	DEFINE_DT_DRIVER(__name ## _dt_driver) = { \
26 		.name = # __name, \
27 		.type = DT_DRIVER_CLK, \
28 		.match_table = __name ## _match_table, \
29 		.probe = __probe, \
30 	}
31 
32 /**
33  * clk_dt_get_by_index - Get a clock at a specific index in "clocks" property
34  *
35  * @fdt: Device tree to work on
36  * @nodeoffset: Node offset of the subnode containing a clock property
37  * @clk_idx: Clock index to get
38  * @clk: Output clock reference upon success
39  *
40  * Return TEE_SUCCESS in case of success
41  * Return TEE_ERROR_DEFER_DRIVER_INIT if clock is not initialized
42  * Return TEE_ERROR_ITEM_NOT_FOUND if the DT does not provide a clock reference
43  * Return any other TEE_Result compliant code in case of error
44  */
45 TEE_Result clk_dt_get_by_index(const void *fdt, int nodeoffset,
46 			       unsigned int clk_idx, struct clk **clk);
47 
48 /**
49  * clk_dt_get_by_name - Get a clock matching a name in "clock-names" property
50  *
51  * @fdt: Device tree to work on
52  * @nodeoffset: Node offset of the subnode containing a clock property
53  * @name: Clock name to get
54  * @clk: Output clock reference upon success
55  *
56  * Return TEE_SUCCESS in case of success
57  * Return TEE_ERROR_DEFER_DRIVER_INIT if clock is not initialized
58  * Return TEE_ERROR_ITEM_NOT_FOUND if the DT does not provide a clock reference
59  * Return any other TEE_Result compliant code in case of error
60  */
61 TEE_Result clk_dt_get_by_name(const void *fdt, int nodeoffset,
62 			      const char *name, struct clk **clk);
63 
64 /**
65  * clk_dt_get_func - Typedef of function to get clock from devicetree properties
66  *
67  * @args: Pointer to devicetree description of the clock to parse
68  * @data: Pointer to data given at clk_dt_register_clk_provider() call
69  * @clk: Output clock reference upon success
70  */
71 typedef TEE_Result (*clk_dt_get_func)(struct dt_pargs *args, void *data,
72 				      struct clk **out_clk);
73 
74 /**
75  * clk_dt_register_clk_provider - Register a clock provider
76  *
77  * @fdt: Device tree to work on
78  * @nodeoffset: Node offset of the clock
79  * @func: Callback to match the devicetree clock with a clock struct
80  * @data: Data which will be passed to the get_dt_clk callback
81  * Returns TEE_Result value
82  */
83 static inline TEE_Result clk_dt_register_clk_provider(const void *fdt,
84 						      int nodeoffset,
85 						      clk_dt_get_func func,
86 						      void *data)
87 {
88 	return dt_driver_register_provider(fdt, nodeoffset,
89 					   (get_of_device_func)func, data,
90 					   DT_DRIVER_CLK);
91 }
92 
93 /**
94  * clk_dt_get_simple_clk: simple clock matching function for single clock
95  * providers
96  */
97 static inline TEE_Result clk_dt_get_simple_clk(struct dt_pargs *args __unused,
98 					       void *data, struct clk **out_clk)
99 {
100 	*out_clk = data;
101 
102 	return TEE_SUCCESS;
103 }
104 
105 #endif /* __DRIVERS_CLK_DT_H */
106