summaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
authorAndy Shevchenko <andriy.shevchenko@linux.intel.com>2018-11-28 06:45:25 -0500
committerAndy Shevchenko <andriy.shevchenko@linux.intel.com>2018-12-03 14:40:02 -0500
commit2dea645ffc21f927067e8e35147985887b1a843d (patch)
tree1161bd0416a590c8d50d4b2f12b47deb734e32d2 /drivers/i2c
parent1aaeae493aad4d71f75f4129e676fbfcdf8b1422 (diff)
i2c: acpi: Return error pointers from i2c_acpi_new_device()
The caller would like to know the reason why the i2c_acpi_new_device() fails. For example, if adapter is not available, it might be in the future and we would like to re-probe the clients again. But at the same time we would like to bail out if the error seems unrecoverable, such as invalid argument supplied. To achieve this, return error pointer in some cases. Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> Reviewed-by: Hans de Goede <hdegoede@redhat.com> Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com> Acked-by: Wolfram Sang <wsa@the-dreams.de>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/i2c-core-acpi.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c
index 32affd3fa8bd..689c0c467e97 100644
--- a/drivers/i2c/i2c-core-acpi.c
+++ b/drivers/i2c/i2c-core-acpi.c
@@ -386,20 +386,22 @@ struct notifier_block i2c_acpi_notifier = {
386 * 386 *
387 * Also see i2c_new_device, which this function calls to create the i2c-client. 387 * Also see i2c_new_device, which this function calls to create the i2c-client.
388 * 388 *
389 * Returns a pointer to the new i2c-client, or NULL if the adapter is not found. 389 * Returns a pointer to the new i2c-client, or error pointer in case of failure.
390 * Specifically, -EPROBE_DEFER is returned if the adapter is not found.
390 */ 391 */
391struct i2c_client *i2c_acpi_new_device(struct device *dev, int index, 392struct i2c_client *i2c_acpi_new_device(struct device *dev, int index,
392 struct i2c_board_info *info) 393 struct i2c_board_info *info)
393{ 394{
394 struct i2c_acpi_lookup lookup; 395 struct i2c_acpi_lookup lookup;
395 struct i2c_adapter *adapter; 396 struct i2c_adapter *adapter;
397 struct i2c_client *client;
396 struct acpi_device *adev; 398 struct acpi_device *adev;
397 LIST_HEAD(resource_list); 399 LIST_HEAD(resource_list);
398 int ret; 400 int ret;
399 401
400 adev = ACPI_COMPANION(dev); 402 adev = ACPI_COMPANION(dev);
401 if (!adev) 403 if (!adev)
402 return NULL; 404 return ERR_PTR(-EINVAL);
403 405
404 memset(&lookup, 0, sizeof(lookup)); 406 memset(&lookup, 0, sizeof(lookup));
405 lookup.info = info; 407 lookup.info = info;
@@ -408,16 +410,23 @@ struct i2c_client *i2c_acpi_new_device(struct device *dev, int index,
408 410
409 ret = acpi_dev_get_resources(adev, &resource_list, 411 ret = acpi_dev_get_resources(adev, &resource_list,
410 i2c_acpi_fill_info, &lookup); 412 i2c_acpi_fill_info, &lookup);
413 if (ret < 0)
414 return ERR_PTR(ret);
415
411 acpi_dev_free_resource_list(&resource_list); 416 acpi_dev_free_resource_list(&resource_list);
412 417
413 if (ret < 0 || !info->addr) 418 if (!info->addr)
414 return NULL; 419 return ERR_PTR(-EADDRNOTAVAIL);
415 420
416 adapter = i2c_acpi_find_adapter_by_handle(lookup.adapter_handle); 421 adapter = i2c_acpi_find_adapter_by_handle(lookup.adapter_handle);
417 if (!adapter) 422 if (!adapter)
418 return NULL; 423 return ERR_PTR(-EPROBE_DEFER);
424
425 client = i2c_new_device(adapter, info);
426 if (!client)
427 return ERR_PTR(-ENODEV);
419 428
420 return i2c_new_device(adapter, info); 429 return client;
421} 430}
422EXPORT_SYMBOL_GPL(i2c_acpi_new_device); 431EXPORT_SYMBOL_GPL(i2c_acpi_new_device);
423 432