aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2011-10-03 09:13:46 -0400
committerDave Airlie <airlied@redhat.com>2011-10-03 13:37:31 -0400
commit6375bda073724ead7df08746866b724b1799a295 (patch)
treee2fb38f42845db6a31a532611e1f4e4dd164bc12 /drivers
parent109bc10d30f33e84f1d7289f0039e0c858ade82f (diff)
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: Alex Deucher <alexander.deucher@amd.com> Cc: Brad Campbell <lists2009@fnarfbargle.com> Cc: stable@kernel.org Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/radeon/atombios_dp.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c
index f526fa77e32..4da23889fea 100644
--- a/drivers/gpu/drm/radeon/atombios_dp.c
+++ b/drivers/gpu/drm/radeon/atombios_dp.c
@@ -115,6 +115,7 @@ static int radeon_dp_aux_native_write(struct radeon_connector *radeon_connector,
115 u8 msg[20]; 115 u8 msg[20];
116 int msg_bytes = send_bytes + 4; 116 int msg_bytes = send_bytes + 4;
117 u8 ack; 117 u8 ack;
118 unsigned retry;
118 119
119 if (send_bytes > 16) 120 if (send_bytes > 16)
120 return -1; 121 return -1;
@@ -125,20 +126,20 @@ static int radeon_dp_aux_native_write(struct radeon_connector *radeon_connector,
125 msg[3] = (msg_bytes << 4) | (send_bytes - 1); 126 msg[3] = (msg_bytes << 4) | (send_bytes - 1);
126 memcpy(&msg[4], send, send_bytes); 127 memcpy(&msg[4], send, send_bytes);
127 128
128 while (1) { 129 for (retry = 0; retry < 4; retry++) {
129 ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus, 130 ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus,
130 msg, msg_bytes, NULL, 0, delay, &ack); 131 msg, msg_bytes, NULL, 0, delay, &ack);
131 if (ret < 0) 132 if (ret < 0)
132 return ret; 133 return ret;
133 if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) 134 if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK)
134 break; 135 return send_bytes;
135 else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER) 136 else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER)
136 udelay(400); 137 udelay(400);
137 else 138 else
138 return -EIO; 139 return -EIO;
139 } 140 }
140 141
141 return send_bytes; 142 return -EIO;
142} 143}
143 144
144static int radeon_dp_aux_native_read(struct radeon_connector *radeon_connector, 145static 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 int msg_bytes = 4; 150 int msg_bytes = 4;
150 u8 ack; 151 u8 ack;
151 int ret; 152 int ret;
153 unsigned retry;
152 154
153 msg[0] = address; 155 msg[0] = address;
154 msg[1] = address >> 8; 156 msg[1] = address >> 8;
155 msg[2] = AUX_NATIVE_READ << 4; 157 msg[2] = AUX_NATIVE_READ << 4;
156 msg[3] = (msg_bytes << 4) | (recv_bytes - 1); 158 msg[3] = (msg_bytes << 4) | (recv_bytes - 1);
157 159
158 while (1) { 160 for (retry = 0; retry < 4; retry++) {
159 ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus, 161 ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus,
160 msg, msg_bytes, recv, recv_bytes, delay, &ack); 162 msg, msg_bytes, recv, recv_bytes, delay, &ack);
161 if (ret < 0) 163 if (ret < 0)
@@ -169,6 +171,8 @@ static int radeon_dp_aux_native_read(struct radeon_connector *radeon_connector,
169 else 171 else
170 return -EIO; 172 return -EIO;
171 } 173 }
174
175 return -EIO;
172} 176}
173 177
174static void radeon_write_dpcd_reg(struct radeon_connector *radeon_connector, 178static void radeon_write_dpcd_reg(struct radeon_connector *radeon_connector,