linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH v2 0/7] of: Introduce hardware prober driver
@ 2023-11-09 10:05 Chen-Yu Tsai
  2023-11-09 10:05 ` [RFC PATCH v2 1/7] of: base: Add of_device_is_fail Chen-Yu Tsai
                   ` (8 more replies)
  0 siblings, 9 replies; 30+ messages in thread
From: Chen-Yu Tsai @ 2023-11-09 10:05 UTC (permalink / raw)
  To: Rob Herring, Frank Rowand, Krzysztof Kozlowski, Conor Dooley,
	Matthias Brugger, AngeloGioacchino Del Regno
  Cc: Hsin-Yi Wang, Dmitry Torokhov, andriy.shevchenko, Jiri Kosina,
	linus.walleij, broonie, gregkh, hdegoede, james.clark, james,
	keescook, petr.tesarik.ext, rafael, tglx, Jeff LaBundy,
	linux-input, Chen-Yu Tsai, devicetree, linux-arm-kernel,
	linux-mediatek, linux-kernel, Douglas Anderson, Johan Hovold

Hi everyone,

This v2 series continues Doug's "of: device: Support 2nd sources of
probeable but undiscoverable devices" [1] series, but follows the scheme
suggested by Rob, marking all second source component device nodes
as "fail-needs-probe-XXX", and having a hardware prober driver enable
the one of them. I tried to include everyone from the original Cc: list.
Please let me know if you would like to be dropped from future
submissions.


For the I2C component (touchscreens and trackpads) case from the
original series, the hardware prober driver finds the particular
class of device in the device tree, gets its parent I2C adapter,
and tries to initiate a simple I2C read for each device under that
I2C bus. When it finds one that responds, it considers that one
present, marks it as "okay", and returns, letting the driver core
actually probe the device.

This works fine in most cases since these components are connected
via ribbon cable and always have the same resources. The driver as
implemented currently doesn't deal with regulators or GPIO pins,
since in the existing device trees they are either always on for
regulators, or have GPIO hogs or pinmux and pinconfig directly
tied to the pin controller.


Another case this driver could handle is selecting components based
on some identifier passed in by the firmware. On Chromebooks we have
a SKU ID which is inserted by the bootloader at
/firmware/coreboot/sku-id. When a new combination of components is
introduced, a new SKU ID is allocated to it. To have SKU ID based
device trees, we would need to have one per SKU ID. This ends up
increasing the number of device trees we have a lot. The recent
MT8186 devices already have 10+10 SKUs [2], with possibly more to come.

Instead, we could have just one device tree for each device, with
component options listed and marked as "fail-needs-probe-XXX", and
let the hardware prober enable one of them based on the given SKU ID.
The driver will also fix up OF graph remote endpoints to point to the
enabled component.

The MT8186 Corsola series [2] can also benefit from this, though I
haven't implemented anything yet.


Patch 1 adds of_device_is_fail() for the new driver to use.

Patch 2 implements the first case, probing the I2C bus for presence
of components. This initial version targets the Hana Chromebooks.

Patch 3 modifies the Hana device tree and marks the touchscreens
and trackpads as "fail-needs-probe-XXX", ready for the driver to
probe.

Patch 4 adds a missing touchscreen variant to Hana.

Patch 5 implements the second case, selectively enabling components
based on the SKU ID. This initial version targets the Krane ChromeOS
tablet, which has two possible MIPI DSI display panel options.

Patch 6 drops Krane's SKU-specific compatible strings from the bindings.

Patch 7 merges Krane's SKU-specific device trees into one, with the
device tree now containing two possible panels. This unfortunately
introduces a dtc warning:

    arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dts:81.13-83.6:
        Warning (graph_endpoint): /soc/dsi@14014000/panel2@0/port/endpoint:
	graph connection to node '/soc/dsi@14014000/ports/port/endpoint'
	    is not bidirectional


Please take a look.

Johan, I'm not sure if this works as is for the Lenovo Thinkpad 13S
case, since it looks like the trackpad shares the I2C bus with the
keyboard.


Thanks
ChenYu


Background as given in Doug's cover letter:

Support for multiple "equivalent" sources for components (also known
as second sourcing components) is a standard practice that helps keep
cost down and also makes sure that if one component is unavailable due
to a shortage that we don't need to stop production for the whole
product.

Some components are very easy to second source. eMMC, for instance, is
fully discoverable and probable so you can stuff a wide variety of
similar eMMC chips on your board and things will work without a hitch.

Some components are more difficult to second source, specifically
because it's difficult for software to probe what component is present
on any given board. In cases like this software is provided
supplementary information to help it, like a GPIO strap or a SKU ID
programmed into an EEPROM. This helpful information can allow the
bootloader to select a different device tree. The various different
"SKUs" of different Chromebooks are examples of this.

Some components are somewhere in between. These in-between components
are the subject of this patch. Specifically, these components are
easily "probeable" but not easily "discoverable".

A good example of a probeable but undiscoverable device is an
i2c-connected touchscreen or trackpad. Two separate components may be
electrically compatible with each other and may have compatible power
sequencing requirements but may require different software. If
software is told about the different possible components (because it
can't discover them), it can safely probe them to figure out which
ones are present.

On systems using device tree, if we want to tell the OS about all of
the different components we need to list them all in the device
tree. This leads to a problem. The multiple sources for components
likely use the same resources (GPIOs, interrupts, regulators). If the
OS tries to probe all of these components at the same time then it
will detect a resource conflict and that's a fatal error.

The fact that Linux can't handle these probeable but undiscoverable
devices well has had a few consequences:
1. In some cases, we've abandoned the idea of second sourcing
   components for a given board, which increases cost / generates
   manufacturing headaches.
2. In some cases, we've been forced to add some sort of strapping /
   EEPROM to indicate which component is present. This adds difficulty
   to manufacturing / refurb processes.
3. In some cases, we've managed to make things work by the skin of our
   teeth through slightly hacky solutions. Specifically, if we remove
   the "pinctrl" entry from the various options then it won't
   conflict. Regulators inherently can have more than one consumer, so
   as long as there are no GPIOs involved in power sequencing and
   probing devices then things can work. This is how
   "sc8280xp-lenovo-thinkpad-x13s" works and also how
   "mt8173-elm-hana" works.

End of background from Doug's cover letter.

[1] https://lore.kernel.org/all/20230921102420.RFC.1.I9dddd99ccdca175e3ceb1b9fa1827df0928c5101@changeid/
[2] https://lore.kernel.org/linux-mediatek/20231012230237.2676469-1-wenst@chromium.org/

Chen-Yu Tsai (7):
  of: base: Add of_device_is_fail
  of: Introduce hardware prober driver
  arm64: dts: mediatek: mt8173-elm-hana: Mark touchscreens and trackpads
    as fail
  arm64: dts: mediatek: mt8173-elm-hana: Add G2touch G7500 touchscreen
  of: hw_prober: Support Chromebook SKU ID based component selection
  dt-bindings: arm: mediatek: Remove SKU specific compatibles for Google
    Krane
  arm64: dts: mediatek: mt8183-kukui: Merge Krane device trees

 .../devicetree/bindings/arm/mediatek.yaml     |   3 -
 arch/arm64/boot/dts/mediatek/Makefile         |   3 +-
 .../boot/dts/mediatek/mt8173-elm-hana.dtsi    |  20 ++
 .../dts/mediatek/mt8183-kukui-krane-sku0.dts  |  24 --
 .../mediatek/mt8183-kukui-krane-sku176.dts    |  24 --
 ...ukui-krane.dtsi => mt8183-kukui-krane.dts} |  47 ++-
 drivers/of/Kconfig                            |  13 +
 drivers/of/Makefile                           |   1 +
 drivers/of/base.c                             |  20 ++
 drivers/of/hw_prober.c                        | 314 ++++++++++++++++++
 include/linux/of.h                            |   6 +
 11 files changed, 418 insertions(+), 57 deletions(-)
 delete mode 100644 arch/arm64/boot/dts/mediatek/mt8183-kukui-krane-sku0.dts
 delete mode 100644 arch/arm64/boot/dts/mediatek/mt8183-kukui-krane-sku176.dts
 rename arch/arm64/boot/dts/mediatek/{mt8183-kukui-krane.dtsi => mt8183-kukui-krane.dts} (86%)
 create mode 100644 drivers/of/hw_prober.c

-- 
2.42.0.869.gea05f2083d-goog


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [RFC PATCH v2 1/7] of: base: Add of_device_is_fail
  2023-11-09 10:05 [RFC PATCH v2 0/7] of: Introduce hardware prober driver Chen-Yu Tsai
@ 2023-11-09 10:05 ` Chen-Yu Tsai
  2023-11-09 10:05 ` [RFC PATCH v2 2/7] of: Introduce hardware prober driver Chen-Yu Tsai
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 30+ messages in thread
From: Chen-Yu Tsai @ 2023-11-09 10:05 UTC (permalink / raw)
  To: Rob Herring, Frank Rowand, Krzysztof Kozlowski, Conor Dooley,
	Matthias Brugger, AngeloGioacchino Del Regno
  Cc: Hsin-Yi Wang, Dmitry Torokhov, andriy.shevchenko, Jiri Kosina,
	linus.walleij, broonie, gregkh, hdegoede, james.clark, james,
	keescook, petr.tesarik.ext, rafael, tglx, Jeff LaBundy,
	linux-input, Chen-Yu Tsai, devicetree, linux-arm-kernel,
	linux-mediatek, linux-kernel, Douglas Anderson, Johan Hovold

In some cases we want to check that a device is not only unavailable,
but specifically marked as "fail".

This will be used in a following change in the hardware prober driver.

Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
 drivers/of/base.c  | 20 ++++++++++++++++++++
 include/linux/of.h |  6 ++++++
 2 files changed, 26 insertions(+)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index 8d93cb6ea9cd..2726e5dce1bf 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -486,6 +486,26 @@ static bool __of_device_is_fail(const struct device_node *device)
 	return !strcmp(status, "fail") || !strncmp(status, "fail-", 5);
 }
 
+/**
+ *  of_device_is_fail - check if a device has status "fail" or "fail-..."
+ *
+ *  @device: Node to check status for
+ *
+ *  Return: True if the status property is set to "fail" or "fail-..." (for any
+ *  error code suffix), false otherwise
+ */
+bool of_device_is_fail(const struct device_node *device)
+{
+	unsigned long flags;
+	bool res;
+
+	raw_spin_lock_irqsave(&devtree_lock, flags);
+	res = __of_device_is_fail(device);
+	raw_spin_unlock_irqrestore(&devtree_lock, flags);
+	return res;
+}
+EXPORT_SYMBOL(of_device_is_fail);
+
 /**
  *  of_device_is_big_endian - check if a device has BE registers
  *
diff --git a/include/linux/of.h b/include/linux/of.h
index 6a9ddf20e79a..463fbf0072bd 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -350,6 +350,7 @@ extern int of_device_is_compatible(const struct device_node *device,
 extern int of_device_compatible_match(const struct device_node *device,
 				      const char *const *compat);
 extern bool of_device_is_available(const struct device_node *device);
+extern bool of_device_is_fail(const struct device_node *device);
 extern bool of_device_is_big_endian(const struct device_node *device);
 extern const void *of_get_property(const struct device_node *node,
 				const char *name,
@@ -584,6 +585,11 @@ static inline bool of_device_is_available(const struct device_node *device)
 	return false;
 }
 
+static inline bool of_device_is_fail(const struct device_node *device)
+{
+	return false;
+}
+
 static inline bool of_device_is_big_endian(const struct device_node *device)
 {
 	return false;
-- 
2.42.0.869.gea05f2083d-goog


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [RFC PATCH v2 2/7] of: Introduce hardware prober driver
  2023-11-09 10:05 [RFC PATCH v2 0/7] of: Introduce hardware prober driver Chen-Yu Tsai
  2023-11-09 10:05 ` [RFC PATCH v2 1/7] of: base: Add of_device_is_fail Chen-Yu Tsai
@ 2023-11-09 10:05 ` Chen-Yu Tsai
  2023-11-09 15:13   ` Rob Herring
  2023-11-09 17:54   ` Andy Shevchenko
  2023-11-09 10:06 ` [RFC PATCH v2 3/7] arm64: dts: mediatek: mt8173-elm-hana: Mark touchscreens and trackpads as fail Chen-Yu Tsai
                   ` (6 subsequent siblings)
  8 siblings, 2 replies; 30+ messages in thread
From: Chen-Yu Tsai @ 2023-11-09 10:05 UTC (permalink / raw)
  To: Rob Herring, Frank Rowand, Krzysztof Kozlowski, Conor Dooley,
	Matthias Brugger, AngeloGioacchino Del Regno
  Cc: Hsin-Yi Wang, Dmitry Torokhov, andriy.shevchenko, Jiri Kosina,
	linus.walleij, broonie, gregkh, hdegoede, james.clark, james,
	keescook, petr.tesarik.ext, rafael, tglx, Jeff LaBundy,
	linux-input, Chen-Yu Tsai, devicetree, linux-arm-kernel,
	linux-mediatek, linux-kernel, Douglas Anderson, Johan Hovold

Some devices are designed and manufactured with some components having
multiple drop-in replacement options. These components are often
connected to the mainboard via ribbon cables, having the same signals
and pin assignments across all options. These may include the display
panel and touchscreen on laptops and tablets, and the trackpad on
laptops. Sometimes which component option is used in a particular device
can be detected by some firmware provided identifier, other times that
information is not available, and the kernel has to try to probe each
device.

This change attempts to make the "probe each device" case cleaner. The
current approach is to have all options added and enabled in the device
tree. The kernel would then bind each device and run each driver's probe
function. This works, but has been broken before due to the introduction
of asynchronous probing, causing multiple instances requesting "shared"
resources, such as pinmuxes, GPIO pins, interrupt lines, at the same
time, with only one instance succeeding. Work arounds for these include
moving the pinmux to the parent I2C controller, using GPIO hogs or
pinmux settings to keep the GPIO pins in some fixed configuration, and
requesting the interrupt line very late. Such configurations can be seen
on the MT8183 Krane Chromebook tablets, and the Qualcomm sc8280xp-based
Lenovo Thinkpad 13S.

Instead of this delicate dance between drivers and device tree quirks,
this change introduces a simple I2C component prober. For any given
class of devices on the same I2C bus, it will go through all of them,
doing a simple I2C read transfer and see which one of them responds.
It will then enable the device that responds.

This requires some minor modifications in the existing device tree.
The status for all the device nodes for the component options must be
set to "failed-needs-probe-xxx". This makes it clear that some mechanism
is needed to enable one of them, and also prevents the prober and device
drivers running at the same time.

Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
 drivers/of/Kconfig     |  13 ++++
 drivers/of/Makefile    |   1 +
 drivers/of/hw_prober.c | 154 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 168 insertions(+)
 create mode 100644 drivers/of/hw_prober.c

diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index da9826accb1b..269d20d51936 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -102,4 +102,17 @@ config OF_OVERLAY
 config OF_NUMA
 	bool
 
+config HW_PROBER
+	bool "Hardware Prober driver"
+	select I2C
+	select OF_DYNAMIC
+	help
+	  Some devices will have multiple drop-in options for one component.
+	  In many cases the different options are indistinguishable by the
+	  kernel without actually probing each possible option.
+
+	  This driver is meant to handle the probing of such components, and
+	  update the running device tree such that the correct variant is
+	  made available.
+
 endif # OF
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index eff624854575..ed3875cdc554 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
 obj-$(CONFIG_OF_RESOLVE)  += resolver.o
 obj-$(CONFIG_OF_OVERLAY) += overlay.o
 obj-$(CONFIG_OF_NUMA) += of_numa.o
+obj-$(CONFIG_HW_PROBER) += hw_prober.o
 
 ifdef CONFIG_KEXEC_FILE
 ifdef CONFIG_OF_FLATTREE
diff --git a/drivers/of/hw_prober.c b/drivers/of/hw_prober.c
new file mode 100644
index 000000000000..442da6eff896
--- /dev/null
+++ b/drivers/of/hw_prober.c
@@ -0,0 +1,154 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * hw_prober.c - Hardware prober driver
+ *
+ * Copyright (c) 2023 Google LLC
+ */
+
+#include <linux/array_size.h>
+#include <linux/i2c.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#define DRV_NAME	"hw_prober"
+
+/**
+ * struct hw_prober_entry - Holds an entry for the hardware prober
+ *
+ * @compatible:	compatible string to match against the machine
+ * @prober:	prober function to call when machine matches
+ * @data:	extra data for the prober function
+ */
+struct hw_prober_entry {
+	const char *compatible;
+	int (*prober)(struct platform_device *pdev, const void *data);
+	const void *data;
+};
+
+/*
+ * Some devices, such as Google Hana Chromebooks, are produced by multiple
+ * vendors each using their preferred components. This prober assumes such
+ * drop-in parts are on dedicated I2C busses, have non-conflicting addresses,
+ * and can be directly probed by seeing which address responds without needing
+ * regulators or GPIOs being enabled or toggled.
+ */
+static int i2c_component_prober(struct platform_device *pdev, const void *data)
+{
+	const char *node_name = data;
+	struct device_node *node, *i2c_node;
+	struct i2c_adapter *i2c;
+	int ret = 0;
+
+	node = of_find_node_by_name(NULL, node_name);
+	if (!node)
+		return dev_err_probe(&pdev->dev, -ENODEV, "Could not find %s device node\n",
+				     node_name);
+
+	i2c_node = of_get_next_parent(node);
+	if (strcmp(i2c_node->name, "i2c")) {
+		of_node_put(i2c_node);
+		return dev_err_probe(&pdev->dev, -EINVAL, "%s device isn't on I2C bus\n",
+				     node_name);
+	}
+
+	for_each_child_of_node(i2c_node, node) {
+		if (!of_node_name_prefix(node, node_name))
+			continue;
+		if (!of_device_is_fail(node)) {
+			/* device tree has component already enabled */
+			of_node_put(node);
+			of_node_put(i2c_node);
+			return 0;
+		}
+	}
+
+	i2c = of_get_i2c_adapter_by_node(i2c_node);
+	if (!i2c) {
+		of_node_put(i2c_node);
+		return dev_err_probe(&pdev->dev, -EPROBE_DEFER, "Couldn't get I2C adapter\n");
+	}
+
+	for_each_child_of_node(i2c_node, node) {
+		struct property *prop;
+		union i2c_smbus_data data;
+		u32 addr;
+
+		if (!of_node_name_prefix(node, node_name))
+			continue;
+		if (of_property_read_u32(node, "reg", &addr))
+			continue;
+		if (i2c_smbus_xfer(i2c, addr, 0, I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE, &data) < 0)
+			continue;
+
+		dev_info(&pdev->dev, "Enabling %pOF\n", node);
+
+		prop = kzalloc(sizeof(*prop), GFP_KERNEL);
+		if (!prop) {
+			ret = -ENOMEM;
+			of_node_put(node);
+			break;
+		}
+
+		prop->name	= "status";
+		prop->length	= 5;
+		prop->value	= "okay";
+
+		/* Found a device that is responding */
+		ret = of_update_property(node, prop);
+		if (ret)
+			kfree(prop);
+
+		of_node_put(node);
+		break;
+	}
+
+	i2c_put_adapter(i2c);
+	of_node_put(i2c_node);
+
+	return ret;
+}
+
+static const struct hw_prober_entry hw_prober_platforms[] = {
+	{ .compatible = "google,hana", .prober = i2c_component_prober, .data = "touchscreen" },
+	{ .compatible = "google,hana", .prober = i2c_component_prober, .data = "trackpad" },
+};
+
+static int hw_prober_probe(struct platform_device *pdev)
+{
+	for (int i = 0; i < ARRAY_SIZE(hw_prober_platforms); i++)
+		if (of_machine_is_compatible(hw_prober_platforms[i].compatible)) {
+			int ret;
+
+			ret = hw_prober_platforms[i].prober(pdev, hw_prober_platforms[i].data);
+			if (ret)
+				return ret;
+		}
+
+	return 0;
+}
+
+static struct platform_driver hw_prober_driver = {
+	.probe	= hw_prober_probe,
+	.driver	= {
+		.name = DRV_NAME,
+	},
+};
+
+static int __init hw_prober_driver_init(void)
+{
+	struct platform_device *pdev;
+	int ret;
+
+	ret = platform_driver_register(&hw_prober_driver);
+	if (ret)
+		return ret;
+
+	pdev = platform_device_register_simple(DRV_NAME, -1, NULL, 0);
+	if (!IS_ERR(pdev))
+		return 0;
+
+	platform_driver_unregister(&hw_prober_driver);
+
+	return PTR_ERR(pdev);
+}
+device_initcall(hw_prober_driver_init);
-- 
2.42.0.869.gea05f2083d-goog


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [RFC PATCH v2 3/7] arm64: dts: mediatek: mt8173-elm-hana: Mark touchscreens and trackpads as fail
  2023-11-09 10:05 [RFC PATCH v2 0/7] of: Introduce hardware prober driver Chen-Yu Tsai
  2023-11-09 10:05 ` [RFC PATCH v2 1/7] of: base: Add of_device_is_fail Chen-Yu Tsai
  2023-11-09 10:05 ` [RFC PATCH v2 2/7] of: Introduce hardware prober driver Chen-Yu Tsai
