|
@@ -1494,26 +1494,18 @@ static void process_single_down_tx_qlock(struct drm_dp_mst_topology_mgr *mgr)
|
|
|
}
|
|
|
|
|
|
/* called holding qlock */
|
|
|
-static void process_single_up_tx_qlock(struct drm_dp_mst_topology_mgr *mgr)
|
|
|
+static void process_single_up_tx_qlock(struct drm_dp_mst_topology_mgr *mgr,
|
|
|
+ struct drm_dp_sideband_msg_tx *txmsg)
|
|
|
{
|
|
|
- struct drm_dp_sideband_msg_tx *txmsg;
|
|
|
int ret;
|
|
|
|
|
|
/* construct a chunk from the first msg in the tx_msg queue */
|
|
|
- if (list_empty(&mgr->tx_msg_upq)) {
|
|
|
- mgr->tx_up_in_progress = false;
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- txmsg = list_first_entry(&mgr->tx_msg_upq, struct drm_dp_sideband_msg_tx, next);
|
|
|
ret = process_single_tx_qlock(mgr, txmsg, true);
|
|
|
- if (ret == 1) {
|
|
|
- /* up txmsgs aren't put in slots - so free after we send it */
|
|
|
- list_del(&txmsg->next);
|
|
|
- kfree(txmsg);
|
|
|
- } else if (ret)
|
|
|
+
|
|
|
+ if (ret != 1)
|
|
|
DRM_DEBUG_KMS("failed to send msg in q %d\n", ret);
|
|
|
- mgr->tx_up_in_progress = true;
|
|
|
+
|
|
|
+ txmsg->dst->tx_slots[txmsg->seqno] = NULL;
|
|
|
}
|
|
|
|
|
|
static void drm_dp_queue_down_tx(struct drm_dp_mst_topology_mgr *mgr,
|
|
@@ -1907,11 +1899,12 @@ static int drm_dp_send_up_ack_reply(struct drm_dp_mst_topology_mgr *mgr,
|
|
|
drm_dp_encode_up_ack_reply(txmsg, req_type);
|
|
|
|
|
|
mutex_lock(&mgr->qlock);
|
|
|
- list_add_tail(&txmsg->next, &mgr->tx_msg_upq);
|
|
|
- if (!mgr->tx_up_in_progress) {
|
|
|
- process_single_up_tx_qlock(mgr);
|
|
|
- }
|
|
|
+
|
|
|
+ process_single_up_tx_qlock(mgr, txmsg);
|
|
|
+
|
|
|
mutex_unlock(&mgr->qlock);
|
|
|
+
|
|
|
+ kfree(txmsg);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -2843,7 +2836,6 @@ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
|
|
|
mutex_init(&mgr->qlock);
|
|
|
mutex_init(&mgr->payload_lock);
|
|
|
mutex_init(&mgr->destroy_connector_lock);
|
|
|
- INIT_LIST_HEAD(&mgr->tx_msg_upq);
|
|
|
INIT_LIST_HEAD(&mgr->tx_msg_downq);
|
|
|
INIT_LIST_HEAD(&mgr->destroy_connector_list);
|
|
|
INIT_WORK(&mgr->work, drm_dp_mst_link_probe_work);
|