Right now sdp_reg_bank is only used during atomic enable/disable and
thus there is no risk of two threads accidently claiming the same bit.

This changes once more SDP users (like audio support) are added, so
introduce a mutex to protect concurrent access to the bitmap.

Signed-off-by: Sebastian Reichel <[email protected]>
---
 drivers/gpu/drm/bridge/synopsys/dw-dp.c | 24 +++++++++++++++++-------
 1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-dp.c 
b/drivers/gpu/drm/bridge/synopsys/dw-dp.c
index 31f944e143ea..31495a813e40 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-dp.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-dp.c
@@ -323,6 +323,8 @@ struct dw_dp {
        struct dw_dp_hotplug hotplug;
        /* Serialize hpd status access */
        struct mutex irq_lock;
+       /* Serialize sdp_reg_bank access */
+       struct mutex sdp_lock;
 
        struct drm_dp_aux aux;
 
@@ -1048,11 +1050,13 @@ static int dw_dp_send_sdp(struct dw_dp *dp, struct 
dw_dp_sdp *sdp)
        u32 reg;
        int i, nr;
 
-       nr = find_first_zero_bit(dp->sdp_reg_bank, SDP_REG_BANK_SIZE);
-       if (nr < SDP_REG_BANK_SIZE)
-               set_bit(nr, dp->sdp_reg_bank);
-       else
-               return -EBUSY;
+       scoped_guard(mutex, &dp->sdp_lock) {
+               nr = find_first_zero_bit(dp->sdp_reg_bank, SDP_REG_BANK_SIZE);
+               if (nr < SDP_REG_BANK_SIZE)
+                       set_bit(nr, dp->sdp_reg_bank);
+               else
+                       return -EBUSY;
+       }
 
        reg = DW_DP_SDP_REGISTER_BANK + nr * 9 * 4;
 
@@ -1709,7 +1713,8 @@ static void dw_dp_bridge_atomic_enable(struct drm_bridge 
*bridge,
                return;
        }
 
-       set_bit(0, dp->sdp_reg_bank);
+       scoped_guard(mutex, &dp->sdp_lock)
+               set_bit(0, dp->sdp_reg_bank);
 
        ret = dw_dp_link_enable(dp);
        if (ret < 0) {
@@ -1753,7 +1758,8 @@ static void dw_dp_bridge_atomic_disable(struct drm_bridge 
*bridge,
 
        dw_dp_video_disable(dp);
        dw_dp_link_disable(dp);
-       bitmap_zero(dp->sdp_reg_bank, SDP_REG_BANK_SIZE);
+       scoped_guard(mutex, &dp->sdp_lock)
+               bitmap_zero(dp->sdp_reg_bank, SDP_REG_BANK_SIZE);
        dw_dp_reset(dp);
        pm_runtime_put_autosuspend(dp->dev);
 }
@@ -2227,6 +2233,10 @@ int dw_dp_probe(struct dw_dp *dp)
        if (ret)
                return ret;
 
+       ret = devm_mutex_init(dev, &dp->sdp_lock);
+       if (ret)
+               return ret;
+
        res = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(res))
                return PTR_ERR(res);

-- 
2.53.0

Reply via email to