@ 2023-11-09 10:06 ` Chen-Yu Tsai
  2023-11-09 10:06 ` [RFC PATCH v2 4/7] arm64: dts: mediatek: mt8173-elm-hana: Add G2touch G7500 touchscreen Chen-Yu Tsai
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 30+ messages in thread
From: Chen-Yu Tsai @ 2023-11-09 10:06 UTC (permalink / raw)
  To: Rob Herring, Frank Rowand, Krzysztof Kozlowski, Conor Dooley,
	Matthias Brugger, AngeloGioacchino Del Regno
  Cc: Hsin-Yi Wang, Dmitry Torokhov, andriy.shevchenko, Jiri Kosina,
	linus.walleij, broonie, gregkh, hdegoede, james.clark, james,
	keescook, petr.tesarik.ext, rafael, tglx, Jeff LaBundy,
	linux-input, Chen-Yu Tsai, devicetree, linux-arm-kernel,
	linux-mediatek, linux-kernel, Douglas Anderson, Johan Hovold

Instead of having them all available, mark them all as "fail-needs-probe-*"
and have the implementation try to probe which one is present.

Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
 arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi b/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi
index bdcd35cecad9..052109b0fa3b 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi
@@ -15,6 +15,7 @@ touchscreen2: touchscreen@34 {
 		reg = <0x34>;
 		interrupt-parent = <&pio>;
 		interrupts = <88 IRQ_TYPE_LEVEL_LOW>;
+		status = "fail-needs-probe-touchscreen";
 	};
 
 	/*
@@ -28,6 +29,7 @@ touchscreen3: touchscreen@20 {
 		hid-descr-addr = <0x0020>;
 		interrupt-parent = <&pio>;
 		interrupts = <88 IRQ_TYPE_LEVEL_LOW>;
+		status = "fail-needs-probe-touchscreen";
 	};
 };
 
@@ -44,6 +46,7 @@ trackpad2: trackpad@2c {
 		reg = <0x2c>;
 		hid-descr-addr = <0x0020>;
 		wakeup-source;
+		status = "fail-needs-probe-trackpad";
 	};
 };
 
@@ -68,3 +71,11 @@ pins_wp {
 		};
 	};
 };
+
+&touchscreen {
+	status = "fail-needs-probe-touchscreen";
+};
+
+&trackpad {
+	status = "fail-needs-probe-trackpad";
+};
-- 
2.42.0.869.gea05f2083d-goog


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [RFC PATCH v2 4/7] arm64: dts: mediatek: mt8173-elm-hana: Add G2touch G7500 touchscreen
  2023-11-09 10:05 [RFC PATCH v2 0/7] of: Introduce hardware prober driver Chen-Yu Tsai
                   ` (2 preceding siblings ...)
  2023-11-09 10:06 ` [RFC PATCH v2 3/7] arm64: dts: mediatek: mt8173-elm-hana: Mark touchscreens and trackpads as fail Chen-Yu Tsai
@ 2023-11-09 10:06 ` Chen-Yu Tsai
  2023-11-09 10:06 ` [RFC PATCH v2 5/7] of: hw_prober: Support Chromebook SKU ID based component selection Chen-Yu Tsai
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 30+ messages in thread
From: Chen-Yu Tsai @ 2023-11-09 10:06 UTC (permalink / raw)
  To: Rob Herring, Frank Rowand, Krzysztof Kozlowski, Conor Dooley,
	Matthias Brugger, AngeloGioacchino Del Regno
  Cc: Hsin-Yi Wang, Dmitry Torokhov, andriy.shevchenko, Jiri Kosina,
	linus.walleij, broonie, gregkh, hdegoede, james.clark, james,
	keescook, petr.tesarik.ext, rafael, tglx, Jeff LaBundy,
	linux-input, Chen-Yu Tsai, devicetree, linux-arm-kernel,
	linux-mediatek, linux-kernel, Douglas Anderson, Johan Hovold

This introduces yet another second-source touchscreen found on Hana.
This is a G2touch G7500 touchscreen, which is compatible with HID over
I2C.

Add a device node for it. In keeping with the new scheme for second
source components, mark it as "failed-needs-probe-touchscreen".

Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
 arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi b/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi
index 052109b0fa3b..d3f1277ac9b2 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi
@@ -31,6 +31,15 @@ touchscreen3: touchscreen@20 {
 		interrupts = <88 IRQ_TYPE_LEVEL_LOW>;
 		status = "fail-needs-probe-touchscreen";
 	};
+
+	touchscreen4: touchscreen@40 {
+		compatible = "hid-over-i2c";
+		reg = <0x40>;
+		hid-descr-addr = <0x0001>;
+		interrupt-parent = <&pio>;
+		interrupts = <88 IRQ_TYPE_LEVEL_LOW>;
+		status = "fail-needs-probe-touchscreen";
+	};
 };
 
 &i2c4 {
-- 
2.42.0.869.gea05f2083d-goog


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [RFC PATCH v2 5/7] of: hw_prober: Support Chromebook SKU ID based component selection
  2023-11-09 10:05 [RFC PATCH v2 0/7] of: Introduce hardware prober driver Chen-Yu Tsai
                   ` (3 preceding siblings ...)
  2023-11-09 10:06 ` [RFC PATCH v2 4/7] arm64: dts: mediatek: mt8173-elm-hana: Add G2touch G7500 touchscreen Chen-Yu Tsai
@ 2023-11-09 10:06 ` Chen-Yu Tsai
  2023-11-10 21:07   ` Rob Herring
  2023-11-09 10:06 ` [RFC PATCH v2 6/7] dt-bindings: arm: mediatek: Remove SKU specific compatibles for Google Krane Chen-Yu Tsai
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 30+ messages in thread
From: Chen-Yu Tsai @ 2023-11-09 10:06 UTC (permalink / raw)
  To: Rob Herring, Frank Rowand, Krzysztof Kozlowski, Conor Dooley,
	Matthias Brugger, AngeloGioacchino Del Regno
  Cc: Hsin-Yi Wang, Dmitry Torokhov, andriy.shevchenko, Jiri Kosina,
	linus.walleij, broonie, gregkh, hdegoede, james.clark, james,
	keescook, petr.tesarik.ext, rafael, tglx, Jeff LaBundy,
	linux-input, Chen-Yu Tsai, devicetree, linux-arm-kernel,
	linux-mediatek, linux-kernel, Douglas Anderson, Johan Hovold

In cases where the same Chromebook model is manufactured with different
components (MIPI DSI panels, MIPI CSI camera sensors, or trackpad /
touchscreens with conflicting addresses), a different SKU ID is
allocated to each specific combination. This SKU ID is exported by the
bootloader into the device tree, and can be used to "discover" which
combination is present on the current machine.

This change adds a hardware prober that will match the SKU ID against
a provided table, and enable the component for the matched entry based
on the given compatible string. In the MIPI DSI panel and MIPI CSI
camera sensor cases which have OF graphs, it will also update the
remote endpoint to point to the enabled component. This assumes a single
endpoint only.

This will provide a path to reducing the number of Chromebook device
trees.

Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
 drivers/of/hw_prober.c | 160 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 160 insertions(+)

diff --git a/drivers/of/hw_prober.c b/drivers/of/hw_prober.c
index 442da6eff896..4345e5aed6d8 100644
--- a/drivers/of/hw_prober.c
+++ b/drivers/of/hw_prober.c
@@ -8,6 +8,7 @@
 #include <linux/array_size.h>
 #include <linux/i2c.h>
 #include <linux/of.h>
+#include <linux/of_graph.h>
 #include <linux/platform_device.h>
 
 #define DRV_NAME	"hw_prober"
@@ -108,9 +109,168 @@ static int i2c_component_prober(struct platform_device *pdev, const void *data)
 	return ret;
 }
 
+static int cros_get_coreboot_sku_id(struct device *dev, u32 *sku_id)
+{
+	struct device_node *node = NULL;
+	int ret;
+
+	node = of_find_node_by_path("/firmware/coreboot");
+	if (!node)
+		return dev_err_probe(dev, -EINVAL, "Cannot find coreboot firmware node\n");
+
+	ret = of_property_read_u32(node, "sku-id", sku_id);
+	if (ret)
+		dev_err_probe(dev, ret, "Cannot get SKU ID\n");
+
+	of_node_put(node);
+	return ret;
+}
+
+struct cros_sku_option {
+	u32	sku_id_val;
+	u32	sku_id_mask;
+	const char *compatible;
+};
+
+struct cros_sku_component_data {
+	const struct cros_sku_option *options;
+	int num_options;
+};
+
+/*
+ * cros_sku_component_selector - Selectively enable a component based on SKU ID
+ *
+ * Based on the list of component options and SKU ID read back from the device
+ * tree, enable the matching component. Also update the OF graph if it exists,
+ * so that the enabled component's remote endpoint correctly points to it. This
+ * assumes a single local endpoint, which should be the case for panels and
+ * camera sensors.
+ */
+static int cros_sku_component_selector(struct platform_device *pdev, const void *data)
+{
+	const struct cros_sku_component_data *pdata = data;
+	const char *compatible;
+	struct device_node *node = NULL, *endpoint = NULL, *remote = NULL;
+	struct property *status_prop = NULL, *endpoint_prop = NULL;
+	struct of_changeset *ocs = NULL;
+	__be32 *val = NULL;
+	int ret, i;
+	u32 sku_id;
+
+	if (!data)
+		return dev_err_probe(&pdev->dev, -EINVAL, "No data given\n");
+
+	ret = cros_get_coreboot_sku_id(&pdev->dev, &sku_id);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < pdata->num_options; i++)
+		if ((sku_id & pdata->options[i].sku_id_mask) == pdata->options[i].sku_id_val) {
+			compatible = pdata->options->compatible;
+			break;
+		}
+
+	if (i == pdata->num_options)
+		return dev_err_probe(&pdev->dev, -EINVAL, "Unknown SKU ID: 0x%x\n", sku_id);
+
+	node = of_find_compatible_node(NULL, NULL, compatible);
+	if (!node)
+		return dev_err_probe(&pdev->dev, -ENODEV, "Cannot find matching device node\n");
+
+	/* device node not marked as fail; don't mess with the device tree */
+	if (!of_device_is_fail(node))
+		goto err_free;
+
+	dev_info(&pdev->dev, "Enabling %pOF for SKU 0x%x\n", node, sku_id);
+
+	ret = -ENOMEM;
+	ocs = kzalloc(sizeof(*ocs), GFP_KERNEL);
+	if (!ocs)
+		goto err_free;
+
+	status_prop = kzalloc(sizeof(*status_prop), GFP_KERNEL);
+	if (!status_prop)
+		goto err_free;
+
+	status_prop->name   = "status";
+	status_prop->length = 5;
+	status_prop->value  = "okay";
+
+	/* Create changeset to apply DT changes atomically */
+	of_changeset_init(ocs);
+
+	if (of_graph_is_present(node)) {
+		ret = -EINVAL;
+
+		/* This currently assumes a single port on the component. */
+		endpoint = of_graph_get_next_endpoint(node, NULL);
+		if (!endpoint) {
+			dev_err(&pdev->dev, "No endpoint found for %pOF\n", node);
+			goto err_destroy_ocs;
+		}
+
+		remote = of_graph_get_remote_endpoint(endpoint);
+		if (!remote) {
+			dev_err(&pdev->dev, "No remote endpoint node found for %pOF\n", endpoint);
+			goto err_destroy_ocs;
+		}
+
+		endpoint_prop = kzalloc(sizeof(*endpoint_prop), GFP_KERNEL);
+		if (!endpoint_prop)
+			goto err_destroy_ocs;
+
+		val = kzalloc(sizeof(*val), GFP_KERNEL);
+		if (!val)
+			goto err_destroy_ocs;
+
+		*val = cpu_to_be32(endpoint->phandle);
+		endpoint_prop->name   = "remote-endpoint";
+		endpoint_prop->length = sizeof(*val);
+		endpoint_prop->value  = val;
+
+		ret = of_changeset_update_property(ocs, node, endpoint_prop);
+		if (ret)
+			goto err_destroy_ocs;
+	}
+
+	ret = of_changeset_update_property(ocs, node, status_prop);
+	if (ret)
+		goto err_destroy_ocs;
+	ret = of_changeset_apply(ocs);
+	if (ret)
+		goto err_destroy_ocs;
+
+	of_node_put(node);
+
+	return 0;
+
+err_destroy_ocs:
+	of_node_put(remote);
+	of_node_put(endpoint);
+	kfree(val);
+	kfree(endpoint_prop);
+	of_changeset_destroy(ocs);
+err_free:
+	kfree(ocs);
+	kfree(status_prop);
+	of_node_put(node);
+	return ret;
+}
+
+static const struct cros_sku_option cros_krane_panel_options[] = {
+	{ .sku_id_val = 0x00, .sku_id_mask = 0xf0, .compatible = "auo,kd101n80-45na" },
+	{ .sku_id_val = 0xb0, .sku_id_mask = 0xf0, .compatible = "boe,tv101wum-nl6" },
+};
+
+static const struct cros_sku_component_data cros_krane_panel_data = {
+	.options     = cros_krane_panel_options,
+	.num_options = ARRAY_SIZE(cros_krane_panel_options),
+};
+
 static const struct hw_prober_entry hw_prober_platforms[] = {
 	{ .compatible = "google,hana", .prober = i2c_component_prober, .data = "touchscreen" },
 	{ .compatible = "google,hana", .prober = i2c_component_prober, .data = "trackpad" },
+	{ .compatible = "google,krane", .prober = cros_sku_component_selector, .data = &cros_krane_panel_data },
 };
 
 static int hw_prober_probe(struct platform_device *pdev)
-- 
2.42.0.869.gea05f2083d-goog


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [RFC PATCH v2 6/7] dt-bindings: arm: mediatek: Remove SKU specific compatibles for Google Krane
  2023-11-09 10:05 [RFC PATCH v2 0/7] of: Introduce hardware prober driver Chen-Yu Tsai
                   ` (4 preceding siblings ...)
  2023-11-09 10:06 ` [RFC PATCH v2 5/7] of: hw_prober: Support Chromebook SKU ID based component selection Chen-Yu Tsai
@ 2023-11-09 10:06 ` Chen-Yu Tsai
  2023-11-10 21:04   ` Rob Herring
  2023-11-09 10:06 ` [RFC PATCH v2 7/7] arm64: dts: mediatek: mt8183-kukui: Merge Krane device trees Chen-Yu Tsai
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 30+ messages in thread
From: Chen-Yu Tsai @ 2023-11-09 10:06 UTC (permalink / raw)
  To: Rob Herring, Frank Rowand, Krzysztof Kozlowski, Conor Dooley,
	Matthias Brugger, AngeloGioacchino Del Regno
  Cc: Hsin-Yi Wang, Dmitry Torokhov, andriy.shevchenko, Jiri Kosina,
	linus.walleij, broonie, gregkh, hdegoede, james.clark, james,
	keescook, petr.tesarik.ext, rafael, tglx, Jeff LaBundy,
	linux-input, Chen-Yu Tsai, devicetree, linux-arm-kernel,
	linux-mediatek, linux-kernel, Douglas Anderson, Johan Hovold

In cases where the same Chromebook model is manufactured with different
components (MIPI DSI panels, MIPI CSI camera sensors, or trackpad /
touchscreens with conflicting addresses), a different SKU ID is
allocated to each specific combination. This SKU ID is exported by the
bootloader into the device tree, and can be used to "discover" which
combination is present on the current machine. Thus we no longer have
to specify separate compatible strings for each of them.

Remove the SKU specific compatible strings for Google Krane.

Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
 Documentation/devicetree/bindings/arm/mediatek.yaml | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/mediatek.yaml b/Documentation/devicetree/bindings/arm/mediatek.yaml
index a4541855a838..ef3dfb286814 100644
--- a/Documentation/devicetree/bindings/arm/mediatek.yaml
+++ b/Documentation/devicetree/bindings/arm/mediatek.yaml
@@ -186,9 +186,6 @@ properties:
           - const: mediatek,mt8183
       - description: Google Krane (Lenovo IdeaPad Duet, 10e,...)
         items:
-          - enum:
-              - google,krane-sku0
-              - google,krane-sku176
           - const: google,krane
           - const: mediatek,mt8183
       - description: Google Willow (Acer Chromebook 311 C722/C722T)
-- 
2.42.0.869.gea05f2083d-goog


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [RFC PATCH v2 7/7] arm64: dts: mediatek: mt8183-kukui: Merge Krane device trees
  2023-11-09 10:05 [RFC PATCH v2 0/7] of: Introduce hardware prober driver Chen-Yu Tsai
                   ` (5 preceding siblings ...)
  2023-11-09 10:06 ` [RFC PATCH v2 6/7] dt-bindings: arm: mediatek: Remove SKU specific compatibles for Google Krane Chen-Yu Tsai
@ 2023-11-09 10:06 ` Chen-Yu Tsai
  2023-11-09 10:54 ` [RFC PATCH v2 0/7] of: Introduce hardware prober driver AngeloGioacchino Del Regno
  2023-11-11  0:22 ` Doug Anderson
  8 siblings, 0 replies; 30+ messages in thread
From: Chen-Yu Tsai @ 2023-11-09 10:06 UTC (permalink / raw)
  To: Rob Herring, Frank Rowand, Krzysztof Kozlowski, Conor Dooley,
	Matthias Brugger, AngeloGioacchino Del Regno
  Cc: Hsin-Yi Wang, Dmitry Torokhov, andriy.shevchenko, Jiri Kosina,
	linus.walleij, broonie, gregkh, hdegoede, james.clark, james,
	keescook, petr.tesarik.ext, rafael, tglx, Jeff LaBundy,
	linux-input, Chen-Yu Tsai, devicetree, linux-arm-kernel,
	linux-mediatek, linux-kernel, Douglas Anderson, Johan Hovold

In cases where the same Chromebook model is manufactured with different
components (MIPI DSI panels, MIPI CSI camera sensors, or trackpad /
touchscreens with conflicting addresses), a different SKU ID is
allocated to each specific combination. This SKU ID is exported by the
bootloader into the device tree, and can be used to "discover" which
combination is present on the current machine.

Merge the separate Krane dtsi/dts files into one shared for all SKUs.
A new device node is added for the alternative panel. Both it and the
original panel are marked as "fail-needs-probe-panel" to let the
hardware prober handle it.

Also move the cros_ec node so that all node references are ordered
alphabetically.

Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
 arch/arm64/boot/dts/mediatek/Makefile         |  3 +-
 .../dts/mediatek/mt8183-kukui-krane-sku0.dts  | 24 ----------
 .../mediatek/mt8183-kukui-krane-sku176.dts    | 24 ----------
 ...ukui-krane.dtsi => mt8183-kukui-krane.dts} | 47 +++++++++++++++++--
 4 files changed, 44 insertions(+), 54 deletions(-)
 delete mode 100644 arch/arm64/boot/dts/mediatek/mt8183-kukui-krane-sku0.dts
 delete mode 100644 arch/arm64/boot/dts/mediatek/mt8183-kukui-krane-sku176.dts
 rename arch/arm64/boot/dts/mediatek/{mt8183-kukui-krane.dtsi => mt8183-kukui-krane.dts} (86%)

diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
index 7e365e9516ab..d4d97b315b2f 100644
--- a/arch/arm64/boot/dts/mediatek/Makefile
+++ b/arch/arm64/boot/dts/mediatek/Makefile
@@ -40,8 +40,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kodama-sku16.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kodama-sku272.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kodama-sku288.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kodama-sku32.dtb
-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku0.dtb
-dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku176.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-pumpkin.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393216.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-corsola-magneton-sku393217.dtb
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane-sku0.dts b/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane-sku0.dts
deleted file mode 100644
index 4ac75806fa94..000000000000
--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane-sku0.dts
+++ /dev/null
@@ -1,24 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-/*
- * Copyright 2019 Google LLC
- *
- * Device-tree for Krane sku0.
- *
- * SKU is a 8-bit value (0x00 == 0):
- *  - Bits 7..4: Panel ID: 0x0 (AUO)
- *  - Bits 3..0: SKU ID:   0x0 (default)
- */
-
-/dts-v1/;
-#include "mt8183-kukui-krane.dtsi"
-
-/ {
-	model = "MediaTek krane sku0 board";
-	chassis-type = "tablet";
-	compatible = "google,krane-sku0", "google,krane", "mediatek,mt8183";
-};
-
-&panel {
-	status = "okay";
-	compatible = "auo,kd101n80-45na";
-};
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane-sku176.dts b/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane-sku176.dts
deleted file mode 100644
index 095279e55d50..000000000000
--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane-sku176.dts
+++ /dev/null
@@ -1,24 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-/*
- * Copyright 2019 Google LLC
- *
- * Device-tree for Krane sku176.
- *
- * SKU is a 8-bit value (0xb0 == 176):
- *  - Bits 7..4: Panel ID: 0xb (BOE)
- *  - Bits 3..0: SKU ID:   0x0 (default)
- */
-
-/dts-v1/;
-#include "mt8183-kukui-krane.dtsi"
-
-/ {
-	model = "MediaTek krane sku176 board";
-	chassis-type = "tablet";
-	compatible = "google,krane-sku176", "google,krane", "mediatek,mt8183";
-};
-
-&panel {
-        status = "okay";
-        compatible = "boe,tv101wum-nl6";
-};
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dts
similarity index 86%
rename from arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi
rename to arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dts
index d5f41c6c9881..75a734c0fbcc 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dts
@@ -1,12 +1,24 @@
 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
 /*
  * Copyright 2019 Google LLC
+ *
+ * Device tree for Krane Chromebook family.
+ *
+ * SKU ID is a 8-bit value (0x00 == 0):
+ *  - Bits 7..4: Panel ID: 0x0 (AUO)
+ *                         0xb (BOE)
+ *  - Bits 3..0: SKU ID:   0x0 (default)
  */
 
