On Wed, Sep 11, 2024 at 04:39:45PM +0800, Kimriver Liu wrote: > It was observed that issuing ABORT bit (IC_ENABLE[1]) will not > work when IC_ENABLE is already disabled. > > Check if ENABLE bit (IC_ENABLE[0]) is disabled when the controller > is holding SCL low. If ENABLE bit is disabled, the software need > to enable it before trying to issue ABORT bit. otherwise, > the controller ignores any write to ABORT bit. > > These kernel logs show up whenever an I2C transaction is > attempted after this failure. > i2c_designware e95e0000.i2c: timeout waiting for bus ready > i2c_designware e95e0000.i2c: timeout in disabling adapter > > The patch can be fix the controller cannot be disabled while > SCL is held low in ENABLE bit is already disabled. ... > +/* > + * This functions waits controller idling before disabling I2C > + * When the controller is not in the IDLE state, > + * MST_ACTIVITY bit (IC_STATUS[5]) is set. > + * Values: > + * 0x1 (ACTIVE): Controller not idle > + * 0x0 (IDLE): Controller is idle > + * The function is called after returning the end of the current transfer > + * Returns: > + * Return 0 as controller IDLE > + * Return a negative errno as controller ACTIVE But why non-boolean again? > + */ > +static int i2c_dw_is_controller_active(struct dw_i2c_dev *dev) > +{ > + u32 status; > + > + regmap_read(dev->map, DW_IC_STATUS, &status); > + if (!(status & DW_IC_STATUS_MASTER_ACTIVITY)) > + return 0; > + > + return regmap_read_poll_timeout(dev->map, DW_IC_STATUS, status, > + !(status & DW_IC_STATUS_MASTER_ACTIVITY), > + 1100, 20000); > +} ... > + /* > + * This happens rarely (~1:500) and is hard to reproduce. Debug trace > + * showed that IC_STATUS had value of 0x23 when STOP_DET occurred, > + * if disable IC_ENABLE.ENABLE immediately that can result in > + * IC_RAW_INTR_STAT.MASTER_ON_HOLD holding SCL low. Check if > + * controller is still ACTIVE before disabling I2C. > + */ > + if (i2c_dw_is_controller_active(dev)) > + dev_err(dev->dev, "controller active\n"); No, this is rarely we skip the error code returned. Either you find the meaningful use of the returned error code, or change to boolean. Personally I think the latter is what we need for now. > /* > * We must disable the adapter before returning and signaling the end > * of the current transfer. Otherwise the hardware might continue -- With Best Regards, Andy Shevchenko