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