+/dts-v1/;
 #include "mt8183-kukui.dtsi"
 #include "mt8183-kukui-audio-max98357a.dtsi"
 
 / {
+	model = "Google Krane Chromebook";
+	chassis-type = "tablet";
+	compatible = "google,krane", "mediatek,mt8183";
+
 	ppvarn_lcd: ppvarn-lcd {
 		compatible = "regulator-fixed";
 		regulator-name = "ppvarn_lcd";
@@ -45,6 +57,34 @@ &bluetooth {
 	firmware-name = "nvm_00440302_i2s_eu.bin";
 };
 
+&cros_ec {
+	keyboard-controller {
+		compatible = "google,cros-ec-keyb-switches";
+	};
+};
+
+&dsi0 {
+	panel2@0 {
+		compatible = "boe,tv101wum-nl6";
+		reg = <0>;
+		enable-gpios = <&pio 45 0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&panel_pins_default>;
+		avdd-supply = <&ppvarn_lcd>;
+		avee-supply = <&ppvarp_lcd>;
+		pp1800-supply = <&pp1800_lcd>;
+		backlight = <&backlight_lcd0>;
+		rotation = <270>;
+		status = "fail-needs-probe-panel";
+
+		port {
+			endpoint {
+				remote-endpoint = <&dsi_out>;
+			};
+		};
+	};
+};
+
 &i2c0 {
 	status = "okay";
 
@@ -343,10 +383,9 @@ rst_pin {
 	};
 };
 
-&cros_ec {
-	keyboard-controller {
-		compatible = "google,cros-ec-keyb-switches";
-	};
+&panel {
+	compatible = "auo,kd101n80-45na";
+	status = "fail-needs-probe-panel";
 };
 
 &qca_wifi {
-- 
2.42.0.869.gea05f2083d-goog


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH v2 0/7] of: Introduce hardware prober driver
  2023-11-09 10:05 [RFC PATCH v2 0/7] of: Introduce hardware prober driver Chen-Yu Tsai
                   ` (6 preceding siblings ...)
  2023-11-09 10:06 ` [RFC PATCH v2 7/7] arm64: dts: mediatek: mt8183-kukui: Merge Krane device trees Chen-Yu Tsai
@ 2023-11-09 10:54 ` AngeloGioacchino Del Regno
  2023-11-09 13:51   ` Rob Herring
  2023-11-14  8:57   ` Chen-Yu Tsai
  2023-11-11  0:22 ` Doug Anderson
  8 siblings, 2 replies; 30+ messages in thread
From: AngeloGioacchino Del Regno @ 2023-11-09 10:54 UTC (permalink / raw)
  To: Chen-Yu Tsai, Rob Herring, Frank Rowand, Krzysztof Kozlowski,
	Conor Dooley, Matthias Brugger
  Cc: Hsin-Yi Wang, Dmitry Torokhov, andriy.shevchenko, Jiri Kosina,
	linus.walleij, broonie, gregkh, hdegoede, james.clark, james,
	keescook, petr.tesarik.ext, rafael, tglx, Jeff LaBundy,
	linux-input, devicetree, linux-arm-kernel, linux-mediatek,
	linux-kernel, Douglas Anderson, Johan Hovold

Il 09/11/23 11:05, Chen-Yu Tsai ha scritto:
> Hi everyone,
> 
> This v2 series continues Doug's "of: device: Support 2nd sources of
> probeable but undiscoverable devices" [1] series, but follows the scheme
> suggested by Rob, marking all second source component device nodes
> as "fail-needs-probe-XXX", and having a hardware prober driver enable
> the one of them. I tried to include everyone from the original Cc: list.
> Please let me know if you would like to be dropped from future
> submissions.
> 
> 
> For the I2C component (touchscreens and trackpads) case from the
> original series, the hardware prober driver finds the particular
> class of device in the device tree, gets its parent I2C adapter,
> and tries to initiate a simple I2C read for each device under that
> I2C bus. When it finds one that responds, it considers that one
> present, marks it as "okay", and returns, letting the driver core
> actually probe the device.
> 
> This works fine in most cases since these components are connected
> via ribbon cable and always have the same resources. The driver as
> implemented currently doesn't deal with regulators or GPIO pins,
> since in the existing device trees they are either always on for
> regulators, or have GPIO hogs or pinmux and pinconfig directly
> tied to the pin controller.
> 
> 
> Another case this driver could handle is selecting components based
> on some identifier passed in by the firmware. On Chromebooks we have
> a SKU ID which is inserted by the bootloader at
> /firmware/coreboot/sku-id. When a new combination of components is
> introduced, a new SKU ID is allocated to it. To have SKU ID based
> device trees, we would need to have one per SKU ID. This ends up
> increasing the number of device trees we have a lot. The recent
> MT8186 devices already have 10+10 SKUs [2], with possibly more to come.
> 
> Instead, we could have just one device tree for each device, with
> component options listed and marked as "fail-needs-probe-XXX", and
> let the hardware prober enable one of them based on the given SKU ID.
> The driver will also fix up OF graph remote endpoints to point to the
> enabled component.
> 
> The MT8186 Corsola series [2] can also benefit from this, though I
> haven't implemented anything yet.
> 
> 
> Patch 1 adds of_device_is_fail() for the new driver to use.
> 
> Patch 2 implements the first case, probing the I2C bus for presence
> of components. This initial version targets the Hana Chromebooks.
> 
> Patch 3 modifies the Hana device tree and marks the touchscreens
> and trackpads as "fail-needs-probe-XXX", ready for the driver to
> probe.
> 
> Patch 4 adds a missing touchscreen variant to Hana.
> 
> Patch 5 implements the second case, selectively enabling components
> based on the SKU ID. This initial version targets the Krane ChromeOS
> tablet, which has two possible MIPI DSI display panel options.
> 
> Patch 6 drops Krane's SKU-specific compatible strings from the bindings.
> 
> Patch 7 merges Krane's SKU-specific device trees into one, with the
> device tree now containing two possible panels. This unfortunately
> introduces a dtc warning:
> 
>      arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dts:81.13-83.6:
>          Warning (graph_endpoint): /soc/dsi@14014000/panel2@0/port/endpoint:
> 	graph connection to node '/soc/dsi@14014000/ports/port/endpoint'
> 	    is not bidirectional
> 
> 
> Please take a look.
> 
> Johan, I'm not sure if this works as is for the Lenovo Thinkpad 13S
> case, since it looks like the trackpad shares the I2C bus with the
> keyboard.
> 
> 
> Thanks
> ChenYu
> 
> 
> Background as given in Doug's cover letter:
> 
> Support for multiple "equivalent" sources for components (also known
> as second sourcing components) is a standard practice that helps keep
> cost down and also makes sure that if one component is unavailable due
> to a shortage that we don't need to stop production for the whole
> product.
> 
> Some components are very easy to second source. eMMC, for instance, is
> fully discoverable and probable so you can stuff a wide variety of
> similar eMMC chips on your board and things will work without a hitch.
> 
> Some components are more difficult to second source, specifically
> because it's difficult for software to probe what component is present
> on any given board. In cases like this software is provided
> supplementary information to help it, like a GPIO strap or a SKU ID
> programmed into an EEPROM. This helpful information can allow the
> bootloader to select a different device tree. The various different
> "SKUs" of different Chromebooks are examples of this.
> 
> Some components are somewhere in between. These in-between components
> are the subject of this patch. Specifically, these components are
> easily "probeable" but not easily "discoverable".
> 
> A good example of a probeable but undiscoverable device is an
> i2c-connected touchscreen or trackpad. Two separate components may be
> electrically compatible with each other and may have compatible power
> sequencing requirements but may require different software. If
> software is told about the different possible components (because it
> can't discover them), it can safely probe them to figure out which
> ones are present.
> 
> On systems using device tree, if we want to tell the OS about all of
> the different components we need to list them all in the device
> tree. This leads to a problem. The multiple sources for components
> likely use the same resources (GPIOs, interrupts, regulators). If the
> OS tries to probe all of these components at the same time then it
> will detect a resource conflict and that's a fatal error.
> 
> The fact that Linux can't handle these probeable but undiscoverable
> devices well has had a few consequences:
> 1. In some cases, we've abandoned the idea of second sourcing
>     components for a given board, which increases cost / generates
>     manufacturing headaches.
> 2. In some cases, we've been forced to add some sort of strapping /
>     EEPROM to indicate which component is present. This adds difficulty
>     to manufacturing / refurb processes.
> 3. In some cases, we've managed to make things work by the skin of our
>     teeth through slightly hacky solutions. Specifically, if we remove
>     the "pinctrl" entry from the various options then it won't
>     conflict. Regulators inherently can have more than one consumer, so
>     as long as there are no GPIOs involved in power sequencing and
>     probing devices then things can work. This is how
>     "sc8280xp-lenovo-thinkpad-x13s" works and also how
>     "mt8173-elm-hana" works.
> 
> End of background from Doug's cover letter.

I think that using "status" is not a good idea, I find that confusing.

Perhaps we could have a node like

something {
	device-class-one = <&device1>, <&device2>, <&device3>;
	device-class-two = <&device4>, <&device5>, <&device6>;
}

so that'd be more or less

hw-prober {
	trackpads = <&tp1>, <&tp2>;
	keyboards = <&kb1>, <&kb2>;
	touchscreens = <&ts1>, <&ts2>;
}

Besides, something else I can suggest here is to make this more generic: actually,
this issue is spread across way more devices than you maybe think... for example,
I know of some smartphones that may have the same situation with DSI displays and
they're sometimes distinguished by an ADC value, sometimes by reading back the
manufacturer ID (or panel id) through DSI.

Also, if Chromebooks really need something "special", such as that coreboot sku-id
parameter, I think that this should be registered externally into the hw prober
and not embedded inside of the *generic* hw prober driver.

We can even reuse of_device_id instead of inventing a new hw_prober_entry struct...

Idea:

drivers/platform/chrome/cros_of_hw_prober.c

static int cros_sku_hw_prober(struct platform_device *pdev, const void *data)
{
	...this is your cros_sku_component_selector() function, anyway...
}

static const struct of_device_id cros_hw_prober_ids[] = {
	{ .compatible = "google,hana", .data = something },
	{ /* sentinel */ }
};

static int some_kind_of_early_init_function(something)
{
	int a,b,c,ret,something;

	.. some logic if necessary ..

	return of_hw_prober_register(cros_sku_hw_prober, cros_hw_prober_ids);
}


Btw, thanks for starting that. If this will be done the right way, it's going to
be useful to many, many people.

Regards,
Angelo	

> 
> [1] https://lore.kernel.org/all/20230921102420.RFC.1.I9dddd99ccdca175e3ceb1b9fa1827df0928c5101@changeid/
> [2] https://lore.kernel.org/linux-mediatek/20231012230237.2676469-1-wenst@chromium.org/
> 
> Chen-Yu Tsai (7):
>    of: base: Add of_device_is_fail
>    of: Introduce hardware prober driver
>    arm64: dts: mediatek: mt8173-elm-hana: Mark touchscreens and trackpads
>      as fail
>    arm64: dts: mediatek: mt8173-elm-hana: Add G2touch G7500 touchscreen
>    of: hw_prober: Support Chromebook SKU ID based component selection
>    dt-bindings: arm: mediatek: Remove SKU specific compatibles for Google
>      Krane
>    arm64: dts: mediatek: mt8183-kukui: Merge Krane device trees
> 
>   .../devicetree/bindings/arm/mediatek.yaml     |   3 -
>   arch/arm64/boot/dts/mediatek/Makefile         |   3 +-
>   .../boot/dts/mediatek/mt8173-elm-hana.dtsi    |  20 ++
>   .../dts/mediatek/mt8183-kukui-krane-sku0.dts  |  24 --
>   .../mediatek/mt8183-kukui-krane-sku176.dts    |  24 --
>   ...ukui-krane.dtsi => mt8183-kukui-krane.dts} |  47 ++-
>   drivers/of/Kconfig                            |  13 +
>   drivers/of/Makefile                           |   1 +
>   drivers/of/base.c                             |  20 ++
>   drivers/of/hw_prober.c                        | 314 ++++++++++++++++++
>   include/linux/of.h                            |   6 +
>   11 files changed, 418 insertions(+), 57 deletions(-)
>   delete mode 100644 arch/arm64/boot/dts/mediatek/mt8183-kukui-krane-sku0.dts
>   delete mode 100644 arch/arm64/boot/dts/mediatek/mt8183-kukui-krane-sku176.dts
>   rename arch/arm64/boot/dts/mediatek/{mt8183-kukui-krane.dtsi => mt8183-kukui-krane.dts} (86%)
>   create mode 100644 drivers/of/hw_prober.c
> 


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH v2 0/7] of: Introduce hardware prober driver
  2023-11-09 10:54 ` [RFC PATCH v2 0/7] of: Introduce hardware prober driver AngeloGioacchino Del Regno
@ 2023-11-09 13:51   ` Rob Herring
  2023-11-11  0:12     ` Doug Anderson
  2023-11-14  7:05     ` Chen-Yu Tsai
  2023-11-14  8:57   ` Chen-Yu Tsai
  1 sibling, 2 replies; 30+ messages in thread
From: Rob Herring @ 2023-11-09 13:51 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno
  Cc: Chen-Yu Tsai, Frank Rowand, Krzysztof Kozlowski, Conor Dooley,
	Matthias Brugger, Hsin-Yi Wang, Dmitry Torokhov,
	andriy.shevchenko, Jiri Kosina, linus.walleij, broonie, gregkh,
	hdegoede, james.clark, james, keescook, petr.tesarik.ext, rafael,
	tglx, Jeff LaBundy, linux-input, devicetree, linux-arm-kernel,
	linux-mediatek, linux-kernel, Douglas Anderson, Johan Hovold

On Thu, Nov 9, 2023 at 4:54 AM AngeloGioacchino Del Regno
<angelogioacchino.delregno@collabora.com> wrote:
>
> Il 09/11/23 11:05, Chen-Yu Tsai ha scritto:
> > Hi everyone,
> >
> > This v2 series continues Doug's "of: device: Support 2nd sources of
> > probeable but undiscoverable devices" [1] series, but follows the scheme
> > suggested by Rob, marking all second source component device nodes
> > as "fail-needs-probe-XXX", and having a hardware prober driver enable
> > the one of them. I tried to include everyone from the original Cc: list.
> > Please let me know if you would like to be dropped from future
> > submissions.
> >
> >
> > For the I2C component (touchscreens and trackpads) case from the
> > original series, the hardware prober driver finds the particular
> > class of device in the device tree, gets its parent I2C adapter,
> > and tries to initiate a simple I2C read for each device under that
> > I2C bus. When it finds one that responds, it considers that one
> > present, marks it as "okay", and returns, letting the driver core
> > actually probe the device.
> >
> > This works fine in most cases since these components are connected
> > via ribbon cable and always have the same resources. The driver as
> > implemented currently doesn't deal with regulators or GPIO pins,
> > since in the existing device trees they are either always on for
> > regulators, or have GPIO hogs or pinmux and pinconfig directly
> > tied to the pin controller.
> >
> >
> > Another case this driver could handle is selecting components based
> > on some identifier passed in by the firmware. On Chromebooks we have
> > a SKU ID which is inserted by the bootloader at
> > /firmware/coreboot/sku-id. When a new combination of components is
> > introduced, a new SKU ID is allocated to it. To have SKU ID based
> > device trees, we would need to have one per SKU ID. This ends up
> > increasing the number of device trees we have a lot. The recent
> > MT8186 devices already have 10+10 SKUs [2], with possibly more to come.
> >
> > Instead, we could have just one device tree for each device, with
> > component options listed and marked as "fail-needs-probe-XXX", and
> > let the hardware prober enable one of them based on the given SKU ID.
> > The driver will also fix up OF graph remote endpoints to point to the
> > enabled component.
> >
> > The MT8186 Corsola series [2] can also benefit from this, though I
> > haven't implemented anything yet.
> >
> >
> > Patch 1 adds of_device_is_fail() for the new driver to use.
> >
> > Patch 2 implements the first case, probing the I2C bus for presence
> > of components. This initial version targets the Hana Chromebooks.
> >
> > Patch 3 modifies the Hana device tree and marks the touchscreens
> > and trackpads as "fail-needs-probe-XXX", ready for the driver to
> > probe.
> >
> > Patch 4 adds a missing touchscreen variant to Hana.
> >
> > Patch 5 implements the second case, selectively enabling components
> > based on the SKU ID. This initial version targets the Krane ChromeOS
> > tablet, which has two possible MIPI DSI display panel options.
> >
> > Patch 6 drops Krane's SKU-specific compatible strings from the bindings.
> >
> > Patch 7 merges Krane's SKU-specific device trees into one, with the
> > device tree now containing two possible panels. This unfortunately
> > introduces a dtc warning:
> >
> >      arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dts:81.13-83.6:
> >          Warning (graph_endpoint): /soc/dsi@14014000/panel2@0/port/endpoint:
> >       graph connection to node '/soc/dsi@14014000/ports/port/endpoint'
> >           is not bidirectional
> >
> >
> > Please take a look.
> >
> > Johan, I'm not sure if this works as is for the Lenovo Thinkpad 13S
> > case, since it looks like the trackpad shares the I2C bus with the
> > keyboard.
> >
> >
> > Thanks
> > ChenYu
> >
> >
> > Background as given in Doug's cover letter:
> >
> > Support for multiple "equivalent" sources for components (also known
> > as second sourcing components) is a standard practice that helps keep
> > cost down and also makes sure that if one component is unavailable due
> > to a shortage that we don't need to stop production for the whole
> > product.
> >
> > Some components are very easy to second source. eMMC, for instance, is
> > fully discoverable and probable so you can stuff a wide variety of
> > similar eMMC chips on your board and things will work without a hitch.
> >
> > Some components are more difficult to second source, specifically
> > because it's difficult for software to probe what component is present
> > on any given board. In cases like this software is provided
> > supplementary information to help it, like a GPIO strap or a SKU ID
> > programmed into an EEPROM. This helpful information can allow the
> > bootloader to select a different device tree. The various different
> > "SKUs" of different Chromebooks are examples of this.
> >
> > Some components are somewhere in between. These in-between components
> > are the subject of this patch. Specifically, these components are
> > easily "probeable" but not easily "discoverable".
> >
> > A good example of a probeable but undiscoverable device is an
> > i2c-connected touchscreen or trackpad. Two separate components may be
> > electrically compatible with each other and may have compatible power
> > sequencing requirements but may require different software. If
> > software is told about the different possible components (because it
> > can't discover them), it can safely probe them to figure out which
> > ones are present.
> >
> > On systems using device tree, if we want to tell the OS about all of
> > the different components we need to list them all in the device
> > tree. This leads to a problem. The multiple sources for components
> > likely use the same resources (GPIOs, interrupts, regulators). If the
> > OS tries to probe all of these components at the same time then it
> > will detect a resource conflict and that's a fatal error.
> >
> > The fact that Linux can't handle these probeable but undiscoverable
> > devices well has had a few consequences:
> > 1. In some cases, we've abandoned the idea of second sourcing
> >     components for a given board, which increases cost / generates
> >     manufacturing headaches.
> > 2. In some cases, we've been forced to add some sort of strapping /
> >     EEPROM to indicate which component is present. This adds difficulty
> >     to manufacturing / refurb processes.
> > 3. In some cases, we've managed to make things work by the skin of our
> >     teeth through slightly hacky solutions. Specifically, if we remove
> >     the "pinctrl" entry from the various options then it won't
> >     conflict. Regulators inherently can have more than one consumer, so
> >     as long as there are no GPIOs involved in power sequencing and
> >     probing devices then things can work. This is how
> >     "sc8280xp-lenovo-thinkpad-x13s" works and also how
> >     "mt8173-elm-hana" works.
> >
> > End of background from Doug's cover letter.
>
> I think that using "status" is not a good idea, I find that confusing.

"status" is what defines a device's state in terms of enabled,
present, available. That's exactly what we're expressing here.

Now, I do not think we should be mixing the device class (e.g.
touchscreen) into status. I said this on v1, but apparently that was
not listened to.

>
> Perhaps we could have a node like
>
> something {
>         device-class-one = <&device1>, <&device2>, <&device3>;
>         device-class-two = <&device4>, <&device5>, <&device6>;
> }
>
> so that'd be more or less
>
> hw-prober {
>         trackpads = <&tp1>, <&tp2>;
>         keyboards = <&kb1>, <&kb2>;
>         touchscreens = <&ts1>, <&ts2>;
> }

No. That's more or less what v1 had.

Rob

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH v2 2/7] of: Introduce hardware prober driver
  2023-11-09 10:05 ` [RFC PATCH v2 2/7] of: Introduce hardware prober driver Chen-Yu Tsai
@ 2023-11-09 15:13   ` Rob Herring
  2023-11-14  8:30     ` Chen-Yu Tsai
  2023-11-09 17:54   ` Andy Shevchenko
  1 sibling, 1 reply; 30+ messages in thread
From: Rob Herring @ 2023-11-09 15:13 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Frank Rowand, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Hsin-Yi Wang, Dmitry Torokhov,
	andriy.shevchenko, Jiri Kosina, linus.walleij, broonie, gregkh,
	hdegoede, james.clark, james, keescook, rafael, tglx,
	Jeff LaBundy, linux-input, devicetree, linux-arm-kernel,
	linux-mediatek, linux-kernel, Douglas Anderson, Johan Hovold

On Thu, Nov 9, 2023 at 4:06 AM Chen-Yu Tsai <wenst@chromium.org> wrote:
>
> Some devices are designed and manufactured with some components having
> multiple drop-in replacement options. These components are often
> connected to the mainboard via ribbon cables, having the same signals
> and pin assignments across all options. These may include the display
> panel and touchscreen on laptops and tablets, and the trackpad on
> laptops. Sometimes which component option is used in a particular device
> can be detected by some firmware provided identifier, other times that
> information is not available, and the kernel has to try to probe each
> device.
>
> This change attempts to make the "probe each device" case cleaner. The
> current approach is to have all options added and enabled in the device
> tree. The kernel would then bind each device and run each driver's probe
> function. This works, but has been broken before due to the introduction
> of asynchronous probing, causing multiple instances requesting "shared"
> resources, such as pinmuxes, GPIO pins, interrupt lines, at the same
> time, with only one instance succeeding. Work arounds for these include
> moving the pinmux to the parent I2C controller, using GPIO hogs or
> pinmux settings to keep the GPIO pins in some fixed configuration, and
> requesting the interrupt line very late. Such configurations can be seen
> on the MT8183 Krane Chromebook tablets, and the Qualcomm sc8280xp-based
> Lenovo Thinkpad 13S.
>
> Instead of this delicate dance between drivers and device tree quirks,
> this change introduces a simple I2C component prober. For any given
> class of devices on the same I2C bus, it will go through all of them,
> doing a simple I2C read transfer and see which one of them responds.
> It will then enable the device that responds.
>
> This requires some minor modifications in the existing device tree.
> The status for all the device nodes for the component options must be
> set to "failed-needs-probe-xxx". This makes it clear that some mechanism
> is needed to enable one of them, and also prevents the prober and device
> drivers running at the same time.
>
> Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
> ---
>  drivers/of/Kconfig     |  13 ++++
>  drivers/of/Makefile    |   1 +
>  drivers/of/hw_prober.c | 154 +++++++++++++++++++++++++++++++++++++++++

Not sure about having this in drivers/of/, but fine for now... Really,
the I2C bus stuff should be in the I2C core with the rest of the code
that knows how to parse I2C bus nodes.

>  3 files changed, 168 insertions(+)
>  create mode 100644 drivers/of/hw_prober.c
>
> diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
> index da9826accb1b..269d20d51936 100644
> --- a/drivers/of/Kconfig
> +++ b/drivers/of/Kconfig
> @@ -102,4 +102,17 @@ config OF_OVERLAY
>  config OF_NUMA
>         bool
>
> +config HW_PROBER
> +       bool "Hardware Prober driver"
> +       select I2C

You should not select I2C, but enable/disable I2C functionality based
on it being enabled.

> +       select OF_DYNAMIC
> +       help
> +         Some devices will have multiple drop-in options for one component.
> +         In many cases the different options are indistinguishable by the
> +         kernel without actually probing each possible option.
> +
> +         This driver is meant to handle the probing of such components, and
> +         update the running device tree such that the correct variant is
> +         made available.
> +
>  endif # OF
> diff --git a/drivers/of/Makefile b/drivers/of/Makefile
> index eff624854575..ed3875cdc554 100644
> --- a/drivers/of/Makefile
> +++ b/drivers/of/Makefile
> @@ -12,6 +12,7 @@ obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
>  obj-$(CONFIG_OF_RESOLVE)  += resolver.o
>  obj-$(CONFIG_OF_OVERLAY) += overlay.o
>  obj-$(CONFIG_OF_NUMA) += of_numa.o
> +obj-$(CONFIG_HW_PROBER) += hw_prober.o
>
>  ifdef CONFIG_KEXEC_FILE
>  ifdef CONFIG_OF_FLATTREE
> diff --git a/drivers/of/hw_prober.c b/drivers/of/hw_prober.c
> new file mode 100644
> index 000000000000..442da6eff896
> --- /dev/null
> +++ b/drivers/of/hw_prober.c
> @@ -0,0 +1,154 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * hw_prober.c - Hardware prober driver
> + *
> + * Copyright (c) 2023 Google LLC
> + */
> +
> +#include <linux/array_size.h>
> +#include <linux/i2c.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +
> +#define DRV_NAME       "hw_prober"
> +
> +/**
> + * struct hw_prober_entry - Holds an entry for the hardware prober
> + *
> + * @compatible:        compatible string to match against the machine
> + * @prober:    prober function to call when machine matches
> + * @data:      extra data for the prober function
> + */
> +struct hw_prober_entry {
> +       const char *compatible;
> +       int (*prober)(struct platform_device *pdev, const void *data);
> +       const void *data;
> +};
> +
> +/*
> + * Some devices, such as Google Hana Chromebooks, are produced by multiple
> + * vendors each using their preferred components. This prober assumes such
> + * drop-in parts are on dedicated I2C busses, have non-conflicting addresses,
> + * and can be directly probed by seeing which address responds without needing
> + * regulators or GPIOs being enabled or toggled.
> + */
> +static int i2c_component_prober(struct platform_device *pdev, const void *data)
> +{
> +       const char *node_name = data;
> +       struct device_node *node, *i2c_node;
> +       struct i2c_adapter *i2c;
> +       int ret = 0;
> +
> +       node = of_find_node_by_name(NULL, node_name);
> +       if (!node)
> +               return dev_err_probe(&pdev->dev, -ENODEV, "Could not find %s device node\n",
> +                                    node_name);
> +
> +       i2c_node = of_get_next_parent(node);
> +       if (strcmp(i2c_node->name, "i2c")) {

We have functions for comparing node names, use them and don't access
->name directly.

> +               of_node_put(i2c_node);
> +               return dev_err_probe(&pdev->dev, -EINVAL, "%s device isn't on I2C bus\n",
> +                                    node_name);
> +       }
> +
> +       for_each_child_of_node(i2c_node, node) {
> +               if (!of_node_name_prefix(node, node_name))
> +                       continue;
> +               if (!of_device_is_fail(node)) {
> +                       /* device tree has component already enabled */

This isn't quite right if there's a disabled device. To check 'is
enabled', you just need to use of_device_is_available().

> +                       of_node_put(node);
> +                       of_node_put(i2c_node);
> +                       return 0;
> +               }
> +       }
> +
> +       i2c = of_get_i2c_adapter_by_node(i2c_node);
> +       if (!i2c) {
> +               of_node_put(i2c_node);
> +               return dev_err_probe(&pdev->dev, -EPROBE_DEFER, "Couldn't get I2C adapter\n");
> +       }
> +
> +       for_each_child_of_node(i2c_node, node) {

The I2C core will walk the devices too. Perhaps if that saves off a
list of failed devices, then we don't need to walk the nodes again.

> +               struct property *prop;
> +               union i2c_smbus_data data;
> +               u32 addr;
> +
> +               if (!of_node_name_prefix(node, node_name))
> +                       continue;
> +               if (of_property_read_u32(node, "reg", &addr))
> +                       continue;
> +               if (i2c_smbus_xfer(i2c, addr, 0, I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE, &data) < 0)
> +                       continue;
> +
> +               dev_info(&pdev->dev, "Enabling %pOF\n", node);
> +
> +               prop = kzalloc(sizeof(*prop), GFP_KERNEL);
> +               if (!prop) {
> +                       ret = -ENOMEM;
> +                       of_node_put(node);
> +                       break;
> +               }
> +
> +               prop->name      = "status";
> +               prop->length    = 5;
> +               prop->value     = "okay";
> +
> +               /* Found a device that is responding */
> +               ret = of_update_property(node, prop);

Use the changeset API instead and make an update flavor of
of_changeset_add_prop_string().

> +               if (ret)
> +                       kfree(prop);
> +
> +               of_node_put(node);
> +               break;
> +       }
> +
> +       i2c_put_adapter(i2c);
> +       of_node_put(i2c_node);
> +
> +       return ret;
> +}
> +
> +static const struct hw_prober_entry hw_prober_platforms[] = {
> +       { .compatible = "google,hana", .prober = i2c_component_prober, .data = "touchscreen" },
> +       { .compatible = "google,hana", .prober = i2c_component_prober, .data = "trackpad" },

Not generic code. Needs to be somewhere else.

> +};
> +
> +static int hw_prober_probe(struct platform_device *pdev)
> +{
> +       for (int i = 0; i < ARRAY_SIZE(hw_prober_platforms); i++)
> +               if (of_machine_is_compatible(hw_prober_platforms[i].compatible)) {
> +                       int ret;
> +
> +                       ret = hw_prober_platforms[i].prober(pdev, hw_prober_platforms[i].data);
> +                       if (ret)
> +                               return ret;
> +               }
> +
> +       return 0;
> +}
> +
> +static struct platform_driver hw_prober_driver = {
> +       .probe  = hw_prober_probe,
> +       .driver = {
> +               .name = DRV_NAME,
> +       },
> +};
> +
> +static int __init hw_prober_driver_init(void)
> +{
> +       struct platform_device *pdev;
> +       int ret;
> +
> +       ret = platform_driver_register(&hw_prober_driver);
> +       if (ret)
> +               return ret;
> +
> +       pdev = platform_device_register_simple(DRV_NAME, -1, NULL, 0);

This should be dependent on platforms that need it, not everyone. IOW,
this is where checking for "google,hana" belongs.


Rob

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH v2 2/7] of: Introduce hardware prober driver
  2023-11-09 10:05 ` [RFC PATCH v2 2/7] of: Introduce hardware prober driver Chen-Yu Tsai
  2023-11-09 15:13   ` Rob Herring
@ 2023-11-09 17:54   ` Andy Shevchenko
  2023-11-14  8:26     ` Chen-Yu Tsai
  1 sibling, 1 reply; 30+ messages in thread
From: Andy Shevchenko @ 2023-11-09 17:54 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Rob Herring, Frank Rowand, Krzysztof Kozlowski, Conor Dooley,
	Matthias Brugger, AngeloGioacchino Del Regno, Hsin-Yi Wang,
	Dmitry Torokhov, Jiri Kosina, linus.walleij, broonie, gregkh,
	hdegoede, james.clark, james, keescook, petr.tesarik.ext, rafael,
	tglx, Jeff LaBundy, linux-input, devicetree, linux-arm-kernel,
	linux-mediatek, linux-kernel, Douglas Anderson, Johan Hovold

On Thu, Nov 09, 2023 at 06:05:59PM +0800, Chen-Yu Tsai wrote:
> Some devices are designed and manufactured with some components having
> multiple drop-in replacement options. These components are often
> connected to the mainboard via ribbon cables, having the same signals
> and pin assignments across all options. These may include the display
> panel and touchscreen on laptops and tablets, and the trackpad on
> laptops. Sometimes which component option is used in a particular device
> can be detected by some firmware provided identifier, other times that
> information is not available, and the kernel has to try to probe each
> device.
> 
> This change attempts to make the "probe each device" case cleaner. The
> current approach is to have all options added and enabled in the device
> tree. The kernel would then bind each device and run each driver's probe
> function. This works, but has been broken before due to the introduction
> of asynchronous probing, causing multiple instances requesting "shared"
> resources, such as pinmuxes, GPIO pins, interrupt lines, at the same
> time, with only one instance succeeding. Work arounds for these include
> moving the pinmux to the parent I2C controller, using GPIO hogs or
> pinmux settings to keep the GPIO pins in some fixed configuration, and
> requesting the interrupt line very late. Such configurations can be seen
> on the MT8183 Krane Chromebook tablets, and the Qualcomm sc8280xp-based
> Lenovo Thinkpad 13S.
> 
> Instead of this delicate dance between drivers and device tree quirks,
> this change introduces a simple I2C component prober. For any given
> class of devices on the same I2C bus, it will go through all of them,
> doing a simple I2C read transfer and see which one of them responds.
> It will then enable the device that responds.
> 
> This requires some minor modifications in the existing device tree.
> The status for all the device nodes for the component options must be
> set to "failed-needs-probe-xxx". This makes it clear that some mechanism
> is needed to enable one of them, and also prevents the prober and device
> drivers running at the same time.

...

> +config HW_PROBER

config OF_HW_PROBER // or anything with explicit OF

Don't give a false impression that this is something that may works without
OF support.

...

> +	bool "Hardware Prober driver"

Ditto.

...

> +/*
> + * hw_prober.c - Hardware prober driver

Do not include filename into the file itself.

> + *
> + * Copyright (c) 2023 Google LLC
> + */

...

> +	node = of_find_node_by_name(NULL, node_name);
> +	if (!node)
> +		return dev_err_probe(&pdev->dev, -ENODEV, "Could not find %s device node\n",
> +				     node_name);

With

	struct device *dev = &pdev->dev;

this and other lines can be made neater.

...


For better maintenance it's good to have ret assignment be placed here

	ret = 0;

> +	for_each_child_of_node(i2c_node, node) {
> +		struct property *prop;
> +		union i2c_smbus_data data;
> +		u32 addr;
> +
> +		if (!of_node_name_prefix(node, node_name))
> +			continue;
> +		if (of_property_read_u32(node, "reg", &addr))
> +			continue;
> +		if (i2c_smbus_xfer(i2c, addr, 0, I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE, &data) < 0)
> +			continue;
> +
> +		dev_info(&pdev->dev, "Enabling %pOF\n", node);
> +
> +		prop = kzalloc(sizeof(*prop), GFP_KERNEL);
> +		if (!prop) {
> +			ret = -ENOMEM;
> +			of_node_put(node);
> +			break;
> +		}
> +
> +		prop->name	= "status";
> +		prop->length	= 5;
> +		prop->value	= "okay";
> +
> +		/* Found a device that is responding */
> +		ret = of_update_property(node, prop);
> +		if (ret)
> +			kfree(prop);
> +
> +		of_node_put(node);
> +		break;
> +	}

...

> +static const struct hw_prober_entry hw_prober_platforms[] = {
> +	{ .compatible = "google,hana", .prober = i2c_component_prober, .data = "touchscreen" },
> +	{ .compatible = "google,hana", .prober = i2c_component_prober, .data = "trackpad" },
> +};

Why can't OF ID table be used for this?

...

> +	for (int i = 0; i < ARRAY_SIZE(hw_prober_platforms); i++)

unsigned?

> +		if (of_machine_is_compatible(hw_prober_platforms[i].compatible)) {
> +			int ret;
> +
> +			ret = hw_prober_platforms[i].prober(pdev, hw_prober_platforms[i].data);
> +			if (ret)
> +				return ret;
> +		}

...

> +	pdev = platform_device_register_simple(DRV_NAME, -1, NULL, 0);

-1 is defined in the header, use that definition.

> +	if (!IS_ERR(pdev))
> +		return 0;
> +
> +	platform_driver_unregister(&hw_prober_driver);
> +
> +	return PTR_ERR(pdev);

Can you use standard pattern, i.e. checking for the _error_ condition?

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH v2 6/7] dt-bindings: arm: mediatek: Remove SKU specific compatibles for Google Krane
  2023-11-09 10:06 ` [RFC PATCH v2 6/7] dt-bindings: arm: mediatek: Remove SKU specific compatibles for Google Krane Chen-Yu Tsai
@ 2023-11-10 21:04   ` Rob Herring
  2023-11-11  0:29     ` Doug Anderson
  0 siblings, 1 reply; 30+ messages in thread
From: Rob Herring @ 2023-11-10 21:04 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Frank Rowand, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Hsin-Yi Wang, Dmitry Torokhov,
	andriy.shevchenko, Jiri Kosina, linus.walleij, broonie, gregkh,
	hdegoede, james.clark, james, keescook, petr.tesarik.ext, rafael,
	tglx, Jeff LaBundy, linux-input, devicetree, linux-arm-kernel,
	linux-mediatek, linux-kernel, Douglas Anderson, Johan Hovold

On Thu, Nov 09, 2023 at 06:06:03PM +0800, Chen-Yu Tsai wrote:
> In cases where the same Chromebook model is manufactured with different
> components (MIPI DSI panels, MIPI CSI camera sensors, or trackpad /
> touchscreens with conflicting addresses), a different SKU ID is
> allocated to each specific combination. This SKU ID is exported by the
> bootloader into the device tree, and can be used to "discover" which
> combination is present on the current machine. Thus we no longer have
> to specify separate compatible strings for each of them.

You just broke an existing kernel with a new DT having this change.

Just because you come up with a new way to do things, doesn't mean you 
can remove the old way.

> 
> Remove the SKU specific compatible strings for Google Krane.
> 
> Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
> ---
>  Documentation/devicetree/bindings/arm/mediatek.yaml | 3 ---
>  1 file changed, 3 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/arm/mediatek.yaml b/Documentation/devicetree/bindings/arm/mediatek.yaml
> index a4541855a838..ef3dfb286814 100644
> --- a/Documentation/devicetree/bindings/arm/mediatek.yaml
> +++ b/Documentation/devicetree/bindings/arm/mediatek.yaml
> @@ -186,9 +186,6 @@ properties:
>            - const: mediatek,mt8183
>        - description: Google Krane (Lenovo IdeaPad Duet, 10e,...)
>          items:
> -          - enum:
> -              - google,krane-sku0
> -              - google,krane-sku176
>            - const: google,krane
>            - const: mediatek,mt8183
>        - description: Google Willow (Acer Chromebook 311 C722/C722T)
> -- 
> 2.42.0.869.gea05f2083d-goog
> 

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH v2 5/7] of: hw_prober: Support Chromebook SKU ID based component selection
  2023-11-09 10:06 ` [RFC PATCH v2 5/7] of: hw_prober: Support Chromebook SKU ID based component selection Chen-Yu Tsai
@ 2023-11-10 21:07   ` Rob Herring
  0 siblings, 0 replies; 30+ messages in thread
From: Rob Herring @ 2023-11-10 21:07 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Frank Rowand, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Hsin-Yi Wang, Dmitry Torokhov,
	andriy.shevchenko, Jiri Kosina, linus.walleij, broonie, gregkh,
	hdegoede, james.clark, james, keescook, petr.tesarik.ext, rafael,
	tglx, Jeff LaBundy, linux-input, devicetree, linux-arm-kernel,
	linux-mediatek, linux-kernel, Douglas Anderson, Johan Hovold

On Thu, Nov 09, 2023 at 06:06:02PM +0800, Chen-Yu Tsai wrote:
> In cases where the same Chromebook model is manufactured with different
> components (MIPI DSI panels, MIPI CSI camera sensors, or trackpad /
> touchscreens with conflicting addresses), a different SKU ID is
> allocated to each specific combination. This SKU ID is exported by the
> bootloader into the device tree, and can be used to "discover" which
> combination is present on the current machine.
> 
> This change adds a hardware prober that will match the SKU ID against
> a provided table, and enable the component for the matched entry based
> on the given compatible string. In the MIPI DSI panel and MIPI CSI
> camera sensor cases which have OF graphs, it will also update the
> remote endpoint to point to the enabled component. This assumes a single
> endpoint only.
> 
> This will provide a path to reducing the number of Chromebook device
> trees.
> 
> Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
> ---
>  drivers/of/hw_prober.c | 160 +++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 160 insertions(+)

This certainly does not belong in drivers/of/.


> diff --git a/drivers/of/hw_prober.c b/drivers/of/hw_prober.c
> index 442da6eff896..4345e5aed6d8 100644
> --- a/drivers/of/hw_prober.c
> +++ b/drivers/of/hw_prober.c
> @@ -8,6 +8,7 @@
>  #include <linux/array_size.h>
>  #include <linux/i2c.h>
>  #include <linux/of.h>
> +#include <linux/of_graph.h>
>  #include <linux/platform_device.h>
>  
>  #define DRV_NAME	"hw_prober"
> @@ -108,9 +109,168 @@ static int i2c_component_prober(struct platform_device *pdev, const void *data)
>  	return ret;
>  }
>  
> +static int cros_get_coreboot_sku_id(struct device *dev, u32 *sku_id)
> +{
> +	struct device_node *node = NULL;
> +	int ret;
> +
> +	node = of_find_node_by_path("/firmware/coreboot");
> +	if (!node)
> +		return dev_err_probe(dev, -EINVAL, "Cannot find coreboot firmware node\n");
> +
> +	ret = of_property_read_u32(node, "sku-id", sku_id);

Not documented.

Rob

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH v2 0/7] of: Introduce hardware prober driver
  2023-11-09 13:51   ` Rob Herring
@ 2023-11-11  0:12     ` Doug Anderson
  2023-11-15 19:28       ` Rob Herring
  2023-11-14  7:05     ` Chen-Yu Tsai
  1 sibling, 1 reply; 30+ messages in thread
