@@ -716,14 +716,22 @@ EXPORT_SYMBOL(drm_dp_dpcd_write);
* @aux: DisplayPort AUX channel
* @status: buffer to store the link status in (must be at least 6 bytes)
*
- * Returns the number of bytes transferred on success or a negative error
- * code on failure.
+ * Returns the zero on success or a negative error code on failure.
*/
int drm_dp_dpcd_read_link_status(struct drm_dp_aux *aux,
u8 status[DP_LINK_STATUS_SIZE])
{
- return drm_dp_dpcd_read(aux, DP_LANE0_1_STATUS, status,
- DP_LINK_STATUS_SIZE);
+ int ret;
+
+ ret = drm_dp_dpcd_read(aux, DP_LANE0_1_STATUS, status,
+ DP_LINK_STATUS_SIZE);
+ if (ret < 0)
+ return ret;
+
+ if (ret < DP_LINK_STATUS_SIZE)
+ return -EPROTO;
+
+ return 0;
}
EXPORT_SYMBOL(drm_dp_dpcd_read_link_status);
@@ -1100,20 +1100,6 @@ static bool msm_dp_ctrl_train_pattern_set(struct msm_dp_ctrl_private *ctrl,
return ret == 1;
}
-static int msm_dp_ctrl_read_link_status(struct msm_dp_ctrl_private *ctrl,
- u8 *link_status)
-{
- int ret = 0, len;
-
- len = drm_dp_dpcd_read_link_status(ctrl->aux, link_status);
- if (len != DP_LINK_STATUS_SIZE) {
- DRM_ERROR("DP link status read failed, err: %d\n", len);
- ret = -EINVAL;
- }
-
- return ret;
-}
-
static int msm_dp_ctrl_link_train_1(struct msm_dp_ctrl_private *ctrl,
int *training_step)
{
@@ -1140,9 +1126,11 @@ static int msm_dp_ctrl_link_train_1(struct msm_dp_ctrl_private *ctrl,
for (tries = 0; tries < maximum_retries; tries++) {
drm_dp_link_train_clock_recovery_delay(ctrl->aux, ctrl->panel->dpcd);
- ret = msm_dp_ctrl_read_link_status(ctrl, link_status);
- if (ret)
+ ret = drm_dp_dpcd_read_link_status(ctrl->aux, link_status);
+ if (ret < 0) {
+ DRM_ERROR("DP link status read failed, err: %d\n", ret);
return ret;
+ }
if (drm_dp_clock_recovery_ok(link_status,
ctrl->link->link_params.num_lanes)) {
@@ -1252,9 +1240,11 @@ static int msm_dp_ctrl_link_train_2(struct msm_dp_ctrl_private *ctrl,
for (tries = 0; tries <= maximum_retries; tries++) {
drm_dp_link_train_channel_eq_delay(ctrl->aux, ctrl->panel->dpcd);
- ret = msm_dp_ctrl_read_link_status(ctrl, link_status);
- if (ret)
+ ret = drm_dp_dpcd_read_link_status(ctrl->aux, link_status);
+ if (ret) {
+ DRM_ERROR("DP link status read failed, err: %d\n", ret);
return ret;
+ }
if (drm_dp_channel_eq_ok(link_status,
ctrl->link->link_params.num_lanes)) {
@@ -1804,8 +1794,13 @@ static bool msm_dp_ctrl_channel_eq_ok(struct msm_dp_ctrl_private *ctrl)
{
u8 link_status[DP_LINK_STATUS_SIZE];
int num_lanes = ctrl->link->link_params.num_lanes;
+ int ret;
- msm_dp_ctrl_read_link_status(ctrl, link_status);
+ ret = drm_dp_dpcd_read_link_status(ctrl->aux, link_status);
+ if (ret < 0) {
+ DRM_ERROR("DP link status read failed, err: %d\n", ret);
+ return false;
+ }
return drm_dp_channel_eq_ok(link_status, num_lanes);
}
@@ -1863,7 +1858,11 @@ int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl)
if (!msm_dp_catalog_link_is_connected(ctrl->catalog))
break;
- msm_dp_ctrl_read_link_status(ctrl, link_status);
+ rc = drm_dp_dpcd_read_link_status(ctrl->aux, link_status);
+ if (rc < 0) {
+ DRM_ERROR("DP link status read failed, err: %d\n", rc);
+ break;
+ }
rc = msm_dp_ctrl_link_rate_down_shift(ctrl);
if (rc < 0) { /* already in RBR = 1.6G */
@@ -1888,7 +1887,11 @@ int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl)
if (!msm_dp_catalog_link_is_connected(ctrl->catalog))
break;
- msm_dp_ctrl_read_link_status(ctrl, link_status);
+ rc = drm_dp_dpcd_read_link_status(ctrl->aux, link_status);
+ if (rc < 0) {
+ DRM_ERROR("DP link status read failed, err: %d\n", rc);
+ break;
+ }
if (!drm_dp_clock_recovery_ok(link_status,
ctrl->link->link_params.num_lanes))
@@ -714,21 +714,20 @@ static int msm_dp_link_parse_request(struct msm_dp_link_private *link)
static int msm_dp_link_parse_sink_status_field(struct msm_dp_link_private *link)
{
- int len;
+ int ret;
link->prev_sink_count = link->msm_dp_link.sink_count;
- len = drm_dp_read_sink_count(link->aux);
- if (len < 0) {
+ ret = drm_dp_read_sink_count(link->aux);
+ if (ret < 0) {
DRM_ERROR("DP parse sink count failed\n");
- return len;
+ return ret;
}
- link->msm_dp_link.sink_count = len;
+ link->msm_dp_link.sink_count = ret;
- len = drm_dp_dpcd_read_link_status(link->aux,
- link->link_status);
- if (len < DP_LINK_STATUS_SIZE) {
+ ret = drm_dp_dpcd_read_link_status(link->aux, link->link_status);
+ if (ret < 0) {
DRM_ERROR("DP link status read failed\n");
- return len;
+ return ret;
}
return msm_dp_link_parse_request(link);
drm_dp_dpcd_read_link_status() follows the "return error code or number of bytes read" protocol, with the code returning less bytes than requested in case of some errors. However most of the drivers (except the drm/msm one) interpreted that as "return error code in case of any error". Move return len check to drm_dp_dpcd_read_link_status() and make drm/msm/dp follow that protocol too. Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/display/drm_dp_helper.c | 16 +++++++++--- drivers/gpu/drm/msm/dp/dp_ctrl.c | 45 ++++++++++++++++++--------------- drivers/gpu/drm/msm/dp/dp_link.c | 17 ++++++------- 3 files changed, 44 insertions(+), 34 deletions(-)