Skip to content

Commit 7617e96

Browse files
Wayne LinLyude
authored andcommitted
drm/dp_mst: clear time slots for ports invalid
[Why] When change the connection status in a MST topology, mst device which detect the event will send out CONNECTION_STATUS_NOTIFY messgae. e.g. src-mst-mst-sst => src-mst (unplug) mst-sst Currently, under the above case of unplugging device, ports which have been allocated payloads and are no longer in the topology still occupy time slots and recorded in proposed_vcpi[] of topology manager. If we don't clean up the proposed_vcpi[], when code flow goes to try to update payload table by calling drm_dp_update_payload_part1(), we will fail at checking port validation due to there are ports with proposed time slots but no longer in the mst topology. As the result of that, we will also stop updating the DPCD payload table of down stream port. [How] While handling the CONNECTION_STATUS_NOTIFY message, add a detection to see if the event indicates that a device is unplugged to an output port. If the detection is true, then iterrate over all proposed_vcpi[] to see whether a port of the proposed_vcpi[] is still in the topology or not. If the port is invalid, set its num_slots to 0. Thereafter, when try to update payload table by calling drm_dp_update_payload_part1(), we can successfully update the DPCD payload table of down stream port and clear the proposed_vcpi[] to NULL. Changes since v1:(https://patchwork.kernel.org/patch/11275801/) * Invert the conditional to reduce the indenting Reviewed-by: Lyude Paul <[email protected]> Signed-off-by: Wayne Lin <[email protected]> Signed-off-by: Lyude Paul <[email protected]> [removed cc for stable - there's too many patches this depends on for this to backport cleanly] Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent c3b040b commit 7617e96

File tree

1 file changed

+24
-1
lines changed

1 file changed

+24
-1
lines changed

drivers/gpu/drm/drm_dp_mst_topology.c

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2318,7 +2318,7 @@ drm_dp_mst_handle_conn_stat(struct drm_dp_mst_branch *mstb,
23182318
{
23192319
struct drm_dp_mst_topology_mgr *mgr = mstb->mgr;
23202320
struct drm_dp_mst_port *port;
2321-
int old_ddps, ret;
2321+
int old_ddps, old_input, ret, i;
23222322
u8 new_pdt;
23232323
bool dowork = false, create_connector = false;
23242324

@@ -2349,6 +2349,7 @@ drm_dp_mst_handle_conn_stat(struct drm_dp_mst_branch *mstb,
23492349
}
23502350

23512351
old_ddps = port->ddps;
2352+
old_input = port->input;
23522353
port->input = conn_stat->input_port;
23532354
port->mcs = conn_stat->message_capability_status;
23542355
port->ldps = conn_stat->legacy_device_plug_status;
@@ -2373,6 +2374,28 @@ drm_dp_mst_handle_conn_stat(struct drm_dp_mst_branch *mstb,
23732374
dowork = false;
23742375
}
23752376

2377+
if (!old_input && old_ddps != port->ddps && !port->ddps) {
2378+
for (i = 0; i < mgr->max_payloads; i++) {
2379+
struct drm_dp_vcpi *vcpi = mgr->proposed_vcpis[i];
2380+
struct drm_dp_mst_port *port_validated;
2381+
2382+
if (!vcpi)
2383+
continue;
2384+
2385+
port_validated =
2386+
container_of(vcpi, struct drm_dp_mst_port, vcpi);
2387+
port_validated =
2388+
drm_dp_mst_topology_get_port_validated(mgr, port_validated);
2389+
if (!port_validated) {
2390+
mutex_lock(&mgr->payload_lock);
2391+
vcpi->num_slots = 0;
2392+
mutex_unlock(&mgr->payload_lock);
2393+
} else {
2394+
drm_dp_mst_topology_put_port(port_validated);
2395+
}
2396+
}
2397+
}
2398+
23762399
if (port->connector)
23772400
drm_modeset_unlock(&mgr->base.lock);
23782401
else if (create_connector)

0 commit comments

Comments
 (0)