Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

i2c: core: add generic I2C GPIO recovery

Multiple I2C bus drivers use similar bindings to obtain information needed
for I2C recovery. For example, for platforms using device-tree, the
properties look something like this:

&i2c {
...
pinctrl-names = "default", "gpio";
pinctrl-0 = <&pinctrl_i2c_default>;
pinctrl-1 = <&pinctrl_i2c_gpio>;
sda-gpios = <&pio 0 GPIO_ACTIVE_HIGH>;
scl-gpios = <&pio 1 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
...
}

For this reason, we can add this common initialization in the core. This
way, other I2C bus drivers will be able to support GPIO recovery just by
providing a pointer to platform's pinctrl and calling i2c_recover_bus()
when SDA is stuck low.

Signed-off-by: Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
[wsa: inverted one logic for better readability, minor update to kdoc]
Signed-off-by: Wolfram Sang <wsa@kernel.org>

authored by

Codrin Ciubotariu and committed by
Wolfram Sang
75820314 db36e827

+137
+126
drivers/i2c/i2c-core-base.c
··· 32 32 #include <linux/of_device.h> 33 33 #include <linux/of.h> 34 34 #include <linux/of_irq.h> 35 + #include <linux/pinctrl/consumer.h> 35 36 #include <linux/pm_domain.h> 36 37 #include <linux/pm_runtime.h> 37 38 #include <linux/pm_wakeirq.h> ··· 182 181 183 182 if (bri->prepare_recovery) 184 183 bri->prepare_recovery(adap); 184 + if (bri->pinctrl) 185 + pinctrl_select_state(bri->pinctrl, bri->pins_gpio); 185 186 186 187 /* 187 188 * If we can set SDA, we will always create a STOP to ensure additional ··· 239 236 240 237 if (bri->unprepare_recovery) 241 238 bri->unprepare_recovery(adap); 239 + if (bri->pinctrl) 240 + pinctrl_select_state(bri->pinctrl, bri->pins_default); 242 241 243 242 return ret; 244 243 } ··· 256 251 } 257 252 EXPORT_SYMBOL_GPL(i2c_recover_bus); 258 253 254 + static void i2c_gpio_init_pinctrl_recovery(struct i2c_adapter *adap) 255 + { 256 + struct i2c_bus_recovery_info *bri = adap->bus_recovery_info; 257 + struct device *dev = &adap->dev; 258 + struct pinctrl *p = bri->pinctrl; 259 + 260 + /* 261 + * we can't change states without pinctrl, so remove the states if 262 + * populated 263 + */ 264 + if (!p) { 265 + bri->pins_default = NULL; 266 + bri->pins_gpio = NULL; 267 + return; 268 + } 269 + 270 + if (!bri->pins_default) { 271 + bri->pins_default = pinctrl_lookup_state(p, 272 + PINCTRL_STATE_DEFAULT); 273 + if (IS_ERR(bri->pins_default)) { 274 + dev_dbg(dev, PINCTRL_STATE_DEFAULT " state not found for GPIO recovery\n"); 275 + bri->pins_default = NULL; 276 + } 277 + } 278 + if (!bri->pins_gpio) { 279 + bri->pins_gpio = pinctrl_lookup_state(p, "gpio"); 280 + if (IS_ERR(bri->pins_gpio)) 281 + bri->pins_gpio = pinctrl_lookup_state(p, "recovery"); 282 + 283 + if (IS_ERR(bri->pins_gpio)) { 284 + dev_dbg(dev, "no gpio or recovery state found for GPIO recovery\n"); 285 + bri->pins_gpio = NULL; 286 + } 287 + } 288 + 289 + /* for pinctrl state changes, we need all the information */ 290 + if (bri->pins_default && bri->pins_gpio) { 291 + dev_info(dev, "using pinctrl states for GPIO recovery"); 292 + } else { 293 + bri->pinctrl = NULL; 294 + bri->pins_default = NULL; 295 + bri->pins_gpio = NULL; 296 + } 297 + } 298 + 299 + static int i2c_gpio_init_generic_recovery(struct i2c_adapter *adap) 300 + { 301 + struct i2c_bus_recovery_info *bri = adap->bus_recovery_info; 302 + struct device *dev = &adap->dev; 303 + struct gpio_desc *gpiod; 304 + int ret = 0; 305 + 306 + /* 307 + * don't touch the recovery information if the driver is not using 308 + * generic SCL recovery 309 + */ 310 + if (bri->recover_bus && bri->recover_bus != i2c_generic_scl_recovery) 311 + return 0; 312 + 313 + /* 314 + * pins might be taken as GPIO, so we should inform pinctrl about 315 + * this and move the state to GPIO 316 + */ 317 + if (bri->pinctrl) 318 + pinctrl_select_state(bri->pinctrl, bri->pins_gpio); 319 + 320 + /* 321 + * if there is incomplete or no recovery information, see if generic 322 + * GPIO recovery is available 323 + */ 324 + if (!bri->scl_gpiod) { 325 + gpiod = devm_gpiod_get(dev, "scl", GPIOD_OUT_HIGH_OPEN_DRAIN); 326 + if (PTR_ERR(gpiod) == -EPROBE_DEFER) { 327 + ret = -EPROBE_DEFER; 328 + goto cleanup_pinctrl_state; 329 + } 330 + if (!IS_ERR(gpiod)) { 331 + bri->scl_gpiod = gpiod; 332 + bri->recover_bus = i2c_generic_scl_recovery; 333 + dev_info(dev, "using generic GPIOs for recovery\n"); 334 + } 335 + } 336 + 337 + /* SDA GPIOD line is optional, so we care about DEFER only */ 338 + if (!bri->sda_gpiod) { 339 + /* 340 + * We have SCL. Pull SCL low and wait a bit so that SDA glitches 341 + * have no effect. 342 + */ 343 + gpiod_direction_output(bri->scl_gpiod, 0); 344 + udelay(10); 345 + gpiod = devm_gpiod_get(dev, "sda", GPIOD_IN); 346 + 347 + /* Wait a bit in case of a SDA glitch, and then release SCL. */ 348 + udelay(10); 349 + gpiod_direction_output(bri->scl_gpiod, 1); 350 + 351 + if (PTR_ERR(gpiod) == -EPROBE_DEFER) { 352 + ret = -EPROBE_DEFER; 353 + goto cleanup_pinctrl_state; 354 + } 355 + if (!IS_ERR(gpiod)) 356 + bri->sda_gpiod = gpiod; 357 + } 358 + 359 + cleanup_pinctrl_state: 360 + /* change the state of the pins back to their default state */ 361 + if (bri->pinctrl) 362 + pinctrl_select_state(bri->pinctrl, bri->pins_default); 363 + 364 + return ret; 365 + } 366 + 367 + static int i2c_gpio_init_recovery(struct i2c_adapter *adap) 368 + { 369 + i2c_gpio_init_pinctrl_recovery(adap); 370 + return i2c_gpio_init_generic_recovery(adap); 371 + } 372 + 259 373 static void i2c_init_recovery(struct i2c_adapter *adap) 260 374 { 261 375 struct i2c_bus_recovery_info *bri = adap->bus_recovery_info; ··· 382 258 383 259 if (!bri) 384 260 return; 261 + 262 + i2c_gpio_init_recovery(adap); 385 263 386 264 if (!bri->recover_bus) { 387 265 err_str = "no recover_bus() found";
+11
include/linux/i2c.h
··· 606 606 * may configure padmux here for SDA/SCL line or something else they want. 607 607 * @scl_gpiod: gpiod of the SCL line. Only required for GPIO recovery. 608 608 * @sda_gpiod: gpiod of the SDA line. Only required for GPIO recovery. 609 + * @pinctrl: pinctrl used by GPIO recovery to change the state of the I2C pins. 610 + * Optional. 611 + * @pins_default: default pinctrl state of SCL/SDA lines, when they are assigned 612 + * to the I2C bus. Optional. Populated internally for GPIO recovery, if 613 + * state with the name PINCTRL_STATE_DEFAULT is found and pinctrl is valid. 614 + * @pins_gpio: recovery pinctrl state of SCL/SDA lines, when they are used as 615 + * GPIOs. Optional. Populated internally for GPIO recovery, if this state 616 + * is called "gpio" or "recovery" and pinctrl is valid. 609 617 */ 610 618 struct i2c_bus_recovery_info { 611 619 int (*recover_bus)(struct i2c_adapter *adap); ··· 630 622 /* gpio recovery */ 631 623 struct gpio_desc *scl_gpiod; 632 624 struct gpio_desc *sda_gpiod; 625 + struct pinctrl *pinctrl; 626 + struct pinctrl_state *pins_default; 627 + struct pinctrl_state *pins_gpio; 633 628 }; 634 629 635 630 int i2c_recover_bus(struct i2c_adapter *adap);