@@ -956,21 +956,142 @@ zl3073x_dev_periodic_work(struct kthread_work *work)
956956 msecs_to_jiffies (500 ));
957957}
958958
959+ /**
960+ * zl3073x_dev_phase_meas_setup - setup phase offset measurement
961+ * @zldev: pointer to zl3073x_dev structure
962+ *
963+ * Enable phase offset measurement block, set measurement averaging factor
964+ * and enable DPLL-to-its-ref phase measurement for all DPLLs.
965+ *
966+ * Returns: 0 on success, <0 on error
967+ */
968+ static int
969+ zl3073x_dev_phase_meas_setup (struct zl3073x_dev * zldev )
970+ {
971+ struct zl3073x_dpll * zldpll ;
972+ u8 dpll_meas_ctrl , mask = 0 ;
973+ int rc ;
974+
975+ /* Read DPLL phase measurement control register */
976+ rc = zl3073x_read_u8 (zldev , ZL_REG_DPLL_MEAS_CTRL , & dpll_meas_ctrl );
977+ if (rc )
978+ return rc ;
979+
980+ /* Setup phase measurement averaging factor */
981+ dpll_meas_ctrl &= ~ZL_DPLL_MEAS_CTRL_AVG_FACTOR ;
982+ dpll_meas_ctrl |= FIELD_PREP (ZL_DPLL_MEAS_CTRL_AVG_FACTOR , 3 );
983+
984+ /* Enable DPLL measurement block */
985+ dpll_meas_ctrl |= ZL_DPLL_MEAS_CTRL_EN ;
986+
987+ /* Update phase measurement control register */
988+ rc = zl3073x_write_u8 (zldev , ZL_REG_DPLL_MEAS_CTRL , dpll_meas_ctrl );
989+ if (rc )
990+ return rc ;
991+
992+ /* Enable DPLL-to-connected-ref measurement for each channel */
993+ list_for_each_entry (zldpll , & zldev -> dplls , list )
994+ mask |= BIT (zldpll -> id );
995+
996+ return zl3073x_write_u8 (zldev , ZL_REG_DPLL_PHASE_ERR_READ_MASK , mask );
997+ }
998+
999+ /**
1000+ * zl3073x_dev_start - Start normal operation
1001+ * @zldev: zl3073x device pointer
1002+ * @full: perform full initialization
1003+ *
1004+ * The function starts normal operation, which means registering all DPLLs and
1005+ * their pins, and starting monitoring. If full initialization is requested,
1006+ * the function additionally initializes the phase offset measurement block and
1007+ * fetches hardware-invariant parameters.
1008+ *
1009+ * Return: 0 on success, <0 on error
1010+ */
1011+ int zl3073x_dev_start (struct zl3073x_dev * zldev , bool full )
1012+ {
1013+ struct zl3073x_dpll * zldpll ;
1014+ int rc ;
1015+
1016+ if (full ) {
1017+ /* Fetch device state */
1018+ rc = zl3073x_dev_state_fetch (zldev );
1019+ if (rc )
1020+ return rc ;
1021+
1022+ /* Setup phase offset measurement block */
1023+ rc = zl3073x_dev_phase_meas_setup (zldev );
1024+ if (rc ) {
1025+ dev_err (zldev -> dev ,
1026+ "Failed to setup phase measurement\n" );
1027+ return rc ;
1028+ }
1029+ }
1030+
1031+ /* Register all DPLLs */
1032+ list_for_each_entry (zldpll , & zldev -> dplls , list ) {
1033+ rc = zl3073x_dpll_register (zldpll );
1034+ if (rc ) {
1035+ dev_err_probe (zldev -> dev , rc ,
1036+ "Failed to register DPLL%u\n" ,
1037+ zldpll -> id );
1038+ return rc ;
1039+ }
1040+ }
1041+
1042+ /* Perform initial firmware fine phase correction */
1043+ rc = zl3073x_dpll_init_fine_phase_adjust (zldev );
1044+ if (rc ) {
1045+ dev_err_probe (zldev -> dev , rc ,
1046+ "Failed to init fine phase correction\n" );
1047+ return rc ;
1048+ }
1049+
1050+ /* Start monitoring */
1051+ kthread_queue_delayed_work (zldev -> kworker , & zldev -> work , 0 );
1052+
1053+ return 0 ;
1054+ }
1055+
1056+ /**
1057+ * zl3073x_dev_stop - Stop normal operation
1058+ * @zldev: zl3073x device pointer
1059+ *
1060+ * The function stops the normal operation that mean deregistration of all
1061+ * DPLLs and their pins and stop monitoring.
1062+ *
1063+ * Return: 0 on success, <0 on error
1064+ */
1065+ void zl3073x_dev_stop (struct zl3073x_dev * zldev )
1066+ {
1067+ struct zl3073x_dpll * zldpll ;
1068+
1069+ /* Stop monitoring */
1070+ kthread_cancel_delayed_work_sync (& zldev -> work );
1071+
1072+ /* Unregister all DPLLs */
1073+ list_for_each_entry (zldpll , & zldev -> dplls , list ) {
1074+ if (zldpll -> dpll_dev )
1075+ zl3073x_dpll_unregister (zldpll );
1076+ }
1077+ }
1078+
9591079static void zl3073x_dev_dpll_fini (void * ptr )
9601080{
9611081 struct zl3073x_dpll * zldpll , * next ;
9621082 struct zl3073x_dev * zldev = ptr ;
9631083
964- /* Stop monitoring thread */
1084+ /* Stop monitoring and unregister DPLLs */
1085+ zl3073x_dev_stop (zldev );
1086+
1087+ /* Destroy monitoring thread */
9651088 if (zldev -> kworker ) {
966- kthread_cancel_delayed_work_sync (& zldev -> work );
9671089 kthread_destroy_worker (zldev -> kworker );
9681090 zldev -> kworker = NULL ;
9691091 }
9701092
971- /* Release DPLLs */
1093+ /* Free all DPLLs */
9721094 list_for_each_entry_safe (zldpll , next , & zldev -> dplls , list ) {
973- zl3073x_dpll_unregister (zldpll );
9741095 list_del (& zldpll -> list );
9751096 zl3073x_dpll_free (zldpll );
9761097 }
@@ -986,7 +1107,7 @@ zl3073x_devm_dpll_init(struct zl3073x_dev *zldev, u8 num_dplls)
9861107
9871108 INIT_LIST_HEAD (& zldev -> dplls );
9881109
989- /* Initialize all DPLLs */
1110+ /* Allocate all DPLLs */
9901111 for (i = 0 ; i < num_dplls ; i ++ ) {
9911112 zldpll = zl3073x_dpll_alloc (zldev , i );
9921113 if (IS_ERR (zldpll )) {
@@ -996,35 +1117,24 @@ zl3073x_devm_dpll_init(struct zl3073x_dev *zldev, u8 num_dplls)
9961117 goto error ;
9971118 }
9981119
999- rc = zl3073x_dpll_register (zldpll );
1000- if (rc ) {
1001- dev_err_probe (zldev -> dev , rc ,
1002- "Failed to register DPLL%u\n" , i );
1003- zl3073x_dpll_free (zldpll );
1004- goto error ;
1005- }
1006-
10071120 list_add_tail (& zldpll -> list , & zldev -> dplls );
10081121 }
10091122
1010- /* Perform initial firmware fine phase correction */
1011- rc = zl3073x_dpll_init_fine_phase_adjust (zldev );
1012- if (rc ) {
1013- dev_err_probe (zldev -> dev , rc ,
1014- "Failed to init fine phase correction\n" );
1015- goto error ;
1016- }
1017-
10181123 /* Initialize monitoring thread */
10191124 kthread_init_delayed_work (& zldev -> work , zl3073x_dev_periodic_work );
10201125 kworker = kthread_run_worker (0 , "zl3073x-%s" , dev_name (zldev -> dev ));
10211126 if (IS_ERR (kworker )) {
10221127 rc = PTR_ERR (kworker );
10231128 goto error ;
10241129 }
1025-
10261130 zldev -> kworker = kworker ;
1027- kthread_queue_delayed_work (zldev -> kworker , & zldev -> work , 0 );
1131+
1132+ /* Start normal operation */
1133+ rc = zl3073x_dev_start (zldev , true);
1134+ if (rc ) {
1135+ dev_err_probe (zldev -> dev , rc , "Failed to start device\n" );
1136+ goto error ;
1137+ }
10281138
10291139 /* Add devres action to release DPLL related resources */
10301140 rc = devm_add_action_or_reset (zldev -> dev , zl3073x_dev_dpll_fini , zldev );
@@ -1039,46 +1149,6 @@ zl3073x_devm_dpll_init(struct zl3073x_dev *zldev, u8 num_dplls)
10391149 return rc ;
10401150}
10411151
1042- /**
1043- * zl3073x_dev_phase_meas_setup - setup phase offset measurement
1044- * @zldev: pointer to zl3073x_dev structure
1045- * @num_channels: number of DPLL channels
1046- *
1047- * Enable phase offset measurement block, set measurement averaging factor
1048- * and enable DPLL-to-its-ref phase measurement for all DPLLs.
1049- *
1050- * Returns: 0 on success, <0 on error
1051- */
1052- static int
1053- zl3073x_dev_phase_meas_setup (struct zl3073x_dev * zldev , int num_channels )
1054- {
1055- u8 dpll_meas_ctrl , mask ;
1056- int i , rc ;
1057-
1058- /* Read DPLL phase measurement control register */
1059- rc = zl3073x_read_u8 (zldev , ZL_REG_DPLL_MEAS_CTRL , & dpll_meas_ctrl );
1060- if (rc )
1061- return rc ;
1062-
1063- /* Setup phase measurement averaging factor */
1064- dpll_meas_ctrl &= ~ZL_DPLL_MEAS_CTRL_AVG_FACTOR ;
1065- dpll_meas_ctrl |= FIELD_PREP (ZL_DPLL_MEAS_CTRL_AVG_FACTOR , 3 );
1066-
1067- /* Enable DPLL measurement block */
1068- dpll_meas_ctrl |= ZL_DPLL_MEAS_CTRL_EN ;
1069-
1070- /* Update phase measurement control register */
1071- rc = zl3073x_write_u8 (zldev , ZL_REG_DPLL_MEAS_CTRL , dpll_meas_ctrl );
1072- if (rc )
1073- return rc ;
1074-
1075- /* Enable DPLL-to-connected-ref measurement for each channel */
1076- for (i = 0 , mask = 0 ; i < num_channels ; i ++ )
1077- mask |= BIT (i );
1078-
1079- return zl3073x_write_u8 (zldev , ZL_REG_DPLL_PHASE_ERR_READ_MASK , mask );
1080- }
1081-
10821152/**
10831153 * zl3073x_dev_probe - initialize zl3073x device
10841154 * @zldev: pointer to zl3073x device
@@ -1146,17 +1216,6 @@ int zl3073x_dev_probe(struct zl3073x_dev *zldev,
11461216 return dev_err_probe (zldev -> dev , rc ,
11471217 "Failed to initialize mutex\n" );
11481218
1149- /* Fetch device state */
1150- rc = zl3073x_dev_state_fetch (zldev );
1151- if (rc )
1152- return rc ;
1153-
1154- /* Setup phase offset measurement block */
1155- rc = zl3073x_dev_phase_meas_setup (zldev , chip_info -> num_channels );
1156- if (rc )
1157- return dev_err_probe (zldev -> dev , rc ,
1158- "Failed to setup phase measurement\n" );
1159-
11601219 /* Register DPLL channels */
11611220 rc = zl3073x_devm_dpll_init (zldev , chip_info -> num_channels );
11621221 if (rc )
0 commit comments