| From 2702c0018bef27dad2683167ec1349453b27cdd0 Mon Sep 17 00:00:00 2001 |
| From: Furquan Shaikh <furquan@google.com> |
| Date: Wed, 13 Jun 2018 21:55:26 -0700 |
| Subject: [PATCH] CHROMIUM: i2c: Add device property for probing |
| |
| Add a new device property to indicate if an I2C device should be |
| probed before being added. If this property is present and set |
| then the I2C core layer will use i2c_new_probed_device() instead |
| of i2c_new_device(). |
| |
| This can be used to provide devices in ACPI or DT that may not be |
| present on the board. For example, multiple trackpad vendors can |
| be supported on a single board with a unified firmware image this |
| way by having their device address be probed before being added. |
| |
| This property is styled after the PCI Host Bridge probe property |
| (bindings/pci/host-generic-pci.txt:linuxk,pci-probe-only) and is |
| a linux specific directive to alter device probing. |
| |
| BUG=b:110013532 |
| TEST=tested on soraka with 4.14 kernel: |
| 1) add "linux,probed=1" device property to the touchscreen ACPI device |
| on soraka and ensure that the device is probed before being added. |
| |
| tested on yorp with 4.14 kernel: |
| 1) I2C devices without the "linux,probed=1" device property are still |
| functional. |
| |
| Original-change-Id: I9cf689f7b75ef445c1f0e9f7ec143fa695eb398e |
| Original-signed-off-by: Duncan Laurie <dlaurie@chromium.org> |
| Original-reviewed-on: https://chromium-review.googlesource.com/388767 |
| Original-reviewed-by: Benson Leung <bleung@chromium.org> |
| |
| Change-Id: I54015fe102f2834f6a094d9e650c166a0cc0583b |
| Signed-off-by: Furquan Shaikh <furquan@google.com> |
| Reviewed-on: https://chromium-review.googlesource.com/1100544 |
| Commit-Ready: Furquan Shaikh <furquan@chromium.org> |
| Tested-by: Furquan Shaikh <furquan@chromium.org> |
| Reviewed-by: Justin TerAvest <teravest@chromium.org> |
| |
| Conflicts: |
| drivers/i2c/i2c-core-of.c |
| |
| [rebase419(groeck): Context conflicts] |
| Signed-off-by: Guenter Roeck <groeck@chromium.org> |
| [rebase510(groeck): Context conflicts] |
| Signed-off-by: Guenter Roeck <groeck@chromium.org> |
| Change-Id: Id10adae00b381e62813fd6b8ce7c6c50f140c31b |
| --- |
| Documentation/devicetree/bindings/i2c/i2c.txt | 5 +++++ |
| drivers/i2c/i2c-core-acpi.c | 12 +++++++++++- |
| drivers/i2c/i2c-core-of.c | 10 +++++++++- |
| 3 files changed, 25 insertions(+), 2 deletions(-) |
| |
| diff --git a/Documentation/devicetree/bindings/i2c/i2c.txt b/Documentation/devicetree/bindings/i2c/i2c.txt |
| index df41f72afc87..d1a2ac210307 100644 |
| --- a/Documentation/devicetree/bindings/i2c/i2c.txt |
| +++ b/Documentation/devicetree/bindings/i2c/i2c.txt |
| @@ -130,6 +130,11 @@ wants to support one of the below features, it should adapt these bindings. |
| - wakeup-source |
| device can be used as a wakeup source. |
| |
| +- linux,probed |
| + If this property is present, then the I2C device will be |
| + probed before being added using i2c_new_scanned_device, else |
| + linux will instantiate the I2C device normally. |
| + |
| Binding may contain optional "interrupts" property, describing interrupts |
| used by the device. I2C core will assign "irq" interrupt (or the very first |
| interrupt if not using interrupt names) as primary interrupt for the slave. |
| diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c |
| index 8ceaa88dd78f..4f7860f39523 100644 |
| --- a/drivers/i2c/i2c-core-acpi.c |
| +++ b/drivers/i2c/i2c-core-acpi.c |
| @@ -222,10 +222,20 @@ static void i2c_acpi_register_device(struct i2c_adapter *adapter, |
| struct acpi_device *adev, |
| struct i2c_board_info *info) |
| { |
| + struct i2c_client *client; |
| + |
| adev->power.flags.ignore_parent = true; |
| acpi_device_set_enumerated(adev); |
| |
| - if (IS_ERR(i2c_new_client_device(adapter, info))) |
| + if (!acpi_dev_get_property(adev, "linux,probed", ACPI_TYPE_ANY, NULL)) { |
| + unsigned short addrs[] = { info->addr, I2C_CLIENT_END }; |
| + |
| + client = i2c_new_scanned_device(adapter, info, addrs, NULL); |
| + } else { |
| + client = i2c_new_client_device(adapter, info); |
| + } |
| + |
| + if (IS_ERR(client)) |
| adev->power.flags.ignore_parent = false; |
| } |
| |
| diff --git a/drivers/i2c/i2c-core-of.c b/drivers/i2c/i2c-core-of.c |
| index 3ed74aa4b44b..fd375ce38a9e 100644 |
| --- a/drivers/i2c/i2c-core-of.c |
| +++ b/drivers/i2c/i2c-core-of.c |
| @@ -75,7 +75,15 @@ static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap, |
| if (ret) |
| return ERR_PTR(ret); |
| |
| - client = i2c_new_client_device(adap, &info); |
| + /* Allow device property to enable probing before init */ |
| + if (of_get_property(node, "linux,probed", NULL)) { |
| + unsigned short addrs[] = { info.addr, I2C_CLIENT_END }; |
| + |
| + client = i2c_new_scanned_device(adap, &info, addrs, NULL); |
| + } else { |
| + client = i2c_new_client_device(adap, &info); |
| + } |
| + |
| if (IS_ERR(client)) |
| dev_err(&adap->dev, "of_i2c: Failure registering %pOF\n", node); |
| |
| -- |
| 2.17.1 |
| |