mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH v4 00/17] barebox deep probe support
@ 2021-04-16  9:49 Sascha Hauer
  2021-04-16  9:49 ` [PATCH 01/17] imx53: remove unused imx53_add_nand Sascha Hauer
                   ` (18 more replies)
  0 siblings, 19 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-04-16  9:49 UTC (permalink / raw)
  To: Barebox List

Hi All,

This is the fourth round of patches for barebox deep-probe support.
I picked up the series from Marco, it has the things fixed I mentioned
during the last review and some other improvements:

Changes since v3:
  - Add deep-probe support for pinctrl
  - Port over Phytec Physom to deep-probe
  - Make sure console is probed ealier at postconsole_initcall time
  - Let of_devices_ensure_probed_by_dev_id() probe all matching devices, not
    only the first one
  - add GPIO support to the base deep probe patch

Lucas Stach (1):
  of: base: move memory init from DT to initcall

Marco Felsch (9):
  imx53: remove unused imx53_add_nand
  of: platform: remove check of already added devices
  of: platform: Keep track of populated platform devices
  of: base: move clock init from of_probe() to barebox_register_of()
  initcall: add of_populate_initcall
  common: add initial barebox deep-probe support
  ARM: i.MX: esdctl: add deep-probe support
  ARM: stm32mp: ddrctrl: add deep-probe support
  ARM: boards: mx6-sabrelite: add deep-probe support

Sascha Hauer (7):
  of: Set of_chosen and of_model earlier
  of: implement of_get_stdoutpath()
  pinctrl: Find controller node first
  common: Explicitly probe consoles earlier with deep probe
  pinctrl: Add deep probe support
  ARM: i.MX Phytec physom: convert to board driver
  ARM: i.MX Phytec physom: Add deep-probe support

 .../boards/freescale-mx6-sabrelite/board.c    |  24 +-
 arch/arm/boards/phytec-som-imx6/board.c       | 169 ++++++++++---
 arch/arm/mach-imx/esdctl.c                    |  12 +-
 .../arm/mach-imx/include/mach/devices-imx53.h |  27 --
 arch/arm/mach-stm32mp/ddrctrl.c               |  12 +-
 common/Makefile                               |   1 +
 common/deep-probe.c                           |  34 +++
 drivers/base/driver.c                         |  11 +-
 drivers/clk/clk.c                             |   5 +
 drivers/i2c/i2c.c                             |   8 +
 drivers/of/base.c                             |  61 +++--
 drivers/of/of_gpio.c                          |   4 +
 drivers/of/platform.c                         | 230 +++++++++++++++---
 drivers/pinctrl/pinctrl.c                     |  16 +-
 drivers/regulator/core.c                      |   6 +
 drivers/reset/core.c                          |   4 +
 drivers/spi/spi.c                             |   2 +
 include/asm-generic/barebox.lds.h             |  11 +-
 include/deep-probe.h                          |  26 ++
 include/init.h                                |  10 +-
 include/of.h                                  |  33 +++
 21 files changed, 575 insertions(+), 131 deletions(-)
 create mode 100644 common/deep-probe.c
 create mode 100644 include/deep-probe.h

-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 01/17] imx53: remove unused imx53_add_nand
  2021-04-16  9:49 [PATCH v4 00/17] barebox deep probe support Sascha Hauer
@ 2021-04-16  9:49 ` Sascha Hauer
  2021-04-16  9:49 ` [PATCH 02/17] of: platform: remove check of already added devices Sascha Hauer
                   ` (17 subsequent siblings)
  18 siblings, 0 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-04-16  9:49 UTC (permalink / raw)
  To: Barebox List; +Cc: Marco Felsch

From: Marco Felsch <m.felsch@pengutronix.de>

The TX53 board was the last user of this function. This board was
converted to device tree based boot by commit 971366078893
("i.MX53/TX53: rework to dts based boot") so we can remove this
legacy helper.

Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
Link: https://lore.pengutronix.de/20201021115813.31645-2-m.felsch@pengutronix.de
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 .../arm/mach-imx/include/mach/devices-imx53.h | 27 -------------------
 1 file changed, 27 deletions(-)

diff --git a/arch/arm/mach-imx/include/mach/devices-imx53.h b/arch/arm/mach-imx/include/mach/devices-imx53.h
index e5c257a40b..3d1e8a27a8 100644
--- a/arch/arm/mach-imx/include/mach/devices-imx53.h
+++ b/arch/arm/mach-imx/include/mach/devices-imx53.h
@@ -77,33 +77,6 @@ static inline struct device_d *imx53_add_mmc3(struct esdhc_platform_data *pdata)
 	return imx_add_esdhc_imx5((void *)MX53_ESDHC4_BASE_ADDR, 3, pdata);
 }
 
-static inline struct device_d *imx53_add_nand(struct imx_nand_platform_data *pdata)
-{
-	struct resource res[] = {
-		{
-			.start = MX53_NFC_BASE_ADDR,
-			.end = MX53_NFC_BASE_ADDR + SZ_4K - 1,
-			.flags = IORESOURCE_MEM,
-		}, {
-			.start = MX53_NFC_AXI_BASE_ADDR,
-			.end = MX53_NFC_AXI_BASE_ADDR + SZ_4K - 1,
-			.flags = IORESOURCE_MEM,
-		},
-	};
-	struct device_d *dev = xzalloc(sizeof(*dev));
-
-	dev->resource = xzalloc(sizeof(struct resource) * ARRAY_SIZE(res));
-	memcpy(dev->resource, res, sizeof(struct resource) * ARRAY_SIZE(res));
-	dev->num_resources = ARRAY_SIZE(res);
-	dev_set_name(dev, "imx_nand");
-	dev->id = DEVICE_ID_DYNAMIC;
-	dev->platform_data = pdata;
-
-	platform_device_register(dev);
-
-	return dev;
-}
-
 static inline struct device_d *imx53_add_kpp(struct matrix_keymap_data *pdata)
 {
 	return imx_add_kpp((void *)MX53_KPP_BASE_ADDR, pdata);
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 02/17] of: platform: remove check of already added devices
  2021-04-16  9:49 [PATCH v4 00/17] barebox deep probe support Sascha Hauer
  2021-04-16  9:49 ` [PATCH 01/17] imx53: remove unused imx53_add_nand Sascha Hauer
@ 2021-04-16  9:49 ` Sascha Hauer
  2021-04-16  9:49 ` [PATCH 03/17] of: platform: Keep track of populated platform devices Sascha Hauer
                   ` (16 subsequent siblings)
  18 siblings, 0 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-04-16  9:49 UTC (permalink / raw)
  To: Barebox List; +Cc: Marco Felsch

From: Marco Felsch <m.felsch@pengutronix.de>

This check is a relict of the early barebox device tree days, where
devices were added by machine and/or board code too. The check ensured
too not populate the same device twice. Nowadays _real_ hardware devices
(devices with hardware resources) which are not auto enumerable should
only be added using the device tree. Remove the check to cleanup the
code and to remove looping over each device every time
of_platform_device_create() is called instead of keeping it for legacy
boards/machines. Those legacy boards/machines should be converted
instead.

Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
Link: https://lore.pengutronix.de/20201021115813.31645-3-m.felsch@pengutronix.de
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/of/platform.c | 31 +------------------------------
 1 file changed, 1 insertion(+), 30 deletions(-)

diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 21c7cce1a5..51781798c6 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -101,7 +101,7 @@ struct device_d *of_platform_device_create(struct device_node *np,
 	struct device_d *dev;
 	struct resource *res = NULL, temp_res;
 	resource_size_t resinval;
-	int i, j, ret, num_reg = 0, match;
+	int i, ret, num_reg = 0;
 
 	if (!of_device_is_available(np))
 		return NULL;
@@ -121,35 +121,6 @@ struct device_d *of_platform_device_create(struct device_node *np,
 				return NULL;
 			}
 		}
-
-		/*
-		 * A device may already be registered as platform_device.
-		 * Instead of registering the same device again, just
-		 * add this node to the existing device.
-		 */
-		for_each_device(dev) {
-			if (!dev->resource)
-				continue;
-
-			for (i = 0, match = 0; i < num_reg; i++)
-				for (j = 0; j < dev->num_resources; j++)
-					if (dev->resource[j].start ==
-						res[i].start &&
-					    dev->resource[j].end ==
-						res[i].end) {
-						match++;
-						break;
-					}
-
-			/* check if all address resources match */
-			if (match == num_reg) {
-				debug("connecting %s to %s\n",
-					np->name, dev_name(dev));
-				dev->device_node = np;
-				free(res);
-				return dev;
-			}
-		}
 	}
 
 	/* setup generic device info */
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 03/17] of: platform: Keep track of populated platform devices
  2021-04-16  9:49 [PATCH v4 00/17] barebox deep probe support Sascha Hauer
  2021-04-16  9:49 ` [PATCH 01/17] imx53: remove unused imx53_add_nand Sascha Hauer
  2021-04-16  9:49 ` [PATCH 02/17] of: platform: remove check of already added devices Sascha Hauer
@ 2021-04-16  9:49 ` Sascha Hauer
  2021-04-16  9:49 ` [PATCH 04/17] of: base: move memory init from DT to initcall Sascha Hauer
                   ` (15 subsequent siblings)
  18 siblings, 0 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-04-16  9:49 UTC (permalink / raw)
  To: Barebox List; +Cc: Marco Felsch

From: Marco Felsch <m.felsch@pengutronix.de>

Linux does not allow to populate the same of device more than once.
Linux uses the OF_POPULATED flag for that purpose. Align the logic with
the current linux state with the exception that we are returning the
already created device. This is needed for the later added deep-probe
mechanism.

Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
Link: https://lore.pengutronix.de/20201021115813.31645-4-m.felsch@pengutronix.de
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/of/platform.c | 20 +++++++++++++++++++-
 include/of.h          |  1 +
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 51781798c6..01de6f98af 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -106,6 +106,13 @@ struct device_d *of_platform_device_create(struct device_node *np,
 	if (!of_device_is_available(np))
 		return NULL;
 
+	/*
+	 * Linux uses the OF_POPULATED flag to skip already populated/created
+	 * devices.
+	 */
+	if (np->dev)
+		return np->dev;
+
 	/* count the io resources */
 	if (of_can_translate_address(np))
 		while (of_address_to_resource(np, num_reg, &temp_res) == 0)
@@ -141,8 +148,10 @@ struct device_d *of_platform_device_create(struct device_node *np,
 		(num_reg) ? &dev->resource[0].start : &resinval);
 
 	ret = platform_device_register(dev);
-	if (!ret)
+	if (!ret) {
+		np->dev = dev;
 		return dev;
+	}
 
 	free(dev);
 	if (num_reg)
@@ -223,6 +232,13 @@ static struct device_d *of_amba_device_create(struct device_node *np)
 	if (!of_device_is_available(np))
 		return NULL;
 
+	/*
+	 * Linux uses the OF_POPULATED flag to skip already populated/created
+	 * devices.
+	 */
+	if (np->dev)
+		return np->dev;
+
 	dev = xzalloc(sizeof(*dev));
 
 	/* setup generic device info */
@@ -246,6 +262,8 @@ static struct device_d *of_amba_device_create(struct device_node *np)
 	if (ret)
 		goto amba_err_free;
 
+	np->dev = &dev->dev;
+
 	return &dev->dev;
 
 amba_err_free:
diff --git a/include/of.h b/include/of.h
index 645f429bde..1f68d78b24 100644
--- a/include/of.h
+++ b/include/of.h
@@ -35,6 +35,7 @@ struct device_node {
 	struct list_head parent_list;
 	struct list_head list;
 	phandle phandle;
+	struct device_d *dev;
 };
 
 struct of_device_id {
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 04/17] of: base: move memory init from DT to initcall
  2021-04-16  9:49 [PATCH v4 00/17] barebox deep probe support Sascha Hauer
                   ` (2 preceding siblings ...)
  2021-04-16  9:49 ` [PATCH 03/17] of: platform: Keep track of populated platform devices Sascha Hauer
@ 2021-04-16  9:49 ` Sascha Hauer
  2021-04-16  9:49 ` [PATCH 05/17] of: base: move clock init from of_probe() to barebox_register_of() Sascha Hauer
                   ` (14 subsequent siblings)
  18 siblings, 0 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-04-16  9:49 UTC (permalink / raw)
  To: Barebox List; +Cc: Marco Felsch

From: Lucas Stach <dev@lynxeye.de>

Instead of calling it from of_probe, convert it to a initcall at
the appropriate level. This allows to move of_probe to later in
the init sequence while keeping the memory init at the same place,
which is important as many other drivers need the valid memory area
to be set up properly.

Signed-off-by: Lucas Stach <dev@lynxeye.de>
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
Link: https://lore.pengutronix.de/20201021115813.31645-5-m.felsch@pengutronix.de
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/of/base.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index 6fe02649ee..549a0a2c2c 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -2281,10 +2281,13 @@ const struct of_device_id of_default_bus_match_table[] = {
 	}
 };
 
-static void of_probe_memory(void)
+static int of_probe_memory(void)
 {
 	struct device_node *memory = root_node;
 
+	if (!IS_ENABLED(CONFIG_OFDEVICE))
+		return 0;
+
 	/* Parse all available node with "memory" device_type */
 	while (1) {
 		memory = of_find_node_by_type(memory, "memory");
@@ -2293,7 +2296,10 @@ static void of_probe_memory(void)
 
 		of_add_memory(memory, false);
 	}
+
+	return 0;
 }
+mem_initcall(of_probe_memory);
 
 static void of_platform_device_create_root(struct device_node *np)
 {
@@ -2323,8 +2329,6 @@ int of_probe(void)
 	if (of_model)
 		barebox_set_model(of_model);
 
-	of_probe_memory();
-
 	firmware = of_find_node_by_path("/firmware");
 	if (firmware)
 		of_platform_populate(firmware, NULL, NULL);
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 05/17] of: base: move clock init from of_probe() to barebox_register_of()
  2021-04-16  9:49 [PATCH v4 00/17] barebox deep probe support Sascha Hauer
                   ` (3 preceding siblings ...)
  2021-04-16  9:49 ` [PATCH 04/17] of: base: move memory init from DT to initcall Sascha Hauer
@ 2021-04-16  9:49 ` Sascha Hauer
  2021-04-16  9:49 ` [PATCH 06/17] of: Set of_chosen and of_model earlier Sascha Hauer
                   ` (13 subsequent siblings)
  18 siblings, 0 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-04-16  9:49 UTC (permalink / raw)
  To: Barebox List; +Cc: Marco Felsch

From: Marco Felsch <m.felsch@pengutronix.de>

This is required for the new deep-probe mechanism. Barebox deep-probe
calls of_probe() very late and so clock drivers using the old
CLK_OF_DECLARE_DRIVER() mechanism are added very late. This would break
the deep-probe approach.

Move of_clk_init() and call it right before of_probe() should have no
impact because of_clk_init() depends only on an unflatten dtb.

Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
Link: https://lore.pengutronix.de/20201021115813.31645-6-m.felsch@pengutronix.de
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/of/base.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index 549a0a2c2c..7b3cfa8393 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1707,8 +1707,10 @@ void barebox_register_of(struct device_node *root)
 	of_set_root_node(root);
 	of_fix_tree(root);
 
-	if (IS_ENABLED(CONFIG_OFDEVICE))
+	if (IS_ENABLED(CONFIG_OFDEVICE)) {
+		of_clk_init(root, NULL);
 		of_probe();
+	}
 }
 
 void barebox_register_fdt(const void *dtb)
@@ -2335,7 +2337,6 @@ int of_probe(void)
 
 	of_platform_device_create_root(root_node);
 
-	of_clk_init(root_node, NULL);
 	of_platform_populate(root_node, of_default_bus_match_table, NULL);
 
 	return 0;
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 06/17] of: Set of_chosen and of_model earlier
  2021-04-16  9:49 [PATCH v4 00/17] barebox deep probe support Sascha Hauer
                   ` (4 preceding siblings ...)
  2021-04-16  9:49 ` [PATCH 05/17] of: base: move clock init from of_probe() to barebox_register_of() Sascha Hauer
@ 2021-04-16  9:49 ` Sascha Hauer
  2021-04-16  9:49 ` [PATCH 07/17] of: implement of_get_stdoutpath() Sascha Hauer
                   ` (12 subsequent siblings)
  18 siblings, 0 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-04-16  9:49 UTC (permalink / raw)
  To: Barebox List

of_chosen and of_model can be set once we have the device tree root node,
no need to wait until we probe the tree.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/of/base.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index 7b3cfa8393..1518854d2e 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1682,6 +1682,9 @@ int of_modalias_node(struct device_node *node, char *modalias, int len)
 }
 EXPORT_SYMBOL_GPL(of_modalias_node);
 
+static struct device_node *of_chosen;
+static const char *of_model;
+
 struct device_node *of_get_root_node(void)
 {
 	return root_node;
@@ -1694,6 +1697,12 @@ int of_set_root_node(struct device_node *node)
 
 	root_node = node;
 
+	of_chosen = of_find_node_by_path("/chosen");
+	of_property_read_string(root_node, "model", &of_model);
+
+	if (of_model)
+		barebox_set_model(of_model);
+
 	of_alias_scan();
 
 	return 0;
@@ -2263,9 +2272,6 @@ int of_add_memory(struct device_node *node, bool dump)
 	return 0;
 }
 
-static struct device_node *of_chosen;
-static const char *of_model;
-
 const char *of_get_model(void)
 {
 	return of_model;
@@ -2325,12 +2331,6 @@ int of_probe(void)
 	if(!root_node)
 		return -ENODEV;
 
-	of_chosen = of_find_node_by_path("/chosen");
-	of_property_read_string(root_node, "model", &of_model);
-
-	if (of_model)
-		barebox_set_model(of_model);
-
 	firmware = of_find_node_by_path("/firmware");
 	if (firmware)
 		of_platform_populate(firmware, NULL, NULL);
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 07/17] of: implement of_get_stdoutpath()
  2021-04-16  9:49 [PATCH v4 00/17] barebox deep probe support Sascha Hauer
                   ` (5 preceding siblings ...)
  2021-04-16  9:49 ` [PATCH 06/17] of: Set of_chosen and of_model earlier Sascha Hauer
@ 2021-04-16  9:49 ` Sascha Hauer
  2021-04-16  9:49 ` [PATCH 08/17] initcall: add of_populate_initcall Sascha Hauer
                   ` (11 subsequent siblings)
  18 siblings, 0 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-04-16  9:49 UTC (permalink / raw)
  To: Barebox List

