Rework multiplexed pin control to match the state change listed in
the design requirements.

Signed-off-by: Sergey Temerkhanov <[email protected]>
Reviewed-by: Aleksandr Loktionov <[email protected]>
Reviewed-by: Przemyslaw Korba <[email protected]>
---
 drivers/net/ethernet/intel/ice/ice_dpll.c | 35 ++++++++++++++++++++---
 1 file changed, 31 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c 
b/drivers/net/ethernet/intel/ice/ice_dpll.c
index 54958e17713b..cb14621b3aef 100644
--- a/drivers/net/ethernet/intel/ice/ice_dpll.c
+++ b/drivers/net/ethernet/intel/ice/ice_dpll.c
@@ -1381,12 +1381,39 @@ ice_dpll_ufl_pin_state_set(const struct dpll_pin *pin, 
void *pin_priv,
        if (ret)
                goto unlock;
 
-       if (enable)
+       if (enable) {
                ret = ice_dpll_pin_enable(hw, target, d->dpll_idx, type, 
extack);
-       else
+               if (!ret)
+                       ret = ice_dpll_pin_state_update(pf, target, type, 
extack);
+               if (!ret && p->muxed->active) {
+                       struct ice_dpll_pin *peer = p->muxed;
+                       struct ice_dpll_pin *peer_target;
+                       enum ice_dpll_pin_type peer_type;
+                       int peer_ret;
+
+                       if (peer->direction == DPLL_PIN_DIRECTION_OUTPUT) {
+                               peer_target = peer->output;
+                               peer_type = ICE_DPLL_PIN_TYPE_OUTPUT;
+                       } else {
+                               peer_target = peer->input;
+                               peer_type = ICE_DPLL_PIN_TYPE_INPUT;
+                       }
+                       peer_ret = ice_dpll_pin_enable(&pf->hw, peer_target,
+                                                      pf->dplls.eec.dpll_idx,
+                                                      peer_type, NULL);
+                       if (!peer_ret)
+                               peer_ret = ice_dpll_pin_state_update(pf, 
peer_target,
+                                                            peer_type, NULL);
+                       if (peer_ret)
+                               dev_warn(ice_pf_to_dev(pf),
+                                        "Failed to sync peer pin %u after 
enabling U.FL pin %u, err %d\n",
+                                        peer_target->idx, target->idx, 
peer_ret);
+               }
+       } else {
                ret = ice_dpll_pin_disable(hw, target, type, extack);
-       if (!ret)
-               ret = ice_dpll_pin_state_update(pf, target, type, extack);
+               if (!ret)
+                       ret = ice_dpll_pin_state_update(pf, target, type, 
extack);
+       }
 
 unlock:
        mutex_unlock(&pf->dplls.lock);
-- 
2.53.0

Reply via email to