blob: 9ae1ddf2e512a593cfc229c16379cd4fec8e922f [file] [log] [blame]
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