Re: [PATCH] drm/gma500: return errors from Oaktrail HDMI I2C reads

From: Patrik Jakobsson

Date: Wed Jul 22 2026 - 17:03:47 EST


On Thu, Jun 25, 2026 at 2:32 AM Pengpeng Hou <pengpeng@xxxxxxxxxxx> wrote:
>
> xfer_read() waits for the HDMI I2C transaction to reach
> I2C_TRANSACTION_DONE, but it ignores both timeout and signal returns from
> wait_for_completion_interruptible_timeout(). If the interrupt never
> advances the transaction state, the loop can wait forever.
>
> Return -ETIMEDOUT when the completion wait expires, propagate interrupted
> waits, and make the I2C master_xfer callback return the first transfer
> error instead of reporting a successful message count.
>
> Signed-off-by: Pengpeng Hou <pengpeng@xxxxxxxxxxx>

Thanks for the patch.

Applied to drm-misc-fixes.

-Patrik

> ---
> drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c | 21 ++++++++++++++++-----
> 1 file changed, 16 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c b/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c
> index 2a7916ca5..a780643f2 100644
> --- a/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c
> +++ b/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c
> @@ -98,6 +98,7 @@ static int xfer_read(struct i2c_adapter *adap, struct i2c_msg *pmsg)
> struct oaktrail_hdmi_dev *hdmi_dev = i2c_get_adapdata(adap);
> struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev;
> u32 temp;
> + int ret;
>
> i2c_dev->status = I2C_STAT_INIT;
> i2c_dev->msg = pmsg;
> @@ -109,9 +110,14 @@ static int xfer_read(struct i2c_adapter *adap, struct i2c_msg *pmsg)
> HDMI_WRITE(HDMI_HI2CHCR, temp);
> HDMI_READ(HDMI_HI2CHCR);
>
> - while (i2c_dev->status != I2C_TRANSACTION_DONE)
> - wait_for_completion_interruptible_timeout(&i2c_dev->complete,
> + while (i2c_dev->status != I2C_TRANSACTION_DONE) {
> + ret = wait_for_completion_interruptible_timeout(&i2c_dev->complete,
> 10 * HZ);
> + if (ret < 0)
> + return ret;
> + if (!ret)
> + return -ETIMEDOUT;
> + }
>
> return 0;
> }
> @@ -130,7 +136,7 @@ static int oaktrail_hdmi_i2c_access(struct i2c_adapter *adap,
> {
> struct oaktrail_hdmi_dev *hdmi_dev = i2c_get_adapdata(adap);
> struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev;
> - int i;
> + int i, ret = 0;
>
> mutex_lock(&i2c_dev->i2c_lock);
>
> @@ -142,9 +148,11 @@ static int oaktrail_hdmi_i2c_access(struct i2c_adapter *adap,
> for (i = 0; i < num; i++) {
> if (pmsg->len && pmsg->buf) {
> if (pmsg->flags & I2C_M_RD)
> - xfer_read(adap, pmsg);
> + ret = xfer_read(adap, pmsg);
> else
> - xfer_write(adap, pmsg);
> + ret = xfer_write(adap, pmsg);
> + if (ret)
> + break;
> }
> pmsg++; /* next message */
> }
> @@ -154,6 +162,9 @@ static int oaktrail_hdmi_i2c_access(struct i2c_adapter *adap,
>
> mutex_unlock(&i2c_dev->i2c_lock);
>
> + if (ret)
> + return ret;
> +
> return i;
> }
>
> --
> 2.50.1 (Apple Git-155)
>