From: Doug Anderson @ 2023-11-11  0:12 UTC (permalink / raw)
  To: Rob Herring
  Cc: AngeloGioacchino Del Regno, Chen-Yu Tsai, Frank Rowand,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger, Hsin-Yi Wang,
	Dmitry Torokhov, andriy.shevchenko, Jiri Kosina, linus.walleij,
	broonie, gregkh, hdegoede, james.clark, james, keescook,
	petr.tesarik.ext, rafael, tglx, Jeff LaBundy, linux-input,
	devicetree, linux-arm-kernel, linux-mediatek, linux-kernel,
	Johan Hovold

Hi,

On Thu, Nov 9, 2023 at 5:52 AM Rob Herring <robh+dt@kernel.org> wrote:
>
> > > End of background from Doug's cover letter.
> >
> > I think that using "status" is not a good idea, I find that confusing.
>
> "status" is what defines a device's state in terms of enabled,
> present, available. That's exactly what we're expressing here.
>
> Now, I do not think we should be mixing the device class (e.g.
> touchscreen) into status. I said this on v1, but apparently that was
> not listened to.

Interesting. I must have missed the "don't mix device class into
status" part. Do you have a link to your post about that? Maybe
there's other stuff I missed... Having the device class stuck at the
end there was at least part of my last post [1] which gathered no
response.

I think one of the reasons that I felt we needed to mux the device
class into status was that it was going to make the code a lot less
fragile. Everything I've seen indicates that you don't want us to
create a "HW prober" node that could be used to provide relevant
phandles for different classes of devices, so the "HW prober" code
needs to either search through the whole device tree for a status of
"failed-needs-probe" or needs to contain per-board, hardcoded,
fully-qualified paths.

I don't think we want to include hardcoded, fully-qualified paths in
the code. That would mean that if someone changed a node name
somewhere in the path to one of the devices that we're dealing with
then it would break.

