Introduce mutual exclusion between USB and DP PHY modes to prevent
simultaneous activation.

Signed-off-by: Xiangxu Yin <[email protected]>
---
 drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c 
b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
index 
613239d15a6a3bba47a647db4e663713f127c93e..866277036089c588cf0c63204efb91bbec5430ae
 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c
@@ -1061,6 +1061,19 @@ static int qmp_usbc_usb_power_off(struct phy *phy)
        return 0;
 }
 
+static int qmp_check_mutex_phy(struct qmp_usbc *qmp, bool is_dp)
+{
+       if ((is_dp && qmp->usb_init_count) ||
+           (!is_dp && qmp->dp_init_count)) {
+               dev_err(qmp->dev,
+                       "PHY is configured for %s, can not enable %s\n",
+                       is_dp ? "USB" : "DP", is_dp ? "DP" : "USB");
+               return -EBUSY;
+       }
+
+       return 0;
+}
+
 static int qmp_usbc_usb_enable(struct phy *phy)
 {
        struct qmp_usbc *qmp = phy_get_drvdata(phy);
@@ -1068,6 +1081,10 @@ static int qmp_usbc_usb_enable(struct phy *phy)
 
        mutex_lock(&qmp->phy_mutex);
 
+       ret = qmp_check_mutex_phy(qmp, false);
+       if (ret)
+               goto out_unlock;
+
        ret = qmp_usbc_com_init(phy);
        if (ret)
                goto out_unlock;
@@ -1121,6 +1138,10 @@ static int qmp_usbc_dp_enable(struct phy *phy)
 
        mutex_lock(&qmp->phy_mutex);
 
+       ret = qmp_check_mutex_phy(qmp, true);
+       if (ret)
+               goto dp_init_unlock;
+
        ret = qmp_usbc_com_init(phy);
        if (ret)
                goto dp_init_unlock;

-- 
2.34.1

Reply via email to