@@ -962,80 +962,38 @@ static const struct versal_clk_data versal_data = {
962
962
.is_versal = true,
963
963
};
964
964
965
- static int clk_wzrd_probe (struct platform_device * pdev )
965
+ static int clk_wzrd_register_output_clocks (struct device * dev , int nr_outputs )
966
966
{
967
967
const char * clkout_name , * clk_name , * clk_mul_name ;
968
+ struct clk_wzrd * clk_wzrd = dev_get_drvdata (dev );
968
969
u32 regl , regh , edge , regld , reghd , edged , div ;
969
- struct device_node * np = pdev -> dev .of_node ;
970
970
const struct versal_clk_data * data ;
971
- struct clk_wzrd * clk_wzrd ;
972
971
unsigned long flags = 0 ;
972
+ bool is_versal = false;
973
973
void __iomem * ctrl_reg ;
974
974
u32 reg , reg_f , mult ;
975
- bool is_versal = false;
976
- unsigned long rate ;
977
- int nr_outputs ;
978
- int i , ret ;
979
-
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 );
986
- if (!clk_wzrd )
987
- return - ENOMEM ;
988
- platform_set_drvdata (pdev , clk_wzrd );
989
-
990
- clk_wzrd -> base = devm_platform_ioremap_resource (pdev , 0 );
991
- if (IS_ERR (clk_wzrd -> base ))
992
- return PTR_ERR (clk_wzrd -> base );
993
-
994
- ret = of_property_read_u32 (np , "xlnx,speed-grade" , & clk_wzrd -> speed_grade );
995
- if (!ret ) {
996
- if (clk_wzrd -> speed_grade < 1 || clk_wzrd -> speed_grade > 3 ) {
997
- dev_warn (& pdev -> dev , "invalid speed grade '%d'\n" ,
998
- clk_wzrd -> speed_grade );
999
- clk_wzrd -> speed_grade = 0 ;
1000
- }
1001
- }
1002
-
1003
- clk_wzrd -> clk_in1 = devm_clk_get (& pdev -> dev , "clk_in1" );
1004
- if (IS_ERR (clk_wzrd -> clk_in1 ))
1005
- return dev_err_probe (& pdev -> dev , PTR_ERR (clk_wzrd -> clk_in1 ),
1006
- "clk_in1 not found\n" );
975
+ int i ;
1007
976
1008
- clk_wzrd -> axi_clk = devm_clk_get_enabled (& pdev -> dev , "s_axi_aclk" );
1009
- if (IS_ERR (clk_wzrd -> axi_clk ))
1010
- return dev_err_probe (& pdev -> dev , PTR_ERR (clk_wzrd -> axi_clk ),
1011
- "s_axi_aclk not found\n" );
1012
- rate = clk_get_rate (clk_wzrd -> axi_clk );
1013
- if (rate > WZRD_ACLK_MAX_FREQ ) {
1014
- dev_err (& pdev -> dev , "s_axi_aclk frequency (%lu) too high\n" ,
1015
- rate );
1016
- return - EINVAL ;
1017
- }
1018
-
1019
- data = device_get_match_data (& pdev -> dev );
977
+ data = device_get_match_data (dev );
1020
978
if (data )
1021
979
is_versal = data -> is_versal ;
1022
980
1023
- clkout_name = devm_kasprintf (& pdev -> dev , GFP_KERNEL , "%s_out0" , dev_name (& pdev -> dev ));
981
+ clkout_name = devm_kasprintf (dev , GFP_KERNEL , "%s_out0" , dev_name (dev ));
1024
982
if (!clkout_name )
1025
983
return - ENOMEM ;
1026
984
1027
985
if (is_versal ) {
1028
986
if (nr_outputs == 1 ) {
1029
987
clk_wzrd -> clk_data .hws [0 ] = clk_wzrd_ver_register_divider
1030
- (& pdev -> dev , clkout_name ,
988
+ (dev , clkout_name ,
1031
989
__clk_get_name (clk_wzrd -> clk_in1 ), 0 ,
1032
990
clk_wzrd -> base , WZRD_CLK_CFG_REG (is_versal , 3 ),
1033
991
WZRD_CLKOUT_DIVIDE_SHIFT ,
1034
992
WZRD_CLKOUT_DIVIDE_WIDTH ,
1035
993
CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO ,
1036
994
DIV_ALL , & clkwzrd_lock );
1037
995
1038
- goto out ;
996
+ return 0 ;
1039
997
}
1040
998
/* register multiplier */
1041
999
edge = !!(readl (clk_wzrd -> base + WZRD_CLK_CFG_REG (is_versal , 0 )) &
@@ -1060,15 +1018,15 @@ static int clk_wzrd_probe(struct platform_device *pdev)
1060
1018
} else {
1061
1019
if (nr_outputs == 1 ) {
1062
1020
clk_wzrd -> clk_data .hws [0 ] = clk_wzrd_register_divider
1063
- (& pdev -> dev , clkout_name ,
1021
+ (dev , clkout_name ,
1064
1022
__clk_get_name (clk_wzrd -> clk_in1 ), 0 ,
1065
1023
clk_wzrd -> base , WZRD_CLK_CFG_REG (is_versal , 3 ),
1066
1024
WZRD_CLKOUT_DIVIDE_SHIFT ,
1067
1025
WZRD_CLKOUT_DIVIDE_WIDTH ,
1068
1026
CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO ,
1069
1027
DIV_ALL , & clkwzrd_lock );
1070
1028
1071
- goto out ;
1029
+ return 0 ;
1072
1030
}
1073
1031
reg = readl (clk_wzrd -> base + WZRD_CLK_CFG_REG (is_versal , 0 ));
1074
1032
reg_f = reg & WZRD_CLKFBOUT_FRAC_MASK ;
@@ -1079,19 +1037,19 @@ static int clk_wzrd_probe(struct platform_device *pdev)
1079
1037
mult = (reg * 1000 ) + reg_f ;
1080
1038
div = 1000 ;
1081
1039
}
1082
- clk_name = devm_kasprintf (& pdev -> dev , GFP_KERNEL , "%s_mul" , dev_name (& pdev -> dev ));
1040
+ clk_name = devm_kasprintf (dev , GFP_KERNEL , "%s_mul" , dev_name (dev ));
1083
1041
if (!clk_name )
1084
1042
return - ENOMEM ;
1085
1043
clk_wzrd -> clks_internal [wzrd_clk_mul ] = devm_clk_hw_register_fixed_factor
1086
- (& pdev -> dev , clk_name ,
1044
+ (dev , clk_name ,
1087
1045
__clk_get_name (clk_wzrd -> clk_in1 ),
1088
1046
0 , mult , div );
1089
1047
if (IS_ERR (clk_wzrd -> clks_internal [wzrd_clk_mul ])) {
1090
- dev_err (& pdev -> dev , "unable to register fixed-factor clock\n" );
1048
+ dev_err (dev , "unable to register fixed-factor clock\n" );
1091
1049
return PTR_ERR (clk_wzrd -> clks_internal [wzrd_clk_mul ]);
1092
1050
}
1093
1051
1094
- clk_name = devm_kasprintf (& pdev -> dev , GFP_KERNEL , "%s_mul_div" , dev_name (& pdev -> dev ));
1052
+ clk_name = devm_kasprintf (dev , GFP_KERNEL , "%s_mul_div" , dev_name (dev ));
1095
1053
if (!clk_name )
1096
1054
return - ENOMEM ;
1097
1055
@@ -1108,31 +1066,29 @@ static int clk_wzrd_probe(struct platform_device *pdev)
1108
1066
1109
1067
clk_mul_name = clk_hw_get_name (clk_wzrd -> clks_internal [wzrd_clk_mul ]);
1110
1068
clk_wzrd -> clks_internal [wzrd_clk_mul_div ] =
1111
- devm_clk_hw_register_fixed_factor (& pdev -> dev , clk_name ,
1112
- clk_mul_name , 0 , 1 , div );
1069
+ devm_clk_hw_register_fixed_factor (dev , clk_name , clk_mul_name , 0 , 1 , div );
1113
1070
} else {
1114
1071
ctrl_reg = clk_wzrd -> base + WZRD_CLK_CFG_REG (is_versal , 0 );
1115
1072
clk_wzrd -> clks_internal [wzrd_clk_mul_div ] = devm_clk_hw_register_divider
1116
- (& pdev -> dev , clk_name ,
1073
+ (dev , clk_name ,
1117
1074
clk_hw_get_name (clk_wzrd -> clks_internal [wzrd_clk_mul ]),
1118
1075
flags , ctrl_reg , 0 , 8 , CLK_DIVIDER_ONE_BASED |
1119
1076
CLK_DIVIDER_ALLOW_ZERO , & clkwzrd_lock );
1120
1077
}
1121
1078
if (IS_ERR (clk_wzrd -> clks_internal [wzrd_clk_mul_div ])) {
1122
- dev_err (& pdev -> dev , "unable to register divider clock\n" );
1079
+ dev_err (dev , "unable to register divider clock\n" );
1123
1080
return PTR_ERR (clk_wzrd -> clks_internal [wzrd_clk_mul_div ]);
1124
1081
}
1125
1082
1126
1083
/* register div per output */
1127
1084
for (i = nr_outputs - 1 ; i >= 0 ; i -- ) {
1128
- clkout_name = devm_kasprintf (& pdev -> dev , GFP_KERNEL ,
1129
- "%s_out%d" , dev_name (& pdev -> dev ), i );
1085
+ clkout_name = devm_kasprintf (dev , GFP_KERNEL , "%s_out%d" , dev_name (dev ), i );
1130
1086
if (!clkout_name )
1131
1087
return - ENOMEM ;
1132
1088
1133
1089
if (is_versal ) {
1134
1090
clk_wzrd -> clk_data .hws [i ] = clk_wzrd_ver_register_divider
1135
- (& pdev -> dev ,
1091
+ (dev ,
1136
1092
clkout_name , clk_name , 0 ,
1137
1093
clk_wzrd -> base ,
1138
1094
(WZRD_CLK_CFG_REG (is_versal , 3 ) + i * 8 ),
@@ -1144,29 +1100,80 @@ static int clk_wzrd_probe(struct platform_device *pdev)
1144
1100
} else {
1145
1101
if (!i )
1146
1102
clk_wzrd -> clk_data .hws [i ] = clk_wzrd_register_divf
1147
- (& pdev -> dev , clkout_name , clk_name , flags , clk_wzrd -> base ,
1103
+ (dev , clkout_name , clk_name , flags , clk_wzrd -> base ,
1148
1104
(WZRD_CLK_CFG_REG (is_versal , 2 ) + i * 12 ),
1149
1105
WZRD_CLKOUT_DIVIDE_SHIFT ,
1150
1106
WZRD_CLKOUT_DIVIDE_WIDTH ,
1151
1107
CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO ,
1152
1108
DIV_O , & clkwzrd_lock );
1153
1109
else
1154
1110
clk_wzrd -> clk_data .hws [i ] = clk_wzrd_register_divider
1155
- (& pdev -> dev , clkout_name , clk_name , 0 , clk_wzrd -> base ,
1111
+ (dev , clkout_name , clk_name , 0 , clk_wzrd -> base ,
1156
1112
(WZRD_CLK_CFG_REG (is_versal , 2 ) + i * 12 ),
1157
1113
WZRD_CLKOUT_DIVIDE_SHIFT ,
1158
1114
WZRD_CLKOUT_DIVIDE_WIDTH ,
1159
1115
CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO ,
1160
1116
DIV_O , & clkwzrd_lock );
1161
1117
}
1162
1118
if (IS_ERR (clk_wzrd -> clk_data .hws [i ])) {
1163
- dev_err (& pdev -> dev ,
1164
- "unable to register divider clock\n" );
1119
+ dev_err (dev , "unable to register divider clock\n" );
1165
1120
return PTR_ERR (clk_wzrd -> clk_data .hws [i ]);
1166
1121
}
1167
1122
}
1168
1123
1169
- out :
1124
+ return 0 ;
1125
+ }
1126
+
1127
+ static int clk_wzrd_probe (struct platform_device * pdev )
1128
+ {
1129
+ struct device_node * np = pdev -> dev .of_node ;
1130
+ struct clk_wzrd * clk_wzrd ;
1131
+ unsigned long rate ;
1132
+ int nr_outputs ;
1133
+ int ret ;
1134
+
1135
+ ret = of_property_read_u32 (np , "xlnx,nr-outputs" , & nr_outputs );
1136
+ if (ret || nr_outputs > WZRD_NUM_OUTPUTS )
1137
+ return - EINVAL ;
1138
+
1139
+ clk_wzrd = devm_kzalloc (& pdev -> dev , struct_size (clk_wzrd , clk_data .hws , nr_outputs ),
1140
+ GFP_KERNEL );
1141
+ if (!clk_wzrd )
1142
+ return - ENOMEM ;
1143
+ platform_set_drvdata (pdev , clk_wzrd );
1144
+
1145
+ clk_wzrd -> base = devm_platform_ioremap_resource (pdev , 0 );
1146
+ if (IS_ERR (clk_wzrd -> base ))
1147
+ return PTR_ERR (clk_wzrd -> base );
1148
+
1149
+ ret = of_property_read_u32 (np , "xlnx,speed-grade" , & clk_wzrd -> speed_grade );
1150
+ if (!ret ) {
1151
+ if (clk_wzrd -> speed_grade < 1 || clk_wzrd -> speed_grade > 3 ) {
1152
+ dev_warn (& pdev -> dev , "invalid speed grade '%d'\n" ,
1153
+ clk_wzrd -> speed_grade );
1154
+ clk_wzrd -> speed_grade = 0 ;
1155
+ }
1156
+ }
1157
+
1158
+ clk_wzrd -> clk_in1 = devm_clk_get (& pdev -> dev , "clk_in1" );
1159
+ if (IS_ERR (clk_wzrd -> clk_in1 ))
1160
+ return dev_err_probe (& pdev -> dev , PTR_ERR (clk_wzrd -> clk_in1 ),
1161
+ "clk_in1 not found\n" );
1162
+
1163
+ clk_wzrd -> axi_clk = devm_clk_get_enabled (& pdev -> dev , "s_axi_aclk" );
1164
+ if (IS_ERR (clk_wzrd -> axi_clk ))
1165
+ return dev_err_probe (& pdev -> dev , PTR_ERR (clk_wzrd -> axi_clk ),
1166
+ "s_axi_aclk not found\n" );
1167
+ rate = clk_get_rate (clk_wzrd -> axi_clk );
1168
+ if (rate > WZRD_ACLK_MAX_FREQ ) {
1169
+ dev_err (& pdev -> dev , "s_axi_aclk frequency (%lu) too high\n" , rate );
1170
+ return - EINVAL ;
1171
+ }
1172
+
1173
+ ret = clk_wzrd_register_output_clocks (& pdev -> dev , nr_outputs );
1174
+ if (ret )
1175
+ return ret ;
1176
+
1170
1177
clk_wzrd -> clk_data .num = nr_outputs ;
1171
1178
ret = devm_of_clk_add_hw_provider (& pdev -> dev , of_clk_hw_onecell_get , & clk_wzrd -> clk_data );
1172
1179
if (ret ) {
0 commit comments