So if we're searching the whole device tree for "failed-needs-probe"
then we need to figure out which devices are related to each other. If
a given board has second sources for MIPI panels, touchscreens, and
trackpads then we need to know which of the "failed-needs-probe"
devices are trackpads, which are touchscreens, and which are MIPI
panels. Do you have any suggestions for how we should do that? Maybe
it was in some other thread that I missed? I guess we could have a
board-specific table mapping (compatible + node name + reg) to a
class, but that feels awkward.

[1] https://lore.kernel.org/r/CAD=FV=UjVAgT-febtj4=UZ2GQp01D-ern2Ff9+ODcHeQBOsdTQ@mail.gmail.com

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH v2 0/7] of: Introduce hardware prober driver
  2023-11-09 10:05 [RFC PATCH v2 0/7] of: Introduce hardware prober driver Chen-Yu Tsai
                   ` (7 preceding siblings ...)
  2023-11-09 10:54 ` [RFC PATCH v2 0/7] of: Introduce hardware prober driver AngeloGioacchino Del Regno
@ 2023-11-11  0:22 ` Doug Anderson
  2023-11-14  8:44   ` Chen-Yu Tsai
  8 siblings, 1 reply; 30+ messages in thread
From: Doug Anderson @ 2023-11-11  0:22 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Rob Herring, Frank Rowand, Krzysztof Kozlowski, Conor Dooley,
	Matthias Brugger, AngeloGioacchino Del Regno, Hsin-Yi Wang,
	Dmitry Torokhov, andriy.shevchenko, Jiri Kosina, linus.walleij,
	broonie, gregkh, hdegoede, james.clark, james, keescook,
	petr.tesarik.ext, rafael, tglx, Jeff LaBundy, linux-input,
	devicetree, linux-arm-kernel, linux-mediatek, linux-kernel,
	Johan Hovold

Hi,

On Thu, Nov 9, 2023 at 2:06 AM Chen-Yu Tsai <wenst@chromium.org> wrote:
>
> The driver as
> implemented currently doesn't deal with regulators or GPIO pins,
> since in the existing device trees they are either always on for
> regulators, or have GPIO hogs or pinmux and pinconfig directly
> tied to the pin controller.

I guess I won't object too much about this limitation for v1, but IMO
it would be good to get this sorted out since I think part of the
power of having the HW Prober is specifically that it can handle this
type of use case. You have a little bit of board-specific code that
knows how to turn on the regulators / GPIOs and can then probe the
devices.

Note: even if this is "board specific", it doesn't mean you couldn't
share code between boards. For instance, you could have a helper
function that would turn on regulators/GPIOs based on some type of
table and that helper function could be used across a whole pile of
Chromebooks. If a Chromebook is sufficiently different that it
couldn't use the helper function then it could call its own function,
but presumably it wouldn't be hard to support a bunch of boards
without much code.

As part of this, I think that your main "HW Prober" for Chromebooks
should be in "drivers/platform/chrome/". I think that the only things
that should be in the "drivers/of" directory should be helper
functions used by the Chromebook HW Probers.


-Doug

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH v2 6/7] dt-bindings: arm: mediatek: Remove SKU specific compatibles for Google Krane
  2023-11-10 21:04   ` Rob Herring
@ 2023-11-11  0:29     ` Doug Anderson
  0 siblings, 0 replies; 30+ messages in thread
From: Doug Anderson @ 2023-11-11  0:29 UTC (permalink / raw)
  To: Rob Herring
  Cc: Chen-Yu Tsai, Frank Rowand, Krzysztof Kozlowski, Conor Dooley,
	Matthias Brugger, AngeloGioacchino Del Regno, Hsin-Yi Wang,
	Dmitry Torokhov, andriy.shevchenko, Jiri Kosina, linus.walleij,
	broonie, gregkh, hdegoede, james.clark, james, keescook,
	petr.tesarik.ext, rafael, tglx, Jeff LaBundy, linux-input,
	devicetree, linux-arm-kernel, linux-mediatek, linux-kernel,
	Johan Hovold

Hi,

On Fri, Nov 10, 2023 at 1:04 PM Rob Herring <robh@kernel.org> wrote:
>
> On Thu, Nov 09, 2023 at 06:06:03PM +0800, Chen-Yu Tsai wrote:
> > In cases where the same Chromebook model is manufactured with different
> > components (MIPI DSI panels, MIPI CSI camera sensors, or trackpad /
> > touchscreens with conflicting addresses), a different SKU ID is
> > allocated to each specific combination. This SKU ID is exported by the
> > bootloader into the device tree, and can be used to "discover" which
> > combination is present on the current machine. Thus we no longer have
> > to specify separate compatible strings for each of them.
>
> You just broke an existing kernel with a new DT having this change.
>
> Just because you come up with a new way to do things, doesn't mean you
> can remove the old way.

I was wondering about that, actually. My understanding was that what
Chen-Yu was doing here was correct, but I'm happy to be educated.

Specifically, I think that after his series old device trees will
continue to boot just fine. ...so if someone took a device tree from
before his series and booted it on a kernel after his series that
everything would be hunky dory. If that doesn't work then, I agree,
that should be fixed.

However, here, he is documenting what the "latest and greatest" device
tree should look at and that matches what's checked into the "dts"
directory. In general, I thought that yaml files didn't necessarily
always document old/deprecated ways of doing things and just focused
on documenting the new/best way.

Now, obviously, if someone took a new device tree and tried to put it
on an old kernel then it wouldn't work, but I was always under the
impression that wasn't a requirement.


-Doug

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH v2 0/7] of: Introduce hardware prober driver
  2023-11-09 13:51   ` Rob Herring
  2023-11-11  0:12     ` Doug Anderson
@ 2023-11-14  7:05     ` Chen-Yu Tsai
  1 sibling, 0 replies; 30+ messages in thread
From: Chen-Yu Tsai @ 2023-11-14  7:05 UTC (permalink / raw)
  To: Rob Herring
  Cc: AngeloGioacchino Del Regno, Frank Rowand, Krzysztof Kozlowski,
	Conor Dooley, Matthias Brugger, Hsin-Yi Wang, Dmitry Torokhov,
	andriy.shevchenko, Jiri Kosina, linus.walleij, broonie, gregkh,
	hdegoede, james.clark, james, keescook, petr.tesarik.ext, rafael,
	tglx, Jeff LaBundy, linux-input, devicetree, linux-arm-kernel,
	linux-mediatek, linux-kernel, Douglas Anderson, Johan Hovold

On Thu, Nov 9, 2023 at 9:52 PM Rob Herring <robh+dt@kernel.org> wrote:
>
> On Thu, Nov 9, 2023 at 4:54 AM AngeloGioacchino Del Regno
> <angelogioacchino.delregno@collabora.com> wrote:
> >
> > Il 09/11/23 11:05, Chen-Yu Tsai ha scritto:
> > > Hi everyone,
> > >
> > > This v2 series continues Doug's "of: device: Support 2nd sources of
> > > probeable but undiscoverable devices" [1] series, but follows the scheme
> > > suggested by Rob, marking all second source component device nodes
> > > as "fail-needs-probe-XXX", and having a hardware prober driver enable
> > > the one of them. I tried to include everyone from the original Cc: list.
> > > Please let me know if you would like to be dropped from future
> > > submissions.
> > >
> > >
> > > For the I2C component (touchscreens and trackpads) case from the
> > > original series, the hardware prober driver finds the particular
> > > class of device in the device tree, gets its parent I2C adapter,
> > > and tries to initiate a simple I2C read for each device under that
> > > I2C bus. When it finds one that responds, it considers that one
> > > present, marks it as "okay", and returns, letting the driver core
> > > actually probe the device.
> > >
> > > This works fine in most cases since these components are connected
> > > via ribbon cable and always have the same resources. The driver as
> > > implemented currently doesn't deal with regulators or GPIO pins,
> > > since in the existing device trees they are either always on for
> > > regulators, or have GPIO hogs or pinmux and pinconfig directly
> > > tied to the pin controller.
> > >
> > >
> > > Another case this driver could handle is selecting components based
> > > on some identifier passed in by the firmware. On Chromebooks we have
> > > a SKU ID which is inserted by the bootloader at
> > > /firmware/coreboot/sku-id. When a new combination of components is
> > > introduced, a new SKU ID is allocated to it. To have SKU ID based
> > > device trees, we would need to have one per SKU ID. This ends up
> > > increasing the number of device trees we have a lot. The recent
> > > MT8186 devices already have 10+10 SKUs [2], with possibly more to come.
> > >
> > > Instead, we could have just one device tree for each device, with
> > > component options listed and marked as "fail-needs-probe-XXX", and
> > > let the hardware prober enable one of them based on the given SKU ID.
> > > The driver will also fix up OF graph remote endpoints to point to the
> > > enabled component.
> > >
> > > The MT8186 Corsola series [2] can also benefit from this, though I
> > > haven't implemented anything yet.
> > >
> > >
> > > Patch 1 adds of_device_is_fail() for the new driver to use.
> > >
> > > Patch 2 implements the first case, probing the I2C bus for presence
> > > of components. This initial version targets the Hana Chromebooks.
> > >
> > > Patch 3 modifies the Hana device tree and marks the touchscreens
> > > and trackpads as "fail-needs-probe-XXX", ready for the driver to
> > > probe.
> > >
> > > Patch 4 adds a missing touchscreen variant to Hana.
> > >
> > > Patch 5 implements the second case, selectively enabling components
> > > based on the SKU ID. This initial version targets the Krane ChromeOS
> > > tablet, which has two possible MIPI DSI display panel options.
> > >
> > > Patch 6 drops Krane's SKU-specific compatible strings from the bindings.
> > >
> > > Patch 7 merges Krane's SKU-specific device trees into one, with the
> > > device tree now containing two possible panels. This unfortunately
> > > introduces a dtc warning:
> > >
> > >      arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dts:81.13-83.6:
> > >          Warning (graph_endpoint): /soc/dsi@14014000/panel2@0/port/endpoint:
> > >       graph connection to node '/soc/dsi@14014000/ports/port/endpoint'
> > >           is not bidirectional
> > >
> > >
> > > Please take a look.
> > >
> > > Johan, I'm not sure if this works as is for the Lenovo Thinkpad 13S
> > > case, since it looks like the trackpad shares the I2C bus with the
> > > keyboard.
> > >
> > >
> > > Thanks
> > > ChenYu
> > >
> > >
> > > Background as given in Doug's cover letter:
> > >
> > > Support for multiple "equivalent" sources for components (also known
> > > as second sourcing components) is a standard practice that helps keep
> > > cost down and also makes sure that if one component is unavailable due
> > > to a shortage that we don't need to stop production for the whole
> > > product.
> > >
> > > Some components are very easy to second source. eMMC, for instance, is
> > > fully discoverable and probable so you can stuff a wide variety of
> > > similar eMMC chips on your board and things will work without a hitch.
> > >
> > > Some components are more difficult to second source, specifically
> > > because it's difficult for software to probe what component is present
> > > on any given board. In cases like this software is provided
> > > supplementary information to help it, like a GPIO strap or a SKU ID
> > > programmed into an EEPROM. This helpful information can allow the
> > > bootloader to select a different device tree. The various different
> > > "SKUs" of different Chromebooks are examples of this.
> > >
> > > Some components are somewhere in between. These in-between components
> > > are the subject of this patch. Specifically, these components are
> > > easily "probeable" but not easily "discoverable".
> > >
> > > A good example of a probeable but undiscoverable device is an
> > > i2c-connected touchscreen or trackpad. Two separate components may be
> > > electrically compatible with each other and may have compatible power
> > > sequencing requirements but may require different software. If
> > > software is told about the different possible components (because it
> > > can't discover them), it can safely probe them to figure out which
> > > ones are present.
> > >
> > > On systems using device tree, if we want to tell the OS about all of
> > > the different components we need to list them all in the device
> > > tree. This leads to a problem. The multiple sources for components
> > > likely use the same resources (GPIOs, interrupts, regulators). If the
> > > OS tries to probe all of these components at the same time then it
> > > will detect a resource conflict and that's a fatal error.
> > >
> > > The fact that Linux can't handle these probeable but undiscoverable
> > > devices well has had a few consequences:
> > > 1. In some cases, we've abandoned the idea of second sourcing
> > >     components for a given board, which increases cost / generates
> > >     manufacturing headaches.
> > > 2. In some cases, we've been forced to add some sort of strapping /
> > >     EEPROM to indicate which component is present. This adds difficulty
> > >     to manufacturing / refurb processes.
> > > 3. In some cases, we've managed to make things work by the skin of our
> > >     teeth through slightly hacky solutions. Specifically, if we remove
> > >     the "pinctrl" entry from the various options then it won't
> > >     conflict. Regulators inherently can have more than one consumer, so
> > >     as long as there are no GPIOs involved in power sequencing and
> > >     probing devices then things can work. This is how
> > >     "sc8280xp-lenovo-thinkpad-x13s" works and also how
> > >     "mt8173-elm-hana" works.
> > >
> > > End of background from Doug's cover letter.
> >
> > I think that using "status" is not a good idea, I find that confusing.
>
> "status" is what defines a device's state in terms of enabled,
> present, available. That's exactly what we're expressing here.
>
> Now, I do not think we should be mixing the device class (e.g.
> touchscreen) into status. I said this on v1, but apparently that was
> not listened to.

I must have missed it and only took in Doug's final response.

My code doesn't actually use the class in the status property though.
I will remove it and just keep "fail-needs-probe".

ChenYu

> >
> > Perhaps we could have a node like
> >
> > something {
> >         device-class-one = <&device1>, <&device2>, <&device3>;
> >         device-class-two = <&device4>, <&device5>, <&device6>;
> > }
> >
> > so that'd be more or less
> >
> > hw-prober {
> >         trackpads = <&tp1>, <&tp2>;
> >         keyboards = <&kb1>, <&kb2>;
> >         touchscreens = <&ts1>, <&ts2>;
> > }
>
> No. That's more or less what v1 had.
>
> Rob

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH v2 2/7] of: Introduce hardware prober driver
  2023-11-09 17:54   ` Andy Shevchenko
@ 2023-11-14  8:26     ` Chen-Yu Tsai
  0 siblings, 0 replies; 30+ messages in thread
From: Chen-Yu Tsai @ 2023-11-14  8:26 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Rob Herring, Frank Rowand, Krzysztof Kozlowski, Conor Dooley,
	Matthias Brugger, AngeloGioacchino Del Regno, Hsin-Yi Wang,
	Dmitry Torokhov, Jiri Kosina, linus.walleij, broonie, gregkh,
	hdegoede, james.clark, james, keescook, petr.tesarik.ext, rafael,
	tglx, Jeff LaBundy, linux-input, devicetree, linux-arm-kernel,
	linux-mediatek, linux-kernel, Douglas Anderson, Johan Hovold

On Fri, Nov 10, 2023 at 1:54 AM Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:
>
> On Thu, Nov 09, 2023 at 06:05:59PM +0800, Chen-Yu Tsai wrote:
> > Some devices are designed and manufactured with some components having
> > multiple drop-in replacement options. These components are often
> > connected to the mainboard via ribbon cables, having the same signals
> > and pin assignments across all options. These may include the display
> > panel and touchscreen on laptops and tablets, and the trackpad on
> > laptops. Sometimes which component option is used in a particular device
> > can be detected by some firmware provided identifier, other times that
> > information is not available, and the kernel has to try to probe each
> > device.
> >
> > This change attempts to make the "probe each device" case cleaner. The
> > current approach is to have all options added and enabled in the device
> > tree. The kernel would then bind each device and run each driver's probe
> > function. This works, but has been broken before due to the introduction
> > of asynchronous probing, causing multiple instances requesting "shared"
> > resources, such as pinmuxes, GPIO pins, interrupt lines, at the same
> > time, with only one instance succeeding. Work arounds for these include
> > moving the pinmux to the parent I2C controller, using GPIO hogs or
> > pinmux settings to keep the GPIO pins in some fixed configuration, and
> > requesting the interrupt line very late. Such configurations can be seen
> > on the MT8183 Krane Chromebook tablets, and the Qualcomm sc8280xp-based
> > Lenovo Thinkpad 13S.
> >
> > Instead of this delicate dance between drivers and device tree quirks,
> > this change introduces a simple I2C component prober. For any given
> > class of devices on the same I2C bus, it will go through all of them,
> > doing a simple I2C read transfer and see which one of them responds.
> > It will then enable the device that responds.
> >
> > This requires some minor modifications in the existing device tree.
> > The status for all the device nodes for the component options must be
> > set to "failed-needs-probe-xxx". This makes it clear that some mechanism
> > is needed to enable one of them, and also prevents the prober and device
> > drivers running at the same time.
>
> ...
>
> > +config HW_PROBER
>
> config OF_HW_PROBER // or anything with explicit OF
>
> Don't give a false impression that this is something that may works without
> OF support.

Ack.

> ...
>
> > +     bool "Hardware Prober driver"
>
> Ditto.

Ack.

> ...
>
> > +/*
> > + * hw_prober.c - Hardware prober driver
>
> Do not include filename into the file itself.

Ack.

> > + *
> > + * Copyright (c) 2023 Google LLC
> > + */
>
> ...
>
> > +     node = of_find_node_by_name(NULL, node_name);
> > +     if (!node)
> > +             return dev_err_probe(&pdev->dev, -ENODEV, "Could not find %s device node\n",
> > +                                  node_name);
>
> With
>
>         struct device *dev = &pdev->dev;
>
> this and other lines can be made neater.

Ack.

> ...
>
>
> For better maintenance it's good to have ret assignment be placed here
>
>         ret = 0;

Ack.

> > +     for_each_child_of_node(i2c_node, node) {
> > +             struct property *prop;
> > +             union i2c_smbus_data data;
> > +             u32 addr;
> > +
> > +             if (!of_node_name_prefix(node, node_name))
> > +                     continue;
> > +             if (of_property_read_u32(node, "reg", &addr))
> > +                     continue;
> > +             if (i2c_smbus_xfer(i2c, addr, 0, I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE, &data) < 0)
> > +                     continue;
> > +
> > +             dev_info(&pdev->dev, "Enabling %pOF\n", node);
> > +
> > +             prop = kzalloc(sizeof(*prop), GFP_KERNEL);
> > +             if (!prop) {
> > +                     ret = -ENOMEM;
> > +                     of_node_put(node);
> > +                     break;
> > +             }
> > +
> > +             prop->name      = "status";
> > +             prop->length    = 5;
> > +             prop->value     = "okay";
> > +
> > +             /* Found a device that is responding */
> > +             ret = of_update_property(node, prop);
> > +             if (ret)
> > +                     kfree(prop);
> > +
> > +             of_node_put(node);
> > +             break;
> > +     }
>
> ...
>
> > +static const struct hw_prober_entry hw_prober_platforms[] = {
> > +     { .compatible = "google,hana", .prober = i2c_component_prober, .data = "touchscreen" },
> > +     { .compatible = "google,hana", .prober = i2c_component_prober, .data = "trackpad" },
> > +};
>
> Why can't OF ID table be used for this?

My intent was to have this accept a probe function, which may take an extra
data argument. So either a new structure like the one here, or use OF ID table,
and then another layer with a struct holding the prober and extra data pointer.

I'm guessing this will change since Rob thinks the next patch that adds a
different prober doesn't belong here.

> ...
>
> > +     for (int i = 0; i < ARRAY_SIZE(hw_prober_platforms); i++)
>
> unsigned?

Ack.

> > +             if (of_machine_is_compatible(hw_prober_platforms[i].compatible)) {
> > +                     int ret;
> > +
> > +                     ret = hw_prober_platforms[i].prober(pdev, hw_prober_platforms[i].data);
> > +                     if (ret)
> > +                             return ret;
> > +             }
>
> ...
>
> > +     pdev = platform_device_register_simple(DRV_NAME, -1, NULL, 0);
>
> -1 is defined in the header, use that definition.

Ack.

> > +     if (!IS_ERR(pdev))
> > +             return 0;
> > +
> > +     platform_driver_unregister(&hw_prober_driver);
> > +
> > +     return PTR_ERR(pdev);
>
> Can you use standard pattern, i.e. checking for the _error_ condition?

Ack.


Thanks
ChenYu

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH v2 2/7] of: Introduce hardware prober driver
  2023-11-09 15:13   ` Rob Herring
