[Why]
There is no handling for I2C-read-over-AUX when receive reply of
I2C_ACK|AUX_ACK followed by the total number of data bytes Fewer
than LEN + 1

[How]
Refer to DP v2.1: 2.11.7.1.6.3 & 2.11.7.1.6.4, repeat the identical
I2C-read-over-AUX transaction with the updated LEN value equal to
the original LEN value minus the total number of data bytes received
so far.

Fixes: 68ec2a2a2481 ("drm/dp: Use I2C_WRITE_STATUS_UPDATE to drain partial 
I2C_WRITE requests")
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Jani Nikula <jani.nik...@intel.com>
Cc: Mario Limonciello <mario.limoncie...@amd.com>
Cc: Harry Wentland <harry.wentl...@amd.com>
Cc: sta...@vger.kernel.org
Signed-off-by: Wayne Lin <wayne....@amd.com>
---
 drivers/gpu/drm/display/drm_dp_helper.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_dp_helper.c 
b/drivers/gpu/drm/display/drm_dp_helper.c
index 28f0708c3b27..938214a980a9 100644
--- a/drivers/gpu/drm/display/drm_dp_helper.c
+++ b/drivers/gpu/drm/display/drm_dp_helper.c
@@ -1812,10 +1812,11 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, 
struct drm_dp_aux_msg *msg)
                                drm_dbg_kms(aux->drm_dev,
                                            "%s: I2C partially ack (result=%d, 
size=%zu)\n",
                                            aux->name, ret, msg->size);
-                               if (!(msg->request & DP_AUX_I2C_READ)) {
-                                       usleep_range(AUX_RETRY_INTERVAL, 
AUX_RETRY_INTERVAL + 100);
+                               usleep_range(AUX_RETRY_INTERVAL, 
AUX_RETRY_INTERVAL + 100);
+                               if (msg->request & DP_AUX_I2C_READ)
+                                       msg->size -= ret;
+                               else
                                        drm_dp_i2c_msg_write_status_update(msg);
-                               }
 
                                continue;
                        }
-- 
2.43.0

Reply via email to