diff options
Diffstat (limited to 'patches/1625-i2c-recovery-add-get_bus_free-callback.patch')
-rw-r--r-- | patches/1625-i2c-recovery-add-get_bus_free-callback.patch | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/patches/1625-i2c-recovery-add-get_bus_free-callback.patch b/patches/1625-i2c-recovery-add-get_bus_free-callback.patch new file mode 100644 index 00000000000000..4cb4110e22df2c --- /dev/null +++ b/patches/1625-i2c-recovery-add-get_bus_free-callback.patch @@ -0,0 +1,100 @@ +From 4dbf3c9b62c97f070a17ee45c6006ebf79747979 Mon Sep 17 00:00:00 2001 +From: Wolfram Sang <wsa+renesas@sang-engineering.com> +Date: Wed, 11 Jul 2018 00:24:22 +0200 +Subject: [PATCH 1625/1795] i2c: recovery: add get_bus_free callback + +Some IP cores have an internal 'bus free' logic which may be more +advanced than just checking if SDA is high. Add a separate callback to +get this status. Filling it is optional. + +Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com> +Signed-off-by: Wolfram Sang <wsa@the-dreams.de> +(cherry picked from commit 7ca5f6be7900ca753ed01c0202dc5f998a41f4ee) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> +--- + drivers/i2c/i2c-core-base.c | 27 +++++++++++++++++++++++---- + include/linux/i2c.h | 3 +++ + 2 files changed, 26 insertions(+), 4 deletions(-) + +diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c +index 7f768c99464f..e48dae0dea7d 100644 +--- a/drivers/i2c/i2c-core-base.c ++++ b/drivers/i2c/i2c-core-base.c +@@ -192,6 +192,22 @@ static void set_sda_gpio_value(struct i2c_adapter *adap, int val) + gpiod_set_value_cansleep(adap->bus_recovery_info->sda_gpiod, val); + } + ++static int i2c_generic_bus_free(struct i2c_adapter *adap) ++{ ++ struct i2c_bus_recovery_info *bri = adap->bus_recovery_info; ++ int ret = -EOPNOTSUPP; ++ ++ if (bri->get_bus_free) ++ ret = bri->get_bus_free(adap); ++ else if (bri->get_sda) ++ ret = bri->get_sda(adap); ++ ++ if (ret < 0) ++ return ret; ++ ++ return ret ? 0 : -EBUSY; ++} ++ + /* + * We are generating clock pulses. ndelay() determines durating of clk pulses. + * We will generate clock with rate 100 KHz and so duration of both clock levels +@@ -203,7 +219,7 @@ static void set_sda_gpio_value(struct i2c_adapter *adap, int val) + static int i2c_generic_recovery(struct i2c_adapter *adap) + { + struct i2c_bus_recovery_info *bri = adap->bus_recovery_info; +- int i = 0, val = 1, ret = 0; ++ int i = 0, val = 1, ret; + + if (bri->prepare_recovery) + bri->prepare_recovery(adap); +@@ -241,14 +257,17 @@ static int i2c_generic_recovery(struct i2c_adapter *adap) + bri->set_sda(adap, val); + ndelay(RECOVERY_NDELAY / 2); + +- /* Break if SDA is high */ +- if (val && bri->get_sda) { +- ret = bri->get_sda(adap) ? 0 : -EBUSY; ++ if (val) { ++ ret = i2c_generic_bus_free(adap); + if (ret == 0) + break; + } + } + ++ /* If we can't check bus status, assume recovery worked */ ++ if (ret == -EOPNOTSUPP) ++ ret = 0; ++ + if (bri->unprepare_recovery) + bri->unprepare_recovery(adap); + +diff --git a/include/linux/i2c.h b/include/linux/i2c.h +index 6bc0ddb850c8..c3387435e55f 100644 +--- a/include/linux/i2c.h ++++ b/include/linux/i2c.h +@@ -494,6 +494,8 @@ struct i2c_timings { + * @set_sda: This sets/clears the SDA line. This or get_sda() is mandatory for + * generic SCL recovery. Populated internally, if sda_gpio is a valid GPIO, + * for generic GPIO recovery. ++ * @get_bus_free: Returns the bus free state as seen from the IP core in case it ++ * has a more complex internal logic than just reading SDA. Optional. + * @prepare_recovery: This will be called before starting recovery. Platform may + * configure padmux here for SDA/SCL line or something else they want. + * @unprepare_recovery: This will be called after completing recovery. Platform +@@ -510,6 +512,7 @@ struct i2c_bus_recovery_info { + void (*set_scl)(struct i2c_adapter *adap, int val); + int (*get_sda)(struct i2c_adapter *adap); + void (*set_sda)(struct i2c_adapter *adap, int val); ++ int (*get_bus_free)(struct i2c_adapter *adap); + + void (*prepare_recovery)(struct i2c_adapter *adap); + void (*unprepare_recovery)(struct i2c_adapter *adap); +-- +2.19.0 + |