@ 2023-11-14  8:30     ` Chen-Yu Tsai
  0 siblings, 0 replies; 30+ messages in thread
From: Chen-Yu Tsai @ 2023-11-14  8:30 UTC (permalink / raw)
  To: Rob Herring
  Cc: Frank Rowand, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Hsin-Yi Wang, Dmitry Torokhov,
	andriy.shevchenko, Jiri Kosina, linus.walleij, broonie, gregkh,
	hdegoede, james.clark, james, keescook, rafael, tglx,
	Jeff LaBundy, linux-input, devicetree, linux-arm-kernel,
	linux-mediatek, linux-kernel, Douglas Anderson, Johan Hovold

On Thu, Nov 9, 2023 at 11:14 PM Rob Herring <robh+dt@kernel.org> wrote:
>
> On Thu, Nov 9, 2023 at 4:06 AM Chen-Yu Tsai <wenst@chromium.org> wrote:
> >
> > Some devices are designed and manufactured with some components having
> > multiple drop-in replacement options. These components are often
> > connected to the mainboard via ribbon cables, having the same signals
> > and pin assignments across all options. These may include the display
> > panel and touchscreen on laptops and tablets, and the trackpad on
> > laptops. Sometimes which component option is used in a particular device
> > can be detected by some firmware provided identifier, other times that
> > information is not available, and the kernel has to try to probe each
> > device.
> >
> > This change attempts to make the "probe each device" case cleaner. The
> > current approach is to have all options added and enabled in the device
> > tree. The kernel would then bind each device and run each driver's probe
> > function. This works, but has been broken before due to the introduction
> > of asynchronous probing, causing multiple instances requesting "shared"
> > resources, such as pinmuxes, GPIO pins, interrupt lines, at the same
> > time, with only one instance succeeding. Work arounds for these include
> > moving the pinmux to the parent I2C controller, using GPIO hogs or
> > pinmux settings to keep the GPIO pins in some fixed configuration, and
> > requesting the interrupt line very late. Such configurations can be seen
> > on the MT8183 Krane Chromebook tablets, and the Qualcomm sc8280xp-based
> > Lenovo Thinkpad 13S.
> >
> > Instead of this delicate dance between drivers and device tree quirks,
> > this change introduces a simple I2C component prober. For any given
> > class of devices on the same I2C bus, it will go through all of them,
> > doing a simple I2C read transfer and see which one of them responds.
> > It will then enable the device that responds.
> >
> > This requires some minor modifications in the existing device tree.
> > The status for all the device nodes for the component options must be
> > set to "failed-needs-probe-xxx". This makes it clear that some mechanism
> > is needed to enable one of them, and also prevents the prober and device
> > drivers running at the same time.
> >
> > Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
> > ---
> >  drivers/of/Kconfig     |  13 ++++
> >  drivers/of/Makefile    |   1 +
> >  drivers/of/hw_prober.c | 154 +++++++++++++++++++++++++++++++++++++++++
>
> Not sure about having this in drivers/of/, but fine for now... Really,
> the I2C bus stuff should be in the I2C core with the rest of the code
> that knows how to parse I2C bus nodes.

I think we can move the majority of this patch into the I2C core and
export just the one prober function. The remainder and the other SKU
ID based prober could be moved to drivers/platform/chrome.

Not sure how we want to place probers for other platforms though?

> >  3 files changed, 168 insertions(+)
> >  create mode 100644 drivers/of/hw_prober.c
> >
> > diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
> > index da9826accb1b..269d20d51936 100644
> > --- a/drivers/of/Kconfig
> > +++ b/drivers/of/Kconfig
> > @@ -102,4 +102,17 @@ config OF_OVERLAY
> >  config OF_NUMA
> >         bool
> >
> > +config HW_PROBER
> > +       bool "Hardware Prober driver"
> > +       select I2C
>
> You should not select I2C, but enable/disable I2C functionality based
> on it being enabled.

Ack.

> > +       select OF_DYNAMIC
> > +       help
> > +         Some devices will have multiple drop-in options for one component.
> > +         In many cases the different options are indistinguishable by the
> > +         kernel without actually probing each possible option.
> > +
> > +         This driver is meant to handle the probing of such components, and
> > +         update the running device tree such that the correct variant is
> > +         made available.
> > +
> >  endif # OF
> > diff --git a/drivers/of/Makefile b/drivers/of/Makefile
> > index eff624854575..ed3875cdc554 100644
> > --- a/drivers/of/Makefile
> > +++ b/drivers/of/Makefile
> > @@ -12,6 +12,7 @@ obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
> >  obj-$(CONFIG_OF_RESOLVE)  += resolver.o
> >  obj-$(CONFIG_OF_OVERLAY) += overlay.o
> >  obj-$(CONFIG_OF_NUMA) += of_numa.o
> > +obj-$(CONFIG_HW_PROBER) += hw_prober.o
> >
> >  ifdef CONFIG_KEXEC_FILE
> >  ifdef CONFIG_OF_FLATTREE
> > diff --git a/drivers/of/hw_prober.c b/drivers/of/hw_prober.c
> > new file mode 100644
> > index 000000000000..442da6eff896
> > --- /dev/null
> > +++ b/drivers/of/hw_prober.c
> > @@ -0,0 +1,154 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * hw_prober.c - Hardware prober driver
> > + *
> > + * Copyright (c) 2023 Google LLC
> > + */
> > +
> > +#include <linux/array_size.h>
> > +#include <linux/i2c.h>
> > +#include <linux/of.h>
> > +#include <linux/platform_device.h>
> > +
> > +#define DRV_NAME       "hw_prober"
> > +
> > +/**
> > + * struct hw_prober_entry - Holds an entry for the hardware prober
> > + *
> > + * @compatible:        compatible string to match against the machine
> > + * @prober:    prober function to call when machine matches
> > + * @data:      extra data for the prober function
> > + */
> > +struct hw_prober_entry {
> > +       const char *compatible;
> > +       int (*prober)(struct platform_device *pdev, const void *data);
> > +       const void *data;
> > +};
> > +
> > +/*
> > + * Some devices, such as Google Hana Chromebooks, are produced by multiple
> > + * vendors each using their preferred components. This prober assumes such
> > + * drop-in parts are on dedicated I2C busses, have non-conflicting addresses,
> > + * and can be directly probed by seeing which address responds without needing
> > + * regulators or GPIOs being enabled or toggled.
> > + */
> > +static int i2c_component_prober(struct platform_device *pdev, const void *data)
> > +{
> > +       const char *node_name = data;
> > +       struct device_node *node, *i2c_node;
> > +       struct i2c_adapter *i2c;
> > +       int ret = 0;
> > +
> > +       node = of_find_node_by_name(NULL, node_name);
> > +       if (!node)
> > +               return dev_err_probe(&pdev->dev, -ENODEV, "Could not find %s device node\n",
> > +                                    node_name);
> > +
> > +       i2c_node = of_get_next_parent(node);
> > +       if (strcmp(i2c_node->name, "i2c")) {
>
> We have functions for comparing node names, use them and don't access
> ->name directly.

Ack.

> > +               of_node_put(i2c_node);
> > +               return dev_err_probe(&pdev->dev, -EINVAL, "%s device isn't on I2C bus\n",
> > +                                    node_name);
> > +       }
> > +
> > +       for_each_child_of_node(i2c_node, node) {
> > +               if (!of_node_name_prefix(node, node_name))
> > +                       continue;
> > +               if (!of_device_is_fail(node)) {
> > +                       /* device tree has component already enabled */
>
> This isn't quite right if there's a disabled device. To check 'is
> enabled', you just need to use of_device_is_available().

I wanted to distinguish between explicitly disabled, i.e. components
known to not exist on some specific variant, vs fail or components
that need probing. I suppose this is overengineered since the previous
of_node_name_prefix() already restricts the check to the class of
components we are interested in.

> > +                       of_node_put(node);
> > +                       of_node_put(i2c_node);
> > +                       return 0;
> > +               }
> > +       }
> > +
> > +       i2c = of_get_i2c_adapter_by_node(i2c_node);
> > +       if (!i2c) {
> > +               of_node_put(i2c_node);
> > +               return dev_err_probe(&pdev->dev, -EPROBE_DEFER, "Couldn't get I2C adapter\n");
> > +       }
> > +
> > +       for_each_child_of_node(i2c_node, node) {
>
> The I2C core will walk the devices too. Perhaps if that saves off a
> list of failed devices, then we don't need to walk the nodes again.

I will look into it.

> > +               struct property *prop;
> > +               union i2c_smbus_data data;
> > +               u32 addr;
> > +
> > +               if (!of_node_name_prefix(node, node_name))
> > +                       continue;
> > +               if (of_property_read_u32(node, "reg", &addr))
> > +                       continue;
> > +               if (i2c_smbus_xfer(i2c, addr, 0, I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE, &data) < 0)
> > +                       continue;
> > +
> > +               dev_info(&pdev->dev, "Enabling %pOF\n", node);
> > +
> > +               prop = kzalloc(sizeof(*prop), GFP_KERNEL);
> > +               if (!prop) {
> > +                       ret = -ENOMEM;
> > +                       of_node_put(node);
> > +                       break;
> > +               }
> > +
> > +               prop->name      = "status";
> > +               prop->length    = 5;
> > +               prop->value     = "okay";
> > +
> > +               /* Found a device that is responding */
> > +               ret = of_update_property(node, prop);
>
> Use the changeset API instead and make an update flavor of
> of_changeset_add_prop_string().

Ack. However I don't really like the API, as there is no easy way to free
the allocated property if of_changeset_apply fails and we want to clean up.

> > +               if (ret)
> > +                       kfree(prop);
> > +
> > +               of_node_put(node);
> > +               break;
> > +       }
> > +
> > +       i2c_put_adapter(i2c);
> > +       of_node_put(i2c_node);
> > +
> > +       return ret;
> > +}
> > +
> > +static const struct hw_prober_entry hw_prober_platforms[] = {
> > +       { .compatible = "google,hana", .prober = i2c_component_prober, .data = "touchscreen" },
> > +       { .compatible = "google,hana", .prober = i2c_component_prober, .data = "trackpad" },
>
> Not generic code. Needs to be somewhere else.

OK. How about drivers/platform/chrome/ for the non-generic bits and the other
prober patch?

> > +};
> > +
> > +static int hw_prober_probe(struct platform_device *pdev)
> > +{
> > +       for (int i = 0; i < ARRAY_SIZE(hw_prober_platforms); i++)
> > +               if (of_machine_is_compatible(hw_prober_platforms[i].compatible)) {
> > +                       int ret;
> > +
> > +                       ret = hw_prober_platforms[i].prober(pdev, hw_prober_platforms[i].data);
> > +                       if (ret)
> > +                               return ret;
> > +               }
> > +
> > +       return 0;
> > +}
> > +
> > +static struct platform_driver hw_prober_driver = {
> > +       .probe  = hw_prober_probe,
> > +       .driver = {
> > +               .name = DRV_NAME,
> > +       },
> > +};
> > +
> > +static int __init hw_prober_driver_init(void)
> > +{
> > +       struct platform_device *pdev;
> > +       int ret;
> > +
> > +       ret = platform_driver_register(&hw_prober_driver);
> > +       if (ret)
> > +               return ret;
> > +
> > +       pdev = platform_device_register_simple(DRV_NAME, -1, NULL, 0);
>
> This should be dependent on platforms that need it, not everyone. IOW,
> this is where checking for "google,hana" belongs.

Ack.

Thanks
ChenYu

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH v2 0/7] of: Introduce hardware prober driver
  2023-11-11  0:22 ` Doug Anderson
@ 2023-11-14  8:44   ` Chen-Yu Tsai
  0 siblings, 0 replies; 30+ messages in thread
From: Chen-Yu Tsai @ 2023-11-14  8:44 UTC (permalink / raw)
  To: Doug Anderson
  Cc: Rob Herring, Frank Rowand, Krzysztof Kozlowski, Conor Dooley,
	Matthias Brugger, AngeloGioacchino Del Regno, Hsin-Yi Wang,
	Dmitry Torokhov, andriy.shevchenko, Jiri Kosina, linus.walleij,
	broonie, gregkh, hdegoede, james.clark, james, keescook, rafael,
	tglx, Jeff LaBundy, linux-input, devicetree, linux-arm-kernel,
	linux-mediatek, linux-kernel, Johan Hovold

On Sat, Nov 11, 2023 at 8:22 AM Doug Anderson <dianders@chromium.org> wrote:
>
> Hi,
>
> On Thu, Nov 9, 2023 at 2:06 AM Chen-Yu Tsai <wenst@chromium.org> wrote:
> >
> > The driver as
> > implemented currently doesn't deal with regulators or GPIO pins,
> > since in the existing device trees they are either always on for
> > regulators, or have GPIO hogs or pinmux and pinconfig directly
> > tied to the pin controller.
>
> I guess I won't object too much about this limitation for v1, but IMO
> it would be good to get this sorted out since I think part of the
> power of having the HW Prober is specifically that it can handle this
> type of use case. You have a little bit of board-specific code that
> knows how to turn on the regulators / GPIOs and can then probe the
> devices.
>
> Note: even if this is "board specific", it doesn't mean you couldn't
> share code between boards. For instance, you could have a helper
> function that would turn on regulators/GPIOs based on some type of
> table and that helper function could be used across a whole pile of
> Chromebooks. If a Chromebook is sufficiently different that it
> couldn't use the helper function then it could call its own function,
> but presumably it wouldn't be hard to support a bunch of boards
> without much code.

I agree this part is fairly generic and should be implemented.

We probably don't even need such a table. If these components share
a common connection to the mainboard, they certainly will have the
same GPIO lines and regulator supplies. The prober could just scan
the nodes looking for -gpio and -supply properties, de-duplicate
them, and turn them on.

The reason this isn't implemented in this version is because the devices
I'm currently using do not have these resources togglable. The supply is
always on, and the GPIO line is disconnected from the SoC. So I have no
way of testing it yet.

> As part of this, I think that your main "HW Prober" for Chromebooks
> should be in "drivers/platform/chrome/". I think that the only things
> that should be in the "drivers/of" directory should be helper
> functions used by the Chromebook HW Probers.

Sound like what Rob wants.

ChenYu

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH v2 0/7] of: Introduce hardware prober driver
  2023-11-09 10:54 ` [RFC PATCH v2 0/7] of: Introduce hardware prober driver AngeloGioacchino Del Regno
  2023-11-09 13:51   ` Rob Herring
@ 2023-11-14  8:57   ` Chen-Yu Tsai
  2023-11-14 10:04     ` AngeloGioacchino Del Regno
  1 sibling, 1 reply; 30+ messages in thread
From: Chen-Yu Tsai @ 2023-11-14  8:57 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno
  Cc: Rob Herring, Frank Rowand, Krzysztof Kozlowski, Conor Dooley,
	Matthias Brugger, Hsin-Yi Wang, Dmitry Torokhov,
	andriy.shevchenko, Jiri Kosina, linus.walleij, broonie, gregkh,
	hdegoede, james.clark, james, keescook, rafael, tglx,
	Jeff LaBundy, linux-input, devicetree, linux-arm-kernel,
	linux-mediatek, linux-kernel, Douglas Anderson, Johan Hovold

On Thu, Nov 9, 2023 at 6:54 PM AngeloGioacchino Del Regno
<angelogioacchino.delregno@collabora.com> wrote:
>
> Il 09/11/23 11:05, Chen-Yu Tsai ha scritto:
> > Hi everyone,
> >
> > This v2 series continues Doug's "of: device: Support 2nd sources of
> > probeable but undiscoverable devices" [1] series, but follows the scheme
> > suggested by Rob, marking all second source component device nodes
> > as "fail-needs-probe-XXX", and having a hardware prober driver enable
> > the one of them. I tried to include everyone from the original Cc: list.
> > Please let me know if you would like to be dropped from future
> > submissions.
> >
> >
> > For the I2C component (touchscreens and trackpads) case from the
> > original series, the hardware prober driver finds the particular
> > class of device in the device tree, gets its parent I2C adapter,
> > and tries to initiate a simple I2C read for each device under that
> > I2C bus. When it finds one that responds, it considers that one
> > present, marks it as "okay", and returns, letting the driver core
> > actually probe the device.
> >
> > This works fine in most cases since these components are connected
> > via ribbon cable and always have the same resources. The driver as
> > implemented currently doesn't deal with regulators or GPIO pins,
> > since in the existing device trees they are either always on for
> > regulators, or have GPIO hogs or pinmux and pinconfig directly
> > tied to the pin controller.
> >
> >
> > Another case this driver could handle is selecting components based
> > on some identifier passed in by the firmware. On Chromebooks we have
> > a SKU ID which is inserted by the bootloader at
> > /firmware/coreboot/sku-id. When a new combination of components is
> > introduced, a new SKU ID is allocated to it. To have SKU ID based
> > device trees, we would need to have one per SKU ID. This ends up
> > increasing the number of device trees we have a lot. The recent
> > MT8186 devices already have 10+10 SKUs [2], with possibly more to come.
> >
> > Instead, we could have just one device tree for each device, with
> > component options listed and marked as "fail-needs-probe-XXX", and
> > let the hardware prober enable one of them based on the given SKU ID.
> > The driver will also fix up OF graph remote endpoints to point to the
> > enabled component.
> >
> > The MT8186 Corsola series [2] can also benefit from this, though I
> > haven't implemented anything yet.
> >
> >
> > Patch 1 adds of_device_is_fail() for the new driver to use.
> >
> > Patch 2 implements the first case, probing the I2C bus for presence
> > of components. This initial version targets the Hana Chromebooks.
> >
> > Patch 3 modifies the Hana device tree and marks the touchscreens
> > and trackpads as "fail-needs-probe-XXX", ready for the driver to
> > probe.
> >
> > Patch 4 adds a missing touchscreen variant to Hana.
> >
> > Patch 5 implements the second case, selectively enabling components
> > based on the SKU ID. This initial version targets the Krane ChromeOS
> > tablet, which has two possible MIPI DSI display panel options.
> >
> > Patch 6 drops Krane's SKU-specific compatible strings from the bindings.
> >
> > Patch 7 merges Krane's SKU-specific device trees into one, with the
> > device tree now containing two possible panels. This unfortunately
> > introduces a dtc warning:
> >
> >      arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dts:81.13-83.6:
> >          Warning (graph_endpoint): /soc/dsi@14014000/panel2@0/port/endpoint:
> >       graph connection to node '/soc/dsi@14014000/ports/port/endpoint'
> >           is not bidirectional
> >
> >
> > Please take a look.
> >
> > Johan, I'm not sure if this works as is for the Lenovo Thinkpad 13S
> > case, since it looks like the trackpad shares the I2C bus with the
> > keyboard.
> >
> >
> > Thanks
> > ChenYu
> >
> >
> > Background as given in Doug's cover letter:
> >
> > Support for multiple "equivalent" sources for components (also known
> > as second sourcing components) is a standard practice that helps keep
> > cost down and also makes sure that if one component is unavailable due
> > to a shortage that we don't need to stop production for the whole
> > product.
> >
> > Some components are very easy to second source. eMMC, for instance, is
> > fully discoverable and probable so you can stuff a wide variety of
> > similar eMMC chips on your board and things will work without a hitch.
> >
> > Some components are more difficult to second source, specifically
> > because it's difficult for software to probe what component is present
> > on any given board. In cases like this software is provided
> > supplementary information to help it, like a GPIO strap or a SKU ID
> > programmed into an EEPROM. This helpful information can allow the
> > bootloader to select a different device tree. The various different
> > "SKUs" of different Chromebooks are examples of this.
> >
> > Some components are somewhere in between. These in-between components
> > are the subject of this patch. Specifically, these components are
> > easily "probeable" but not easily "discoverable".
> >
> > A good example of a probeable but undiscoverable device is an
> > i2c-connected touchscreen or trackpad. Two separate components may be
> > electrically compatible with each other and may have compatible power
> > sequencing requirements but may require different software. If
> > software is told about the different possible components (because it
> > can't discover them), it can safely probe them to figure out which
> > ones are present.
> >
> > On systems using device tree, if we want to tell the OS about all of
> > the different components we need to list them all in the device
> > tree. This leads to a problem. The multiple sources for components
> > likely use the same resources (GPIOs, interrupts, regulators). If the
> > OS tries to probe all of these components at the same time then it
> > will detect a resource conflict and that's a fatal error.
> >
> > The fact that Linux can't handle these probeable but undiscoverable
> > devices well has had a few consequences:
> > 1. In some cases, we've abandoned the idea of second sourcing
> >     components for a given board, which increases cost / generates
> >     manufacturing headaches.
> > 2. In some cases, we've been forced to add some sort of strapping /
> >     EEPROM to indicate which component is present. This adds difficulty
> >     to manufacturing / refurb processes.
> > 3. In some cases, we've managed to make things work by the skin of our
> >     teeth through slightly hacky solutions. Specifically, if we remove
> >     the "pinctrl" entry from the various options then it won't
> >     conflict. Regulators inherently can have more than one consumer, so
> >     as long as there are no GPIOs involved in power sequencing and
> >     probing devices then things can work. This is how
> >     "sc8280xp-lenovo-thinkpad-x13s" works and also how
> >     "mt8173-elm-hana" works.
> >
> > End of background from Doug's cover letter.
>
> I think that using "status" is not a good idea, I find that confusing.

It isn't a hard requirement. The current I2C prober actually just looks
at the node name, which already should be a generic class type. It then
assumes that all the components of the same class that it is supposed
to probe for are on the same bus. I think this is a fair assumption for
replaceable parts connected via ribbon cable or co-layout parts?

> Perhaps we could have a node like
>
> something {
>         device-class-one = <&device1>, <&device2>, <&device3>;
>         device-class-two = <&device4>, <&device5>, <&device6>;
> }
>
> so that'd be more or less
>
> hw-prober {
>         trackpads = <&tp1>, <&tp2>;
>         keyboards = <&kb1>, <&kb2>;
>         touchscreens = <&ts1>, <&ts2>;
> }

This was already nacked by Rob.

> Besides, something else I can suggest here is to make this more generic: actually,
> this issue is spread across way more devices than you maybe think... for example,
> I know of some smartphones that may have the same situation with DSI displays and
> they're sometimes distinguished by an ADC value, sometimes by reading back the
> manufacturer ID (or panel id) through DSI.

ADC strapping is common. Though we might need some kind of binding about how
to describe the ADC strapping scheme, as this is bound to be different across
boards.

Reading back from DSI feels problematic to implement. But I don't know much
about DSI ATM. Doug implied in our offline discussion that DSI panels might
have power sequencing requirements that are all over the place.

> Also, if Chromebooks really need something "special", such as that coreboot sku-id
> parameter, I think that this should be registered externally into the hw prober
> and not embedded inside of the *generic* hw prober driver.
>
> We can even reuse of_device_id instead of inventing a new hw_prober_entry struct...
>
> Idea:
>
> drivers/platform/chrome/cros_of_hw_prober.c
>
> static int cros_sku_hw_prober(struct platform_device *pdev, const void *data)
> {
>         ...this is your cros_sku_component_selector() function, anyway...
> }
>
> static const struct of_device_id cros_hw_prober_ids[] = {
>         { .compatible = "google,hana", .data = something },
>         { /* sentinel */ }
> };
>
> static int some_kind_of_early_init_function(something)
> {
>         int a,b,c,ret,something;
>
>         .. some logic if necessary ..
>
>         return of_hw_prober_register(cros_sku_hw_prober, cros_hw_prober_ids);
> }

This feels a bit too layered, and requires all the board specific code to
have an early init function. I think exposing common helper functions for
boards to implement prober drivers would be better. Then the prober could
also be a module if that made sense. Given that SoC vendors are making
clock controller drivers modules, this doesn't seem very far fetched.

> Btw, thanks for starting that. If this will be done the right way, it's going to
> be useful to many, many people.

Right. I only have a limited view of applications, so input is always welcome.

Thanks
ChenYu

> Regards,
> Angelo
>
> >
> > [1] https://lore.kernel.org/all/20230921102420.RFC.1.I9dddd99ccdca175e3ceb1b9fa1827df0928c5101@changeid/
> > [2] https://lore.kernel.org/linux-mediatek/20231012230237.2676469-1-wenst@chromium.org/
> >
> > Chen-Yu Tsai (7):
> >    of: base: Add of_device_is_fail
> >    of: Introduce hardware prober driver
> >    arm64: dts: mediatek: mt8173-elm-hana: Mark touchscreens and trackpads
> >      as fail
> >    arm64: dts: mediatek: mt8173-elm-hana: Add G2touch G7500 touchscreen
> >    of: hw_prober: Support Chromebook SKU ID based component selection
> >    dt-bindings: arm: mediatek: Remove SKU specific compatibles for Google
> >      Krane
> >    arm64: dts: mediatek: mt8183-kukui: Merge Krane device trees
> >
> >   .../devicetree/bindings/arm/mediatek.yaml     |   3 -
> >   arch/arm64/boot/dts/mediatek/Makefile         |   3 +-
> >   .../boot/dts/mediatek/mt8173-elm-hana.dtsi    |  20 ++
> >   .../dts/mediatek/mt8183-kukui-krane-sku0.dts  |  24 --
> >   .../mediatek/mt8183-kukui-krane-sku176.dts    |  24 --
> >   ...ukui-krane.dtsi => mt8183-kukui-krane.dts} |  47 ++-
> >   drivers/of/Kconfig                            |  13 +
> >   drivers/of/Makefile                           |   1 +
> >   drivers/of/base.c                             |  20 ++
> >   drivers/of/hw_prober.c                        | 314 ++++++++++++++++++
> >   include/linux/of.h                            |   6 +
> >   11 files changed, 418 insertions(+), 57 deletions(-)
> >   delete mode 100644 arch/arm64/boot/dts/mediatek/mt8183-kukui-krane-sku0.dts
> >   delete mode 100644 arch/arm64/boot/dts/mediatek/mt8183-kukui-krane-sku176.dts
> >   rename arch/arm64/boot/dts/mediatek/{mt8183-kukui-krane.dtsi => mt8183-kukui-krane.dts} (86%)
> >   create mode 100644 drivers/of/hw_prober.c
> >
>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH v2 0/7] of: Introduce hardware prober driver
  2023-11-14  8:57   ` Chen-Yu Tsai
