> Sonasath, Moiz wrote:
> > When an XRDY/XDR is hit, wait for XUDF before writing data to DATA_REG.
> > Otherwise some data bytes can be lost while transferring them from the
> > memory to the I2C interface.
> >
> > Do a Busy-wait for XUDF, before writing data to DATA_REG. While waiting
> > if there is NACK | AL, set the appropriate error flags, ack the pending
> > interrupts and return from the ISR.
> >
> > Signed-off-by: Moiz Sonasath<[email protected]>
> > Signed-off-by: Vikram Pandita<[email protected]>
> > ---
> >  drivers/i2c/busses/i2c-omap.c |   24 +++++++++++++++++++++++-
> >  1 files changed, 23 insertions(+), 1 deletions(-)
> >
> > diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-
> omap.c
> > index 05b5e4c..8deaf87 100644
> > --- a/drivers/i2c/busses/i2c-omap.c
> > +++ b/drivers/i2c/busses/i2c-omap.c
> > @@ -672,9 +672,10 @@ omap_i2c_isr(int this_irq, void *dev_id)
> >                     break;
> >             }
> >
> > +           err = 0;
> > +complete:
> cant we rename this label?
> [Moiz]
> This path actually completes the IRQ service routine and therefore the
> name.
> 
> >             omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, stat);
> >
> > -           err = 0;
> >             if (stat & OMAP_I2C_STAT_NACK) {
> >                     err |= OMAP_I2C_STAT_NACK;
> >                     omap_i2c_write_reg(dev, OMAP_I2C_CON_REG,
> > @@ -764,6 +765,27 @@ omap_i2c_isr(int this_irq, void *dev_id)
> >                                                     "data to send\n");
> >                                     break;
> >                             }
> > +
> > +                           /*
> > +                            * OMAP3430 Errata 1.153: When an XRDY/XDR
> > +                            * is hit, wait for XUDF before writing data
> > +                            * to DATA_REG. Otherwise some data bytes can
> > +                            * be lost while transferring them from the
> > +                            * memory to the I2C interface.
> > +                            */
> > +
> > +                           if (cpu_is_omap34xx()) {
> > +                                           while (!(stat & 
> > OMAP_I2C_STAT_XUDF)) {
> > +                                                   if (stat & 
> > (OMAP_I2C_STAT_NACK |
> OMAP_I2C_STAT_AL)) {
> > +                                                           
> > omap_i2c_ack_stat(dev,
> stat & (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR));
> generic comment - code nesting is getting overwhelming - we may like to
> refactor the isr function at a later date I think..
> > +                                                           err |= 
> > OMAP_I2C_STAT_XUDF;
> why set the err if we wantedly force this to happen?
> [Moiz]
> The idea here is to let the upper application to know that something went
> wrong while waiting for the XUDF bit to be set. This is just for debugging
> purpose.
> > +                                                           goto complete;
> 
> > +                                                   }
> > +                                                   cpu_relax();
> > +                                                   stat = 
> > omap_i2c_read_reg(dev,
> OMAP_I2C_STAT_REG);
> > +                                           }
> this is an infinite while loop + it tries to handle error cases -
> essentially do another isr routine inside itself.
> [Moiz]
> Yes, it is a busy wait loop. But AFAIK while we come to this part of the
> code the only thing that can go wrong in the transfer is either the device
> would go off suddenly (creating a NACK) or there is an arbitration
> lost(AL). This loop takes care of these two error conditions. Apart from
> these, if the hardware is functional, the XUDF bit should be set as soon
> as the FIFO gets empty.
> 
> Correct me if I am missing something.

As of now I am posting my patch without a timeout, later as per the need I will 
optimize it with a timeout approach.

> 
> How about:
> Apply [1] and the following?
> diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
> index ad8d201..e3f21af 100644
> --- a/drivers/i2c/busses/i2c-omap.c
> +++ b/drivers/i2c/busses/i2c-omap.c
> @@ -728,6 +728,12 @@ omap_i2c_isr(int this_irq, void *dev_id)
>                  }
>                  if (stat & (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)) {
>                          u8 num_bytes = 1;
> +                       if (cpu_is_omap34xx() &&
> +                               !(stat & OMAP_I2C_STAT_XUDF)){
> +                               cpu_relax();
> +                               continue;
> +                       }
> +
>                          if (dev->fifo_size) {
>                                  if (stat & OMAP_I2C_STAT_XRDY)
>                                          num_bytes = dev->fifo_size;
> 
> 
> Regards,
> Nishanth Menon
> Ref:
> [1] http://patchwork.kernel.org/patch/32332/
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to [email protected]
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to