diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c index cfd1e63359e7..d5e6e2eca3b3 100644 --- a/drivers/i2c/busses/i2c-imx.c +++ b/drivers/i2c/busses/i2c-imx.c @@ -1061,11 +1061,28 @@ static inline enum imx_i2c_state i2c_imx_isr_read_continue(struct imx_i2c_struct static inline void i2c_imx_isr_read_block_data_len(struct imx_i2c_struct *i2c_imx) { u8 len = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2DR); + unsigned int temp; if (len == 0 || len > I2C_SMBUS_BLOCK_MAX) { + /* + * SMBus 3.1 6.5.7: support count byte of 0. + * I2C_SMBUS_BLOCK_MAX case should not hold the SDA either. + * So NACK it (TXAK) to not hold the bus. + */ + temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR); + temp |= I2CR_TXAK; + imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR); + + if (len == 0) { + i2c_imx->msg->buf[i2c_imx->msg_buf_idx++] = 0; + i2c_imx->msg->len = 2; + return; + } + i2c_imx->isr_result = -EPROTO; i2c_imx->state = IMX_I2C_STATE_FAILED; wake_up(&i2c_imx->queue); + return; } i2c_imx->msg->len += len; i2c_imx->msg->buf[i2c_imx->msg_buf_idx++] = len;