lkml.org 
[lkml]   [2018]   [Jul]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.9 23/32] i2c: tegra: Fix NACK error handling
    Date
    4.9-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Jon Hunter <jonathanh@nvidia.com>

    commit 54836e2d03e76d80aec3399368ffaf5b7caadd1b upstream.

    On Tegra30 Cardhu the PCA9546 I2C mux is not ACK'ing I2C commands on
    resume from suspend (which is caused by the reset signal for the I2C
    mux not being configured correctl). However, this NACK is causing the
    Tegra30 to hang on resuming from suspend which is not expected as we
    detect NACKs and handle them. The hang observed appears to occur when
    resetting the I2C controller to recover from the NACK.

    Commit 77821b4678f9 ("i2c: tegra: proper handling of error cases") added
    additional error handling for some error cases including NACK, however,
    it appears that this change conflicts with an early fix by commit
    f70893d08338 ("i2c: tegra: Add delay before resetting the controller
    after NACK"). After commit 77821b4678f9 was made we now disable 'packet
    mode' before the delay from commit f70893d08338 happens. Testing shows
    that moving the delay to before disabling 'packet mode' fixes the hang
    observed on Tegra30. The delay was added to give the I2C controller
    chance to send a stop condition and so it makes sense to move this to
    before we disable packet mode. Please note that packet mode is always
    enabled for Tegra.

    Fixes: 77821b4678f9 ("i2c: tegra: proper handling of error cases")
    Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
    Acked-by: Thierry Reding <treding@nvidia.com>
    Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
    Cc: stable@vger.kernel.org
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/i2c/busses/i2c-tegra.c | 17 ++++++++---------
    1 file changed, 8 insertions(+), 9 deletions(-)

    --- a/drivers/i2c/busses/i2c-tegra.c
    +++ b/drivers/i2c/busses/i2c-tegra.c
    @@ -547,6 +547,14 @@ static int tegra_i2c_disable_packet_mode
    {
    u32 cnfg;

    + /*
    + * NACK interrupt is generated before the I2C controller generates
    + * the STOP condition on the bus. So wait for 2 clock periods
    + * before disabling the controller so that the STOP condition has
    + * been delivered properly.
    + */
    + udelay(DIV_ROUND_UP(2 * 1000000, i2c_dev->bus_clk_rate));
    +
    cnfg = i2c_readl(i2c_dev, I2C_CNFG);
    if (cnfg & I2C_CNFG_PACKET_MODE_EN)
    i2c_writel(i2c_dev, cnfg & ~I2C_CNFG_PACKET_MODE_EN, I2C_CNFG);
    @@ -708,15 +716,6 @@ static int tegra_i2c_xfer_msg(struct teg
    if (likely(i2c_dev->msg_err == I2C_ERR_NONE))
    return 0;

    - /*
    - * NACK interrupt is generated before the I2C controller generates
    - * the STOP condition on the bus. So wait for 2 clock periods
    - * before resetting the controller so that the STOP condition has
    - * been delivered properly.
    - */
    - if (i2c_dev->msg_err == I2C_ERR_NO_ACK)
    - udelay(DIV_ROUND_UP(2 * 1000000, i2c_dev->bus_clk_rate));
    -
    tegra_i2c_init(i2c_dev);
    if (i2c_dev->msg_err == I2C_ERR_NO_ACK) {
    if (msg->flags & I2C_M_IGNORE_NAK)

    \
     
     \ /
      Last update: 2018-07-16 09:51    [W:4.069 / U:0.108 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site