I thought all of the comments made sense and will be addressed in my next revision, except the following: >> +static int aspeed_i2c_recover_bus(struct aspeed_i2c_bus *bus) >> +{ >> + unsigned long time_left, flags; >> + int ret = 0; >> + u32 command; >> + >> + spin_lock_irqsave(&bus->lock, flags); >> + command = readl(bus->base + ASPEED_I2C_CMD_REG); >> + >> + if (command & ASPEED_I2CD_SDA_LINE_STS) { >> + /* Bus is idle: no recovery needed. */ >> + if (command & ASPEED_I2CD_SCL_LINE_STS) >> + goto out; >> + dev_dbg(bus->dev, "bus hung (state %x), attempting recovery\n", >> + command); >> + >> + reinit_completion(&bus->cmd_complete); >> + writel(ASPEED_I2CD_M_STOP_CMD, bus->base + ASPEED_I2C_CMD_REG); >> + spin_unlock_irqrestore(&bus->lock, flags); >> + >> + time_left = wait_for_completion_timeout( >> + &bus->cmd_complete, bus->adap.timeout); >> + >> + spin_lock_irqsave(&bus->lock, flags); >> + if (time_left == 0) >> + goto reset_out; >> + else if (bus->cmd_err) >> + goto reset_out; >> + /* Recovery failed. */ >> + else if (!(readl(bus->base + ASPEED_I2C_CMD_REG) & >> + ASPEED_I2CD_SCL_LINE_STS)) >> + goto reset_out; >> + /* Bus error. */ >> + } else { >> + dev_dbg(bus->dev, "bus hung (state %x), attempting recovery\n", >> + command); > > Same dbg message as in the condition? Move it out of the 'if'? Message is the same; that's true; however, I only want to print this if I am actually doing the recovery. There is a case in the first condition where we actually don't attempt recovery. (See both SDA and SCL high). Nevertheless, now that I am looking at this. I think it might make sense to make the dbg statements different since I can explain what type of recovery I am attempting. > >> + >> + reinit_completion(&bus->cmd_complete); >> + writel(ASPEED_I2CD_BUS_RECOVER_CMD, >> + bus->base + ASPEED_I2C_CMD_REG); > > Out of interest: What does the RECOVER_CMD do? According to the documentation, it attempts to create 1 to 8 SCL cycles to force any stuck device to let go of the SDA line. It then puts the hardware in a sane state once it detects that the bus has been recovered. I will put a comment to this effect. > >> + spin_unlock_irqrestore(&bus->lock, flags); >> + >> + time_left = wait_for_completion_timeout( >> + &bus->cmd_complete, bus->adap.timeout); >> + >> + spin_lock_irqsave(&bus->lock, flags); >> + if (time_left == 0) >> + goto reset_out; >> + else if (bus->cmd_err) >> + goto reset_out; >> + /* Recovery failed. */ >> + else if (!(readl(bus->base + ASPEED_I2C_CMD_REG) & >> + ASPEED_I2CD_SDA_LINE_STS)) >> + goto reset_out; >> + } >> + >> +out: >> + spin_unlock_irqrestore(&bus->lock, flags); >> + >> + return ret; >> + >> +reset_out: >> + spin_unlock_irqrestore(&bus->lock, flags); >> + >> + return aspeed_i2c_reset(bus); >> +} Cheers! -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html