diff options
Diffstat (limited to 'drivers/i2c/i2c-core-base.c')
-rw-r--r-- | drivers/i2c/i2c-core-base.c | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index 5a2783ad52ea..d46ae60fd8d0 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c @@ -336,8 +336,10 @@ static int i2c_device_probe(struct device *dev) } else if (ACPI_COMPANION(dev)) { irq = acpi_dev_gpio_irq_get(ACPI_COMPANION(dev), 0); } - if (irq == -EPROBE_DEFER) - return irq; + if (irq == -EPROBE_DEFER) { + status = irq; + goto put_sync_adapter; + } if (irq < 0) irq = 0; @@ -351,16 +353,20 @@ static int i2c_device_probe(struct device *dev) */ if (!driver->id_table && !i2c_acpi_match_device(dev->driver->acpi_match_table, client) && - !i2c_of_match_device(dev->driver->of_match_table, client)) - return -ENODEV; + !i2c_of_match_device(dev->driver->of_match_table, client)) { + status = -ENODEV; + goto put_sync_adapter; + } if (client->flags & I2C_CLIENT_WAKE) { int wakeirq = -ENOENT; if (dev->of_node) { wakeirq = of_irq_get_byname(dev->of_node, "wakeup"); - if (wakeirq == -EPROBE_DEFER) - return wakeirq; + if (wakeirq == -EPROBE_DEFER) { + status = wakeirq; + goto put_sync_adapter; + } } device_init_wakeup(&client->dev, true); @@ -408,6 +414,10 @@ err_detach_pm_domain: err_clear_wakeup_irq: dev_pm_clear_wake_irq(&client->dev); device_init_wakeup(&client->dev, false); +put_sync_adapter: + if (client->flags & I2C_CLIENT_HOST_NOTIFY) + pm_runtime_put_sync(&client->adapter->dev); + return status; } @@ -728,7 +738,7 @@ static int i2c_dev_irq_from_resources(const struct resource *resources, * This returns the new i2c client, which may be saved for later use with * i2c_unregister_device(); or an ERR_PTR to describe the error. */ -static struct i2c_client * +struct i2c_client * i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *info) { struct i2c_client *client; @@ -894,8 +904,7 @@ static struct i2c_driver dummy_driver = { * This returns the new i2c client, which should be saved for later use with * i2c_unregister_device(); or an ERR_PTR to describe the error. */ -static struct i2c_client * -i2c_new_dummy_device(struct i2c_adapter *adapter, u16 address) +struct i2c_client *i2c_new_dummy_device(struct i2c_adapter *adapter, u16 address) { struct i2c_board_info info = { I2C_BOARD_INFO("dummy", address), |