diff --git a/drivers/i2c/i2c-slave-testunit.c b/drivers/i2c/i2c-slave-testunit.c index 23a11e4e9256..61f3f25de372 100644 --- a/drivers/i2c/i2c-slave-testunit.c +++ b/drivers/i2c/i2c-slave-testunit.c @@ -33,6 +33,7 @@ enum testunit_regs { enum testunit_flags { TU_FLAG_IN_PROCESS, + TU_FLAG_NACK, }; struct testunit_data { @@ -95,8 +96,10 @@ static int i2c_slave_testunit_slave_cb(struct i2c_client *client, switch (event) { case I2C_SLAVE_WRITE_RECEIVED: - if (test_bit(TU_FLAG_IN_PROCESS, &tu->flags)) - return -EBUSY; + if (test_bit(TU_FLAG_IN_PROCESS | TU_FLAG_NACK, &tu->flags)) { + ret = -EBUSY; + break; + } if (tu->reg_idx < TU_NUM_REGS) tu->regs[tu->reg_idx] = *val; @@ -125,11 +128,15 @@ static int i2c_slave_testunit_slave_cb(struct i2c_client *client, * here because we still need them in the workqueue! */ tu->reg_idx = 0; + + clear_bit(TU_FLAG_NACK, &tu->flags); break; case I2C_SLAVE_WRITE_REQUESTED: - if (test_bit(TU_FLAG_IN_PROCESS, &tu->flags)) - return -EBUSY; + if (test_bit(TU_FLAG_IN_PROCESS | TU_FLAG_NACK, &tu->flags)) { + ret = -EBUSY; + break; + } memset(tu->regs, 0, TU_NUM_REGS); tu->reg_idx = 0; @@ -145,6 +152,10 @@ static int i2c_slave_testunit_slave_cb(struct i2c_client *client, break; } + /* If an error occurred somewhen, we NACK everything until next STOP */ + if (ret) + set_bit(TU_FLAG_NACK, &tu->flags); + return ret; }