For deep probe support it will be useful to have a function to
get the node corresponding to the stdoutpath. of_device_is_stdout_path()
already has that functionality in it, so make a separate funcion from
it.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/of/base.c | 15 ++++++++++-----
 include/of.h      |  6 ++++++
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index 1518854d2e..1e3921f915 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -2434,16 +2434,13 @@ void of_delete_node(struct device_node *node)
 		of_set_root_node(NULL);
 }
 
-int of_device_is_stdout_path(struct device_d *dev)
+struct device_node *of_get_stdoutpath(void)
 {
 	struct device_node *dn;
 	const char *name;
 	const char *p;
 	char *q;
 
-	if (!dev->device_node)
-		return 0;
-
 	name = of_get_property(of_chosen, "stdout-path", NULL);
 	if (!name)
 		name = of_get_property(of_chosen, "linux,stdout-path", NULL);
@@ -2462,7 +2459,15 @@ int of_device_is_stdout_path(struct device_d *dev)
 
 	free(q);
 
-	return dn == dev->device_node;
+	return dn;
+}
+
+int of_device_is_stdout_path(struct device_d *dev)
+{
+	if (!dev->device_node)
+		return 0;
+
+	return dev->device_node == of_get_stdoutpath();
 }
 
 /**
diff --git a/include/of.h b/include/of.h
index 1f68d78b24..a3527c1afd 100644
--- a/include/of.h
+++ b/include/of.h
@@ -280,6 +280,7 @@ struct cdev *of_parse_partition(struct cdev *cdev, struct device_node *node);
 int of_parse_partitions(struct cdev *cdev, struct device_node *node);
 int of_fixup_partitions(struct device_node *np, struct cdev *cdev);
 int of_partitions_register_fixup(struct cdev *cdev);
+struct device_node *of_get_stdoutpath(void);
 int of_device_is_stdout_path(struct device_d *dev);
 const char *of_get_model(void);
 void *of_flatten_dtb(struct device_node *node);
@@ -317,6 +318,11 @@ static inline int of_partitions_register_fixup(struct cdev *cdev)
 	return -ENOSYS;
 }
 
+static inline struct device_node *of_get_stdoutpath(void)
+{
+	return NULL;
+}
+
 static inline int of_device_is_stdout_path(struct device_d *dev)
 {
 	return 0;
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 08/17] initcall: add of_populate_initcall
  2021-04-16  9:49 [PATCH v4 00/17] barebox deep probe support Sascha Hauer
                   ` (6 preceding siblings ...)
  2021-04-16  9:49 ` [PATCH 07/17] of: implement of_get_stdoutpath() Sascha Hauer
@ 2021-04-16  9:49 ` Sascha Hauer
  2021-04-16  9:49 ` [PATCH 09/17] common: add initial barebox deep-probe support Sascha Hauer
                   ` (10 subsequent siblings)
  18 siblings, 0 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-04-16  9:49 UTC (permalink / raw)
  To: Barebox List; +Cc: Marco Felsch

From: Marco Felsch <m.felsch@pengutronix.de>

Add dedicated initcall for of_probe() which is required for the following
device-on-demand/deep-probe mechanism.

Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
Link: https://lore.pengutronix.de/20201021115813.31645-7-m.felsch@pengutronix.de
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 include/asm-generic/barebox.lds.h |  1 +
 include/init.h                    | 10 +++++++---
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/include/asm-generic/barebox.lds.h b/include/asm-generic/barebox.lds.h
index 6971e2c1d2..a7d32160d1 100644
--- a/include/asm-generic/barebox.lds.h
+++ b/include/asm-generic/barebox.lds.h
@@ -33,6 +33,7 @@
 	KEEP(*(.initcall.12))			\
 	KEEP(*(.initcall.13))			\
 	KEEP(*(.initcall.14))			\
+	KEEP(*(.initcall.15))			\
 	__barebox_initcalls_end = .;
 
 #define BAREBOX_EXITCALLS			\
diff --git a/include/init.h b/include/init.h
index 2d61bc8963..c695f99867 100644
--- a/include/init.h
+++ b/include/init.h
@@ -47,6 +47,9 @@ typedef void (*exitcall_t)(void);
  * initializes variables that couldn't be statically initialized.
  *
  * This only exists for built-in code, not for modules.
+ *
+ * The only purpose for "of_populate" is to call of_probe() other functions are
+ * not allowed.
  */
 #define pure_initcall(fn)		__define_initcall("0",fn,0)
 
@@ -61,9 +64,10 @@ typedef void (*exitcall_t)(void);
 #define fs_initcall(fn)			__define_initcall("9",fn,9)
 #define device_initcall(fn)		__define_initcall("10",fn,10)
 #define crypto_initcall(fn)		__define_initcall("11",fn,11)
-#define late_initcall(fn)		__define_initcall("12",fn,12)
-#define environment_initcall(fn)	__define_initcall("13",fn,13)
-#define postenvironment_initcall(fn)	__define_initcall("14",fn,14)
+#define of_populate_initcall(fn)	__define_initcall("12",fn,12)
+#define late_initcall(fn)		__define_initcall("13",fn,13)
+#define environment_initcall(fn)	__define_initcall("14",fn,14)
+#define postenvironment_initcall(fn)	__define_initcall("15",fn,15)
 
 #define early_exitcall(fn)		__define_exitcall("0",fn,0)
 #define predevshutdown_exitcall(fn)	__define_exitcall("1",fn,1)
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 09/17] common: add initial barebox deep-probe support
  2021-04-16  9:49 [PATCH v4 00/17] barebox deep probe support Sascha Hauer
                   ` (7 preceding siblings ...)
  2021-04-16  9:49 ` [PATCH 08/17] initcall: add of_populate_initcall Sascha Hauer
@ 2021-04-16  9:49 ` Sascha Hauer
  2021-04-19  7:16   ` Ahmad Fatoum
  2021-04-16  9:49 ` [PATCH 10/17] pinctrl: Find controller node first Sascha Hauer
                   ` (9 subsequent siblings)
  18 siblings, 1 reply; 34+ messages in thread
From: Sascha Hauer @ 2021-04-16  9:49 UTC (permalink / raw)
  To: Barebox List; +Cc: Marco Felsch

From: Marco Felsch <m.felsch@pengutronix.de>

The barebox 'deep probe' or 'probe on demand' mechanism is the answer of
unwanted -EPROBE_DEFER failures. The EPROBE_DEFER error code was
introduced by commit ab3da15bc14c ("base: Introduce deferred probing")
and since then it causes a few problems.

The error is returned if either the device is not yet present or the
driver is not yet registered. This makes sense on linux systems where
modules and hot-plug devices are used very often but not for barebox.
The module support is rarely used and devices aren't hot pluggable.

The current barebox behaviour populates all devices before the drivers
are registered so all devices are present during the driver
registration. So the driver probe() function gets called immediately
after the driver registration and causes the -EPROBE_DEFER error if this
driver depends on an other not yet registered driver.

To get rid of the EPROBE_DEFER error code we need to reorder the device
population and the driver registration. All drivers must be registered
first. In an ideal world all driver can be registered by the same
initcall level. Then devices are getting populated which causes calling
the driver probe() function but this time resources/devices are created
on demand if not yet available.

Dependencies between devices are normally expressed as references to
other device nodes. With deep probe barebox provides helper functions
which take a device node and probe the device behind that node if
necessary. This means instead of returning -EPROBE_DEFER, we can now
make the desired resources available once we need them.

If the resource can't be created we are returning -ENODEV since we are
not supporting hot-plugging. Dropping EPROBE_DEFER is the long-term
goal, avoid initcall shifting is the short-term goal.

Call it deep-probe since the on-demand device creation can create very
deep stacks. This commit adds the initial support for: spi, i2c, reset,
regulator, gpio and clk resource on-demand creation. The deep-probe
mechanism must be enabled for each board to avoid breaking changes using
deep_probe_enable(). This can be changed later after all boards are
converted to the new mechanism.

Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
Link: https://lore.pengutronix.de/20201021115813.31645-8-m.felsch@pengutronix.de
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 common/Makefile                   |   1 +
 common/deep-probe.c               |  34 +++++++
 drivers/base/driver.c             |  11 +-
 drivers/clk/clk.c                 |   5 +
 drivers/i2c/i2c.c                 |   8 ++
 drivers/of/base.c                 |  13 ++-
 drivers/of/of_gpio.c              |   4 +
 drivers/of/platform.c             | 162 ++++++++++++++++++++++++++++++
 drivers/regulator/core.c          |   6 ++
 drivers/reset/core.c              |   4 +
 drivers/spi/spi.c                 |   2 +
 include/asm-generic/barebox.lds.h |  10 +-
 include/deep-probe.h              |  26 +++++
 include/of.h                      |  26 +++++
 14 files changed, 309 insertions(+), 3 deletions(-)
 create mode 100644 common/deep-probe.c
 create mode 100644 include/deep-probe.h

diff --git a/common/Makefile b/common/Makefile
index c0b45d263e..aa06e6e82e 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -3,6 +3,7 @@ obj-y				+= memory_display.o
 pbl-$(CONFIG_PBL_CONSOLE)	+= memory_display.o
 obj-y				+= clock.o
 obj-y				+= console_common.o
+obj-y				+= deep-probe.o
 obj-y				+= startup.o
 obj-y				+= misc.o
 obj-pbl-y			+= memsize.o
diff --git a/common/deep-probe.c b/common/deep-probe.c
new file mode 100644
index 0000000000..9fc67f170c
--- /dev/null
+++ b/common/deep-probe.c
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <common.h>
+#include <deep-probe.h>
+#include <of.h>
+
+enum deep_probe_state {
+	DEEP_PROBE_UNKONWN = -1,
+	DEEP_PROBE_NOT_SUPPORTED,
+	DEEP_PROBE_SUPPORTED
+};
+
+static enum deep_probe_state boardstate = DEEP_PROBE_UNKONWN;
+
+bool deep_probe_is_supported(void)
+{
+	struct deep_probe_entry *board;
+
+	if (boardstate > DEEP_PROBE_UNKONWN)
+		return boardstate;
+
+	/* determine boardstate */
+	for (board = &__barebox_deep_probe_start;
+	     board != &__barebox_deep_probe_end; board++) {
+		if (of_machine_is_compatible(board->compatible)) {
+			boardstate = DEEP_PROBE_SUPPORTED;
+			return true;
+		}
+	}
+
+	boardstate = DEEP_PROBE_NOT_SUPPORTED;
+	return false;
+}
+EXPORT_SYMBOL_GPL(deep_probe_is_supported);
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index f60533c59e..ea23884624 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -21,6 +21,7 @@
 
 #include <common.h>
 #include <command.h>
+#include <deep-probe.h>
 #include <driver.h>
 #include <malloc.h>
 #include <console.h>
@@ -95,7 +96,15 @@ int device_probe(struct device_d *dev)
 	if (ret == -EPROBE_DEFER) {
 		list_del(&dev->active);
 		list_add(&dev->active, &deferred);
-		dev_dbg(dev, "probe deferred\n");
+
+		/*
+		 * -EPROBE_DEFER should never appear on a deep-probe machine so
+		 * inform the user immediately.
+		 */
+		if (deep_probe_is_supported())
+			dev_warn(dev, "probe deferred\n");
+		else
+			dev_dbg(dev, "probe deferred\n");
 		return ret;
 	}
 
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index b04d44593b..e40dfae9ce 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -439,6 +439,11 @@ struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec)
 {
 	struct of_clk_provider *provider;
 	struct clk *clk = ERR_PTR(-EPROBE_DEFER);
+	int ret;
+
+	ret = of_device_ensure_probed(clkspec->np);
+	if (ret)
+		return ERR_PTR(ret);
 
 	/* Check if we have such a provider in our array */
 	list_for_each_entry(provider, &of_clk_providers, link) {
diff --git a/drivers/i2c/i2c.c b/drivers/i2c/i2c.c
index 57d8c7017f..12aac42794 100644
--- a/drivers/i2c/i2c.c
+++ b/drivers/i2c/i2c.c
@@ -407,6 +407,9 @@ static struct i2c_client *i2c_new_device(struct i2c_adapter *adapter,
 	}
 	client->dev.info = i2c_info;
 
+	if (chip->of_node)
+		chip->of_node->dev = &client->dev;
+
 	return client;
 }
 
@@ -548,6 +551,11 @@ struct i2c_adapter *i2c_get_adapter(int busnum)
 struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node)
 {
 	struct i2c_adapter *adap;
+	int ret;
+
+	ret = of_device_ensure_probed(node);
+	if (ret)
+		return ERR_PTR(ret);
 
 	for_each_i2c_adapter(adap)
 		if (adap->dev.device_node == node)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 1e3921f915..00141a394f 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -15,6 +15,7 @@
  * GNU General Public License for more details.
  */
 #include <common.h>
+#include <deep-probe.h>
 #include <of.h>
 #include <of_address.h>
 #include <errno.h>
@@ -1708,6 +1709,15 @@ int of_set_root_node(struct device_node *node)
 	return 0;
 }
 
+static int barebox_of_populate(void)
+{
+	if (IS_ENABLED(CONFIG_OFDEVICE) && deep_probe_is_supported())
+		return of_probe();
+
+	return 0;
+}
+of_populate_initcall(barebox_of_populate);
+
 void barebox_register_of(struct device_node *root)
 {
 	if (root_node)
@@ -1718,7 +1728,8 @@ void barebox_register_of(struct device_node *root)
 
 	if (IS_ENABLED(CONFIG_OFDEVICE)) {
 		of_clk_init(root, NULL);
-		of_probe();
+		if (!deep_probe_is_supported())
+			of_probe();
 	}
 }
 
diff --git a/drivers/of/of_gpio.c b/drivers/of/of_gpio.c
index 7cbeeaf69e..4d3ded0599 100644
--- a/drivers/of/of_gpio.c
+++ b/drivers/of/of_gpio.c
@@ -63,6 +63,10 @@ int of_get_named_gpio_flags(struct device_node *np, const char *propname,
 		return ret;
 	}
 
