Commit 6375bda0 authored by Alex Deucher's avatar Alex Deucher Committed by Dave Airlie

drm/radeon/kms: add retry limits for native DP aux defer

The previous code could potentially loop forever.  Limit
the number of DP aux defer retries to 4 for native aux
transactions, same as i2c over aux transactions.

Noticed by: Brad Campbell <lists2009@fnarfbargle.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Cc: Brad Campbell <lists2009@fnarfbargle.com>
Cc: stable@kernel.org
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 109bc10d
...@@ -115,6 +115,7 @@ static int radeon_dp_aux_native_write(struct radeon_connector *radeon_connector, ...@@ -115,6 +115,7 @@ static int radeon_dp_aux_native_write(struct radeon_connector *radeon_connector,
u8 msg[20]; u8 msg[20];
int msg_bytes = send_bytes + 4; int msg_bytes = send_bytes + 4;
u8 ack; u8 ack;
unsigned retry;
if (send_bytes > 16) if (send_bytes > 16)
return -1; return -1;
...@@ -125,20 +126,20 @@ static int radeon_dp_aux_native_write(struct radeon_connector *radeon_connector, ...@@ -125,20 +126,20 @@ static int radeon_dp_aux_native_write(struct radeon_connector *radeon_connector,
msg[3] = (msg_bytes << 4) | (send_bytes - 1); msg[3] = (msg_bytes << 4) | (send_bytes - 1);
memcpy(&msg[4], send, send_bytes); memcpy(&msg[4], send, send_bytes);
while (1) { for (retry = 0; retry < 4; retry++) {
ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus, ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus,
msg, msg_bytes, NULL, 0, delay, &ack); msg, msg_bytes, NULL, 0, delay, &ack);
if (ret < 0) if (ret < 0)
return ret; return ret;
if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK)
break; return send_bytes;
else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER) else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER)
udelay(400); udelay(400);
else else
return -EIO; return -EIO;
} }
return send_bytes; return -EIO;
} }
static int radeon_dp_aux_native_read(struct radeon_connector *radeon_connector, static int radeon_dp_aux_native_read(struct radeon_connector *radeon_connector,
...@@ -149,13 +150,14 @@ static int radeon_dp_aux_native_read(struct radeon_connector *radeon_connector, ...@@ -149,13 +150,14 @@ static int radeon_dp_aux_native_read(struct radeon_connector *radeon_connector,
int msg_bytes = 4; int msg_bytes = 4;
u8 ack; u8 ack;
int ret; int ret;
unsigned retry;
msg[0] = address; msg[0] = address;
msg[1] = address >> 8; msg[1] = address >> 8;
msg[2] = AUX_NATIVE_READ << 4; msg[2] = AUX_NATIVE_READ << 4;
msg[3] = (msg_bytes << 4) | (recv_bytes - 1); msg[3] = (msg_bytes << 4) | (recv_bytes - 1);
while (1) { for (retry = 0; retry < 4; retry++) {
ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus, ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus,
msg, msg_bytes, recv, recv_bytes, delay, &ack); msg, msg_bytes, recv, recv_bytes, delay, &ack);
if (ret < 0) if (ret < 0)
...@@ -169,6 +171,8 @@ static int radeon_dp_aux_native_read(struct radeon_connector *radeon_connector, ...@@ -169,6 +171,8 @@ static int radeon_dp_aux_native_read(struct radeon_connector *radeon_connector,
else else
return -EIO; return -EIO;
} }
return -EIO;
} }
static void radeon_write_dpcd_reg(struct radeon_connector *radeon_connector, static void radeon_write_dpcd_reg(struct radeon_connector *radeon_connector,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment