All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/20] dm: Enhance of-platdata to support parent devices
@ 2020-10-03 17:31 Simon Glass
  2020-10-03 17:31 ` [PATCH 01/20] sandbox: Drop ad-hoc device declarations in SPL Simon Glass
                   ` (38 more replies)
  0 siblings, 39 replies; 43+ messages in thread
From: Simon Glass @ 2020-10-03 17:31 UTC (permalink / raw)
  To: u-boot

At present dev_get_parent() always returns the root device with
of-platdata. This means that it is not possible to find the I2C bus for an
I2C device easily. In many cases this does not cause problems as there is
only a single I2C bus, but it is still inconsistent with U-Boot proper.

Worse is that because devices are not bound to the correct parent, they
will not have parent_platdata allocated correctly. Manual fix-ups are
required in the code.

This series adds support for parent devices with of-platdata.

Recent improvements to of-platadata have provided a function to obtain a
device based on its driver_info struct. This requires in generated C code
in dm_populate_phandle_data() which writes the udevice pointer into each
phandle value, since this cannot be known at build time.

This works well and fixes a big hole in of-platdata. But the
implementation has a few drawbacks: the need for generated code adds (very
slightly) to code size and it means that the SPL must sit in writable
memory. The latter can be considered a security risk and is not actually
supported on Intel Apollo Lake.

Another point is that in future of-platadata may support instantiation of
devices at build time. Pointer fix-ups could become quite taxing.

So this series adjusts the approach, storing an index (idx) to the
driver_info struct in the linker list instead. That index can be figured
out in dtoc and the value placed directly in the phandle struct. For
64-bit machines it is also smaller than a pointer. It requires a new table
(driver_rt) to be set up at runtime.

This series adds more SPL tests written in C, using the infrastructure in
the previous series (u-boot-dm/tes-working). A few clean-ups and a bug fix
resulting from these are included.

Finally, x86 is updated to use the parent support. For now, parent support
is behind a Kconfig option, but I expect this will become the default,
assuming that no major problems are found.

SPL size impact is fairly neural, slightly positive on chromebook_jerry
(Thumb-2) and slightly negative on rock64-rk3328 (aarch64):

  aarch64: spl/u-boot-spl:all +39.0 spl/u-boot-spl:rodata -5.0
           spl/u-boot-spl:text +44.0
      arm: spl/u-boot-spl:all -49.0 spl/u-boot-spl:data -80.0
           spl/u-boot-spl:text +36.0 spl/u-boot-spl:rodata -5.0

The increase in code size is due to lists_bind_drivers() having to do
multiple passes to ensure that parents are processed before children. This
could possible be reduced with a more complex linker list ordering
mechanism, but it would be a bit messy and that idea is not explored in
this series.


Simon Glass (20):
  sandbox: Drop ad-hoc device declarations in SPL
  dtoc: Document the return value of scan_structs()
  dtoc: Order the structures internally by name
  dm: core: Allow dm_warn() to be used in SPL
  dtoc: Fix widening of int to bytes
  dm: Add a C test for of-platdata properties
  sandbox: Allow selection of SPL unit tests
  dm: test: Drop of-platdata pytest
  dm: test: Add a check that all devices have a dev value
  dm: test: Add a test for of-platdata phandles
  dm: Use an allocated array for run-time device info
  sandbox: Fix up building for of-platdata
  dm: Support parent devices with of-platdata
  dm: Add a test for of-platdata parent information
  dm: core: Convert #ifdef to if() in root.c
  x86: apl: Enable SPI flash in TPL with APL_SPI_FLASH_BOOT
  x86: apl: Take advantage of the of-platdata parent support
  dm: Use driver_info index instead of pointer
  dm: Don't allow U_BOOT_DEVICE() when of-platdata is used
  dm: doc: Update the of-platadata documentation

 arch/sandbox/cpu/spl.c              |  14 +-
 arch/sandbox/cpu/start.c            |  16 +--
 arch/sandbox/dts/sandbox.dts        |   1 +
 arch/sandbox/dts/sandbox.dtsi       |  27 ++++
 arch/sandbox/include/asm/state.h    |   2 +-
 arch/x86/cpu/apollolake/Kconfig     |   2 +
 arch/x86/cpu/apollolake/spl.c       |   3 +-
 board/sandbox/sandbox.c             |   2 +
 configs/sandbox_spl_defconfig       |   5 +-
 doc/driver-model/of-plat.rst        |  42 +++---
 drivers/clk/clk-uclass.c            |   3 +-
 drivers/clk/clk_fixed_rate.c        |   4 +-
 drivers/clk/clk_sandbox.c           |   4 +-
 drivers/core/Kconfig                |  18 ++-
 drivers/core/device.c               |  23 +++-
 drivers/core/lists.c                |  70 +++++++++-
 drivers/core/root.c                 |  29 ++--
 drivers/core/util.c                 |   2 +-
 drivers/i2c/Makefile                |   2 +-
 drivers/i2c/i2c-emul-uclass.c       |   2 +
 drivers/i2c/sandbox_i2c.c           |   4 +-
 drivers/misc/irq-uclass.c           |   2 +-
 drivers/misc/p2sb-uclass.c          |  27 ++--
 drivers/misc/spltest_sandbox.c      |  35 -----
 drivers/mmc/fsl_esdhc_imx.c         |   7 +-
 drivers/rtc/rtc-uclass.c            |   2 +
 drivers/rtc/sandbox_rtc.c           |   4 +-
 drivers/serial/sandbox.c            |   3 +
 drivers/spi/ich.c                   |   4 +-
 drivers/sysreset/sysreset_sandbox.c |   2 +
 dts/Kconfig                         |  18 +++
 include/asm-generic/global_data.h   |  13 ++
 include/config_uncmd_spl.h          |   1 -
 include/dm/device-internal.h        |   2 +-
 include/dm/device.h                 |  14 ++
 include/dm/platdata.h               |  32 ++++-
 include/dm/util.h                   |   2 +-
 include/dt-structs.h                |   6 +-
 test/dm/of_platdata.c               | 203 ++++++++++++++++++++++++++++
 test/dm/test-main.c                 |  24 +++-
 test/py/tests/test_ofplatdata.py    |  47 -------
 test/py/tests/test_spl.py           |   5 +-
 tools/dtoc/dtb_platdata.py          |  63 +++++----
 tools/dtoc/dtoc_test_simple.dts     |   1 +
 tools/dtoc/fdt.py                   |   9 ++
 tools/dtoc/test_dtoc.py             | 178 ++++++++++++++++--------
 tools/dtoc/test_fdt.py              |  10 ++
 47 files changed, 705 insertions(+), 284 deletions(-)

-- 
2.28.0.806.g8561365e88-goog

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

* [PATCH 01/20] sandbox: Drop ad-hoc device declarations in SPL
  2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
@ 2020-10-03 17:31 ` Simon Glass
  2020-10-03 17:31 ` [PATCH 02/20] dtoc: Document the return value of scan_structs() Simon Glass
                   ` (37 subsequent siblings)
  38 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2020-10-03 17:31 UTC (permalink / raw)
  To: u-boot

Since sandbox's SPL is build with of-platadata, we should not use
U_BOOT_DEVICE() declarations as well. Drop them.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 board/sandbox/sandbox.c             | 2 ++
 drivers/serial/sandbox.c            | 3 +++
 drivers/sysreset/sysreset_sandbox.c | 2 ++
 3 files changed, 7 insertions(+)

diff --git a/board/sandbox/sandbox.c b/board/sandbox/sandbox.c
index 937ce284111..18a605de026 100644
--- a/board/sandbox/sandbox.c
+++ b/board/sandbox/sandbox.c
@@ -21,10 +21,12 @@
  */
 gd_t *gd;
 
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
 /* Add a simple GPIO device */
 U_BOOT_DEVICE(gpio_sandbox) = {
 	.name = "sandbox_gpio",
 };
+#endif
 
 void flush_cache(unsigned long start, unsigned long size)
 {
diff --git a/drivers/serial/sandbox.c b/drivers/serial/sandbox.c
index f09d291e043..db2fbac6295 100644
--- a/drivers/serial/sandbox.c
+++ b/drivers/serial/sandbox.c
@@ -267,6 +267,7 @@ U_BOOT_DRIVER(sandbox_serial) = {
 	.flags = DM_FLAG_PRE_RELOC,
 };
 
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
 static const struct sandbox_serial_platdata platdata_non_fdt = {
 	.colour = -1,
 };
@@ -275,4 +276,6 @@ U_BOOT_DEVICE(serial_sandbox_non_fdt) = {
 	.name = "sandbox_serial",
 	.platdata = &platdata_non_fdt,
 };
+#endif
+
 #endif /* CONFIG_IS_ENABLED(OF_CONTROL) */
diff --git a/drivers/sysreset/sysreset_sandbox.c b/drivers/sysreset/sysreset_sandbox.c
index 69c22a70008..71cabd19568 100644
--- a/drivers/sysreset/sysreset_sandbox.c
+++ b/drivers/sysreset/sysreset_sandbox.c
@@ -130,7 +130,9 @@ U_BOOT_DRIVER(warm_sysreset_sandbox) = {
 	.ops		= &sandbox_warm_sysreset_ops,
 };
 
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
 /* This is here in case we don't have a device tree */
 U_BOOT_DEVICE(sysreset_sandbox_non_fdt) = {
 	.name = "sysreset_sandbox",
 };
+#endif
-- 
2.28.0.806.g8561365e88-goog

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

* [PATCH 02/20] dtoc: Document the return value of scan_structs()
  2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
  2020-10-03 17:31 ` [PATCH 01/20] sandbox: Drop ad-hoc device declarations in SPL Simon Glass
@ 2020-10-03 17:31 ` Simon Glass
  2020-10-03 17:31 ` [PATCH 03/20] dtoc: Order the structures internally by name Simon Glass
                   ` (36 subsequent siblings)
  38 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2020-10-03 17:31 UTC (permalink / raw)
  To: u-boot

Add documentation to this function as well as generate_structs(), where
the return value is ultimately passed in.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 tools/dtoc/dtb_platdata.py | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py
index 1b52198a943..72725bb6fa1 100644
--- a/tools/dtoc/dtb_platdata.py
+++ b/tools/dtoc/dtb_platdata.py
@@ -466,6 +466,13 @@ class DtbPlatdata(object):
 
         Once the widest property is determined, all other properties are
         updated to match that width.
+
+        Returns:
+            dict containing structures:
+                key (str): Node name, as a C identifier
+                value: dict containing structure fields:
+                    key (str): Field name
+                    value: Prop object with field information
         """
         structs = {}
         for node in self._valid_nodes:
@@ -536,6 +543,14 @@ class DtbPlatdata(object):
         This writes out the body of a header file consisting of structure
         definitions for node in self._valid_nodes. See the documentation in
         doc/driver-model/of-plat.rst for more information.
+
+        Args:
+            structs: dict containing structures:
+                key (str): Node name, as a C identifier
+                value: dict containing structure fields:
+                    key (str): Field name
+                    value: Prop object with field information
+
         """
         self.out_header()
         self.out('#include <stdbool.h>\n')
-- 
2.28.0.806.g8561365e88-goog

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

* [PATCH 03/20] dtoc: Order the structures internally by name
  2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
  2020-10-03 17:31 ` [PATCH 01/20] sandbox: Drop ad-hoc device declarations in SPL Simon Glass
  2020-10-03 17:31 ` [PATCH 02/20] dtoc: Document the return value of scan_structs() Simon Glass
@ 2020-10-03 17:31 ` Simon Glass
  2020-10-03 17:31 ` [PATCH 04/20] dm: core: Allow dm_warn() to be used in SPL Simon Glass
                   ` (35 subsequent siblings)
  38 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2020-10-03 17:31 UTC (permalink / raw)
  To: u-boot

At present the structures are written in name order, but parents have to
be written before their children, so the file does not end up being in
order. The order of nodes in _valid_nodes matches the order of the
devicetree.

Update the code so that _valid_nodes is in sorted order, by C name of
the structure. This allows us to assign a sequential ordering to each
U_BOOT_DEVICE() declaration.

U-Boot's linker lists are also ordered alphabetically, which means that
the order in the driver_info list will match the order used by dtoc. This
defines an index ('idx') for the U_BOOT_DEVICE declarations. They appear
in alphabetical order, numbered from 0 in _valid_nodes and in the
driver_info linker list.

Add a comment against each declaration, showing the idx value.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 tools/dtoc/dtb_platdata.py |  21 +++++---
 tools/dtoc/test_dtoc.py    | 105 ++++++++++++++++++++++++-------------
 2 files changed, 83 insertions(+), 43 deletions(-)

diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py
index 72725bb6fa1..31a9b3877ea 100644
--- a/tools/dtoc/dtb_platdata.py
+++ b/tools/dtoc/dtb_platdata.py
@@ -143,7 +143,8 @@ class DtbPlatdata(object):
     Properties:
         _fdt: Fdt object, referencing the device tree
         _dtb_fname: Filename of the input device tree binary file
-        _valid_nodes: A list of Node object with compatible strings
+        _valid_nodes: A list of Node object with compatible strings. The list
+            is ordered by conv_name_to_c(node.name)
         _include_disabled: true to include nodes marked status = "disabled"
         _outfile: The current output file (sys.stdout or a real file)
         _warning_disabled: true to disable warnings about driver names not found
@@ -367,23 +368,24 @@ class DtbPlatdata(object):
         """
         self._fdt = fdt.FdtScan(self._dtb_fname)
 
-    def scan_node(self, root):
+    def scan_node(self, root, valid_nodes):
         """Scan a node and subnodes to build a tree of node and phandle info
 
         This adds each node to self._valid_nodes.
 
         Args:
             root: Root node for scan
+            valid_nodes: List of Node objects to add to
         """
         for node in root.subnodes:
             if 'compatible' in node.props:
                 status = node.props.get('status')
                 if (not self._include_disabled and not status or
                         status.value != 'disabled'):
-                    self._valid_nodes.append(node)
+                    valid_nodes.append(node)
 
             # recurse to handle any subnodes
-            self.scan_node(node)
+            self.scan_node(node, valid_nodes)
 
     def scan_tree(self):
         """Scan the device tree for useful information
@@ -392,8 +394,12 @@ class DtbPlatdata(object):
             _valid_nodes: A list of nodes we wish to consider include in the
                 platform data
         """
-        self._valid_nodes = []
-        return self.scan_node(self._fdt.GetRoot())
+        valid_nodes = []
+        self.scan_node(self._fdt.GetRoot(), valid_nodes)
+        self._valid_nodes = sorted(valid_nodes,
+                                   key=lambda x: conv_name_to_c(x.name))
+        for idx, node in enumerate(self._valid_nodes):
+            node.idx = idx
 
     @staticmethod
     def get_num_cells(node):
@@ -474,7 +480,7 @@ class DtbPlatdata(object):
                     key (str): Field name
                     value: Prop object with field information
         """
-        structs = {}
+        structs = collections.OrderedDict()
         for node in self._valid_nodes:
             node_name, _ = self.get_normalized_compat_name(node)
             fields = {}
@@ -633,6 +639,7 @@ class DtbPlatdata(object):
 
         struct_name, _ = self.get_normalized_compat_name(node)
         var_name = conv_name_to_c(node.name)
+        self.buf('/* Node %s index %d */\n' % (node.path, node.idx))
         self.buf('static struct %s%s %s%s = {\n' %
                  (STRUCT_PREFIX, struct_name, VAL_PREFIX, var_name))
         for pname in sorted(node.props):
