Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

w1: mxc_w1: Fix timeout resolution problem leading to bus error

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>

authored by

Martin Fuzzey and committed by
Greg Kroah-Hartman
c9723750 e84d3896

+7 -7
+7 -7
drivers/w1/masters/mxc_w1.c
··· 7 7 #include <linux/clk.h> 8 8 #include <linux/delay.h> 9 9 #include <linux/io.h> 10 - #include <linux/jiffies.h> 10 + #include <linux/ktime.h> 11 11 #include <linux/module.h> 12 12 #include <linux/mod_devicetable.h> 13 13 #include <linux/platform_device.h> ··· 40 40 static u8 mxc_w1_ds2_reset_bus(void *data) 41 41 { 42 42 struct mxc_w1_device *dev = data; 43 - unsigned long timeout; 43 + ktime_t timeout; 44 44 45 45 writeb(MXC_W1_CONTROL_RPP, dev->regs + MXC_W1_CONTROL); 46 46 47 47 /* Wait for reset sequence 511+512us, use 1500us for sure */ 48 - timeout = jiffies + usecs_to_jiffies(1500); 48 + timeout = ktime_add_us(ktime_get(), 1500); 49 49 50 50 udelay(511 + 512); 51 51 ··· 55 55 /* PST bit is valid after the RPP bit is self-cleared */ 56 56 if (!(ctrl & MXC_W1_CONTROL_RPP)) 57 57 return !(ctrl & MXC_W1_CONTROL_PST); 58 - } while (time_is_after_jiffies(timeout)); 58 + } while (ktime_before(ktime_get(), timeout)); 59 59 60 60 return 1; 61 61 } ··· 68 68 static u8 mxc_w1_ds2_touch_bit(void *data, u8 bit) 69 69 { 70 70 struct mxc_w1_device *dev = data; 71 - unsigned long timeout; 71 + ktime_t timeout; 72 72 73 73 writeb(MXC_W1_CONTROL_WR(bit), dev->regs + MXC_W1_CONTROL); 74 74 75 75 /* Wait for read/write bit (60us, Max 120us), use 200us for sure */ 76 - timeout = jiffies + usecs_to_jiffies(200); 76 + timeout = ktime_add_us(ktime_get(), 200); 77 77 78 78 udelay(60); 79 79 ··· 83 83 /* RDST bit is valid after the WR1/RD bit is self-cleared */ 84 84 if (!(ctrl & MXC_W1_CONTROL_WR(bit))) 85 85 return !!(ctrl & MXC_W1_CONTROL_RDST); 86 - } while (time_is_after_jiffies(timeout)); 86 + } while (ktime_before(ktime_get(), timeout)); 87 87 88 88 return 0; 89 89 }