@ 2023-11-14 10:04     ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 30+ messages in thread
From: AngeloGioacchino Del Regno @ 2023-11-14 10:04 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Rob Herring, Frank Rowand, Krzysztof Kozlowski, Conor Dooley,
	Matthias Brugger, Hsin-Yi Wang, Dmitry Torokhov,
	andriy.shevchenko, Jiri Kosina, linus.walleij, broonie, gregkh,
	hdegoede, james.clark, james, keescook, rafael, tglx,
	Jeff LaBundy, linux-input, devicetree, linux-arm-kernel,
	linux-mediatek, linux-kernel, Douglas Anderson, Johan Hovold

Il 14/11/23 09:57, Chen-Yu Tsai ha scritto:
> On Thu, Nov 9, 2023 at 6:54 PM AngeloGioacchino Del Regno
> <angelogioacchino.delregno@collabora.com> wrote:
>>
>> Il 09/11/23 11:05, Chen-Yu Tsai ha scritto:
>>> Hi everyone,
>>>
>>> This v2 series continues Doug's "of: device: Support 2nd sources of
>>> probeable but undiscoverable devices" [1] series, but follows the scheme
>>> suggested by Rob, marking all second source component device nodes
>>> as "fail-needs-probe-XXX", and having a hardware prober driver enable
>>> the one of them. I tried to include everyone from the original Cc: list.
>>> Please let me know if you would like to be dropped from future
>>> submissions.
>>>
>>>
>>> For the I2C component (touchscreens and trackpads) case from the
>>> original series, the hardware prober driver finds the particular
>>> class of device in the device tree, gets its parent I2C adapter,
>>> and tries to initiate a simple I2C read for each device under that
>>> I2C bus. When it finds one that responds, it considers that one
>>> present, marks it as "okay", and returns, letting the driver core
>>> actually probe the device.
>>>
>>> This works fine in most cases since these components are connected
>>> via ribbon cable and always have the same resources. The driver as
>>> implemented currently doesn't deal with regulators or GPIO pins,
>>> since in the existing device trees they are either always on for
>>> regulators, or have GPIO hogs or pinmux and pinconfig directly
>>> tied to the pin controller.
>>>
>>>
>>> Another case this driver could handle is selecting components based
>>> on some identifier passed in by the firmware. On Chromebooks we have
>>> a SKU ID which is inserted by the bootloader at
>>> /firmware/coreboot/sku-id. When a new combination of components is
>>> introduced, a new SKU ID is allocated to it. To have SKU ID based
>>> device trees, we would need to have one per SKU ID. This ends up
>>> increasing the number of device trees we have a lot. The recent
>>> MT8186 devices already have 10+10 SKUs [2], with possibly more to come.
>>>
>>> Instead, we could have just one device tree for each device, with
>>> component options listed and marked as "fail-needs-probe-XXX", and
>>> let the hardware prober enable one of them based on the given SKU ID.
>>> The driver will also fix up OF graph remote endpoints to point to the
>>> enabled component.
>>>
>>> The MT8186 Corsola series [2] can also benefit from this, though I
>>> haven't implemented anything yet.
>>>
>>>
>>> Patch 1 adds of_device_is_fail() for the new driver to use.
>>>
>>> Patch 2 implements the first case, probing the I2C bus for presence
>>> of components. This initial version targets the Hana Chromebooks.
>>>
>>> Patch 3 modifies the Hana device tree and marks the touchscreens
>>> and trackpads as "fail-needs-probe-XXX", ready for the driver to
>>> probe.
>>>
>>> Patch 4 adds a missing touchscreen variant to Hana.
>>>
>>> Patch 5 implements the second case, selectively enabling components
>>> based on the SKU ID. This initial version targets the Krane ChromeOS
>>> tablet, which has two possible MIPI DSI display panel options.
>>>
>>> Patch 6 drops Krane's SKU-specific compatible strings from the bindings.
>>>
>>> Patch 7 merges Krane's SKU-specific device trees into one, with the
>>> device tree now containing two possible panels. This unfortunately
>>> introduces a dtc warning:
>>>
>>>       arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dts:81.13-83.6:
>>>           Warning (graph_endpoint): /soc/dsi@14014000/panel2@0/port/endpoint:
>>>        graph connection to node '/soc/dsi@14014000/ports/port/endpoint'
>>>            is not bidirectional
>>>
>>>
>>> Please take a look.
>>>
>>> Johan, I'm not sure if this works as is for the Lenovo Thinkpad 13S
>>> case, since it looks like the trackpad shares the I2C bus with the
>>> keyboard.
>>>
>>>
>>> Thanks
>>> ChenYu
>>>
>>>
>>> Background as given in Doug's cover letter:
>>>
>>> Support for multiple "equivalent" sources for components (also known
>>> as second sourcing components) is a standard practice that helps keep
>>> cost down and also makes sure that if one component is unavailable due
>>> to a shortage that we don't need to stop production for the whole
>>> product.
>>>
>>> Some components are very easy to second source. eMMC, for instance, is
>>> fully discoverable and probable so you can stuff a wide variety of
>>> similar eMMC chips on your board and things will work without a hitch.
>>>
>>> Some components are more difficult to second source, specifically
>>> because it's difficult for software to probe what component is present
>>> on any given board. In cases like this software is provided
>>> supplementary information to help it, like a GPIO strap or a SKU ID
>>> programmed into an EEPROM. This helpful information can allow the
>>> bootloader to select a different device tree. The various different
>>> "SKUs" of different Chromebooks are examples of this.
>>>
>>> Some components are somewhere in between. These in-between components
>>> are the subject of this patch. Specifically, these components are
>>> easily "probeable" but not easily "discoverable".
>>>
>>> A good example of a probeable but undiscoverable device is an
>>> i2c-connected touchscreen or trackpad. Two separate components may be
>>> electrically compatible with each other and may have compatible power
>>> sequencing requirements but may require different software. If
>>> software is told about the different possible components (because it
>>> can't discover them), it can safely probe them to figure out which
>>> ones are present.
>>>
>>> On systems using device tree, if we want to tell the OS about all of
>>> the different components we need to list them all in the device
>>> tree. This leads to a problem. The multiple sources for components
>>> likely use the same resources (GPIOs, interrupts, regulators). If the
>>> OS tries to probe all of these components at the same time then it
>>> will detect a resource conflict and that's a fatal error.
>>>
>>> The fact that Linux can't handle these probeable but undiscoverable
>>> devices well has had a few consequences:
>>> 1. In some cases, we've abandoned the idea of second sourcing
>>>      components for a given board, which increases cost / generates
>>>      manufacturing headaches.
>>> 2. In some cases, we've been forced to add some sort of strapping /
>>>      EEPROM to indicate which component is present. This adds difficulty
>>>      to manufacturing / refurb processes.
>>> 3. In some cases, we've managed to make things work by the skin of our
>>>      teeth through slightly hacky solutions. Specifically, if we remove
>>>      the "pinctrl" entry from the various options then it won't
>>>      conflict. Regulators inherently can have more than one consumer, so
>>>      as long as there are no GPIOs involved in power sequencing and
>>>      probing devices then things can work. This is how
>>>      "sc8280xp-lenovo-thinkpad-x13s" works and also how
>>>      "mt8173-elm-hana" works.
>>>
>>> End of background from Doug's cover letter.
>>
>> I think that using "status" is not a good idea, I find that confusing.
> 
> It isn't a hard requirement. The current I2C prober actually just looks
> at the node name, which already should be a generic class type. It then
> assumes that all the components of the same class that it is supposed
> to probe for are on the same bus. I think this is a fair assumption for
> replaceable parts connected via ribbon cable or co-layout parts?
> 

Assuming that the parts are on the exact same bus is ok, there has to be a
flexibility limit, or this framework will definitely get abused in the wrong
ways.

>> Perhaps we could have a node like
>>
>> something {
>>          device-class-one = <&device1>, <&device2>, <&device3>;
>>          device-class-two = <&device4>, <&device5>, <&device6>;
>> }
>>
>> so that'd be more or less
>>
>> hw-prober {
>>          trackpads = <&tp1>, <&tp2>;
>>          keyboards = <&kb1>, <&kb2>;
>>          touchscreens = <&ts1>, <&ts2>;
>> }
> 
> This was already nacked by Rob.

Oh. Oops. :-)

> 
>> Besides, something else I can suggest here is to make this more generic: actually,
>> this issue is spread across way more devices than you maybe think... for example,
>> I know of some smartphones that may have the same situation with DSI displays and
>> they're sometimes distinguished by an ADC value, sometimes by reading back the
>> manufacturer ID (or panel id) through DSI.
> 
> ADC strapping is common. Though we might need some kind of binding about how
> to describe the ADC strapping scheme, as this is bound to be different across
> boards.
> 
> Reading back from DSI feels problematic to implement. But I don't know much
> about DSI ATM. Doug implied in our offline discussion that DSI panels might
> have power sequencing requirements that are all over the place.
> 

This is exactly why I think that this should allow a certain kind of "modularity",
meaning that subsystems should be able to register their own hook into this: in
both cases of ADC and/or DSI readback we're getting into some fairly (less, or
more) complicated territory - and it's something that people around each subsystem
knows best - and they must have that kind of flexibility and freedom to change the
hooked implementation in their own subsystem instead of somewhere else.

There would be much more to say about this, but I'm avoiding to write a wall of
text because I'm sure that you can read through the lines and can get my point
anyway.

>> Also, if Chromebooks really need something "special", such as that coreboot sku-id
>> parameter, I think that this should be registered externally into the hw prober
>> and not embedded inside of the *generic* hw prober driver.
>>
>> We can even reuse of_device_id instead of inventing a new hw_prober_entry struct...
>>
>> Idea:
>>
>> drivers/platform/chrome/cros_of_hw_prober.c
>>
>> static int cros_sku_hw_prober(struct platform_device *pdev, const void *data)
>> {
>>          ...this is your cros_sku_component_selector() function, anyway...
>> }
>>
>> static const struct of_device_id cros_hw_prober_ids[] = {
>>          { .compatible = "google,hana", .data = something },
>>          { /* sentinel */ }
>> };
>>
>> static int some_kind_of_early_init_function(something)
>> {
>>          int a,b,c,ret,something;
>>
>>          .. some logic if necessary ..
>>
>>          return of_hw_prober_register(cros_sku_hw_prober, cros_hw_prober_ids);
>> }
> 
> This feels a bit too layered, and requires all the board specific code to
> have an early init function. I think exposing common helper functions for
> boards to implement prober drivers would be better. Then the prober could
> also be a module if that made sense. Given that SoC vendors are making
> clock controller drivers modules, this doesn't seem very far fetched.
> 

That would as well work - and would be way better than early init. Reading it back
now, putting that in a early init function would be counter-productive in general.

>> Btw, thanks for starting that. If this will be done the right way, it's going to
>> be useful to many, many people.
> 
> Right. I only have a limited view of applications, so input is always welcome.
> 
> Thanks
> ChenYu
> 
>> Regards,
>> Angelo
>>
>>>
>>> [1] https://lore.kernel.org/all/20230921102420.RFC.1.I9dddd99ccdca175e3ceb1b9fa1827df0928c5101@changeid/
>>> [2] https://lore.kernel.org/linux-mediatek/20231012230237.2676469-1-wenst@chromium.org/
>>>
>>> Chen-Yu Tsai (7):
>>>     of: base: Add of_device_is_fail
>>>     of: Introduce hardware prober driver
>>>     arm64: dts: mediatek: mt8173-elm-hana: Mark touchscreens and trackpads
>>>       as fail
>>>     arm64: dts: mediatek: mt8173-elm-hana: Add G2touch G7500 touchscreen
>>>     of: hw_prober: Support Chromebook SKU ID based component selection
>>>     dt-bindings: arm: mediatek: Remove SKU specific compatibles for Google
>>>       Krane
>>>     arm64: dts: mediatek: mt8183-kukui: Merge Krane device trees
>>>
>>>    .../devicetree/bindings/arm/mediatek.yaml     |   3 -
>>>    arch/arm64/boot/dts/mediatek/Makefile         |   3 +-
>>>    .../boot/dts/mediatek/mt8173-elm-hana.dtsi    |  20 ++
>>>    .../dts/mediatek/mt8183-kukui-krane-sku0.dts  |  24 --
>>>    .../mediatek/mt8183-kukui-krane-sku176.dts    |  24 --
>>>    ...ukui-krane.dtsi => mt8183-kukui-krane.dts} |  47 ++-
>>>    drivers/of/Kconfig                            |  13 +
>>>    drivers/of/Makefile                           |   1 +
>>>    drivers/of/base.c                             |  20 ++
>>>    drivers/of/hw_prober.c                        | 314 ++++++++++++++++++
>>>    include/linux/of.h                            |   6 +
>>>    11 files changed, 418 insertions(+), 57 deletions(-)
>>>    delete mode 100644 arch/arm64/boot/dts/mediatek/mt8183-kukui-krane-sku0.dts
>>>    delete mode 100644 arch/arm64/boot/dts/mediatek/mt8183-kukui-krane-sku176.dts
>>>    rename arch/arm64/boot/dts/mediatek/{mt8183-kukui-krane.dtsi => mt8183-kukui-krane.dts} (86%)
>>>    create mode 100644 drivers/of/hw_prober.c
>>>
>>




^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH v2 0/7] of: Introduce hardware prober driver
  2023-11-11  0:12     ` Doug Anderson
@ 2023-11-15 19:28       ` Rob Herring
  2023-11-15 20:44         ` Doug Anderson
  0 siblings, 1 reply; 30+ messages in thread
From: Rob Herring @ 2023-11-15 19:28 UTC (permalink / raw)
  To: Doug Anderson
  Cc: AngeloGioacchino Del Regno, Chen-Yu Tsai, Frank Rowand,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger, Hsin-Yi Wang,
	Dmitry Torokhov, andriy.shevchenko, Jiri Kosina, linus.walleij,
	broonie, gregkh, hdegoede, james.clark, james, keescook,
	petr.tesarik.ext, rafael, tglx, Jeff LaBundy, linux-input,
	devicetree, linux-arm-kernel, linux-mediatek, linux-kernel,
	Johan Hovold

On Fri, Nov 10, 2023 at 6:12 PM Doug Anderson <dianders@chromium.org> wrote:
>
> Hi,
>
> On Thu, Nov 9, 2023 at 5:52 AM Rob Herring <robh+dt@kernel.org> wrote:
> >
> > > > End of background from Doug's cover letter.
> > >
> > > I think that using "status" is not a good idea, I find that confusing.
> >
> > "status" is what defines a device's state in terms of enabled,
> > present, available. That's exactly what we're expressing here.
> >
> > Now, I do not think we should be mixing the device class (e.g.
> > touchscreen) into status. I said this on v1, but apparently that was
> > not listened to.
>
> Interesting. I must have missed the "don't mix device class into
> status" part. Do you have a link to your post about that? Maybe
> there's other stuff I missed... Having the device class stuck at the
> end there was at least part of my last post [1] which gathered no
> response.

https://lore.kernel.org/all/CAL_JsqKK0tjeXNv=a8L3k0AjhCa15XOq1tPWqVod9mycsKXJHg@mail.gmail.com/

"I would not combine the 2 things. Knowing the class/type of the device
may be useful independent of your problem."


> I think one of the reasons that I felt we needed to mux the device
> class into status was that it was going to make the code a lot less
> fragile. Everything I've seen indicates that you don't want us to
> create a "HW prober" node that could be used to provide relevant
> phandles for different classes of devices, so the "HW prober" code
> needs to either search through the whole device tree for a status of
> "failed-needs-probe" or needs to contain per-board, hardcoded,
> fully-qualified paths.
>
> I don't think we want to include hardcoded, fully-qualified paths in
> the code. That would mean that if someone changed a node name
> somewhere in the path to one of the devices that we're dealing with
> then it would break.

Right, nothing should depend on the full path. That's not an ABI just
like the device path in sysfs is not (despite what Android HALs do).

> So if we're searching the whole device tree for "failed-needs-probe"
> then we need to figure out which devices are related to each other. If
> a given board has second sources for MIPI panels, touchscreens, and
> trackpads then we need to know which of the "failed-needs-probe"
> devices are trackpads, which are touchscreens, and which are MIPI
> panels. Do you have any suggestions for how we should do that? Maybe
> it was in some other thread that I missed? I guess we could have a
> board-specific table mapping (compatible + node name + reg) to a
> class, but that feels awkward.

Node name is supposed to correspond to device class, so why not use
that (no path or unit-address.) and nothing else (well, besides
"status")?

Rob

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH v2 0/7] of: Introduce hardware prober driver
  2023-11-15 19:28       ` Rob Herring
@ 2023-11-15 20:44         ` Doug Anderson
  2023-11-15 21:34           ` Rob Herring
  0 siblings, 1 reply; 30+ messages in thread
From: Doug Anderson @ 2023-11-15 20:44 UTC (permalink / raw)
  To: Rob Herring
  Cc: AngeloGioacchino Del Regno, Chen-Yu Tsai, Frank Rowand,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger, Hsin-Yi Wang,
	Dmitry Torokhov, andriy.shevchenko, Jiri Kosina, linus.walleij,
	broonie, gregkh, hdegoede, james.clark, james, keescook,
	petr.tesarik.ext, rafael, tglx, Jeff LaBundy, linux-input,
	devicetree, linux-arm-kernel, linux-mediatek, linux-kernel,
	Johan Hovold

Hi,

On Wed, Nov 15, 2023 at 2:28 PM Rob Herring <robh+dt@kernel.org> wrote:
>
> > So if we're searching the whole device tree for "failed-needs-probe"
> > then we need to figure out which devices are related to each other. If
> > a given board has second sources for MIPI panels, touchscreens, and
> > trackpads then we need to know which of the "failed-needs-probe"
> > devices are trackpads, which are touchscreens, and which are MIPI
> > panels. Do you have any suggestions for how we should do that? Maybe
> > it was in some other thread that I missed? I guess we could have a
> > board-specific table mapping (compatible + node name + reg) to a
> > class, but that feels awkward.
>
> Node name is supposed to correspond to device class, so why not use
> that (no path or unit-address.) and nothing else (well, besides
> "status")?

One problem is that I could imagine having two second source trackpads
that both have the same i2c address. That would give them the same
name, right? I guess you could maybe come up with some sort of suffix
rule? Like

trackpad-1@10 {
  compatible = "elan,blah";
  ret = <0x10>;
  status = "failed-needs-probe";
  ...
}
trackpad-2@10 {
  compatible = "goodix,gt7375p";
  ret = <0x10>;
  status = "failed-needs-probe";
  ...
}

Then I guess the class would be "trackpad"?


