diff mbox

drm/i915: Add a timeout to a potentially infinite loop

Message ID 1376613069-15790-4-git-send-email-james.ausmus@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

James Ausmus Aug. 16, 2013, 12:30 a.m. UTC
From: Stéphane Marchesin <marcheu@chromium.org>

BUG=chromium:148595
TEST=by hand, connect a mac DP to VGA adapter, machine doesn't reboot.

Change-Id: I29d518a7e2d906291d75da58a0d4a7c6296658cc
Reviewed-on: https://gerrit.chromium.org/gerrit/33489
Reviewed-by: Mandeep Singh Baines <msb@chromium.org>
Tested-by: Stéphane Marchesin <marcheu@chromium.org>
Reviewed-by: Stuart Abercrombie <sabercrombie@chromium.org>
Commit-Ready: Stéphane Marchesin <marcheu@chromium.org>
[marcheu: fixups for 3.8]
Signed-off-by: Stéphane Marchesin <marcheu@chromium.org>
---
 drivers/gpu/drm/i915/intel_dp.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index ac7d610..29013de 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -345,7 +345,7 @@  intel_dp_aux_ch(struct intel_dp *intel_dp,
 	int recv_bytes;
 	uint32_t status;
 	uint32_t aux_clock_divider;
-	int try, precharge;
+	int try, aux_ch_try, precharge;
 
 	if (IS_HASWELL(dev)) {
 		switch (intel_dig_port->port) {
@@ -428,7 +428,10 @@  intel_dp_aux_ch(struct intel_dp *intel_dp,
 			   DP_AUX_CH_CTL_DONE |
 			   DP_AUX_CH_CTL_TIME_OUT_ERROR |
 			   DP_AUX_CH_CTL_RECEIVE_ERROR);
-		for (;;) {
+		/* Wait 1 ms then timeout, it should be sufficient since the
+		 * timeout above is 400us
+		 */
+		for (aux_ch_try = 0; aux_ch_try < 10; aux_ch_try++) {
 			status = I915_READ(ch_ctl);
 			if ((status & DP_AUX_CH_CTL_SEND_BUSY) == 0)
 				break;
@@ -448,6 +451,9 @@  intel_dp_aux_ch(struct intel_dp *intel_dp,
 		if (status & DP_AUX_CH_CTL_DONE)
 			break;
 	}
+	/* If after 5 tries we're still busy, give up. */
+	if ((status & DP_AUX_CH_CTL_SEND_BUSY) != 0)
+		return -EIO;
 
 	if ((status & DP_AUX_CH_CTL_DONE) == 0) {
 		DRM_ERROR("dp_aux_ch not done status 0x%08x\n", status);