17
17
#include <linux/of.h>
18
18
#include <linux/math64.h>
19
19
#include <linux/module.h>
20
+ #include <linux/overflow.h>
20
21
#include <linux/err.h>
21
22
#include <linux/iopoll.h>
22
23
@@ -121,26 +122,24 @@ enum clk_wzrd_int_clks {
121
122
/**
122
123
* struct clk_wzrd - Clock wizard private data structure
123
124
*
124
- * @clk_data: Clock data
125
125
* @nb: Notifier block
126
126
* @base: Memory base
127
127
* @clk_in1: Handle to input clock 'clk_in1'
128
128
* @axi_clk: Handle to input clock 's_axi_aclk'
129
129
* @clks_internal: Internal clocks
130
- * @clkout: Output clocks
131
130
* @speed_grade: Speed grade of the device
132
131
* @suspended: Flag indicating power state of the device
132
+ * @clk_data: Output clock data
133
133
*/
134
134
struct clk_wzrd {
135
- struct clk_onecell_data clk_data ;
136
135
struct notifier_block nb ;
137
136
void __iomem * base ;
138
137
struct clk * clk_in1 ;
139
138
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 ];
142
140
unsigned int speed_grade ;
143
141
bool suspended ;
142
+ struct clk_hw_onecell_data clk_data ;
144
143
};
145
144
146
145
/**
@@ -765,7 +764,7 @@ static const struct clk_ops clk_wzrd_clk_divider_ops_f = {
765
764
.recalc_rate = clk_wzrd_recalc_ratef ,
766
765
};
767
766
768
- static struct clk * clk_wzrd_register_divf (struct device * dev ,
767
+ static struct clk_hw * clk_wzrd_register_divf (struct device * dev ,
769
768
const char * name ,
770
769
const char * parent_name ,
771
770
unsigned long flags ,
@@ -805,10 +804,10 @@ static struct clk *clk_wzrd_register_divf(struct device *dev,
805
804
if (ret )
806
805
return ERR_PTR (ret );
807
806
808
- return hw -> clk ;
807
+ return hw ;
809
808
}
810
809
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 ,
812
811
const char * name ,
813
812
const char * parent_name ,
814
813
unsigned long flags ,
@@ -852,10 +851,10 @@ static struct clk *clk_wzrd_ver_register_divider(struct device *dev,
852
851
if (ret )
853
852
return ERR_PTR (ret );
854
853
855
- return hw -> clk ;
854
+ return hw ;
856
855
}
857
856
858
- static struct clk * clk_wzrd_register_divider (struct device * dev ,
857
+ static struct clk_hw * clk_wzrd_register_divider (struct device * dev ,
859
858
const char * name ,
860
859
const char * parent_name ,
861
860
unsigned long flags ,
@@ -898,7 +897,7 @@ static struct clk *clk_wzrd_register_divider(struct device *dev,
898
897
if (ret )
899
898
return ERR_PTR (ret );
900
899
901
- return hw -> clk ;
900
+ return hw ;
902
901
}
903
902
904
903
static 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)
978
977
int nr_outputs ;
979
978
int i , ret ;
980
979
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 );
982
986
if (!clk_wzrd )
983
987
return - ENOMEM ;
984
988
platform_set_drvdata (pdev , clk_wzrd );
@@ -1016,17 +1020,13 @@ static int clk_wzrd_probe(struct platform_device *pdev)
1016
1020
if (data )
1017
1021
is_versal = data -> is_versal ;
1018
1022
1019
- ret = of_property_read_u32 (np , "xlnx,nr-outputs" , & nr_outputs );
1020
- if (ret || nr_outputs > WZRD_NUM_OUTPUTS )
1021
- return - EINVAL ;
1022
-
1023
1023
clkout_name = devm_kasprintf (& pdev -> dev , GFP_KERNEL , "%s_out0" , dev_name (& pdev -> dev ));
1024
1024
if (!clkout_name )
1025
1025
return - ENOMEM ;
1026
1026
1027
1027
if (is_versal ) {
1028
1028
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
1030
1030
(& pdev -> dev , clkout_name ,
1031
1031
__clk_get_name (clk_wzrd -> clk_in1 ), 0 ,
1032
1032
clk_wzrd -> base , WZRD_CLK_CFG_REG (is_versal , 3 ),
@@ -1059,7 +1059,7 @@ static int clk_wzrd_probe(struct platform_device *pdev)
1059
1059
div = 64 ;
1060
1060
} else {
1061
1061
if (nr_outputs == 1 ) {
1062
- clk_wzrd -> clkout [0 ] = clk_wzrd_register_divider
1062
+ clk_wzrd -> clk_data . hws [0 ] = clk_wzrd_register_divider
1063
1063
(& pdev -> dev , clkout_name ,
1064
1064
__clk_get_name (clk_wzrd -> clk_in1 ), 0 ,
1065
1065
clk_wzrd -> base , WZRD_CLK_CFG_REG (is_versal , 3 ),
@@ -1082,7 +1082,7 @@ static int clk_wzrd_probe(struct platform_device *pdev)
1082
1082
clk_name = devm_kasprintf (& pdev -> dev , GFP_KERNEL , "%s_mul" , dev_name (& pdev -> dev ));
1083
1083
if (!clk_name )
1084
1084
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
1086
1086
(& pdev -> dev , clk_name ,
1087
1087
__clk_get_name (clk_wzrd -> clk_in1 ),
1088
1088
0 , mult , div );
@@ -1108,15 +1108,15 @@ static int clk_wzrd_probe(struct platform_device *pdev)
1108
1108
if (!div )
1109
1109
div = 1 ;
1110
1110
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 ]);
1112
1112
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 );
1115
1115
} else {
1116
1116
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
1118
1118
(& 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 ]),
1120
1120
flags , ctrl_reg , 0 , 8 , CLK_DIVIDER_ONE_BASED |
1121
1121
CLK_DIVIDER_ALLOW_ZERO , & clkwzrd_lock );
1122
1122
}
@@ -1136,7 +1136,7 @@ static int clk_wzrd_probe(struct platform_device *pdev)
1136
1136
}
1137
1137
1138
1138
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
1140
1140
(& pdev -> dev ,
1141
1141
clkout_name , clk_name , 0 ,
1142
1142
clk_wzrd -> base ,
@@ -1148,38 +1148,41 @@ static int clk_wzrd_probe(struct platform_device *pdev)
1148
1148
DIV_O , & clkwzrd_lock );
1149
1149
} else {
1150
1150
if (!i )
1151
- clk_wzrd -> clkout [i ] = clk_wzrd_register_divf
1151
+ clk_wzrd -> clk_data . hws [i ] = clk_wzrd_register_divf
1152
1152
(& pdev -> dev , clkout_name , clk_name , flags , clk_wzrd -> base ,
1153
1153
(WZRD_CLK_CFG_REG (is_versal , 2 ) + i * 12 ),
1154
1154
WZRD_CLKOUT_DIVIDE_SHIFT ,
1155
1155
WZRD_CLKOUT_DIVIDE_WIDTH ,
1156
1156
CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO ,
1157
1157
DIV_O , & clkwzrd_lock );
1158
1158
else
1159
- clk_wzrd -> clkout [i ] = clk_wzrd_register_divider
1159
+ clk_wzrd -> clk_data . hws [i ] = clk_wzrd_register_divider
1160
1160
(& pdev -> dev , clkout_name , clk_name , 0 , clk_wzrd -> base ,
1161
1161
(WZRD_CLK_CFG_REG (is_versal , 2 ) + i * 12 ),
1162
1162
WZRD_CLKOUT_DIVIDE_SHIFT ,
1163
1163
WZRD_CLKOUT_DIVIDE_WIDTH ,
1164
1164
CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO ,
1165
1165
DIV_O , & clkwzrd_lock );
1166
1166
}
1167
- if (IS_ERR (clk_wzrd -> clkout [i ])) {
1167
+ if (IS_ERR (clk_wzrd -> clk_data . hws [i ])) {
1168
1168
int j ;
1169
1169
1170
1170
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 ]);
1172
1172
dev_err (& pdev -> dev ,
1173
1173
"unable to register divider clock\n" );
1174
- ret = PTR_ERR (clk_wzrd -> clkout [i ]);
1174
+ ret = PTR_ERR (clk_wzrd -> clk_data . hws [i ]);
1175
1175
goto err_rm_int_clks ;
1176
1176
}
1177
1177
}
1178
1178
1179
1179
out :
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
+ }
1183
1186
1184
1187
if (clk_wzrd -> speed_grade ) {
1185
1188
clk_wzrd -> nb .notifier_call = clk_wzrd_clk_notifier ;
@@ -1200,9 +1203,9 @@ static int clk_wzrd_probe(struct platform_device *pdev)
1200
1203
return 0 ;
1201
1204
1202
1205
err_rm_int_clks :
1203
- clk_unregister (clk_wzrd -> clks_internal [1 ]);
1206
+ clk_hw_unregister (clk_wzrd -> clks_internal [1 ]);
1204
1207
err_rm_int_clk :
1205
- clk_unregister (clk_wzrd -> clks_internal [0 ]);
1208
+ clk_hw_unregister (clk_wzrd -> clks_internal [0 ]);
1206
1209
return ret ;
1207
1210
}
1208
1211
@@ -1214,9 +1217,9 @@ static void clk_wzrd_remove(struct platform_device *pdev)
1214
1217
of_clk_del_provider (pdev -> dev .of_node );
1215
1218
1216
1219
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 ]);
1218
1221
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 ]);
1220
1223
}
1221
1224
1222
1225
static const struct of_device_id clk_wzrd_ids [] = {
0 commit comments