On Tue, Apr 13, 2021 at 8:10 AM Chris Packham <chris.pack...@alliedtelesis.co.nz> wrote: > > The fsl-i2c controller will generate an interrupt after every byte > transferred. Make use of this interrupt to drive a state machine which > allows the next part of a transfer to happen as soon as the interrupt is > received. This is particularly helpful with SMBUS devices like the LM81 > which will timeout if we take too long between bytes in a transfer.
Also see my other comments below. ... > +// SPDX-License-Identifier: GPL-2.0 I think it is better to split this with a removal of old stuff and updating a copyright notice and go as a last one in the series. ... > +static char *action_str[] = { static const char * const action_str[] > + "invalid", > + "start", > + "restart", > + "read begin", > + "read", > + "write", > + "stop", > +}; ... > + dev_dbg(i2c->dev, "%s: action = %s\n", __func__, > + action_str[i2c->action]); Drop useless __func__. With Dynamic Debug enabled it can be turned on and off at run time. ... > + /* Generate txack on next to last byte */ Tx ACK ? Ditto for other comments. ... > + dev_dbg(i2c->dev, "%s: %s %02x\n", __func__, > + action_str[i2c->action], byte); You already printed action. Anything changed? > + dev_dbg(i2c->dev, "%s: %s %02x\n", __func__, > + action_str[i2c->action], msg->buf[i2c->byte_posn]); Deduplicate this. Perhaps at the end of switch-case print once with whatever temporary variable value you want to. ... > + case MPC_I2C_ACTION_INVALID: > + default: Does the first one deserve loud WARN? Otherwise, why is it defined at all? > + WARN(1, "Unexpected action %d\n", i2c->action); > + break; ... > +static void mpc_i2c_do_intr(struct mpc_i2c *i2c, u8 status) > { > + spin_lock_irqsave(&i2c->lock, flags); Why _irqsave? ... > + dev_dbg(i2c->dev, "arbiritration lost\n"); arbitration ... > + if (i2c->expect_rxack && (status & CSR_RXAK)) { > + dev_dbg(i2c->dev, "no RXAK\n"); You see, you have to be consistent in comments and messages. Either use TXAK/RXAK, or more verbose 'Tx ACK/Rx ACK' everywhere. ... > +out: out_unlock: > + spin_unlock_irqrestore(&i2c->lock, flags); ... > +static irqreturn_t mpc_i2c_isr(int irq, void *dev_id) > +{ > + struct mpc_i2c *i2c = dev_id; > + u8 status = readb(i2c->base + MPC_I2C_SR); I would split this assignment, so it will be closer to its user. > + if (status & CSR_MIF) { > + writeb(0, i2c->base + MPC_I2C_SR); > + mpc_i2c_do_intr(i2c, status); > + return IRQ_HANDLED; > } > + return IRQ_NONE; > +} ... > + time_left = wait_event_timeout(i2c->waitq, !i2c->block, > i2c->adap.timeout); > + No need for a blank line here. > + if (!time_left) > + i2c->rc = -ETIMEDOUT; > + else if (time_left < 0) Redundant 'else' > + i2c->rc = time_left; Can't you return an error code from here, rather than injecting it somewhere where it doesn't belong to? > } -- With Best Regards, Andy Shevchenko