lkml.org 
[lkml]   [2020]   [Nov]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.9 214/391] w1: mxc_w1: Fix timeout resolution problem leading to bus error
    Date
    From: Martin Fuzzey <martin.fuzzey@flowbird.group>

    commit c9723750a699c3bd465493ac2be8992b72ccb105 upstream.

    On my platform (i.MX53) bus access sometimes fails with
    w1_search: max_slave_count 64 reached, will continue next search.

    The reason is the use of jiffies to implement a 200us timeout in
    mxc_w1_ds2_touch_bit().
    On some platforms the jiffies timer resolution is insufficient for this.

    Fix by replacing jiffies by ktime_get().

    For consistency apply the same change to the other use of jiffies in
    mxc_w1_ds2_reset_bus().

    Fixes: f80b2581a706 ("w1: mxc_w1: Optimize mxc_w1_ds2_touch_bit()")
    Cc: stable <stable@vger.kernel.org>
    Signed-off-by: Martin Fuzzey <martin.fuzzey@flowbird.group>
    Link: https://lore.kernel.org/r/1601455030-6607-1-git-send-email-martin.fuzzey@flowbird.group
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/w1/masters/mxc_w1.c | 14 +++++++-------
    1 file changed, 7 insertions(+), 7 deletions(-)

    --- a/drivers/w1/masters/mxc_w1.c
    +++ b/drivers/w1/masters/mxc_w1.c
    @@ -7,7 +7,7 @@
    #include <linux/clk.h>
    #include <linux/delay.h>
    #include <linux/io.h>
    -#include <linux/jiffies.h>
    +#include <linux/ktime.h>
    #include <linux/module.h>
    #include <linux/mod_devicetable.h>
    #include <linux/platform_device.h>
    @@ -40,12 +40,12 @@ struct mxc_w1_device {
    static u8 mxc_w1_ds2_reset_bus(void *data)
    {
    struct mxc_w1_device *dev = data;
    - unsigned long timeout;
    + ktime_t timeout;

    writeb(MXC_W1_CONTROL_RPP, dev->regs + MXC_W1_CONTROL);

    /* Wait for reset sequence 511+512us, use 1500us for sure */
    - timeout = jiffies + usecs_to_jiffies(1500);
    + timeout = ktime_add_us(ktime_get(), 1500);

    udelay(511 + 512);

    @@ -55,7 +55,7 @@ static u8 mxc_w1_ds2_reset_bus(void *dat
    /* PST bit is valid after the RPP bit is self-cleared */
    if (!(ctrl & MXC_W1_CONTROL_RPP))
    return !(ctrl & MXC_W1_CONTROL_PST);
    - } while (time_is_after_jiffies(timeout));
    + } while (ktime_before(ktime_get(), timeout));

    return 1;
    }
    @@ -68,12 +68,12 @@ static u8 mxc_w1_ds2_reset_bus(void *dat
    static u8 mxc_w1_ds2_touch_bit(void *data, u8 bit)
    {
    struct mxc_w1_device *dev = data;
    - unsigned long timeout;
    + ktime_t timeout;

    writeb(MXC_W1_CONTROL_WR(bit), dev->regs + MXC_W1_CONTROL);

    /* Wait for read/write bit (60us, Max 120us), use 200us for sure */
    - timeout = jiffies + usecs_to_jiffies(200);
    + timeout = ktime_add_us(ktime_get(), 200);

    udelay(60);

    @@ -83,7 +83,7 @@ static u8 mxc_w1_ds2_touch_bit(void *dat
    /* RDST bit is valid after the WR1/RD bit is self-cleared */
    if (!(ctrl & MXC_W1_CONTROL_WR(bit)))
    return !!(ctrl & MXC_W1_CONTROL_RDST);
    - } while (time_is_after_jiffies(timeout));
    + } while (ktime_before(ktime_get(), timeout));

    return 0;
    }

    \
     
     \ /
      Last update: 2020-11-03 22:54    [W:4.043 / U:0.216 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site