+	ret = of_device_ensure_probed(out_args.np);
+	if (ret)
+		return ret;
+
 	dev = of_find_device_by_node(out_args.np);
 	if (!dev) {
 		pr_debug("%s: unable to find device of node %s\n",
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 01de6f98af..4b79a9bc10 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -15,6 +15,7 @@
  * GNU General Public License for more details.
  */
 #include <common.h>
+#include <deep-probe.h>
 #include <malloc.h>
 #include <of.h>
 #include <of_address.h>
@@ -29,6 +30,12 @@
 struct device_d *of_find_device_by_node(struct device_node *np)
 {
 	struct device_d *dev;
+	int ret;
+
+	ret = of_device_ensure_probed(np);
+	if (ret)
+		return NULL;
+
 	for_each_device(dev)
 		if (dev->device_node == np)
 			return dev;
@@ -353,3 +360,158 @@ int of_platform_populate(struct device_node *root,
 	return rc;
 }
 EXPORT_SYMBOL_GPL(of_platform_populate);
+
+static struct device_d *of_device_create_on_demand(struct device_node *np)
+{
+	struct device_node *parent;
+	struct device_d *parent_dev, *dev;
+
+	parent = of_get_parent(np);
+	if (!parent)
+		return NULL;
+
+	/* Create all parent devices needed for the requested device */
+	parent_dev = parent->dev ? : of_device_create_on_demand(parent);
+	if (IS_ERR(parent_dev))
+		return parent_dev;
+
+	/*
+	 * Parent devices like i2c/spi controllers are populating their own
+	 * devices. So it can be that the requested device already exists after
+	 * the parent device creation.
+	 */
+	if (np->dev)
+		return np->dev;
+
+	pr_debug("%s: Create %s (%s) on demand\n", __func__,
+		 np->name, np->full_name);
+
+	if (of_device_is_compatible(np, "arm,primecell"))
+		dev = of_amba_device_create(np);
+	else
+		dev = of_platform_device_create(np, parent_dev);
+
+	return dev ? : ERR_PTR(-ENODEV);
+}
+
+/**
+ * of_device_ensure_probed() - ensures that a device is probed
+ *
+ * @np: the device_node handle which should be probed
+ *
+ * Ensures that the device is populated and probed so frameworks can make use of
+ * it.
+ *
+ * Return: %0 on success
+ *	   %-ENODEV if either the device can't be populated, the driver is
+ *	     missing or the driver probe returns an error.
+ */
+int of_device_ensure_probed(struct device_node *np)
+{
+	struct device_d *dev;
+
+	if (!deep_probe_is_supported())
+		return 0;
+
+	dev = of_device_create_on_demand(np);
+	if (IS_ERR(dev))
+		return PTR_ERR(dev);
+
+	BUG_ON(!dev);
+
+	/*
+	 * The deep-probe mechanism relies on the fact that all necessary
+	 * drivers are added before the device creation. Furthermore deep-probe
+	 * is the answer to the EPROBE_DEFER errno so we must ensure that the
+	 * driver was probed successfully after the device creation. Both
+	 * requirements are fulfilled if 'dev->driver' is not NULL.
+	 */
+	if (!dev->driver)
+		return -ENODEV;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(of_device_ensure_probed);
+
+/**
+ * of_device_ensure_probed_by_alias() - ensures that a device is probed
+ *
+ * @alias: the alias string to search for a device
+ *
+ * The function search for a given alias string and ensures that the device is
+ * populated and probed if found.
+ *
+ * Return: %0 on success
+ *	   %-ENODEV if either the device can't be populated, the driver is
+ *	     missing or the driver probe returns an error
+ *	   %-EINVAL if alias can't be found
+ */
+int of_device_ensure_probed_by_alias(const char *alias)
+{
+	struct device_node *dev_node;
+
+	dev_node = of_find_node_by_alias(NULL, alias);
+	if (!dev_node)
+		return -EINVAL;
+
+	return of_device_ensure_probed(dev_node);
+}
+EXPORT_SYMBOL_GPL(of_device_ensure_probed_by_alias);
+
+/**
+ * of_devices_ensure_probed_by_dev_id() - ensures that devices are probed
+ *
+ * @ids: the matching 'struct of_device_id' ids
+ *
+ * The function start searching the device tree from @np and populates and
+ * probes devices which match @ids.
+ *
+ * Return: %0 on success
+ *	   %-ENODEV if either the device wasn't found, can't be populated,
+ *	     the driver is missing or the driver probe returns an error
+ */
+int of_devices_ensure_probed_by_dev_id(const struct of_device_id *ids)
+{
+	struct device_node *np;
+	int err, ret = 0;
+
+	for_each_matching_node(np, ids) {
+		if (!of_device_is_available(np))
+			continue;
+
+		err = of_device_ensure_probed(np);
+		if (err)
+			ret = err;
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(of_devices_ensure_probed_by_dev_id);
+
+/**
+ * of_devices_ensure_probed_by_property() - ensures that devices are probed
+ *
+ * @property_name: The property name to search for
+ *
+ * The function starts searching the whole device tree and populates and probes
+ * devices which matches @property_name.
+ *
+ * Return: %0 on success
+ *	   %-ENODEV if either the device wasn't found, can't be populated,
+ *	     the driver is missing or the driver probe returns an error
+ */
+int of_devices_ensure_probed_by_property(const char *property_name)
+{
+	struct device_node *node;
+
+	for_each_node_with_property(node, property_name) {
+		int ret;
+
+		ret = of_device_ensure_probed(node);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(of_devices_ensure_probed_by_property);
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index ac3a9b048e..097f7d779b 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -175,6 +175,7 @@ int of_regulator_register(struct regulator_dev *rd, struct device_node *node)
 		return PTR_ERR(ri);
 
 	ri->node = node;
+	node->dev = rd->dev;
 
 	if (rd->desc->off_on_delay)
 		ri->enable_time_us = rd->desc->off_on_delay;
@@ -197,6 +198,7 @@ static struct regulator_internal *of_regulator_get(struct device_d *dev, const c
 	char *propname;
 	struct regulator_internal *ri;
 	struct device_node *node;
+	int ret;
 
 	propname = basprintf("%s-supply", supply);
 
@@ -228,6 +230,10 @@ static struct regulator_internal *of_regulator_get(struct device_d *dev, const c
 		goto out;
 	}
 
+	ret = of_device_ensure_probed(node);
+	if (ret)
+		return ERR_PTR(ret);
+
 	list_for_each_entry(ri, &regulator_list, list) {
 		if (ri->node == node) {
 			dev_dbg(dev, "Using %s regulator from %s\n",
diff --git a/drivers/reset/core.c b/drivers/reset/core.c
index 26a54f21df..e2edca6658 100644
--- a/drivers/reset/core.c
+++ b/drivers/reset/core.c
@@ -168,6 +168,10 @@ static struct reset_control *of_reset_control_get(struct device_node *node,
 	if (ret)
 		return ERR_PTR(ret);
 
+	ret = of_device_ensure_probed(args.np);
+	if (ret)
+		return ERR_PTR(ret);
+
 	rcdev = NULL;
 	list_for_each_entry(r, &reset_controller_list, list) {
 		if (args.np == r->of_node) {
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 8421d9d7c1..d1d3bdcc41 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -107,6 +107,8 @@ struct spi_device *spi_new_device(struct spi_controller *ctrl,
 	if (status)
 		goto fail;
 
+	chip->device_node->dev = &proxy->dev;
+
 	return proxy;
 fail:
 	free(proxy);
diff --git a/include/asm-generic/barebox.lds.h b/include/asm-generic/barebox.lds.h
index a7d32160d1..c5f9d97547 100644
--- a/include/asm-generic/barebox.lds.h
+++ b/include/asm-generic/barebox.lds.h
@@ -114,6 +114,13 @@
 	KEEP(*(.rsa_keys.rodata.*));		\
 	__rsa_keys_end = .;			\
 
+#define BAREBOX_DEEP_PROBE			\
+	STRUCT_ALIGN();				\
+	__barebox_deep_probe_start = .;		\
+	KEEP(*(SORT_BY_NAME(.barebox_deep_probe*)))	\
+	__barebox_deep_probe_end = .;
+
+
 #ifdef CONFIG_CONSTRUCTORS
 #define KERNEL_CTORS()  . = ALIGN(8);                      \
 			__ctors_start = .;                 \
@@ -136,7 +143,8 @@
 	BAREBOX_CLK_TABLE			\
 	BAREBOX_DTB				\
 	BAREBOX_RSA_KEYS			\
-	BAREBOX_PCI_FIXUP
+	BAREBOX_PCI_FIXUP			\
+	BAREBOX_DEEP_PROBE
 
 #if defined(CONFIG_ARCH_BAREBOX_MAX_BARE_INIT_SIZE) && \
 CONFIG_ARCH_BAREBOX_MAX_BARE_INIT_SIZE < CONFIG_BAREBOX_MAX_BARE_INIT_SIZE
diff --git a/include/deep-probe.h b/include/deep-probe.h
new file mode 100644
index 0000000000..a646c10340
--- /dev/null
+++ b/include/deep-probe.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef __DEEP_PROBE_H
+#define __DEEP_PROBE_H
+
+#include <linux/stringify.h>
+#include <linux/types.h>
+
+struct deep_probe_entry {
+	const char *compatible;
+};
+
+bool deep_probe_is_supported(void);
+
+extern struct deep_probe_entry __barebox_deep_probe_start;
+extern struct deep_probe_entry __barebox_deep_probe_end;
+
+#define __BAREBOX_DEEP_PROBE_ENABLE(_entry,_compatible)			\
+	static const struct deep_probe_entry _entry			\
+	__attribute__ ((used,section (".barebox_deep_probe_" __stringify(_entry)))) = { \
+		.compatible = _compatible,				\
+	}
+
+#define BAREBOX_DEEP_PROBE_ENABLE(_compatible)	\
+	__BAREBOX_DEEP_PROBE_ENABLE(__UNIQUE_ID(deepprobe),_compatible)
+
+#endif /* __DEEP_PROBE_H */
diff --git a/include/of.h b/include/of.h
index a3527c1afd..78c06ec2c3 100644
--- a/include/of.h
+++ b/include/of.h
@@ -276,6 +276,11 @@ extern struct device_d *of_device_enable_and_register_by_name(const char *name);
 extern struct device_d *of_device_enable_and_register_by_alias(
 							const char *alias);
 
+extern int of_device_ensure_probed(struct device_node *np);
+extern int of_device_ensure_probed_by_alias(const char *alias);
+extern int of_devices_ensure_probed_by_property(const char *property_name);
+extern int of_devices_ensure_probed_by_dev_id(const struct of_device_id *ids);
+
 struct cdev *of_parse_partition(struct cdev *cdev, struct device_node *node);
 int of_parse_partitions(struct cdev *cdev, struct device_node *node);
 int of_fixup_partitions(struct device_node *np, struct cdev *cdev);
@@ -359,6 +364,27 @@ static inline struct device_d *of_platform_device_create(struct device_node *np,
 	return NULL;
 }
 
+static inline int of_device_ensure_probed(struct device_node *np)
+{
+	return 0;
+}
+
+static inline int of_device_ensure_probed_by_alias(const char *alias)
+{
+	return 0;
+}
+
+static inline int of_devices_ensure_probed_by_property(const char *property_name)
+{
+	return 0;
+}
+
+static inline int
+of_devices_ensure_probed_by_dev_id(const struct of_device_id *ids)
+{
+	return 0;
+}
+
 static inline int of_bus_n_addr_cells(struct device_node *np)
 {
 	return 0;
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 10/17] pinctrl: Find controller node first
  2021-04-16  9:49 [PATCH v4 00/17] barebox deep probe support Sascha Hauer
                   ` (8 preceding siblings ...)
  2021-04-16  9:49 ` [PATCH 09/17] common: add initial barebox deep-probe support Sascha Hauer
@ 2021-04-16  9:49 ` Sascha Hauer
  2021-04-16  9:49 ` [PATCH 11/17] common: Explicitly probe consoles earlier with deep probe Sascha Hauer
                   ` (8 subsequent siblings)
  18 siblings, 0 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-04-16  9:49 UTC (permalink / raw)
  To: Barebox List

The pinctrl controller node is the first parent node that has a compatible
property. Use that information to find the node without iterating up to
the root node.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/pinctrl/pinctrl.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/pinctrl/pinctrl.c b/drivers/pinctrl/pinctrl.c
index b36521ef83..84ac61f2d9 100644
--- a/drivers/pinctrl/pinctrl.c
+++ b/drivers/pinctrl/pinctrl.c
@@ -85,12 +85,15 @@ static int pinctrl_config_one(struct device_node *np)
 		pinctrl_node = pinctrl_node->parent;
 		if (!pinctrl_node)
 			return -ENODEV;
-		pdev = find_pinctrl(pinctrl_node);
-		if (pdev)
+		if (of_get_property(pinctrl_node, "compatible", NULL))
 			break;
 	}
 
-	return pdev->ops->set_state(pdev, np);
+	pdev = find_pinctrl(pinctrl_node);
+	if (pdev)
+		return pdev->ops->set_state(pdev, np);
+	else
+		return -ENODEV;
 }
 
 int of_pinctrl_select_state(struct device_node *np, const char *name)
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 11/17] common: Explicitly probe consoles earlier with deep probe
  2021-04-16  9:49 [PATCH v4 00/17] barebox deep probe support Sascha Hauer
                   ` (9 preceding siblings ...)
  2021-04-16  9:49 ` [PATCH 10/17] pinctrl: Find controller node first Sascha Hauer
@ 2021-04-16  9:49 ` Sascha Hauer
  2021-04-16  9:49 ` [PATCH 12/17] pinctrl: Add deep probe support Sascha Hauer
                   ` (7 subsequent siblings)
  18 siblings, 0 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-04-16  9:49 UTC (permalink / raw)
  To: Barebox List

With deep probe support the device providing the console can come quite
late in the probe order. Make sure it's probed at postconsole_initcall
time as it used to be without deep probe support so that we get output
earlier.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/of/platform.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 4b79a9bc10..6b6f904573 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -515,3 +515,20 @@ int of_devices_ensure_probed_by_property(const char *property_name)
 	return 0;
 }
 EXPORT_SYMBOL_GPL(of_devices_ensure_probed_by_property);
+
+static int of_stdoutpath_init(void)
+{
+	struct device_node *np;
+
+	np = of_get_stdoutpath();
+	if (!np)
+		return 0;
+
+	/*
+	 * With deep probe support the device providing the console
+	 * can come quite late in the probe order. Make sure it's
+	 * probed now so that we get output earlier.
+	 */
+	return of_device_ensure_probed(np);
+}
+postconsole_initcall(of_stdoutpath_init);
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 12/17] pinctrl: Add deep probe support
  2021-04-16  9:49 [PATCH v4 00/17] barebox deep probe support Sascha Hauer
                   ` (10 preceding siblings ...)
  2021-04-16  9:49 ` [PATCH 11/17] common: Explicitly probe consoles earlier with deep probe Sascha Hauer
@ 2021-04-16  9:49 ` Sascha Hauer
  2021-04-16  9:49 ` [PATCH 13/17] ARM: i.MX: esdctl: add deep-probe support Sascha Hauer
                   ` (6 subsequent siblings)
  18 siblings, 0 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-04-16  9:49 UTC (permalink / raw)
  To: Barebox List

This adds deep probe support for pinctrl.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/pinctrl/pinctrl.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/pinctrl/pinctrl.c b/drivers/pinctrl/pinctrl.c
index 84ac61f2d9..7e88391ff3 100644
--- a/drivers/pinctrl/pinctrl.c
+++ b/drivers/pinctrl/pinctrl.c
@@ -76,7 +76,7 @@ static struct pinctrl_device *find_pinctrl(struct device_node *node)
 	return NULL;
 }
 
-static int pinctrl_config_one(struct device_node *np)
+static int pinctrl_config_one(struct device_node *for_node, struct device_node *np)
 {
 	struct pinctrl_device *pdev;
 	struct device_node *pinctrl_node = np;
@@ -89,6 +89,9 @@ static int pinctrl_config_one(struct device_node *np)
 			break;
 	}
 
+	if (pinctrl_node != for_node)
+		of_device_ensure_probed(pinctrl_node);
+
 	pdev = find_pinctrl(pinctrl_node);
 	if (pdev)
 		return pdev->ops->set_state(pdev, np);
@@ -151,7 +154,7 @@ int of_pinctrl_select_state(struct device_node *np, const char *name)
 			}
 
 			/* Parse the node */
-			ret = pinctrl_config_one(np_config);
+			ret = pinctrl_config_one(np, np_config);
 			if (ret < 0)
 				goto err;
 		}
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 13/17] ARM: i.MX: esdctl: add deep-probe support
  2021-04-16  9:49 [PATCH v4 00/17] barebox deep probe support Sascha Hauer
                   ` (11 preceding siblings ...)
  2021-04-16  9:49 ` [PATCH 12/17] pinctrl: Add deep probe support Sascha Hauer
@ 2021-04-16  9:49 ` Sascha Hauer
  2021-04-16  9:49 ` [PATCH 14/17] ARM: stm32mp: ddrctrl: " Sascha Hauer
                   ` (5 subsequent siblings)
  18 siblings, 0 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-04-16  9:49 UTC (permalink / raw)
  To: Barebox List; +Cc: Marco Felsch

From: Marco Felsch <m.felsch@pengutronix.de>

In case of deep-probe we have to ensure that the memory device is
available after the mem_initcall().

Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
Link: https://lore.pengutronix.de/20201021115813.31645-9-m.felsch@pengutronix.de
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-imx/esdctl.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-imx/esdctl.c b/arch/arm/mach-imx/esdctl.c
index 135a16d111..6df4008c2d 100644
--- a/arch/arm/mach-imx/esdctl.c
+++ b/arch/arm/mach-imx/esdctl.c
@@ -706,7 +706,17 @@ static struct driver_d imx_esdctl_driver = {
 	.of_compatible = DRV_OF_COMPAT(imx_esdctl_dt_ids),
 };
 
-mem_platform_driver(imx_esdctl_driver);
+static int imx_esdctl_init(void)
+{
+	int ret;
+
+	ret = platform_driver_register(&imx_esdctl_driver);
+	if (ret)
+		return ret;
+
+	return of_devices_ensure_probed_by_dev_id(imx_esdctl_dt_ids);
+}
+mem_initcall(imx_esdctl_init);
 
 /*
  * The i.MX SoCs usually have two SDRAM chipselects. The following
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 14/17] ARM: stm32mp: ddrctrl: add deep-probe support
  2021-04-16  9:49 [PATCH v4 00/17] barebox deep probe support Sascha Hauer
                   ` (12 preceding siblings ...)
  2021-04-16  9:49 ` [PATCH 13/17] ARM: i.MX: esdctl: add deep-probe support Sascha Hauer
@ 2021-04-16  9:49 ` Sascha Hauer
  2021-04-16  9:49 ` [PATCH 15/17] ARM: boards: mx6-sabrelite: " Sascha Hauer
                   ` (4 subsequent siblings)
  18 siblings, 0 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-04-16  9:49 UTC (permalink / raw)
  To: Barebox List; +Cc: Marco Felsch

From: Marco Felsch <m.felsch@pengutronix.de>

In case of deep-probe we have to ensure that the memory device is
available after the mem_initcall().

Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
Link: https://lore.pengutronix.de/20201021115813.31645-10-m.felsch@pengutronix.de
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-stm32mp/ddrctrl.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-stm32mp/ddrctrl.c b/arch/arm/mach-stm32mp/ddrctrl.c
index 646fe4401a..9687747b3b 100644
--- a/arch/arm/mach-stm32mp/ddrctrl.c
+++ b/arch/arm/mach-stm32mp/ddrctrl.c
@@ -148,4 +148,14 @@ static struct driver_d stm32mp1_ddr_driver = {
 	.of_compatible = DRV_OF_COMPAT(stm32mp1_ddr_dt_ids),
 };
 
-mem_platform_driver(stm32mp1_ddr_driver);
+static int stm32mp1_ddr_init(void)
+{
+	int ret;
+
+	ret = platform_driver_register(&stm32mp1_ddr_driver);
+	if (ret)
+		return ret;
+
+	return of_devices_ensure_probed_by_dev_id(stm32mp1_ddr_dt_ids);
+}
+mem_initcall(stm32mp1_ddr_init);
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 15/17] ARM: boards: mx6-sabrelite: add deep-probe support
  2021-04-16  9:49 [PATCH v4 00/17] barebox deep probe support Sascha Hauer
                   ` (13 preceding siblings ...)
  2021-04-16  9:49 ` [PATCH 14/17] ARM: stm32mp: ddrctrl: " Sascha Hauer
@ 2021-04-16  9:49 ` Sascha Hauer
  2021-04-16  9:49 ` [PATCH 16/17] ARM: i.MX Phytec physom: convert to board driver Sascha Hauer
                   ` (3 subsequent siblings)
  18 siblings, 0 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-04-16  9:49 UTC (permalink / raw)
  To: Barebox List; +Cc: Marco Felsch

From: Marco Felsch <m.felsch@pengutronix.de>

Explicit request the required gpio resources instead of relying on their
existence based on the initcall level.

Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
Link: https://lore.pengutronix.de/20201021115813.31645-11-m.felsch@pengutronix.de
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 .../boards/freescale-mx6-sabrelite/board.c    | 24 ++++++++++++-------
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/arch/arm/boards/freescale-mx6-sabrelite/board.c b/arch/arm/boards/freescale-mx6-sabrelite/board.c
index 1b39ef82c6..0a2df391e9 100644
--- a/arch/arm/boards/freescale-mx6-sabrelite/board.c
+++ b/arch/arm/boards/freescale-mx6-sabrelite/board.c
@@ -13,7 +13,9 @@
 #include <mach/bbu.h>
 #include <asm/armlinux.h>
 #include <generated/mach-types.h>
+#include <of.h>
 #include <partition.h>
+#include <deep-probe.h>
 #include <linux/phy.h>
 #include <asm/io.h>
 #include <asm/mmu.h>
@@ -98,10 +100,6 @@ static int sabrelite_ksz9021rn_setup(void)
 {
 	int ret;
 
-	if (!of_machine_is_compatible("fsl,imx6q-sabrelite") &&
-	    !of_machine_is_compatible("fsl,imx6dl-sabrelite"))
-		return 0;
-
 	mxc_iomux_v3_setup_multiple_pads(sabrelite_enet_gpio_pads,
 			ARRAY_SIZE(sabrelite_enet_gpio_pads));
 
@@ -118,11 +116,6 @@ static int sabrelite_ksz9021rn_setup(void)
 
 	return 0;
 }
-/*
- * Do this before the fec initializes but after our
- * gpios are available.
- */
-fs_initcall(sabrelite_ksz9021rn_setup);
 
 static void sabrelite_ehci_init(void)
 {
@@ -134,10 +127,20 @@ static void sabrelite_ehci_init(void)
 
 static int sabrelite_devices_init(void)
 {
+	int ret;
+
 	if (!of_machine_is_compatible("fsl,imx6q-sabrelite") &&
 	    !of_machine_is_compatible("fsl,imx6dl-sabrelite"))
 		return 0;
 
+	ret = of_devices_ensure_probed_by_property("gpio-controller");
+	if (ret)
+		return ret;
+
+	ret = sabrelite_ksz9021rn_setup();
+	if (ret)
+		return ret;
+
 	sabrelite_ehci_init();
 
 	armlinux_set_architecture(3769);
@@ -163,3 +166,6 @@ static int sabrelite_coredevices_init(void)
 	return 0;
 }
 coredevice_initcall(sabrelite_coredevices_init);
+
+BAREBOX_DEEP_PROBE_ENABLE("fsl,imx6q-sabrelite");
+BAREBOX_DEEP_PROBE_ENABLE("fsl,imx6dl-sabrelite");
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 16/17] ARM: i.MX Phytec physom: convert to board driver
  2021-04-16  9:49 [PATCH v4 00/17] barebox deep probe support Sascha Hauer
                   ` (14 preceding siblings ...)
  2021-04-16  9:49 ` [PATCH 15/17] ARM: boards: mx6-sabrelite: " Sascha Hauer
@ 2021-04-16  9:49 ` Sascha Hauer
  2021-04-16  9:49 ` [PATCH 17/17] ARM: i.MX Phytec physom: Add deep-probe support Sascha Hauer
                   ` (2 subsequent siblings)
  18 siblings, 0 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-04-16  9:49 UTC (permalink / raw)
  To: Barebox List

Board driver is the new way for board specific fixups and the physom
board with its many compatible strings can really take profit from it,
so convert it.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/boards/phytec-som-imx6/board.c | 150 ++++++++++++++++++------
 1 file changed, 117 insertions(+), 33 deletions(-)

diff --git a/arch/arm/boards/phytec-som-imx6/board.c b/arch/arm/boards/phytec-som-imx6/board.c
index bac3e8a8a1..36c4d9a78b 100644
--- a/arch/arm/boards/phytec-som-imx6/board.c
+++ b/arch/arm/boards/phytec-som-imx6/board.c
@@ -141,16 +141,26 @@ err_out:
 	return ret;
 }
 
-static int physom_imx6_devices_init(void)
+#define IS_PHYFLEX	BIT(0)
+#define IS_PHYCORE	BIT(1)
+#define IS_PHYCARD	BIT(2)
+#define IS_PHYCORE_UL	BIT(3)
+#define HAS_MMC3	BIT(4)
+#define HAS_MMC1	BIT(5)
+
+struct board_data {
+	unsigned flags;
+};
+
+static int physom_imx6_probe(struct device_d *dev)
 {
 	int ret;
 	char *environment_path, *default_environment_path;
 	char *envdev, *default_envdev;
+	const struct board_data *brd = device_get_match_data(dev);
+	unsigned flags = brd->flags;
 
-	if (of_machine_is_compatible("phytec,imx6q-pfla02")
-		|| of_machine_is_compatible("phytec,imx6dl-pfla02")
-		|| of_machine_is_compatible("phytec,imx6s-pfla02")) {
-
+	if (flags & IS_PHYFLEX) {
 		phyflex_err006282_workaround();
 
 		pfla02_module_revision = get_module_rev();
@@ -164,21 +174,14 @@ static int physom_imx6_devices_init(void)
 		imx6_bbu_internal_mmc_register_handler("mmc2",
 						"/dev/mmc2", 0);
 
-	} else if (of_machine_is_compatible("phytec,imx6q-pcaaxl3")) {
-
+	} else if (flags & IS_PHYCARD) {
 		barebox_set_hostname("phyCARD-i.MX6");
 		default_environment_path = "/chosen/environment-nand";
 		default_envdev = "NAND flash";
 
 		imx6_bbu_internal_mmc_register_handler("mmc2",
 						"/dev/mmc2", 0);
-
-	} else if (of_machine_is_compatible("phytec,imx6q-pcm058-nand")
-		|| of_machine_is_compatible("phytec,imx6q-pcm058-emmc")
-		|| of_machine_is_compatible("phytec,imx6dl-pcm058-nand")
-		|| of_machine_is_compatible("phytec,imx6qp-pcm058-nand")
-		|| of_machine_is_compatible("phytec,imx6dl-pcm058-emmc")) {
-
+	} else if (flags & IS_PHYCORE) {
 		if (phycore_da9062_setup_buck_mode())
 			pr_err("Setting PMIC BUCK mode failed\n");
 
@@ -189,8 +192,7 @@ static int physom_imx6_devices_init(void)
 		imx6_bbu_internal_mmc_register_handler("mmc0",
 						"/dev/mmc0", 0);
 
-	} else if (of_machine_is_compatible("phytec,imx6ul-pcl063-nand")
-		|| of_machine_is_compatible("phytec,imx6ul-pcl063-emmc")) {
+	} else if (flags & IS_PHYCORE_UL) {
 		barebox_set_hostname("phyCORE-i.MX6UL");
 		default_environment_path = "/chosen/environment-nand";
 		default_envdev = "NAND flash";
@@ -201,8 +203,9 @@ static int physom_imx6_devices_init(void)
 		imx6_bbu_internal_mmc_register_handler("mmc0",
 						"/dev/mmc0", 0);
 
-	} else
-		return 0;
+	} else {
+		return -EINVAL;
+	}
 
 	switch (bootsource_get()) {
 	case BOOTSOURCE_MMC:
@@ -234,14 +237,13 @@ static int physom_imx6_devices_init(void)
 
 	pr_notice("Using environment in %s\n", envdev);
 
-	if (of_machine_is_compatible("phytec,imx6q-pcm058-emmc")
-		|| of_machine_is_compatible("phytec,imx6dl-pcm058-emmc")) {
+	if (flags & HAS_MMC3) {
 		imx6_bbu_internal_mmc_register_handler("mmc3",
 						"/dev/mmc3",
 						BBU_HANDLER_FLAG_DEFAULT);
 		imx6_bbu_internal_mmcboot_register_handler("mmc3-boot",
 						"mmc3", 0);
-	} else if (of_machine_is_compatible("phytec,imx6ul-pcl063-emmc")) {
+	} else if (flags & HAS_MMC1) {
 		imx6_bbu_internal_mmc_register_handler("mmc1",
 						"/dev/mmc1",
 						BBU_HANDLER_FLAG_DEFAULT);
@@ -254,23 +256,105 @@ static int physom_imx6_devices_init(void)
 	defaultenv_append_directory(defaultenv_physom_imx6);
 
 	/* Overwrite file /env/init/automount */
-	if (of_machine_is_compatible("phytec,imx6q-pfla02")
-		|| of_machine_is_compatible("phytec,imx6dl-pfla02")
-		|| of_machine_is_compatible("phytec,imx6s-pfla02")
-		|| of_machine_is_compatible("phytec,imx6q-pcaaxl3")) {
+	if (flags & IS_PHYCARD || flags & IS_PHYFLEX) {
 		defaultenv_append_directory(defaultenv_physom_imx6);
-	} else if (of_machine_is_compatible("phytec,imx6qp-pcm058-nand")
-		|| of_machine_is_compatible("phytec,imx6q-pcm058-nand")
-		|| of_machine_is_compatible("phytec,imx6q-pcm058-emmc")
-		|| of_machine_is_compatible("phytec,imx6dl-pcm058-nand")
-		|| of_machine_is_compatible("phytec,imx6dl-pcm058-emmc")) {
+	} else if (flags & IS_PHYCORE) {
 		defaultenv_append_directory(defaultenv_physom_imx6);
 		defaultenv_append_directory(defaultenv_physom_imx6_phycore);
-	} else if (of_machine_is_compatible("phytec,imx6ul-pcl063-nand")
-		|| of_machine_is_compatible("phytec,imx6ul-pcl063-emmc")) {
+	} else if (flags & IS_PHYCORE_UL) {
 		defaultenv_append_directory(defaultenv_physom_imx6ul_phycore);
 	}
 
 	return 0;
 }
-device_initcall(physom_imx6_devices_init);
+
+static struct board_data imx6q_pfla02 = {
+	.flags = IS_PHYFLEX,
+};
+
+static struct board_data imx6dl_pfla02 = {
+	.flags = IS_PHYFLEX,
+};
+
+static struct board_data imx6s_pfla02 = {
+	.flags = IS_PHYFLEX,
+};
+
+static struct board_data imx6q_pcaaxl3 = {
+	.flags = IS_PHYCARD,
+};
+
+static struct board_data imx6q_pcm058_nand = {
+	.flags = IS_PHYCORE,
+};
+
+static struct board_data imx6q_pcm058_emmc = {
+	.flags = IS_PHYCORE | HAS_MMC3,
+};
+
+static struct board_data imx6dl_pcm058_nand = {
+	.flags = IS_PHYCORE,
+};
+
+static struct board_data imx6qp_pcm058_nand = {
+	.flags = IS_PHYCORE,
+};
+
+static struct board_data imx6dl_pcm058_emmc = {
+	.flags = IS_PHYCORE | HAS_MMC3,
+};
+
+static struct board_data imx6ul_pcl063_nand = {
+	.flags = IS_PHYCORE_UL,
+};
+
+static struct board_data imx6ul_pcl063_emmc = {
+	.flags = IS_PHYCORE_UL | HAS_MMC1,
+};
+
+
+static const struct of_device_id physom_imx6_match[] = {
+	{
+		.compatible = "phytec,imx6q-pfla02",
+		.data = &imx6q_pfla02,
+	}, {
+		.compatible = "phytec,imx6dl-pfla02",
+		.data = &imx6dl_pfla02,
+	}, {
+		.compatible = "phytec,imx6s-pfla02",
+		.data = &imx6s_pfla02,
+	}, {
+		.compatible = "phytec,imx6q-pcaaxl3",
+		.data = &imx6q_pcaaxl3,
+	}, {
+		.compatible = "phytec,imx6q-pcm058-nand",
+		.data = &imx6q_pcm058_nand,
+	}, {
+		.compatible = "phytec,imx6q-pcm058-emmc",
+		.data = &imx6q_pcm058_emmc,
+	}, {
+		.compatible = "phytec,imx6dl-pcm058-nand",
+		.data = &imx6dl_pcm058_nand,
+	}, {
+		.compatible = "phytec,imx6qp-pcm058-nand",
+		.data = &imx6qp_pcm058_nand,
+	}, {
+		.compatible = "phytec,imx6dl-pcm058-emmc",
+		.data = &imx6dl_pcm058_emmc,
+	}, {
+		.compatible = "phytec,imx6ul-pcl063-nand",
+		.data = &imx6ul_pcl063_nand,
+	}, {
+		.compatible = "phytec,imx6ul-pcl063-emmc",
+		.data = &imx6ul_pcl063_emmc,
+	},
+	{ /* Sentinel */ },
+};
+
+static struct driver_d physom_imx6_driver = {
+	.name = "physom-imx6",
+	.probe = physom_imx6_probe,
+	.of_compatible = physom_imx6_match,
+};
+
+postcore_platform_driver(physom_imx6_driver);
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 17/17] ARM: i.MX Phytec physom: Add deep-probe support
  2021-04-16  9:49 [PATCH v4 00/17] barebox deep probe support Sascha Hauer
                   ` (15 preceding siblings ...)
  2021-04-16  9:49 ` [PATCH 16/17] ARM: i.MX Phytec physom: convert to board driver Sascha Hauer
@ 2021-04-16  9:49 ` Sascha Hauer
  2021-04-19  7:12   ` Ahmad Fatoum
  2021-04-19  7:35 ` [PATCH v4 00/17] barebox deep probe support Ahmad Fatoum
  2021-04-28 10:28 ` [PATCH 1/3] fixup! common: add initial barebox deep-probe support Marco Felsch
  18 siblings, 1 reply; 34+ messages in thread
From: Sascha Hauer @ 2021-04-16  9:49 UTC (permalink / raw)
  To: Barebox List

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/boards/phytec-som-imx6/board.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/arch/arm/boards/phytec-som-imx6/board.c b/arch/arm/boards/phytec-som-imx6/board.c
index 36c4d9a78b..a108726468 100644
--- a/arch/arm/boards/phytec-som-imx6/board.c
+++ b/arch/arm/boards/phytec-som-imx6/board.c
@@ -14,6 +14,7 @@
 #include <gpio.h>
 #include <init.h>
 #include <of.h>
+#include <deep-probe.h>
 #include <i2c/i2c.h>
 #include <mach/bbu.h>
 #include <platform_data/eth-fec.h>
@@ -110,6 +111,10 @@ static int phycore_da9062_setup_buck_mode(void)
 	if (!pmic_np)
 		return -ENODEV;
 
+	ret = of_device_ensure_probed(pmic_np);
+	if (ret)
+		return ret;
+
 	adapter = of_find_i2c_adapter_by_node(pmic_np->parent);
 	if (!adapter)
 		return -ENODEV;
@@ -161,6 +166,10 @@ static int physom_imx6_probe(struct device_d *dev)
 	unsigned flags = brd->flags;
 
 	if (flags & IS_PHYFLEX) {
+		ret = of_devices_ensure_probed_by_property("gpio-controller");
+		if (ret)
+			return ret;
+
 		phyflex_err006282_workaround();
 
 		pfla02_module_revision = get_module_rev();
@@ -358,3 +367,15 @@ static struct driver_d physom_imx6_driver = {
 };
 
 postcore_platform_driver(physom_imx6_driver);
+
+BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6q-pfla02");
+BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6dl-pfla02");
+BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6s-pfla02");
+BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6q-pcaaxl3");
+BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6q-pcm058-nand");
+BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6q-pcm058-emmc");
+BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6dl-pcm058-nand");
+BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6qp-pcm058-nand");
+BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6dl-pcm058-emmc");
+BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6ul-pcl063-nand");
+BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6ul-pcl063-emmc");
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* Re: [PATCH 17/17] ARM: i.MX Phytec physom: Add deep-probe support
  2021-04-16  9:49 ` [PATCH 17/17] ARM: i.MX Phytec physom: Add deep-probe support Sascha Hauer
@ 2021-04-19  7:12   ` Ahmad Fatoum
  2021-04-26  9:20     ` Marco Felsch
  0 siblings, 1 reply; 34+ messages in thread
From: Ahmad Fatoum @ 2021-04-19  7:12 UTC (permalink / raw)
  To: Sascha Hauer, Barebox List

Hi,

On 16.04.21 11:49, Sascha Hauer wrote:
> +BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6q-pfla02");
> +BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6dl-pfla02");
> +BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6s-pfla02");
> +BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6q-pcaaxl3");
> +BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6q-pcm058-nand");
> +BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6q-pcm058-emmc");
> +BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6dl-pcm058-nand");
> +BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6qp-pcm058-nand");
> +BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6dl-pcm058-emmc");
> +BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6ul-pcl063-nand");
> +BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6ul-pcl063-emmc");

How about changing BAREBOX_DEEP_PROBE_ENABLE so BAREBOX_DEEP_PROBE_ENABLE(physom_imx6_match);
works? Updated boards should be using board drivers anyway, so make it easier for them to
enable deep probe.

I'd go even further and require board drivers by having it take a driver_d * as argument
and introduce deep_probe_board_driver() that expands to postcore_platform_driver and
BAREBOX_DEEP_PROBE_ENABLE.

This would prevent having a board driver that's deep probe incompatible in the
first place, because it will likely not find the resources it requires that early
if it doesn't deep probe.

Cheers,
Ahmad

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* Re: [PATCH 09/17] common: add initial barebox deep-probe support
  2021-04-16  9:49 ` [PATCH 09/17] common: add initial barebox deep-probe support Sascha Hauer
@ 2021-04-19  7:16   ` Ahmad Fatoum
  2021-04-26  8:15     ` Marco Felsch
  0 siblings, 1 reply; 34+ messages in thread
From: Ahmad Fatoum @ 2021-04-19  7:16 UTC (permalink / raw)
  To: Sascha Hauer, Barebox List; +Cc: Marco Felsch

Hi,

On 16.04.21 11:49, Sascha Hauer wrote:
> diff --git a/drivers/base/driver.c b/drivers/base/driver.c
> index f60533c59e..ea23884624 100644
> --- a/drivers/base/driver.c
> +++ b/drivers/base/driver.c
> @@ -21,6 +21,7 @@
>  
>  #include <common.h>
>  #include <command.h>
> +#include <deep-probe.h>
>  #include <driver.h>
>  #include <malloc.h>
>  #include <console.h>
> @@ -95,7 +96,15 @@ int device_probe(struct device_d *dev)
>  	if (ret == -EPROBE_DEFER) {
>  		list_del(&dev->active);
>  		list_add(&dev->active, &deferred);
> -		dev_dbg(dev, "probe deferred\n");
> +
> +		/*
> +		 * -EPROBE_DEFER should never appear on a deep-probe machine so
> +		 * inform the user immediately.
> +		 */
> +		if (deep_probe_is_supported())
> +			dev_warn(dev, "probe deferred\n");

Such devices wouldn't ever be retried with deep probe, right?
If so, this should be a dev_err, not dev_warn, as it's not a recoverable
issue.

> +		else
> +			dev_dbg(dev, "probe deferred\n");
>  		return ret;
>  	}

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* Re: [PATCH v4 00/17] barebox deep probe support
  2021-04-16  9:49 [PATCH v4 00/17] barebox deep probe support Sascha Hauer
                   ` (16 preceding siblings ...)
  2021-04-16  9:49 ` [PATCH 17/17] ARM: i.MX Phytec physom: Add deep-probe support Sascha Hauer
@ 2021-04-19  7:35 ` Ahmad Fatoum
  2021-04-28 10:28 ` [PATCH 1/3] fixup! common: add initial barebox deep-probe support Marco Felsch
  18 siblings, 0 replies; 34+ messages in thread
From: Ahmad Fatoum @ 2021-04-19  7:35 UTC (permalink / raw)
  To: Sascha Hauer, Barebox List

Hi,

On 16.04.21 11:49, Sascha Hauer wrote:
> Hi All,
> 
> This is the fourth round of patches for barebox deep-probe support.

With feedback addressed,

Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>

> I picked up the series from Marco, it has the things fixed I mentioned
> during the last review and some other improvements:
> 
> Changes since v3:
>   - Add deep-probe support for pinctrl
>   - Port over Phytec Physom to deep-probe
>   - Make sure console is probed ealier at postconsole_initcall time
>   - Let of_devices_ensure_probed_by_dev_id() probe all matching devices, not
>     only the first one
>   - add GPIO support to the base deep probe patch
> 
> Lucas Stach (1):
>   of: base: move memory init from DT to initcall
> 
> Marco Felsch (9):
>   imx53: remove unused imx53_add_nand
>   of: platform: remove check of already added devices
>   of: platform: Keep track of populated platform devices
>   of: base: move clock init from of_probe() to barebox_register_of()
>   initcall: add of_populate_initcall
>   common: add initial barebox deep-probe support
>   ARM: i.MX: esdctl: add deep-probe support
>   ARM: stm32mp: ddrctrl: add deep-probe support
>   ARM: boards: mx6-sabrelite: add deep-probe support
> 
> Sascha Hauer (7):
>   of: Set of_chosen and of_model earlier
>   of: implement of_get_stdoutpath()
>   pinctrl: Find controller node first
>   common: Explicitly probe consoles earlier with deep probe
>   pinctrl: Add deep probe support
>   ARM: i.MX Phytec physom: convert to board driver
>   ARM: i.MX Phytec physom: Add deep-probe support
> 
>  .../boards/freescale-mx6-sabrelite/board.c    |  24 +-
>  arch/arm/boards/phytec-som-imx6/board.c       | 169 ++++++++++---
>  arch/arm/mach-imx/esdctl.c                    |  12 +-
>  .../arm/mach-imx/include/mach/devices-imx53.h |  27 --
>  arch/arm/mach-stm32mp/ddrctrl.c               |  12 +-
>  common/Makefile                               |   1 +
>  common/deep-probe.c                           |  34 +++
>  drivers/base/driver.c                         |  11 +-
>  drivers/clk/clk.c                             |   5 +
>  drivers/i2c/i2c.c                             |   8 +
>  drivers/of/base.c                             |  61 +++--
>  drivers/of/of_gpio.c                          |   4 +
>  drivers/of/platform.c                         | 230 +++++++++++++++---
>  drivers/pinctrl/pinctrl.c                     |  16 +-
>  drivers/regulator/core.c                      |   6 +
>  drivers/reset/core.c                          |   4 +
>  drivers/spi/spi.c                             |   2 +
>  include/asm-generic/barebox.lds.h             |  11 +-
>  include/deep-probe.h                          |  26 ++
>  include/init.h                                |  10 +-
>  include/of.h                                  |  33 +++
>  21 files changed, 575 insertions(+), 131 deletions(-)
>  create mode 100644 common/deep-probe.c
>  create mode 100644 include/deep-probe.h
> 

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* Re: [PATCH 09/17] common: add initial barebox deep-probe support
  2021-04-19  7:16   ` Ahmad Fatoum
@ 2021-04-26  8:15     ` Marco Felsch
  0 siblings, 0 replies; 34+ messages in thread
From: Marco Felsch @ 2021-04-26  8:15 UTC (permalink / raw)
  To: Ahmad Fatoum; +Cc: Barebox List

On 21-04-19 09:16, Ahmad Fatoum wrote:
> Hi,
> 
> On 16.04.21 11:49, Sascha Hauer wrote:
> > diff --git a/drivers/base/driver.c b/drivers/base/driver.c
> > index f60533c59e..ea23884624 100644
> > --- a/drivers/base/driver.c
> > +++ b/drivers/base/driver.c
> > @@ -21,6 +21,7 @@
> >  
> >  #include <common.h>
> >  #include <command.h>
> > +#include <deep-probe.h>
> >  #include <driver.h>
> >  #include <malloc.h>
> >  #include <console.h>
> > @@ -95,7 +96,15 @@ int device_probe(struct device_d *dev)
> >  	if (ret == -EPROBE_DEFER) {
> >  		list_del(&dev->active);
> >  		list_add(&dev->active, &deferred);
> > -		dev_dbg(dev, "probe deferred\n");
> > +
> > +		/*
> > +		 * -EPROBE_DEFER should never appear on a deep-probe machine so
> > +		 * inform the user immediately.
> > +		 */
> > +		if (deep_probe_is_supported())
> > +			dev_warn(dev, "probe deferred\n");
> 
> Such devices wouldn't ever be retried with deep probe, right?

The subsystem needs to support deep probe and if it isn't adapted, right
now only a few ones are adapted, this could still be possible.

> If so, this should be a dev_err, not dev_warn, as it's not a recoverable
> issue.

If all subsystems support it you're right.

Regards,
  Marco

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* Re: [PATCH 17/17] ARM: i.MX Phytec physom: Add deep-probe support
  2021-04-19  7:12   ` Ahmad Fatoum
@ 2021-04-26  9:20     ` Marco Felsch
  2021-04-26  9:26       ` Marco Felsch
  2021-04-26  9:36       ` Ahmad Fatoum
  0 siblings, 2 replies; 34+ messages in thread
From: Marco Felsch @ 2021-04-26  9:20 UTC (permalink / raw)
  To: Ahmad Fatoum; +Cc: Barebox List

On 21-04-19 09:12, Ahmad Fatoum wrote:
> Hi,
> 
> On 16.04.21 11:49, Sascha Hauer wrote:
> > +BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6q-pfla02");
> > +BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6dl-pfla02");
> > +BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6s-pfla02");
> > +BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6q-pcaaxl3");
> > +BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6q-pcm058-nand");
> > +BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6q-pcm058-emmc");
> > +BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6dl-pcm058-nand");
> > +BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6qp-pcm058-nand");
> > +BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6dl-pcm058-emmc");
> > +BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6ul-pcl063-nand");
> > +BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6ul-pcl063-emmc");
> 
> How about changing BAREBOX_DEEP_PROBE_ENABLE so BAREBOX_DEEP_PROBE_ENABLE(physom_imx6_match);
> works? Updated boards should be using board drivers anyway, so make it easier for them to
> enable deep probe.

Hi Ahmad,

Why do I need to chnage it to board drivers if I only wanna fix a probe
order issue? But you're right adding the _match table should be possible
to :)

> I'd go even further and require board drivers by having it take a driver_d * as argument
> and introduce deep_probe_board_driver() that expands to postcore_platform_driver and
> BAREBOX_DEEP_PROBE_ENABLE.

How about this:
 1st) adding a probe_enum like kernel and introduce PROBE_PREFER_DEEP
 2nd) adding a deep_probe_enable_board() function to common/deep_probe.c
 3th) checking during register_driver() if the flag is set and call the
      deep_probe_enable_board().

This allows use to still use the macro mechanism and the boards already
converted to the board driver style can use this simple enum to mark all
boards as deep-probable.

Regards,
  Marco

> This would prevent having a board driver that's deep probe incompatible in the
> first place, because it will likely not find the resources it requires that early
> if it doesn't deep probe.
> 
> Cheers,
> Ahmad
> 
> -- 
> Pengutronix e.K.                           |                             |
> Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
> 31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> 
> _______________________________________________
> barebox mailing list
> barebox@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
> 

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* Re: [PATCH 17/17] ARM: i.MX Phytec physom: Add deep-probe support
  2021-04-26  9:20     ` Marco Felsch
@ 2021-04-26  9:26       ` Marco Felsch
  2021-04-26  9:36       ` Ahmad Fatoum
  1 sibling, 0 replies; 34+ messages in thread
From: Marco Felsch @ 2021-04-26  9:26 UTC (permalink / raw)
  To: Ahmad Fatoum; +Cc: Barebox List

On 21-04-26 11:20, Marco Felsch wrote:
> On 21-04-19 09:12, Ahmad Fatoum wrote:
> > Hi,
> > 
> > On 16.04.21 11:49, Sascha Hauer wrote:
> > > +BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6q-pfla02");
> > > +BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6dl-pfla02");
> > > +BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6s-pfla02");
> > > +BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6q-pcaaxl3");
> > > +BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6q-pcm058-nand");
> > > +BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6q-pcm058-emmc");
> > > +BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6dl-pcm058-nand");
> > > +BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6qp-pcm058-nand");
> > > +BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6dl-pcm058-emmc");
> > > +BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6ul-pcl063-nand");
> > > +BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6ul-pcl063-emmc");
> > 
> > How about changing BAREBOX_DEEP_PROBE_ENABLE so BAREBOX_DEEP_PROBE_ENABLE(physom_imx6_match);
> > works? Updated boards should be using board drivers anyway, so make it easier for them to
> > enable deep probe.
> 
> Hi Ahmad,
> 
> Why do I need to chnage it to board drivers if I only wanna fix a probe
> order issue? But you're right adding the _match table should be possible
> to :)
> 
> > I'd go even further and require board drivers by having it take a driver_d * as argument
> > and introduce deep_probe_board_driver() that expands to postcore_platform_driver and
> > BAREBOX_DEEP_PROBE_ENABLE.
> 
> How about this:
>  1st) adding a probe_enum like kernel and introduce PROBE_PREFER_DEEP
                   ^
	I mean 'enum probe_type', sry.

>  2nd) adding a deep_probe_enable_board() function to common/deep_probe.c
>  3th) checking during register_driver() if the flag is set and call the
>       deep_probe_enable_board().
> 
> This allows use to still use the macro mechanism and the boards already
> converted to the board driver style can use this simple enum to mark all
> boards as deep-probable.
> 
> Regards,
>   Marco
> 
> > This would prevent having a board driver that's deep probe incompatible in the
> > first place, because it will likely not find the resources it requires that early
> > if it doesn't deep probe.
> > 
> > Cheers,
> > Ahmad
> > 
> > -- 
> > Pengutronix e.K.                           |                             |
> > Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
> > 31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
> > Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> > 
> > _______________________________________________
> > barebox mailing list
> > barebox@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/barebox
> > 
> 
> -- 
> Pengutronix e.K.                           |                             |
> Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
> 31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> 
> _______________________________________________
> barebox mailing list
> barebox@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
> 

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* Re: [PATCH 17/17] ARM: i.MX Phytec physom: Add deep-probe support
  2021-04-26  9:20     ` Marco Felsch
  2021-04-26  9:26       ` Marco Felsch
@ 2021-04-26  9:36       ` Ahmad Fatoum
  2021-04-26 10:03         ` Marco Felsch
  1 sibling, 1 reply; 34+ messages in thread
From: Ahmad Fatoum @ 2021-04-26  9:36 UTC (permalink / raw)
  To: Marco Felsch; +Cc: Barebox List

Hi,

On 26.04.21 11:20, Marco Felsch wrote:
>> How about changing BAREBOX_DEEP_PROBE_ENABLE so BAREBOX_DEEP_PROBE_ENABLE(physom_imx6_match);
>> works? Updated boards should be using board drivers anyway, so make it easier for them to
>> enable deep probe.
> 
> Hi Ahmad,
> 
> Why do I need to chnage it to board drivers if I only wanna fix a probe
> order issue? But you're right adding the _match table should be possible
> to :)

Either you have board code at a single init level and changing to a board driver
will be very straight-forward. Or you have multiple initcalls, which expect
drivers at prior initcall levels to have probed a device, which will be broken
by a move to deep probe.

>> I'd go even further and require board drivers by having it take a driver_d * as argument
>> and introduce deep_probe_board_driver() that expands to postcore_platform_driver and
>> BAREBOX_DEEP_PROBE_ENABLE.
> 
> How about this:
>  1st) adding a probe_enum like kernel and introduce PROBE_PREFER_DEEP
>  2nd) adding a deep_probe_enable_board() function to common/deep_probe.c
>  3th) checking during register_driver() if the flag is set and call the
>       deep_probe_enable_board().
> 
> This allows use to still use the macro mechanism and the boards already
> converted to the board driver style can use this simple enum to mark all
> boards as deep-probable.

I don't see how that would work. deep_probe_is_supported() is called on oftree
registration, which is prior to the board driver's register_driver.
I thought that's the point of the linker array: You need the info too early
to be able to dynamically register a board.

Cheers,
Ahmad

> 
> Regards,
>   Marco
> 
>> This would prevent having a board driver that's deep probe incompatible in the
>> first place, because it will likely not find the resources it requires that early
>> if it doesn't deep probe.
>>
>> Cheers,
>> Ahmad
>>
>> -- 
>> Pengutronix e.K.                           |                             |
>> Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
>> 31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
>> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
>>
>> _______________________________________________
>> barebox mailing list
>> barebox@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/barebox
>>
> 

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* Re: [PATCH 17/17] ARM: i.MX Phytec physom: Add deep-probe support
  2021-04-26  9:36       ` Ahmad Fatoum
@ 2021-04-26 10:03         ` Marco Felsch
  0 siblings, 0 replies; 34+ messages in thread
From: Marco Felsch @ 2021-04-26 10:03 UTC (permalink / raw)
  To: Ahmad Fatoum; +Cc: Barebox List

On 21-04-26 11:36, Ahmad Fatoum wrote:
> Hi,
> 
> On 26.04.21 11:20, Marco Felsch wrote:
> >> How about changing BAREBOX_DEEP_PROBE_ENABLE so BAREBOX_DEEP_PROBE_ENABLE(physom_imx6_match);
> >> works? Updated boards should be using board drivers anyway, so make it easier for them to
> >> enable deep probe.
> > 
> > Hi Ahmad,
> > 
> > Why do I need to chnage it to board drivers if I only wanna fix a probe
> > order issue? But you're right adding the _match table should be possible
> > to :)
> 
> Either you have board code at a single init level and changing to a board driver
> will be very straight-forward. Or you have multiple initcalls, which expect
> drivers at prior initcall levels to have probed a device, which will be broken
> by a move to deep probe.
> 
> >> I'd go even further and require board drivers by having it take a driver_d * as argument
> >> and introduce deep_probe_board_driver() that expands to postcore_platform_driver and
> >> BAREBOX_DEEP_PROBE_ENABLE.
> > 
> > How about this:
> >  1st) adding a probe_enum like kernel and introduce PROBE_PREFER_DEEP
> >  2nd) adding a deep_probe_enable_board() function to common/deep_probe.c
> >  3th) checking during register_driver() if the flag is set and call the
> >       deep_probe_enable_board().
> > 
> > This allows use to still use the macro mechanism and the boards already
> > converted to the board driver style can use this simple enum to mark all
> > boards as deep-probable.
> 
> I don't see how that would work. deep_probe_is_supported() is called on oftree
> registration, which is prior to the board driver's register_driver.

Arg.. you're right, didn't noticed that call during
barebox_register_of().

Regards,
  Marco

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 1/3] fixup! common: add initial barebox deep-probe support
  2021-04-16  9:49 [PATCH v4 00/17] barebox deep probe support Sascha Hauer
                   ` (17 preceding siblings ...)
  2021-04-19  7:35 ` [PATCH v4 00/17] barebox deep probe support Ahmad Fatoum
@ 2021-04-28 10:28 ` Marco Felsch
  2021-04-28 10:28   ` [PATCH 2/3] fixup! ARM: boards: mx6-sabrelite: add " Marco Felsch
                     ` (4 more replies)
  18 siblings, 5 replies; 34+ messages in thread
From: Marco Felsch @ 2021-04-28 10:28 UTC (permalink / raw)
  To: barebox

---
Hi,

this is just a proposal to change the current linker array approach to
an initcall approach. Why? Because now we can simply register a
board-driver without having to list each compatible. 

I used the pure_initcall without adding a new one, since the
documentation says that pure_initcalls are used to init variables. In
our case we init boards_list.

Regards,
  Marco

 common/deep-probe.c               | 38 +++++++++++++++++++++++++++++--
 include/asm-generic/barebox.lds.h | 10 +-------
 include/deep-probe.h              | 34 +++++++++++++++------------
 3 files changed, 56 insertions(+), 26 deletions(-)

diff --git a/common/deep-probe.c b/common/deep-probe.c
index 9fc67f170c..6b04b4f5da 100644
--- a/common/deep-probe.c
+++ b/common/deep-probe.c
@@ -2,8 +2,16 @@
 
 #include <common.h>
 #include <deep-probe.h>
+#include <linux/list.h>
 #include <of.h>
 
+struct deep_probe_entry {
+	struct list_head entry;
+	const char *compatible;
+};
+
+LIST_HEAD(boards_list);
+
 enum deep_probe_state {
 	DEEP_PROBE_UNKONWN = -1,
 	DEEP_PROBE_NOT_SUPPORTED,
@@ -12,6 +20,33 @@ enum deep_probe_state {
 
 static enum deep_probe_state boardstate = DEEP_PROBE_UNKONWN;
 
+int deep_probe_enable_board(const struct driver_d *board_driver, const char *compatible)
+{
+	struct deep_probe_entry *new;
+
+	if (!board_driver && !compatible)
+		return -EINVAL;
+
+	if (board_driver) {
+		const struct of_device_id *of_device_ids = board_driver->of_compatible;
+
+		for (; of_device_ids->compatible; of_device_ids++) {
+			new = xzalloc(sizeof(*new));
+			new->compatible = of_device_ids->compatible;
+			list_add(&new->entry, &boards_list);
+		}
+	}
+
+	if (compatible) {
+		new = xzalloc(sizeof(*new));
+		new->compatible = compatible;
+		list_add(&new->entry, &boards_list);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(deep_probe_enable_board);
+
 bool deep_probe_is_supported(void)
 {
 	struct deep_probe_entry *board;
@@ -20,8 +55,7 @@ bool deep_probe_is_supported(void)
 		return boardstate;
 
 	/* determine boardstate */
-	for (board = &__barebox_deep_probe_start;
-	     board != &__barebox_deep_probe_end; board++) {
+	list_for_each_entry(board, &boards_list, entry) {
 		if (of_machine_is_compatible(board->compatible)) {
 			boardstate = DEEP_PROBE_SUPPORTED;
 			return true;
diff --git a/include/asm-generic/barebox.lds.h b/include/asm-generic/barebox.lds.h
index c5f9d97547..a7d32160d1 100644
--- a/include/asm-generic/barebox.lds.h
+++ b/include/asm-generic/barebox.lds.h
@@ -114,13 +114,6 @@
 	KEEP(*(.rsa_keys.rodata.*));		\
 	__rsa_keys_end = .;			\
 
-#define BAREBOX_DEEP_PROBE			\
-	STRUCT_ALIGN();				\
-	__barebox_deep_probe_start = .;		\
-	KEEP(*(SORT_BY_NAME(.barebox_deep_probe*)))	\
-	__barebox_deep_probe_end = .;
-
-
 #ifdef CONFIG_CONSTRUCTORS
 #define KERNEL_CTORS()  . = ALIGN(8);                      \
 			__ctors_start = .;                 \
@@ -143,8 +136,7 @@
 	BAREBOX_CLK_TABLE			\
 	BAREBOX_DTB				\
 	BAREBOX_RSA_KEYS			\
-	BAREBOX_PCI_FIXUP			\
-	BAREBOX_DEEP_PROBE
+	BAREBOX_PCI_FIXUP
 
 #if defined(CONFIG_ARCH_BAREBOX_MAX_BARE_INIT_SIZE) && \
 CONFIG_ARCH_BAREBOX_MAX_BARE_INIT_SIZE < CONFIG_BAREBOX_MAX_BARE_INIT_SIZE
diff --git a/include/deep-probe.h b/include/deep-probe.h
index a646c10340..e00bd9bafe 100644
--- a/include/deep-probe.h
+++ b/include/deep-probe.h
@@ -2,25 +2,29 @@
 #ifndef __DEEP_PROBE_H
 #define __DEEP_PROBE_H
 
-#include <linux/stringify.h>
-#include <linux/types.h>
-
-struct deep_probe_entry {
-	const char *compatible;
-};
+struct driver_d;
 
 bool deep_probe_is_supported(void);
+int deep_probe_enable_board(const struct driver_d *board_driver, const char *compatible);
+
+#define _deep_probe_enable_driver(id,drv)			\
+	static int __init id(void)				\
+	{							\
+		return deep_probe_enable_board(&drv,NULL);	\
+	}							\
+	pure_initcall(id)
 
-extern struct deep_probe_entry __barebox_deep_probe_start;
-extern struct deep_probe_entry __barebox_deep_probe_end;
+#define deep_probe_enable_board_driver(drv)			\
+	_deep_probe_enable_driver(__UNIQUE_ID(deepprobe),drv)
 
-#define __BAREBOX_DEEP_PROBE_ENABLE(_entry,_compatible)			\
-	static const struct deep_probe_entry _entry			\
-	__attribute__ ((used,section (".barebox_deep_probe_" __stringify(_entry)))) = { \
-		.compatible = _compatible,				\
-	}
+#define _deep_probe_enable_compatible(id,compatible)		\
+	static int __init id(void)				\
+	{							\
+		return deep_probe_enable_board(NULL,compatible);\
+	}							\
+	pure_initcall(id)
 
-#define BAREBOX_DEEP_PROBE_ENABLE(_compatible)	\
-	__BAREBOX_DEEP_PROBE_ENABLE(__UNIQUE_ID(deepprobe),_compatible)
+#define deep_probe_enable_board_compatible(compatible)		\
+	_deep_probe_enable_compatible(__UNIQUE_ID(deepprobe),compatible)
 
 #endif /* __DEEP_PROBE_H */
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 2/3] fixup! ARM: boards: mx6-sabrelite: add deep-probe support
  2021-04-28 10:28 ` [PATCH 1/3] fixup! common: add initial barebox deep-probe support Marco Felsch
@ 2021-04-28 10:28   ` Marco Felsch
  2021-04-28 10:28   ` [PATCH 3/3] fixup! ARM: i.MX Phytec physom: Add " Marco Felsch
                     ` (3 subsequent siblings)
  4 siblings, 0 replies; 34+ messages in thread
From: Marco Felsch @ 2021-04-28 10:28 UTC (permalink / raw)
  To: barebox

---
 arch/arm/boards/freescale-mx6-sabrelite/board.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boards/freescale-mx6-sabrelite/board.c b/arch/arm/boards/freescale-mx6-sabrelite/board.c
index 0a2df391e9..69a154d081 100644
--- a/arch/arm/boards/freescale-mx6-sabrelite/board.c
+++ b/arch/arm/boards/freescale-mx6-sabrelite/board.c
@@ -167,5 +167,5 @@ static int sabrelite_coredevices_init(void)
 }
 coredevice_initcall(sabrelite_coredevices_init);
 
-BAREBOX_DEEP_PROBE_ENABLE("fsl,imx6q-sabrelite");
-BAREBOX_DEEP_PROBE_ENABLE("fsl,imx6dl-sabrelite");
+deep_probe_enable_board_compatible("fsl,imx6q-sabrelite");
+deep_probe_enable_board_compatible("fsl,imx6dl-sabrelite");
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 3/3] fixup! ARM: i.MX Phytec physom: Add deep-probe support
  2021-04-28 10:28 ` [PATCH 1/3] fixup! common: add initial barebox deep-probe support Marco Felsch
  2021-04-28 10:28   ` [PATCH 2/3] fixup! ARM: boards: mx6-sabrelite: add " Marco Felsch
@ 2021-04-28 10:28   ` Marco Felsch
  2021-04-28 10:42   ` [PATCH 1/3] fixup! common: add initial barebox " Ahmad Fatoum
                     ` (2 subsequent siblings)
  4 siblings, 0 replies; 34+ messages in thread
From: Marco Felsch @ 2021-04-28 10:28 UTC (permalink / raw)
  To: barebox

---
 arch/arm/boards/phytec-som-imx6/board.c | 12 +-----------
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/arch/arm/boards/phytec-som-imx6/board.c b/arch/arm/boards/phytec-som-imx6/board.c
index a108726468..9727062238 100644
--- a/arch/arm/boards/phytec-som-imx6/board.c
+++ b/arch/arm/boards/phytec-som-imx6/board.c
@@ -368,14 +368,4 @@ static struct driver_d physom_imx6_driver = {
 
 postcore_platform_driver(physom_imx6_driver);
 
-BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6q-pfla02");
-BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6dl-pfla02");
-BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6s-pfla02");
-BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6q-pcaaxl3");
-BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6q-pcm058-nand");
-BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6q-pcm058-emmc");
-BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6dl-pcm058-nand");
-BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6qp-pcm058-nand");
-BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6dl-pcm058-emmc");
-BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6ul-pcl063-nand");
-BAREBOX_DEEP_PROBE_ENABLE("phytec,imx6ul-pcl063-emmc");
+deep_probe_enable_board_driver(physom_imx6_driver);
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* Re: [PATCH 1/3] fixup! common: add initial barebox deep-probe support
  2021-04-28 10:28 ` [PATCH 1/3] fixup! common: add initial barebox deep-probe support Marco Felsch
  2021-04-28 10:28   ` [PATCH 2/3] fixup! ARM: boards: mx6-sabrelite: add " Marco Felsch
  2021-04-28 10:28   ` [PATCH 3/3] fixup! ARM: i.MX Phytec physom: Add " Marco Felsch
@ 2021-04-28 10:42   ` Ahmad Fatoum
  2021-04-28 10:48     ` Marco Felsch
  2021-04-28 11:21   ` Marco Felsch
  2021-05-03 11:54   ` Sascha Hauer
  4 siblings, 1 reply; 34+ messages in thread
From: Ahmad Fatoum @ 2021-04-28 10:42 UTC (permalink / raw)
  To: Marco Felsch, barebox

Hello Marco,

On 28.04.21 12:28, Marco Felsch wrote:
> ---
> Hi,
> 
> this is just a proposal to change the current linker array approach to
> an initcall approach. Why? Because now we can simply register a
> board-driver without having to list each compatible. 
> 
> I used the pure_initcall without adding a new one, since the
> documentation says that pure_initcalls are used to init variables. In
> our case we init boards_list.
> 
> Regards,
>   Marco
> 
>  common/deep-probe.c               | 38 +++++++++++++++++++++++++++++--
>  include/asm-generic/barebox.lds.h | 10 +-------
>  include/deep-probe.h              | 34 +++++++++++++++------------
>  3 files changed, 56 insertions(+), 26 deletions(-)
> 
> diff --git a/common/deep-probe.c b/common/deep-probe.c
> index 9fc67f170c..6b04b4f5da 100644
> --- a/common/deep-probe.c
> +++ b/common/deep-probe.c
> @@ -2,8 +2,16 @@
>  
>  #include <common.h>
>  #include <deep-probe.h>
> +#include <linux/list.h>
>  #include <of.h>
>  
> +struct deep_probe_entry {
> +	struct list_head entry;
> +	const char *compatible;
> +};
> +
> +LIST_HEAD(boards_list);

Looks like it can be made static?

> +
>  enum deep_probe_state {
>  	DEEP_PROBE_UNKONWN = -1,
>  	DEEP_PROBE_NOT_SUPPORTED,
> @@ -12,6 +20,33 @@ enum deep_probe_state {
>  
>  static enum deep_probe_state boardstate = DEEP_PROBE_UNKONWN;
>  
> +int deep_probe_enable_board(const struct driver_d *board_driver, const char *compatible)
> +{
> +	struct deep_probe_entry *new;
> +
> +	if (!board_driver && !compatible)
> +		return -EINVAL;
> +
> +	if (board_driver) {
> +		const struct of_device_id *of_device_ids = board_driver->of_compatible;
> +
> +		for (; of_device_ids->compatible; of_device_ids++) {
> +			new = xzalloc(sizeof(*new));
> +			new->compatible = of_device_ids->compatible;
> +			list_add(&new->entry, &boards_list);
> +		}
> +	}
> +
> +	if (compatible) {
> +		new = xzalloc(sizeof(*new));
> +		new->compatible = compatible;
> +		list_add(&new->entry, &boards_list);
> +	}
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(deep_probe_enable_board);
> +
>  bool deep_probe_is_supported(void)
>  {
>  	struct deep_probe_entry *board;
> @@ -20,8 +55,7 @@ bool deep_probe_is_supported(void)
>  		return boardstate;
>  
>  	/* determine boardstate */
> -	for (board = &__barebox_deep_probe_start;
> -	     board != &__barebox_deep_probe_end; board++) {
> +	list_for_each_entry(board, &boards_list, entry) {
>  		if (of_machine_is_compatible(board->compatible)) {
>  			boardstate = DEEP_PROBE_SUPPORTED;
>  			return true;
> diff --git a/include/asm-generic/barebox.lds.h b/include/asm-generic/barebox.lds.h
> index c5f9d97547..a7d32160d1 100644
> --- a/include/asm-generic/barebox.lds.h
> +++ b/include/asm-generic/barebox.lds.h
> @@ -114,13 +114,6 @@
>  	KEEP(*(.rsa_keys.rodata.*));		\
>  	__rsa_keys_end = .;			\
>  
> -#define BAREBOX_DEEP_PROBE			\
> -	STRUCT_ALIGN();				\
> -	__barebox_deep_probe_start = .;		\
> -	KEEP(*(SORT_BY_NAME(.barebox_deep_probe*)))	\
> -	__barebox_deep_probe_end = .;
> -
> -
>  #ifdef CONFIG_CONSTRUCTORS
>  #define KERNEL_CTORS()  . = ALIGN(8);                      \
>  			__ctors_start = .;                 \
> @@ -143,8 +136,7 @@
>  	BAREBOX_CLK_TABLE			\
>  	BAREBOX_DTB				\
>  	BAREBOX_RSA_KEYS			\
> -	BAREBOX_PCI_FIXUP			\
> -	BAREBOX_DEEP_PROBE
> +	BAREBOX_PCI_FIXUP
>  
>  #if defined(CONFIG_ARCH_BAREBOX_MAX_BARE_INIT_SIZE) && \
>  CONFIG_ARCH_BAREBOX_MAX_BARE_INIT_SIZE < CONFIG_BAREBOX_MAX_BARE_INIT_SIZE
> diff --git a/include/deep-probe.h b/include/deep-probe.h
> index a646c10340..e00bd9bafe 100644
> --- a/include/deep-probe.h
> +++ b/include/deep-probe.h
> @@ -2,25 +2,29 @@
>  #ifndef __DEEP_PROBE_H
>  #define __DEEP_PROBE_H
>  
> -#include <linux/stringify.h>
> -#include <linux/types.h>
> -
> -struct deep_probe_entry {
> -	const char *compatible;
> -};
> +struct driver_d;
>  
>  bool deep_probe_is_supported(void);
> +int deep_probe_enable_board(const struct driver_d *board_driver, const char *compatible);
> +
> +#define _deep_probe_enable_driver(id,drv)			\
> +	static int __init id(void)				\

Can't you use drv ## deep_probe_init here and drop id?

> +	{							\
> +		return deep_probe_enable_board(&drv,NULL);	\

Missing whitespace

> +	}							\
> +	pure_initcall(id)
>  
> -extern struct deep_probe_entry __barebox_deep_probe_start;
> -extern struct deep_probe_entry __barebox_deep_probe_end;
> +#define deep_probe_enable_board_driver(drv)			\
> +	_deep_probe_enable_driver(__UNIQUE_ID(deepprobe),drv)
>  
> -#define __BAREBOX_DEEP_PROBE_ENABLE(_entry,_compatible)			\
> -	static const struct deep_probe_entry _entry			\
> -	__attribute__ ((used,section (".barebox_deep_probe_" __stringify(_entry)))) = { \
> -		.compatible = _compatible,				\
> -	}
> +#define _deep_probe_enable_compatible(id,compatible)		\
> +	static int __init id(void)				\
> +	{							\
> +		return deep_probe_enable_board(NULL,compatible);\
> +	}							\
> +	pure_initcall(id)
>  
> -#define BAREBOX_DEEP_PROBE_ENABLE(_compatible)	\
> -	__BAREBOX_DEEP_PROBE_ENABLE(__UNIQUE_ID(deepprobe),_compatible)
> +#define deep_probe_enable_board_compatible(compatible)		\
> +	_deep_probe_enable_compatible(__UNIQUE_ID(deepprobe),compatible)
>  
>  #endif /* __DEEP_PROBE_H */

Apart from that, I like it:

Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* Re: [PATCH 1/3] fixup! common: add initial barebox deep-probe support
  2021-04-28 10:42   ` [PATCH 1/3] fixup! common: add initial barebox " Ahmad Fatoum
@ 2021-04-28 10:48     ` Marco Felsch
  0 siblings, 0 replies; 34+ messages in thread
From: Marco Felsch @ 2021-04-28 10:48 UTC (permalink / raw)
  To: Ahmad Fatoum; +Cc: barebox

On 21-04-28 12:42, Ahmad Fatoum wrote:
> Hello Marco,
> 
> On 28.04.21 12:28, Marco Felsch wrote:
> > ---
> > Hi,
> > 
> > this is just a proposal to change the current linker array approach to
> > an initcall approach. Why? Because now we can simply register a
> > board-driver without having to list each compatible. 
> > 
> > I used the pure_initcall without adding a new one, since the
> > documentation says that pure_initcalls are used to init variables. In
> > our case we init boards_list.
> > 
> > Regards,
> >   Marco
> > 
> >  common/deep-probe.c               | 38 +++++++++++++++++++++++++++++--
> >  include/asm-generic/barebox.lds.h | 10 +-------
> >  include/deep-probe.h              | 34 +++++++++++++++------------
> >  3 files changed, 56 insertions(+), 26 deletions(-)
> > 
> > diff --git a/common/deep-probe.c b/common/deep-probe.c
> > index 9fc67f170c..6b04b4f5da 100644
> > --- a/common/deep-probe.c
> > +++ b/common/deep-probe.c
> > @@ -2,8 +2,16 @@
> >  
> >  #include <common.h>
> >  #include <deep-probe.h>
> > +#include <linux/list.h>
> >  #include <of.h>
> >  
> > +struct deep_probe_entry {
> > +	struct list_head entry;
> > +	const char *compatible;
> > +};
> > +
> > +LIST_HEAD(boards_list);
> 
> Looks like it can be made static?

Of course.

> > +
> >  enum deep_probe_state {
> >  	DEEP_PROBE_UNKONWN = -1,
> >  	DEEP_PROBE_NOT_SUPPORTED,
> > @@ -12,6 +20,33 @@ enum deep_probe_state {
> >  
> >  static enum deep_probe_state boardstate = DEEP_PROBE_UNKONWN;
> >  
> > +int deep_probe_enable_board(const struct driver_d *board_driver, const char *compatible)
> > +{
> > +	struct deep_probe_entry *new;
> > +
> > +	if (!board_driver && !compatible)
> > +		return -EINVAL;
> > +
> > +	if (board_driver) {
> > +		const struct of_device_id *of_device_ids = board_driver->of_compatible;
> > +
> > +		for (; of_device_ids->compatible; of_device_ids++) {
> > +			new = xzalloc(sizeof(*new));
> > +			new->compatible = of_device_ids->compatible;
> > +			list_add(&new->entry, &boards_list);
> > +		}
> > +	}
> > +
> > +	if (compatible) {
> > +		new = xzalloc(sizeof(*new));
> > +		new->compatible = compatible;
> > +		list_add(&new->entry, &boards_list);
> > +	}
> > +
> > +	return 0;
> > +}
> > +EXPORT_SYMBOL_GPL(deep_probe_enable_board);
> > +
> >  bool deep_probe_is_supported(void)
> >  {
> >  	struct deep_probe_entry *board;
> > @@ -20,8 +55,7 @@ bool deep_probe_is_supported(void)
> >  		return boardstate;
> >  
> >  	/* determine boardstate */
> > -	for (board = &__barebox_deep_probe_start;
> > -	     board != &__barebox_deep_probe_end; board++) {
> > +	list_for_each_entry(board, &boards_list, entry) {
> >  		if (of_machine_is_compatible(board->compatible)) {
> >  			boardstate = DEEP_PROBE_SUPPORTED;
> >  			return true;
> > diff --git a/include/asm-generic/barebox.lds.h b/include/asm-generic/barebox.lds.h
> > index c5f9d97547..a7d32160d1 100644
> > --- a/include/asm-generic/barebox.lds.h
> > +++ b/include/asm-generic/barebox.lds.h
> > @@ -114,13 +114,6 @@
> >  	KEEP(*(.rsa_keys.rodata.*));		\
> >  	__rsa_keys_end = .;			\
> >  
> > -#define BAREBOX_DEEP_PROBE			\
> > -	STRUCT_ALIGN();				\
> > -	__barebox_deep_probe_start = .;		\
> > -	KEEP(*(SORT_BY_NAME(.barebox_deep_probe*)))	\
> > -	__barebox_deep_probe_end = .;
> > -
> > -
> >  #ifdef CONFIG_CONSTRUCTORS
> >  #define KERNEL_CTORS()  . = ALIGN(8);                      \
> >  			__ctors_start = .;                 \
> > @@ -143,8 +136,7 @@
> >  	BAREBOX_CLK_TABLE			\
> >  	BAREBOX_DTB				\
> >  	BAREBOX_RSA_KEYS			\
> > -	BAREBOX_PCI_FIXUP			\
> > -	BAREBOX_DEEP_PROBE
> > +	BAREBOX_PCI_FIXUP
> >  
> >  #if defined(CONFIG_ARCH_BAREBOX_MAX_BARE_INIT_SIZE) && \
> >  CONFIG_ARCH_BAREBOX_MAX_BARE_INIT_SIZE < CONFIG_BAREBOX_MAX_BARE_INIT_SIZE
> > diff --git a/include/deep-probe.h b/include/deep-probe.h
> > index a646c10340..e00bd9bafe 100644
> > --- a/include/deep-probe.h
> > +++ b/include/deep-probe.h
> > @@ -2,25 +2,29 @@
> >  #ifndef __DEEP_PROBE_H
> >  #define __DEEP_PROBE_H
> >  
> > -#include <linux/stringify.h>
> > -#include <linux/types.h>
> > -
> > -struct deep_probe_entry {
> > -	const char *compatible;
> > -};
> > +struct driver_d;
> >  
> >  bool deep_probe_is_supported(void);
> > +int deep_probe_enable_board(const struct driver_d *board_driver, const char *compatible);
> > +
> > +#define _deep_probe_enable_driver(id,drv)			\
> > +	static int __init id(void)				\
> 
> Can't you use drv ## deep_probe_init here and drop id?

Yep, we could use this approach to.

> 
> > +	{							\
> > +		return deep_probe_enable_board(&drv,NULL);	\
> 
> Missing whitespace

> 
> > +	}							\
> > +	pure_initcall(id)
> >  
> > -extern struct deep_probe_entry __barebox_deep_probe_start;
> > -extern struct deep_probe_entry __barebox_deep_probe_end;
> > +#define deep_probe_enable_board_driver(drv)			\
> > +	_deep_probe_enable_driver(__UNIQUE_ID(deepprobe),drv)
> >  
> > -#define __BAREBOX_DEEP_PROBE_ENABLE(_entry,_compatible)			\
> > -	static const struct deep_probe_entry _entry			\
> > -	__attribute__ ((used,section (".barebox_deep_probe_" __stringify(_entry)))) = { \
> > -		.compatible = _compatible,				\
> > -	}
> > +#define _deep_probe_enable_compatible(id,compatible)		\
> > +	static int __init id(void)				\
> > +	{							\
> > +		return deep_probe_enable_board(NULL,compatible);\
> > +	}							\
> > +	pure_initcall(id)
> >  
> > -#define BAREBOX_DEEP_PROBE_ENABLE(_compatible)	\
> > -	__BAREBOX_DEEP_PROBE_ENABLE(__UNIQUE_ID(deepprobe),_compatible)
> > +#define deep_probe_enable_board_compatible(compatible)		\
> > +	_deep_probe_enable_compatible(__UNIQUE_ID(deepprobe),compatible)
> >  
> >  #endif /* __DEEP_PROBE_H */
> 
> Apart from that, I like it:

Thanks for the input, will change it and send a new fixup.

Regards,
  Marco

> 
> Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> 
> -- 
> Pengutronix e.K.                           |                             |
> Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
> 31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> 

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 1/3] fixup! common: add initial barebox deep-probe support
  2021-04-28 10:28 ` [PATCH 1/3] fixup! common: add initial barebox deep-probe support Marco Felsch
                     ` (2 preceding siblings ...)
  2021-04-28 10:42   ` [PATCH 1/3] fixup! common: add initial barebox " Ahmad Fatoum
@ 2021-04-28 11:21   ` Marco Felsch
  2021-05-03 11:54   ` Sascha Hauer
  4 siblings, 0 replies; 34+ messages in thread
From: Marco Felsch @ 2021-04-28 11:21 UTC (permalink / raw)
  To: barebox

---
Hi,

this is the reworked version with Ahmad's review feedback.

Regards,
  Marco

 common/deep-probe.c               | 38 +++++++++++++++++++++++++++++--
 include/asm-generic/barebox.lds.h | 10 +-------
 include/deep-probe.h              | 31 +++++++++++++------------
 3 files changed, 53 insertions(+), 26 deletions(-)

diff --git a/common/deep-probe.c b/common/deep-probe.c
index 9fc67f170c..ef927be02f 100644
--- a/common/deep-probe.c
+++ b/common/deep-probe.c
@@ -2,8 +2,16 @@
 
 #include <common.h>
 #include <deep-probe.h>
+#include <linux/list.h>
 #include <of.h>
 
+struct deep_probe_entry {
+	struct list_head entry;
+	const char *compatible;
+};
+
+static LIST_HEAD(boards_list);
+
 enum deep_probe_state {
 	DEEP_PROBE_UNKONWN = -1,
 	DEEP_PROBE_NOT_SUPPORTED,
@@ -12,6 +20,33 @@ enum deep_probe_state {
 
 static enum deep_probe_state boardstate = DEEP_PROBE_UNKONWN;
 
+int deep_probe_enable_board(const struct driver_d *board_driver, const char *compatible)
+{
+	struct deep_probe_entry *new;
+
+	if (!board_driver && !compatible)
+		return -EINVAL;
+
+	if (board_driver) {
+		const struct of_device_id *of_device_ids = board_driver->of_compatible;
+
+		for (; of_device_ids->compatible; of_device_ids++) {
+			new = xzalloc(sizeof(*new));
+			new->compatible = of_device_ids->compatible;
+			list_add(&new->entry, &boards_list);
+		}
+	}
+
+	if (compatible) {
+		new = xzalloc(sizeof(*new));
+		new->compatible = compatible;
+		list_add(&new->entry, &boards_list);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(deep_probe_enable_board);
+
 bool deep_probe_is_supported(void)
 {
 	struct deep_probe_entry *board;
@@ -20,8 +55,7 @@ bool deep_probe_is_supported(void)
 		return boardstate;
 
 	/* determine boardstate */
-	for (board = &__barebox_deep_probe_start;
-	     board != &__barebox_deep_probe_end; board++) {
+	list_for_each_entry(board, &boards_list, entry) {
 		if (of_machine_is_compatible(board->compatible)) {
 			boardstate = DEEP_PROBE_SUPPORTED;
 			return true;
diff --git a/include/asm-generic/barebox.lds.h b/include/asm-generic/barebox.lds.h
index c5f9d97547..a7d32160d1 100644
--- a/include/asm-generic/barebox.lds.h
+++ b/include/asm-generic/barebox.lds.h
@@ -114,13 +114,6 @@
 	KEEP(*(.rsa_keys.rodata.*));		\
 	__rsa_keys_end = .;			\
 
-#define BAREBOX_DEEP_PROBE			\
-	STRUCT_ALIGN();				\
-	__barebox_deep_probe_start = .;		\
-	KEEP(*(SORT_BY_NAME(.barebox_deep_probe*)))	\
-	__barebox_deep_probe_end = .;
-
-
 #ifdef CONFIG_CONSTRUCTORS
 #define KERNEL_CTORS()  . = ALIGN(8);                      \
 			__ctors_start = .;                 \
@@ -143,8 +136,7 @@
 	BAREBOX_CLK_TABLE			\
 	BAREBOX_DTB				\
 	BAREBOX_RSA_KEYS			\
-	BAREBOX_PCI_FIXUP			\
-	BAREBOX_DEEP_PROBE
+	BAREBOX_PCI_FIXUP
 
 #if defined(CONFIG_ARCH_BAREBOX_MAX_BARE_INIT_SIZE) && \
 CONFIG_ARCH_BAREBOX_MAX_BARE_INIT_SIZE < CONFIG_BAREBOX_MAX_BARE_INIT_SIZE
diff --git a/include/deep-probe.h b/include/deep-probe.h
index a646c10340..327e02071e 100644
--- a/include/deep-probe.h
+++ b/include/deep-probe.h
@@ -2,25 +2,26 @@
 #ifndef __DEEP_PROBE_H
 #define __DEEP_PROBE_H
 
-#include <linux/stringify.h>
-#include <linux/types.h>
-
-struct deep_probe_entry {
-	const char *compatible;
-};
+struct driver_d;
 
 bool deep_probe_is_supported(void);
+int deep_probe_enable_board(const struct driver_d *board_driver, const char *compatible);
 
-extern struct deep_probe_entry __barebox_deep_probe_start;
-extern struct deep_probe_entry __barebox_deep_probe_end;
+#define deep_probe_enable_board_driver(drv)			\
+	static int __init drv##deep_probe_init(void)		\
+	{							\
+		return deep_probe_enable_board(&drv, NULL);	\
+	}							\
+	pure_initcall(drv##deep_probe_init)
 
-#define __BAREBOX_DEEP_PROBE_ENABLE(_entry,_compatible)			\
-	static const struct deep_probe_entry _entry			\
-	__attribute__ ((used,section (".barebox_deep_probe_" __stringify(_entry)))) = { \
-		.compatible = _compatible,				\
-	}
+#define _deep_probe_enable_compatible(id, compatible)		\
+	static int __init id(void)				\
+	{							\
+		return deep_probe_enable_board(NULL, compatible);\
+	}							\
+	pure_initcall(id)
 
-#define BAREBOX_DEEP_PROBE_ENABLE(_compatible)	\
-	__BAREBOX_DEEP_PROBE_ENABLE(__UNIQUE_ID(deepprobe),_compatible)
+#define deep_probe_enable_board_compatible(compatible)		\
+	_deep_probe_enable_compatible(__PASTE(__UNIQUE_ID(deep_probe), _init), compatible)
 
 #endif /* __DEEP_PROBE_H */
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* Re: [PATCH 1/3] fixup! common: add initial barebox deep-probe support
  2021-04-28 10:28 ` [PATCH 1/3] fixup! common: add initial barebox deep-probe support Marco Felsch
                     ` (3 preceding siblings ...)
  2021-04-28 11:21   ` Marco Felsch
@ 2021-05-03 11:54   ` Sascha Hauer
  4 siblings, 0 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-05-03 11:54 UTC (permalink / raw)
  To: Marco Felsch; +Cc: barebox

On Wed, Apr 28, 2021 at 12:28:19PM +0200, Marco Felsch wrote:
> ---
> Hi,
> 
> this is just a proposal to change the current linker array approach to
> an initcall approach. Why? Because now we can simply register a
> board-driver without having to list each compatible. 
> 
> I used the pure_initcall without adding a new one, since the
> documentation says that pure_initcalls are used to init variables. In
> our case we init boards_list.
> 
> Regards,
>   Marco
> 
>  
> -extern struct deep_probe_entry __barebox_deep_probe_start;
> -extern struct deep_probe_entry __barebox_deep_probe_end;
> +#define deep_probe_enable_board_driver(drv)			\
> +	_deep_probe_enable_driver(__UNIQUE_ID(deepprobe),drv)
>  
> -#define __BAREBOX_DEEP_PROBE_ENABLE(_entry,_compatible)			\
> -	static const struct deep_probe_entry _entry			\
> -	__attribute__ ((used,section (".barebox_deep_probe_" __stringify(_entry)))) = { \
> -		.compatible = _compatible,				\
> -	}
> +#define _deep_probe_enable_compatible(id,compatible)		\
> +	static int __init id(void)				\
> +	{							\
> +		return deep_probe_enable_board(NULL,compatible);\
> +	}							\
> +	pure_initcall(id)
>  
> -#define BAREBOX_DEEP_PROBE_ENABLE(_compatible)	\
> -	__BAREBOX_DEEP_PROBE_ENABLE(__UNIQUE_ID(deepprobe),_compatible)

I like the version with the linker array as we don't add a whole bunch
of new initcalls. Why not simply replace the _compatible argument with a
pointer to a of_device_id array?

Sascha

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 09/17] common: add initial barebox deep-probe support
  2021-05-06  9:28 [PATCH v5 00/17] barebox deep probe support Sascha Hauer
@ 2021-05-06  9:28 ` Sascha Hauer
  0 siblings, 0 replies; 34+ messages in thread
From: Sascha Hauer @ 2021-05-06  9:28 UTC (permalink / raw)
  To: Barebox List; +Cc: Marco Felsch

From: Marco Felsch <m.felsch@pengutronix.de>

The barebox 'deep probe' or 'probe on demand' mechanism is the answer of
unwanted -EPROBE_DEFER failures. The EPROBE_DEFER error code was
introduced by commit ab3da15bc14c ("base: Introduce deferred probing")
and since then it causes a few problems.

The error is returned if either the device is not yet present or the
driver is not yet registered. This makes sense on linux systems where
modules and hot-plug devices are used very often but not for barebox.
The module support is rarely used and devices aren't hot pluggable.

The current barebox behaviour populates all devices before the drivers
are registered so all devices are present during the driver
registration. So the driver probe() function gets called immediately
after the driver registration and causes the -EPROBE_DEFER error if this
driver depends on an other not yet registered driver.

To get rid of the EPROBE_DEFER error code we need to reorder the device
population and the driver registration. All drivers must be registered
first. In an ideal world all driver can be registered by the same
initcall level. Then devices are getting populated which causes calling
the driver probe() function but this time resources/devices are created
on demand if not yet available.

Dependencies between devices are normally expressed as references to
other device nodes. With deep probe barebox provides helper functions
which take a device node and probe the device behind that node if
necessary. This means instead of returning -EPROBE_DEFER, we can now
make the desired resources available once we need them.

If the resource can't be created we are returning -ENODEV since we are
not supporting hot-plugging. Dropping EPROBE_DEFER is the long-term
goal, avoid initcall shifting is the short-term goal.

Call it deep-probe since the on-demand device creation can create very
deep stacks. This commit adds the initial support for: spi, i2c, reset,
regulator, gpio and clk resource on-demand creation. The deep-probe
mechanism must be enabled for each board to avoid breaking changes using
deep_probe_enable(). This can be changed later after all boards are
converted to the new mechanism.

Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
Link: https://lore.pengutronix.de/20201021115813.31645-8-m.felsch@pengutronix.de
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 common/Makefile                   |   1 +
 common/deep-probe.c               |  39 +++++++
 drivers/base/driver.c             |  11 +-
 drivers/clk/clk.c                 |   5 +
 drivers/i2c/i2c.c                 |   8 ++
 drivers/of/base.c                 |  13 ++-
 drivers/of/of_gpio.c              |   4 +
 drivers/of/platform.c             | 162 ++++++++++++++++++++++++++++++
 drivers/regulator/core.c          |   6 ++
 drivers/reset/core.c              |   4 +
 drivers/spi/spi.c                 |   2 +
 include/asm-generic/barebox.lds.h |  10 +-
 include/deep-probe.h              |  26 +++++
 include/of.h                      |  26 +++++
 14 files changed, 314 insertions(+), 3 deletions(-)
 create mode 100644 common/deep-probe.c
 create mode 100644 include/deep-probe.h

diff --git a/common/Makefile b/common/Makefile
index c0b45d263e..aa06e6e82e 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -3,6 +3,7 @@ obj-y				+= memory_display.o
 pbl-$(CONFIG_PBL_CONSOLE)	+= memory_display.o
 obj-y				+= clock.o
 obj-y				+= console_common.o
+obj-y				+= deep-probe.o
 obj-y				+= startup.o
 obj-y				+= misc.o
 obj-pbl-y			+= memsize.o
diff --git a/common/deep-probe.c b/common/deep-probe.c
new file mode 100644
index 0000000000..1020ad93b7
--- /dev/null
+++ b/common/deep-probe.c
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <common.h>
+#include <deep-probe.h>
+#include <of.h>
+
+enum deep_probe_state {
+	DEEP_PROBE_UNKONWN = -1,
+	DEEP_PROBE_NOT_SUPPORTED,
+	DEEP_PROBE_SUPPORTED
+};
+
+static enum deep_probe_state boardstate = DEEP_PROBE_UNKONWN;
+
+bool deep_probe_is_supported(void)
+{
+	struct deep_probe_entry *board;
+
+	if (boardstate > DEEP_PROBE_UNKONWN)
+		return boardstate;
+
+	/* determine boardstate */
+	for (board = &__barebox_deep_probe_start;
+	     board != &__barebox_deep_probe_end; board++) {
+		const struct of_device_id *matches = board->device_id;
+
+		for (; matches->compatible; matches++) {
+			if (of_machine_is_compatible(matches->compatible)) {
+				boardstate = DEEP_PROBE_SUPPORTED;
+				printk("Deep probe supported due to %s\n", matches->compatible);
+				return true;
+			}
+		}
+	}
+
+	boardstate = DEEP_PROBE_NOT_SUPPORTED;
+	return false;
+}
+EXPORT_SYMBOL_GPL(deep_probe_is_supported);
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index f60533c59e..58e6a8fcc9 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -21,6 +21,7 @@
 
 #include <common.h>
 #include <command.h>
+#include <deep-probe.h>
 #include <driver.h>
 #include <malloc.h>
 #include <console.h>
@@ -95,7 +96,15 @@ int device_probe(struct device_d *dev)
 	if (ret == -EPROBE_DEFER) {
 		list_del(&dev->active);
 		list_add(&dev->active, &deferred);
-		dev_dbg(dev, "probe deferred\n");
+
+		/*
+		 * -EPROBE_DEFER should never appear on a deep-probe machine so
+		 * inform the user immediately.
+		 */
+		if (deep_probe_is_supported())
+			dev_err(dev, "probe deferred\n");
+		else
+			dev_dbg(dev, "probe deferred\n");
 		return ret;
 	}
 
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index b04d44593b..e40dfae9ce 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -439,6 +439,11 @@ struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec)
 {
 	struct of_clk_provider *provider;
 	struct clk *clk = ERR_PTR(-EPROBE_DEFER);
+	int ret;
+
+	ret = of_device_ensure_probed(clkspec->np);
+	if (ret)
+		return ERR_PTR(ret);
 
 	/* Check if we have such a provider in our array */
 	list_for_each_entry(provider, &of_clk_providers, link) {
diff --git a/drivers/i2c/i2c.c b/drivers/i2c/i2c.c
index 57d8c7017f..12aac42794 100644
--- a/drivers/i2c/i2c.c
+++ b/drivers/i2c/i2c.c
@@ -407,6 +407,9 @@ static struct i2c_client *i2c_new_device(struct i2c_adapter *adapter,
 	}
 	client->dev.info = i2c_info;
 
+	if (chip->of_node)
+		chip->of_node->dev = &client->dev;
+
 	return client;
 }
 
@@ -548,6 +551,11 @@ struct i2c_adapter *i2c_get_adapter(int busnum)
 struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node)
 {
 	struct i2c_adapter *adap;
+	int ret;
+
+	ret = of_device_ensure_probed(node);
+	if (ret)
+		return ERR_PTR(ret);
 
 	for_each_i2c_adapter(adap)
 		if (adap->dev.device_node == node)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 1e3921f915..00141a394f 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -15,6 +15,7 @@
  * GNU General Public License for more details.
  */
 #include <common.h>
+#include <deep-probe.h>
 #include <of.h>
 #include <of_address.h>
 #include <errno.h>
@@ -1708,6 +1709,15 @@ int of_set_root_node(struct device_node *node)
 	return 0;
 }
 
+static int barebox_of_populate(void)
+{
+	if (IS_ENABLED(CONFIG_OFDEVICE) && deep_probe_is_supported())
+		return of_probe();
+
+	return 0;
+}
+of_populate_initcall(barebox_of_populate);
+
 void barebox_register_of(struct device_node *root)
 {
 	if (root_node)
@@ -1718,7 +1728,8 @@ void barebox_register_of(struct device_node *root)
 
 	if (IS_ENABLED(CONFIG_OFDEVICE)) {
 		of_clk_init(root, NULL);
-		of_probe();
+		if (!deep_probe_is_supported())
+			of_probe();
 	}
 }
 
diff --git a/drivers/of/of_gpio.c b/drivers/of/of_gpio.c
index 7cbeeaf69e..4d3ded0599 100644
--- a/drivers/of/of_gpio.c
+++ b/drivers/of/of_gpio.c
@@ -63,6 +63,10 @@ int of_get_named_gpio_flags(struct device_node *np, const char *propname,
 		return ret;
 	}
 
+	ret = of_device_ensure_probed(out_args.np);
+	if (ret)
+		return ret;
+
 	dev = of_find_device_by_node(out_args.np);
 	if (!dev) {
 		pr_debug("%s: unable to find device of node %s\n",
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 01de6f98af..4b79a9bc10 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -15,6 +15,7 @@
  * GNU General Public License for more details.
  */
 #include <common.h>
+#include <deep-probe.h>
 #include <malloc.h>
 #include <of.h>
 #include <of_address.h>
@@ -29,6 +30,12 @@
 struct device_d *of_find_device_by_node(struct device_node *np)
 {
 	struct device_d *dev;
+	int ret;
+
+	ret = of_device_ensure_probed(np);
+	if (ret)
+		return NULL;
+
 	for_each_device(dev)
 		if (dev->device_node == np)
 			return dev;
@@ -353,3 +360,158 @@ int of_platform_populate(struct device_node *root,
 	return rc;
 }
 EXPORT_SYMBOL_GPL(of_platform_populate);
+
+static struct device_d *of_device_create_on_demand(struct device_node *np)
+{
+	struct device_node *parent;
+	struct device_d *parent_dev, *dev;
+
+	parent = of_get_parent(np);
+	if (!parent)
+		return NULL;
+
+	/* Create all parent devices needed for the requested device */
+	parent_dev = parent->dev ? : of_device_create_on_demand(parent);
+	if (IS_ERR(parent_dev))
+		return parent_dev;
+
+	/*
+	 * Parent devices like i2c/spi controllers are populating their own
+	 * devices. So it can be that the requested device already exists after
+	 * the parent device creation.
+	 */
+	if (np->dev)
+		return np->dev;
+
+	pr_debug("%s: Create %s (%s) on demand\n", __func__,
+		 np->name, np->full_name);
+
+	if (of_device_is_compatible(np, "arm,primecell"))
+		dev = of_amba_device_create(np);
+	else
+		dev = of_platform_device_create(np, parent_dev);
+
+	return dev ? : ERR_PTR(-ENODEV);
+}
+
+/**
+ * of_device_ensure_probed() - ensures that a device is probed
+ *
+ * @np: the device_node handle which should be probed
+ *
+ * Ensures that the device is populated and probed so frameworks can make use of
+ * it.
+ *
+ * Return: %0 on success
+ *	   %-ENODEV if either the device can't be populated, the driver is
+ *	     missing or the driver probe returns an error.
+ */
+int of_device_ensure_probed(struct device_node *np)
+{
+	struct device_d *dev;
+
+	if (!deep_probe_is_supported())
+		return 0;
+
+	dev = of_device_create_on_demand(np);
+	if (IS_ERR(dev))
+		return PTR_ERR(dev);
+
+	BUG_ON(!dev);
+
+	/*
+	 * The deep-probe mechanism relies on the fact that all necessary
+	 * drivers are added before the device creation. Furthermore deep-probe
+	 * is the answer to the EPROBE_DEFER errno so we must ensure that the
+	 * driver was probed successfully after the device creation. Both
+	 * requirements are fulfilled if 'dev->driver' is not NULL.
+	 */
+	if (!dev->driver)
+		return -ENODEV;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(of_device_ensure_probed);
+
+/**
+ * of_device_ensure_probed_by_alias() - ensures that a device is probed
+ *
+ * @alias: the alias string to search for a device
+ *
+ * The function search for a given alias string and ensures that the device is
+ * populated and probed if found.
+ *
+ * Return: %0 on success
+ *	   %-ENODEV if either the device can't be populated, the driver is
+ *	     missing or the driver probe returns an error
+ *	   %-EINVAL if alias can't be found
+ */
+int of_device_ensure_probed_by_alias(const char *alias)
+{
+	struct device_node *dev_node;
+
+	dev_node = of_find_node_by_alias(NULL, alias);
+	if (!dev_node)
+		return -EINVAL;
+
+	return of_device_ensure_probed(dev_node);
+}
+EXPORT_SYMBOL_GPL(of_device_ensure_probed_by_alias);
+
+/**
+ * of_devices_ensure_probed_by_dev_id() - ensures that devices are probed
+ *
+ * @ids: the matching 'struct of_device_id' ids
+ *
+ * The function start searching the device tree from @np and populates and
+ * probes devices which match @ids.
+ *
+ * Return: %0 on success
+ *	   %-ENODEV if either the device wasn't found, can't be populated,
+ *	     the driver is missing or the driver probe returns an error
+ */
+int of_devices_ensure_probed_by_dev_id(const struct of_device_id *ids)
+{
+	struct device_node *np;
+	int err, ret = 0;
+
+	for_each_matching_node(np, ids) {
+		if (!of_device_is_available(np))
+			continue;
+
+		err = of_device_ensure_probed(np);
+		if (err)
+			ret = err;
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(of_devices_ensure_probed_by_dev_id);
+
+/**
+ * of_devices_ensure_probed_by_property() - ensures that devices are probed
+ *
+ * @property_name: The property name to search for
+ *
+ * The function starts searching the whole device tree and populates and probes
+ * devices which matches @property_name.
+ *
+ * Return: %0 on success
+ *	   %-ENODEV if either the device wasn't found, can't be populated,
+ *	     the driver is missing or the driver probe returns an error
+ */
+int of_devices_ensure_probed_by_property(const char *property_name)
+{
+	struct device_node *node;
+
+	for_each_node_with_property(node, property_name) {
+		int ret;
+
+		ret = of_device_ensure_probed(node);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(of_devices_ensure_probed_by_property);
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index ac3a9b048e..097f7d779b 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -175,6 +175,7 @@ int of_regulator_register(struct regulator_dev *rd, struct device_node *node)
 		return PTR_ERR(ri);
 
 	ri->node = node;
+	node->dev = rd->dev;
 
 	if (rd->desc->off_on_delay)
 		ri->enable_time_us = rd->desc->off_on_delay;
@@ -197,6 +198,7 @@ static struct regulator_internal *of_regulator_get(struct device_d *dev, const c
 	char *propname;
 	struct regulator_internal *ri;
 	struct device_node *node;
+	int ret;
 
 	propname = basprintf("%s-supply", supply);
 
@@ -228,6 +230,10 @@ static struct regulator_internal *of_regulator_get(struct device_d *dev, const c
 		goto out;
 	}
 
+	ret = of_device_ensure_probed(node);
+	if (ret)
+		return ERR_PTR(ret);
+
 	list_for_each_entry(ri, &regulator_list, list) {
 		if (ri->node == node) {
 			dev_dbg(dev, "Using %s regulator from %s\n",
diff --git a/drivers/reset/core.c b/drivers/reset/core.c
index 26a54f21df..e2edca6658 100644
--- a/drivers/reset/core.c
+++ b/drivers/reset/core.c
@@ -168,6 +168,10 @@ static struct reset_control *of_reset_control_get(struct device_node *node,
 	if (ret)
 		return ERR_PTR(ret);
 
+	ret = of_device_ensure_probed(args.np);
+	if (ret)
+		return ERR_PTR(ret);
+
 	rcdev = NULL;
 	list_for_each_entry(r, &reset_controller_list, list) {
 		if (args.np == r->of_node) {
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 8421d9d7c1..d1d3bdcc41 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -107,6 +107,8 @@ struct spi_device *spi_new_device(struct spi_controller *ctrl,
 	if (status)
 		goto fail;
 
+	chip->device_node->dev = &proxy->dev;
+
 	return proxy;
 fail:
 	free(proxy);
diff --git a/include/asm-generic/barebox.lds.h b/include/asm-generic/barebox.lds.h
index a7d32160d1..c5f9d97547 100644
--- a/include/asm-generic/barebox.lds.h
+++ b/include/asm-generic/barebox.lds.h
@@ -114,6 +114,13 @@
 	KEEP(*(.rsa_keys.rodata.*));		\
 	__rsa_keys_end = .;			\
 
+#define BAREBOX_DEEP_PROBE			\
+	STRUCT_ALIGN();				\
+	__barebox_deep_probe_start = .;		\
+	KEEP(*(SORT_BY_NAME(.barebox_deep_probe*)))	\
+	__barebox_deep_probe_end = .;
+
+
 #ifdef CONFIG_CONSTRUCTORS
 #define KERNEL_CTORS()  . = ALIGN(8);                      \
 			__ctors_start = .;                 \
@@ -136,7 +143,8 @@
 	BAREBOX_CLK_TABLE			\
 	BAREBOX_DTB				\
 	BAREBOX_RSA_KEYS			\
-	BAREBOX_PCI_FIXUP
+	BAREBOX_PCI_FIXUP			\
+	BAREBOX_DEEP_PROBE
 
 #if defined(CONFIG_ARCH_BAREBOX_MAX_BARE_INIT_SIZE) && \
 CONFIG_ARCH_BAREBOX_MAX_BARE_INIT_SIZE < CONFIG_BAREBOX_MAX_BARE_INIT_SIZE
diff --git a/include/deep-probe.h b/include/deep-probe.h
new file mode 100644
index 0000000000..f75ad1065c
--- /dev/null
+++ b/include/deep-probe.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef __DEEP_PROBE_H
+#define __DEEP_PROBE_H
+
+#include <linux/stringify.h>
+#include <linux/types.h>
+
+struct deep_probe_entry {
+	const struct of_device_id *device_id;
+};
+
+bool deep_probe_is_supported(void);
+
+extern struct deep_probe_entry __barebox_deep_probe_start;
+extern struct deep_probe_entry __barebox_deep_probe_end;
+
+#define __BAREBOX_DEEP_PROBE_ENABLE(_entry,_device_id)			\
+	static const struct deep_probe_entry _entry			\
+	__attribute__ ((used,section (".barebox_deep_probe_" __stringify(_entry)))) = { \
+		.device_id = _device_id,				\
+	}
+
+#define BAREBOX_DEEP_PROBE_ENABLE(_device_id)	\
+	__BAREBOX_DEEP_PROBE_ENABLE(__UNIQUE_ID(deepprobe),_device_id)
+
+#endif /* __DEEP_PROBE_H */
diff --git a/include/of.h b/include/of.h
index a3527c1afd..78c06ec2c3 100644
--- a/include/of.h
+++ b/include/of.h
@@ -276,6 +276,11 @@ extern struct device_d *of_device_enable_and_register_by_name(const char *name);
 extern struct device_d *of_device_enable_and_register_by_alias(
 							const char *alias);
 
+extern int of_device_ensure_probed(struct device_node *np);
+extern int of_device_ensure_probed_by_alias(const char *alias);
+extern int of_devices_ensure_probed_by_property(const char *property_name);
+extern int of_devices_ensure_probed_by_dev_id(const struct of_device_id *ids);
+
 struct cdev *of_parse_partition(struct cdev *cdev, struct device_node *node);
 int of_parse_partitions(struct cdev *cdev, struct device_node *node);
 int of_fixup_partitions(struct device_node *np, struct cdev *cdev);
@@ -359,6 +364,27 @@ static inline struct device_d *of_platform_device_create(struct device_node *np,
 	return NULL;
 }
 
+static inline int of_device_ensure_probed(struct device_node *np)
+{
+	return 0;
+}
+
+static inline int of_device_ensure_probed_by_alias(const char *alias)
+{
+	return 0;
+}
+
+static inline int of_devices_ensure_probed_by_property(const char *property_name)
+{
+	return 0;
+}
+
+static inline int
+of_devices_ensure_probed_by_dev_id(const struct of_device_id *ids)
+{
+	return 0;
+}
+
 static inline int of_bus_n_addr_cells(struct device_node *np)
 {
 	return 0;
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

end of thread, other threads:[~2021-05-06  9:31 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-16  9:49 [PATCH v4 00/17] barebox deep probe support Sascha Hauer
2021-04-16  9:49 ` [PATCH 01/17] imx53: remove unused imx53_add_nand Sascha Hauer
2021-04-16  9:49 ` [PATCH 02/17] of: platform: remove check of already added devices Sascha Hauer
2021-04-16  9:49 ` [PATCH 03/17] of: platform: Keep track of populated platform devices Sascha Hauer
2021-04-16  9:49 ` [PATCH 04/17] of: base: move memory init from DT to initcall Sascha Hauer
2021-04-16  9:49 ` [PATCH 05/17] of: base: move clock init from of_probe() to barebox_register_of() Sascha Hauer
2021-04-16  9:49 ` [PATCH 06/17] of: Set of_chosen and of_model earlier Sascha Hauer
2021-04-16  9:49 ` [PATCH 07/17] of: implement of_get_stdoutpath() Sascha Hauer
2021-04-16  9:49 ` [PATCH 08/17] initcall: add of_populate_initcall Sascha Hauer
2021-04-16  9:49 ` [PATCH 09/17] common: add initial barebox deep-probe support Sascha Hauer
2021-04-19  7:16   ` Ahmad Fatoum
2021-04-26  8:15     ` Marco Felsch
2021-04-16  9:49 ` [PATCH 10/17] pinctrl: Find controller node first Sascha Hauer
2021-04-16  9:49 ` [PATCH 11/17] common: Explicitly probe consoles earlier with deep probe Sascha Hauer
2021-04-16  9:49 ` [PATCH 12/17] pinctrl: Add deep probe support Sascha Hauer
2021-04-16  9:49 ` [PATCH 13/17] ARM: i.MX: esdctl: add deep-probe support Sascha Hauer
2021-04-16  9:49 ` [PATCH 14/17] ARM: stm32mp: ddrctrl: " Sascha Hauer
2021-04-16  9:49 ` [PATCH 15/17] ARM: boards: mx6-sabrelite: " Sascha Hauer
2021-04-16  9:49 ` [PATCH 16/17] ARM: i.MX Phytec physom: convert to board driver Sascha Hauer
2021-04-16  9:49 ` [PATCH 17/17] ARM: i.MX Phytec physom: Add deep-probe support Sascha Hauer
2021-04-19  7:12   ` Ahmad Fatoum
2021-04-26  9:20     ` Marco Felsch
2021-04-26  9:26       ` Marco Felsch
2021-04-26  9:36       ` Ahmad Fatoum
2021-04-26 10:03         ` Marco Felsch
2021-04-19  7:35 ` [PATCH v4 00/17] barebox deep probe support Ahmad Fatoum
2021-04-28 10:28 ` [PATCH 1/3] fixup! common: add initial barebox deep-probe support Marco Felsch
2021-04-28 10:28   ` [PATCH 2/3] fixup! ARM: boards: mx6-sabrelite: add " Marco Felsch
2021-04-28 10:28   ` [PATCH 3/3] fixup! ARM: i.MX Phytec physom: Add " Marco Felsch
2021-04-28 10:42   ` [PATCH 1/3] fixup! common: add initial barebox " Ahmad Fatoum
2021-04-28 10:48     ` Marco Felsch
2021-04-28 11:21   ` Marco Felsch
2021-05-03 11:54   ` Sascha Hauer
2021-05-06  9:28 [PATCH v5 00/17] barebox deep probe support Sascha Hauer
2021-05-06  9:28 ` [PATCH 09/17] common: add initial barebox deep-probe support Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox