drm_dp_remove_payload_part1() doesn't send the removal of a payload to the
branch devices if the port of the payload is not in the topology anymore.
The caller can't tell, so it generates the ACT and waits for it afterwards,
polling DPCD 0x2c0 for up to 3 seconds, although the payload table of the
branch devices wasn't changed and the ACT will never be handled.

Return whether the removal was sent, so that drivers can skip the ACT in
the other case. The existing callers ignore the return value and are not
affected.

Signed-off-by: Xiao Lu <[email protected]>
---
 drivers/gpu/drm/display/drm_dp_mst_topology.c | 10 +++++++++-
 include/drm/display/drm_dp_mst_helper.h       |  2 +-
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c 
b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index 7ce9e2127..363cd5237 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -3369,8 +3369,14 @@ EXPORT_SYMBOL(drm_dp_add_payload_part1);
  * Removes a payload along the virtual channel if it was successfully 
allocated.
  * After calling this, the driver should set HW to generate ACT and then 
switch to new
  * payload allocation state.
+ *
+ * Returns:
+ * %true if the port of the payload is in the topology, so the removal was
+ * sent to the branch devices and the driver should generate the ACT and wait
+ * for it. %false if the port is not in the topology anymore, so nothing was
+ * sent to the branch devices and there is no ACT to generate or wait for.
  */
-void drm_dp_remove_payload_part1(struct drm_dp_mst_topology_mgr *mgr,
+bool drm_dp_remove_payload_part1(struct drm_dp_mst_topology_mgr *mgr,
                                 struct drm_dp_mst_topology_state *mst_state,
                                 struct drm_dp_mst_atomic_payload *payload)
 {
@@ -3388,6 +3394,8 @@ void drm_dp_remove_payload_part1(struct 
drm_dp_mst_topology_mgr *mgr,
                            payload->vcpi);
 
        payload->payload_allocation_status = 
DRM_DP_MST_PAYLOAD_ALLOCATION_LOCAL;
+
+       return send_remove;
 }
 EXPORT_SYMBOL(drm_dp_remove_payload_part1);
 
diff --git a/include/drm/display/drm_dp_mst_helper.h 
b/include/drm/display/drm_dp_mst_helper.h
index 27658bfb5..d5a3bbb28 100644
--- a/include/drm/display/drm_dp_mst_helper.h
+++ b/include/drm/display/drm_dp_mst_helper.h
@@ -885,7 +885,7 @@ int drm_dp_add_payload_part1(struct drm_dp_mst_topology_mgr 
*mgr,
                             struct drm_dp_mst_atomic_payload *payload);
 int drm_dp_add_payload_part2(struct drm_dp_mst_topology_mgr *mgr,
                             struct drm_dp_mst_atomic_payload *payload);
-void drm_dp_remove_payload_part1(struct drm_dp_mst_topology_mgr *mgr,
+bool drm_dp_remove_payload_part1(struct drm_dp_mst_topology_mgr *mgr,
                                 struct drm_dp_mst_topology_state *mst_state,
                                 struct drm_dp_mst_atomic_payload *payload);
 void drm_dp_remove_payload_part2(struct drm_dp_mst_topology_mgr *mgr,
-- 
2.43.0

Reply via email to