aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/bcm27xx/patches-4.19/950-0610-i2c-bcm2835-Set-clock-stretch-timeout-to-35ms.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/bcm27xx/patches-4.19/950-0610-i2c-bcm2835-Set-clock-stretch-timeout-to-35ms.patch')
-rw-r--r--target/linux/bcm27xx/patches-4.19/950-0610-i2c-bcm2835-Set-clock-stretch-timeout-to-35ms.patch47
1 files changed, 47 insertions, 0 deletions
diff --git a/target/linux/bcm27xx/patches-4.19/950-0610-i2c-bcm2835-Set-clock-stretch-timeout-to-35ms.patch b/target/linux/bcm27xx/patches-4.19/950-0610-i2c-bcm2835-Set-clock-stretch-timeout-to-35ms.patch
new file mode 100644
index 0000000000..280cddf9f2
--- /dev/null
+++ b/target/linux/bcm27xx/patches-4.19/950-0610-i2c-bcm2835-Set-clock-stretch-timeout-to-35ms.patch
@@ -0,0 +1,47 @@
+From 8d453e2193951057db696e37b9c10e7e35c18cb0 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Fri, 12 Jul 2019 15:38:35 +0100
+Subject: [PATCH] i2c: bcm2835: Set clock-stretch timeout to 35ms
+
+The BCM2835 I2C blocks have a register to set the clock-stretch
+timeout - how long the device is allowed to hold SCL low - in bus
+cycles. The current driver doesn't write to the register, therefore
+the default value of 64 cycles is being used for all devices.
+
+Set the timeout to the value recommended for SMBus - 35ms.
+
+See: https://github.com/raspberrypi/linux/issues/3064
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+---
+ drivers/i2c/busses/i2c-bcm2835.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/drivers/i2c/busses/i2c-bcm2835.c
++++ b/drivers/i2c/busses/i2c-bcm2835.c
+@@ -194,6 +194,7 @@ static int clk_bcm2835_i2c_set_rate(stru
+ {
+ struct clk_bcm2835_i2c *div = to_clk_bcm2835_i2c(hw);
+ u32 redl, fedl;
++ u32 clk_tout;
+ u32 divider = clk_bcm2835_i2c_calc_divider(rate, parent_rate);
+
+ if (divider == -EINVAL)
+@@ -217,6 +218,17 @@ static int clk_bcm2835_i2c_set_rate(stru
+ bcm2835_i2c_writel(div->i2c_dev, BCM2835_I2C_DEL,
+ (fedl << BCM2835_I2C_FEDL_SHIFT) |
+ (redl << BCM2835_I2C_REDL_SHIFT));
++
++ /*
++ * Set the clock stretch timeout to the SMBUs-recommended 35ms.
++ */
++ if (rate > 0xffff*1000/35)
++ clk_tout = 0xffff;
++ else
++ clk_tout = 35*rate/1000;
++
++ bcm2835_i2c_writel(div->i2c_dev, BCM2835_I2C_CLKT, clk_tout);
++
+ return 0;
+ }
+