Hi again, On Fri, Nov 14, 2014 at 09:47:56PM -0600, Felipe Balbi wrote: > > > how ? This is an interesting bug which deserves further explanation. > > > > Look at the loops above, and at the omap_i2c_complete_cmd: > > > > static inline void > > omap_i2c_complete_cmd(struct omap_i2c_dev *dev, u16 err) > > { > > dev->cmd_err |= err; > > complete(&dev->cmd_complete); > > } > > > > You can see, loop will be aborted if counter reached 100. Final state > > of transfer depends on values stored in the 'err' and 'dev->cmd_err'. > > If 'err' and 'dev->cmd_err' are zero, than transfer would be aborted > > with status 0. look at the IRQ handler again: | omap_i2c_isr_thread(int this_irq, void *dev_id) | { | struct omap_i2c_dev *dev = dev_id; | unsigned long flags; | u16 bits; | u16 stat; | int err = 0, count = 0; | | spin_lock_irqsave(&dev->lock, flags); | do { [...] | if (stat & OMAP_I2C_STAT_NACK) { | err |= OMAP_I2C_STAT_NACK; | omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK); | break; | } | | if (stat & OMAP_I2C_STAT_AL) { | dev_err(dev->dev, "Arbitration lost\n"); | err |= OMAP_I2C_STAT_AL; | omap_i2c_ack_stat(dev, OMAP_I2C_STAT_AL); | break; | } [...] | | } while (stat); | | omap_i2c_complete_cmd(dev, err); | | out: | spin_unlock_irqrestore(&dev->lock, flags); | | return IRQ_HANDLED; | } How could I ever call omap_i2c_complete_cmd() with 'err' set as 0 if I had either a NACK or Arbitration Lost ? -- balbi
Attachment:
signature.asc
Description: Digital signature