diff options
Diffstat (limited to 'drivers/gpu/drm/drm_dp_mst_topology.c')
-rw-r--r-- | drivers/gpu/drm/drm_dp_mst_topology.c | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index 27fbd79d0daf..71ea0521ea96 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c | |||
@@ -1672,13 +1672,19 @@ static int drm_dp_payload_send_msg(struct drm_dp_mst_topology_mgr *mgr, | |||
1672 | u8 sinks[DRM_DP_MAX_SDP_STREAMS]; | 1672 | u8 sinks[DRM_DP_MAX_SDP_STREAMS]; |
1673 | int i; | 1673 | int i; |
1674 | 1674 | ||
1675 | port = drm_dp_get_validated_port_ref(mgr, port); | ||
1676 | if (!port) | ||
1677 | return -EINVAL; | ||
1678 | |||
1675 | port_num = port->port_num; | 1679 | port_num = port->port_num; |
1676 | mstb = drm_dp_get_validated_mstb_ref(mgr, port->parent); | 1680 | mstb = drm_dp_get_validated_mstb_ref(mgr, port->parent); |
1677 | if (!mstb) { | 1681 | if (!mstb) { |
1678 | mstb = drm_dp_get_last_connected_port_and_mstb(mgr, port->parent, &port_num); | 1682 | mstb = drm_dp_get_last_connected_port_and_mstb(mgr, port->parent, &port_num); |
1679 | 1683 | ||
1680 | if (!mstb) | 1684 | if (!mstb) { |
1685 | drm_dp_put_port(port); | ||
1681 | return -EINVAL; | 1686 | return -EINVAL; |
1687 | } | ||
1682 | } | 1688 | } |
1683 | 1689 | ||
1684 | txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL); | 1690 | txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL); |
@@ -1707,6 +1713,7 @@ static int drm_dp_payload_send_msg(struct drm_dp_mst_topology_mgr *mgr, | |||
1707 | kfree(txmsg); | 1713 | kfree(txmsg); |
1708 | fail_put: | 1714 | fail_put: |
1709 | drm_dp_put_mst_branch_device(mstb); | 1715 | drm_dp_put_mst_branch_device(mstb); |
1716 | drm_dp_put_port(port); | ||
1710 | return ret; | 1717 | return ret; |
1711 | } | 1718 | } |
1712 | 1719 | ||
@@ -1789,6 +1796,11 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr) | |||
1789 | req_payload.start_slot = cur_slots; | 1796 | req_payload.start_slot = cur_slots; |
1790 | if (mgr->proposed_vcpis[i]) { | 1797 | if (mgr->proposed_vcpis[i]) { |
1791 | port = container_of(mgr->proposed_vcpis[i], struct drm_dp_mst_port, vcpi); | 1798 | port = container_of(mgr->proposed_vcpis[i], struct drm_dp_mst_port, vcpi); |
1799 | port = drm_dp_get_validated_port_ref(mgr, port); | ||
1800 | if (!port) { | ||
1801 | mutex_unlock(&mgr->payload_lock); | ||
1802 | return -EINVAL; | ||
1803 | } | ||
1792 | req_payload.num_slots = mgr->proposed_vcpis[i]->num_slots; | 1804 | req_payload.num_slots = mgr->proposed_vcpis[i]->num_slots; |
1793 | req_payload.vcpi = mgr->proposed_vcpis[i]->vcpi; | 1805 | req_payload.vcpi = mgr->proposed_vcpis[i]->vcpi; |
1794 | } else { | 1806 | } else { |
@@ -1816,6 +1828,9 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr) | |||
1816 | mgr->payloads[i].payload_state = req_payload.payload_state; | 1828 | mgr->payloads[i].payload_state = req_payload.payload_state; |
1817 | } | 1829 | } |
1818 | cur_slots += req_payload.num_slots; | 1830 | cur_slots += req_payload.num_slots; |
1831 | |||
1832 | if (port) | ||
1833 | drm_dp_put_port(port); | ||
1819 | } | 1834 | } |
1820 | 1835 | ||
1821 | for (i = 0; i < mgr->max_payloads; i++) { | 1836 | for (i = 0; i < mgr->max_payloads; i++) { |
@@ -2121,6 +2136,8 @@ int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr) | |||
2121 | 2136 | ||
2122 | if (mgr->mst_primary) { | 2137 | if (mgr->mst_primary) { |
2123 | int sret; | 2138 | int sret; |
2139 | u8 guid[16]; | ||
2140 | |||
2124 | sret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd, DP_RECEIVER_CAP_SIZE); | 2141 | sret = drm_dp_dpcd_read(mgr->aux, DP_DPCD_REV, mgr->dpcd, DP_RECEIVER_CAP_SIZE); |
2125 | if (sret != DP_RECEIVER_CAP_SIZE) { | 2142 | if (sret != DP_RECEIVER_CAP_SIZE) { |
2126 | DRM_DEBUG_KMS("dpcd read failed - undocked during suspend?\n"); | 2143 | DRM_DEBUG_KMS("dpcd read failed - undocked during suspend?\n"); |
@@ -2135,6 +2152,16 @@ int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr) | |||
2135 | ret = -1; | 2152 | ret = -1; |
2136 | goto out_unlock; | 2153 | goto out_unlock; |
2137 | } | 2154 | } |
2155 | |||
2156 | /* Some hubs forget their guids after they resume */ | ||
2157 | sret = drm_dp_dpcd_read(mgr->aux, DP_GUID, guid, 16); | ||
2158 | if (sret != 16) { | ||
2159 | DRM_DEBUG_KMS("dpcd read failed - undocked during suspend?\n"); | ||
2160 | ret = -1; | ||
2161 | goto out_unlock; | ||
2162 | } | ||
2163 | drm_dp_check_mstb_guid(mgr->mst_primary, guid); | ||
2164 | |||
2138 | ret = 0; | 2165 | ret = 0; |
2139 | } else | 2166 | } else |
2140 | ret = -1; | 2167 | ret = -1; |