-Doug

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH v2 0/7] of: Introduce hardware prober driver
  2023-11-15 20:44         ` Doug Anderson
@ 2023-11-15 21:34           ` Rob Herring
  2023-11-15 22:13             ` Doug Anderson
  2023-11-16  5:07             ` Chen-Yu Tsai
  0 siblings, 2 replies; 30+ messages in thread
From: Rob Herring @ 2023-11-15 21:34 UTC (permalink / raw)
  To: Doug Anderson
  Cc: AngeloGioacchino Del Regno, Chen-Yu Tsai, Frank Rowand,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger, Hsin-Yi Wang,
	Dmitry Torokhov, andriy.shevchenko, Jiri Kosina, linus.walleij,
	broonie, gregkh, hdegoede, james.clark, james, keescook,
	petr.tesarik.ext, rafael, tglx, Jeff LaBundy, linux-input,
	devicetree, linux-arm-kernel, linux-mediatek, linux-kernel,
	Johan Hovold

On Wed, Nov 15, 2023 at 2:45 PM Doug Anderson <dianders@chromium.org> wrote:
>
> Hi,
>
> On Wed, Nov 15, 2023 at 2:28 PM Rob Herring <robh+dt@kernel.org> wrote:
> >
> > > So if we're searching the whole device tree for "failed-needs-probe"
> > > then we need to figure out which devices are related to each other. If
> > > a given board has second sources for MIPI panels, touchscreens, and
> > > trackpads then we need to know which of the "failed-needs-probe"
> > > devices are trackpads, which are touchscreens, and which are MIPI
> > > panels. Do you have any suggestions for how we should do that? Maybe
> > > it was in some other thread that I missed? I guess we could have a
> > > board-specific table mapping (compatible + node name + reg) to a
> > > class, but that feels awkward.
> >
> > Node name is supposed to correspond to device class, so why not use
> > that (no path or unit-address.) and nothing else (well, besides
> > "status")?
>
> One problem is that I could imagine having two second source trackpads
> that both have the same i2c address. That would give them the same
> name, right? I guess you could maybe come up with some sort of suffix
> rule? Like
>
> trackpad-1@10 {
>   compatible = "elan,blah";
>   ret = <0x10>;
>   status = "failed-needs-probe";
>   ...
> }
> trackpad-2@10 {
>   compatible = "goodix,gt7375p";
>   ret = <0x10>;
>   status = "failed-needs-probe";
>   ...
> }
>
> Then I guess the class would be "trackpad"?

That issue is somewhat orthogonal because it is not following the spec.

I'm not sure mixing the 2 styles of node names is a good idea. While
not used too much, matching by node name does ignore the unit-address,
but I'm not sure we could ignore a '-N'.

I think our options are either add something to the unit-address or
use i2c-mux binding. Adding to the unit-address is not unprecedented.
I did that for some of the register bit level bindings where you have
a node for different bits at the same address. The downside is
unit-address is bus specific, so we'd have to add that for multiple
buses. For the i2c-mux, it's perhaps a bit complex and I'm not sure
what if anything you'd have to do to manage the mux that's not really
there.

Rob

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH v2 0/7] of: Introduce hardware prober driver
  2023-11-15 21:34           ` Rob Herring
@ 2023-11-15 22:13             ` Doug Anderson
  2023-11-16  5:11               ` Chen-Yu Tsai
  2023-11-19 14:34               ` Rob Herring
  2023-11-16  5:07             ` Chen-Yu Tsai
  1 sibling, 2 replies; 30+ messages in thread
From: Doug Anderson @ 2023-11-15 22:13 UTC (permalink / raw)
  To: Rob Herring
  Cc: AngeloGioacchino Del Regno, Chen-Yu Tsai, Frank Rowand,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger, Hsin-Yi Wang,
	Dmitry Torokhov, andriy.shevchenko, Jiri Kosina, linus.walleij,
	broonie, gregkh, hdegoede, james.clark, james, keescook,
	petr.tesarik.ext, rafael, tglx, Jeff LaBundy, linux-input,
	devicetree, linux-arm-kernel, linux-mediatek, linux-kernel,
	Johan Hovold

Hi,

On Wed, Nov 15, 2023 at 4:35 PM Rob Herring <robh+dt@kernel.org> wrote:
>
> On Wed, Nov 15, 2023 at 2:45 PM Doug Anderson <dianders@chromium.org> wrote:
> >
> > Hi,
> >
> > On Wed, Nov 15, 2023 at 2:28 PM Rob Herring <robh+dt@kernel.org> wrote:
> > >
> > > > So if we're searching the whole device tree for "failed-needs-probe"
> > > > then we need to figure out which devices are related to each other. If
> > > > a given board has second sources for MIPI panels, touchscreens, and
> > > > trackpads then we need to know which of the "failed-needs-probe"
> > > > devices are trackpads, which are touchscreens, and which are MIPI
> > > > panels. Do you have any suggestions for how we should do that? Maybe
> > > > it was in some other thread that I missed? I guess we could have a
> > > > board-specific table mapping (compatible + node name + reg) to a
> > > > class, but that feels awkward.
> > >
> > > Node name is supposed to correspond to device class, so why not use
> > > that (no path or unit-address.) and nothing else (well, besides
> > > "status")?
> >
> > One problem is that I could imagine having two second source trackpads
> > that both have the same i2c address. That would give them the same
> > name, right? I guess you could maybe come up with some sort of suffix
> > rule? Like
> >
> > trackpad-1@10 {
> >   compatible = "elan,blah";
> >   ret = <0x10>;
> >   status = "failed-needs-probe";
> >   ...
> > }
> > trackpad-2@10 {
> >   compatible = "goodix,gt7375p";
> >   ret = <0x10>;
> >   status = "failed-needs-probe";
> >   ...
> > }
> >
> > Then I guess the class would be "trackpad"?
>
> That issue is somewhat orthogonal because it is not following the spec.

I'm not sure why you say it's orthogonal. The whole reason why we get
into the situation above is that we could have two devices, only one
of which is present (hence the status of "failed-needs-probe"), that
are the same type and have the same "reg" address.

Essentially the whole "failed-needs-probe" is extending the spec,
right? While extending the spec, we also need to talk about what to do
if some of the devices that we need to probe have the same class and
the same "reg".


> I'm not sure mixing the 2 styles of node names is a good idea. While
> not used too much, matching by node name does ignore the unit-address,
> but I'm not sure we could ignore a '-N'.
>
> I think our options are either add something to the unit-address or
> use i2c-mux binding. Adding to the unit-address is not unprecedented.
> I did that for some of the register bit level bindings where you have
> a node for different bits at the same address. The downside is
> unit-address is bus specific, so we'd have to add that for multiple
> buses. For the i2c-mux, it's perhaps a bit complex and I'm not sure
> what if anything you'd have to do to manage the mux that's not really
> there.

Somehow it feels weird to use an i2c-mux because there's no real mux
present, right? ...so this would be a virtual (bogus) device that
doesn't really exist in hardware.

...though I guess if the "mux" type binding is OK then maybe we just
use that as the HW prober, at least for i2c devices...

-Doug

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH v2 0/7] of: Introduce hardware prober driver
  2023-11-15 21:34           ` Rob Herring
  2023-11-15 22:13             ` Doug Anderson
@ 2023-11-16  5:07             ` Chen-Yu Tsai
  1 sibling, 0 replies; 30+ messages in thread
From: Chen-Yu Tsai @ 2023-11-16  5:07 UTC (permalink / raw)
  To: Rob Herring
  Cc: Doug Anderson, AngeloGioacchino Del Regno, Frank Rowand,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger, Hsin-Yi Wang,
	Dmitry Torokhov, andriy.shevchenko, Jiri Kosina, linus.walleij,
	broonie, gregkh, hdegoede, james.clark, james, keescook,
	petr.tesarik.ext, rafael, tglx, Jeff LaBundy, linux-input,
	devicetree, linux-arm-kernel, linux-mediatek, linux-kernel,
	Johan Hovold

On Thu, Nov 16, 2023 at 5:35 AM Rob Herring <robh+dt@kernel.org> wrote:
>
> On Wed, Nov 15, 2023 at 2:45 PM Doug Anderson <dianders@chromium.org> wrote:
> >
> > Hi,
> >
> > On Wed, Nov 15, 2023 at 2:28 PM Rob Herring <robh+dt@kernel.org> wrote:
> > >
> > > > So if we're searching the whole device tree for "failed-needs-probe"
> > > > then we need to figure out which devices are related to each other. If
> > > > a given board has second sources for MIPI panels, touchscreens, and
> > > > trackpads then we need to know which of the "failed-needs-probe"
> > > > devices are trackpads, which are touchscreens, and which are MIPI
> > > > panels. Do you have any suggestions for how we should do that? Maybe
> > > > it was in some other thread that I missed? I guess we could have a
> > > > board-specific table mapping (compatible + node name + reg) to a
> > > > class, but that feels awkward.
> > >
> > > Node name is supposed to correspond to device class, so why not use
> > > that (no path or unit-address.) and nothing else (well, besides
> > > "status")?
> >
> > One problem is that I could imagine having two second source trackpads
> > that both have the same i2c address. That would give them the same
> > name, right? I guess you could maybe come up with some sort of suffix
> > rule? Like
> >
> > trackpad-1@10 {
> >   compatible = "elan,blah";
> >   ret = <0x10>;
> >   status = "failed-needs-probe";
> >   ...
> > }
> > trackpad-2@10 {
> >   compatible = "goodix,gt7375p";
> >   ret = <0x10>;
> >   status = "failed-needs-probe";
> >   ...
> > }
> >
> > Then I guess the class would be "trackpad"?
>
> That issue is somewhat orthogonal because it is not following the spec.
>
> I'm not sure mixing the 2 styles of node names is a good idea. While
> not used too much, matching by node name does ignore the unit-address,
> but I'm not sure we could ignore a '-N'.

of_node_name_prefix() solves that. I assume that's the intended use case?

> I think our options are either add something to the unit-address or
> use i2c-mux binding. Adding to the unit-address is not unprecedented.
> I did that for some of the register bit level bindings where you have
> a node for different bits at the same address. The downside is
> unit-address is bus specific, so we'd have to add that for multiple
> buses. For the i2c-mux, it's perhaps a bit complex and I'm not sure
> what if anything you'd have to do to manage the mux that's not really
> there.
>
> Rob

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH v2 0/7] of: Introduce hardware prober driver
  2023-11-15 22:13             ` Doug Anderson
@ 2023-11-16  5:11               ` Chen-Yu Tsai
  2023-11-19 14:34               ` Rob Herring
  1 sibling, 0 replies; 30+ messages in thread
From: Chen-Yu Tsai @ 2023-11-16  5:11 UTC (permalink / raw)
  To: Doug Anderson
  Cc: Rob Herring, AngeloGioacchino Del Regno, Frank Rowand,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger, Hsin-Yi Wang,
	Dmitry Torokhov, andriy.shevchenko, Jiri Kosina, linus.walleij,
	broonie, gregkh, hdegoede, james.clark, james, keescook, rafael,
	tglx, Jeff LaBundy, linux-input, devicetree, linux-arm-kernel,
	linux-mediatek, linux-kernel, Johan Hovold

On Thu, Nov 16, 2023 at 6:14 AM Doug Anderson <dianders@chromium.org> wrote:
>
> Hi,
>
> On Wed, Nov 15, 2023 at 4:35 PM Rob Herring <robh+dt@kernel.org> wrote:
> >
> > On Wed, Nov 15, 2023 at 2:45 PM Doug Anderson <dianders@chromium.org> wrote:
> > >
> > > Hi,
> > >
> > > On Wed, Nov 15, 2023 at 2:28 PM Rob Herring <robh+dt@kernel.org> wrote:
> > > >
> > > > > So if we're searching the whole device tree for "failed-needs-probe"
> > > > > then we need to figure out which devices are related to each other. If
> > > > > a given board has second sources for MIPI panels, touchscreens, and
> > > > > trackpads then we need to know which of the "failed-needs-probe"
> > > > > devices are trackpads, which are touchscreens, and which are MIPI
> > > > > panels. Do you have any suggestions for how we should do that? Maybe
> > > > > it was in some other thread that I missed? I guess we could have a
> > > > > board-specific table mapping (compatible + node name + reg) to a
> > > > > class, but that feels awkward.
> > > >
> > > > Node name is supposed to correspond to device class, so why not use
> > > > that (no path or unit-address.) and nothing else (well, besides
> > > > "status")?
> > >
> > > One problem is that I could imagine having two second source trackpads
> > > that both have the same i2c address. That would give them the same
> > > name, right? I guess you could maybe come up with some sort of suffix
> > > rule? Like
> > >
> > > trackpad-1@10 {
> > >   compatible = "elan,blah";
> > >   ret = <0x10>;
> > >   status = "failed-needs-probe";
> > >   ...
> > > }
> > > trackpad-2@10 {
> > >   compatible = "goodix,gt7375p";
> > >   ret = <0x10>;
> > >   status = "failed-needs-probe";
> > >   ...
> > > }
> > >
> > > Then I guess the class would be "trackpad"?
> >
> > That issue is somewhat orthogonal because it is not following the spec.
>
> I'm not sure why you say it's orthogonal. The whole reason why we get
> into the situation above is that we could have two devices, only one
> of which is present (hence the status of "failed-needs-probe"), that
> are the same type and have the same "reg" address.
>
> Essentially the whole "failed-needs-probe" is extending the spec,
> right? While extending the spec, we also need to talk about what to do
> if some of the devices that we need to probe have the same class and
> the same "reg".

If it's at the same address, then you would need some device specific
probing code, like reading a register back and checking if matches
some known value. This could be done by passing in some kind of table,
but it is by no means as generic as checking if an address responds.

This is what we have on MT8186 Tentacruel. We do have the ability to
differentiate using the SKU ID for the same address case, but I'm happy
to try other methods if it helps everyone else.

ChenYu

> > I'm not sure mixing the 2 styles of node names is a good idea. While
> > not used too much, matching by node name does ignore the unit-address,
> > but I'm not sure we could ignore a '-N'.
> >
> > I think our options are either add something to the unit-address or
> > use i2c-mux binding. Adding to the unit-address is not unprecedented.
> > I did that for some of the register bit level bindings where you have
> > a node for different bits at the same address. The downside is
> > unit-address is bus specific, so we'd have to add that for multiple
> > buses. For the i2c-mux, it's perhaps a bit complex and I'm not sure
> > what if anything you'd have to do to manage the mux that's not really
> > there.
>
> Somehow it feels weird to use an i2c-mux because there's no real mux
> present, right? ...so this would be a virtual (bogus) device that
> doesn't really exist in hardware.
>
> ...though I guess if the "mux" type binding is OK then maybe we just
> use that as the HW prober, at least for i2c devices...
>
> -Doug

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [RFC PATCH v2 0/7] of: Introduce hardware prober driver
  2023-11-15 22:13             ` Doug Anderson
  2023-11-16  5:11               ` Chen-Yu Tsai
@ 2023-11-19 14:34               ` Rob Herring
  1 sibling, 0 replies; 30+ messages in thread
From: Rob Herring @ 2023-11-19 14:34 UTC (permalink / raw)
  To: Doug Anderson
  Cc: AngeloGioacchino Del Regno, Chen-Yu Tsai, Frank Rowand,
	Krzysztof Kozlowski, Conor Dooley, Matthias Brugger, Hsin-Yi Wang,
	Dmitry Torokhov, andriy.shevchenko, Jiri Kosina, linus.walleij,
	broonie, gregkh, hdegoede, james.clark, james, keescook,
	petr.tesarik.ext, rafael, tglx, Jeff LaBundy, linux-input,
	devicetree, linux-arm-kernel, linux-mediatek, linux-kernel,
	Johan Hovold

On Wed, Nov 15, 2023 at 05:13:50PM -0500, Doug Anderson wrote:
> Hi,
> 
> On Wed, Nov 15, 2023 at 4:35 PM Rob Herring <robh+dt@kernel.org> wrote:
> >
> > On Wed, Nov 15, 2023 at 2:45 PM Doug Anderson <dianders@chromium.org> wrote:
> > >
> > > Hi,
> > >
> > > On Wed, Nov 15, 2023 at 2:28 PM Rob Herring <robh+dt@kernel.org> wrote:
> > > >
> > > > > So if we're searching the whole device tree for "failed-needs-probe"
> > > > > then we need to figure out which devices are related to each other. If
> > > > > a given board has second sources for MIPI panels, touchscreens, and
> > > > > trackpads then we need to know which of the "failed-needs-probe"
> > > > > devices are trackpads, which are touchscreens, and which are MIPI
> > > > > panels. Do you have any suggestions for how we should do that? Maybe
> > > > > it was in some other thread that I missed? I guess we could have a
> > > > > board-specific table mapping (compatible + node name + reg) to a
> > > > > class, but that feels awkward.
> > > >
> > > > Node name is supposed to correspond to device class, so why not use
> > > > that (no path or unit-address.) and nothing else (well, besides
> > > > "status")?
> > >
> > > One problem is that I could imagine having two second source trackpads
> > > that both have the same i2c address. That would give them the same
> > > name, right? I guess you could maybe come up with some sort of suffix
> > > rule? Like
> > >
> > > trackpad-1@10 {
> > >   compatible = "elan,blah";
> > >   ret = <0x10>;
> > >   status = "failed-needs-probe";
> > >   ...
> > > }
> > > trackpad-2@10 {
> > >   compatible = "goodix,gt7375p";
> > >   ret = <0x10>;
> > >   status = "failed-needs-probe";
> > >   ...
> > > }
> > >
> > > Then I guess the class would be "trackpad"?
> >
> > That issue is somewhat orthogonal because it is not following the spec.
> 
> I'm not sure why you say it's orthogonal. The whole reason why we get
> into the situation above is that we could have two devices, only one
> of which is present (hence the status of "failed-needs-probe"), that
> are the same type and have the same "reg" address.

I just mean that defining a node name for 2 devices of the same class 
and at same address is separate problem from selecting which one to 
enable.

> 
> Essentially the whole "failed-needs-probe" is extending the spec,
> right? While extending the spec, we also need to talk about what to do
> if some of the devices that we need to probe have the same class and
> the same "reg".
> 
> 
> > I'm not sure mixing the 2 styles of node names is a good idea. While
> > not used too much, matching by node name does ignore the unit-address,
> > but I'm not sure we could ignore a '-N'.
> >
> > I think our options are either add something to the unit-address or
> > use i2c-mux binding. Adding to the unit-address is not unprecedented.
> > I did that for some of the register bit level bindings where you have
> > a node for different bits at the same address. The downside is
> > unit-address is bus specific, so we'd have to add that for multiple
> > buses. For the i2c-mux, it's perhaps a bit complex and I'm not sure
> > what if anything you'd have to do to manage the mux that's not really
> > there.
> 
> Somehow it feels weird to use an i2c-mux because there's no real mux
> present, right? ...so this would be a virtual (bogus) device that
> doesn't really exist in hardware.

Yes, shrug... 


> ...though I guess if the "mux" type binding is OK then maybe we just
> use that as the HW prober, at least for i2c devices...

Except for any other case where it's different addresses or different 
buses. Maybe different addresses could still use the same thing. I 
suppose the same class of device is unlikely to be on a different bus.

An extension to the unit-address would be the simpler solution, so we 
should explore that first I think.

Rob

^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2023-11-19 14:34 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-11-09 10:05 [RFC PATCH v2 0/7] of: Introduce hardware prober driver Chen-Yu Tsai
2023-11-09 10:05 ` [RFC PATCH v2 1/7] of: base: Add of_device_is_fail Chen-Yu Tsai
2023-11-09 10:05 ` [RFC PATCH v2 2/7] of: Introduce hardware prober driver Chen-Yu Tsai
2023-11-09 15:13   ` Rob Herring
2023-11-14  8:30     ` Chen-Yu Tsai
2023-11-09 17:54   ` Andy Shevchenko
2023-11-14  8:26     ` Chen-Yu Tsai
2023-11-09 10:06 ` [RFC PATCH v2 3/7] arm64: dts: mediatek: mt8173-elm-hana: Mark touchscreens and trackpads as fail Chen-Yu Tsai
2023-11-09 10:06 ` [RFC PATCH v2 4/7] arm64: dts: mediatek: mt8173-elm-hana: Add G2touch G7500 touchscreen Chen-Yu Tsai
2023-11-09 10:06 ` [RFC PATCH v2 5/7] of: hw_prober: Support Chromebook SKU ID based component selection Chen-Yu Tsai
2023-11-10 21:07   ` Rob Herring
2023-11-09 10:06 ` [RFC PATCH v2 6/7] dt-bindings: arm: mediatek: Remove SKU specific compatibles for Google Krane Chen-Yu Tsai
2023-11-10 21:04   ` Rob Herring
2023-11-11  0:29     ` Doug Anderson
2023-11-09 10:06 ` [RFC PATCH v2 7/7] arm64: dts: mediatek: mt8183-kukui: Merge Krane device trees Chen-Yu Tsai
2023-11-09 10:54 ` [RFC PATCH v2 0/7] of: Introduce hardware prober driver AngeloGioacchino Del Regno
2023-11-09 13:51   ` Rob Herring
2023-11-11  0:12     ` Doug Anderson
2023-11-15 19:28       ` Rob Herring
2023-11-15 20:44         ` Doug Anderson
2023-11-15 21:34           ` Rob Herring
2023-11-15 22:13             ` Doug Anderson
2023-11-16  5:11               ` Chen-Yu Tsai
2023-11-19 14:34               ` Rob Herring
2023-11-16  5:07             ` Chen-Yu Tsai
2023-11-14  7:05     ` Chen-Yu Tsai
2023-11-14  8:57   ` Chen-Yu Tsai
2023-11-14 10:04     ` AngeloGioacchino Del Regno
2023-11-11  0:22 ` Doug Anderson
2023-11-14  8:44   ` Chen-Yu Tsai

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).