1717#include <linux/of.h>
1818#include <linux/math64.h>
1919#include <linux/module.h>
20+ #include <linux/overflow.h>
2021#include <linux/err.h>
2122#include <linux/iopoll.h>
2223
@@ -121,26 +122,24 @@ enum clk_wzrd_int_clks {
121122/**
122123 * struct clk_wzrd - Clock wizard private data structure
123124 *
124- * @clk_data: Clock data
125125 * @nb: Notifier block
126126 * @base: Memory base
127127 * @clk_in1: Handle to input clock 'clk_in1'
128128 * @axi_clk: Handle to input clock 's_axi_aclk'
129129 * @clks_internal: Internal clocks
130- * @clkout: Output clocks
131130 * @speed_grade: Speed grade of the device
132131 * @suspended: Flag indicating power state of the device
132+ * @clk_data: Output clock data
133133 */
134134struct clk_wzrd {
135- struct clk_onecell_data clk_data ;
136135 struct notifier_block nb ;
137136 void __iomem * base ;
138137 struct clk * clk_in1 ;
139138 struct clk * axi_clk ;
140- struct clk * clks_internal [wzrd_clk_int_max ];
141- struct clk * clkout [WZRD_NUM_OUTPUTS ];
139+ struct clk_hw * clks_internal [wzrd_clk_int_max ];
142140 unsigned int speed_grade ;
143141 bool suspended ;
142+ struct clk_hw_onecell_data clk_data ;
144143};
145144
146145/**
@@ -765,7 +764,7 @@ static const struct clk_ops clk_wzrd_clk_divider_ops_f = {
765764 .recalc_rate = clk_wzrd_recalc_ratef ,
766765};
767766
768- static struct clk * clk_wzrd_register_divf (struct device * dev ,
767+ static struct clk_hw * clk_wzrd_register_divf (struct device * dev ,
769768 const char * name ,
770769 const char * parent_name ,
771770 unsigned long flags ,
@@ -805,10 +804,10 @@ static struct clk *clk_wzrd_register_divf(struct device *dev,
805804 if (ret )
806805 return ERR_PTR (ret );
807806
808- return hw -> clk ;
807+ return hw ;
809808}
810809
811- static struct clk * clk_wzrd_ver_register_divider (struct device * dev ,
810+ static struct clk_hw * clk_wzrd_ver_register_divider (struct device * dev ,
812811 const char * name ,
813812 const char * parent_name ,
814813 unsigned long flags ,
@@ -852,10 +851,10 @@ static struct clk *clk_wzrd_ver_register_divider(struct device *dev,
852851 if (ret )
853852 return ERR_PTR (ret );
854853
855- return hw -> clk ;
854+ return hw ;
856855}
857856
858- static struct clk * clk_wzrd_register_divider (struct device * dev ,
857+ static struct clk_hw * clk_wzrd_register_divider (struct device * dev ,
859858 const char * name ,
860859 const char * parent_name ,
861860 unsigned long flags ,
@@ -898,7 +897,7 @@ static struct clk *clk_wzrd_register_divider(struct device *dev,
898897 if (ret )
899898 return ERR_PTR (ret );
900899
901- return hw -> clk ;
900+ return hw ;
902901}
903902
904903static int clk_wzrd_clk_notifier (struct notifier_block * nb , unsigned long event ,
@@ -978,7 +977,12 @@ static int clk_wzrd_probe(struct platform_device *pdev)
978977 int nr_outputs ;
979978 int i , ret ;
980979
981- clk_wzrd = devm_kzalloc (& pdev -> dev , sizeof (* clk_wzrd ), GFP_KERNEL );
980+ ret = of_property_read_u32 (np , "xlnx,nr-outputs" , & nr_outputs );
981+ if (ret || nr_outputs > WZRD_NUM_OUTPUTS )
982+ return - EINVAL ;
983+
984+ clk_wzrd = devm_kzalloc (& pdev -> dev , struct_size (clk_wzrd , clk_data .hws , nr_outputs ),
985+ GFP_KERNEL );
982986 if (!clk_wzrd )
983987 return - ENOMEM ;
984988 platform_set_drvdata (pdev , clk_wzrd );
@@ -1016,17 +1020,13 @@ static int clk_wzrd_probe(struct platform_device *pdev)
10161020 if (data )
10171021 is_versal = data -> is_versal ;
10181022
1019- ret = of_property_read_u32 (np , "xlnx,nr-outputs" , & nr_outputs );
1020- if (ret || nr_outputs > WZRD_NUM_OUTPUTS )
1021- return - EINVAL ;
1022-
10231023 clkout_name = devm_kasprintf (& pdev -> dev , GFP_KERNEL , "%s_out0" , dev_name (& pdev -> dev ));
10241024 if (!clkout_name )
10251025 return - ENOMEM ;
10261026
10271027 if (is_versal ) {
10281028 if (nr_outputs == 1 ) {
1029- clk_wzrd -> clkout [0 ] = clk_wzrd_ver_register_divider
1029+ clk_wzrd -> clk_data . hws [0 ] = clk_wzrd_ver_register_divider
10301030 (& pdev -> dev , clkout_name ,
10311031 __clk_get_name (clk_wzrd -> clk_in1 ), 0 ,
10321032 clk_wzrd -> base , WZRD_CLK_CFG_REG (is_versal , 3 ),
@@ -1059,7 +1059,7 @@ static int clk_wzrd_probe(struct platform_device *pdev)
10591059 div = 64 ;
10601060 } else {
10611061 if (nr_outputs == 1 ) {
1062- clk_wzrd -> clkout [0 ] = clk_wzrd_register_divider
1062+ clk_wzrd -> clk_data . hws [0 ] = clk_wzrd_register_divider
10631063 (& pdev -> dev , clkout_name ,
10641064 __clk_get_name (clk_wzrd -> clk_in1 ), 0 ,
10651065 clk_wzrd -> base , WZRD_CLK_CFG_REG (is_versal , 3 ),
@@ -1082,7 +1082,7 @@ static int clk_wzrd_probe(struct platform_device *pdev)
10821082 clk_name = devm_kasprintf (& pdev -> dev , GFP_KERNEL , "%s_mul" , dev_name (& pdev -> dev ));
10831083 if (!clk_name )
10841084 return - ENOMEM ;
1085- clk_wzrd -> clks_internal [wzrd_clk_mul ] = clk_register_fixed_factor
1085+ clk_wzrd -> clks_internal [wzrd_clk_mul ] = clk_hw_register_fixed_factor
10861086 (& pdev -> dev , clk_name ,
10871087 __clk_get_name (clk_wzrd -> clk_in1 ),
10881088 0 , mult , div );
@@ -1108,15 +1108,15 @@ static int clk_wzrd_probe(struct platform_device *pdev)
11081108 if (!div )
11091109 div = 1 ;
11101110
1111- clk_mul_name = __clk_get_name (clk_wzrd -> clks_internal [wzrd_clk_mul ]);
1111+ clk_mul_name = clk_hw_get_name (clk_wzrd -> clks_internal [wzrd_clk_mul ]);
11121112 clk_wzrd -> clks_internal [wzrd_clk_mul_div ] =
1113- clk_register_fixed_factor (& pdev -> dev , clk_name ,
1114- clk_mul_name , 0 , 1 , div );
1113+ clk_hw_register_fixed_factor (& pdev -> dev , clk_name ,
1114+ clk_mul_name , 0 , 1 , div );
11151115 } else {
11161116 ctrl_reg = clk_wzrd -> base + WZRD_CLK_CFG_REG (is_versal , 0 );
1117- clk_wzrd -> clks_internal [wzrd_clk_mul_div ] = clk_register_divider
1117+ clk_wzrd -> clks_internal [wzrd_clk_mul_div ] = clk_hw_register_divider
11181118 (& pdev -> dev , clk_name ,
1119- __clk_get_name (clk_wzrd -> clks_internal [wzrd_clk_mul ]),
1119+ clk_hw_get_name (clk_wzrd -> clks_internal [wzrd_clk_mul ]),
11201120 flags , ctrl_reg , 0 , 8 , CLK_DIVIDER_ONE_BASED |
11211121 CLK_DIVIDER_ALLOW_ZERO , & clkwzrd_lock );
11221122 }
@@ -1136,7 +1136,7 @@ static int clk_wzrd_probe(struct platform_device *pdev)
11361136 }
11371137
11381138 if (is_versal ) {
1139- clk_wzrd -> clkout [i ] = clk_wzrd_ver_register_divider
1139+ clk_wzrd -> clk_data . hws [i ] = clk_wzrd_ver_register_divider
11401140 (& pdev -> dev ,
11411141 clkout_name , clk_name , 0 ,
11421142 clk_wzrd -> base ,
@@ -1148,38 +1148,41 @@ static int clk_wzrd_probe(struct platform_device *pdev)
11481148 DIV_O , & clkwzrd_lock );
11491149 } else {
11501150 if (!i )
1151- clk_wzrd -> clkout [i ] = clk_wzrd_register_divf
1151+ clk_wzrd -> clk_data . hws [i ] = clk_wzrd_register_divf
11521152 (& pdev -> dev , clkout_name , clk_name , flags , clk_wzrd -> base ,
11531153 (WZRD_CLK_CFG_REG (is_versal , 2 ) + i * 12 ),
11541154 WZRD_CLKOUT_DIVIDE_SHIFT ,
11551155 WZRD_CLKOUT_DIVIDE_WIDTH ,
11561156 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO ,
11571157 DIV_O , & clkwzrd_lock );
11581158 else
1159- clk_wzrd -> clkout [i ] = clk_wzrd_register_divider
1159+ clk_wzrd -> clk_data . hws [i ] = clk_wzrd_register_divider
11601160 (& pdev -> dev , clkout_name , clk_name , 0 , clk_wzrd -> base ,
11611161 (WZRD_CLK_CFG_REG (is_versal , 2 ) + i * 12 ),
11621162 WZRD_CLKOUT_DIVIDE_SHIFT ,
11631163 WZRD_CLKOUT_DIVIDE_WIDTH ,
11641164 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO ,
11651165 DIV_O , & clkwzrd_lock );
11661166 }
1167- if (IS_ERR (clk_wzrd -> clkout [i ])) {
1167+ if (IS_ERR (clk_wzrd -> clk_data . hws [i ])) {
11681168 int j ;
11691169
11701170 for (j = i + 1 ; j < nr_outputs ; j ++ )
1171- clk_unregister (clk_wzrd -> clkout [j ]);
1171+ clk_hw_unregister (clk_wzrd -> clk_data . hws [j ]);
11721172 dev_err (& pdev -> dev ,
11731173 "unable to register divider clock\n" );
1174- ret = PTR_ERR (clk_wzrd -> clkout [i ]);
1174+ ret = PTR_ERR (clk_wzrd -> clk_data . hws [i ]);
11751175 goto err_rm_int_clks ;
11761176 }
11771177 }
11781178
11791179out :
1180- clk_wzrd -> clk_data .clks = clk_wzrd -> clkout ;
1181- clk_wzrd -> clk_data .clk_num = ARRAY_SIZE (clk_wzrd -> clkout );
1182- of_clk_add_provider (np , of_clk_src_onecell_get , & clk_wzrd -> clk_data );
1180+ clk_wzrd -> clk_data .num = nr_outputs ;
1181+ ret = of_clk_add_hw_provider (pdev -> dev .of_node , of_clk_hw_onecell_get , & clk_wzrd -> clk_data );
1182+ if (ret ) {
1183+ dev_err (& pdev -> dev , "unable to register clock provider\n" );
1184+ return ret ;
1185+ }
11831186
11841187 if (clk_wzrd -> speed_grade ) {
11851188 clk_wzrd -> nb .notifier_call = clk_wzrd_clk_notifier ;
@@ -1200,9 +1203,9 @@ static int clk_wzrd_probe(struct platform_device *pdev)
12001203 return 0 ;
12011204
12021205err_rm_int_clks :
1203- clk_unregister (clk_wzrd -> clks_internal [1 ]);
1206+ clk_hw_unregister (clk_wzrd -> clks_internal [1 ]);
12041207err_rm_int_clk :
1205- clk_unregister (clk_wzrd -> clks_internal [0 ]);
1208+ clk_hw_unregister (clk_wzrd -> clks_internal [0 ]);
12061209 return ret ;
12071210}
12081211
@@ -1214,9 +1217,9 @@ static void clk_wzrd_remove(struct platform_device *pdev)
12141217 of_clk_del_provider (pdev -> dev .of_node );
12151218
12161219 for (i = 0 ; i < WZRD_NUM_OUTPUTS ; i ++ )
1217- clk_unregister (clk_wzrd -> clkout [i ]);
1220+ clk_hw_unregister (clk_wzrd -> clk_data . hws [i ]);
12181221 for (i = 0 ; i < wzrd_clk_int_max ; i ++ )
1219- clk_unregister (clk_wzrd -> clks_internal [i ]);
1222+ clk_hw_unregister (clk_wzrd -> clks_internal [i ]);
12201223}
12211224
12221225static const struct of_device_id clk_wzrd_ids [] = {
0 commit comments