085-v4.16-0001-i2c-gpio-Enable-working-over-slow-can_sleep-GPIOs.patch 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. From f11a04464ae57e8db1bb7634547842b43e36a898 Mon Sep 17 00:00:00 2001
  2. From: =?UTF-8?q?Jan=20Kundr=C3=A1t?= <jan.kundrat@cesnet.cz>
  3. Date: Fri, 22 Dec 2017 22:47:16 +0100
  4. Subject: i2c: gpio: Enable working over slow can_sleep GPIOs
  5. MIME-Version: 1.0
  6. Content-Type: text/plain; charset=UTF-8
  7. Content-Transfer-Encoding: 8bit
  8. "Slow" GPIOs (usually those connected over an SPI or an I2C bus) are,
  9. well, slow in their operation. It is generally a good idea to avoid
  10. using them for time-critical operation, but sometimes the hardware just
  11. sucks, and the software has to cope. In addition to that, the I2C bus
  12. itself does not actually define any strict timing limits; the bus is
  13. free to go all the way down to DC. The timeouts (and therefore the
  14. slowest acceptable frequency) are present only in SMBus.
  15. The `can_sleep` is IMHO a wrong concept to use here. My SPI-to-quad-UART
  16. chip (MAX14830) is connected via a 26MHz SPI bus, and it happily drives
  17. SCL at 200kHz (5µs pulses) during my benchmarks. That's faster than the
  18. maximal allowed speed of the traditional I2C.
  19. The previous version of this code did not really block operation over
  20. slow GPIO pins, anyway. Instead, it just resorted to printing a warning
  21. with a backtrace each time a GPIO pin was accessed, thereby slowing
  22. things down even more.
  23. Finally, it's not just me. A similar patch was originally submitted in
  24. 2015 [1].
  25. [1] https://patchwork.ozlabs.org/patch/450956/
  26. Signed-off-by: Jan Kundrát <jan.kundrat@cesnet.cz>
  27. Acked-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
  28. Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
  29. ---
  30. drivers/i2c/busses/i2c-gpio.c | 11 +++++++----
  31. 1 file changed, 7 insertions(+), 4 deletions(-)
  32. --- a/drivers/i2c/busses/i2c-gpio.c
  33. +++ b/drivers/i2c/busses/i2c-gpio.c
  34. @@ -44,7 +44,7 @@ static void i2c_gpio_setsda_val(void *da
  35. {
  36. struct i2c_gpio_platform_data *pdata = data;
  37. - gpio_set_value(pdata->sda_pin, state);
  38. + gpio_set_value_cansleep(pdata->sda_pin, state);
  39. }
  40. /* Toggle SCL by changing the direction of the pin. */
  41. @@ -68,21 +68,21 @@ static void i2c_gpio_setscl_val(void *da
  42. {
  43. struct i2c_gpio_platform_data *pdata = data;
  44. - gpio_set_value(pdata->scl_pin, state);
  45. + gpio_set_value_cansleep(pdata->scl_pin, state);
  46. }
  47. static int i2c_gpio_getsda(void *data)
  48. {
  49. struct i2c_gpio_platform_data *pdata = data;
  50. - return gpio_get_value(pdata->sda_pin);
  51. + return gpio_get_value_cansleep(pdata->sda_pin);
  52. }
  53. static int i2c_gpio_getscl(void *data)
  54. {
  55. struct i2c_gpio_platform_data *pdata = data;
  56. - return gpio_get_value(pdata->scl_pin);
  57. + return gpio_get_value_cansleep(pdata->scl_pin);
  58. }
  59. static int of_i2c_gpio_get_pins(struct device_node *np,
  60. @@ -175,6 +175,9 @@ static int i2c_gpio_probe(struct platfor
  61. memcpy(pdata, dev_get_platdata(&pdev->dev), sizeof(*pdata));
  62. }
  63. + if (gpiod_cansleep(gpio_to_desc(pdata->sda_pin)) || gpiod_cansleep(gpio_to_desc(pdata->scl_pin)))
  64. + dev_warn(&pdev->dev, "Slow GPIO pins might wreak havoc into I2C/SMBus bus timing");
  65. +
  66. if (pdata->sda_is_open_drain) {
  67. gpio_direction_output(pdata->sda_pin, 1);
  68. bit_data->setsda = i2c_gpio_setsda_val;