Rev 5271 | Rev 6088 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5271 | Rev 6084 | ||
---|---|---|---|
Line 58... | Line 58... | ||
58 | 58 | ||
59 | static int drm_dp_send_dpcd_write(struct drm_dp_mst_topology_mgr *mgr, |
59 | static int drm_dp_send_dpcd_write(struct drm_dp_mst_topology_mgr *mgr, |
60 | struct drm_dp_mst_port *port, |
60 | struct drm_dp_mst_port *port, |
Line 61... | Line 61... | ||
61 | int offset, int size, u8 *bytes); |
61 | int offset, int size, u8 *bytes); |
62 | 62 | ||
63 | static int drm_dp_send_link_address(struct drm_dp_mst_topology_mgr *mgr, |
63 | static void drm_dp_send_link_address(struct drm_dp_mst_topology_mgr *mgr, |
64 | struct drm_dp_mst_branch *mstb); |
64 | struct drm_dp_mst_branch *mstb); |
65 | static int drm_dp_send_enum_path_resources(struct drm_dp_mst_topology_mgr *mgr, |
65 | static int drm_dp_send_enum_path_resources(struct drm_dp_mst_topology_mgr *mgr, |
66 | struct drm_dp_mst_branch *mstb, |
66 | struct drm_dp_mst_branch *mstb, |
Line 738... | Line 738... | ||
738 | 738 | ||
739 | static bool check_txmsg_state(struct drm_dp_mst_topology_mgr *mgr, |
739 | static bool check_txmsg_state(struct drm_dp_mst_topology_mgr *mgr, |
740 | struct drm_dp_sideband_msg_tx *txmsg) |
740 | struct drm_dp_sideband_msg_tx *txmsg) |
741 | { |
741 | { |
- | 742 | bool ret; |
|
- | 743 | ||
742 | bool ret; |
744 | /* |
- | 745 | * All updates to txmsg->state are protected by mgr->qlock, and the two |
|
- | 746 | * cases we check here are terminal states. For those the barriers |
|
- | 747 | * provided by the wake_up/wait_event pair are enough. |
|
743 | mutex_lock(&mgr->qlock); |
748 | */ |
744 | ret = (txmsg->state == DRM_DP_SIDEBAND_TX_RX || |
749 | ret = (txmsg->state == DRM_DP_SIDEBAND_TX_RX || |
745 | txmsg->state == DRM_DP_SIDEBAND_TX_TIMEOUT); |
- | |
746 | mutex_unlock(&mgr->qlock); |
750 | txmsg->state == DRM_DP_SIDEBAND_TX_TIMEOUT); |
747 | return ret; |
751 | return ret; |
Line 748... | Line 752... | ||
748 | } |
752 | } |
749 | 753 | ||
Line 805... | Line 809... | ||
805 | { |
809 | { |
806 | struct drm_dp_mst_branch *mstb = container_of(kref, struct drm_dp_mst_branch, kref); |
810 | struct drm_dp_mst_branch *mstb = container_of(kref, struct drm_dp_mst_branch, kref); |
807 | struct drm_dp_mst_port *port, *tmp; |
811 | struct drm_dp_mst_port *port, *tmp; |
808 | bool wake_tx = false; |
812 | bool wake_tx = false; |
Line 809... | Line -... | ||
809 | - | ||
810 | cancel_work_sync(&mstb->mgr->work); |
- | |
811 | 813 | ||
812 | /* |
814 | /* |
813 | * destroy all ports - don't need lock |
815 | * destroy all ports - don't need lock |
814 | * as there are no more references to the mst branch |
816 | * as there are no more references to the mst branch |
815 | * device at this point. |
817 | * device at this point. |
Line 864... | Line 866... | ||
864 | 866 | ||
865 | static void drm_dp_destroy_port(struct kref *kref) |
867 | static void drm_dp_destroy_port(struct kref *kref) |
866 | { |
868 | { |
867 | struct drm_dp_mst_port *port = container_of(kref, struct drm_dp_mst_port, kref); |
869 | struct drm_dp_mst_port *port = container_of(kref, struct drm_dp_mst_port, kref); |
- | 870 | struct drm_dp_mst_topology_mgr *mgr = port->mgr; |
|
868 | struct drm_dp_mst_topology_mgr *mgr = port->mgr; |
871 | |
869 | if (!port->input) { |
872 | if (!port->input) { |
Line 870... | Line 873... | ||
870 | port->vcpi.num_slots = 0; |
873 | port->vcpi.num_slots = 0; |
871 | - | ||
872 | kfree(port->cached_edid); |
- | |
873 | if (port->connector) |
- | |
Line -... | Line 874... | ||
- | 874 | ||
- | 875 | kfree(port->cached_edid); |
|
874 | (*port->mgr->cbs->destroy_connector)(mgr, port->connector); |
876 | |
- | 877 | /* |
|
- | 878 | * The only time we don't have a connector |
|
- | 879 | * on an output port is if the connector init |
|
- | 880 | * fails. |
|
- | 881 | */ |
|
- | 882 | if (port->connector) { |
|
- | 883 | /* we can't destroy the connector here, as |
|
- | 884 | * we might be holding the mode_config.mutex |
|
- | 885 | * from an EDID retrieval */ |
|
- | 886 | ||
- | 887 | mutex_lock(&mgr->destroy_connector_lock); |
|
- | 888 | list_add(&port->next, &mgr->destroy_connector_list); |
|
- | 889 | mutex_unlock(&mgr->destroy_connector_lock); |
|
- | 890 | // schedule_work(&mgr->destroy_connector_work); |
|
- | 891 | return; |
|
875 | drm_dp_port_teardown_pdt(port, port->pdt); |
892 | } |
876 | 893 | /* no need to clean up vcpi |
|
877 | if (!port->input && port->vcpi.vcpi > 0) |
894 | * as if we have no connector we never setup a vcpi */ |
878 | drm_dp_mst_put_payload_id(mgr, port->vcpi.vcpi); |
- | |
879 | } |
- | |
880 | kfree(port); |
895 | drm_dp_port_teardown_pdt(port, port->pdt); |
Line 881... | Line 896... | ||
881 | 896 | } |
|
882 | (*mgr->cbs->hotplug)(mgr); |
897 | kfree(port); |
883 | } |
898 | } |
Line 1019... | Line 1034... | ||
1019 | port->guid_valid = true; |
1034 | port->guid_valid = true; |
1020 | } |
1035 | } |
1021 | } |
1036 | } |
1022 | } |
1037 | } |
Line 1023... | Line 1038... | ||
1023 | 1038 | ||
1024 | static void build_mst_prop_path(struct drm_dp_mst_port *port, |
1039 | static void build_mst_prop_path(const struct drm_dp_mst_branch *mstb, |
1025 | struct drm_dp_mst_branch *mstb, |
1040 | int pnum, |
1026 | char *proppath, |
1041 | char *proppath, |
1027 | size_t proppath_size) |
1042 | size_t proppath_size) |
1028 | { |
1043 | { |
1029 | int i; |
1044 | int i; |
Line 1033... | Line 1048... | ||
1033 | int shift = (i % 2) ? 0 : 4; |
1048 | int shift = (i % 2) ? 0 : 4; |
1034 | int port_num = mstb->rad[i / 2] >> shift; |
1049 | int port_num = mstb->rad[i / 2] >> shift; |
1035 | snprintf(temp, sizeof(temp), "-%d", port_num); |
1050 | snprintf(temp, sizeof(temp), "-%d", port_num); |
1036 | strlcat(proppath, temp, proppath_size); |
1051 | strlcat(proppath, temp, proppath_size); |
1037 | } |
1052 | } |
1038 | snprintf(temp, sizeof(temp), "-%d", port->port_num); |
1053 | snprintf(temp, sizeof(temp), "-%d", pnum); |
1039 | strlcat(proppath, temp, proppath_size); |
1054 | strlcat(proppath, temp, proppath_size); |
1040 | } |
1055 | } |
Line 1041... | Line 1056... | ||
1041 | 1056 | ||
1042 | static void drm_dp_add_port(struct drm_dp_mst_branch *mstb, |
1057 | static void drm_dp_add_port(struct drm_dp_mst_branch *mstb, |
Line 1097... | Line 1112... | ||
1097 | 1112 | ||
1098 | if (old_pdt != port->pdt && !port->input) { |
1113 | if (old_pdt != port->pdt && !port->input) { |
Line 1099... | Line 1114... | ||
1099 | drm_dp_port_teardown_pdt(port, old_pdt); |
1114 | drm_dp_port_teardown_pdt(port, old_pdt); |
1100 | 1115 | ||
1101 | ret = drm_dp_port_setup_pdt(port); |
1116 | ret = drm_dp_port_setup_pdt(port); |
1102 | if (ret == true) { |
- | |
1103 | drm_dp_send_link_address(mstb->mgr, port->mstb); |
- | |
1104 | port->mstb->link_address_sent = true; |
1117 | if (ret == true) |
Line 1105... | Line 1118... | ||
1105 | } |
1118 | drm_dp_send_link_address(mstb->mgr, port->mstb); |
1106 | } |
1119 | } |
1107 | - | ||
1108 | if (created && !port->input) { |
- | |
Line -... | Line 1120... | ||
- | 1120 | ||
- | 1121 | if (created && !port->input) { |
|
1109 | char proppath[255]; |
1122 | char proppath[255]; |
- | 1123 | ||
- | 1124 | build_mst_prop_path(mstb, port->port_num, proppath, sizeof(proppath)); |
|
- | 1125 | port->connector = (*mstb->mgr->cbs->add_connector)(mstb->mgr, port, proppath); |
|
- | 1126 | if (!port->connector) { |
|
- | 1127 | /* remove it from the port list */ |
|
- | 1128 | mutex_lock(&mstb->mgr->lock); |
|
- | 1129 | list_del(&port->next); |
|
- | 1130 | mutex_unlock(&mstb->mgr->lock); |
|
- | 1131 | /* drop port list reference */ |
|
1110 | build_mst_prop_path(port, mstb, proppath, sizeof(proppath)); |
1132 | drm_dp_put_port(port); |
- | 1133 | goto out; |
|
1111 | port->connector = (*mstb->mgr->cbs->add_connector)(mstb->mgr, port, proppath); |
1134 | } |
- | 1135 | if (port->port_num >= DP_MST_LOGICAL_PORT_0) { |
|
1112 | 1136 | port->cached_edid = drm_get_edid(port->connector, &port->aux.ddc); |
|
Line -... | Line 1137... | ||
- | 1137 | drm_mode_connector_set_tile_property(port->connector); |
|
1113 | if (port->port_num >= 8) { |
1138 | } |
1114 | port->cached_edid = drm_get_edid(port->connector, &port->aux.ddc); |
1139 | (*mstb->mgr->cbs->register_connector)(port->connector); |
1115 | } |
1140 | } |
Line 1116... | Line 1141... | ||
1116 | } |
1141 | |
Line 1164... | Line 1189... | ||
1164 | { |
1189 | { |
1165 | struct drm_dp_mst_branch *mstb; |
1190 | struct drm_dp_mst_branch *mstb; |
1166 | struct drm_dp_mst_port *port; |
1191 | struct drm_dp_mst_port *port; |
1167 | int i; |
1192 | int i; |
1168 | /* find the port by iterating down */ |
1193 | /* find the port by iterating down */ |
- | 1194 | ||
- | 1195 | mutex_lock(&mgr->lock); |
|
1169 | mstb = mgr->mst_primary; |
1196 | mstb = mgr->mst_primary; |
Line 1170... | Line 1197... | ||
1170 | 1197 | ||
1171 | for (i = 0; i < lct - 1; i++) { |
1198 | for (i = 0; i < lct - 1; i++) { |
1172 | int shift = (i % 2) ? 0 : 4; |
1199 | int shift = (i % 2) ? 0 : 4; |
Line 1173... | Line 1200... | ||
1173 | int port_num = rad[i / 2] >> shift; |
1200 | int port_num = rad[i / 2] >> shift; |
1174 | 1201 | ||
- | 1202 | list_for_each_entry(port, &mstb->ports, next) { |
|
1175 | list_for_each_entry(port, &mstb->ports, next) { |
1203 | if (port->port_num == port_num) { |
1176 | if (port->port_num == port_num) { |
1204 | mstb = port->mstb; |
1177 | if (!port->mstb) { |
1205 | if (!mstb) { |
1178 | DRM_ERROR("failed to lookup MSTB with lct %d, rad %02x\n", lct, rad[0]); |
1206 | DRM_ERROR("failed to lookup MSTB with lct %d, rad %02x\n", lct, rad[0]); |
Line 1179... | Line -... | ||
1179 | return NULL; |
- | |
1180 | } |
1207 | goto out; |
1181 | 1208 | } |
|
1182 | mstb = port->mstb; |
1209 | |
1183 | break; |
1210 | break; |
1184 | } |
1211 | } |
- | 1212 | } |
|
- | 1213 | } |
|
1185 | } |
1214 | kref_get(&mstb->kref); |
1186 | } |
1215 | out: |
Line 1187... | Line 1216... | ||
1187 | kref_get(&mstb->kref); |
1216 | mutex_unlock(&mgr->lock); |
1188 | return mstb; |
1217 | return mstb; |
1189 | } |
1218 | } |
1190 | 1219 | ||
1191 | static void drm_dp_check_and_send_link_address(struct drm_dp_mst_topology_mgr *mgr, |
- | |
- | 1220 | static void drm_dp_check_and_send_link_address(struct drm_dp_mst_topology_mgr *mgr, |
|
1192 | struct drm_dp_mst_branch *mstb) |
1221 | struct drm_dp_mst_branch *mstb) |
1193 | { |
1222 | { |
1194 | struct drm_dp_mst_port *port; |
- | |
1195 | 1223 | struct drm_dp_mst_port *port; |
|
1196 | if (!mstb->link_address_sent) { |
1224 | struct drm_dp_mst_branch *mstb_child; |
1197 | drm_dp_send_link_address(mgr, mstb); |
1225 | if (!mstb->link_address_sent) |
1198 | mstb->link_address_sent = true; |
1226 | drm_dp_send_link_address(mgr, mstb); |
Line 1199... | Line 1227... | ||
1199 | } |
1227 | |
1200 | list_for_each_entry(port, &mstb->ports, next) { |
1228 | list_for_each_entry(port, &mstb->ports, next) { |
Line 1201... | Line 1229... | ||
1201 | if (port->input) |
1229 | if (port->input) |
1202 | continue; |
1230 | continue; |
Line 1203... | Line 1231... | ||
1203 | 1231 | ||
- | 1232 | if (!port->ddps) |
|
- | 1233 | continue; |
|
1204 | if (!port->ddps) |
1234 | |
- | 1235 | if (!port->available_pbn) |
|
- | 1236 | drm_dp_send_enum_path_resources(mgr, mstb, port); |
|
- | 1237 | ||
1205 | continue; |
1238 | if (port->mstb) { |
1206 | 1239 | mstb_child = drm_dp_get_validated_mstb_ref(mgr, port->mstb); |
|
Line 1207... | Line 1240... | ||
1207 | if (!port->available_pbn) |
1240 | if (mstb_child) { |
1208 | drm_dp_send_enum_path_resources(mgr, mstb, port); |
1241 | drm_dp_check_and_send_link_address(mgr, mstb_child); |
1209 | 1242 | drm_dp_put_mst_branch_device(mstb_child); |
|
- | 1243 | } |
|
Line -... | Line 1244... | ||
- | 1244 | } |
|
- | 1245 | } |
|
- | 1246 | } |
|
- | 1247 | ||
- | 1248 | static void drm_dp_mst_link_probe_work(struct work_struct *work) |
|
- | 1249 | { |
|
- | 1250 | struct drm_dp_mst_topology_mgr *mgr = container_of(work, struct drm_dp_mst_topology_mgr, work); |
|
1210 | if (port->mstb) |
1251 | struct drm_dp_mst_branch *mstb; |
- | 1252 | ||
1211 | drm_dp_check_and_send_link_address(mgr, port->mstb); |
1253 | mutex_lock(&mgr->lock); |
1212 | } |
1254 | mstb = mgr->mst_primary; |
Line 1213... | Line 1255... | ||
1213 | } |
1255 | if (mstb) { |
1214 | 1256 | kref_get(&mstb->kref); |
|
1215 | static void drm_dp_mst_link_probe_work(struct work_struct *work) |
1257 | } |
Line 1270... | Line 1312... | ||
1270 | if (ret == -EIO && retries < 5) { |
1312 | if (ret == -EIO && retries < 5) { |
1271 | retries++; |
1313 | retries++; |
1272 | goto retry; |
1314 | goto retry; |
1273 | } |
1315 | } |
1274 | DRM_DEBUG_KMS("failed to dpcd write %d %d\n", tosend, ret); |
1316 | DRM_DEBUG_KMS("failed to dpcd write %d %d\n", tosend, ret); |
1275 | WARN(1, "fail\n"); |
- | |
Line 1276... | Line 1317... | ||
1276 | 1317 | ||
1277 | return -EIO; |
1318 | return -EIO; |
1278 | } |
1319 | } |
1279 | offset += tosend; |
1320 | offset += tosend; |
Line 1368... | Line 1409... | ||
1368 | return 1; |
1409 | return 1; |
1369 | } |
1410 | } |
1370 | return 0; |
1411 | return 0; |
1371 | } |
1412 | } |
Line 1372... | Line -... | ||
1372 | - | ||
1373 | /* must be called holding qlock */ |
1413 | |
1374 | static void process_single_down_tx_qlock(struct drm_dp_mst_topology_mgr *mgr) |
1414 | static void process_single_down_tx_qlock(struct drm_dp_mst_topology_mgr *mgr) |
1375 | { |
1415 | { |
1376 | struct drm_dp_sideband_msg_tx *txmsg; |
1416 | struct drm_dp_sideband_msg_tx *txmsg; |
Line -... | Line 1417... | ||
- | 1417 | int ret; |
|
- | 1418 | ||
1377 | int ret; |
1419 | WARN_ON(!mutex_is_locked(&mgr->qlock)); |
1378 | 1420 | ||
1379 | /* construct a chunk from the first msg in the tx_msg queue */ |
1421 | /* construct a chunk from the first msg in the tx_msg queue */ |
1380 | if (list_empty(&mgr->tx_msg_downq)) { |
1422 | if (list_empty(&mgr->tx_msg_downq)) { |
1381 | mgr->tx_down_in_progress = false; |
1423 | mgr->tx_down_in_progress = false; |
Line 1433... | Line 1475... | ||
1433 | if (!mgr->tx_down_in_progress) |
1475 | if (!mgr->tx_down_in_progress) |
1434 | process_single_down_tx_qlock(mgr); |
1476 | process_single_down_tx_qlock(mgr); |
1435 | mutex_unlock(&mgr->qlock); |
1477 | mutex_unlock(&mgr->qlock); |
1436 | } |
1478 | } |
Line 1437... | Line 1479... | ||
1437 | 1479 | ||
1438 | static int drm_dp_send_link_address(struct drm_dp_mst_topology_mgr *mgr, |
1480 | static void drm_dp_send_link_address(struct drm_dp_mst_topology_mgr *mgr, |
1439 | struct drm_dp_mst_branch *mstb) |
1481 | struct drm_dp_mst_branch *mstb) |
1440 | { |
1482 | { |
1441 | int len; |
1483 | int len; |
1442 | struct drm_dp_sideband_msg_tx *txmsg; |
1484 | struct drm_dp_sideband_msg_tx *txmsg; |
Line 1443... | Line 1485... | ||
1443 | int ret; |
1485 | int ret; |
1444 | 1486 | ||
1445 | txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL); |
1487 | txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL); |
Line 1446... | Line 1488... | ||
1446 | if (!txmsg) |
1488 | if (!txmsg) |
1447 | return -ENOMEM; |
1489 | return; |
Line -... | Line 1490... | ||
- | 1490 | ||
1448 | 1491 | txmsg->dst = mstb; |
|
Line 1449... | Line 1492... | ||
1449 | txmsg->dst = mstb; |
1492 | len = build_link_address(txmsg); |
1450 | len = build_link_address(txmsg); |
1493 | |
1451 | 1494 | mstb->link_address_sent = true; |
|
Line 1474... | Line 1517... | ||
1474 | for (i = 0; i < txmsg->reply.u.link_addr.nports; i++) { |
1517 | for (i = 0; i < txmsg->reply.u.link_addr.nports; i++) { |
1475 | drm_dp_add_port(mstb, mgr->dev, &txmsg->reply.u.link_addr.ports[i]); |
1518 | drm_dp_add_port(mstb, mgr->dev, &txmsg->reply.u.link_addr.ports[i]); |
1476 | } |
1519 | } |
1477 | (*mgr->cbs->hotplug)(mgr); |
1520 | (*mgr->cbs->hotplug)(mgr); |
1478 | } |
1521 | } |
1479 | } else |
1522 | } else { |
- | 1523 | mstb->link_address_sent = false; |
|
1480 | DRM_DEBUG_KMS("link address failed %d\n", ret); |
1524 | DRM_DEBUG_KMS("link address failed %d\n", ret); |
- | 1525 | } |
|
Line 1481... | Line 1526... | ||
1481 | 1526 | ||
1482 | kfree(txmsg); |
- | |
1483 | return 0; |
1527 | kfree(txmsg); |
Line 1484... | Line 1528... | ||
1484 | } |
1528 | } |
1485 | 1529 | ||
1486 | static int drm_dp_send_enum_path_resources(struct drm_dp_mst_topology_mgr *mgr, |
1530 | static int drm_dp_send_enum_path_resources(struct drm_dp_mst_topology_mgr *mgr, |
Line 2238... | Line 2282... | ||
2238 | if (!port) |
2282 | if (!port) |
2239 | return NULL; |
2283 | return NULL; |
Line 2240... | Line 2284... | ||
2240 | 2284 | ||
2241 | if (port->cached_edid) |
2285 | if (port->cached_edid) |
2242 | edid = drm_edid_duplicate(port->cached_edid); |
2286 | edid = drm_edid_duplicate(port->cached_edid); |
2243 | else |
2287 | else { |
2244 | edid = drm_get_edid(connector, &port->aux.ddc); |
- | |
2245 | 2288 | edid = drm_get_edid(connector, &port->aux.ddc); |
|
- | 2289 | drm_mode_connector_set_tile_property(connector); |
|
2246 | drm_mode_connector_set_tile_property(connector); |
2290 | } |
2247 | drm_dp_put_port(port); |
2291 | drm_dp_put_port(port); |
2248 | return edid; |
2292 | return edid; |
2249 | } |
2293 | } |
Line 2324... | Line 2368... | ||
2324 | out: |
2368 | out: |
2325 | return false; |
2369 | return false; |
2326 | } |
2370 | } |
2327 | EXPORT_SYMBOL(drm_dp_mst_allocate_vcpi); |
2371 | EXPORT_SYMBOL(drm_dp_mst_allocate_vcpi); |
Line -... | Line 2372... | ||
- | 2372 | ||
- | 2373 | int drm_dp_mst_get_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port) |
|
- | 2374 | { |
|
- | 2375 | int slots = 0; |
|
- | 2376 | port = drm_dp_get_validated_port_ref(mgr, port); |
|
- | 2377 | if (!port) |
|
- | 2378 | return slots; |
|
- | 2379 | ||
- | 2380 | slots = port->vcpi.num_slots; |
|
- | 2381 | drm_dp_put_port(port); |
|
- | 2382 | return slots; |
|
- | 2383 | } |
|
- | 2384 | EXPORT_SYMBOL(drm_dp_mst_get_vcpi_slots); |
|
2328 | 2385 | ||
2329 | /** |
2386 | /** |
2330 | * drm_dp_mst_reset_vcpi_slots() - Reset number of slots to 0 for VCPI |
2387 | * drm_dp_mst_reset_vcpi_slots() - Reset number of slots to 0 for VCPI |
2331 | * @mgr: manager for this port |
2388 | * @mgr: manager for this port |
2332 | * @port: unverified pointer to a port. |
2389 | * @port: unverified pointer to a port. |
Line 2586... | Line 2643... | ||
2586 | int max_payloads, int conn_base_id) |
2643 | int max_payloads, int conn_base_id) |
2587 | { |
2644 | { |
2588 | mutex_init(&mgr->lock); |
2645 | mutex_init(&mgr->lock); |
2589 | mutex_init(&mgr->qlock); |
2646 | mutex_init(&mgr->qlock); |
2590 | mutex_init(&mgr->payload_lock); |
2647 | mutex_init(&mgr->payload_lock); |
- | 2648 | mutex_init(&mgr->destroy_connector_lock); |
|
2591 | INIT_LIST_HEAD(&mgr->tx_msg_upq); |
2649 | INIT_LIST_HEAD(&mgr->tx_msg_upq); |
2592 | INIT_LIST_HEAD(&mgr->tx_msg_downq); |
2650 | INIT_LIST_HEAD(&mgr->tx_msg_downq); |
- | 2651 | INIT_LIST_HEAD(&mgr->destroy_connector_list); |
|
2593 | INIT_WORK(&mgr->work, drm_dp_mst_link_probe_work); |
2652 | INIT_WORK(&mgr->work, drm_dp_mst_link_probe_work); |
2594 | INIT_WORK(&mgr->tx_work, drm_dp_tx_work); |
2653 | INIT_WORK(&mgr->tx_work, drm_dp_tx_work); |
2595 | // init_waitqueue_head(&mgr->tx_waitq); |
2654 | // init_waitqueue_head(&mgr->tx_waitq); |
2596 | mgr->dev = dev; |
2655 | mgr->dev = dev; |
2597 | mgr->aux = aux; |
2656 | mgr->aux = aux; |
Line 2648... | Line 2707... | ||
2648 | /* construct i2c msg */ |
2707 | /* construct i2c msg */ |
2649 | /* see if last msg is a read */ |
2708 | /* see if last msg is a read */ |
2650 | if (msgs[num - 1].flags & I2C_M_RD) |
2709 | if (msgs[num - 1].flags & I2C_M_RD) |
2651 | reading = true; |
2710 | reading = true; |
Line 2652... | Line 2711... | ||
2652 | 2711 | ||
2653 | if (!reading) { |
2712 | if (!reading || (num - 1 > DP_REMOTE_I2C_READ_MAX_TRANSACTIONS)) { |
2654 | DRM_DEBUG_KMS("Unsupported I2C transaction for MST device\n"); |
2713 | DRM_DEBUG_KMS("Unsupported I2C transaction for MST device\n"); |
2655 | ret = -EIO; |
2714 | ret = -EIO; |
2656 | goto out; |
2715 | goto out; |
Line -... | Line 2716... | ||
- | 2716 | } |
|
2657 | } |
2717 | |
2658 | 2718 | memset(&msg, 0, sizeof(msg)); |
|
2659 | msg.req_type = DP_REMOTE_I2C_READ; |
2719 | msg.req_type = DP_REMOTE_I2C_READ; |
2660 | msg.u.i2c_read.num_transactions = num - 1; |
2720 | msg.u.i2c_read.num_transactions = num - 1; |
2661 | msg.u.i2c_read.port_number = port->port_num; |
2721 | msg.u.i2c_read.port_number = port->port_num; |