Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0bfca731 authored by Martin Fuzzey's avatar Martin Fuzzey Committed by Greg Kroah-Hartman
Browse files

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



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: f80b2581 ("w1: mxc_w1: Optimize mxc_w1_ds2_touch_bit()")
Cc: stable <stable@vger.kernel.org>
Signed-off-by: default avatarMartin Fuzzey <martin.fuzzey@flowbird.group>
Link: https://lore.kernel.org/r/1601455030-6607-1-git-send-email-martin.fuzzey@flowbird.group


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 57cbc85d
Loading
Loading
Loading
Loading
+7 −7
Original line number Diff line number Diff line
@@ -15,7 +15,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>
@@ -48,12 +48,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);

@@ -63,7 +63,7 @@ static u8 mxc_w1_ds2_reset_bus(void *data)
		/* 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;
}
@@ -76,12 +76,12 @@ static u8 mxc_w1_ds2_reset_bus(void *data)
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);

@@ -91,7 +91,7 @@ static u8 mxc_w1_ds2_touch_bit(void *data, u8 bit)
		/* 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;
}