@@ -757,6 +757,7 @@ static int adxcvr_clk_register(struct device *dev,
757
757
{
758
758
struct adxcvr_state * st = dev_get_drvdata (dev );
759
759
unsigned int out_clk_divider , out_clk_multiplier ;
760
+ struct clk_hw * fixed_factor ;
760
761
struct clk_init_data init ;
761
762
const char * clk_names [3 ];
762
763
unsigned int num_clks ;
@@ -784,13 +785,18 @@ static int adxcvr_clk_register(struct device *dev,
784
785
st -> lane_clk_hw .init = & init ;
785
786
786
787
/* register the clock */
787
- st -> clks [ 0 ] = devm_clk_register (dev , & st -> lane_clk_hw );
788
- if (IS_ERR ( st -> clks [ 0 ]) )
789
- return PTR_ERR ( st -> clks [ 0 ]) ;
788
+ ret = devm_clk_hw_register (dev , & st -> lane_clk_hw );
789
+ if (ret )
790
+ return ret ;
790
791
791
792
/* Backwards compatibility */
792
793
if (num_clks == 1 )
793
- return of_clk_add_provider (node , of_clk_src_simple_get , st -> clks [0 ]);
794
+ return devm_of_clk_add_hw_provider (dev , of_clk_hw_simple_get , & st -> lane_clk_hw );
795
+
796
+ st -> clk_lookup = devm_kzalloc (dev , struct_size (st -> clk_lookup , hws , num_clks ),
797
+ GFP_KERNEL );
798
+ if (!st -> clk_lookup )
799
+ return - ENOMEM ;
794
800
795
801
if (num_clks == 3 ) {
796
802
init .name = clk_names [2 ];
@@ -803,9 +809,11 @@ static int adxcvr_clk_register(struct device *dev,
803
809
st -> qpll_clk_hw .init = & init ;
804
810
805
811
/* register the clock */
806
- st -> clks [2 ] = devm_clk_register (dev , & st -> qpll_clk_hw );
807
- if (IS_ERR (st -> clks [2 ]))
808
- return PTR_ERR (st -> clks [2 ]);
812
+ ret = devm_clk_hw_register (dev , & st -> qpll_clk_hw );
813
+ if (ret )
814
+ return ret ;
815
+
816
+ st -> clk_lookup -> hws [2 ] = & st -> qpll_clk_hw ;
809
817
}
810
818
811
819
switch (st -> out_clk_sel ) {
@@ -847,19 +855,16 @@ static int adxcvr_clk_register(struct device *dev,
847
855
return 0 ;
848
856
}
849
857
850
- st -> clks [1 ] = clk_register_fixed_factor (dev , clk_names [1 ],
851
- parent_name , 0 , out_clk_multiplier , out_clk_divider );
852
-
853
- st -> clk_lookup .clks = st -> clks ;
854
- st -> clk_lookup .clk_num = ARRAY_SIZE (st -> clks );
858
+ fixed_factor = devm_clk_hw_register_fixed_factor (dev , clk_names [1 ], parent_name , 0 ,
859
+ out_clk_multiplier , out_clk_divider );
860
+ if (IS_ERR (fixed_factor ))
861
+ return PTR_ERR (fixed_factor );
855
862
856
- ret = of_clk_add_provider (node , of_clk_src_onecell_get ,
857
- & st -> clk_lookup );
858
-
859
- if (ret )
860
- clk_unregister_fixed_factor (st -> clks [1 ]);
863
+ st -> clk_lookup -> hws [0 ] = & st -> lane_clk_hw ;
864
+ st -> clk_lookup -> hws [1 ] = fixed_factor ;
865
+ st -> clk_lookup -> num = num_clks ;
861
866
862
- return ret ;
867
+ return devm_of_clk_add_hw_provider ( dev , of_clk_hw_onecell_get , st -> clk_lookup ) ;
863
868
}
864
869
865
870
static void adxcvr_parse_dt_vco_ranges (struct adxcvr_state * st ,
@@ -974,6 +979,21 @@ static const char *adxcvr_gt_names[] = {
974
979
static const struct jesd204_dev_data adxcvr_jesd204_data = {
975
980
};
976
981
982
+ static void adxcvr_clock_disable (void * clk )
983
+ {
984
+ clk_disable_unprepare (clk );
985
+ }
986
+
987
+ static void adxvcr_lane_rate_disable (void * data )
988
+ {
989
+ struct adxcvr_state * st = data ;
990
+
991
+ /* sync up the worker */
992
+ cancel_work_sync (& st -> work );
993
+ if (__clk_is_enabled (st -> lane_rate_div40_clk ))
994
+ clk_disable_unprepare (st -> lane_rate_div40_clk );
995
+ }
996
+
977
997
static void adxcvr_device_remove_files (void * data )
978
998
{
979
999
struct adxcvr_state * st = data ;
@@ -992,12 +1012,31 @@ static void adxcvr_device_remove_files(void *data)
992
1012
device_remove_file (st -> dev , & dev_attr_reg_access );
993
1013
}
994
1014
1015
+ static void adxcvr_unregister_eyescan (void * st )
1016
+ {
1017
+ adxcvr_eyescan_unregister (st );
1018
+ }
1019
+
995
1020
static void adxcvr_fsm_en_work (struct work_struct * work )
996
1021
{
997
1022
struct adxcvr_state * st =
998
1023
container_of (work , struct adxcvr_state , jesd_fsm_en_work .work );
999
1024
1000
- jesd204_fsm_start (st -> jdev , JESD204_LINKS_ALL );
1025
+ st -> fsm_start_delayed_ret = jesd204_fsm_start (st -> jdev , JESD204_LINKS_ALL );
1026
+ }
1027
+
1028
+ static void adxvcr_jesd204_fsm_stop (void * data )
1029
+ {
1030
+ struct adxcvr_state * st = data ;
1031
+
1032
+ /* unlikely but just in case... */
1033
+ if (st -> fsm_enable_delay_ms )
1034
+ cancel_delayed_work_sync (& st -> jesd_fsm_en_work );
1035
+
1036
+ if (st -> fsm_start_delayed_ret )
1037
+ return ;
1038
+
1039
+ jesd204_fsm_stop (st -> jdev , JESD204_LINKS_ALL );
1001
1040
}
1002
1041
1003
1042
static int adxcvr_probe (struct platform_device * pdev )
@@ -1015,7 +1054,7 @@ static int adxcvr_probe(struct platform_device *pdev)
1015
1054
if (IS_ERR (st -> jdev ))
1016
1055
return PTR_ERR (st -> jdev );
1017
1056
1018
- st -> conv_clk = devm_clk_get (& pdev -> dev , "conv" );
1057
+ st -> conv_clk = devm_clk_get_enabled (& pdev -> dev , "conv" );
1019
1058
if (IS_ERR (st -> conv_clk ))
1020
1059
return PTR_ERR (st -> conv_clk );
1021
1060
@@ -1044,14 +1083,15 @@ static int adxcvr_probe(struct platform_device *pdev)
1044
1083
st -> lane_rate_div40_clk = ERR_PTR (- ENOENT );
1045
1084
}
1046
1085
1047
- ret = clk_prepare_enable (st -> conv_clk );
1048
- if (ret < 0 )
1049
- return ret ;
1050
-
1051
1086
if (st -> conv2_clk ) {
1052
1087
ret = clk_prepare_enable (st -> conv2_clk );
1053
1088
if (ret )
1054
- goto disable_unprepare_conv_clk ;
1089
+ return ret ;
1090
+
1091
+ ret = devm_add_action_or_reset (& pdev -> dev , adxcvr_clock_disable ,
1092
+ st -> conv2_clk );
1093
+ if (ret )
1094
+ return ret ;
1055
1095
}
1056
1096
1057
1097
st -> xcvr .dev = & pdev -> dev ;
@@ -1067,7 +1107,7 @@ static int adxcvr_probe(struct platform_device *pdev)
1067
1107
st -> regs = devm_platform_ioremap_resource (pdev , 0 );
1068
1108
if (IS_ERR (st -> regs )) {
1069
1109
ret = PTR_ERR (st -> regs );
1070
- goto disable_unprepare_conv_clk2 ;
1110
+ return ret ;
1071
1111
}
1072
1112
1073
1113
st -> dev = & pdev -> dev ;
@@ -1100,8 +1140,7 @@ static int adxcvr_probe(struct platform_device *pdev)
1100
1140
break ;
1101
1141
default :
1102
1142
pr_err ("axi_adxcvr: not supported\n" );
1103
- ret = - EINVAL ;
1104
- goto disable_unprepare_conv_clk2 ;
1143
+ return - EINVAL ;
1105
1144
}
1106
1145
} else
1107
1146
st -> xcvr .type = xcvr_type ;
@@ -1115,8 +1154,7 @@ static int adxcvr_probe(struct platform_device *pdev)
1115
1154
default :
1116
1155
dev_err (& pdev -> dev , "Unknown transceiver type: %d\n" ,
1117
1156
st -> xcvr .type );
1118
- ret = - EINVAL ;
1119
- goto disable_unprepare_conv_clk2 ;
1157
+ return - EINVAL ;
1120
1158
}
1121
1159
1122
1160
st -> xcvr .encoding = ENC_8B10B ;
@@ -1146,11 +1184,15 @@ static int adxcvr_probe(struct platform_device *pdev)
1146
1184
1147
1185
ret = adxcvr_clk_register (& pdev -> dev , np , __clk_get_name (st -> conv_clk ));
1148
1186
if (ret )
1149
- goto disable_unprepare_conv_clk2 ;
1187
+ return ret ;
1150
1188
1151
1189
ret = adxcvr_eyescan_register (st );
1152
1190
if (ret )
1153
- goto unreg_adxcvr_clk ;
1191
+ return ret ;
1192
+
1193
+ ret = devm_add_action_or_reset (& pdev -> dev , adxcvr_unregister_eyescan , st );
1194
+ if (ret )
1195
+ return ret ;
1154
1196
1155
1197
device_create_file (st -> dev , & dev_attr_reg_access );
1156
1198
@@ -1166,16 +1208,30 @@ static int adxcvr_probe(struct platform_device *pdev)
1166
1208
}
1167
1209
}
1168
1210
1169
- devm_add_action_or_reset (st -> dev , adxcvr_device_remove_files , st );
1211
+ ret = devm_add_action_or_reset (st -> dev , adxcvr_device_remove_files , st );
1212
+ if (ret )
1213
+ return ret ;
1170
1214
1171
- if (st -> fsm_enable_delay_ms ) {
1172
- INIT_DELAYED_WORK (& st -> jesd_fsm_en_work , adxcvr_fsm_en_work );
1173
- schedule_delayed_work (& st -> jesd_fsm_en_work ,
1174
- msecs_to_jiffies (st -> fsm_enable_delay_ms ));
1175
- } else {
1176
- ret = jesd204_fsm_start (st -> jdev , JESD204_LINKS_ALL );
1215
+ if (st -> jdev ) {
1216
+ if (st -> fsm_enable_delay_ms ) {
1217
+ INIT_DELAYED_WORK (& st -> jesd_fsm_en_work , adxcvr_fsm_en_work );
1218
+ schedule_delayed_work (& st -> jesd_fsm_en_work ,
1219
+ msecs_to_jiffies (st -> fsm_enable_delay_ms ));
1220
+ } else {
1221
+ ret = jesd204_fsm_start (st -> jdev , JESD204_LINKS_ALL );
1222
+ if (ret )
1223
+ return ret ;
1224
+ }
1225
+
1226
+ ret = devm_add_action_or_reset (& pdev -> dev , adxvcr_jesd204_fsm_stop , st );
1177
1227
if (ret )
1178
- goto unreg_eyescan ;
1228
+ return ret ;
1229
+ }
1230
+
1231
+ if (!IS_ERR (st -> lane_rate_div40_clk )) {
1232
+ ret = devm_add_action_or_reset (& pdev -> dev , adxvcr_lane_rate_disable , st );
1233
+ if (ret )
1234
+ return ret ;
1179
1235
}
1180
1236
1181
1237
dev_info (& pdev -> dev , "AXI-ADXCVR-%s (%d.%.2d.%c) using %s on %s. Number of lanes: %d." ,
@@ -1186,55 +1242,14 @@ static int adxcvr_probe(struct platform_device *pdev)
1186
1242
st -> num_lanes );
1187
1243
1188
1244
return 0 ;
1189
-
1190
- unreg_eyescan :
1191
- adxcvr_eyescan_unregister (st );
1192
- unreg_adxcvr_clk :
1193
- if (st -> clks [1 ])
1194
- clk_unregister_fixed_factor (st -> clks [1 ]);
1195
- of_clk_del_provider (pdev -> dev .of_node );
1196
- disable_unprepare_conv_clk2 :
1197
- clk_disable_unprepare (st -> conv2_clk );
1198
- disable_unprepare_conv_clk :
1199
- clk_disable_unprepare (st -> conv_clk );
1200
-
1201
- return ret ;
1202
- }
1203
-
1204
- /**
1205
- * adxcvr_remove - unbinds the driver from the AIM device.
1206
- * @of_dev: pointer to OF device structure
1207
- *
1208
- * This function is called if a device is physically removed from the system or
1209
- * if the driver module is being unloaded. It frees any resources allocated to
1210
- * the device.
1211
- */
1212
- static int adxcvr_remove (struct platform_device * pdev )
1213
- {
1214
- struct adxcvr_state * st = platform_get_drvdata (pdev );
1215
-
1216
- /* sync up the worker */
1217
- cancel_work_sync (& st -> work );
1218
- if (!IS_ERR (st -> lane_rate_div40_clk ) && __clk_is_enabled (st -> lane_rate_div40_clk ))
1219
- clk_disable_unprepare (st -> lane_rate_div40_clk );
1220
- adxcvr_eyescan_unregister (st );
1221
- if (st -> clks [1 ])
1222
- clk_unregister_fixed_factor (st -> clks [1 ]);
1223
- of_clk_del_provider (pdev -> dev .of_node );
1224
- clk_disable_unprepare (st -> conv2_clk );
1225
- clk_disable_unprepare (st -> conv_clk );
1226
-
1227
- return 0 ;
1228
1245
}
1229
1246
1230
1247
static struct platform_driver adxcvr_of_driver = {
1231
1248
.driver = {
1232
1249
.name = KBUILD_MODNAME ,
1233
- .owner = THIS_MODULE ,
1234
1250
.of_match_table = adxcvr_of_match ,
1235
1251
},
1236
1252
.probe = adxcvr_probe ,
1237
- .remove = adxcvr_remove ,
1238
1253
};
1239
1254
1240
1255
module_platform_driver (adxcvr_of_driver );
0 commit comments