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 * 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 const struct dt_driver __name ## _dt_driver __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_idx - 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 * @res: Output result code of the operation: 39 * TEE_SUCCESS in case of success 40 * TEE_ERROR_DEFER_DRIVER_INIT if clock is not initialized 41 * Any TEE_Result compliant code in case of error. 42 * 43 * Returns a clk struct pointer matching the clock at index clk_idx in clocks 44 * property or NULL if no clock match the given index in which case @res 45 * provides the error code. 46 */ 47 struct clk *clk_dt_get_by_idx(const void *fdt, int nodeoffset, 48 unsigned int clk_idx, TEE_Result *res); 49 50 /** 51 * clk_dt_get_by_name - Get a clock matching a name in the "clock-names" 52 * property 53 * 54 * @fdt: Device tree to work on 55 * @nodeoffset: Node offset of the subnode containing a clock property 56 * @name: Clock name to get 57 * @res: Output result code of the operation: 58 * TEE_SUCCESS in case of success 59 * TEE_ERROR_DEFER_DRIVER_INIT if clock is not initialized 60 * Any TEE_Result compliant code in case of error. 61 * 62 * Returns a clk struct pointer matching the name in "clock-names" property or 63 * NULL if no clock match the given name in which case @res provides the 64 * error code. 65 */ 66 struct clk *clk_dt_get_by_name(const void *fdt, int nodeoffset, 67 const char *name, TEE_Result *res); 68 69 /** 70 * clk_dt_get_func - Typedef of function to get clock from devicetree properties 71 * 72 * @args: Pointer to devicetree description of the clock to parse 73 * @data: Pointer to data given at clk_dt_register_clk_provider() call 74 * @res: Output result code of the operation: 75 * TEE_SUCCESS in case of success 76 * TEE_ERROR_DEFER_DRIVER_INIT if clock is not initialized 77 * Any TEE_Result compliant code in case of error. 78 * 79 * Returns a clk struct pointer pointing to a clock matching the devicetree 80 * description or NULL if invalid description in which case @res provides the 81 * error code. 82 */ 83 typedef struct clk *(*clk_dt_get_func)(struct dt_driver_phandle_args *args, 84 void *data, TEE_Result *res); 85 86 /** 87 * clk_dt_register_clk_provider - Register a clock provider 88 * 89 * @fdt: Device tree to work on 90 * @nodeoffset: Node offset of the clock 91 * @get_dt_clk: Callback to match the devicetree clock with a clock struct 92 * @data: Data which will be passed to the get_dt_clk callback 93 * Returns TEE_Result value 94 */ 95 static inline 96 TEE_Result clk_dt_register_clk_provider(const void *fdt, int nodeoffset, 97 clk_dt_get_func get_dt_clk, void *data) 98 { 99 return dt_driver_register_provider(fdt, nodeoffset, 100 (get_of_device_func)get_dt_clk, 101 data, DT_DRIVER_CLK); 102 } 103 104 /** 105 * clk_dt_get_simple_clk: simple clock matching function for single clock 106 * providers 107 */ 108 static inline 109 struct clk *clk_dt_get_simple_clk(struct dt_driver_phandle_args *args __unused, 110 void *data, TEE_Result *res) 111 { 112 *res = TEE_SUCCESS; 113 114 return data; 115 } 116 117 #endif /* __DRIVERS_CLK_DT_H */ 118