xref: /optee_os/core/include/drivers/clk_dt.h (revision 8c0c44c9d2f768a95beacd4605776cfe29c9bff6)
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.h>
10 #include <kernel/dt_driver.h>
11 #include <stdint.h>
12 #include <sys/queue.h>
13 
14 /**
15  * struct clk_driver - Clock driver setup struct
16  * probe: probe function for the clock driver
17  */
18 struct clk_driver {
19 	TEE_Result (*probe)(const void *fdt, int nodeoffset, const void *data);
20 };
21 
22 /**
23  * CLK_DT_DECLARE - Declare a clock driver
24  * @__name: Clock driver name
25  * @__compat: Compatible string
26  * @__probe: Clock probe function
27  */
28 #define CLK_DT_DECLARE(__name, __compat, __probe) \
29 	static const struct clk_driver __name ## _driver = { \
30 		.probe = __probe, \
31 	}; \
32 	static const struct dt_device_match __name ## _match_table[] = { \
33 		{ .compatible = __compat }, \
34 		{ } \
35 	}; \
36 	const struct dt_driver __name ## _dt_driver __dt_driver = { \
37 		.name = # __name, \
38 		.type = DT_DRIVER_CLK, \
39 		.match_table = __name ## _match_table, \
40 		.driver = &__name ## _driver, \
41 	}
42 
43 /**
44  * clk_dt_get_by_idx - Get a clock at a specific index in "clocks" property
45  *
46  * @fdt: Device tree to work on
47  * @nodeoffset: Node offset of the subnode containing a clock property
48  * @clk_idx: Clock index to get
49  * Returns a clk struct pointer matching the clock at index clk_idx in clocks
50  * property or NULL if no clock match the given index.
51  */
52 struct clk *clk_dt_get_by_idx(const void *fdt, int nodeoffset,
53 			      unsigned int clk_idx);
54 
55 /**
56  * clk_dt_get_by_name - Get a clock matching a name in the "clock-names"
57  * property
58  *
59  * @fdt: Device tree to work on
60  * @nodeoffset: Node offset of the subnode containing a clock property
61  * @name: Clock name to get
62  * Returns a clk struct pointer matching the name in "clock-names" property or
63  * NULL if no clock match the given name.
64  */
65 struct clk *clk_dt_get_by_name(const void *fdt, int nodeoffset,
66 			       const char *name);
67 
68 /**
69  * clk_dt_get_func - Typedef of function to get clock from devicetree properties
70  *
71  * @args: Pointer to devicetree description of the clock to parse
72  * @data: Pointer to data given at clk_dt_register_clk_provider() call
73  *
74  * Returns a clk struct pointer pointing to a clock matching the devicetree
75  * description or NULL if invalid description.
76  */
77 typedef struct clk *(*clk_dt_get_func)(struct dt_driver_phandle_args *args,
78 				       void *data);
79 
80 /**
81  * clk_dt_register_clk_provider - Register a clock provider
82  *
83  * @fdt: Device tree to work on
84  * @nodeoffset: Node offset of the clock
85  * @get_dt_clk: Callback to match the devicetree clock with a clock struct
86  * @data: Data which will be passed to the get_dt_clk callback
87  * Returns TEE_Result value
88  */
89 TEE_Result clk_dt_register_clk_provider(const void *fdt, int nodeoffset,
90 					clk_dt_get_func get_dt_clk, void *data);
91 
92 /**
93  * clk_dt_get_simple_clk: simple clock matching function for single clock
94  * providers
95  */
96 static inline
97 struct clk *clk_dt_get_simple_clk(struct dt_driver_phandle_args *args __unused,
98 				  void *data)
99 {
100 	return data;
101 }
102 
103 #endif /* __DRIVERS_CLK_DT_H */
104