@@ -809,21 +809,142 @@ zl3073x_dev_periodic_work(struct kthread_work *work)
809809 msecs_to_jiffies (500 ));
810810}
811811
812+ /**
813+ * zl3073x_dev_phase_meas_setup - setup phase offset measurement
814+ * @zldev: pointer to zl3073x_dev structure
815+ *
816+ * Enable phase offset measurement block, set measurement averaging factor
817+ * and enable DPLL-to-its-ref phase measurement for all DPLLs.
818+ *
819+ * Returns: 0 on success, <0 on error
820+ */
821+ static int
822+ zl3073x_dev_phase_meas_setup (struct zl3073x_dev * zldev )
823+ {
824+ struct zl3073x_dpll * zldpll ;
825+ u8 dpll_meas_ctrl , mask = 0 ;
826+ int rc ;
827+
828+ /* Read DPLL phase measurement control register */
829+ rc = zl3073x_read_u8 (zldev , ZL_REG_DPLL_MEAS_CTRL , & dpll_meas_ctrl );
830+ if (rc )
831+ return rc ;
832+
833+ /* Setup phase measurement averaging factor */
834+ dpll_meas_ctrl &= ~ZL_DPLL_MEAS_CTRL_AVG_FACTOR ;
835+ dpll_meas_ctrl |= FIELD_PREP (ZL_DPLL_MEAS_CTRL_AVG_FACTOR , 3 );
836+
837+ /* Enable DPLL measurement block */
838+ dpll_meas_ctrl |= ZL_DPLL_MEAS_CTRL_EN ;
839+
840+ /* Update phase measurement control register */
841+ rc = zl3073x_write_u8 (zldev , ZL_REG_DPLL_MEAS_CTRL , dpll_meas_ctrl );
842+ if (rc )
843+ return rc ;
844+
845+ /* Enable DPLL-to-connected-ref measurement for each channel */
846+ list_for_each_entry (zldpll , & zldev -> dplls , list )
847+ mask |= BIT (zldpll -> id );
848+
849+ return zl3073x_write_u8 (zldev , ZL_REG_DPLL_PHASE_ERR_READ_MASK , mask );
850+ }
851+
852+ /**
853+ * zl3073x_dev_start - Start normal operation
854+ * @zldev: zl3073x device pointer
855+ * @full: perform full initialization
856+ *
857+ * The function starts normal operation, which means registering all DPLLs and
858+ * their pins, and starting monitoring. If full initialization is requested,
859+ * the function additionally initializes the phase offset measurement block and
860+ * fetches hardware-invariant parameters.
861+ *
862+ * Return: 0 on success, <0 on error
863+ */
864+ int zl3073x_dev_start (struct zl3073x_dev * zldev , bool full )
865+ {
866+ struct zl3073x_dpll * zldpll ;
867+ int rc ;
868+
869+ if (full ) {
870+ /* Fetch device state */
871+ rc = zl3073x_dev_state_fetch (zldev );
872+ if (rc )
873+ return rc ;
874+
875+ /* Setup phase offset measurement block */
876+ rc = zl3073x_dev_phase_meas_setup (zldev );
877+ if (rc ) {
878+ dev_err (zldev -> dev ,
879+ "Failed to setup phase measurement\n" );
880+ return rc ;
881+ }
882+ }
883+
884+ /* Register all DPLLs */
885+ list_for_each_entry (zldpll , & zldev -> dplls , list ) {
886+ rc = zl3073x_dpll_register (zldpll );
887+ if (rc ) {
888+ dev_err_probe (zldev -> dev , rc ,
889+ "Failed to register DPLL%u\n" ,
890+ zldpll -> id );
891+ return rc ;
892+ }
893+ }
894+
895+ /* Perform initial firmware fine phase correction */
896+ rc = zl3073x_dpll_init_fine_phase_adjust (zldev );
897+ if (rc ) {
898+ dev_err_probe (zldev -> dev , rc ,
899+ "Failed to init fine phase correction\n" );
900+ return rc ;
901+ }
902+
903+ /* Start monitoring */
904+ kthread_queue_delayed_work (zldev -> kworker , & zldev -> work , 0 );
905+
906+ return 0 ;
907+ }
908+
909+ /**
910+ * zl3073x_dev_stop - Stop normal operation
911+ * @zldev: zl3073x device pointer
912+ *
913+ * The function stops the normal operation that mean deregistration of all
914+ * DPLLs and their pins and stop monitoring.
915+ *
916+ * Return: 0 on success, <0 on error
917+ */
918+ void zl3073x_dev_stop (struct zl3073x_dev * zldev )
919+ {
920+ struct zl3073x_dpll * zldpll ;
921+
922+ /* Stop monitoring */
923+ kthread_cancel_delayed_work_sync (& zldev -> work );
924+
925+ /* Unregister all DPLLs */
926+ list_for_each_entry (zldpll , & zldev -> dplls , list ) {
927+ if (zldpll -> dpll_dev )
928+ zl3073x_dpll_unregister (zldpll );
929+ }
930+ }
931+
812932static void zl3073x_dev_dpll_fini (void * ptr )
813933{
814934 struct zl3073x_dpll * zldpll , * next ;
815935 struct zl3073x_dev * zldev = ptr ;
816936
817- /* Stop monitoring thread */
937+ /* Stop monitoring and unregister DPLLs */
938+ zl3073x_dev_stop (zldev );
939+
940+ /* Destroy monitoring thread */
818941 if (zldev -> kworker ) {
819- kthread_cancel_delayed_work_sync (& zldev -> work );
820942 kthread_destroy_worker (zldev -> kworker );
821943 zldev -> kworker = NULL ;
822944 }
823945
824- /* Release DPLLs */
946+ /* Free all DPLLs */
825947 list_for_each_entry_safe (zldpll , next , & zldev -> dplls , list ) {
826- zl3073x_dpll_unregister (zldpll );
827948 list_del (& zldpll -> list );
828949 zl3073x_dpll_free (zldpll );
829950 }
@@ -839,7 +960,7 @@ zl3073x_devm_dpll_init(struct zl3073x_dev *zldev, u8 num_dplls)
839960
840961 INIT_LIST_HEAD (& zldev -> dplls );
841962
842- /* Initialize all DPLLs */
963+ /* Allocate all DPLLs */
843964 for (i = 0 ; i < num_dplls ; i ++ ) {
844965 zldpll = zl3073x_dpll_alloc (zldev , i );
845966 if (IS_ERR (zldpll )) {
@@ -849,35 +970,24 @@ zl3073x_devm_dpll_init(struct zl3073x_dev *zldev, u8 num_dplls)
849970 goto error ;
850971 }
851972
852- rc = zl3073x_dpll_register (zldpll );
853- if (rc ) {
854- dev_err_probe (zldev -> dev , rc ,
855- "Failed to register DPLL%u\n" , i );
856- zl3073x_dpll_free (zldpll );
857- goto error ;
858- }
859-
860973 list_add_tail (& zldpll -> list , & zldev -> dplls );
861974 }
862975
863- /* Perform initial firmware fine phase correction */
864- rc = zl3073x_dpll_init_fine_phase_adjust (zldev );
865- if (rc ) {
866- dev_err_probe (zldev -> dev , rc ,
867- "Failed to init fine phase correction\n" );
868- goto error ;
869- }
870-
871976 /* Initialize monitoring thread */
872977 kthread_init_delayed_work (& zldev -> work , zl3073x_dev_periodic_work );
873978 kworker = kthread_run_worker (0 , "zl3073x-%s" , dev_name (zldev -> dev ));
874979 if (IS_ERR (kworker )) {
875980 rc = PTR_ERR (kworker );
876981 goto error ;
877982 }
878-
879983 zldev -> kworker = kworker ;
880- kthread_queue_delayed_work (zldev -> kworker , & zldev -> work , 0 );
984+
985+ /* Start normal operation */
986+ rc = zl3073x_dev_start (zldev , true);
987+ if (rc ) {
988+ dev_err_probe (zldev -> dev , rc , "Failed to start device\n" );
989+ goto error ;
990+ }
881991
882992 /* Add devres action to release DPLL related resources */
883993 rc = devm_add_action_or_reset (zldev -> dev , zl3073x_dev_dpll_fini , zldev );
@@ -892,46 +1002,6 @@ zl3073x_devm_dpll_init(struct zl3073x_dev *zldev, u8 num_dplls)
8921002 return rc ;
8931003}
8941004
895- /**
896- * zl3073x_dev_phase_meas_setup - setup phase offset measurement
897- * @zldev: pointer to zl3073x_dev structure
898- * @num_channels: number of DPLL channels
899- *
900- * Enable phase offset measurement block, set measurement averaging factor
901- * and enable DPLL-to-its-ref phase measurement for all DPLLs.
902- *
903- * Returns: 0 on success, <0 on error
904- */
905- static int
906- zl3073x_dev_phase_meas_setup (struct zl3073x_dev * zldev , int num_channels )
907- {
908- u8 dpll_meas_ctrl , mask ;
909- int i , rc ;
910-
911- /* Read DPLL phase measurement control register */
912- rc = zl3073x_read_u8 (zldev , ZL_REG_DPLL_MEAS_CTRL , & dpll_meas_ctrl );
913- if (rc )
914- return rc ;
915-
916- /* Setup phase measurement averaging factor */
917- dpll_meas_ctrl &= ~ZL_DPLL_MEAS_CTRL_AVG_FACTOR ;
918- dpll_meas_ctrl |= FIELD_PREP (ZL_DPLL_MEAS_CTRL_AVG_FACTOR , 3 );
919-
920- /* Enable DPLL measurement block */
921- dpll_meas_ctrl |= ZL_DPLL_MEAS_CTRL_EN ;
922-
923- /* Update phase measurement control register */
924- rc = zl3073x_write_u8 (zldev , ZL_REG_DPLL_MEAS_CTRL , dpll_meas_ctrl );
925- if (rc )
926- return rc ;
927-
928- /* Enable DPLL-to-connected-ref measurement for each channel */
929- for (i = 0 , mask = 0 ; i < num_channels ; i ++ )
930- mask |= BIT (i );
931-
932- return zl3073x_write_u8 (zldev , ZL_REG_DPLL_PHASE_ERR_READ_MASK , mask );
933- }
934-
9351005/**
9361006 * zl3073x_dev_probe - initialize zl3073x device
9371007 * @zldev: pointer to zl3073x device
@@ -999,17 +1069,6 @@ int zl3073x_dev_probe(struct zl3073x_dev *zldev,
9991069 return dev_err_probe (zldev -> dev , rc ,
10001070 "Failed to initialize mutex\n" );
10011071
1002- /* Fetch device state */
1003- rc = zl3073x_dev_state_fetch (zldev );
1004- if (rc )
1005- return rc ;
1006-
1007- /* Setup phase offset measurement block */
1008- rc = zl3073x_dev_phase_meas_setup (zldev , chip_info -> num_channels );
1009- if (rc )
1010- return dev_err_probe (zldev -> dev , rc ,
1011- "Failed to setup phase measurement\n" );
1012-
10131072 /* Register DPLL channels */
10141073 rc = zl3073x_devm_dpll_init (zldev , chip_info -> num_channels );
10151074 if (rc )
0 commit comments