| From 4301d892633b6fdef42e68f6c19ab397650ab29c Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Fri, 23 Feb 2018 22:42:31 +0100 |
| Subject: i2c: bcm2835: Avoid clock stretching timeouts |
| |
| From: Eric Anholt <eric@anholt.net> |
| |
| [ Upstream commit 9495b9b31abe525ebd93da58de2c88b9f66d3a0e ] |
| |
| The CLKT register contains at poweron 0x40, which at our typical 100kHz |
| bus rate means .64ms. But there is no specified limit to how long devices |
| should be able to stretch the clocks, so just disable the timeout. We |
| still have a timeout wrapping the entire transfer. |
| |
| Signed-off-by: Eric Anholt <eric@anholt.net> |
| Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com> |
| BugLink: https://github.com/raspberrypi/linux/issues/3064 |
| Signed-off-by: Wolfram Sang <wsa@kernel.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/i2c/busses/i2c-bcm2835.c | 11 +++++++++++ |
| 1 file changed, 11 insertions(+) |
| |
| diff --git a/drivers/i2c/busses/i2c-bcm2835.c b/drivers/i2c/busses/i2c-bcm2835.c |
| index 5ab901ad615dd..c265fe4621621 100644 |
| --- a/drivers/i2c/busses/i2c-bcm2835.c |
| +++ b/drivers/i2c/busses/i2c-bcm2835.c |
| @@ -23,6 +23,11 @@ |
| #define BCM2835_I2C_FIFO 0x10 |
| #define BCM2835_I2C_DIV 0x14 |
| #define BCM2835_I2C_DEL 0x18 |
| +/* |
| + * 16-bit field for the number of SCL cycles to wait after rising SCL |
| + * before deciding the slave is not responding. 0 disables the |
| + * timeout detection. |
| + */ |
| #define BCM2835_I2C_CLKT 0x1c |
| |
| #define BCM2835_I2C_C_READ BIT(0) |
| @@ -479,6 +484,12 @@ static int bcm2835_i2c_probe(struct platform_device *pdev) |
| adap->dev.of_node = pdev->dev.of_node; |
| adap->quirks = of_device_get_match_data(&pdev->dev); |
| |
| + /* |
| + * Disable the hardware clock stretching timeout. SMBUS |
| + * specifies a limit for how long the device can stretch the |
| + * clock, but core I2C doesn't. |
| + */ |
| + bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_CLKT, 0); |
| bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, 0); |
| |
| ret = i2c_add_adapter(adap); |
| -- |
| 2.34.1 |
| |