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

i2c: core: treat EPROBE_DEFER when acquiring SCL/SDA GPIOs

Even if I2C bus GPIO recovery is optional, devm_gpiod_get() can return
-EPROBE_DEFER, so we should at least treat that. This ends up with
i2c_register_adapter() to be able to return -EPROBE_DEFER.

Signed-off-by: Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
Signed-off-by: Wolfram Sang <wsa@kernel.org>

authored by

Codrin Ciubotariu and committed by
Wolfram Sang
23a698fe 75820314

+14 -12
+14 -12
drivers/i2c/i2c-core-base.c
··· 375 375 return i2c_gpio_init_generic_recovery(adap); 376 376 } 377 377 378 - static void i2c_init_recovery(struct i2c_adapter *adap) 378 + static int i2c_init_recovery(struct i2c_adapter *adap) 379 379 { 380 380 struct i2c_bus_recovery_info *bri = adap->bus_recovery_info; 381 381 char *err_str; 382 382 383 383 if (!bri) 384 - return; 384 + return 0; 385 385 386 - i2c_gpio_init_recovery(adap); 386 + if (i2c_gpio_init_recovery(adap) == -EPROBE_DEFER) 387 + return -EPROBE_DEFER; 387 388 388 389 if (!bri->recover_bus) { 389 390 err_str = "no recover_bus() found"; ··· 400 399 if (gpiod_get_direction(bri->sda_gpiod) == 0) 401 400 bri->set_sda = set_sda_gpio_value; 402 401 } 403 - return; 404 - } 405 - 406 - if (bri->recover_bus == i2c_generic_scl_recovery) { 402 + } else if (bri->recover_bus == i2c_generic_scl_recovery) { 407 403 /* Generic SCL recovery */ 408 404 if (!bri->set_scl || !bri->get_scl) { 409 405 err_str = "no {get|set}_scl() found"; ··· 412 414 } 413 415 } 414 416 415 - return; 417 + return 0; 416 418 err: 417 419 dev_err(&adap->dev, "Not using recovery: %s\n", err_str); 418 420 adap->bus_recovery_info = NULL; 421 + 422 + return -EINVAL; 419 423 } 420 424 421 425 static int i2c_smbus_host_notify_to_irq(const struct i2c_client *client) ··· 1444 1444 if (res) 1445 1445 goto out_reg; 1446 1446 1447 - dev_dbg(&adap->dev, "adapter [%s] registered\n", adap->name); 1448 - 1449 1447 pm_runtime_no_callbacks(&adap->dev); 1450 1448 pm_suspend_ignore_children(&adap->dev, true); 1451 1449 pm_runtime_enable(&adap->dev); 1450 + 1451 + res = i2c_init_recovery(adap); 1452 + if (res == -EPROBE_DEFER) 1453 + goto out_reg; 1454 + 1455 + dev_dbg(&adap->dev, "adapter [%s] registered\n", adap->name); 1452 1456 1453 1457 #ifdef CONFIG_I2C_COMPAT 1454 1458 res = class_compat_create_link(i2c_adapter_compat_class, &adap->dev, ··· 1461 1457 dev_warn(&adap->dev, 1462 1458 "Failed to create compatibility class link\n"); 1463 1459 #endif 1464 - 1465 - i2c_init_recovery(adap); 1466 1460 1467 1461 /* create pre-declared device nodes */ 1468 1462 of_i2c_register_devices(adap);