This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Linux/PROCESSOR-SDK-AM335X: am335x I2C omap_i2c_prepare_recovery() function lock entire system

Part Number: PROCESSOR-SDK-AM335X

Tool/software: Linux

Could you pull this patch into your linux branch?

 

Without this an error on I2C bus can lock entire system in omap_i2c_prepare_recovery() function. You can reproduce the issue by pulling low SDA line using wire longer than 2x timeouts, it simulates an slave device left without clock while driving low ACK signal. AM335x is affected by other processors might be also.

  • Peter,,
    Thanks for sending it to us, I will let our SW team reply. Please note that due the holidays, our response may be delayed. We appreciate the path sent.
  • Actually previous solution has still problem when bus recovery happens in receive mode - unserviced TX interrupt spams all the time effectively locking system. Here is my patch which works for me.

    Date: Mon, 31 Dec 2018 18:25:58 -0600 Subject: [PATCH] i2c-omap.c: Fix recovery from SDA low level. When recovery enters I2C test mode in omap_i2c_prepare_recovery() I2C module generates spurious interrupts which lock entire system. Solution is to clear the RX interrupt flag and service TX interrupt. --- drivers/i2c/busses/i2c-omap.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index b9172f0..bfb47c5 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -1044,6 +1044,7 @@ omap_i2c_isr_thread(int this_irq, void *dev_id) struct omap_i2c_dev *omap = dev_id; u16 bits; u16 stat; + u16 buf; int err = 0, count = 0; do { @@ -1051,11 +1052,21 @@ omap_i2c_isr_thread(int this_irq, void *dev_id) stat = omap_i2c_read_reg(omap, OMAP_I2C_STAT_REG); stat &= bits; - /* If we're in receiver mode, ignore XDR/XRDY */ - if (omap->receiver) - stat &= ~(OMAP_I2C_STAT_XDR | OMAP_I2C_STAT_XRDY); - else + /* + * If we're in receiver mode, service OMAP_I2C_STAT_XDR/OMAP_I2C_STAT_XRDY. + * In transmitter mode ignore OMAP_I2C_STAT_RDR/OMAP_I2C_STAT_RRDY. + */ + if (omap->receiver && stat & (OMAP_I2C_STAT_XDR | OMAP_I2C_STAT_XRDY)) { + /*Print error but still service the interrupt otherwise when it happens in bus recovery I2C spams this interrupt*/ + dev_err_ratelimited(omap->dev, "TX interrupt in receive mode probably due to bus recovery\n"); + } else if (!omap->receiver && stat & (OMAP_I2C_STAT_RDR | OMAP_I2C_STAT_RRDY)) { + dev_err_ratelimited(omap->dev, "ignoring RX interrupt in transmit mode\n"); stat &= ~(OMAP_I2C_STAT_RDR | OMAP_I2C_STAT_RRDY); + buf = omap_i2c_read_reg(omap, OMAP_I2C_BUF_REG); + buf |= OMAP_I2C_BUF_RXFIF_CLR; + omap_i2c_write_reg(omap, OMAP_I2C_BUF_REG, buf); + omap_i2c_ack_stat(omap, OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR); + } if (!stat) { /* my work here is done */ -- 2.7.4

    PS

    I couldn't attach patch file.

  • Peter I edit and removed your email and company name to keep your privacy.
    Thanks. Linux team will post their comments here later.
  • Peter,

    Thanks for sharing your solution. Let me discuss this with the developers and get their recommendation on how best to proceed.

    Thanks.
  • Peter,

    I've logged this as a bug in our database and provided your inputs. It will take some time for us to come up with a solution and it will likely be in a future Processors SDK release. I'm going to go ahead and mark this thread as closed for now. Thanks again for sharing your solution.

  • Peter,

    I've discussed further with the development team and they directed me to the v2 version of the patch here:

    www.spinics.net/.../msg139376.html

    This patch was accepted into the 2018 LTS, v4.14 was based on. Our current series of Processors SDKs, v5.x, is based on that kernel version and should have the patches.

    What Kernel version are you on?

    Thank for your continued feedback and helping us drive this to final resolution.
  • I'm using 4.14.67 and I do have this patch but still when SDA is held low (by misbehaving device or physical short e.g by skewed wire) for more than 2x OMAP_I2C_TIMEOUT system locks.

  • Peter, thanks for getting back to us. I will continue to work with the development team.