Message ID | 20250511-i2c-pxa-fix-i2c-communication-v1-1-e9097d09a015@gmail.com |
---|---|
State | New |
Headers | show |
Series | [1/3] i2c: add init_recovery() callback | expand |
Szía Gabor, köszönöm a patch-et! On Sun, May 11, 2025 at 3:31 PM Gabor Juhos <j4g8y7@gmail.com> wrote: > Add a new init_recovery() callback to struct 'i2c_bus_recovery_info' > and modify the i2c_init_recovery() function to call that if specified > instead of the generic i2c_gpio_init_recovery() function. > > This allows controller drivers to skip calling the generic code by > implementing a dummy callback function, or alternatively to run a > fine tuned custom implementation. > > This is needed for the 'i2c-pxa' driver in order to be able to fix > a long standing bug for which the fix will be implemented in a > followup patch. > > Cc: stable@vger.kernel.org # 6.3+ > Signed-off-by: Gabor Juhos <j4g8y7@gmail.com> > Signed-off-by: Imre Kaloz <kaloz@openwrt.org> Clearly, since the same problems keeps appearing on other platforms as well, this is the right way to go! Reviewed-by: Linus Walleij <linus.walleij@linaro.org> Yours, Linus Walleij
diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index 7ad1ad5c8c3f56943b627254b1fdbf8f787afdb5..6b8b961b845caf6f28ea1a9a76d623ac73f5e0dd 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c @@ -427,12 +427,18 @@ static int i2c_init_recovery(struct i2c_adapter *adap) struct i2c_bus_recovery_info *bri = adap->bus_recovery_info; bool is_error_level = true; char *err_str; + int ret; if (!bri) return 0; - if (i2c_gpio_init_recovery(adap) == -EPROBE_DEFER) + if (bri->init_recovery) { + ret = bri->init_recovery(adap); + if (ret) + return ret; + } else if (i2c_gpio_init_recovery(adap) == -EPROBE_DEFER) { return -EPROBE_DEFER; + } if (!bri->recover_bus) { err_str = "no suitable method provided"; diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 2e4903b7f7bc11627f9cbc23a4d549dd48c4dcc7..1cff399822c817429e520572546a3d0b7f704723 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -638,6 +638,9 @@ struct i2c_timings { * 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. + * @init_recovery: If specified, it will be called instead of the generic GPIO + * recovery initialization code. Platform may use a dummy callback to skip + * calling the generic code, or it may use a custom implementation. * @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 @@ -662,6 +665,7 @@ struct i2c_bus_recovery_info { void (*set_sda)(struct i2c_adapter *adap, int val); int (*get_bus_free)(struct i2c_adapter *adap); + int (*init_recovery)(struct i2c_adapter *adap); void (*prepare_recovery)(struct i2c_adapter *adap); void (*unprepare_recovery)(struct i2c_adapter *adap);