diff --git a/tools/dtoc/test_dtoc.py b/tools/dtoc/test_dtoc.py
index c2ff267de70..857a98e435f 100755
--- a/tools/dtoc/test_dtoc.py
+++ b/tools/dtoc/test_dtoc.py
@@ -209,6 +209,27 @@ struct dtd_sandbox_spl_test_2 {
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(C_HEADER + '''
+/* Node /i2c at 0 index 0 */
+static struct dtd_sandbox_i2c_test dtv_i2c_at_0 = {
+};
+U_BOOT_DEVICE(i2c_at_0) = {
+\t.name\t\t= "sandbox_i2c_test",
+\t.platdata\t= &dtv_i2c_at_0,
+\t.platdata_size\t= sizeof(dtv_i2c_at_0),
+};
+
+/* Node /i2c at 0/pmic at 9 index 1 */
+static struct dtd_sandbox_pmic_test dtv_pmic_at_9 = {
+\t.low_power\t\t= true,
+\t.reg\t\t\t= {0x9, 0x0},
+};
+U_BOOT_DEVICE(pmic_at_9) = {
+\t.name\t\t= "sandbox_pmic_test",
+\t.platdata\t= &dtv_pmic_at_9,
+\t.platdata_size\t= sizeof(dtv_pmic_at_9),
+};
+
+/* Node /spl-test index 2 */
 static struct dtd_sandbox_spl_test dtv_spl_test = {
 \t.boolval\t\t= true,
 \t.bytearray\t\t= {0x6, 0x0, 0x0},
@@ -227,6 +248,7 @@ U_BOOT_DEVICE(spl_test) = {
 \t.platdata_size\t= sizeof(dtv_spl_test),
 };
 
+/* Node /spl-test2 index 3 */
 static struct dtd_sandbox_spl_test dtv_spl_test2 = {
 \t.acpi_name\t\t= "\\\\_SB.GPO0",
 \t.bytearray\t\t= {0x1, 0x23, 0x34},
@@ -244,6 +266,7 @@ U_BOOT_DEVICE(spl_test2) = {
 \t.platdata_size\t= sizeof(dtv_spl_test2),
 };
 
+/* Node /spl-test3 index 4 */
 static struct dtd_sandbox_spl_test dtv_spl_test3 = {
 \t.stringarray\t\t= {"one", "", ""},
 };
@@ -253,6 +276,7 @@ U_BOOT_DEVICE(spl_test3) = {
 \t.platdata_size\t= sizeof(dtv_spl_test3),
 };
 
+/* Node /spl-test4 index 5 */
 static struct dtd_sandbox_spl_test_2 dtv_spl_test4 = {
 };
 U_BOOT_DEVICE(spl_test4) = {
@@ -261,24 +285,6 @@ U_BOOT_DEVICE(spl_test4) = {
 \t.platdata_size\t= sizeof(dtv_spl_test4),
 };
 
-static struct dtd_sandbox_i2c_test dtv_i2c_at_0 = {
-};
-U_BOOT_DEVICE(i2c_at_0) = {
-\t.name\t\t= "sandbox_i2c_test",
-\t.platdata\t= &dtv_i2c_at_0,
-\t.platdata_size\t= sizeof(dtv_i2c_at_0),
-};
-
-static struct dtd_sandbox_pmic_test dtv_pmic_at_9 = {
-\t.low_power\t\t= true,
-\t.reg\t\t\t= {0x9, 0x0},
-};
-U_BOOT_DEVICE(pmic_at_9) = {
-\t.name\t\t= "sandbox_pmic_test",
-\t.platdata\t= &dtv_pmic_at_9,
-\t.platdata_size\t= sizeof(dtv_pmic_at_9),
-};
-
 ''' + C_EMPTY_POPULATE_PHANDLE_DATA, data)
 
     def test_driver_alias(self):
@@ -300,6 +306,7 @@ struct dtd_sandbox_gpio {
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(C_HEADER + '''
+/* Node /gpios at 0 index 0 */
 static struct dtd_sandbox_gpio dtv_gpios_at_0 = {
 \t.gpio_bank_name\t\t= "a",
 \t.gpio_controller\t= true,
@@ -333,6 +340,7 @@ struct dtd_invalid {
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(C_HEADER + '''
+/* Node /spl-test index 0 */
 static struct dtd_invalid dtv_spl_test = {
 };
 U_BOOT_DEVICE(spl_test) = {
@@ -365,15 +373,7 @@ struct dtd_target {
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(C_HEADER + '''
-static struct dtd_target dtv_phandle_target = {
-\t.intval\t\t\t= 0x0,
-};
-U_BOOT_DEVICE(phandle_target) = {
-\t.name\t\t= "target",
-\t.platdata\t= &dtv_phandle_target,
-\t.platdata_size\t= sizeof(dtv_phandle_target),
-};
-
+/* Node /phandle2-target index 0 */
 static struct dtd_target dtv_phandle2_target = {
 \t.intval\t\t\t= 0x1,
 };
@@ -383,6 +383,7 @@ U_BOOT_DEVICE(phandle2_target) = {
 \t.platdata_size\t= sizeof(dtv_phandle2_target),
 };
 
+/* Node /phandle3-target index 1 */
 static struct dtd_target dtv_phandle3_target = {
 \t.intval\t\t\t= 0x2,
 };
@@ -392,6 +393,17 @@ U_BOOT_DEVICE(phandle3_target) = {
 \t.platdata_size\t= sizeof(dtv_phandle3_target),
 };
 
+/* Node /phandle-target index 4 */
+static struct dtd_target dtv_phandle_target = {
+\t.intval\t\t\t= 0x0,
+};
+U_BOOT_DEVICE(phandle_target) = {
+\t.name\t\t= "target",
+\t.platdata\t= &dtv_phandle_target,
+\t.platdata_size\t= sizeof(dtv_phandle_target),
+};
+
+/* Node /phandle-source index 2 */
 static struct dtd_source dtv_phandle_source = {
 \t.clocks\t\t\t= {
 \t\t\t{NULL, {}},
@@ -405,6 +417,7 @@ U_BOOT_DEVICE(phandle_source) = {
 \t.platdata_size\t= sizeof(dtv_phandle_source),
 };
 
+/* Node /phandle-source2 index 3 */
 static struct dtd_source dtv_phandle_source2 = {
 \t.clocks\t\t\t= {
 \t\t\t{NULL, {}},},
@@ -448,6 +461,7 @@ struct dtd_target {
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(C_HEADER + '''
+/* Node /phandle-target index 1 */
 static struct dtd_target dtv_phandle_target = {
 };
 U_BOOT_DEVICE(phandle_target) = {
@@ -456,6 +470,7 @@ U_BOOT_DEVICE(phandle_target) = {
 \t.platdata_size\t= sizeof(dtv_phandle_target),
 };
 
+/* Node /phandle-source2 index 0 */
 static struct dtd_source dtv_phandle_source2 = {
 \t.clocks\t\t\t= {
 \t\t\t{NULL, {}},},
@@ -479,15 +494,7 @@ void dm_populate_phandle_data(void) {
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(C_HEADER + '''
-static struct dtd_target dtv_phandle_target = {
-\t.intval\t\t\t= 0x0,
-};
-U_BOOT_DEVICE(phandle_target) = {
-\t.name\t\t= "target",
-\t.platdata\t= &dtv_phandle_target,
-\t.platdata_size\t= sizeof(dtv_phandle_target),
-};
-
+/* Node /phandle2-target index 0 */
 static struct dtd_target dtv_phandle2_target = {
 \t.intval\t\t\t= 0x1,
 };
@@ -497,6 +504,7 @@ U_BOOT_DEVICE(phandle2_target) = {
 \t.platdata_size\t= sizeof(dtv_phandle2_target),
 };
 
+/* Node /phandle3-target index 1 */
 static struct dtd_target dtv_phandle3_target = {
 \t.intval\t\t\t= 0x2,
 };
@@ -506,6 +514,17 @@ U_BOOT_DEVICE(phandle3_target) = {
 \t.platdata_size\t= sizeof(dtv_phandle3_target),
 };
 
+/* Node /phandle-target index 4 */
+static struct dtd_target dtv_phandle_target = {
+\t.intval\t\t\t= 0x0,
+};
+U_BOOT_DEVICE(phandle_target) = {
+\t.name\t\t= "target",
+\t.platdata\t= &dtv_phandle_target,
+\t.platdata_size\t= sizeof(dtv_phandle_target),
+};
+
+/* Node /phandle-source index 2 */
 static struct dtd_source dtv_phandle_source = {
 \t.cd_gpios\t\t= {
 \t\t\t{NULL, {}},
@@ -519,6 +538,7 @@ U_BOOT_DEVICE(phandle_source) = {
 \t.platdata_size\t= sizeof(dtv_phandle_source),
 };
 
+/* Node /phandle-source2 index 3 */
 static struct dtd_source dtv_phandle_source2 = {
 \t.cd_gpios\t\t= {
 \t\t\t{NULL, {}},},
@@ -581,6 +601,7 @@ struct dtd_test3 {
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(C_HEADER + '''
+/* Node /test1 index 0 */
 static struct dtd_test1 dtv_test1 = {
 \t.reg\t\t\t= {0x1234, 0x5678},
 };
@@ -590,6 +611,7 @@ U_BOOT_DEVICE(test1) = {
 \t.platdata_size\t= sizeof(dtv_test1),
 };
 
+/* Node /test2 index 1 */
 static struct dtd_test2 dtv_test2 = {
 \t.reg\t\t\t= {0x1234567890123456, 0x9876543210987654},
 };
@@ -599,6 +621,7 @@ U_BOOT_DEVICE(test2) = {
 \t.platdata_size\t= sizeof(dtv_test2),
 };
 
+/* Node /test3 index 2 */
 static struct dtd_test3 dtv_test3 = {
 \t.reg\t\t\t= {0x1234567890123456, 0x9876543210987654, 0x2, 0x3},
 };
@@ -630,6 +653,7 @@ struct dtd_test2 {
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(C_HEADER + '''
+/* Node /test1 index 0 */
 static struct dtd_test1 dtv_test1 = {
 \t.reg\t\t\t= {0x1234, 0x5678},
 };
@@ -639,6 +663,7 @@ U_BOOT_DEVICE(test1) = {
 \t.platdata_size\t= sizeof(dtv_test1),
 };
 
+/* Node /test2 index 1 */
 static struct dtd_test2 dtv_test2 = {
 \t.reg\t\t\t= {0x12345678, 0x98765432, 0x2, 0x3},
 };
@@ -673,6 +698,7 @@ struct dtd_test3 {
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(C_HEADER + '''
+/* Node /test1 index 0 */
 static struct dtd_test1 dtv_test1 = {
 \t.reg\t\t\t= {0x123400000000, 0x5678},
 };
@@ -682,6 +708,7 @@ U_BOOT_DEVICE(test1) = {
 \t.platdata_size\t= sizeof(dtv_test1),
 };
 
+/* Node /test2 index 1 */
 static struct dtd_test2 dtv_test2 = {
 \t.reg\t\t\t= {0x1234567890123456, 0x98765432},
 };
@@ -691,6 +718,7 @@ U_BOOT_DEVICE(test2) = {
 \t.platdata_size\t= sizeof(dtv_test2),
 };
 
+/* Node /test3 index 2 */
 static struct dtd_test3 dtv_test3 = {
 \t.reg\t\t\t= {0x1234567890123456, 0x98765432, 0x2, 0x3},
 };
@@ -725,6 +753,7 @@ struct dtd_test3 {
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(C_HEADER + '''
+/* Node /test1 index 0 */
 static struct dtd_test1 dtv_test1 = {
 \t.reg\t\t\t= {0x1234, 0x567800000000},
 };
@@ -734,6 +763,7 @@ U_BOOT_DEVICE(test1) = {
 \t.platdata_size\t= sizeof(dtv_test1),
 };
 
+/* Node /test2 index 1 */
 static struct dtd_test2 dtv_test2 = {
 \t.reg\t\t\t= {0x12345678, 0x9876543210987654},
 };
@@ -743,6 +773,7 @@ U_BOOT_DEVICE(test2) = {
 \t.platdata_size\t= sizeof(dtv_test2),
 };
 
+/* Node /test3 index 2 */
 static struct dtd_test3 dtv_test3 = {
 \t.reg\t\t\t= {0x12345678, 0x9876543210987654, 0x2, 0x3},
 };
@@ -792,6 +823,7 @@ struct dtd_sandbox_spl_test {
         with open(output) as infile:
             data = infile.read()
         self._CheckStrings(C_HEADER + '''
+/* Node /spl-test index 0 */
 static struct dtd_sandbox_spl_test dtv_spl_test = {
 \t.intval\t\t\t= 0x1,
 };
@@ -801,6 +833,7 @@ U_BOOT_DEVICE(spl_test) = {
 \t.platdata_size\t= sizeof(dtv_spl_test),
 };
 
+/* Node /spl-test2 index 1 */
 static struct dtd_sandbox_spl_test dtv_spl_test2 = {
 \t.intarray\t\t= 0x5,
 };
-- 
2.28.0.806.g8561365e88-goog

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

* [PATCH 04/20] dm: core: Allow dm_warn() to be used in SPL
  2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
                   ` (2 preceding siblings ...)
  2020-10-03 17:31 ` [PATCH 03/20] dtoc: Order the structures internally by name Simon Glass
@ 2020-10-03 17:31 ` Simon Glass
  2020-10-03 17:31 ` [PATCH 05/20] dtoc: Fix widening of int to bytes Simon Glass
                   ` (34 subsequent siblings)
  38 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2020-10-03 17:31 UTC (permalink / raw)
  To: u-boot

At present this option is disabled in SPL, meaning that warnings are not
displayed. It is sometimes useful to see warnings in SPL for debugging
purposes.

Add a new Kconfig option to permit this.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 drivers/core/Kconfig       | 18 ++++++++++++++++--
 drivers/core/util.c        |  2 +-
 include/config_uncmd_spl.h |  1 -
 include/dm/util.h          |  2 +-
 4 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig
index 1ca5d66141b..603a1d27c0c 100644
--- a/drivers/core/Kconfig
+++ b/drivers/core/Kconfig
@@ -40,10 +40,24 @@ config DM_WARN
 	depends on DM
 	default y
 	help
+	  Enable this to see warnings related to driver model.
+
+	  Warnings may help with debugging, such as when expected devices do
+	  not bind correctly. If the option is disabled, dm_warn() is compiled
+	  out - it will do nothing when called.
+
+config SPL_DM_WARN
+	bool "Enable warnings in driver model wuth SPL"
+	depends on SPL_DM
+	help
+	  Enable this to see warnings related to driver model in SPL
+
 	  The dm_warn() function can use up quite a bit of space for its
 	  strings. By default this is disabled for SPL builds to save space.
-	  This will cause dm_warn() to be compiled out - it will do nothing
-	  when called.
+
+	  Warnings may help with debugging, such as when expected devices do
+	  not bind correctly. If the option is disabled, dm_warn() is compiled
+	  out - it will do nothing when called.
 
 config DM_DEBUG
 	bool "Enable debug messages in driver model core"
diff --git a/drivers/core/util.c b/drivers/core/util.c
index 25b0d76f430..91e93b0cf14 100644
--- a/drivers/core/util.c
+++ b/drivers/core/util.c
@@ -11,7 +11,7 @@
 #include <linux/libfdt.h>
 #include <vsprintf.h>
 
-#ifdef CONFIG_DM_WARN
+#if CONFIG_IS_ENABLED(DM_WARN)
 void dm_warn(const char *fmt, ...)
 {
 	va_list args;
diff --git a/include/config_uncmd_spl.h b/include/config_uncmd_spl.h
index 31da6215b3a..af7e3e49fdd 100644
--- a/include/config_uncmd_spl.h
+++ b/include/config_uncmd_spl.h
@@ -16,7 +16,6 @@
 #undef CONFIG_DM_SPI
 #endif
 
-#undef CONFIG_DM_WARN
 #undef CONFIG_DM_STDIO
 
 #endif /* CONFIG_SPL_BUILD */
diff --git a/include/dm/util.h b/include/dm/util.h
index 9773db6de17..01a044992f2 100644
--- a/include/dm/util.h
+++ b/include/dm/util.h
@@ -6,7 +6,7 @@
 #ifndef __DM_UTIL_H
 #define __DM_UTIL_H
 
-#ifdef CONFIG_DM_WARN
+#if CONFIG_IS_ENABLED(DM_WARN)
 void dm_warn(const char *fmt, ...);
 #else
 static inline void dm_warn(const char *fmt, ...)
-- 
2.28.0.806.g8561365e88-goog

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

* [PATCH 05/20] dtoc: Fix widening of int to bytes
  2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
                   ` (3 preceding siblings ...)
  2020-10-03 17:31 ` [PATCH 04/20] dm: core: Allow dm_warn() to be used in SPL Simon Glass
@ 2020-10-03 17:31 ` Simon Glass
  2020-10-03 17:31 ` [PATCH 06/20] dm: Add a C test for of-platdata properties Simon Glass
                   ` (33 subsequent siblings)
  38 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2020-10-03 17:31 UTC (permalink / raw)
  To: u-boot

At present an integer is converted to bytes incorrectly. The whole 32-bit
integer is inserted as the first element of the byte array, and the other
three bytes are skipped. This was not noticed because the unit test did
not check it, and the functional test was checking for wrong values.

Update the code to handle this as a special case. Add one more test to
cover all code paths.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 test/py/tests/test_ofplatdata.py |  2 +-
 tools/dtoc/dtoc_test_simple.dts  |  1 +
 tools/dtoc/fdt.py                |  9 +++++++++
 tools/dtoc/test_dtoc.py          |  4 +++-
 tools/dtoc/test_fdt.py           | 10 ++++++++++
 5 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/test/py/tests/test_ofplatdata.py b/test/py/tests/test_ofplatdata.py
index 263334b0743..13154935b9b 100644
--- a/test/py/tests/test_ofplatdata.py
+++ b/test/py/tests/test_ofplatdata.py
@@ -20,7 +20,7 @@ byte 08
 bytearray 01 23 34
 int 3
 intarray 5 0 0 0
-longbytearray 09 00 00 00 00 00 00 00 00
+longbytearray 09 0a 0b 0c 00 00 00 00 00
 string message2
 stringarray "another" "multi-word" "message"
 of-platdata probe:
diff --git a/tools/dtoc/dtoc_test_simple.dts b/tools/dtoc/dtoc_test_simple.dts
index 11bfc4c47aa..fd168cb5931 100644
--- a/tools/dtoc/dtoc_test_simple.dts
+++ b/tools/dtoc/dtoc_test_simple.dts
@@ -41,6 +41,7 @@
 		u-boot,dm-pre-reloc;
 		compatible = "sandbox,spl-test";
 		stringarray = "one";
+		longbytearray = [09 0a 0b 0c 0d 0e 0f 10];
 	};
 
 	spl-test4 {
diff --git a/tools/dtoc/fdt.py b/tools/dtoc/fdt.py
index d058c59e927..03b86773d5f 100644
--- a/tools/dtoc/fdt.py
+++ b/tools/dtoc/fdt.py
@@ -129,6 +129,15 @@ class Prop:
         specific.
         """
         if newprop.type < self.type:
+            # Special handling to convert an int into bytes
+            if self.type == TYPE_INT and newprop.type == TYPE_BYTE:
+                if type(self.value) == list:
+                    new_value = []
+                    for val in self.value:
+                        new_value += [tools.ToChar(by) for by in val]
+                else:
+                    new_value = [tools.ToChar(by) for by in self.value]
+                self.value = new_value
             self.type = newprop.type
 
         if type(newprop.value) == list and type(self.value) != list:
diff --git a/tools/dtoc/test_dtoc.py b/tools/dtoc/test_dtoc.py
index 857a98e435f..8dcac91ee70 100755
--- a/tools/dtoc/test_dtoc.py
+++ b/tools/dtoc/test_dtoc.py
@@ -255,7 +255,7 @@ static struct dtd_sandbox_spl_test dtv_spl_test2 = {
 \t.byteval\t\t= 0x8,
 \t.intarray\t\t= {0x5, 0x0, 0x0, 0x0},
 \t.intval\t\t\t= 0x3,
-\t.longbytearray\t\t= {0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+\t.longbytearray\t\t= {0x9, 0xa, 0xb, 0xc, 0x0, 0x0, 0x0, 0x0,
 \t\t0x0},
 \t.stringarray\t\t= {"another", "multi-word", "message"},
 \t.stringval\t\t= "message2",
@@ -268,6 +268,8 @@ U_BOOT_DEVICE(spl_test2) = {
 
 /* Node /spl-test3 index 4 */
 static struct dtd_sandbox_spl_test dtv_spl_test3 = {
+\t.longbytearray\t\t= {0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10,
+\t\t0x0},
 \t.stringarray\t\t= {"one", "", ""},
 };
 U_BOOT_DEVICE(spl_test3) = {
diff --git a/tools/dtoc/test_fdt.py b/tools/dtoc/test_fdt.py
index b4f9b7f498f..cfe3e04c7ad 100755
--- a/tools/dtoc/test_fdt.py
+++ b/tools/dtoc/test_fdt.py
@@ -298,6 +298,7 @@ class TestProp(unittest.TestCase):
     def testWiden(self):
         """Test widening of values"""
         node2 = self.dtb.GetNode('/spl-test2')
+        node3 = self.dtb.GetNode('/spl-test3')
         prop = self.node.props['intval']
 
         # No action
@@ -316,11 +317,20 @@ class TestProp(unittest.TestCase):
         # byte array, it should turn into an array.
         prop = self.node.props['longbytearray']
         prop2 = node2.props['longbytearray']
+        prop3 = node3.props['longbytearray']
         self.assertFalse(isinstance(prop2.value, list))
         self.assertEqual(4, len(prop2.value))
+        self.assertEqual(b'\x09\x0a\x0b\x0c', prop2.value)
         prop2.Widen(prop)
         self.assertTrue(isinstance(prop2.value, list))
         self.assertEqual(9, len(prop2.value))
+        self.assertEqual(['\x09', '\x0a', '\x0b', '\x0c', '\0',
+                          '\0', '\0', '\0', '\0'], prop2.value)
+        prop3.Widen(prop)
+        self.assertTrue(isinstance(prop3.value, list))
+        self.assertEqual(9, len(prop3.value))
+        self.assertEqual(['\x09', '\x0a', '\x0b', '\x0c', '\x0d',
+                          '\x0e', '\x0f', '\x10', '\0'], prop3.value)
 
         # Similarly for a string array
         prop = self.node.props['stringval']
-- 
2.28.0.806.g8561365e88-goog

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

* [PATCH 06/20] dm: Add a C test for of-platdata properties
  2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
                   ` (4 preceding siblings ...)
  2020-10-03 17:31 ` [PATCH 05/20] dtoc: Fix widening of int to bytes Simon Glass
@ 2020-10-03 17:31 ` Simon Glass
  2020-10-03 17:31 ` [PATCH 07/20] sandbox: Allow selection of SPL unit tests Simon Glass
                   ` (32 subsequent siblings)
  38 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2020-10-03 17:31 UTC (permalink / raw)
  To: u-boot

At present properties are tested in a roundabout way. The driver's probe()
method writes out the values of the properties and the Python test checks
the output from U-Boot SPL.

Add a C test which checks these values more directly.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 test/dm/of_platdata.c | 69 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 69 insertions(+)

diff --git a/test/dm/of_platdata.c b/test/dm/of_platdata.c
index 7a864eb0fb3..8763005ea9a 100644
--- a/test/dm/of_platdata.c
+++ b/test/dm/of_platdata.c
@@ -2,6 +2,7 @@
 
 #include <common.h>
 #include <dm.h>
+#include <dt-structs.h>
 #include <dm/test.h>
 #include <test/test.h>
 #include <test/ut.h>
@@ -17,3 +18,71 @@ static int dm_test_of_platdata_base(struct unit_test_state *uts)
 	return 0;
 }
 DM_TEST(dm_test_of_platdata_base, UT_TESTF_SCAN_PDATA);
+
+/* Test that we can read properties from a device */
+static int dm_test_of_platdata_props(struct unit_test_state *uts)
+{
+	struct dtd_sandbox_spl_test *plat;
+	struct udevice *dev;
+	int i;
+
+	ut_assertok(uclass_first_device_err(UCLASS_MISC, &dev));
+	plat = dev_get_platdata(dev);
+	ut_assert(plat->boolval);
+	ut_asserteq(1, plat->intval);
+	ut_asserteq(4, ARRAY_SIZE(plat->intarray));
+	ut_asserteq(2, plat->intarray[0]);
+	ut_asserteq(3, plat->intarray[1]);
+	ut_asserteq(4, plat->intarray[2]);
+	ut_asserteq(0, plat->intarray[3]);
+	ut_asserteq(5, plat->byteval);
+	ut_asserteq(3, ARRAY_SIZE(plat->bytearray));
+	ut_asserteq(6, plat->bytearray[0]);
+	ut_asserteq(0, plat->bytearray[1]);
+	ut_asserteq(0, plat->bytearray[2]);
+	ut_asserteq(9, ARRAY_SIZE(plat->longbytearray));
+	for (i = 0; i < ARRAY_SIZE(plat->longbytearray); i++)
+		ut_asserteq(9 + i, plat->longbytearray[i]);
+	ut_asserteq_str("message", plat->stringval);
+	ut_asserteq(3, ARRAY_SIZE(plat->stringarray));
+	ut_asserteq_str("multi-word", plat->stringarray[0]);
+	ut_asserteq_str("message", plat->stringarray[1]);
+	ut_asserteq_str("", plat->stringarray[2]);
+
+	ut_assertok(uclass_next_device_err(&dev));
+	plat = dev_get_platdata(dev);
+	ut_assert(!plat->boolval);
+	ut_asserteq(3, plat->intval);
+	ut_asserteq(5, plat->intarray[0]);
+	ut_asserteq(0, plat->intarray[1]);
+	ut_asserteq(0, plat->intarray[2]);
+	ut_asserteq(0, plat->intarray[3]);
+	ut_asserteq(8, plat->byteval);
+	ut_asserteq(3, ARRAY_SIZE(plat->bytearray));
+	ut_asserteq(1, plat->bytearray[0]);
+	ut_asserteq(0x23, plat->bytearray[1]);
+	ut_asserteq(0x34, plat->bytearray[2]);
+	for (i = 0; i < ARRAY_SIZE(plat->longbytearray); i++)
+		ut_asserteq(i < 4 ? 9 + i : 0, plat->longbytearray[i]);
+	ut_asserteq_str("message2", plat->stringval);
+	ut_asserteq_str("another", plat->stringarray[0]);
+	ut_asserteq_str("multi-word", plat->stringarray[1]);
+	ut_asserteq_str("message", plat->stringarray[2]);
+
+	ut_assertok(uclass_next_device_err(&dev));
+	plat = dev_get_platdata(dev);
+	ut_assert(!plat->boolval);
+	ut_asserteq_str("one", plat->stringarray[0]);
+	ut_asserteq_str("", plat->stringarray[1]);
+	ut_asserteq_str("", plat->stringarray[2]);
+
+	ut_assertok(uclass_next_device_err(&dev));
+	plat = dev_get_platdata(dev);
+	ut_assert(!plat->boolval);
+	ut_asserteq_str("spl", plat->stringarray[0]);
+
+	ut_asserteq(-ENODEV, uclass_next_device_err(&dev));
+
+	return 0;
+}
+DM_TEST(dm_test_of_platdata_props, UT_TESTF_SCAN_PDATA);
-- 
2.28.0.806.g8561365e88-goog

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

* [PATCH 07/20] sandbox: Allow selection of SPL unit tests
  2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
                   ` (5 preceding siblings ...)
  2020-10-03 17:31 ` [PATCH 06/20] dm: Add a C test for of-platdata properties Simon Glass
@ 2020-10-03 17:31 ` Simon Glass
  2020-10-03 17:31 ` [PATCH 08/20] dm: test: Drop of-platdata pytest Simon Glass
                   ` (31 subsequent siblings)
  38 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2020-10-03 17:31 UTC (permalink / raw)
  To: u-boot

Now that we have more than one test, add a way to select the test to run.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 arch/sandbox/cpu/spl.c           | 2 +-
 arch/sandbox/cpu/start.c         | 9 +++++++++
 arch/sandbox/include/asm/state.h | 1 +
 3 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/sandbox/cpu/spl.c b/arch/sandbox/cpu/spl.c
index 48fd1265afe..81b217a1d70 100644
--- a/arch/sandbox/cpu/spl.c
+++ b/arch/sandbox/cpu/spl.c
@@ -72,7 +72,7 @@ void spl_board_init(void)
 	if (state->run_unittests) {
 		int ret;
 
-		ret = dm_test_main(NULL);
+		ret = dm_test_main(state->select_unittests);
 		/* continue execution into U-Boot */
 	}
 }
diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c
index f5e104b127b..569dafbcfee 100644
--- a/arch/sandbox/cpu/start.c
+++ b/arch/sandbox/cpu/start.c
@@ -383,6 +383,15 @@ static int sandbox_cmdline_cb_unittests(struct sandbox_state *state,
 }
 SANDBOX_CMDLINE_OPT_SHORT(unittests, 'u', 0, "Run unit tests");
 
+static int sandbox_cmdline_cb_select_unittests(struct sandbox_state *state,
+					       const char *arg)
+{
+	state->select_unittests = arg;
+
+	return 0;
+}
+SANDBOX_CMDLINE_OPT_SHORT(select_unittests, 'k', 1, "Select unit tests to run");
+
 static void setup_ram_buf(struct sandbox_state *state)
 {
 	/* Zero the RAM buffer if we didn't read it, to keep valgrind happy */
diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h
index f828d9d2447..7547602dd1c 100644
--- a/arch/sandbox/include/asm/state.h
+++ b/arch/sandbox/include/asm/state.h
@@ -93,6 +93,7 @@ struct sandbox_state {
 	bool show_of_platdata;		/* Show of-platdata in SPL */
 	bool ram_buf_read;		/* true if we read the RAM buffer */
 	bool run_unittests;		/* Run unit tests */
+	const char *select_unittests;	/* Unit test to run */
 
 	/* Pointer to information for each SPI bus/cs */
 	struct sandbox_spi_info spi[CONFIG_SANDBOX_SPI_MAX_BUS]
-- 
2.28.0.806.g8561365e88-goog

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

* [PATCH 08/20] dm: test: Drop of-platdata pytest
  2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
                   ` (6 preceding siblings ...)
  2020-10-03 17:31 ` [PATCH 07/20] sandbox: Allow selection of SPL unit tests Simon Glass
@ 2020-10-03 17:31 ` Simon Glass
  2020-10-03 17:31 ` [PATCH 09/20] dm: test: Add a check that all devices have a dev value Simon Glass
                   ` (30 subsequent siblings)
  38 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2020-10-03 17:31 UTC (permalink / raw)
  To: u-boot

Now that we have a C version of this test, drop the Python implementation.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 arch/sandbox/cpu/spl.c           | 12 --------
 arch/sandbox/cpu/start.c         |  9 ------
 arch/sandbox/include/asm/state.h |  1 -
 drivers/misc/spltest_sandbox.c   | 35 ------------------------
 test/py/tests/test_ofplatdata.py | 47 --------------------------------
 5 files changed, 104 deletions(-)

diff --git a/arch/sandbox/cpu/spl.c b/arch/sandbox/cpu/spl.c
index 81b217a1d70..9a77da15619 100644
--- a/arch/sandbox/cpu/spl.c
+++ b/arch/sandbox/cpu/spl.c
@@ -54,20 +54,8 @@ SPL_LOAD_IMAGE_METHOD("sandbox", 9, BOOT_DEVICE_BOARD, spl_board_load_image);
 void spl_board_init(void)
 {
 	struct sandbox_state *state = state_get_current();
-	struct udevice *dev;
 
 	preloader_console_init();
-	if (state->show_of_platdata) {
-		/*
-		 * Scan all the devices so that we can output their platform
-		 * data. See sandbox_spl_probe().
-		 */
-		printf("Scanning misc devices\n");
-		for (uclass_first_device(UCLASS_MISC, &dev);
-		     dev;
-		     uclass_next_device(&dev))
-			;
-	}
 
 	if (state->run_unittests) {
 		int ret;
diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c
index 569dafbcfee..58ada13fba5 100644
--- a/arch/sandbox/cpu/start.c
+++ b/arch/sandbox/cpu/start.c
@@ -365,15 +365,6 @@ static int sandbox_cmdline_cb_log_level(struct sandbox_state *state,
 SANDBOX_CMDLINE_OPT_SHORT(log_level, 'L', 1,
 			  "Set log level (0=panic, 7=debug)");
 
-static int sandbox_cmdline_cb_show_of_platdata(struct sandbox_state *state,
-					       const char *arg)
-{
-	state->show_of_platdata = true;
-
-	return 0;
-}
-SANDBOX_CMDLINE_OPT(show_of_platdata, 0, "Show of-platdata in SPL");
-
 static int sandbox_cmdline_cb_unittests(struct sandbox_state *state,
 					const char *arg)
 {
diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h
index 7547602dd1c..bca13069824 100644
--- a/arch/sandbox/include/asm/state.h
+++ b/arch/sandbox/include/asm/state.h
@@ -90,7 +90,6 @@ struct sandbox_state {
 	bool skip_delays;		/* Ignore any time delays (for test) */
 	bool show_test_output;		/* Don't suppress stdout in tests */
 	int default_log_level;		/* Default log level for sandbox */
-	bool show_of_platdata;		/* Show of-platdata in SPL */
 	bool ram_buf_read;		/* true if we read the RAM buffer */
 	bool run_unittests;		/* Run unit tests */
 	const char *select_unittests;	/* Unit test to run */
diff --git a/drivers/misc/spltest_sandbox.c b/drivers/misc/spltest_sandbox.c
index 999031625b5..3ae6707593e 100644
--- a/drivers/misc/spltest_sandbox.c
+++ b/drivers/misc/spltest_sandbox.c
@@ -8,43 +8,8 @@
 #include <dm.h>
 #include <dt-structs.h>
 
-static int sandbox_spl_probe(struct udevice *dev)
-{
-	struct dtd_sandbox_spl_test *plat = dev_get_platdata(dev);
-	int i;
-
-	printf("of-platdata probe:\n");
-	printf("bool %d\n", plat->boolval);
-
-	printf("byte %02x\n", plat->byteval);
-	printf("bytearray");
-	for (i = 0; i < sizeof(plat->bytearray); i++)
-		printf(" %02x", plat->bytearray[i]);
-	printf("\n");
-
-	printf("int %d\n", plat->intval);
-	printf("intarray");
-	for (i = 0; i < ARRAY_SIZE(plat->intarray); i++)
-		printf(" %d", plat->intarray[i]);
-	printf("\n");
-
-	printf("longbytearray");
-	for (i = 0; i < sizeof(plat->longbytearray); i++)
-		printf(" %02x", plat->longbytearray[i]);
-	printf("\n");
-
-	printf("string %s\n", plat->stringval);
-	printf("stringarray");
-	for (i = 0; i < ARRAY_SIZE(plat->stringarray); i++)
-		printf(" \"%s\"", plat->stringarray[i]);
-	printf("\n");
-
-	return 0;
-}
-
 U_BOOT_DRIVER(sandbox_spl_test) = {
 	.name	= "sandbox_spl_test",
 	.id	= UCLASS_MISC,
 	.flags	= DM_FLAG_PRE_RELOC,
-	.probe	= sandbox_spl_probe,
 };
diff --git a/test/py/tests/test_ofplatdata.py b/test/py/tests/test_ofplatdata.py
index 13154935b9b..78837a3c008 100644
--- a/test/py/tests/test_ofplatdata.py
+++ b/test/py/tests/test_ofplatdata.py
@@ -4,53 +4,6 @@
 import pytest
 import u_boot_utils as util
 
-OF_PLATDATA_OUTPUT = '''
-of-platdata probe:
-bool 1
-byte 05
-bytearray 06 00 00
-int 1
-intarray 2 3 4 0
-longbytearray 09 0a 0b 0c 0d 0e 0f 10 11
-string message
-stringarray "multi-word" "message" ""
-of-platdata probe:
-bool 0
-byte 08
-bytearray 01 23 34
-int 3
-intarray 5 0 0 0
-longbytearray 09 0a 0b 0c 00 00 00 00 00
-string message2
-stringarray "another" "multi-word" "message"
-of-platdata probe:
-bool 0
-byte 00
-bytearray 00 00 00
-int 0
-intarray 0 0 0 0
-longbytearray 00 00 00 00 00 00 00 00 00
-string <NULL>
-stringarray "one" "" ""
-of-platdata probe:
-bool 0
-byte 00
-bytearray 00 00 00
-int 0
-intarray 0 0 0 0
-longbytearray 00 00 00 00 00 00 00 00 00
-string <NULL>
-stringarray "spl" "" ""
-'''
-
- at pytest.mark.buildconfigspec('spl_of_platdata')
-def test_ofplatdata(u_boot_console):
-    """Test that of-platdata can be generated and used in sandbox"""
-    cons = u_boot_console
-    cons.restart_uboot_with_flags(['--show_of_platdata'])
-    output = cons.get_spawn_output().replace('\r', '')
-    assert OF_PLATDATA_OUTPUT in output
-
 @pytest.mark.buildconfigspec('spl_of_platdata')
 def test_spl_devicetree(u_boot_console):
     """Test content of spl device-tree"""
-- 
2.28.0.806.g8561365e88-goog

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

* [PATCH 09/20] dm: test: Add a check that all devices have a dev value
  2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
                   ` (7 preceding siblings ...)
  2020-10-03 17:31 ` [PATCH 08/20] dm: test: Drop of-platdata pytest Simon Glass
@ 2020-10-03 17:31 ` Simon Glass
  2020-10-03 17:31 ` [PATCH 10/20] dm: test: Add a test for of-platdata phandles Simon Glass
                   ` (29 subsequent siblings)
  38 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2020-10-03 17:31 UTC (permalink / raw)
  To: u-boot

With of-platdata, the driver_info struct is updated with the device
pointer when it is bound. This makes it easy for a device to be found by
its driver info with the device_get_by_driver_info() function.

Add a test that all devices (except the root device) have such an entry.
Fix a bug that the function does not set *devp to NULL on failure, which
the documentation asserts.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 drivers/core/device.c |  1 +
 test/dm/of_platdata.c | 81 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 82 insertions(+)

diff --git a/drivers/core/device.c b/drivers/core/device.c
index 355dbd147a9..aacc6adf02d 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -745,6 +745,7 @@ int device_get_by_driver_info(const struct driver_info *info,
 	struct udevice *dev;
 
 	dev = info->dev;
+	*devp = NULL;
 
 	return device_get_device_tail(dev, dev ? 0 : -ENOENT, devp);
 }
diff --git a/test/dm/of_platdata.c b/test/dm/of_platdata.c
index 8763005ea9a..80900e416ba 100644
--- a/test/dm/of_platdata.c
+++ b/test/dm/of_platdata.c
@@ -86,3 +86,84 @@ static int dm_test_of_platdata_props(struct unit_test_state *uts)
 	return 0;
 }
 DM_TEST(dm_test_of_platdata_props, UT_TESTF_SCAN_PDATA);
+
+/*
+ * find_driver_info - recursively find the driver_info for a device
+ *
+ * This sets found[idx] to true when it finds the driver_info record for a
+ * device, where idx is the index in the driver_info linker list.
+ *
+ * @uts: Test state
+ * @parent: Parent to search
+ * @found: bool array to update
+ * @return 0 if OK, non-zero on error
+ */
+static int find_driver_info(struct unit_test_state *uts, struct udevice *parent,
+			    bool found[])
+{
+	struct udevice *dev;
+
+	/* If not the root device, find the entry that caused it to be bound */
+	if (parent->parent) {
+		const struct driver_info *info =
+			ll_entry_start(struct driver_info, driver_info);
+		const int n_ents =
+			ll_entry_count(struct driver_info, driver_info);
+		const struct driver_info *entry;
+		int idx = -1;
+
+		for (entry = info; entry != info + n_ents; entry++) {
+			if (entry->dev == parent) {
+				idx = entry - info;
+				found[idx] = true;
+				break;
+			}
+		}
+
+		ut_assert(idx != -1);
+	}
+
+	device_foreach_child(dev, parent) {
+		int ret;
+
+		ret = find_driver_info(uts, dev, found);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+/* Check that every device is recorded in its driver_info struct */
+static int dm_test_of_platdata_dev(struct unit_test_state *uts)
+{
+	const struct driver_info *info =
+		ll_entry_start(struct driver_info, driver_info);
+	const int n_ents = ll_entry_count(struct driver_info, driver_info);
+	bool found[n_ents];
+	uint i;
+
+	/* Record the indexes that are found */
+	memset(found, '\0', sizeof(found));
+	ut_assertok(find_driver_info(uts, gd->dm_root, found));
+
+	/* Make sure that the driver entries without devices have no ->dev */
+	for (i = 0; i < n_ents; i++) {
+		const struct driver_info *entry = info + i;
+		struct udevice *dev;
+
+		if (found[i]) {
+			/* Make sure we can find it */
+			ut_assertnonnull(entry->dev);
+			ut_assertok(device_get_by_driver_info(entry, &dev));
+			ut_asserteq_ptr(dev, entry->dev);
+		} else {
+			ut_assertnull(entry->dev);
+			ut_asserteq(-ENOENT,
+				    device_get_by_driver_info(entry, &dev));
+		}
+	}
+
+	return 0;
+}
+DM_TEST(dm_test_of_platdata_dev, UT_TESTF_SCAN_PDATA);
-- 
2.28.0.806.g8561365e88-goog

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

* [PATCH 10/20] dm: test: Add a test for of-platdata phandles
  2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
                   ` (8 preceding siblings ...)
  2020-10-03 17:31 ` [PATCH 09/20] dm: test: Add a check that all devices have a dev value Simon Glass
@ 2020-10-03 17:31 ` Simon Glass
  2020-10-03 17:31 ` [PATCH 11/20] dm: Use an allocated array for run-time device info Simon Glass
                   ` (28 subsequent siblings)
  38 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2020-10-03 17:31 UTC (permalink / raw)
  To: u-boot

We have a test in dtoc for this feature, but not one in U-Boot itself.
Add a simple test that checks that the information comes through
correctly.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 arch/sandbox/dts/sandbox.dtsi | 26 ++++++++++++++++++++++++
 configs/sandbox_spl_defconfig |  1 +
 drivers/clk/clk_fixed_rate.c  |  4 ++--
 drivers/clk/clk_sandbox.c     |  4 ++--
 test/dm/of_platdata.c         | 37 +++++++++++++++++++++++++++++++++++
 5 files changed, 68 insertions(+), 4 deletions(-)

diff --git a/arch/sandbox/dts/sandbox.dtsi b/arch/sandbox/dts/sandbox.dtsi
index c76ecc013c9..ca7049fc974 100644
--- a/arch/sandbox/dts/sandbox.dtsi
+++ b/arch/sandbox/dts/sandbox.dtsi
@@ -29,6 +29,32 @@
 		};
 	};
 
+	clk_fixed: clk-fixed {
+		u-boot,dm-pre-reloc;
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <1234>;
+	};
+
+	clk_sandbox: clk-sbox {
+		u-boot,dm-pre-reloc;
+		compatible = "sandbox,clk";
+		#clock-cells = <1>;
+		assigned-clocks = <&clk_sandbox 3>;
+		assigned-clock-rates = <321>;
+	};
+
+	clk-test {
+		u-boot,dm-pre-reloc;
+		compatible = "sandbox,clk-test";
+		clocks = <&clk_fixed>,
+			 <&clk_sandbox 1>,
+			 <&clk_sandbox 0>,
+			 <&clk_sandbox 3>,
+			 <&clk_sandbox 2>;
+		clock-names = "fixed", "i2c", "spi", "uart2", "uart1";
+	};
+
 	gpio_a: gpios at 0 {
 		u-boot,dm-pre-reloc;
 		gpio-controller;
diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig
index 49060cab7a3..91215d23a0f 100644
--- a/configs/sandbox_spl_defconfig
+++ b/configs/sandbox_spl_defconfig
@@ -104,6 +104,7 @@ CONFIG_ADC_SANDBOX=y
 CONFIG_AXI=y
 CONFIG_AXI_SANDBOX=y
 CONFIG_CLK=y
+CONFIG_SPL_CLK=y
 CONFIG_CPU=y
 CONFIG_DM_DEMO=y
 CONFIG_DM_DEMO_SIMPLE=y
diff --git a/drivers/clk/clk_fixed_rate.c b/drivers/clk/clk_fixed_rate.c
index 55e1f8caa52..f86b4a0e924 100644
--- a/drivers/clk/clk_fixed_rate.c
+++ b/drivers/clk/clk_fixed_rate.c
@@ -46,8 +46,8 @@ static const struct udevice_id clk_fixed_rate_match[] = {
 	{ /* sentinel */ }
 };
 
-U_BOOT_DRIVER(clk_fixed_rate) = {
-	.name = "fixed_rate_clock",
+U_BOOT_DRIVER(fixed_clock) = {
+	.name = "fixed_clock",
 	.id = UCLASS_CLK,
 	.of_match = clk_fixed_rate_match,
 	.ofdata_to_platdata = clk_fixed_rate_ofdata_to_platdata,
diff --git a/drivers/clk/clk_sandbox.c b/drivers/clk/clk_sandbox.c
index 768fbb7c520..0ff1b496338 100644
--- a/drivers/clk/clk_sandbox.c
+++ b/drivers/clk/clk_sandbox.c
@@ -124,8 +124,8 @@ static const struct udevice_id sandbox_clk_ids[] = {
 	{ }
 };
 
-U_BOOT_DRIVER(clk_sandbox) = {
-	.name		= "clk_sandbox",
+U_BOOT_DRIVER(sandbox_clk) = {
+	.name		= "sandbox_clk",
 	.id		= UCLASS_CLK,
 	.of_match	= sandbox_clk_ids,
 	.ops		= &sandbox_clk_ops,
diff --git a/test/dm/of_platdata.c b/test/dm/of_platdata.c
index 80900e416ba..57f903611a6 100644
--- a/test/dm/of_platdata.c
+++ b/test/dm/of_platdata.c
@@ -26,7 +26,11 @@ static int dm_test_of_platdata_props(struct unit_test_state *uts)
 	struct udevice *dev;
 	int i;
 
+	/* Skip the clock */
 	ut_assertok(uclass_first_device_err(UCLASS_MISC, &dev));
+	ut_asserteq_str("sandbox_clk_test", dev->name);
+
+	ut_assertok(uclass_next_device_err(&dev));
 	plat = dev_get_platdata(dev);
 	ut_assert(plat->boolval);
 	ut_asserteq(1, plat->intval);
@@ -167,3 +171,36 @@ static int dm_test_of_platdata_dev(struct unit_test_state *uts)
 	return 0;
 }
 DM_TEST(dm_test_of_platdata_dev, UT_TESTF_SCAN_PDATA);
+
+/* Test handling of phandles that point to other devices */
+static int dm_test_of_platdata_phandle(struct unit_test_state *uts)
+{
+	struct dtd_sandbox_clk_test *plat;
+	struct udevice *dev, *clk;
+
+	ut_assertok(uclass_first_device_err(UCLASS_MISC, &dev));
+	ut_asserteq_str("sandbox_clk_test", dev->name);
+	plat = dev_get_platdata(dev);
+
+	ut_assertok(device_get_by_driver_info(plat->clocks[0].node, &clk));
+	ut_asserteq_str("fixed_clock", clk->name);
+
+	ut_assertok(device_get_by_driver_info(plat->clocks[1].node, &clk));
+	ut_asserteq_str("sandbox_clk", clk->name);
+	ut_asserteq(1, plat->clocks[1].arg[0]);
+
+	ut_assertok(device_get_by_driver_info(plat->clocks[2].node, &clk));
+	ut_asserteq_str("sandbox_clk", clk->name);
+	ut_asserteq(0, plat->clocks[2].arg[0]);
+
+	ut_assertok(device_get_by_driver_info(plat->clocks[3].node, &clk));
+	ut_asserteq_str("sandbox_clk", clk->name);
+	ut_asserteq(3, plat->clocks[3].arg[0]);
+
+	ut_assertok(device_get_by_driver_info(plat->clocks[4].node, &clk));
+	ut_asserteq_str("sandbox_clk", clk->name);
+	ut_asserteq(2, plat->clocks[4].arg[0]);
+
+	return 0;
+}
+DM_TEST(dm_test_of_platdata_phandle, UT_TESTF_SCAN_PDATA);
-- 
2.28.0.806.g8561365e88-goog

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

* [PATCH 11/20] dm: Use an allocated array for run-time device info
  2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
                   ` (9 preceding siblings ...)
  2020-10-03 17:31 ` [PATCH 10/20] dm: test: Add a test for of-platdata phandles Simon Glass
@ 2020-10-03 17:31 ` Simon Glass
  2020-10-03 17:31 ` [PATCH 12/20] sandbox: Fix up building for of-platdata Simon Glass
                   ` (27 subsequent siblings)
  38 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2020-10-03 17:31 UTC (permalink / raw)
  To: u-boot

At present we update the driver_info struct with a pointer to the device
that it created (i.e. caused to be bound). This works fine when U-Boot SPL
is stored in read-write memory. But on some platforms, such as Intel
Apollo Lake, it is not possible to update the data memory.

In any case, it is bad form to put this information in a structure that is
in the data region, since it expands the size of the binary.

Create a new driver_rt structure which holds runtime information about
drivers. Update the code to store the device pointer in this instead.
Also update the test check that this works.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 drivers/core/device.c             | 11 ++++++-----
 drivers/core/lists.c              | 16 +++++++++++-----
 drivers/core/root.c               | 11 +++++++++++
 include/asm-generic/global_data.h | 13 +++++++++++++
 include/dm/device-internal.h      |  2 +-
 include/dm/platdata.h             | 14 ++++++++++++--
 test/dm/of_platdata.c             | 19 ++++++++++---------
 7 files changed, 64 insertions(+), 22 deletions(-)

diff --git a/drivers/core/device.c b/drivers/core/device.c
index aacc6adf02d..c3338efc4fa 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -249,7 +249,7 @@ int device_bind_ofnode(struct udevice *parent, const struct driver *drv,
 }
 
 int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
-			struct driver_info *info, struct udevice **devp)
+			const struct driver_info *info, struct udevice **devp)
 {
 	struct driver *drv;
 	uint platdata_size = 0;
@@ -269,9 +269,6 @@ int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
 				 platdata_size, devp);
 	if (ret)
 		return ret;
-#if CONFIG_IS_ENABLED(OF_PLATDATA)
-	info->dev = *devp;
-#endif
 
 	return ret;
 }
@@ -742,9 +739,13 @@ int device_get_global_by_ofnode(ofnode ofnode, struct udevice **devp)
 int device_get_by_driver_info(const struct driver_info *info,
 			      struct udevice **devp)
 {
+	struct driver_info *info_base =
+		ll_entry_start(struct driver_info, driver_info);
+	int idx = info - info_base;
+	struct driver_rt *drt = gd_dm_driver_rt() + idx;
 	struct udevice *dev;
 
-	dev = info->dev;
+	dev = drt->dev;
 	*devp = NULL;
 
 	return device_get_device_tail(dev, dev ? 0 : -ENOENT, devp);
diff --git a/drivers/core/lists.c b/drivers/core/lists.c
index 5beba9181cc..2e6bd5006ce 100644
--- a/drivers/core/lists.c
+++ b/drivers/core/lists.c
@@ -56,14 +56,20 @@ int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only)
 	struct driver_info *info =
 		ll_entry_start(struct driver_info, driver_info);
 	const int n_ents = ll_entry_count(struct driver_info, driver_info);
-	struct driver_info *entry;
-	struct udevice *dev;
 	int result = 0;
-	int ret;
+	uint idx;
+
+	for (idx = 0; idx < n_ents; idx++) {
+		const struct driver_info *entry = info + idx;
+		struct driver_rt *drt = gd_dm_driver_rt() + idx;
+		struct udevice *dev;
+		int ret;
 
-	for (entry = info; entry != info + n_ents; entry++) {
 		ret = device_bind_by_name(parent, pre_reloc_only, entry, &dev);
-		if (ret && ret != -EPERM) {
+		if (!ret) {
+			if (CONFIG_IS_ENABLED(OF_PLATDATA))
+				drt->dev = dev;
+		} else if (ret != -EPERM) {
 			dm_warn("No match for driver '%s'\n", entry->name);
 			if (!result || ret != -ENOENT)
 				result = ret;
diff --git a/drivers/core/root.c b/drivers/core/root.c
index de23161cff8..e8df5aebe84 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -185,6 +185,17 @@ int dm_scan_platdata(bool pre_reloc_only)
 {
 	int ret;
 
+	if (CONFIG_IS_ENABLED(OF_PLATDATA)) {
+		struct driver_rt *dyn;
+		int n_ents;
+
+		n_ents = ll_entry_count(struct driver_info, driver_info);
+		dyn = calloc(n_ents, sizeof(struct driver_rt));
+		if (!dyn)
+			return -ENOMEM;
+		gd_set_dm_driver_rt(dyn);
+	}
+
 	ret = lists_bind_drivers(DM_ROOT_NON_CONST, pre_reloc_only);
 	if (ret == -ENOENT) {
 		dm_warn("Some drivers were not found\n");
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index d6f562d90d4..7fc53e8deee 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -24,6 +24,8 @@
 #include <membuff.h>
 #include <linux/list.h>
 
+struct driver_rt;
+
 typedef struct global_data {
 	struct bd_info *bd;
 	unsigned long flags;
@@ -67,6 +69,9 @@ typedef struct global_data {
 	struct udevice	*dm_root;	/* Root instance for Driver Model */
 	struct udevice	*dm_root_f;	/* Pre-relocation root instance */
 	struct list_head uclass_root;	/* Head of core tree */
+# if CONFIG_IS_ENABLED(OF_PLATDATA)
+	struct driver_rt *dm_driver_rt;	/* Dynamic info about the driver */
+# endif
 #endif
 #ifdef CONFIG_TIMER
 	struct udevice	*timer;		/* Timer instance for Driver Model */
@@ -157,6 +162,14 @@ typedef struct global_data {
 #define gd_set_of_root(_root)
 #endif
 
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+#define gd_set_dm_driver_rt(dyn)	gd->dm_driver_rt = dyn
+#define gd_dm_driver_rt()		gd->dm_driver_rt
+#else
+#define gd_set_dm_driver_rt(dyn)
+#define gd_dm_driver_rt()		NULL
+#endif
+
 /*
  * Global Data Flags
  */
diff --git a/include/dm/device-internal.h b/include/dm/device-internal.h
index 5145fb4e145..294d6c18105 100644
--- a/include/dm/device-internal.h
+++ b/include/dm/device-internal.h
@@ -81,7 +81,7 @@ int device_bind_with_driver_data(struct udevice *parent,
  * @return 0 if OK, -ve on error
  */
 int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
-			struct driver_info *info, struct udevice **devp);
+			const struct driver_info *info, struct udevice **devp);
 
 /**
  * device_ofdata_to_platdata() - Read platform data for a device
diff --git a/include/dm/platdata.h b/include/dm/platdata.h
index 25479b03d22..2c3cc90c291 100644
--- a/include/dm/platdata.h
+++ b/include/dm/platdata.h
@@ -22,17 +22,27 @@
  * @name:	Driver name
  * @platdata:	Driver-specific platform data
  * @platdata_size: Size of platform data structure
- * @dev:	Device created from this structure data
  */
 struct driver_info {
 	const char *name;
 	const void *platdata;
 #if CONFIG_IS_ENABLED(OF_PLATDATA)
 	uint platdata_size;
-	struct udevice *dev;
 #endif
 };
 
+/**
+ * driver_rt - runtime information set up by U-Boot
+ *
+ * There is one of these for every driver_info in the linker list, indexed by
+ * the driver_info idx value.
+ *
+ * @dev: Device created from this idx
+ */
+struct driver_rt {
+	struct udevice *dev;
+};
+
 /**
  * NOTE: Avoid using these except in extreme circumstances, where device tree
  * is not feasible (e.g. serial driver in SPL where <8KB of SRAM is
diff --git a/test/dm/of_platdata.c b/test/dm/of_platdata.c
index 57f903611a6..e827d45ffb7 100644
--- a/test/dm/of_platdata.c
+++ b/test/dm/of_platdata.c
@@ -109,16 +109,16 @@ static int find_driver_info(struct unit_test_state *uts, struct udevice *parent,
 
 	/* If not the root device, find the entry that caused it to be bound */
 	if (parent->parent) {
-		const struct driver_info *info =
-			ll_entry_start(struct driver_info, driver_info);
 		const int n_ents =
 			ll_entry_count(struct driver_info, driver_info);
-		const struct driver_info *entry;
 		int idx = -1;
+		int i;
 
-		for (entry = info; entry != info + n_ents; entry++) {
-			if (entry->dev == parent) {
-				idx = entry - info;
+		for (i = 0; i < n_ents; i++) {
+			const struct driver_rt *drt = gd_dm_driver_rt() + i;
+
+			if (drt->dev == parent) {
+				idx = i;
 				found[idx] = true;
 				break;
 			}
@@ -153,16 +153,17 @@ static int dm_test_of_platdata_dev(struct unit_test_state *uts)
 
 	/* Make sure that the driver entries without devices have no ->dev */
 	for (i = 0; i < n_ents; i++) {
+		const struct driver_rt *drt = gd_dm_driver_rt() + i;
 		const struct driver_info *entry = info + i;
 		struct udevice *dev;
 
 		if (found[i]) {
 			/* Make sure we can find it */
-			ut_assertnonnull(entry->dev);
+			ut_assertnonnull(drt->dev);
 			ut_assertok(device_get_by_driver_info(entry, &dev));
-			ut_asserteq_ptr(dev, entry->dev);
+			ut_asserteq_ptr(dev, drt->dev);
 		} else {
-			ut_assertnull(entry->dev);
+			ut_assertnull(drt->dev);
 			ut_asserteq(-ENOENT,
 				    device_get_by_driver_info(entry, &dev));
 		}
-- 
2.28.0.806.g8561365e88-goog

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

* [PATCH 12/20] sandbox: Fix up building for of-platdata
  2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
                   ` (10 preceding siblings ...)
  2020-10-03 17:31 ` [PATCH 11/20] dm: Use an allocated array for run-time device info Simon Glass
@ 2020-10-03 17:31 ` Simon Glass
  2020-10-03 17:31 ` [PATCH 13/20] dm: Support parent devices with of-platdata Simon Glass
                   ` (26 subsequent siblings)
  38 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2020-10-03 17:31 UTC (permalink / raw)
  To: u-boot

There is no devicetree with of-platdata. Update a few uclasses to allow
them to be built for sandbox_spl. Also drop the i2c-gpio from SPL to avoid
build errors, since it does not support of-platdata.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 drivers/i2c/Makefile          | 2 +-
 drivers/i2c/i2c-emul-uclass.c | 2 ++
 drivers/rtc/rtc-uclass.c      | 2 ++
 3 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index bd248cbf52b..b37198036c0 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -6,7 +6,7 @@ obj-$(CONFIG_DM_I2C) += i2c-uclass.o
 ifdef CONFIG_ACPIGEN
 obj-$(CONFIG_DM_I2C) += acpi_i2c.o
 endif
-obj-$(CONFIG_DM_I2C_GPIO) += i2c-gpio.o
+obj-$(CONFIG_$(SPL_)DM_I2C_GPIO) += i2c-gpio.o
 obj-$(CONFIG_$(SPL_)I2C_CROS_EC_TUNNEL) += cros_ec_tunnel.o
 obj-$(CONFIG_$(SPL_)I2C_CROS_EC_LDO) += cros_ec_ldo.o
 
diff --git a/drivers/i2c/i2c-emul-uclass.c b/drivers/i2c/i2c-emul-uclass.c
index 1b70e140545..84b6a219d19 100644
--- a/drivers/i2c/i2c-emul-uclass.c
+++ b/drivers/i2c/i2c-emul-uclass.c
@@ -76,7 +76,9 @@ UCLASS_DRIVER(i2c_emul) = {
 UCLASS_DRIVER(i2c_emul_parent) = {
 	.id		= UCLASS_I2C_EMUL_PARENT,
 	.name		= "i2c_emul_parent",
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
 	.post_bind	= dm_scan_fdt_dev,
+#endif
 };
 
 static const struct udevice_id i2c_emul_parent_ids[] = {
diff --git a/drivers/rtc/rtc-uclass.c b/drivers/rtc/rtc-uclass.c
index 8035f7fe9cc..b406bab32d1 100644
--- a/drivers/rtc/rtc-uclass.c
+++ b/drivers/rtc/rtc-uclass.c
@@ -174,5 +174,7 @@ int rtc_write32(struct udevice *dev, unsigned int reg, u32 value)
 UCLASS_DRIVER(rtc) = {
 	.name		= "rtc",
 	.id		= UCLASS_RTC,
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
 	.post_bind	= dm_scan_fdt_dev,
+#endif
 };
-- 
2.28.0.806.g8561365e88-goog

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

* [PATCH 13/20] dm: Support parent devices with of-platdata
  2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
                   ` (11 preceding siblings ...)
  2020-10-03 17:31 ` [PATCH 12/20] sandbox: Fix up building for of-platdata Simon Glass
@ 2020-10-03 17:31 ` Simon Glass
  2020-10-03 17:31 ` [PATCH 14/20] dm: Add a test for of-platdata parent information Simon Glass
                   ` (25 subsequent siblings)
  38 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2020-10-03 17:31 UTC (permalink / raw)
  To: u-boot

At present of-platdata does not provide parent information. But this is
useful for I2C devices, for example, since it allows them to determine
which bus they are on.

Add support for setting the parent correctly, by storing the parent
driver_info index in dtoc and reading this in lists_bind_drivers(). This
needs multiple passes since we must process children after their parents
already have been bound.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 drivers/core/lists.c       | 54 ++++++++++++++++++++++++++++++++++++--
 dts/Kconfig                | 18 +++++++++++++
 include/dm/platdata.h      | 10 ++++++-
 tools/dtoc/dtb_platdata.py |  4 +++
 tools/dtoc/test_dtoc.py    | 33 +++++++++++++++++++++++
 5 files changed, 116 insertions(+), 3 deletions(-)

diff --git a/drivers/core/lists.c b/drivers/core/lists.c
index 2e6bd5006ce..b23ee3030e5 100644
--- a/drivers/core/lists.c
+++ b/drivers/core/lists.c
@@ -51,21 +51,48 @@ struct uclass_driver *lists_uclass_lookup(enum uclass_id id)
 	return NULL;
 }
 
-int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only)
+static int bind_drivers_pass(struct udevice *parent, bool pre_reloc_only)
 {
 	struct driver_info *info =
 		ll_entry_start(struct driver_info, driver_info);
 	const int n_ents = ll_entry_count(struct driver_info, driver_info);
+	bool missing_parent = false;
 	int result = 0;
 	uint idx;
 
+	/*
+	 * Do one iteration through the driver_info records. For of-platdata,
+	 * bind only devices whose parent is already bound. If we find any
+	 * device we can't bind, set missing_parent to true, which will cause
+	 * this function to be called again.
+	 */
 	for (idx = 0; idx < n_ents; idx++) {
+		struct udevice *par = parent;
 		const struct driver_info *entry = info + idx;
 		struct driver_rt *drt = gd_dm_driver_rt() + idx;
 		struct udevice *dev;
 		int ret;
 
-		ret = device_bind_by_name(parent, pre_reloc_only, entry, &dev);
+		if (CONFIG_IS_ENABLED(OF_PLATDATA)) {
+			int parent_idx = driver_info_parent_id(entry);
+
+			if (drt->dev)
+				continue;
+
+			if (CONFIG_IS_ENABLED(OF_PLATDATA_PARENT) &&
+			    parent_idx != -1) {
+				struct driver_rt *parent_drt;
+
+				parent_drt = gd_dm_driver_rt() + parent_idx;
+				if (!parent_drt->dev) {
+					missing_parent = true;
+					continue;
+				}
+
+				par = parent_drt->dev;
+			}
+		}
+		ret = device_bind_by_name(par, pre_reloc_only, entry, &dev);
 		if (!ret) {
 			if (CONFIG_IS_ENABLED(OF_PLATDATA))
 				drt->dev = dev;
@@ -76,6 +103,29 @@ int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only)
 		}
 	}
 
+	return result ? result : missing_parent ? -EAGAIN : 0;
+}
+
+int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only)
+{
+	int result = 0;
+	int pass;
+
+	/*
+	 * 10 passes is 10 levels deep in the devicetree, which is plenty. If
+	 * OF_PLATDATA_PARENT is not enabled, then bind_drivers_pass() will
+	 * always succeed on the first pass.
+	 */
+	for (pass = 0; pass < 10; pass++) {
+		int ret;
+
+		ret = bind_drivers_pass(parent, pre_reloc_only);
+		if (!ret)
+			break;
+		if (ret != -EAGAIN && !result)
+			result = ret;
+	}
+
 	return result;
 }
 
diff --git a/dts/Kconfig b/dts/Kconfig
index 046a54a1736..616f8484280 100644
--- a/dts/Kconfig
+++ b/dts/Kconfig
@@ -355,6 +355,15 @@ config SPL_OF_PLATDATA
 	  compatible string, then adding platform data and U_BOOT_DEVICE
 	  declarations for each node. See of-plat.txt for more information.
 
+config SPL_OF_PLATDATA_PARENT
+	bool "Support parent information in devices"
+	depends on SPL_OF_PLATDATA
+	default y
+	help
+	  Generally it is useful to be able to access the parent of a device
+	  with of-platdata. To save space this can be disabled, but in that
+	  case dev_get_parent() will always return NULL;
+
 config TPL_OF_PLATDATA
 	bool "Generate platform data for use in TPL"
 	depends on TPL_OF_CONTROL
@@ -376,6 +385,15 @@ config TPL_OF_PLATDATA
 	  compatible string, then adding platform data and U_BOOT_DEVICE
 	  declarations for each node. See of-plat.txt for more information.
 
+config TPL_OF_PLATDATA_PARENT
+	bool "Support parent information in devices"
+	depends on TPL_OF_PLATDATA
+	default y
+	help
+	  Generally it is useful to be able to access the parent of a device
+	  with of-platdata. To save space this can be disabled, but in that
+	  case dev_get_parent() will always return NULL;
+
 endmenu
 
 config MKIMAGE_DTC_PATH
diff --git a/include/dm/platdata.h b/include/dm/platdata.h
index 2c3cc90c291..f800a866dda 100644
--- a/include/dm/platdata.h
+++ b/include/dm/platdata.h
@@ -22,15 +22,23 @@
  * @name:	Driver name
  * @platdata:	Driver-specific platform data
  * @platdata_size: Size of platform data structure
+ * @parent_idx:	Index of the parent driver_info structure
  */
 struct driver_info {
 	const char *name;
 	const void *platdata;
 #if CONFIG_IS_ENABLED(OF_PLATDATA)
-	uint platdata_size;
+	unsigned short platdata_size;
+	short parent_idx;
 #endif
 };
 
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+#define driver_info_parent_id(driver_info)	driver_info->parent_idx
+#else
+#define driver_info_parent_id(driver_info)	(-1)
+#endif
+
 /**
  * driver_rt - runtime information set up by U-Boot
  *
diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py
index 31a9b3877ea..8832e6ebecb 100644
--- a/tools/dtoc/dtb_platdata.py
+++ b/tools/dtoc/dtb_platdata.py
@@ -662,6 +662,10 @@ class DtbPlatdata(object):
         self.buf('\t.name\t\t= "%s",\n' % struct_name)
         self.buf('\t.platdata\t= &%s%s,\n' % (VAL_PREFIX, var_name))
         self.buf('\t.platdata_size\t= sizeof(%s%s),\n' % (VAL_PREFIX, var_name))
+        idx = -1
+        if node.parent and node.parent in self._valid_nodes:
+            idx = node.parent.idx
+        self.buf('\t.parent_idx\t= %d,\n' % idx)
         self.buf('};\n')
         self.buf('\n')
 
diff --git a/tools/dtoc/test_dtoc.py b/tools/dtoc/test_dtoc.py
index 8dcac91ee70..fee9853d034 100755
--- a/tools/dtoc/test_dtoc.py
+++ b/tools/dtoc/test_dtoc.py
@@ -216,6 +216,7 @@ U_BOOT_DEVICE(i2c_at_0) = {
 \t.name\t\t= "sandbox_i2c_test",
 \t.platdata\t= &dtv_i2c_at_0,
 \t.platdata_size\t= sizeof(dtv_i2c_at_0),
+\t.parent_idx\t= -1,
 };
 
 /* Node /i2c at 0/pmic at 9 index 1 */
@@ -227,6 +228,7 @@ U_BOOT_DEVICE(pmic_at_9) = {
 \t.name\t\t= "sandbox_pmic_test",
 \t.platdata\t= &dtv_pmic_at_9,
 \t.platdata_size\t= sizeof(dtv_pmic_at_9),
+\t.parent_idx\t= 0,
 };
 
 /* Node /spl-test index 2 */
@@ -246,6 +248,7 @@ U_BOOT_DEVICE(spl_test) = {
 \t.name\t\t= "sandbox_spl_test",
 \t.platdata\t= &dtv_spl_test,
 \t.platdata_size\t= sizeof(dtv_spl_test),
+\t.parent_idx\t= -1,
 };
 
 /* Node /spl-test2 index 3 */
@@ -264,6 +267,7 @@ U_BOOT_DEVICE(spl_test2) = {
 \t.name\t\t= "sandbox_spl_test",
 \t.platdata\t= &dtv_spl_test2,
 \t.platdata_size\t= sizeof(dtv_spl_test2),
+\t.parent_idx\t= -1,
 };
 
 /* Node /spl-test3 index 4 */
@@ -276,6 +280,7 @@ U_BOOT_DEVICE(spl_test3) = {
 \t.name\t\t= "sandbox_spl_test",
 \t.platdata\t= &dtv_spl_test3,
 \t.platdata_size\t= sizeof(dtv_spl_test3),
+\t.parent_idx\t= -1,
 };
 
 /* Node /spl-test4 index 5 */
@@ -285,6 +290,7 @@ U_BOOT_DEVICE(spl_test4) = {
 \t.name\t\t= "sandbox_spl_test_2",
 \t.platdata\t= &dtv_spl_test4,
 \t.platdata_size\t= sizeof(dtv_spl_test4),
+\t.parent_idx\t= -1,
 };
 
 ''' + C_EMPTY_POPULATE_PHANDLE_DATA, data)
@@ -318,6 +324,7 @@ U_BOOT_DEVICE(gpios_at_0) = {
 \t.name\t\t= "sandbox_gpio",
 \t.platdata\t= &dtv_gpios_at_0,
 \t.platdata_size\t= sizeof(dtv_gpios_at_0),
+\t.parent_idx\t= -1,
 };
 
 void dm_populate_phandle_data(void) {
@@ -349,6 +356,7 @@ U_BOOT_DEVICE(spl_test) = {
 \t.name\t\t= "invalid",
 \t.platdata\t= &dtv_spl_test,
 \t.platdata_size\t= sizeof(dtv_spl_test),
+\t.parent_idx\t= -1,
 };
 
 void dm_populate_phandle_data(void) {
@@ -383,6 +391,7 @@ U_BOOT_DEVICE(phandle2_target) = {
 \t.name\t\t= "target",
 \t.platdata\t= &dtv_phandle2_target,
 \t.platdata_size\t= sizeof(dtv_phandle2_target),
+\t.parent_idx\t= -1,
 };
 
 /* Node /phandle3-target index 1 */
@@ -393,6 +402,7 @@ U_BOOT_DEVICE(phandle3_target) = {
 \t.name\t\t= "target",
 \t.platdata\t= &dtv_phandle3_target,
 \t.platdata_size\t= sizeof(dtv_phandle3_target),
+\t.parent_idx\t= -1,
 };
 
 /* Node /phandle-target index 4 */
@@ -403,6 +413,7 @@ U_BOOT_DEVICE(phandle_target) = {
 \t.name\t\t= "target",
 \t.platdata\t= &dtv_phandle_target,
 \t.platdata_size\t= sizeof(dtv_phandle_target),
+\t.parent_idx\t= -1,
 };
 
 /* Node /phandle-source index 2 */
@@ -417,6 +428,7 @@ U_BOOT_DEVICE(phandle_source) = {
 \t.name\t\t= "source",
 \t.platdata\t= &dtv_phandle_source,
 \t.platdata_size\t= sizeof(dtv_phandle_source),
+\t.parent_idx\t= -1,
 };
 
 /* Node /phandle-source2 index 3 */
@@ -428,6 +440,7 @@ U_BOOT_DEVICE(phandle_source2) = {
 \t.name\t\t= "source",
 \t.platdata\t= &dtv_phandle_source2,
 \t.platdata_size\t= sizeof(dtv_phandle_source2),
+\t.parent_idx\t= -1,
 };
 
 void dm_populate_phandle_data(void) {
@@ -470,6 +483,7 @@ U_BOOT_DEVICE(phandle_target) = {
 \t.name\t\t= "target",
 \t.platdata\t= &dtv_phandle_target,
 \t.platdata_size\t= sizeof(dtv_phandle_target),
+\t.parent_idx\t= -1,
 };
 
 /* Node /phandle-source2 index 0 */
@@ -481,6 +495,7 @@ U_BOOT_DEVICE(phandle_source2) = {
 \t.name\t\t= "source",
 \t.platdata\t= &dtv_phandle_source2,
 \t.platdata_size\t= sizeof(dtv_phandle_source2),
+\t.parent_idx\t= -1,
 };
 
 void dm_populate_phandle_data(void) {
@@ -504,6 +519,7 @@ U_BOOT_DEVICE(phandle2_target) = {
 \t.name\t\t= "target",
 \t.platdata\t= &dtv_phandle2_target,
 \t.platdata_size\t= sizeof(dtv_phandle2_target),
+\t.parent_idx\t= -1,
 };
 
 /* Node /phandle3-target index 1 */
@@ -514,6 +530,7 @@ U_BOOT_DEVICE(phandle3_target) = {
 \t.name\t\t= "target",
 \t.platdata\t= &dtv_phandle3_target,
 \t.platdata_size\t= sizeof(dtv_phandle3_target),
+\t.parent_idx\t= -1,
 };
 
 /* Node /phandle-target index 4 */
@@ -524,6 +541,7 @@ U_BOOT_DEVICE(phandle_target) = {
 \t.name\t\t= "target",
 \t.platdata\t= &dtv_phandle_target,
 \t.platdata_size\t= sizeof(dtv_phandle_target),
+\t.parent_idx\t= -1,
 };
 
 /* Node /phandle-source index 2 */
@@ -538,6 +556,7 @@ U_BOOT_DEVICE(phandle_source) = {
 \t.name\t\t= "source",
 \t.platdata\t= &dtv_phandle_source,
 \t.platdata_size\t= sizeof(dtv_phandle_source),
+\t.parent_idx\t= -1,
 };
 
 /* Node /phandle-source2 index 3 */
@@ -549,6 +568,7 @@ U_BOOT_DEVICE(phandle_source2) = {
 \t.name\t\t= "source",
 \t.platdata\t= &dtv_phandle_source2,
 \t.platdata_size\t= sizeof(dtv_phandle_source2),
+\t.parent_idx\t= -1,
 };
 
 void dm_populate_phandle_data(void) {
@@ -611,6 +631,7 @@ U_BOOT_DEVICE(test1) = {
 \t.name\t\t= "test1",
 \t.platdata\t= &dtv_test1,
 \t.platdata_size\t= sizeof(dtv_test1),
+\t.parent_idx\t= -1,
 };
 
 /* Node /test2 index 1 */
@@ -621,6 +642,7 @@ U_BOOT_DEVICE(test2) = {
 \t.name\t\t= "test2",
 \t.platdata\t= &dtv_test2,
 \t.platdata_size\t= sizeof(dtv_test2),
+\t.parent_idx\t= -1,
 };
 
 /* Node /test3 index 2 */
@@ -631,6 +653,7 @@ U_BOOT_DEVICE(test3) = {
 \t.name\t\t= "test3",
 \t.platdata\t= &dtv_test3,
 \t.platdata_size\t= sizeof(dtv_test3),
+\t.parent_idx\t= -1,
 };
 
 ''' + C_EMPTY_POPULATE_PHANDLE_DATA, data)
@@ -663,6 +686,7 @@ U_BOOT_DEVICE(test1) = {
 \t.name\t\t= "test1",
 \t.platdata\t= &dtv_test1,
 \t.platdata_size\t= sizeof(dtv_test1),
+\t.parent_idx\t= -1,
 };
 
 /* Node /test2 index 1 */
@@ -673,6 +697,7 @@ U_BOOT_DEVICE(test2) = {
 \t.name\t\t= "test2",
 \t.platdata\t= &dtv_test2,
 \t.platdata_size\t= sizeof(dtv_test2),
+\t.parent_idx\t= -1,
 };
 
 ''' + C_EMPTY_POPULATE_PHANDLE_DATA, data)
@@ -708,6 +733,7 @@ U_BOOT_DEVICE(test1) = {
 \t.name\t\t= "test1",
 \t.platdata\t= &dtv_test1,
 \t.platdata_size\t= sizeof(dtv_test1),
+\t.parent_idx\t= -1,
 };
 
 /* Node /test2 index 1 */
@@ -718,6 +744,7 @@ U_BOOT_DEVICE(test2) = {
 \t.name\t\t= "test2",
 \t.platdata\t= &dtv_test2,
 \t.platdata_size\t= sizeof(dtv_test2),
+\t.parent_idx\t= -1,
 };
 
 /* Node /test3 index 2 */
@@ -728,6 +755,7 @@ U_BOOT_DEVICE(test3) = {
 \t.name\t\t= "test3",
 \t.platdata\t= &dtv_test3,
 \t.platdata_size\t= sizeof(dtv_test3),
+\t.parent_idx\t= -1,
 };
 
 ''' + C_EMPTY_POPULATE_PHANDLE_DATA, data)
@@ -763,6 +791,7 @@ U_BOOT_DEVICE(test1) = {
 \t.name\t\t= "test1",
 \t.platdata\t= &dtv_test1,
 \t.platdata_size\t= sizeof(dtv_test1),
+\t.parent_idx\t= -1,
 };
 
 /* Node /test2 index 1 */
@@ -773,6 +802,7 @@ U_BOOT_DEVICE(test2) = {
 \t.name\t\t= "test2",
 \t.platdata\t= &dtv_test2,
 \t.platdata_size\t= sizeof(dtv_test2),
+\t.parent_idx\t= -1,
 };
 
 /* Node /test3 index 2 */
@@ -783,6 +813,7 @@ U_BOOT_DEVICE(test3) = {
 \t.name\t\t= "test3",
 \t.platdata\t= &dtv_test3,
 \t.platdata_size\t= sizeof(dtv_test3),
+\t.parent_idx\t= -1,
 };
 
 ''' + C_EMPTY_POPULATE_PHANDLE_DATA, data)
@@ -833,6 +864,7 @@ U_BOOT_DEVICE(spl_test) = {
 \t.name\t\t= "sandbox_spl_test",
 \t.platdata\t= &dtv_spl_test,
 \t.platdata_size\t= sizeof(dtv_spl_test),
+\t.parent_idx\t= -1,
 };
 
 /* Node /spl-test2 index 1 */
@@ -843,6 +875,7 @@ U_BOOT_DEVICE(spl_test2) = {
 \t.name\t\t= "sandbox_spl_test",
 \t.platdata\t= &dtv_spl_test2,
 \t.platdata_size\t= sizeof(dtv_spl_test2),
+\t.parent_idx\t= -1,
 };
 
 ''' + C_EMPTY_POPULATE_PHANDLE_DATA, data)
-- 
2.28.0.806.g8561365e88-goog

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

* [PATCH 14/20] dm: Add a test for of-platdata parent information
  2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
                   ` (12 preceding siblings ...)
  2020-10-03 17:31 ` [PATCH 13/20] dm: Support parent devices with of-platdata Simon Glass
@ 2020-10-03 17:31 ` Simon Glass
  2020-10-03 17:31 ` [PATCH 15/20] dm: core: Convert #ifdef to if() in root.c Simon Glass
                   ` (24 subsequent siblings)
  38 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2020-10-03 17:31 UTC (permalink / raw)
  To: u-boot

Add a simple test that we can obtain the correct parent for an I2C
device. This requires updating the driver names to match the compatible
strings, adding them to the devicetree and enabling a few options.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 arch/sandbox/dts/sandbox.dts  |  1 +
 arch/sandbox/dts/sandbox.dtsi |  1 +
 configs/sandbox_spl_defconfig |  4 +++-
 drivers/i2c/sandbox_i2c.c     |  4 ++--
 drivers/rtc/sandbox_rtc.c     |  4 ++--
 test/dm/of_platdata.c         | 15 +++++++++++++++
 6 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/arch/sandbox/dts/sandbox.dts b/arch/sandbox/dts/sandbox.dts
index 20f68938297..8b50a402898 100644
--- a/arch/sandbox/dts/sandbox.dts
+++ b/arch/sandbox/dts/sandbox.dts
@@ -69,6 +69,7 @@
 		clock-frequency = <400000>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_i2c0>;
+		u-boot,dm-pre-reloc;
 	};
 
 	pcic: pci at 0 {
diff --git a/arch/sandbox/dts/sandbox.dtsi b/arch/sandbox/dts/sandbox.dtsi
index ca7049fc974..2ec43b009bc 100644
--- a/arch/sandbox/dts/sandbox.dtsi
+++ b/arch/sandbox/dts/sandbox.dtsi
@@ -90,6 +90,7 @@
 			reg = <0x43>;
 			compatible = "sandbox-rtc";
 			sandbox,emul = <&emul0>;
+			u-boot,dm-pre-reloc;
 		};
 		sandbox_pmic: sandbox_pmic {
 			reg = <0x40>;
diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig
index 91215d23a0f..0cf8cf76577 100644
--- a/configs/sandbox_spl_defconfig
+++ b/configs/sandbox_spl_defconfig
@@ -26,6 +26,8 @@ CONFIG_DISPLAY_BOARDINFO_LATE=y
 CONFIG_HANDOFF=y
 CONFIG_SPL_BOARD_INIT=y
 CONFIG_SPL_ENV_SUPPORT=y
+CONFIG_SPL_I2C_SUPPORT=y
+CONFIG_SPL_RTC_SUPPORT=y
 CONFIG_CMD_CPU=y
 CONFIG_CMD_LICENSE=y
 CONFIG_CMD_BOOTZ=y
@@ -120,7 +122,6 @@ CONFIG_I2C_CROS_EC_LDO=y
 CONFIG_DM_I2C_GPIO=y
 CONFIG_SYS_I2C_SANDBOX=y
 CONFIG_I2C_MUX=y
-CONFIG_SPL_I2C_MUX=y
 CONFIG_I2C_ARB_GPIO_CHALLENGE=y
 CONFIG_CROS_EC_KEYB=y
 CONFIG_I8042_KEYB=y
@@ -187,6 +188,7 @@ CONFIG_REMOTEPROC_SANDBOX=y
 CONFIG_DM_RESET=y
 CONFIG_SANDBOX_RESET=y
 CONFIG_DM_RTC=y
+CONFIG_SPL_DM_RTC=y
 CONFIG_SANDBOX_SERIAL=y
 CONFIG_SOUND=y
 CONFIG_SOUND_SANDBOX=y
diff --git a/drivers/i2c/sandbox_i2c.c b/drivers/i2c/sandbox_i2c.c
index 57b1c60fde6..2cbdaf9cc73 100644
--- a/drivers/i2c/sandbox_i2c.c
+++ b/drivers/i2c/sandbox_i2c.c
@@ -93,8 +93,8 @@ static const struct udevice_id sandbox_i2c_ids[] = {
 	{ }
 };
 
-U_BOOT_DRIVER(i2c_sandbox) = {
-	.name	= "i2c_sandbox",
+U_BOOT_DRIVER(sandbox_i2c) = {
+	.name	= "sandbox_i2c",
 	.id	= UCLASS_I2C,
 	.of_match = sandbox_i2c_ids,
 	.ops	= &sandbox_i2c_ops,
diff --git a/drivers/rtc/sandbox_rtc.c b/drivers/rtc/sandbox_rtc.c
index 852770a49cf..d0864b1df97 100644
--- a/drivers/rtc/sandbox_rtc.c
+++ b/drivers/rtc/sandbox_rtc.c
@@ -92,8 +92,8 @@ static const struct udevice_id sandbox_rtc_ids[] = {
 	{ }
 };
 
-U_BOOT_DRIVER(rtc_sandbox) = {
-	.name	= "rtc-sandbox",
+U_BOOT_DRIVER(sandbox_rtc) = {
+	.name	= "sandbox_rtc",
 	.id	= UCLASS_RTC,
 	.of_match = sandbox_rtc_ids,
 	.ops	= &sandbox_rtc_ops,
diff --git a/test/dm/of_platdata.c b/test/dm/of_platdata.c
index e827d45ffb7..bad733fbee0 100644
--- a/test/dm/of_platdata.c
+++ b/test/dm/of_platdata.c
@@ -205,3 +205,18 @@ static int dm_test_of_platdata_phandle(struct unit_test_state *uts)
 	return 0;
 }
 DM_TEST(dm_test_of_platdata_phandle, UT_TESTF_SCAN_PDATA);
+
+#if CONFIG_IS_ENABLED(OF_PLATDATA_PARENT)
+/* Test that device parents are correctly set up */
+static int dm_test_of_platdata_parent(struct unit_test_state *uts)
+{
+	struct udevice *rtc, *i2c;
+
+	ut_assertok(uclass_first_device_err(UCLASS_RTC, &rtc));
+	ut_assertok(uclass_first_device_err(UCLASS_I2C, &i2c));
+	ut_asserteq_ptr(i2c, dev_get_parent(rtc));
+
+	return 0;
+}
+DM_TEST(dm_test_of_platdata_parent, UT_TESTF_SCAN_PDATA);
+#endif
-- 
2.28.0.806.g8561365e88-goog

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

* [PATCH 15/20] dm: core: Convert #ifdef to if() in root.c
  2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
                   ` (13 preceding siblings ...)
  2020-10-03 17:31 ` [PATCH 14/20] dm: Add a test for of-platdata parent information Simon Glass
@ 2020-10-03 17:31 ` Simon Glass
  2020-11-04 12:55   ` Michal Simek
  2020-10-03 17:31 ` [PATCH 16/20] x86: apl: Enable SPI flash in TPL with APL_SPI_FLASH_BOOT Simon Glass
                   ` (23 subsequent siblings)
  38 siblings, 1 reply; 43+ messages in thread
From: Simon Glass @ 2020-10-03 17:31 UTC (permalink / raw)
  To: u-boot

Convert a few conditions to use compile-time checks to reduce the number
of build paths.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 drivers/core/root.c | 18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/drivers/core/root.c b/drivers/core/root.c
index e8df5aebe84..5f10d7a39c7 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -50,7 +50,6 @@ void dm_fixup_for_gd_move(struct global_data *new_gd)
 	}
 }
 
-#if defined(CONFIG_NEEDS_MANUAL_RELOC)
 void fix_drivers(void)
 {
 	struct driver *drv =
@@ -129,8 +128,6 @@ void fix_devices(void)
 	}
 }
 
-#endif
-
 int dm_init(bool of_live)
 {
 	int ret;
@@ -141,11 +138,11 @@ int dm_init(bool of_live)
 	}
 	INIT_LIST_HEAD(&DM_UCLASS_ROOT_NON_CONST);
 
-#if defined(CONFIG_NEEDS_MANUAL_RELOC)
-	fix_drivers();
-	fix_uclass();
-	fix_devices();
-#endif
+	if (IS_ENABLED(CONFIG_NEEDS_MANUAL_RELOC)) {
+		fix_drivers();
+		fix_uclass();
+		fix_devices();
+	}
 
 	ret = device_bind_by_name(NULL, false, &root_info, &DM_ROOT_NON_CONST);
 	if (ret)
@@ -350,9 +347,8 @@ int dm_init_and_scan(bool pre_reloc_only)
 {
 	int ret;
 
-#if CONFIG_IS_ENABLED(OF_PLATDATA)
-	dm_populate_phandle_data();
-#endif
+	if (CONFIG_IS_ENABLED(OF_PLATDATA))
+		dm_populate_phandle_data();
 
 	ret = dm_init(CONFIG_IS_ENABLED(OF_LIVE));
 	if (ret) {
-- 
2.28.0.806.g8561365e88-goog

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

* [PATCH 16/20] x86: apl: Enable SPI flash in TPL with APL_SPI_FLASH_BOOT
  2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
                   ` (14 preceding siblings ...)
  2020-10-03 17:31 ` [PATCH 15/20] dm: core: Convert #ifdef to if() in root.c Simon Glass
@ 2020-10-03 17:31 ` Simon Glass
  2020-10-03 17:31 ` [PATCH 17/20] x86: apl: Take advantage of the of-platdata parent support Simon Glass
                   ` (22 subsequent siblings)
  38 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2020-10-03 17:31 UTC (permalink / raw)
  To: u-boot

At present, enabling CONFIG_APL_SPI_FLASH_BOOT does not build since SPI
and SPI flash are not enabled for TPL. Add a condition to fix this and
tidy up a build warning in the SPI-flash driver.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 arch/x86/cpu/apollolake/Kconfig | 2 ++
 drivers/spi/ich.c               | 4 +++-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/x86/cpu/apollolake/Kconfig b/arch/x86/cpu/apollolake/Kconfig
index 35a425cd1bc..c6c1350f4f0 100644
--- a/arch/x86/cpu/apollolake/Kconfig
+++ b/arch/x86/cpu/apollolake/Kconfig
@@ -85,6 +85,8 @@ config APL_SPI_FLASH_BOOT
 	bool "Support booting with SPI-flash driver instead memory-mapped SPI"
 	select TPL_SPI_FLASH_SUPPORT
 	select TPL_SPI_SUPPORT
+	select TPL_DM_SPI
+	select TPL_DM_SPI_FLASH
 	help
 	  This enables SPI and SPI flash in TPL. Without the this only
 	  available boot method is to use memory-mapped SPI. Since this is
diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c
index e1336b89c5a..a91cb785680 100644
--- a/drivers/spi/ich.c
+++ b/drivers/spi/ich.c
@@ -615,6 +615,7 @@ static int ich_spi_exec_op(struct spi_slave *slave, const struct spi_mem_op *op)
 	return ret;
 }
 
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
 /**
  * ich_spi_get_basics() - Get basic information about the ICH device
  *
@@ -657,6 +658,7 @@ static int ich_spi_get_basics(struct udevice *bus, bool can_probe,
 
 	return ret;
 }
+#endif
 
 /**
  * ich_get_mmap_bus() - Handle the get_mmap() method for a bus
@@ -946,10 +948,10 @@ static int ich_spi_child_pre_probe(struct udevice *dev)
 static int ich_spi_ofdata_to_platdata(struct udevice *dev)
 {
 	struct ich_spi_platdata *plat = dev_get_platdata(dev);
-	int ret;
 
 #if !CONFIG_IS_ENABLED(OF_PLATDATA)
 	struct ich_spi_priv *priv = dev_get_priv(dev);
+	int ret;
 
 	ret = ich_spi_get_basics(dev, true, &priv->pch, &plat->ich_version,
 				 &plat->mmio_base);
-- 
2.28.0.806.g8561365e88-goog

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

* [PATCH 17/20] x86: apl: Take advantage of the of-platdata parent support
  2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
                   ` (15 preceding siblings ...)
  2020-10-03 17:31 ` [PATCH 16/20] x86: apl: Enable SPI flash in TPL with APL_SPI_FLASH_BOOT Simon Glass
@ 2020-10-03 17:31 ` Simon Glass
  2020-10-03 17:31 ` [PATCH 18/20] dm: Use driver_info index instead of pointer Simon Glass
                   ` (21 subsequent siblings)
  38 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2020-10-03 17:31 UTC (permalink / raw)
  To: u-boot

Now that parent devices are supported with of-platadata, we don't need the
messy code to fix up the parent pointers and allocations on Apollo Lake.
Put the code behind a condition.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 arch/x86/cpu/apollolake/spl.c |  3 ++-
 drivers/misc/p2sb-uclass.c    | 27 ++++++++++++++-------------
 2 files changed, 16 insertions(+), 14 deletions(-)

diff --git a/arch/x86/cpu/apollolake/spl.c b/arch/x86/cpu/apollolake/spl.c
index 5a53831dc6a..089b37c59f8 100644
--- a/arch/x86/cpu/apollolake/spl.c
+++ b/arch/x86/cpu/apollolake/spl.c
@@ -90,7 +90,8 @@ static int apl_flash_probe(struct udevice *dev)
  */
 static int apl_flash_bind(struct udevice *dev)
 {
-	if (CONFIG_IS_ENABLED(OF_PLATDATA)) {
+	if (CONFIG_IS_ENABLED(OF_PLATDATA) &&
+	    !CONFIG_IS_ENABLED(OF_PLATDATA_PARENT)) {
 		struct dm_spi_slave_platdata *plat;
 		struct udevice *spi;
 		int ret;
diff --git a/drivers/misc/p2sb-uclass.c b/drivers/misc/p2sb-uclass.c
index b5219df46be..12abcff2da4 100644
--- a/drivers/misc/p2sb-uclass.c
+++ b/drivers/misc/p2sb-uclass.c
@@ -174,19 +174,20 @@ int p2sb_set_port_id(struct udevice *dev, int portid)
 	if (!CONFIG_IS_ENABLED(OF_PLATDATA))
 		return -ENOSYS;
 
-	uclass_find_first_device(UCLASS_P2SB, &ps2b);
-	if (!ps2b)
-		return -EDEADLK;
-	dev->parent = ps2b;
-
-	/*
-	 * We must allocate this, since when the device was bound it did not
-	 * have a parent.
-	 * TODO(sjg at chromium.org): Add a parent pointer to child devices in dtoc
-	 */
-	dev->parent_platdata = malloc(sizeof(*pplat));
-	if (!dev->parent_platdata)
-		return -ENOMEM;
+	if (!CONFIG_IS_ENABLED(OF_PLATDATA_PARENT)) {
+		uclass_find_first_device(UCLASS_P2SB, &ps2b);
+		if (!ps2b)
+			return -EDEADLK;
+		dev->parent = ps2b;
+
+		/*
+		 * We must allocate this, since when the device was bound it did
+		 * not have a parent.
+		 */
+		dev->parent_platdata = malloc(sizeof(*pplat));
+		if (!dev->parent_platdata)
+			return -ENOMEM;
+	}
 	pplat = dev_get_parent_platdata(dev);
 	pplat->pid = portid;
 
-- 
2.28.0.806.g8561365e88-goog

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

* [PATCH 18/20] dm: Use driver_info index instead of pointer
  2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
                   ` (16 preceding siblings ...)
  2020-10-03 17:31 ` [PATCH 17/20] x86: apl: Take advantage of the of-platdata parent support Simon Glass
@ 2020-10-03 17:31 ` Simon Glass
  2020-10-03 17:31 ` [PATCH 19/20] dm: Don't allow U_BOOT_DEVICE() when of-platdata is used Simon Glass
                   ` (20 subsequent siblings)
  38 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2020-10-03 17:31 UTC (permalink / raw)
  To: u-boot

At present we use a 'node' pointer in the of-platadata phandle_n_arg
structs. This is a pointer to the struct driver_info for a particular
device, and we can use it to obtain the struct udevice pointer itself.

Since we don't know the struct udevice pointer until it is allocated in
memory, we have to fix up the phandle_n_arg.node at runtime. This is
annoying since it requires that SPL's data is writable and adds a small
amount of extra (generated) code in the dm_populate_phandle_data()
function.

Now that we can find a driver_info by its index, it is easier to put the
index in the phandle_n_arg structures.

Update dtoc to do this, add a new device_get_by_driver_info_idx() to look
up a device by drive_info index and update the tests to match.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 drivers/clk/clk-uclass.c    |  3 +--
 drivers/core/device.c       | 11 +++++++++++
 drivers/misc/irq-uclass.c   |  2 +-
 drivers/mmc/fsl_esdhc_imx.c |  7 ++-----
 include/dm/device.h         | 14 ++++++++++++++
 include/dt-structs.h        |  6 +++---
 test/dm/of_platdata.c       | 10 +++++-----
 test/dm/test-main.c         | 24 ++++++++++++++++++++----
 test/py/tests/test_spl.py   |  5 ++---
 tools/dtoc/dtb_platdata.py  | 20 ++++----------------
 tools/dtoc/test_dtoc.py     | 33 +++++++++++----------------------
 11 files changed, 74 insertions(+), 61 deletions(-)

diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
index 934cd5787a5..c56bc71e387 100644
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -37,8 +37,7 @@ int clk_get_by_driver_info(struct udevice *dev, struct phandle_1_arg *cells,
 {
 	int ret;
 
-	ret = device_get_by_driver_info((struct driver_info *)cells->node,
-					&clk->dev);
+	ret = device_get_by_driver_info_idx(cells->idx, &clk->dev);
 	if (ret)
 		return ret;
 	clk->id = cells->arg[0];
diff --git a/drivers/core/device.c b/drivers/core/device.c
index c3338efc4fa..522d2ffe7e3 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -750,6 +750,17 @@ int device_get_by_driver_info(const struct driver_info *info,
 
 	return device_get_device_tail(dev, dev ? 0 : -ENOENT, devp);
 }
+
+int device_get_by_driver_info_idx(uint idx, struct udevice **devp)
+{
+	struct driver_rt *drt = gd_dm_driver_rt() + idx;
+	struct udevice *dev;
+
+	dev = drt->dev;
+	*devp = NULL;
+
+	return device_get_device_tail(dev, dev ? 0 : -ENOENT, devp);
+}
 #endif
 
 int device_find_first_child(const struct udevice *parent, struct udevice **devp)
diff --git a/drivers/misc/irq-uclass.c b/drivers/misc/irq-uclass.c
index 94fa233f193..24b27962a7d 100644
--- a/drivers/misc/irq-uclass.c
+++ b/drivers/misc/irq-uclass.c
@@ -69,7 +69,7 @@ int irq_get_by_driver_info(struct udevice *dev,
 {
 	int ret;
 
-	ret = device_get_by_driver_info(cells->node, &irq->dev);
+	ret = device_get_by_driver_info_idx(cells->idx, &irq->dev);
 	if (ret)
 		return ret;
 	irq->id = cells->arg[0];
diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c
index 0c866b168f9..ed04d1f964c 100644
--- a/drivers/mmc/fsl_esdhc_imx.c
+++ b/drivers/mmc/fsl_esdhc_imx.c
@@ -1511,12 +1511,9 @@ static int fsl_esdhc_probe(struct udevice *dev)
 
 	if (CONFIG_IS_ENABLED(DM_GPIO) && !priv->non_removable) {
 		struct udevice *gpiodev;
-		struct driver_info *info;
-
-		info = (struct driver_info *)dtplat->cd_gpios->node;
-
-		ret = device_get_by_driver_info(info, &gpiodev);
 
+		ret = device_get_by_driver_info(dtplat->cd_gpios->idx,
+						&gpiodev);
 		if (ret)
 			return ret;
 
diff --git a/include/dm/device.h b/include/dm/device.h
index ac3b6c1b8a0..c00bee1ccb0 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -553,6 +553,20 @@ int device_get_global_by_ofnode(ofnode node, struct udevice **devp);
 int device_get_by_driver_info(const struct driver_info *info,
 			      struct udevice **devp);
 
+/**
+ * device_get_by_driver_info_idx() - Get a device based on driver_info index
+ *
+ * Locates a device by its struct driver_info, by using its index number which
+ * is written into the idx field of struct phandle_1_arg, etc.
+ *
+ * The device is probed to activate it ready for use.
+ *
+ * @idx: Index number of the driver_info structure (0=first)
+ * @devp: Returns pointer to device if found, otherwise this is set to NULL
+ * @return 0 if OK, -ve on error
+ */
+int device_get_by_driver_info_idx(uint idx, struct udevice **devp);
+
 /**
  * device_find_first_child() - Find the first child of a device
  *
diff --git a/include/dt-structs.h b/include/dt-structs.h
index eed8273d18e..f0e1c9cb901 100644
--- a/include/dt-structs.h
+++ b/include/dt-structs.h
@@ -11,17 +11,17 @@
 struct driver_info;
 
 struct phandle_0_arg {
-	const struct driver_info *node;
+	uint idx;
 	int arg[0];
 };
 
 struct phandle_1_arg {
-	const struct driver_info *node;
+	uint idx;
 	int arg[1];
 };
 
 struct phandle_2_arg {
-	const struct driver_info *node;
+	uint idx;
 	int arg[2];
 };
 #include <generated/dt-structs-gen.h>
diff --git a/test/dm/of_platdata.c b/test/dm/of_platdata.c
index bad733fbee0..4f3cc159d03 100644
--- a/test/dm/of_platdata.c
+++ b/test/dm/of_platdata.c
@@ -183,22 +183,22 @@ static int dm_test_of_platdata_phandle(struct unit_test_state *uts)
 	ut_asserteq_str("sandbox_clk_test", dev->name);
 	plat = dev_get_platdata(dev);
 
-	ut_assertok(device_get_by_driver_info(plat->clocks[0].node, &clk));
+	ut_assertok(device_get_by_driver_info_idx(plat->clocks[0].idx, &clk));
 	ut_asserteq_str("fixed_clock", clk->name);
 
-	ut_assertok(device_get_by_driver_info(plat->clocks[1].node, &clk));
+	ut_assertok(device_get_by_driver_info_idx(plat->clocks[1].idx, &clk));
 	ut_asserteq_str("sandbox_clk", clk->name);
 	ut_asserteq(1, plat->clocks[1].arg[0]);
 
-	ut_assertok(device_get_by_driver_info(plat->clocks[2].node, &clk));
+	ut_assertok(device_get_by_driver_info_idx(plat->clocks[2].idx, &clk));
 	ut_asserteq_str("sandbox_clk", clk->name);
 	ut_asserteq(0, plat->clocks[2].arg[0]);
 
-	ut_assertok(device_get_by_driver_info(plat->clocks[3].node, &clk));
+	ut_assertok(device_get_by_driver_info_idx(plat->clocks[3].idx, &clk));
 	ut_asserteq_str("sandbox_clk", clk->name);
 	ut_asserteq(3, plat->clocks[3].arg[0]);
 
-	ut_assertok(device_get_by_driver_info(plat->clocks[4].node, &clk));
+	ut_assertok(device_get_by_driver_info_idx(plat->clocks[4].idx, &clk));
 	ut_asserteq_str("sandbox_clk", clk->name);
 	ut_asserteq(2, plat->clocks[4].arg[0]);
 
diff --git a/test/dm/test-main.c b/test/dm/test-main.c
index 9d22df8c4dc..fd24635006c 100644
--- a/test/dm/test-main.c
+++ b/test/dm/test-main.c
@@ -127,6 +127,24 @@ static bool dm_test_run_on_flattree(struct unit_test *test)
 	return !strstr(fname, "video") || strstr(test->name, "video_base");
 }
 
+static bool test_matches(const char *test_name, const char *find_name)
+{
+	if (!find_name)
+		return true;
+
+	if (!strcmp(test_name, find_name))
+		return true;
+
+	/* All tests have this prefix */
+	if (!strncmp(test_name, "dm_test_", 8))
+		test_name += 8;
+
+	if (!strcmp(test_name, find_name))
+		return true;
+
+	return false;
+}
+
 int dm_test_main(const char *test_name)
 {
 	struct unit_test *tests = ll_entry_start(struct unit_test, dm_test);
@@ -152,6 +170,7 @@ int dm_test_main(const char *test_name)
 
 	if (!test_name)
 		printf("Running %d driver model tests\n", n_ents);
+	else
 
 	found = 0;
 	uts->of_root = gd_of_root();
@@ -159,10 +178,7 @@ int dm_test_main(const char *test_name)
 		const char *name = test->name;
 		int runs;
 
-		/* All tests have this prefix */
-		if (!strncmp(name, "dm_test_", 8))
-			name += 8;
-		if (test_name && strcmp(test_name, name))
+		if (!test_matches(name, test_name))
 			continue;
 
 		/* Run with the live tree if possible */
diff --git a/test/py/tests/test_spl.py b/test/py/tests/test_spl.py
index 58a851e5ec8..d2b99027ce6 100644
--- a/test/py/tests/test_spl.py
+++ b/test/py/tests/test_spl.py
@@ -20,10 +20,9 @@ def test_spl(u_boot_console, ut_spl_subtest):
 
     Args:
         u_boot_console (ConsoleBase): U-Boot console
-        ut_subtest (str): test to be executed via command ut, e.g 'foo bar' to
-            execute command 'ut foo bar'
+        ut_subtest (str): SPL test to be executed (e.g. 'dm platdata_phandle')
     """
     cons = u_boot_console
-    cons.restart_uboot_with_flags(['-u', ut_spl_subtest])
+    cons.restart_uboot_with_flags(['-u', '-k', ut_spl_subtest.split()[1]])
     output = cons.get_spawn_output().replace('\r', '')
     assert 'Failures: 0' in output
diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py
index 8832e6ebecb..2be11fff6c2 100644
--- a/tools/dtoc/dtb_platdata.py
+++ b/tools/dtoc/dtb_platdata.py
@@ -154,8 +154,6 @@ class DtbPlatdata(object):
             key: Driver alias declared with
                 U_BOOT_DRIVER_ALIAS(driver_alias, driver_name)
             value: Driver name declared with U_BOOT_DRIVER(driver_name)
-        _links: List of links to be included in dm_populate_phandle_data(),
-            each a PhandleLink
         _drivers_additional: List of additional drivers to use during scanning
     """
     def __init__(self, dtb_fname, include_disabled, warning_disabled,
@@ -169,7 +167,6 @@ class DtbPlatdata(object):
         self._lines = []
         self._drivers = []
         self._driver_aliases = {}
-        self._links = []
         self._drivers_additional = drivers_additional
 
     def get_normalized_compat_name(self, node):
@@ -612,17 +609,11 @@ class DtbPlatdata(object):
                     name = conv_name_to_c(target_node.name)
                     arg_values = []
                     for i in range(args):
-                        arg_values.append(str(fdt_util.fdt32_to_cpu(prop.value[pos + 1 + i])))
+                        arg_values.append(
+                            str(fdt_util.fdt32_to_cpu(prop.value[pos + 1 + i])))
                     pos += 1 + args
-                    # node member is filled with NULL as the real value
-                    # will be update at run-time during dm_init_and_scan()
-                    # by dm_populate_phandle_data()
-                    vals.append('\t{NULL, {%s}}' % (', '.join(arg_values)))
-                    var_node = '%s%s.%s[%d].node' % \
-                                (VAL_PREFIX, var_name, member_name, item)
-                    # Save the the link information to be use to define
-                    # dm_populate_phandle_data()
-                    self._links.append(PhandleLink(var_node, name))
+                    vals.append('\t{%d, {%s}}' % (target_node.idx,
+                                                  ', '.join(arg_values)))
                     item += 1
                 for val in vals:
                     self.buf('\n\t\t%s,' % val)
@@ -703,9 +694,6 @@ class DtbPlatdata(object):
         # nodes using DM_GET_DEVICE
         # dtv_dmc_at_xxx.clocks[0].node = DM_GET_DEVICE(clock_controller_at_xxx)
         self.buf('void dm_populate_phandle_data(void) {\n')
-        for link in self._links:
-            self.buf('\t%s = DM_GET_DEVICE(%s);\n' %
-                     (link.var_node, link.dev_name))
         self.buf('}\n')
 
         self.out(''.join(self.get_buf()))
diff --git a/tools/dtoc/test_dtoc.py b/tools/dtoc/test_dtoc.py
index fee9853d034..8e16dc0f0fa 100755
--- a/tools/dtoc/test_dtoc.py
+++ b/tools/dtoc/test_dtoc.py
@@ -419,10 +419,10 @@ U_BOOT_DEVICE(phandle_target) = {
 /* Node /phandle-source index 2 */
 static struct dtd_source dtv_phandle_source = {
 \t.clocks\t\t\t= {
-\t\t\t{NULL, {}},
-\t\t\t{NULL, {11}},
-\t\t\t{NULL, {12, 13}},
-\t\t\t{NULL, {}},},
+\t\t\t{4, {}},
+\t\t\t{0, {11}},
+\t\t\t{1, {12, 13}},
+\t\t\t{4, {}},},
 };
 U_BOOT_DEVICE(phandle_source) = {
 \t.name\t\t= "source",
@@ -434,7 +434,7 @@ U_BOOT_DEVICE(phandle_source) = {
 /* Node /phandle-source2 index 3 */
 static struct dtd_source dtv_phandle_source2 = {
 \t.clocks\t\t\t= {
-\t\t\t{NULL, {}},},
+\t\t\t{4, {}},},
 };
 U_BOOT_DEVICE(phandle_source2) = {
 \t.name\t\t= "source",
@@ -444,11 +444,6 @@ U_BOOT_DEVICE(phandle_source2) = {
 };
 
 void dm_populate_phandle_data(void) {
-\tdtv_phandle_source.clocks[0].node = DM_GET_DEVICE(phandle_target);
-\tdtv_phandle_source.clocks[1].node = DM_GET_DEVICE(phandle2_target);
-\tdtv_phandle_source.clocks[2].node = DM_GET_DEVICE(phandle3_target);
-\tdtv_phandle_source.clocks[3].node = DM_GET_DEVICE(phandle_target);
-\tdtv_phandle_source2.clocks[0].node = DM_GET_DEVICE(phandle_target);
 }
 ''', data)
 
@@ -489,7 +484,7 @@ U_BOOT_DEVICE(phandle_target) = {
 /* Node /phandle-source2 index 0 */
 static struct dtd_source dtv_phandle_source2 = {
 \t.clocks\t\t\t= {
-\t\t\t{NULL, {}},},
+\t\t\t{1, {}},},
 };
 U_BOOT_DEVICE(phandle_source2) = {
 \t.name\t\t= "source",
@@ -499,7 +494,6 @@ U_BOOT_DEVICE(phandle_source2) = {
 };
 
 void dm_populate_phandle_data(void) {
-\tdtv_phandle_source2.clocks[0].node = DM_GET_DEVICE(phandle_target);
 }
 ''', data)
 
@@ -547,10 +541,10 @@ U_BOOT_DEVICE(phandle_target) = {
 /* Node /phandle-source index 2 */
 static struct dtd_source dtv_phandle_source = {
 \t.cd_gpios\t\t= {
-\t\t\t{NULL, {}},
-\t\t\t{NULL, {11}},
-\t\t\t{NULL, {12, 13}},
-\t\t\t{NULL, {}},},
+\t\t\t{4, {}},
+\t\t\t{0, {11}},
+\t\t\t{1, {12, 13}},
+\t\t\t{4, {}},},
 };
 U_BOOT_DEVICE(phandle_source) = {
 \t.name\t\t= "source",
@@ -562,7 +556,7 @@ U_BOOT_DEVICE(phandle_source) = {
 /* Node /phandle-source2 index 3 */
 static struct dtd_source dtv_phandle_source2 = {
 \t.cd_gpios\t\t= {
-\t\t\t{NULL, {}},},
+\t\t\t{4, {}},},
 };
 U_BOOT_DEVICE(phandle_source2) = {
 \t.name\t\t= "source",
@@ -572,11 +566,6 @@ U_BOOT_DEVICE(phandle_source2) = {
 };
 
 void dm_populate_phandle_data(void) {
-\tdtv_phandle_source.cd_gpios[0].node = DM_GET_DEVICE(phandle_target);
-\tdtv_phandle_source.cd_gpios[1].node = DM_GET_DEVICE(phandle2_target);
-\tdtv_phandle_source.cd_gpios[2].node = DM_GET_DEVICE(phandle3_target);
-\tdtv_phandle_source.cd_gpios[3].node = DM_GET_DEVICE(phandle_target);
-\tdtv_phandle_source2.cd_gpios[0].node = DM_GET_DEVICE(phandle_target);
 }
 ''', data)
 
-- 
2.28.0.806.g8561365e88-goog

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

* [PATCH 19/20] dm: Don't allow U_BOOT_DEVICE() when of-platdata is used
  2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
                   ` (17 preceding siblings ...)
  2020-10-03 17:31 ` [PATCH 18/20] dm: Use driver_info index instead of pointer Simon Glass
@ 2020-10-03 17:31 ` Simon Glass
  2020-10-03 17:31 ` [PATCH 20/20] dm: doc: Update the of-platadata documentation Simon Glass
                   ` (19 subsequent siblings)
  38 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2020-10-03 17:31 UTC (permalink / raw)
  To: u-boot

With of-platdata, the devicetree is supposed to specify all the devices
in the system. So far this hasn't really mattered since of-platdata still
works correctly.

However, new of-platdata features rely on numbering the devices in a
particular order so that they can be referenced by a single integer. It is
tricky to implement this efficiently when other devices are present in the
build.

To address this, disable use of U_BOOT_DEVICE() when of-platdata is
enabled. This seems acceptable as it is not supposed to be used at all,
except in SPL/TPL, where of-platdata is the recommended approach.

This breaks one non-compliant boards at present: mx6cuboxi

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 include/dm/platdata.h      | 8 ++++++++
 tools/dtoc/dtb_platdata.py | 3 +++
 tools/dtoc/test_dtoc.py    | 3 +++
 3 files changed, 14 insertions(+)

diff --git a/include/dm/platdata.h b/include/dm/platdata.h
index f800a866dda..216efa8ef77 100644
--- a/include/dm/platdata.h
+++ b/include/dm/platdata.h
@@ -55,9 +55,17 @@ struct driver_rt {
  * NOTE: Avoid using these except in extreme circumstances, where device tree
  * is not feasible (e.g. serial driver in SPL where <8KB of SRAM is
  * available). U-Boot's driver model uses device tree for configuration.
+ *
+ * When of-platdata is in use, U_BOOT_DEVICE() cannot be used outside of the
+ * dt-platdata.c file created by dtoc
  */
+#if CONFIG_IS_ENABLED(OF_PLATDATA) && !defined(DT_PLATDATA_C)
+#define U_BOOT_DEVICE(__name)	_Static_assert(false, \
+	"Cannot use U_BOOT_DEVICE with of-platdata. Please use devicetree instead")
+#else
 #define U_BOOT_DEVICE(__name)						\
 	ll_entry_declare(struct driver_info, __name, driver_info)
+#endif
 
 /* Declare a list of devices. The argument is a driver_info[] array */
 #define U_BOOT_DEVICES(__name)						\
diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py
index 2be11fff6c2..9b27aecc140 100644
--- a/tools/dtoc/dtb_platdata.py
+++ b/tools/dtoc/dtb_platdata.py
@@ -673,6 +673,9 @@ class DtbPlatdata(object):
         information.
         """
         self.out_header()
+        self.out('/* Allow use of U_BOOT_DEVICE() in this file */\n')
+        self.out('#define DT_PLATDATA_C\n')
+        self.out('\n')
         self.out('#include <common.h>\n')
         self.out('#include <dm.h>\n')
         self.out('#include <dt-structs.h>\n')
diff --git a/tools/dtoc/test_dtoc.py b/tools/dtoc/test_dtoc.py
index 8e16dc0f0fa..a5836e04b7a 100755
--- a/tools/dtoc/test_dtoc.py
+++ b/tools/dtoc/test_dtoc.py
@@ -44,6 +44,9 @@ C_HEADER = '''/*
  * This file was generated by dtoc from a .dtb (device tree binary) file.
  */
 
+/* Allow use of U_BOOT_DEVICE() in this file */
+#define DT_PLATDATA_C
+
 #include <common.h>
 #include <dm.h>
 #include <dt-structs.h>
-- 
2.28.0.806.g8561365e88-goog

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

* [PATCH 20/20] dm: doc: Update the of-platadata documentation
  2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
                   ` (18 preceding siblings ...)
  2020-10-03 17:31 ` [PATCH 19/20] dm: Don't allow U_BOOT_DEVICE() when of-platdata is used Simon Glass
@ 2020-10-03 17:31 ` Simon Glass
  2020-10-27  1:01 ` [PATCH 05/20] dtoc: Fix widening of int to bytes Simon Glass
                   ` (18 subsequent siblings)
  38 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2020-10-03 17:31 UTC (permalink / raw)
  To: u-boot

Update this to incorporate the parent feature as well as other recent
developments.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 doc/driver-model/of-plat.rst | 42 ++++++++++++++++--------------------
 1 file changed, 19 insertions(+), 23 deletions(-)

diff --git a/doc/driver-model/of-plat.rst b/doc/driver-model/of-plat.rst
index 1e3fad137be..58481665cec 100644
--- a/doc/driver-model/of-plat.rst
+++ b/doc/driver-model/of-plat.rst
@@ -66,12 +66,6 @@ strictly necessary. Notable problems include:
      normally also supports device tree it must use #ifdef to separate
      out this code, since the structures are only available in SPL.
 
-   - Correct relations between nodes are not implemented. This means that
-     parent/child relations (like bus device iteration) do not work yet.
-     Some phandles (those that are recognised as such) are converted into
-     a pointer to struct driver_info. This pointer can be used to access
-     the referenced device.
-
 
 How it works
 ------------
@@ -134,10 +128,14 @@ the following C struct declaration:
             fdt32_t         vmmc_supply;
     };
 
-and the following device declaration:
+and the following device declarations:
 
 .. code-block:: c
 
+    /* Node /clock-controller at ff760000 index 0 */
+    ...
+
+    /* Node /dwmmc at ff0c0000 index 2 */
     static struct dtd_rockchip_rk3288_dw_mshc dtv_dwmmc_at_ff0c0000 = {
             .fifo_depth             = 0x100,
             .cap_sd_highspeed       = true,
@@ -145,10 +143,10 @@ and the following device declaration:
             .clock_freq_min_max     = {0x61a80, 0x8f0d180},
             .vmmc_supply            = 0xb,
             .num_slots              = 0x1,
-            .clocks                 = {{NULL, 456},
-                                       {NULL, 68},
-                                       {NULL, 114},
-                                       {NULL, 118}},
+            .clocks                 = {{0, 456},
+                                       {0, 68},
+                                       {0, 114},
+                                       {0, 118}},
             .cap_mmc_highspeed      = true,
             .disable_wp             = true,
             .bus_width              = 0x4,
@@ -161,13 +159,10 @@ and the following device declaration:
             .name           = "rockchip_rk3288_dw_mshc",
             .platdata       = &dtv_dwmmc_at_ff0c0000,
             .platdata_size  = sizeof(dtv_dwmmc_at_ff0c0000),
+            .parent_idx     = -1,
     };
 
     void dm_populate_phandle_data(void) {
-            dtv_dwmmc_at_ff0c0000.clocks[0].node = DM_GET_DEVICE(clock_controller_at_ff760000);
-            dtv_dwmmc_at_ff0c0000.clocks[1].node = DM_GET_DEVICE(clock_controller_at_ff760000);
-            dtv_dwmmc_at_ff0c0000.clocks[2].node = DM_GET_DEVICE(clock_controller_at_ff760000);
-            dtv_dwmmc_at_ff0c0000.clocks[3].node = DM_GET_DEVICE(clock_controller_at_ff760000);
     }
 
 The device is then instantiated at run-time and the platform data can be
@@ -193,6 +188,13 @@ In order to make this a bit more flexible U_BOOT_DRIVER_ALIAS macro can be
 used to declare an alias for a driver name, typically a 'compatible' string.
 This macro produces no code, but it is by dtoc tool.
 
+The parent_idx is the index of the parent driver_info structure within its
+linker list (instantiated by the U_BOOT_DEVICE() macro). This is used to support
+dev_get_parent(). The dm_populate_phandle_data() is included to allow for
+fix-ups required by dtoc. It is not currently used. The values in 'clocks' are
+the index of the driver_info for the target device followed by any phandle
+arguments. This is used to support device_get_by_driver_info_idx().
+
 During the build process dtoc parses both U_BOOT_DRIVER and U_BOOT_DRIVER_ALIAS
 to build a list of valid driver names and driver aliases. If the 'compatible'
 string used for a device does not not match a valid driver name, it will be
@@ -339,12 +341,7 @@ spl/dt-platdata.c. It additionally contains the definition of
 dm_populate_phandle_data() which is responsible of filling the phandle
 information by adding references to U_BOOT_DEVICE by using DM_GET_DEVICE
 
-The beginnings of a libfdt Python module are provided. So far this only
-implements a subset of the features.
-
-The 'swig' tool is needed to build the libfdt Python module. If this is not
-found then the Python model is not used and a fallback is used instead, which
-makes use of fdtget.
+The pylibfdt Python module is used to access the devicetree.
 
 
 Credits
@@ -357,11 +354,10 @@ Future work
 -----------
 - Consider programmatically reading binding files instead of device tree
   contents
-- Complete the phandle feature
-- Move to using a full Python libfdt module
 
 
 .. Simon Glass <sjg@chromium.org>
 .. Google, Inc
 .. 6/6/16
 .. Updated Independence Day 2016
+.. Updated 1st October 2020
-- 
2.28.0.806.g8561365e88-goog

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

* [PATCH 05/20] dtoc: Fix widening of int to bytes
  2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
                   ` (19 preceding siblings ...)
  2020-10-03 17:31 ` [PATCH 20/20] dm: doc: Update the of-platadata documentation Simon Glass
@ 2020-10-27  1:01 ` Simon Glass
  2020-10-27  1:01 ` [PATCH 04/20] dm: core: Allow dm_warn() to be used in SPL Simon Glass
                   ` (17 subsequent siblings)
  38 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2020-10-27  1:01 UTC (permalink / raw)
  To: u-boot

At present an integer is converted to bytes incorrectly. The whole 32-bit
integer is inserted as the first element of the byte array, and the other
three bytes are skipped. This was not noticed because the unit test did
not check it, and the functional test was checking for wrong values.

Update the code to handle this as a special case. Add one more test to
cover all code paths.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 test/py/tests/test_ofplatdata.py |  2 +-
 tools/dtoc/dtoc_test_simple.dts  |  1 +
 tools/dtoc/fdt.py                |  9 +++++++++
 tools/dtoc/test_dtoc.py          |  4 +++-
 tools/dtoc/test_fdt.py           | 10 ++++++++++
 5 files changed, 24 insertions(+), 2 deletions(-)

Applied to u-boot-dm, thanks!

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

* [PATCH 04/20] dm: core: Allow dm_warn() to be used in SPL
  2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
                   ` (20 preceding siblings ...)
  2020-10-27  1:01 ` [PATCH 05/20] dtoc: Fix widening of int to bytes Simon Glass
@ 2020-10-27  1:01 ` Simon Glass
  2020-10-27  1:01 ` [PATCH 03/20] dtoc: Order the structures internally by name Simon Glass
                   ` (16 subsequent siblings)
  38 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2020-10-27  1:01 UTC (permalink / raw)
  To: u-boot

At present this option is disabled in SPL, meaning that warnings are not
displayed. It is sometimes useful to see warnings in SPL for debugging
purposes.

Add a new Kconfig option to permit this.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 drivers/core/Kconfig       | 18 ++++++++++++++++--
 drivers/core/util.c        |  2 +-
 include/config_uncmd_spl.h |  1 -
 include/dm/util.h          |  2 +-
 4 files changed, 18 insertions(+), 5 deletions(-)

Applied to u-boot-dm, thanks!

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

* [PATCH 03/20] dtoc: Order the structures internally by name
  2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
                   ` (21 preceding siblings ...)
  2020-10-27  1:01 ` [PATCH 04/20] dm: core: Allow dm_warn() to be used in SPL Simon Glass
@ 2020-10-27  1:01 ` Simon Glass
  2020-10-27  1:01 ` [PATCH 02/20] dtoc: Document the return value of scan_structs() Simon Glass
                   ` (15 subsequent siblings)
  38 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2020-10-27  1:01 UTC (permalink / raw)
  To: u-boot

At present the structures are written in name order, but parents have to
be written before their children, so the file does not end up being in
order. The order of nodes in _valid_nodes matches the order of the
devicetree.

Update the code so that _valid_nodes is in sorted order, by C name of
the structure. This allows us to assign a sequential ordering to each
U_BOOT_DEVICE() declaration.

U-Boot's linker lists are also ordered alphabetically, which means that
the order in the driver_info list will match the order used by dtoc. This
defines an index ('idx') for the U_BOOT_DEVICE declarations. They appear
in alphabetical order, numbered from 0 in _valid_nodes and in the
driver_info linker list.

Add a comment against each declaration, showing the idx value.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 tools/dtoc/dtb_platdata.py |  21 +++++---
 tools/dtoc/test_dtoc.py    | 105 ++++++++++++++++++++++++-------------
 2 files changed, 83 insertions(+), 43 deletions(-)

Applied to u-boot-dm, thanks!

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

* [PATCH 02/20] dtoc: Document the return value of scan_structs()
  2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
                   ` (22 preceding siblings ...)
  2020-10-27  1:01 ` [PATCH 03/20] dtoc: Order the structures internally by name Simon Glass
@ 2020-10-27  1:01 ` Simon Glass
  2020-10-27  1:01 ` [PATCH 01/20] sandbox: Drop ad-hoc device declarations in SPL Simon Glass
                   ` (14 subsequent siblings)
  38 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2020-10-27  1:01 UTC (permalink / raw)
  To: u-boot

Add documentation to this function as well as generate_structs(), where
the return value is ultimately passed in.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 tools/dtoc/dtb_platdata.py | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

Applied to u-boot-dm, thanks!

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

* [PATCH 01/20] sandbox: Drop ad-hoc device declarations in SPL
  2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
                   ` (23 preceding siblings ...)
  2020-10-27  1:01 ` [PATCH 02/20] dtoc: Document the return value of scan_structs() Simon Glass
@ 2020-10-27  1:01 ` Simon Glass
  2020-10-30  3:34 ` [PATCH 20/20] dm: doc: Update the of-platadata documentation Simon Glass
                   ` (13 subsequent siblings)
  38 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2020-10-27  1:01 UTC (permalink / raw)
  To: u-boot

Since sandbox's SPL is build with of-platadata, we should not use
U_BOOT_DEVICE() declarations as well. Drop them.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 board/sandbox/sandbox.c             | 2 ++
 drivers/serial/sandbox.c            | 3 +++
 drivers/sysreset/sysreset_sandbox.c | 2 ++
 3 files changed, 7 insertions(+)

Applied to u-boot-dm, thanks!

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

* [PATCH 20/20] dm: doc: Update the of-platadata documentation
  2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
                   ` (24 preceding siblings ...)
  2020-10-27  1:01 ` [PATCH 01/20] sandbox: Drop ad-hoc device declarations in SPL Simon Glass
@ 2020-10-30  3:34 ` Simon Glass
  2020-10-30  3:34 ` [PATCH 19/20] dm: Don't allow U_BOOT_DEVICE() when of-platdata is used Simon Glass
                   ` (12 subsequent siblings)
  38 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2020-10-30  3:34 UTC (permalink / raw)
  To: u-boot

Update this to incorporate the parent feature as well as other recent
developments.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 doc/driver-model/of-plat.rst | 42 ++++++++++++++++--------------------
 1 file changed, 19 insertions(+), 23 deletions(-)

Applied to u-boot-dm, thanks!

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

* [PATCH 19/20] dm: Don't allow U_BOOT_DEVICE() when of-platdata is used
  2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
                   ` (25 preceding siblings ...)
  2020-10-30  3:34 ` [PATCH 20/20] dm: doc: Update the of-platadata documentation Simon Glass
@ 2020-10-30  3:34 ` Simon Glass
  2020-10-30  3:34 ` [PATCH 18/20] dm: Use driver_info index instead of pointer Simon Glass
                   ` (11 subsequent siblings)
  38 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2020-10-30  3:34 UTC (permalink / raw)
  To: u-boot

With of-platdata, the devicetree is supposed to specify all the devices
in the system. So far this hasn't really mattered since of-platdata still
works correctly.

However, new of-platdata features rely on numbering the devices in a
particular order so that they can be referenced by a single integer. It is
tricky to implement this efficiently when other devices are present in the
build.

To address this, disable use of U_BOOT_DEVICE() when of-platdata is
enabled. This seems acceptable as it is not supposed to be used at all,
except in SPL/TPL, where of-platdata is the recommended approach.

This breaks one non-compliant boards at present: mx6cuboxi

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 include/dm/platdata.h      | 8 ++++++++
 tools/dtoc/dtb_platdata.py | 3 +++
 tools/dtoc/test_dtoc.py    | 3 +++
 3 files changed, 14 insertions(+)

Applied to u-boot-dm, thanks!

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

* [PATCH 18/20] dm: Use driver_info index instead of pointer
  2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
                   ` (26 preceding siblings ...)
  2020-10-30  3:34 ` [PATCH 19/20] dm: Don't allow U_BOOT_DEVICE() when of-platdata is used Simon Glass
@ 2020-10-30  3:34 ` Simon Glass
  2020-10-30  3:34 ` [PATCH 16/20] x86: apl: Enable SPI flash in TPL with APL_SPI_FLASH_BOOT Simon Glass
                   ` (10 subsequent siblings)
  38 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2020-10-30  3:34 UTC (permalink / raw)
  To: u-boot

At present we use a 'node' pointer in the of-platadata phandle_n_arg
structs. This is a pointer to the struct driver_info for a particular
device, and we can use it to obtain the struct udevice pointer itself.

Since we don't know the struct udevice pointer until it is allocated in
memory, we have to fix up the phandle_n_arg.node at runtime. This is
annoying since it requires that SPL's data is writable and adds a small
amount of extra (generated) code in the dm_populate_phandle_data()
function.

Now that we can find a driver_info by its index, it is easier to put the
index in the phandle_n_arg structures.

Update dtoc to do this, add a new device_get_by_driver_info_idx() to look
up a device by drive_info index and update the tests to match.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 drivers/clk/clk-uclass.c    |  3 +--
 drivers/core/device.c       | 11 +++++++++++
 drivers/misc/irq-uclass.c   |  2 +-
 drivers/mmc/fsl_esdhc_imx.c |  7 ++-----
 include/dm/device.h         | 14 ++++++++++++++
 include/dt-structs.h        |  6 +++---
 test/dm/of_platdata.c       | 10 +++++-----
 test/dm/test-main.c         | 24 ++++++++++++++++++++----
 test/py/tests/test_spl.py   |  5 ++---
 tools/dtoc/dtb_platdata.py  | 20 ++++----------------
 tools/dtoc/test_dtoc.py     | 33 +++++++++++----------------------
 11 files changed, 74 insertions(+), 61 deletions(-)

Applied to u-boot-dm, thanks!

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

* [PATCH 17/20] x86: apl: Take advantage of the of-platdata parent support
  2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
                   ` (28 preceding siblings ...)
  2020-10-30  3:34 ` [PATCH 16/20] x86: apl: Enable SPI flash in TPL with APL_SPI_FLASH_BOOT Simon Glass
@ 2020-10-30  3:34 ` Simon Glass
  2020-10-30  3:34 ` [PATCH 15/20] dm: core: Convert #ifdef to if() in root.c Simon Glass
                   ` (8 subsequent siblings)
  38 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2020-10-30  3:34 UTC (permalink / raw)
  To: u-boot

Now that parent devices are supported with of-platadata, we don't need the
messy code to fix up the parent pointers and allocations on Apollo Lake.
Put the code behind a condition.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 arch/x86/cpu/apollolake/spl.c |  3 ++-
 drivers/misc/p2sb-uclass.c    | 27 ++++++++++++++-------------
 2 files changed, 16 insertions(+), 14 deletions(-)

Applied to u-boot-dm, thanks!

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

* [PATCH 16/20] x86: apl: Enable SPI flash in TPL with APL_SPI_FLASH_BOOT
  2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
                   ` (27 preceding siblings ...)
  2020-10-30  3:34 ` [PATCH 18/20] dm: Use driver_info index instead of pointer Simon Glass
@ 2020-10-30  3:34 ` Simon Glass
  2020-10-30  3:34 ` [PATCH 17/20] x86: apl: Take advantage of the of-platdata parent support Simon Glass
                   ` (9 subsequent siblings)
  38 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2020-10-30  3:34 UTC (permalink / raw)
  To: u-boot

At present, enabling CONFIG_APL_SPI_FLASH_BOOT does not build since SPI
and SPI flash are not enabled for TPL. Add a condition to fix this and
tidy up a build warning in the SPI-flash driver.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 arch/x86/cpu/apollolake/Kconfig | 2 ++
 drivers/spi/ich.c               | 4 +++-
 2 files changed, 5 insertions(+), 1 deletion(-)

Applied to u-boot-dm, thanks!

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

* [PATCH 15/20] dm: core: Convert #ifdef to if() in root.c
  2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
                   ` (29 preceding siblings ...)
  2020-10-30  3:34 ` [PATCH 17/20] x86: apl: Take advantage of the of-platdata parent support Simon Glass
@ 2020-10-30  3:34 ` Simon Glass
  2020-10-30  3:34 ` [PATCH 14/20] dm: Add a test for of-platdata parent information Simon Glass
                   ` (7 subsequent siblings)
  38 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2020-10-30  3:34 UTC (permalink / raw)
  To: u-boot

Convert a few conditions to use compile-time checks to reduce the number
of build paths.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 drivers/core/root.c | 18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)

Applied to u-boot-dm, thanks!

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

* [PATCH 13/20] dm: Support parent devices with of-platdata
  2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
                   ` (31 preceding siblings ...)
  2020-10-30  3:34 ` [PATCH 14/20] dm: Add a test for of-platdata parent information Simon Glass
@ 2020-10-30  3:34 ` Simon Glass
  2020-10-30  3:34 ` [PATCH 12/20] sandbox: Fix up building for of-platdata Simon Glass
                   ` (5 subsequent siblings)
  38 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2020-10-30  3:34 UTC (permalink / raw)
  To: u-boot

At present of-platdata does not provide parent information. But this is
useful for I2C devices, for example, since it allows them to determine
which bus they are on.

Add support for setting the parent correctly, by storing the parent
driver_info index in dtoc and reading this in lists_bind_drivers(). This
needs multiple passes since we must process children after their parents
already have been bound.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 drivers/core/lists.c       | 54 ++++++++++++++++++++++++++++++++++++--
 dts/Kconfig                | 18 +++++++++++++
 include/dm/platdata.h      | 10 ++++++-
 tools/dtoc/dtb_platdata.py |  4 +++
 tools/dtoc/test_dtoc.py    | 33 +++++++++++++++++++++++
 5 files changed, 116 insertions(+), 3 deletions(-)

Applied to u-boot-dm, thanks!

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

* [PATCH 14/20] dm: Add a test for of-platdata parent information
  2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
                   ` (30 preceding siblings ...)
  2020-10-30  3:34 ` [PATCH 15/20] dm: core: Convert #ifdef to if() in root.c Simon Glass
@ 2020-10-30  3:34 ` Simon Glass
  2020-10-30  3:34 ` [PATCH 13/20] dm: Support parent devices with of-platdata Simon Glass
                   ` (6 subsequent siblings)
  38 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2020-10-30  3:34 UTC (permalink / raw)
  To: u-boot

Add a simple test that we can obtain the correct parent for an I2C
device. This requires updating the driver names to match the compatible
strings, adding them to the devicetree and enabling a few options.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 arch/sandbox/dts/sandbox.dts  |  1 +
 arch/sandbox/dts/sandbox.dtsi |  1 +
 configs/sandbox_spl_defconfig |  4 +++-
 drivers/i2c/sandbox_i2c.c     |  4 ++--
 drivers/rtc/sandbox_rtc.c     |  4 ++--
 test/dm/of_platdata.c         | 15 +++++++++++++++
 6 files changed, 24 insertions(+), 5 deletions(-)

Applied to u-boot-dm, thanks!

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

* [PATCH 12/20] sandbox: Fix up building for of-platdata
  2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
                   ` (32 preceding siblings ...)
  2020-10-30  3:34 ` [PATCH 13/20] dm: Support parent devices with of-platdata Simon Glass
@ 2020-10-30  3:34 ` Simon Glass
  2020-10-30  3:34 ` [PATCH 11/20] dm: Use an allocated array for run-time device info Simon Glass
                   ` (4 subsequent siblings)
  38 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2020-10-30  3:34 UTC (permalink / raw)
  To: u-boot

There is no devicetree with of-platdata. Update a few uclasses to allow
them to be built for sandbox_spl. Also drop the i2c-gpio from SPL to avoid
build errors, since it does not support of-platdata.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 drivers/i2c/Makefile          | 2 +-
 drivers/i2c/i2c-emul-uclass.c | 2 ++
 drivers/rtc/rtc-uclass.c      | 2 ++
 3 files changed, 5 insertions(+), 1 deletion(-)

Applied to u-boot-dm, thanks!

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

* [PATCH 11/20] dm: Use an allocated array for run-time device info
  2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
                   ` (33 preceding siblings ...)
  2020-10-30  3:34 ` [PATCH 12/20] sandbox: Fix up building for of-platdata Simon Glass
@ 2020-10-30  3:34 ` Simon Glass
  2020-10-30  3:34 ` [PATCH 10/20] dm: test: Add a test for of-platdata phandles Simon Glass
                   ` (3 subsequent siblings)
  38 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2020-10-30  3:34 UTC (permalink / raw)
  To: u-boot

At present we update the driver_info struct with a pointer to the device
that it created (i.e. caused to be bound). This works fine when U-Boot SPL
is stored in read-write memory. But on some platforms, such as Intel
Apollo Lake, it is not possible to update the data memory.

In any case, it is bad form to put this information in a structure that is
in the data region, since it expands the size of the binary.

Create a new driver_rt structure which holds runtime information about
drivers. Update the code to store the device pointer in this instead.
Also update the test check that this works.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 drivers/core/device.c             | 11 ++++++-----
 drivers/core/lists.c              | 16 +++++++++++-----
 drivers/core/root.c               | 11 +++++++++++
 include/asm-generic/global_data.h | 13 +++++++++++++
 include/dm/device-internal.h      |  2 +-
 include/dm/platdata.h             | 14 ++++++++++++--
 test/dm/of_platdata.c             | 19 ++++++++++---------
 7 files changed, 64 insertions(+), 22 deletions(-)

Applied to u-boot-dm, thanks!

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

* [PATCH 10/20] dm: test: Add a test for of-platdata phandles
  2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
                   ` (34 preceding siblings ...)
  2020-10-30  3:34 ` [PATCH 11/20] dm: Use an allocated array for run-time device info Simon Glass
@ 2020-10-30  3:34 ` Simon Glass
  2020-10-30  3:34 ` [PATCH 07/20] sandbox: Allow selection of SPL unit tests Simon Glass
                   ` (2 subsequent siblings)
  38 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2020-10-30  3:34 UTC (permalink / raw)
  To: u-boot

We have a test in dtoc for this feature, but not one in U-Boot itself.
Add a simple test that checks that the information comes through
correctly.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 arch/sandbox/dts/sandbox.dtsi | 26 ++++++++++++++++++++++++
 configs/sandbox_spl_defconfig |  1 +
 drivers/clk/clk_fixed_rate.c  |  4 ++--
 drivers/clk/clk_sandbox.c     |  4 ++--
 test/dm/of_platdata.c         | 37 +++++++++++++++++++++++++++++++++++
 5 files changed, 68 insertions(+), 4 deletions(-)

Applied to u-boot-dm, thanks!

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

* [PATCH 09/20] dm: test: Add a check that all devices have a dev value
  2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
                   ` (36 preceding siblings ...)
  2020-10-30  3:34 ` [PATCH 07/20] sandbox: Allow selection of SPL unit tests Simon Glass
@ 2020-10-30  3:34 ` Simon Glass
  2020-10-30  3:34 ` [PATCH 06/20] dm: Add a C test for of-platdata properties Simon Glass
  38 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2020-10-30  3:34 UTC (permalink / raw)
  To: u-boot

With of-platdata, the driver_info struct is updated with the device
pointer when it is bound. This makes it easy for a device to be found by
its driver info with the device_get_by_driver_info() function.

Add a test that all devices (except the root device) have such an entry.
Fix a bug that the function does not set *devp to NULL on failure, which
the documentation asserts.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 drivers/core/device.c |  1 +
 test/dm/of_platdata.c | 81 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 82 insertions(+)

Applied to u-boot-dm, thanks!

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

* [PATCH 07/20] sandbox: Allow selection of SPL unit tests
  2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
                   ` (35 preceding siblings ...)
  2020-10-30  3:34 ` [PATCH 10/20] dm: test: Add a test for of-platdata phandles Simon Glass
@ 2020-10-30  3:34 ` Simon Glass
  2020-10-30  3:34 ` [PATCH 09/20] dm: test: Add a check that all devices have a dev value Simon Glass
  2020-10-30  3:34 ` [PATCH 06/20] dm: Add a C test for of-platdata properties Simon Glass
  38 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2020-10-30  3:34 UTC (permalink / raw)
  To: u-boot

Now that we have more than one test, add a way to select the test to run.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 arch/sandbox/cpu/spl.c           | 2 +-
 arch/sandbox/cpu/start.c         | 9 +++++++++
 arch/sandbox/include/asm/state.h | 1 +
 3 files changed, 11 insertions(+), 1 deletion(-)

Applied to u-boot-dm, thanks!

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

* [PATCH 06/20] dm: Add a C test for of-platdata properties
  2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
                   ` (37 preceding siblings ...)
  2020-10-30  3:34 ` [PATCH 09/20] dm: test: Add a check that all devices have a dev value Simon Glass
@ 2020-10-30  3:34 ` Simon Glass
  38 siblings, 0 replies; 43+ messages in thread
From: Simon Glass @ 2020-10-30  3:34 UTC (permalink / raw)
  To: u-boot

At present properties are tested in a roundabout way. The driver's probe()
method writes out the values of the properties and the Python test checks
the output from U-Boot SPL.

Add a C test which checks these values more directly.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 test/dm/of_platdata.c | 69 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 69 insertions(+)

Applied to u-boot-dm, thanks!

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

* [PATCH 15/20] dm: core: Convert #ifdef to if() in root.c
  2020-10-03 17:31 ` [PATCH 15/20] dm: core: Convert #ifdef to if() in root.c Simon Glass
@ 2020-11-04 12:55   ` Michal Simek
  2020-11-04 13:59     ` Tom Rini
  0 siblings, 1 reply; 43+ messages in thread
From: Michal Simek @ 2020-11-04 12:55 UTC (permalink / raw)
  To: u-boot

Hi Simon,

so 3. 10. 2020 v 19:35 odes?latel Simon Glass <sjg@chromium.org> napsal:
>
> Convert a few conditions to use compile-time checks to reduce the number
> of build paths.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
>  drivers/core/root.c | 18 +++++++-----------
>  1 file changed, 7 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/core/root.c b/drivers/core/root.c
> index e8df5aebe84..5f10d7a39c7 100644
> --- a/drivers/core/root.c
> +++ b/drivers/core/root.c
> @@ -50,7 +50,6 @@ void dm_fixup_for_gd_move(struct global_data *new_gd)
>         }
>  }
>
> -#if defined(CONFIG_NEEDS_MANUAL_RELOC)
>  void fix_drivers(void)
>  {
>         struct driver *drv =
> @@ -129,8 +128,6 @@ void fix_devices(void)
>         }
>  }
>
> -#endif
> -
>  int dm_init(bool of_live)
>  {
>         int ret;
> @@ -141,11 +138,11 @@ int dm_init(bool of_live)
>         }
>         INIT_LIST_HEAD(&DM_UCLASS_ROOT_NON_CONST);
>
> -#if defined(CONFIG_NEEDS_MANUAL_RELOC)
> -       fix_drivers();
> -       fix_uclass();
> -       fix_devices();
> -#endif
> +       if (IS_ENABLED(CONFIG_NEEDS_MANUAL_RELOC)) {
> +               fix_drivers();
> +               fix_uclass();
> +               fix_devices();
> +       }

This change is causing a hang on the Microblaze system.
CONFIG_NEEDS_MANUAL_RELOC is out of Kconfig that's why likely this
condition is not handled properly.

U-Boot 2021.01-rc1-00211-g63677927bf26-dirty (Nov 04 2020 - 13:46:33 +0100)

Model: Xilinx MicroBlaze
DRAM:  1 GiB
Error binding driver 'axi_emac': -12
Error binding driver 'xlnx_gpio': -12
Error binding driver 'xlnx_gpio': -12
Error binding driver 'xlnx_gpio': -12
Error binding driver 'xlnx_gpio': -12
Error binding driver 'xlnx_gpio': -12
Error binding driver 'ns16550_serial': -12
Error binding driver 'gpio_restart': -12
Some drivers failed to bind
Error binding driver 'simple_bus': -12
Some drivers failed to bind
initcall sequence bffeec9c failed at call 85016230 (err=-12)
### ERROR ### Please RESET the board ###

Thanks,
Michal

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

* [PATCH 15/20] dm: core: Convert #ifdef to if() in root.c
  2020-11-04 12:55   ` Michal Simek
@ 2020-11-04 13:59     ` Tom Rini
  2020-11-04 14:33       ` Michal Simek
  0 siblings, 1 reply; 43+ messages in thread
From: Tom Rini @ 2020-11-04 13:59 UTC (permalink / raw)
  To: u-boot

On Wed, Nov 04, 2020 at 01:55:50PM +0100, Michal Simek wrote:
> Hi Simon,
> 
> so 3. 10. 2020 v 19:35 odes?latel Simon Glass <sjg@chromium.org> napsal:
> >
> > Convert a few conditions to use compile-time checks to reduce the number
> > of build paths.
> >
> > Signed-off-by: Simon Glass <sjg@chromium.org>
> > ---
> >
> >  drivers/core/root.c | 18 +++++++-----------
> >  1 file changed, 7 insertions(+), 11 deletions(-)
> >
> > diff --git a/drivers/core/root.c b/drivers/core/root.c
> > index e8df5aebe84..5f10d7a39c7 100644
> > --- a/drivers/core/root.c
> > +++ b/drivers/core/root.c
> > @@ -50,7 +50,6 @@ void dm_fixup_for_gd_move(struct global_data *new_gd)
> >         }
> >  }
> >
> > -#if defined(CONFIG_NEEDS_MANUAL_RELOC)
> >  void fix_drivers(void)
> >  {
> >         struct driver *drv =
> > @@ -129,8 +128,6 @@ void fix_devices(void)
> >         }
> >  }
> >
> > -#endif
> > -
> >  int dm_init(bool of_live)
> >  {
> >         int ret;
> > @@ -141,11 +138,11 @@ int dm_init(bool of_live)
> >         }
> >         INIT_LIST_HEAD(&DM_UCLASS_ROOT_NON_CONST);
> >
> > -#if defined(CONFIG_NEEDS_MANUAL_RELOC)
> > -       fix_drivers();
> > -       fix_uclass();
> > -       fix_devices();
> > -#endif
> > +       if (IS_ENABLED(CONFIG_NEEDS_MANUAL_RELOC)) {
> > +               fix_drivers();
> > +               fix_uclass();
> > +               fix_devices();
> > +       }
> 
> This change is causing a hang on the Microblaze system.
> CONFIG_NEEDS_MANUAL_RELOC is out of Kconfig that's why likely this
> condition is not handled properly.

Can you do the migration or should I?  It looks like just adding to the
top-level Kconfig and select'ing for microblaze/m68k.

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 659 bytes
Desc: not available
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20201104/81531075/attachment.sig>

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

* [PATCH 15/20] dm: core: Convert #ifdef to if() in root.c
  2020-11-04 13:59     ` Tom Rini
@ 2020-11-04 14:33       ` Michal Simek
  0 siblings, 0 replies; 43+ messages in thread
From: Michal Simek @ 2020-11-04 14:33 UTC (permalink / raw)
  To: u-boot

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,

On 04. 11. 20 14:59, Tom Rini wrote:
> On Wed, Nov 04, 2020 at 01:55:50PM +0100, Michal Simek wrote:
>> Hi Simon,
>>
>> so 3. 10. 2020 v 19:35 odes?latel Simon Glass <sjg@chromium.org>
>> napsal:
>>>
>>> Convert a few conditions to use compile-time checks to reduce
>>> the number of build paths.
>>>
>>> Signed-off-by: Simon Glass <sjg@chromium.org> ---
>>>
>>> drivers/core/root.c | 18 +++++++----------- 1 file changed, 7
>>> insertions(+), 11 deletions(-)
>>>
>>> diff --git a/drivers/core/root.c b/drivers/core/root.c index
>>> e8df5aebe84..5f10d7a39c7 100644 --- a/drivers/core/root.c +++
>>> b/drivers/core/root.c @@ -50,7 +50,6 @@ void
>>> dm_fixup_for_gd_move(struct global_data *new_gd) } }
>>>
>>> -#if defined(CONFIG_NEEDS_MANUAL_RELOC) void fix_drivers(void)
>>> { struct driver *drv = @@ -129,8 +128,6 @@ void
>>> fix_devices(void) } }
>>>
>>> -#endif - int dm_init(bool of_live) { int ret; @@ -141,11
>>> +138,11 @@ int dm_init(bool of_live) }
>>> INIT_LIST_HEAD(&DM_UCLASS_ROOT_NON_CONST);
>>>
>>> -#if defined(CONFIG_NEEDS_MANUAL_RELOC) -       fix_drivers();
>>> -       fix_uclass(); -       fix_devices(); -#endif +       if
>>> (IS_ENABLED(CONFIG_NEEDS_MANUAL_RELOC)) { +
>>> fix_drivers(); +               fix_uclass(); +
>>> fix_devices(); +       }
>>
>> This change is causing a hang on the Microblaze system.
>> CONFIG_NEEDS_MANUAL_RELOC is out of Kconfig that's why likely
>> this condition is not handled properly.
>
> Can you do the migration or should I?  It looks like just adding to
> the top-level Kconfig and select'ing for microblaze/m68k.
>

Send a patch your way. Please review.

Thanks,
Michal
-----BEGIN PGP SIGNATURE-----

iF0EARECAB0WIQQbPNTMvXmYlBPRwx7KSWXLKUoMIQUCX6K7xQAKCRDKSWXLKUoM
ITb5AJ9nzJXtJkmxuKTc/C7zn6Y9onNNWgCdGw68CTEMEeuA9FkCjIJvV0F77U8=
=opbA
-----END PGP SIGNATURE-----

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

end of thread, other threads:[~2020-11-04 14:33 UTC | newest]

Thread overview: 43+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-03 17:31 [PATCH 00/20] dm: Enhance of-platdata to support parent devices Simon Glass
2020-10-03 17:31 ` [PATCH 01/20] sandbox: Drop ad-hoc device declarations in SPL Simon Glass
2020-10-03 17:31 ` [PATCH 02/20] dtoc: Document the return value of scan_structs() Simon Glass
2020-10-03 17:31 ` [PATCH 03/20] dtoc: Order the structures internally by name Simon Glass
2020-10-03 17:31 ` [PATCH 04/20] dm: core: Allow dm_warn() to be used in SPL Simon Glass
2020-10-03 17:31 ` [PATCH 05/20] dtoc: Fix widening of int to bytes Simon Glass
2020-10-03 17:31 ` [PATCH 06/20] dm: Add a C test for of-platdata properties Simon Glass
2020-10-03 17:31 ` [PATCH 07/20] sandbox: Allow selection of SPL unit tests Simon Glass
2020-10-03 17:31 ` [PATCH 08/20] dm: test: Drop of-platdata pytest Simon Glass
2020-10-03 17:31 ` [PATCH 09/20] dm: test: Add a check that all devices have a dev value Simon Glass
2020-10-03 17:31 ` [PATCH 10/20] dm: test: Add a test for of-platdata phandles Simon Glass
2020-10-03 17:31 ` [PATCH 11/20] dm: Use an allocated array for run-time device info Simon Glass
2020-10-03 17:31 ` [PATCH 12/20] sandbox: Fix up building for of-platdata Simon Glass
2020-10-03 17:31 ` [PATCH 13/20] dm: Support parent devices with of-platdata Simon Glass
2020-10-03 17:31 ` [PATCH 14/20] dm: Add a test for of-platdata parent information Simon Glass
2020-10-03 17:31 ` [PATCH 15/20] dm: core: Convert #ifdef to if() in root.c Simon Glass
2020-11-04 12:55   ` Michal Simek
2020-11-04 13:59     ` Tom Rini
2020-11-04 14:33       ` Michal Simek
2020-10-03 17:31 ` [PATCH 16/20] x86: apl: Enable SPI flash in TPL with APL_SPI_FLASH_BOOT Simon Glass
2020-10-03 17:31 ` [PATCH 17/20] x86: apl: Take advantage of the of-platdata parent support Simon Glass
2020-10-03 17:31 ` [PATCH 18/20] dm: Use driver_info index instead of pointer Simon Glass
2020-10-03 17:31 ` [PATCH 19/20] dm: Don't allow U_BOOT_DEVICE() when of-platdata is used Simon Glass
2020-10-03 17:31 ` [PATCH 20/20] dm: doc: Update the of-platadata documentation Simon Glass
2020-10-27  1:01 ` [PATCH 05/20] dtoc: Fix widening of int to bytes Simon Glass
2020-10-27  1:01 ` [PATCH 04/20] dm: core: Allow dm_warn() to be used in SPL Simon Glass
2020-10-27  1:01 ` [PATCH 03/20] dtoc: Order the structures internally by name Simon Glass
2020-10-27  1:01 ` [PATCH 02/20] dtoc: Document the return value of scan_structs() Simon Glass
2020-10-27  1:01 ` [PATCH 01/20] sandbox: Drop ad-hoc device declarations in SPL Simon Glass
2020-10-30  3:34 ` [PATCH 20/20] dm: doc: Update the of-platadata documentation Simon Glass
2020-10-30  3:34 ` [PATCH 19/20] dm: Don't allow U_BOOT_DEVICE() when of-platdata is used Simon Glass
2020-10-30  3:34 ` [PATCH 18/20] dm: Use driver_info index instead of pointer Simon Glass
2020-10-30  3:34 ` [PATCH 16/20] x86: apl: Enable SPI flash in TPL with APL_SPI_FLASH_BOOT Simon Glass
2020-10-30  3:34 ` [PATCH 17/20] x86: apl: Take advantage of the of-platdata parent support Simon Glass
2020-10-30  3:34 ` [PATCH 15/20] dm: core: Convert #ifdef to if() in root.c Simon Glass
2020-10-30  3:34 ` [PATCH 14/20] dm: Add a test for of-platdata parent information Simon Glass
2020-10-30  3:34 ` [PATCH 13/20] dm: Support parent devices with of-platdata Simon Glass
2020-10-30  3:34 ` [PATCH 12/20] sandbox: Fix up building for of-platdata Simon Glass
2020-10-30  3:34 ` [PATCH 11/20] dm: Use an allocated array for run-time device info Simon Glass
2020-10-30  3:34 ` [PATCH 10/20] dm: test: Add a test for of-platdata phandles Simon Glass
2020-10-30  3:34 ` [PATCH 07/20] sandbox: Allow selection of SPL unit tests Simon Glass
2020-10-30  3:34 ` [PATCH 09/20] dm: test: Add a check that all devices have a dev value Simon Glass
2020-10-30  3:34 ` [PATCH 06/20] dm: Add a C test for of-platdata properties Simon Glass

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.