drm/radeon/kms: retry aux transactions if there are status flags
authorAlex Deucher <alexander.deucher@amd.com>
Tue, 4 Oct 2011 21:23:15 +0000 (17:23 -0400)
committerDave Airlie <airlied@redhat.com>
Wed, 5 Oct 2011 09:30:50 +0000 (10:30 +0100)
If there are error flags in the aux status, retry the transaction.
This makes aux much more reliable, especially on llano systems.

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
Cc: stable@kernel.org
Signed-off-by: Dave Airlie <airlied@redhat.com>
drivers/gpu/drm/radeon/atombios_dp.c

index 4da2388..79e8ebc 100644 (file)
@@ -129,7 +129,9 @@ static int radeon_dp_aux_native_write(struct radeon_connector *radeon_connector,
        for (retry = 0; retry < 4; retry++) {
                ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus,
                                            msg, msg_bytes, NULL, 0, delay, &ack);
-               if (ret < 0)
+               if (ret == -EBUSY)
+                       continue;
+               else if (ret < 0)
                        return ret;
                if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK)
                        return send_bytes;
@@ -160,7 +162,9 @@ static int radeon_dp_aux_native_read(struct radeon_connector *radeon_connector,
        for (retry = 0; retry < 4; retry++) {
                ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus,
                                            msg, msg_bytes, recv, recv_bytes, delay, &ack);
-               if (ret < 0)
+               if (ret == -EBUSY)
+                       continue;
+               else if (ret < 0)
                        return ret;
                if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK)
                        return ret;
@@ -236,7 +240,9 @@ int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
        for (retry = 0; retry < 4; retry++) {
                ret = radeon_process_aux_ch(auxch,
                                            msg, msg_bytes, reply, reply_bytes, 0, &ack);
-               if (ret < 0) {
+               if (ret == -EBUSY)
+                       continue;
+               else if (ret < 0) {
                        DRM_DEBUG_KMS("aux_ch failed %d\n", ret);
                        return ret;
                }