summaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/i2c-amd-mp2-plat.c27
-rw-r--r--drivers/i2c/busses/i2c-davinci.c3
-rw-r--r--drivers/i2c/busses/i2c-mlxbf.c20
-rw-r--r--drivers/i2c/i2c-core-acpi.c40
-rw-r--r--drivers/i2c/i2c-core-base.c6
-rw-r--r--drivers/i2c/i2c-core.h4
6 files changed, 54 insertions, 46 deletions
diff --git a/drivers/i2c/busses/i2c-amd-mp2-plat.c b/drivers/i2c/busses/i2c-amd-mp2-plat.c
index 84b7e6cbc67b..423fe0c8a471 100644
--- a/drivers/i2c/busses/i2c-amd-mp2-plat.c
+++ b/drivers/i2c/busses/i2c-amd-mp2-plat.c
@@ -244,14 +244,18 @@ static const struct i2c_adapter_quirks amd_i2c_dev_quirks = {
static int i2c_amd_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
int ret;
struct amd_i2c_dev *i2c_dev;
- struct acpi_device *adev = ACPI_COMPANION(&pdev->dev);
struct amd_mp2_dev *mp2_dev;
- const char *uid;
+ u64 uid;
- if (!adev)
- return -ENODEV;
+ ret = acpi_dev_uid_to_integer(ACPI_COMPANION(dev), &uid);
+ if (ret)
+ return dev_err_probe(dev, ret, "missing UID/bus id!\n");
+ if (uid >= 2)
+ return dev_err_probe(dev, -EINVAL, "incorrect UID/bus id \"%llu\"!\n", uid);
+ dev_dbg(dev, "bus id is %llu\n", uid);
/* The ACPI namespace doesn't contain information about which MP2 PCI
* device an AMDI0011 ACPI device is related to, so assume that there's
@@ -266,6 +270,7 @@ static int i2c_amd_probe(struct platform_device *pdev)
if (!i2c_dev)
return -ENOMEM;
+ i2c_dev->common.bus_id = uid;
i2c_dev->common.mp2_dev = mp2_dev;
i2c_dev->pdev = pdev;
platform_set_drvdata(pdev, i2c_dev);
@@ -276,20 +281,6 @@ static int i2c_amd_probe(struct platform_device *pdev)
i2c_dev->common.resume = &i2c_amd_resume;
#endif
- uid = adev->pnp.unique_id;
- if (!uid) {
- dev_err(&pdev->dev, "missing UID/bus id!\n");
- return -EINVAL;
- } else if (strcmp(uid, "0") == 0) {
- i2c_dev->common.bus_id = 0;
- } else if (strcmp(uid, "1") == 0) {
- i2c_dev->common.bus_id = 1;
- } else {
- dev_err(&pdev->dev, "incorrect UID/bus id \"%s\"!\n", uid);
- return -EINVAL;
- }
- dev_dbg(&pdev->dev, "bus id is %u\n", i2c_dev->common.bus_id);
-
/* Register the adapter */
amd_mp2_pm_runtime_get(mp2_dev);
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
index 471c47db546b..c836cf884185 100644
--- a/drivers/i2c/busses/i2c-davinci.c
+++ b/drivers/i2c/busses/i2c-davinci.c
@@ -823,7 +823,7 @@ static int davinci_i2c_probe(struct platform_device *pdev)
r = pm_runtime_resume_and_get(dev->dev);
if (r < 0) {
dev_err(dev->dev, "failed to runtime_get device: %d\n", r);
- return r;
+ goto err_pm;
}
i2c_davinci_init(dev);
@@ -882,6 +882,7 @@ static int davinci_i2c_probe(struct platform_device *pdev)
err_unuse_clocks:
pm_runtime_dont_use_autosuspend(dev->dev);
pm_runtime_put_sync(dev->dev);
+err_pm:
pm_runtime_disable(dev->dev);
return r;
diff --git a/drivers/i2c/busses/i2c-mlxbf.c b/drivers/i2c/busses/i2c-mlxbf.c
index ad5efd7497d1..60908c5737f1 100644
--- a/drivers/i2c/busses/i2c-mlxbf.c
+++ b/drivers/i2c/busses/i2c-mlxbf.c
@@ -2215,35 +2215,27 @@ MODULE_DEVICE_TABLE(acpi, mlxbf_i2c_acpi_ids);
static int mlxbf_i2c_acpi_probe(struct device *dev, struct mlxbf_i2c_priv *priv)
{
const struct acpi_device_id *aid;
- struct acpi_device *adev;
- unsigned long bus_id = 0;
- const char *uid;
+ u64 bus_id;
int ret;
if (acpi_disabled)
return -ENOENT;
- adev = ACPI_COMPANION(dev);
- if (!adev)
- return -ENXIO;
-
aid = acpi_match_device(mlxbf_i2c_acpi_ids, dev);
if (!aid)
return -ENODEV;
priv->chip = (struct mlxbf_i2c_chip_info *)aid->driver_data;
- uid = acpi_device_uid(adev);
- if (!uid || !(*uid)) {
+ ret = acpi_dev_uid_to_integer(ACPI_COMPANION(dev), &bus_id);
+ if (ret) {
dev_err(dev, "Cannot retrieve UID\n");
- return -ENODEV;
+ return ret;
}
- ret = kstrtoul(uid, 0, &bus_id);
- if (!ret)
- priv->bus = bus_id;
+ priv->bus = bus_id;
- return ret;
+ return 0;
}
#else
static int mlxbf_i2c_acpi_probe(struct device *dev, struct mlxbf_i2c_priv *priv)
diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c
index 08b561f0709d..f88386d732d2 100644
--- a/drivers/i2c/i2c-core-acpi.c
+++ b/drivers/i2c/i2c-core-acpi.c
@@ -137,6 +137,11 @@ static const struct acpi_device_id i2c_acpi_ignored_device_ids[] = {
{}
};
+struct i2c_acpi_irq_context {
+ int irq;
+ bool wake_capable;
+};
+
static int i2c_acpi_do_lookup(struct acpi_device *adev,
struct i2c_acpi_lookup *lookup)
{
@@ -168,13 +173,19 @@ static int i2c_acpi_do_lookup(struct acpi_device *adev,
return 0;
}
-static int i2c_acpi_add_resource(struct acpi_resource *ares, void *data)
+static int i2c_acpi_add_irq_resource(struct acpi_resource *ares, void *data)
{
- int *irq = data;
+ struct i2c_acpi_irq_context *irq_ctx = data;
struct resource r;
- if (*irq <= 0 && acpi_dev_resource_interrupt(ares, 0, &r))
- *irq = i2c_dev_irq_from_resources(&r, 1);
+ if (irq_ctx->irq > 0)
+ return 1;
+
+ if (!acpi_dev_resource_interrupt(ares, 0, &r))
+ return 1;
+
+ irq_ctx->irq = i2c_dev_irq_from_resources(&r, 1);
+ irq_ctx->wake_capable = r.flags & IORESOURCE_IRQ_WAKECAPABLE;
return 1; /* No need to add resource to the list */
}
@@ -182,31 +193,40 @@ static int i2c_acpi_add_resource(struct acpi_resource *ares, void *data)
/**
* i2c_acpi_get_irq - get device IRQ number from ACPI
* @client: Pointer to the I2C client device
+ * @wake_capable: Set to true if the IRQ is wake capable
*
* Find the IRQ number used by a specific client device.
*
* Return: The IRQ number or an error code.
*/
-int i2c_acpi_get_irq(struct i2c_client *client)
+int i2c_acpi_get_irq(struct i2c_client *client, bool *wake_capable)
{
struct acpi_device *adev = ACPI_COMPANION(&client->dev);
struct list_head resource_list;
- int irq = -ENOENT;
+ struct i2c_acpi_irq_context irq_ctx = {
+ .irq = -ENOENT,
+ };
int ret;
INIT_LIST_HEAD(&resource_list);
ret = acpi_dev_get_resources(adev, &resource_list,
- i2c_acpi_add_resource, &irq);
+ i2c_acpi_add_irq_resource, &irq_ctx);
if (ret < 0)
return ret;
acpi_dev_free_resource_list(&resource_list);
- if (irq == -ENOENT)
- irq = acpi_dev_gpio_irq_get(adev, 0);
+ if (irq_ctx.irq == -ENOENT)
+ irq_ctx.irq = acpi_dev_gpio_irq_wake_get(adev, 0, &irq_ctx.wake_capable);
+
+ if (irq_ctx.irq < 0)
+ return irq_ctx.irq;
+
+ if (wake_capable)
+ *wake_capable = irq_ctx.wake_capable;
- return irq;
+ return irq_ctx.irq;
}
static int i2c_acpi_get_info(struct acpi_device *adev,
diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
index 91007558bcb2..fc4b85fb90b1 100644
--- a/drivers/i2c/i2c-core-base.c
+++ b/drivers/i2c/i2c-core-base.c
@@ -487,7 +487,11 @@ static int i2c_device_probe(struct device *dev)
if (irq == -EINVAL || irq == -ENODATA)
irq = of_irq_get(dev->of_node, 0);
} else if (ACPI_COMPANION(dev)) {
- irq = i2c_acpi_get_irq(client);
+ bool wake_capable;
+
+ irq = i2c_acpi_get_irq(client, &wake_capable);
+ if (irq > 0 && wake_capable)
+ client->flags |= I2C_CLIENT_WAKE;
}
if (irq == -EPROBE_DEFER) {
status = irq;
diff --git a/drivers/i2c/i2c-core.h b/drivers/i2c/i2c-core.h
index 87e2c914f1c5..1247e6e6e975 100644
--- a/drivers/i2c/i2c-core.h
+++ b/drivers/i2c/i2c-core.h
@@ -61,11 +61,11 @@ static inline int __i2c_check_suspended(struct i2c_adapter *adap)
#ifdef CONFIG_ACPI
void i2c_acpi_register_devices(struct i2c_adapter *adap);
-int i2c_acpi_get_irq(struct i2c_client *client);
+int i2c_acpi_get_irq(struct i2c_client *client, bool *wake_capable);
#else /* CONFIG_ACPI */
static inline void i2c_acpi_register_devices(struct i2c_adapter *adap) { }
-static inline int i2c_acpi_get_irq(struct i2c_client *client)
+static inline int i2c_acpi_get_irq(struct i2c_client *client, bool *wake_capable)
{
return 0;
}