aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_dp_mst_topology.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_dp_mst_topology.c')
-rw-r--r--drivers/gpu/drm/drm_dp_mst_topology.c29
1 files changed, 23 insertions, 6 deletions
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index b0487c9f018c..e23df5fd3836 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -873,9 +873,10 @@ static void drm_dp_destroy_port(struct kref *kref)
873 from an EDID retrieval */ 873 from an EDID retrieval */
874 if (port->connector) { 874 if (port->connector) {
875 mutex_lock(&mgr->destroy_connector_lock); 875 mutex_lock(&mgr->destroy_connector_lock);
876 list_add(&port->connector->destroy_list, &mgr->destroy_connector_list); 876 list_add(&port->next, &mgr->destroy_connector_list);
877 mutex_unlock(&mgr->destroy_connector_lock); 877 mutex_unlock(&mgr->destroy_connector_lock);
878 schedule_work(&mgr->destroy_connector_work); 878 schedule_work(&mgr->destroy_connector_work);
879 return;
879 } 880 }
880 drm_dp_port_teardown_pdt(port, port->pdt); 881 drm_dp_port_teardown_pdt(port, port->pdt);
881 882
@@ -2631,6 +2632,16 @@ void drm_dp_mst_dump_topology(struct seq_file *m,
2631 seq_printf(m, "%02x ", buf[i]); 2632 seq_printf(m, "%02x ", buf[i]);
2632 seq_printf(m, "\n"); 2633 seq_printf(m, "\n");
2633 2634
2635 /* dump the standard OUI branch header */
2636 ret = drm_dp_dpcd_read(mgr->aux, DP_BRANCH_OUI, buf, DP_BRANCH_OUI_HEADER_SIZE);
2637 seq_printf(m, "branch oui: ");
2638 for (i = 0; i < 0x3; i++)
2639 seq_printf(m, "%02x", buf[i]);
2640 seq_printf(m, " devid: ");
2641 for (i = 0x3; i < 0x8; i++)
2642 seq_printf(m, "%c", buf[i]);
2643 seq_printf(m, " revision: hw: %x.%x sw: %x.%x", buf[0x9] >> 4, buf[0x9] & 0xf, buf[0xa], buf[0xb]);
2644 seq_printf(m, "\n");
2634 bret = dump_dp_payload_table(mgr, buf); 2645 bret = dump_dp_payload_table(mgr, buf);
2635 if (bret == true) { 2646 if (bret == true) {
2636 seq_printf(m, "payload table: "); 2647 seq_printf(m, "payload table: ");
@@ -2659,7 +2670,7 @@ static void drm_dp_tx_work(struct work_struct *work)
2659static void drm_dp_destroy_connector_work(struct work_struct *work) 2670static void drm_dp_destroy_connector_work(struct work_struct *work)
2660{ 2671{
2661 struct drm_dp_mst_topology_mgr *mgr = container_of(work, struct drm_dp_mst_topology_mgr, destroy_connector_work); 2672 struct drm_dp_mst_topology_mgr *mgr = container_of(work, struct drm_dp_mst_topology_mgr, destroy_connector_work);
2662 struct drm_connector *connector; 2673 struct drm_dp_mst_port *port;
2663 2674
2664 /* 2675 /*
2665 * Not a regular list traverse as we have to drop the destroy 2676 * Not a regular list traverse as we have to drop the destroy
@@ -2668,15 +2679,21 @@ static void drm_dp_destroy_connector_work(struct work_struct *work)
2668 */ 2679 */
2669 for (;;) { 2680 for (;;) {
2670 mutex_lock(&mgr->destroy_connector_lock); 2681 mutex_lock(&mgr->destroy_connector_lock);
2671 connector = list_first_entry_or_null(&mgr->destroy_connector_list, struct drm_connector, destroy_list); 2682 port = list_first_entry_or_null(&mgr->destroy_connector_list, struct drm_dp_mst_port, next);
2672 if (!connector) { 2683 if (!port) {
2673 mutex_unlock(&mgr->destroy_connector_lock); 2684 mutex_unlock(&mgr->destroy_connector_lock);
2674 break; 2685 break;
2675 } 2686 }
2676 list_del(&connector->destroy_list); 2687 list_del(&port->next);
2677 mutex_unlock(&mgr->destroy_connector_lock); 2688 mutex_unlock(&mgr->destroy_connector_lock);
2678 2689
2679 mgr->cbs->destroy_connector(mgr, connector); 2690 mgr->cbs->destroy_connector(mgr, port->connector);
2691
2692 drm_dp_port_teardown_pdt(port, port->pdt);
2693
2694 if (!port->input && port->vcpi.vcpi > 0)
2695 drm_dp_mst_put_payload_id(mgr, port->vcpi.vcpi);
2696 kfree(port);
2680 } 2697 }
2681} 2698}
2682 2699