From f7d367c2e66ec550976818b8297416f2e4e299ce Mon Sep 17 00:00:00 2001 From: Michal Suchanek Date: Sun, 25 Sep 2022 15:28:47 +0200 Subject: dm: doc: Fix serial howto u-boot,dm-pre-reloc typo In a couple of places the document says u-boot,pre-reloc but all examples show u-boot,dm-pre-reloc, use the latter consistently. Signed-off-by: Michal Suchanek Reviewed-by: Fabio Estevam Reviewed-by: Simon Glass --- doc/develop/driver-model/serial-howto.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/develop/driver-model/serial-howto.rst b/doc/develop/driver-model/serial-howto.rst index 9da0e57..5b1d57d 100644 --- a/doc/develop/driver-model/serial-howto.rst +++ b/doc/develop/driver-model/serial-howto.rst @@ -62,7 +62,7 @@ what you need. U-Boot automatically includes these files: see :ref:`dttweaks`. Here are some things you might need to consider: 1. The serial driver itself needs to be present before relocation, so that the - U-Boot banner appears. Make sure it has a u-boot,pre-reloc tag in the device + U-Boot banner appears. Make sure it has a u-boot,dm-pre-reloc tag in the device tree, so that the serial driver is bound when U-Boot starts. For example, on iMX8:: @@ -79,7 +79,7 @@ Here are some things you might need to consider: }; 2. If your serial port requires a particular pinmux configuration, you may need - a pinctrl driver. This needs to have a u-boot,pre-reloc tag also. Take care + a pinctrl driver. This needs to have a u-boot,dm-pre-reloc tag also. Take care that any subnodes have the same tag, if they are needed to make the correct pinctrl available. -- cgit v1.1 From d7e9de7ec1bb79261c08e7689a1856a464ee2443 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Tue, 27 Sep 2022 10:18:05 +0200 Subject: fdt_support: cosmetic: remove fdt_fixup_nor_flash_size prototype Remove prototype for the removed function fdt_fixup_nor_flash_size. This patch has no impact as the function is never used. Fixes: 98f705c9cefd ("powerpc: remove 4xx support") Signed-off-by: Patrick Delaunay Reviewed-by: Simon Glass --- include/fdt_support.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/fdt_support.h b/include/fdt_support.h index b838071..5638bd4 100644 --- a/include/fdt_support.h +++ b/include/fdt_support.h @@ -243,8 +243,6 @@ int fdt_increase_size(void *fdt, int add_len); int fdt_delete_disabled_nodes(void *blob); -int fdt_fixup_nor_flash_size(void *blob); - struct node_info; #if defined(CONFIG_FDT_FIXUP_PARTITIONS) void fdt_fixup_mtdparts(void *fdt, const struct node_info *node_info, -- cgit v1.1 From 1fcfadcb82a21af058baa5dea2b20883b8c388b8 Mon Sep 17 00:00:00 2001 From: Michal Suchanek Date: Tue, 27 Sep 2022 23:25:24 +0200 Subject: dm: pci: Fix doc typo first -> next pci_find_first_device description says it can be used for iteration with itself but it should really be with pci_find_next_device Signed-off-by: Michal Suchanek --- include/pci.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/pci.h b/include/pci.h index d7ed35d..c55d610 100644 --- a/include/pci.h +++ b/include/pci.h @@ -957,7 +957,7 @@ int pci_bus_find_devfn(const struct udevice *bus, pci_dev_t find_devfn, /** * pci_find_first_device() - return the first available PCI device * - * This function and pci_find_first_device() allow iteration through all + * This function and pci_find_next_device() allow iteration through all * available PCI devices on all buses. Assuming there are any, this will * return the first one. * -- cgit v1.1 From fc872ee84cd5dd3a74bf51ce6519377b0de4940f Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sat, 1 Oct 2022 15:00:21 +0200 Subject: x86: fix longjmp() implementation If longjmp(jmp_buf env, int val) is called with val = 0, the setjmp() macro must return 1. Signed-off-by: Heinrich Schuchardt Reviewed-by: Simon Glass --- arch/x86/cpu/i386/setjmp.S | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/x86/cpu/i386/setjmp.S b/arch/x86/cpu/i386/setjmp.S index 40b10dc..eceeafa 100644 --- a/arch/x86/cpu/i386/setjmp.S +++ b/arch/x86/cpu/i386/setjmp.S @@ -49,12 +49,17 @@ longjmp: xchgl %eax, %edx #else movl 4(%esp), %edx /* jmp_ptr address */ + movl 8(%esp), %eax /* Return value */ #endif movl (%edx), %ebx movl 4(%edx), %esp movl 8(%edx), %ebp movl 12(%edx), %esi movl 16(%edx), %edi + test %eax, %eax + jnz nz + inc %eax +nz: jmp *20(%edx) .size longjmp, .-longjmp -- cgit v1.1 From 95e7cafa8171397b5ef5d15ec4eac29ffa6fbe87 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sat, 1 Oct 2022 15:00:22 +0200 Subject: x86: provide typedef jmp_buf The jmp_buf type is required by the C99 specification. Defining it for x86 fixes building the longjmp unit test. Signed-off-by: Heinrich Schuchardt Reviewed-by: Simon Glass --- arch/x86/include/asm/setjmp.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/setjmp.h b/arch/x86/include/asm/setjmp.h index 49c36c1..15915d0 100644 --- a/arch/x86/include/asm/setjmp.h +++ b/arch/x86/include/asm/setjmp.h @@ -34,7 +34,9 @@ struct jmp_buf_data { #endif -int setjmp(struct jmp_buf_data *jmp_buf); -void longjmp(struct jmp_buf_data *jmp_buf, int val); +typedef struct jmp_buf_data jmp_buf[1]; + +int setjmp(jmp_buf env); +void longjmp(jmp_buf env, int val); #endif -- cgit v1.1 From 10e66449d7e8a6aaee69b9fd130a3f04ea7b6f57 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Mon, 3 Oct 2022 11:02:45 +0200 Subject: gpio-uclass: fix gpio lookup by label Matching anything that just happens to have the sought-for label as a prefix is wrong. For example, if the board designer has designated 10 lines for debug purposes, named "debug1" through "debug10", and we are looking up "debug1", if debug10 happens to be met first during the iteration we'd wrongly return that. In theory, this can break existing users that could rely on this quirk, but OTOH keeping the current broken semantics can cause a lot of grief for people hitting this in the future and not understanding why they don't find the line they expect. Considering how few in-tree defconfigs currently set DM_GPIO_LOOKUP_LABEL (ignoring sandbox, only four "real" boards), let's fix it before the use becomes more widespread. Signed-off-by: Rasmus Villemoes Reviewed-by: Simon Glass Reviewed-by: Heiko Schocher --- drivers/gpio/gpio-uclass.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c index a00880e..6503325 100644 --- a/drivers/gpio/gpio-uclass.c +++ b/drivers/gpio/gpio-uclass.c @@ -91,15 +91,13 @@ static int gpio_to_device(unsigned int gpio, struct gpio_desc *desc) static int dm_gpio_lookup_label(const char *name, struct gpio_dev_priv *uc_priv, ulong *offset) { - int len; int i; *offset = -1; - len = strlen(name); for (i = 0; i < uc_priv->gpio_count; i++) { if (!uc_priv->name[i]) continue; - if (!strncmp(name, uc_priv->name[i], len)) { + if (!strcmp(name, uc_priv->name[i])) { *offset = i; return 0; } -- cgit v1.1 From d13879211285d5cc5cfb727eb36b41da0111edf0 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 8 Oct 2022 21:33:20 -0600 Subject: dm: core: Fix lists_bind_fdt() using non-existent of_match The call to device_bind_with_driver_data() passes id->data but if the entry has no of_match then the id has not been set by the selected driver. Normally this passes unnoticed since a previous driver likely had an of_match value, so the id is set to that. Of course it is not correct to pass the id->data from a different driver. With clang-14 the driver ordering is such that the id is never actually set in the 'bind /usb@1 usb_ether' line in test_bind_unbind_with_node() thus causing a crash. Fix this by passing 0 if the of_match for a driver does not exist. Signed-off-by: Simon Glass --- drivers/core/lists.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/core/lists.c b/drivers/core/lists.c index c49695b..3878957 100644 --- a/drivers/core/lists.c +++ b/drivers/core/lists.c @@ -222,6 +222,7 @@ int lists_bind_fdt(struct udevice *parent, ofnode node, struct udevice **devp, log_debug(" - attempt to match compatible string '%s'\n", compat); + id = NULL; for (entry = driver; entry != driver + n_ents; entry++) { if (drv) { if (drv != entry) @@ -250,7 +251,8 @@ int lists_bind_fdt(struct udevice *parent, ofnode node, struct udevice **devp, entry->name, entry->of_match->compatible, id->compatible); ret = device_bind_with_driver_data(parent, entry, name, - id->data, node, &dev); + id ? id->data : 0, node, + &dev); if (ret == -ENODEV) { log_debug("Driver '%s' refuses to bind\n", entry->name); continue; -- cgit v1.1 From 5fe72d968f6c388b41202c54c563815f2db977fc Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 8 Oct 2022 21:33:21 -0600 Subject: event: Drop the path when checking event-list filenames This path does not seem to be present in clang-14 for some reason. Relax the regular expression so that the test works, at least for non-LTO. Signed-off-by: Simon Glass --- test/py/tests/test_event_dump.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/py/tests/test_event_dump.py b/test/py/tests/test_event_dump.py index e63c25d..674df2e 100644 --- a/test/py/tests/test_event_dump.py +++ b/test/py/tests/test_event_dump.py @@ -16,7 +16,7 @@ def test_event_dump(u_boot_console): out = util.run_and_log(cons, ['scripts/event_dump.py', sandbox]) expect = '''.*Event type Id Source location -------------------- ------------------------------ ------------------------------ -EVT_FT_FIXUP bootmeth_vbe_ft_fixup .*boot/vbe_fixup.c:.* -EVT_FT_FIXUP bootmeth_vbe_simple_ft_fixup .*boot/vbe_simple.c:.* -EVT_MISC_INIT_F sandbox_misc_init_f .*arch/sandbox/cpu/start.c:''' +EVT_FT_FIXUP bootmeth_vbe_ft_fixup .*vbe_fixup.c:.* +EVT_FT_FIXUP bootmeth_vbe_simple_ft_fixup .*vbe_simple.c:.* +EVT_MISC_INIT_F sandbox_misc_init_f .*start.c:''' assert re.match(expect, out, re.MULTILINE) is not None -- cgit v1.1 From 7e8d3e1b016faa50cbd1c0ef8ff3d12014ab2e7a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 8 Oct 2022 21:33:22 -0600 Subject: test: Drop unwanted option in event_dump.py This option is not used. Drop it. Signed-off-by: Simon Glass --- scripts/event_dump.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/scripts/event_dump.py b/scripts/event_dump.py index 6aadddf..d87823f 100755 --- a/scripts/event_dump.py +++ b/scripts/event_dump.py @@ -108,8 +108,6 @@ def main(argv): parser.add_argument('elf', type=str, help='ELF file to decode') parser.add_argument('-e', '--endian', type=str, default='auto', help='Big-endian image') - parser.add_argument('-t', '--test', action='store_true', - help='Big-endian image') args = parser.parse_args(argv) show_event_spy_list(args.elf, args.endian) -- cgit v1.1 From c977b184350479b8c43a0e002eaf2b13b510ba4f Mon Sep 17 00:00:00 2001 From: Michal Suchanek Date: Thu, 13 Oct 2022 22:39:51 +0200 Subject: libfdt: Fix invalid version warning python does not like the u-boot- prefix in the version, drop it. /usr/lib/python3.10/site-packages/setuptools/dist.py:544: UserWarning: The version specified ('u-boot-2022.10') is an invalid version, this may not work as expected with newer versions of setuptools, pip, and PyPI. Please see PEP 440 for more details. Signed-off-by: Michal Suchanek Reviewed-by: Simon Glass --- scripts/dtc/pylibfdt/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/dtc/pylibfdt/Makefile b/scripts/dtc/pylibfdt/Makefile index 493995e..a7579f0 100644 --- a/scripts/dtc/pylibfdt/Makefile +++ b/scripts/dtc/pylibfdt/Makefile @@ -17,7 +17,7 @@ quiet_cmd_pymod = PYMOD $@ cmd_pymod = unset CROSS_COMPILE; unset CFLAGS; \ CC="$(HOSTCC)" LDSHARED="$(HOSTCC) -shared " \ LDFLAGS="$(HOSTLDFLAGS)" \ - VERSION="u-boot-$(UBOOTVERSION)" \ + VERSION="$(UBOOTVERSION)" \ CPPFLAGS="$(HOSTCFLAGS) -I$(LIBFDT_srcdir)" OBJDIR=$(obj) \ SOURCES="$(PYLIBFDT_srcs)" \ SWIG_OPTS="-I$(LIBFDT_srcdir) -I$(LIBFDT_srcdir)/.." \ -- cgit v1.1 From 7d01bb1c5a1daef0187c9ea276bde19a8d0e7fde Mon Sep 17 00:00:00 2001 From: Michal Suchanek Date: Thu, 13 Oct 2022 22:43:41 +0200 Subject: libfdt: Fix build with python 3.10 Python 3.10 requires defining PY_SSIZE_T_CLEAN. This will be fixed in swig 4.10 but it is not clear when it will be released. There was a warning since python 3.8. Link: https://github.com/swig/swig/pull/2277 Signed-off-by: Michal Suchanek Reviewed-by: Simon Glass --- scripts/dtc/pylibfdt/libfdt.i_shipped | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/dtc/pylibfdt/libfdt.i_shipped b/scripts/dtc/pylibfdt/libfdt.i_shipped index 27c29ea..56cc5d4 100644 --- a/scripts/dtc/pylibfdt/libfdt.i_shipped +++ b/scripts/dtc/pylibfdt/libfdt.i_shipped @@ -7,6 +7,10 @@ %module libfdt +%begin %{ +#define PY_SSIZE_T_CLEAN +%} + %include %{ -- cgit v1.1 From 6792bd999b03bef74fc0762510f8a98eebb8c161 Mon Sep 17 00:00:00 2001 From: William Zhang Date: Fri, 14 Oct 2022 11:04:55 -0700 Subject: dm: tpl: Add fdt address translation support in TPL This is needed in the platforms that use "ranges" node property for address translation in their dts for TPL. Signed-off-by: William Zhang Reviewed-by: Simon Glass --- drivers/core/Kconfig | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig index 0dc442b..b79e99b 100644 --- a/drivers/core/Kconfig +++ b/drivers/core/Kconfig @@ -350,6 +350,20 @@ config SPL_OF_TRANSLATE used for the address translation. This function is faster and smaller in size than fdt_translate_address(). +config TPL_OF_TRANSLATE + bool "Translate addresses using fdt_translate_address in TPL" + depends on TPL_DM && TPL_OF_CONTROL + help + If this option is enabled, the reg property will be translated + using the fdt_translate_address() function. This is necessary + on some platforms (e.g. MVEBU) using complex "ranges" + properties in many nodes. As this translation is not handled + correctly in the default simple_bus_translate() function. + + If this option is not enabled, simple_bus_translate() will be + used for the address translation. This function is faster and + smaller in size than fdt_translate_address() + config VPL_OF_TRANSLATE bool "Translate addresses using fdt_translate_address in SPL" depends on SPL_DM && VPL_OF_CONTROL -- cgit v1.1 From 5bde2e06caba0f072d0d3788fafcedafd11ae28a Mon Sep 17 00:00:00 2001 From: Michal Suchanek Date: Fri, 14 Oct 2022 22:52:33 +0200 Subject: tests: Build correct sandbox configuration on 32bit Currently sandbox configuration defautls to 64bit and there is no automation for building 32bit sandbox on 32bit hosts. Use _LP64 macro as heuristic for detecting 64bit targets. Signed-off-by: Michal Suchanek Reviewed-by: Simon Glass --- arch/sandbox/Kconfig | 18 +++--------------- scripts/Kconfig.include | 4 ++++ 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/arch/sandbox/Kconfig b/arch/sandbox/Kconfig index 852a7c8..35508c6 100644 --- a/arch/sandbox/Kconfig +++ b/arch/sandbox/Kconfig @@ -13,7 +13,7 @@ config SYS_CPU config SANDBOX64 bool "Use 64-bit addresses" select PHYS_64BIT - select HOST_64BIT + depends on HOST_64BIT config SANDBOX_RAM_SIZE_MB int "RAM size in MiB" @@ -41,23 +41,11 @@ config SYS_CONFIG_NAME default "sandbox_spl" if SANDBOX_SPL default "sandbox" if !SANDBOX_SPL -choice - prompt "Run sandbox on 32/64-bit host" - default HOST_64BIT - help - Sandbox can be built on 32-bit and 64-bit hosts. - The default is to build on a 64-bit host and run - on a 64-bit host. If you want to run sandbox on - a 32-bit host, change it here. - config HOST_32BIT - bool "32-bit host" - depends on !PHYS_64BIT + def_bool ! $(cc-define,_LP64) config HOST_64BIT - bool "64-bit host" - -endchoice + def_bool $(cc-define,_LP64) config SANDBOX_CRASH_RESET bool "Reset on crash" diff --git a/scripts/Kconfig.include b/scripts/Kconfig.include index dad5583..b7598ca 100644 --- a/scripts/Kconfig.include +++ b/scripts/Kconfig.include @@ -22,6 +22,10 @@ success = $(if-success,$(1),y,n) # Return y if the compiler supports , n otherwise cc-option = $(success,$(CC) -Werror $(1) -E -x c /dev/null -o /dev/null) +# $(cc-define,) +# Return y if the compiler defines , n otherwise +cc-define = $(success,$(CC) -dM -E -x c /dev/null | grep -q '^#define \<$(1)\>') + # $(ld-option,) # Return y if the linker supports , n otherwise ld-option = $(success,$(LD) -v $(1)) -- cgit v1.1 From f29f98d1e40e6b4d9c723af503b20948aa482bf2 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sun, 16 Oct 2022 22:17:46 +0200 Subject: sandbox: typo Fictionnal %s/Fictionnal/Fictional/ Signed-off-by: Heinrich Schuchardt Reviewed-by: Simon Glass --- board/sandbox/sandbox.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/board/sandbox/sandbox.c b/board/sandbox/sandbox.c index ca9a2ca..38cfa08 100644 --- a/board/sandbox/sandbox.c +++ b/board/sandbox/sandbox.c @@ -129,7 +129,7 @@ int extension_board_scan(struct list_head *extension_list) snprintf(extension->name, sizeof(extension->name), "extension board %d", i); snprintf(extension->owner, sizeof(extension->owner), "sandbox"); snprintf(extension->version, sizeof(extension->version), "1.1"); - snprintf(extension->other, sizeof(extension->other), "Fictionnal extension board"); + snprintf(extension->other, sizeof(extension->other), "Fictional extension board"); list_add_tail(&extension->list, extension_list); } -- cgit v1.1 From 3545e8595c944c893bc3fa64c8e4727c928cf892 Mon Sep 17 00:00:00 2001 From: Neha Malcom Francis Date: Mon, 17 Oct 2022 16:36:25 +0530 Subject: binman: Add support for symlinking images Adding support to symlink an image packaged using binman. Signed-off-by: Neha Malcom Francis Reviewed-by: Simon Glass --- tools/binman/binman.rst | 3 +++ tools/binman/ftest.py | 9 +++++++++ tools/binman/image.py | 6 ++++++ tools/binman/test/259_symlink.dts | 16 ++++++++++++++++ 4 files changed, 34 insertions(+) create mode 100644 tools/binman/test/259_symlink.dts diff --git a/tools/binman/binman.rst b/tools/binman/binman.rst index 4ee6f41..d8a3d77 100644 --- a/tools/binman/binman.rst +++ b/tools/binman/binman.rst @@ -780,6 +780,9 @@ align-default: This means that each section must specify its own default alignment, if required. +symlink: + Adds a symlink to the image with string given in the symlink property. + Examples of the above options can be found in the tests. See the tools/binman/test directory. diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 261107b..232ac2c 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -5995,6 +5995,15 @@ fdt fdtmap Extract the devicetree blob from the fdtmap self.assertIn('Expected __bss_size symbol in vpl/u-boot-vpl', str(e.exception)) + def testSymlink(self): + """Test that image files can be named""" + retcode = self._DoTestFile('259_symlink.dts', debug=True, map=True) + self.assertEqual(0, retcode) + image = control.images['test_image'] + fname = tools.get_output_filename('test_image.bin') + sname = tools.get_output_filename('symlink_to_test.bin') + self.assertTrue(os.path.islink(sname)) + self.assertEqual(os.readlink(sname), fname) if __name__ == "__main__": unittest.main() diff --git a/tools/binman/image.py b/tools/binman/image.py index afc4b4d..6d4bff5 100644 --- a/tools/binman/image.py +++ b/tools/binman/image.py @@ -38,6 +38,7 @@ class Image(section.Entry_section): repacked later test_section_timeout: Use a zero timeout for section multi-threading (for testing) + symlink: Name of symlink to image Args: copy_to_orig: Copy offset/size to orig_offset/orig_size after reading @@ -97,6 +98,7 @@ class Image(section.Entry_section): if filename: self._filename = filename self.allow_repack = fdt_util.GetBool(self._node, 'allow-repack') + self._symlink = fdt_util.GetString(self._node, 'symlink') @classmethod def FromFile(cls, fname): @@ -180,6 +182,10 @@ class Image(section.Entry_section): data = self.GetPaddedData() fd.write(data) tout.info("Wrote %#x bytes" % len(data)) + # Create symlink to file if symlink given + if self._symlink is not None: + sname = tools.get_output_filename(self._symlink) + os.symlink(fname, sname) def WriteMap(self): """Write a map of the image to a .map file diff --git a/tools/binman/test/259_symlink.dts b/tools/binman/test/259_symlink.dts new file mode 100644 index 0000000..2ee1f7f --- /dev/null +++ b/tools/binman/test/259_symlink.dts @@ -0,0 +1,16 @@ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + multiple-images; + test_image { + filename = "test_image.bin"; + symlink = "symlink_to_test.bin"; + u-boot { + }; + }; + }; +}; -- cgit v1.1 From 529b2c2d9c757b3ed7d898c90ab7611f1b0c9d0f Mon Sep 17 00:00:00 2001 From: Sughosh Ganu Date: Tue, 18 Oct 2022 14:17:25 +0530 Subject: thermal: sandbox: Enable thermal uclass for sandbox64 variant The sandbox64 variant is currently building the sandbox thermal driver but not the corresponding uclass driver. This results in the sandbox64 variant not booting with the test device tree. Enable building the thermal uclass for the sandbox64 variant as well. Also enable the temperature command to allow the test to be run on the sandbox64 variant. Signed-off-by: Sughosh Ganu Reviewed-by: Simon Glass --- configs/sandbox64_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig index 0475672..e28f1e8 100644 --- a/configs/sandbox64_defconfig +++ b/configs/sandbox64_defconfig @@ -54,6 +54,7 @@ CONFIG_CMD_PCI=y CONFIG_CMD_READ=y CONFIG_CMD_REMOTEPROC=y CONFIG_CMD_SPI=y +CONFIG_CMD_TEMPERATURE=y CONFIG_CMD_USB=y CONFIG_CMD_CAT=y CONFIG_CMD_WDT=y @@ -220,6 +221,7 @@ CONFIG_SYSINFO=y CONFIG_SYSINFO_SANDBOX=y CONFIG_SYSINFO_GPIO=y CONFIG_SYSRESET=y +CONFIG_DM_THERMAL=y CONFIG_TIMER=y CONFIG_TIMER_EARLY=y CONFIG_SANDBOX_TIMER=y -- cgit v1.1 From 6b08fb5cc44f8d32260a17a4f04c5bfa8dd5f18f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 30 Jul 2022 20:57:11 -0600 Subject: fdt: Move to setuptools The distutils package is deprecated. The upstream libfdt repo uses setuptools for building the pylibfdt module, so bring in that code, suitably modified for U-Boot. Also bring in the README. The modifications include setting the version correctly, making use of the environment variables provided by the Makefile and various tweaks to the directories. Note that the version omits the minus character at the start of EXTRAVERSION, since this creates a warning. The build is really just used within U-Boot itself, so it doesn't matter too much if the version matches upstream, or exactly matches U-Boot. Signed-off-by: Simon Glass --- scripts/dtc/README | 106 ++++++++++++++++++++++++++++++++++++++++++ scripts/dtc/pylibfdt/Makefile | 5 +- scripts/dtc/pylibfdt/setup.py | 57 +++++++++++++++++++---- 3 files changed, 158 insertions(+), 10 deletions(-) create mode 100644 scripts/dtc/README diff --git a/scripts/dtc/README b/scripts/dtc/README new file mode 100644 index 0000000..a48312a --- /dev/null +++ b/scripts/dtc/README @@ -0,0 +1,106 @@ +The source tree contains the Device Tree Compiler (dtc) toolchain for +working with device tree source and binary files and also libfdt, a +utility library for reading and manipulating the binary format. + +DTC and LIBFDT are maintained by: + +David Gibson +Jon Loeliger + + +Python library +-------------- + +A Python library is also available. To build this you will need to install +swig and Python development files. On Debian distributions: + + sudo apt-get install swig python3-dev + +The library provides an Fdt class which you can use like this: + +$ PYTHONPATH=../pylibfdt python3 +>>> import libfdt +>>> fdt = libfdt.Fdt(open('test_tree1.dtb', mode='rb').read()) +>>> node = fdt.path_offset('/subnode@1') +>>> print(node) +124 +>>> prop_offset = fdt.first_property_offset(node) +>>> prop = fdt.get_property_by_offset(prop_offset) +>>> print('%s=%s' % (prop.name, prop.as_str())) +compatible=subnode1 +>>> node2 = fdt.path_offset('/') +>>> print(fdt.getprop(node2, 'compatible').as_str()) +test_tree1 + +You will find tests in tests/pylibfdt_tests.py showing how to use each +method. Help is available using the Python help command, e.g.: + + $ cd pylibfdt + $ python3 -c "import libfdt; help(libfdt)" + +If you add new features, please check code coverage: + + $ sudo apt-get install python3-coverage + $ cd tests + # It's just 'coverage' on most other distributions + $ python3-coverage run pylibfdt_tests.py + $ python3-coverage html + # Open 'htmlcov/index.html' in your browser + + +The library can be installed with pip from a local source tree: + + pip install . [--user|--prefix=/path/to/install_dir] + +Or directly from a remote git repo: + + pip install git+git://git.kernel.org/pub/scm/utils/dtc/dtc.git@main + +The install depends on libfdt shared library being installed on the host system +first. Generally, using --user or --prefix is not necessary and pip will use the +default location for the Python installation which varies if the user is root or +not. + +You can also install everything via make if you like, but pip is recommended. + +To install both libfdt and pylibfdt you can use: + + make install [PREFIX=/path/to/install_dir] + +To disable building the python library, even if swig and Python are available, +use: + + make NO_PYTHON=1 + + +More work remains to support all of libfdt, including access to numeric +values. + + +Adding a new function to libfdt.h +--------------------------------- + +The shared library uses libfdt/version.lds to list the exported functions, so +add your new function there. Check that your function works with pylibfdt. If +it cannot be supported, put the declaration in libfdt.h behind #ifndef SWIG so +that swig ignores it. + + +Tests +----- + +Test files are kept in the tests/ directory. Use 'make check' to build and run +all tests. + +If you want to adjust a test file, be aware that tree_tree1.dts is compiled +and checked against a binary tree from assembler macros in trees.S. So +if you change that file you must change tree.S also. + + +Mailing list +------------ +The following list is for discussion about dtc and libfdt implementation +mailto:devicetree-compiler@vger.kernel.org + +Core device tree bindings are discussed on the devicetree-spec list: +mailto:devicetree-spec@vger.kernel.org diff --git a/scripts/dtc/pylibfdt/Makefile b/scripts/dtc/pylibfdt/Makefile index a7579f0..e442d5c 100644 --- a/scripts/dtc/pylibfdt/Makefile +++ b/scripts/dtc/pylibfdt/Makefile @@ -13,11 +13,14 @@ include $(LIBFDT_srcdir)/Makefile.libfdt PYLIBFDT_srcs = $(addprefix $(LIBFDT_srcdir)/,$(LIBFDT_SRCS)) \ $(obj)/libfdt.i +# create a version string compliant with PEP 440 +PEP_VERSION = $(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL)$(if $(SUBLEVEL),.$(SUBLEVEL)))$(subst -,,$(EXTRAVERSION)) + quiet_cmd_pymod = PYMOD $@ cmd_pymod = unset CROSS_COMPILE; unset CFLAGS; \ CC="$(HOSTCC)" LDSHARED="$(HOSTCC) -shared " \ LDFLAGS="$(HOSTLDFLAGS)" \ - VERSION="$(UBOOTVERSION)" \ + VERSION="$(PEP_VERSION)" \ CPPFLAGS="$(HOSTCFLAGS) -I$(LIBFDT_srcdir)" OBJDIR=$(obj) \ SOURCES="$(PYLIBFDT_srcs)" \ SWIG_OPTS="-I$(LIBFDT_srcdir) -I$(LIBFDT_srcdir)/.." \ diff --git a/scripts/dtc/pylibfdt/setup.py b/scripts/dtc/pylibfdt/setup.py index 992cdec..ec1fc50 100755 --- a/scripts/dtc/pylibfdt/setup.py +++ b/scripts/dtc/pylibfdt/setup.py @@ -1,11 +1,13 @@ #!/usr/bin/env python3 +# SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) """ setup.py file for SWIG libfdt Copyright (C) 2017 Google, Inc. Written by Simon Glass -SPDX-License-Identifier: GPL-2.0+ BSD-2-Clause +This script is modified from the upstream version, to fit in with the U-Boot +build system. Files to be built into the extension are provided in SOURCES C flags to use are provided in CPPFLAGS @@ -18,14 +20,29 @@ allows this script to be run stand-alone, e.g.: ./pylibfdt/setup.py install [--prefix=...] """ -from distutils.core import setup, Extension +from setuptools import setup, Extension +from setuptools.command.build_py import build_py as _build_py import os import re import sys +srcdir = os.path.dirname(__file__) + +with open(os.path.join(srcdir, "../README"), "r") as fh: + long_description = fh.read() + # Decodes a Makefile assignment line into key and value (and plus for +=) RE_KEY_VALUE = re.compile('(?P\w+) *(?P[+])?= *(?P.*)$') +def get_top_builddir(): + if '--top-builddir' in sys.argv: + index = sys.argv.index('--top-builddir') + sys.argv.pop(index) + return sys.argv.pop(index) + else: + return os.path.join(srcdir, '..') + +top_builddir = get_top_builddir() def ParseMakefile(fname): """Parse a Makefile to obtain its variables. @@ -86,7 +103,7 @@ def GetEnvFromMakefiles(): makevars = ParseMakefile(os.path.join(basedir, 'libfdt', 'Makefile.libfdt')) files = makevars['LIBFDT_SRCS'].split() files = [os.path.join(basedir, 'libfdt', fname) for fname in files] - files.append('pylibfdt/libfdt.i') + files.append('libfdt.i') cflags = ['-I%s' % basedir, '-I%s/libfdt' % basedir] objdir = '' return swig_opts, version, files, cflags, objdir @@ -107,17 +124,39 @@ if not all((swig_opts, version, files, cflags, objdir)): libfdt_module = Extension( '_libfdt', - sources = files, - extra_compile_args = cflags, - swig_opts = swig_opts, + sources=files, + include_dirs=[os.path.join(srcdir, 'libfdt')], + library_dirs=[os.path.join(top_builddir, 'libfdt')], + swig_opts=swig_opts, ) +class build_py(_build_py): + def run(self): + self.run_command("build_ext") + return super().run() + setup( name='libfdt', - version= version, - author='Simon Glass ', + version=version, + cmdclass = {'build_py' : build_py}, + author='Simon Glass', + author_email='sjg@chromium.org', description='Python binding for libfdt', ext_modules=[libfdt_module], package_dir={'': objdir}, - py_modules=['pylibfdt/libfdt'], + py_modules=['libfdt'], + + long_description=long_description, + long_description_content_type="text/plain", + url="https://git.kernel.org/pub/scm/utils/dtc/dtc.git", + license="BSD", + license_files=["GPL", "BSD-2-Clause"], + + classifiers=[ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: BSD License", + "License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)", + "Operating System :: OS Independent", + ], + ) -- cgit v1.1 From 58ddb937e1699de241e4aa39de90a68a0be71744 Mon Sep 17 00:00:00 2001 From: Michal Suchanek Date: Sun, 25 Sep 2022 13:08:16 +0200 Subject: dm: core: Switch uclass_*_device_err to use uclass_*_device_check Clarify documentation, fix a few more cases that could be broken by the change. Signed-off-by: Michal Suchanek --- drivers/pci/pci-uclass.c | 7 +++---- drivers/sysinfo/sysinfo-uclass.c | 10 +++++++++- include/dm/uclass.h | 12 ++++++++---- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index 5cff81a..6dd1965 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -1777,10 +1777,9 @@ int pci_sriov_init(struct udevice *pdev, int vf_en) bdf = dm_pci_get_bdf(pdev); - pci_get_bus(PCI_BUS(bdf), &bus); - - if (!bus) - return -ENODEV; + ret = pci_get_bus(PCI_BUS(bdf), &bus); + if (ret) + return ret; bdf += PCI_BDF(0, 0, vf_offset); diff --git a/drivers/sysinfo/sysinfo-uclass.c b/drivers/sysinfo/sysinfo-uclass.c index c5cc3cb..10194d0 100644 --- a/drivers/sysinfo/sysinfo-uclass.c +++ b/drivers/sysinfo/sysinfo-uclass.c @@ -16,7 +16,15 @@ struct sysinfo_priv { int sysinfo_get(struct udevice **devp) { - return uclass_first_device_err(UCLASS_SYSINFO, devp); + int ret = uclass_first_device_err(UCLASS_SYSINFO, devp); + + /* + * There is some very dodgy error handling in gazerbeam, + * do not return a device on error. + */ + if (ret) + *devp = NULL; + return ret; } int sysinfo_detect(struct udevice *dev) diff --git a/include/dm/uclass.h b/include/dm/uclass.h index 823a165..b1c016e 100644 --- a/include/dm/uclass.h +++ b/include/dm/uclass.h @@ -350,7 +350,8 @@ int uclass_next_device(struct udevice **devp); /** * uclass_first_device_err() - Get the first device in a uclass * - * The device returned is probed if necessary, and ready for use + * The device returned is probed if necessary, and ready for use if no error is + * returned * * @id: Uclass ID to look up * @devp: Returns pointer to the first device in that uclass, or NULL if none @@ -361,7 +362,8 @@ int uclass_first_device_err(enum uclass_id id, struct udevice **devp); /** * uclass_next_device_err() - Get the next device in a uclass * - * The device returned is probed if necessary, and ready for use + * The device returned is probed if necessary, and ready for use if no error is + * returned * * @devp: On entry, pointer to device to lookup. On exit, returns pointer * to the next device in the uclass if no error occurred, or NULL if @@ -373,7 +375,8 @@ int uclass_next_device_err(struct udevice **devp); /** * uclass_first_device_check() - Get the first device in a uclass * - * The device returned is probed if necessary, and ready for use + * The device returned is probed if necessary, and ready for use if no error is + * returned * * This function is useful to start iterating through a list of devices which * are functioning correctly and can be probed. @@ -389,7 +392,8 @@ int uclass_first_device_check(enum uclass_id id, struct udevice **devp); /** * uclass_next_device_check() - Get the next device in a uclass * - * The device returned is probed if necessary, and ready for use + * The device returned is probed if necessary, and ready for use if no error is + * returned * * This function is useful to start iterating through a list of devices which * are functioning correctly and can be probed. -- cgit v1.1 From 73f8fbc532c3546dd4bf6f267e530a82f04703fa Mon Sep 17 00:00:00 2001 From: Michal Suchanek Date: Tue, 27 Sep 2022 23:24:36 +0200 Subject: dm: core: Document return value of device bind functions These functions use device_bind_with_driver_data internally, copy the return value description. Signed-off-by: Michal Suchanek --- include/dm/lists.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/dm/lists.h b/include/dm/lists.h index fc3b4ae..97236f8 100644 --- a/include/dm/lists.h +++ b/include/dm/lists.h @@ -73,6 +73,7 @@ int lists_bind_fdt(struct udevice *parent, ofnode node, struct udevice **devp, * @drv_name: Name of driver to attach to this parent * @dev_name: Name of the new device thus created * @devp: If non-NULL, returns the newly bound device + * Return: 0 if OK, -ve on error */ int device_bind_driver(struct udevice *parent, const char *drv_name, const char *dev_name, struct udevice **devp); @@ -88,6 +89,7 @@ int device_bind_driver(struct udevice *parent, const char *drv_name, * @dev_name: Name of the new device thus created * @node: Device tree node * @devp: If non-NULL, returns the newly bound device + * Return: 0 if OK, -ve on error */ int device_bind_driver_to_node(struct udevice *parent, const char *drv_name, const char *dev_name, ofnode node, -- cgit v1.1 From aa5511e77b8bd8f943c66b6403896d06083b1d92 Mon Sep 17 00:00:00 2001 From: Michal Suchanek Date: Tue, 27 Sep 2022 23:25:08 +0200 Subject: dm: core: Add note about device_probe idempotence device_probe returns early when the device is already activated. Add a note to the documentation that it can be used on already activated devices. Signed-off-by: Michal Suchanek --- include/dm/device-internal.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/dm/device-internal.h b/include/dm/device-internal.h index 94844d3..f31c470 100644 --- a/include/dm/device-internal.h +++ b/include/dm/device-internal.h @@ -184,8 +184,8 @@ int device_of_to_plat(struct udevice *dev); /** * device_probe() - Probe a device, activating it * - * Activate a device so that it is ready for use. All its parents are probed - * first. + * Activate a device (if not yet activated) so that it is ready for use. + * All its parents are probed first. * * @dev: Pointer to device to probe * Return: 0 if OK, -ve on error -- cgit v1.1 From 4954937d922840c212b7eba297cc2d4779f087ad Mon Sep 17 00:00:00 2001 From: Michal Suchanek Date: Wed, 12 Oct 2022 21:58:08 +0200 Subject: dm: treewide: Do not use the return value of simple uclass iterator uclass_first_device/uclass_next_device return value will be removed, don't use it. With the current implementation dev is equivalent to !ret. It is redundant to check both, ret check can be replaced with dev check, and ret check inside the iteration is dead code. Signed-off-by: Michal Suchanek Reviewed-by: Simon Glass --- cmd/virtio.c | 9 +++------ drivers/dma/dma-uclass.c | 7 +++---- drivers/gpio/gpio-uclass.c | 14 ++++++-------- drivers/pci/pci-uclass.c | 15 +++------------ drivers/w1/w1-uclass.c | 9 ++------- 5 files changed, 17 insertions(+), 37 deletions(-) diff --git a/cmd/virtio.c b/cmd/virtio.c index ec87d4f..019e317 100644 --- a/cmd/virtio.c +++ b/cmd/virtio.c @@ -23,18 +23,15 @@ static int do_virtio(struct cmd_tbl *cmdtp, int flag, int argc, * device_probe() for children (i.e. virtio devices) */ struct udevice *bus, *child; - int ret; - ret = uclass_first_device(UCLASS_VIRTIO, &bus); - if (ret) + uclass_first_device(UCLASS_VIRTIO, &bus); + if (!bus) return CMD_RET_FAILURE; while (bus) { device_foreach_child_probe(child, bus) ; - ret = uclass_next_device(&bus); - if (ret) - break; + uclass_next_device(&bus); } return CMD_RET_SUCCESS; diff --git a/drivers/dma/dma-uclass.c b/drivers/dma/dma-uclass.c index 81dbb4d..34f72fa 100644 --- a/drivers/dma/dma-uclass.c +++ b/drivers/dma/dma-uclass.c @@ -210,10 +210,9 @@ int dma_get_cfg(struct dma *dma, u32 cfg_id, void **cfg_data) int dma_get_device(u32 transfer_type, struct udevice **devp) { struct udevice *dev; - int ret; - for (ret = uclass_first_device(UCLASS_DMA, &dev); dev && !ret; - ret = uclass_next_device(&dev)) { + for (uclass_first_device(UCLASS_DMA, &dev); dev; + uclass_next_device(&dev)) { struct dma_dev_priv *uc_priv; uc_priv = dev_get_uclass_priv(dev); @@ -229,7 +228,7 @@ int dma_get_device(u32 transfer_type, struct udevice **devp) *devp = dev; - return ret; + return 0; } int dma_memcpy(void *dst, void *src, size_t len) diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c index 6503325..3a6ef3b 100644 --- a/drivers/gpio/gpio-uclass.c +++ b/drivers/gpio/gpio-uclass.c @@ -59,11 +59,10 @@ static int gpio_to_device(unsigned int gpio, struct gpio_desc *desc) { struct gpio_dev_priv *uc_priv; struct udevice *dev; - int ret; - for (ret = uclass_first_device(UCLASS_GPIO, &dev); + for (uclass_first_device(UCLASS_GPIO, &dev); dev; - ret = uclass_next_device(&dev)) { + uclass_next_device(&dev)) { uc_priv = dev_get_uclass_priv(dev); if (gpio >= uc_priv->gpio_base && gpio < uc_priv->gpio_base + uc_priv->gpio_count) { @@ -73,7 +72,7 @@ static int gpio_to_device(unsigned int gpio, struct gpio_desc *desc) } /* No such GPIO */ - return ret ? ret : -ENOENT; + return -ENOENT; } #if CONFIG_IS_ENABLED(DM_GPIO_LOOKUP_LABEL) @@ -119,12 +118,11 @@ int dm_gpio_lookup_name(const char *name, struct gpio_desc *desc) struct udevice *dev; ulong offset; int numeric; - int ret; numeric = isdigit(*name) ? dectoul(name, NULL) : -1; - for (ret = uclass_first_device(UCLASS_GPIO, &dev); + for (uclass_first_device(UCLASS_GPIO, &dev); dev; - ret = uclass_next_device(&dev)) { + uclass_next_device(&dev)) { int len; uc_priv = dev_get_uclass_priv(dev); @@ -152,7 +150,7 @@ int dm_gpio_lookup_name(const char *name, struct gpio_desc *desc) } if (!dev) - return ret ? ret : -EINVAL; + return -EINVAL; gpio_desc_init(desc, dev, offset); diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index 6dd1965..9343cfc 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -1211,7 +1211,6 @@ static int pci_bridge_write_config(struct udevice *bus, pci_dev_t bdf, static int skip_to_next_device(struct udevice *bus, struct udevice **devp) { struct udevice *dev; - int ret = 0; /* * Scan through all the PCI controllers. On x86 there will only be one @@ -1223,9 +1222,7 @@ static int skip_to_next_device(struct udevice *bus, struct udevice **devp) *devp = dev; return 0; } - ret = uclass_next_device(&bus); - if (ret) - return ret; + uclass_next_device(&bus); } return 0; @@ -1235,7 +1232,6 @@ int pci_find_next_device(struct udevice **devp) { struct udevice *child = *devp; struct udevice *bus = child->parent; - int ret; /* First try all the siblings */ *devp = NULL; @@ -1248,9 +1244,7 @@ int pci_find_next_device(struct udevice **devp) } /* We ran out of siblings. Try the next bus */ - ret = uclass_next_device(&bus); - if (ret) - return ret; + uclass_next_device(&bus); return bus ? skip_to_next_device(bus, devp) : 0; } @@ -1258,12 +1252,9 @@ int pci_find_next_device(struct udevice **devp) int pci_find_first_device(struct udevice **devp) { struct udevice *bus; - int ret; *devp = NULL; - ret = uclass_first_device(UCLASS_PCI, &bus); - if (ret) - return ret; + uclass_first_device(UCLASS_PCI, &bus); return skip_to_next_device(bus, devp); } diff --git a/drivers/w1/w1-uclass.c b/drivers/w1/w1-uclass.c index de4f25b..a4247ec 100644 --- a/drivers/w1/w1-uclass.c +++ b/drivers/w1/w1-uclass.c @@ -36,15 +36,10 @@ int w1_bus_find_dev(const struct udevice *bus, u64 id, struct udevice { struct udevice *dev; u8 family = id & 0xff; - int ret; - for (ret = uclass_first_device(UCLASS_W1_EEPROM, &dev); - !ret && dev; + for (uclass_first_device(UCLASS_W1_EEPROM, &dev); + dev; uclass_next_device(&dev)) { - if (ret || !dev) { - debug("cannot find w1 eeprom dev\n"); - return -ENODEV; - } if (dev_get_driver_data(dev) == family) { *devp = dev; -- cgit v1.1 From f21954750aa8ed445ab83998bb099e366136c428 Mon Sep 17 00:00:00 2001 From: Michal Suchanek Date: Wed, 12 Oct 2022 21:58:09 +0200 Subject: dm: core: Do not stop uclass iteration on error When probing a device fails NULL pointer is returned, and following devices in uclass list cannot be iterated. Skip to next device on error instead. With that the only condition under which these simple iteration functions return error is when the dm is not initialized at uclass_get time. This is not all that interesting, change return type to void. Fixes: 6494d708bf ("dm: Add base driver model support") Signed-off-by: Michal Suchanek Reviewed-by: Simon Glass --- drivers/core/uclass.c | 30 ++++++++++++++++++------------ include/dm/uclass.h | 13 ++++++------- test/dm/core.c | 10 ++++------ test/dm/test-fdt.c | 27 ++++++++++++++++++++------- 4 files changed, 48 insertions(+), 32 deletions(-) diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c index b7d11bd..1762a07 100644 --- a/drivers/core/uclass.c +++ b/drivers/core/uclass.c @@ -574,28 +574,34 @@ int uclass_get_device_by_phandle(enum uclass_id id, struct udevice *parent, } #endif -int uclass_first_device(enum uclass_id id, struct udevice **devp) +/* + * Starting from the given device @dev, return pointer to the first device in + * the uclass that probes successfully in @devp. + */ +static void _uclass_next_device(struct udevice *dev, struct udevice **devp) +{ + for (; dev; uclass_find_next_device(&dev)) { + if (!device_probe(dev)) + break; + } + *devp = dev; +} + +void uclass_first_device(enum uclass_id id, struct udevice **devp) { struct udevice *dev; int ret; - *devp = NULL; ret = uclass_find_first_device(id, &dev); - if (!dev) - return 0; - return uclass_get_device_tail(dev, ret, devp); + _uclass_next_device(dev, devp); } -int uclass_next_device(struct udevice **devp) +void uclass_next_device(struct udevice **devp) { struct udevice *dev = *devp; - int ret; - *devp = NULL; - ret = uclass_find_next_device(&dev); - if (!dev) - return 0; - return uclass_get_device_tail(dev, ret, devp); + uclass_find_next_device(&dev); + _uclass_next_device(dev, devp); } int uclass_first_device_err(enum uclass_id id, struct udevice **devp) diff --git a/include/dm/uclass.h b/include/dm/uclass.h index b1c016e..ee15c92 100644 --- a/include/dm/uclass.h +++ b/include/dm/uclass.h @@ -320,32 +320,31 @@ int uclass_get_device_by_driver(enum uclass_id id, const struct driver *drv, * uclass_first_device() - Get the first device in a uclass * * The device returned is probed if necessary, and ready for use + * Devices that fail to probe are skipped * * This function is useful to start iterating through a list of devices which * are functioning correctly and can be probed. * * @id: Uclass ID to look up * @devp: Returns pointer to the first device in that uclass if no error - * occurred, or NULL if there is no first device, or an error occurred with - * that device. - * Return: 0 if OK (found or not found), other -ve on error + * occurred, or NULL if there is no usable device */ -int uclass_first_device(enum uclass_id id, struct udevice **devp); +void uclass_first_device(enum uclass_id id, struct udevice **devp); /** * uclass_next_device() - Get the next device in a uclass * * The device returned is probed if necessary, and ready for use + * Devices that fail to probe are skipped * * This function is useful to iterate through a list of devices which * are functioning correctly and can be probed. * * @devp: On entry, pointer to device to lookup. On exit, returns pointer * to the next device in the uclass if no error occurred, or NULL if there is - * no next device, or an error occurred with that next device. - * Return: 0 if OK (found or not found), other -ve on error + * no next device */ -int uclass_next_device(struct udevice **devp); +void uclass_next_device(struct udevice **devp); /** * uclass_first_device_err() - Get the first device in a uclass diff --git a/test/dm/core.c b/test/dm/core.c index 84eb76e..7f3f8d1 100644 --- a/test/dm/core.c +++ b/test/dm/core.c @@ -1078,11 +1078,10 @@ static int dm_test_uclass_devices_get(struct unit_test_state *uts) struct udevice *dev; int ret; - for (ret = uclass_first_device(UCLASS_TEST, &dev); + for (ret = uclass_first_device_check(UCLASS_TEST, &dev); dev; - ret = uclass_next_device(&dev)) { + ret = uclass_next_device_check(&dev)) { ut_assert(!ret); - ut_assert(dev); ut_assert(device_active(dev)); } @@ -1112,11 +1111,10 @@ static int dm_test_uclass_devices_get_by_name(struct unit_test_state *uts) * this will fail on checking condition: testdev == finddev, since the * uclass_get_device_by_name(), returns the first device by given name. */ - for (ret = uclass_first_device(UCLASS_TEST_FDT, &testdev); + for (ret = uclass_first_device_check(UCLASS_TEST_FDT, &testdev); testdev; - ret = uclass_next_device(&testdev)) { + ret = uclass_next_device_check(&testdev)) { ut_assertok(ret); - ut_assert(testdev); ut_assert(device_active(testdev)); findret = uclass_get_device_by_name(UCLASS_TEST_FDT, diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c index 1f14513..8bb868b 100644 --- a/test/dm/test-fdt.c +++ b/test/dm/test-fdt.c @@ -403,13 +403,12 @@ static int dm_test_first_next_device_probeall(struct unit_test_state *uts) int ret; /* There should be 4 devices */ - for (ret = uclass_first_device(UCLASS_TEST_PROBE, &dev), count = 0; + for (uclass_first_device(UCLASS_TEST_PROBE, &dev), count = 0; dev; - ret = uclass_next_device(&dev)) { + uclass_next_device(&dev)) { count++; parent = dev_get_parent(dev); } - ut_assertok(ret); ut_asserteq(4, count); /* Remove them and try again, with an error on the second one */ @@ -417,16 +416,30 @@ static int dm_test_first_next_device_probeall(struct unit_test_state *uts) pdata = dev_get_plat(dev); pdata->probe_err = -ENOMEM; device_remove(parent, DM_REMOVE_NORMAL); - ut_assertok(uclass_first_device(UCLASS_TEST_PROBE, &dev)); - ut_asserteq(-ENOMEM, uclass_next_device(&dev)); - ut_asserteq_ptr(dev, NULL); + for (ret = uclass_first_device_check(UCLASS_TEST_PROBE, &dev), + count = 0; + dev; + ret = uclass_next_device_check(&dev)) { + if (!ret) + count++; + else + ut_asserteq(-ENOMEM, ret); + parent = dev_get_parent(dev); + } + ut_asserteq(3, count); /* Now an error on the first one */ ut_assertok(uclass_get_device(UCLASS_TEST_PROBE, 0, &dev)); pdata = dev_get_plat(dev); pdata->probe_err = -ENOENT; device_remove(parent, DM_REMOVE_NORMAL); - ut_asserteq(-ENOENT, uclass_first_device(UCLASS_TEST_PROBE, &dev)); + for (uclass_first_device(UCLASS_TEST_PROBE, &dev), count = 0; + dev; + uclass_next_device(&dev)) { + count++; + parent = dev_get_parent(dev); + } + ut_asserteq(2, count); /* Now that broken devices are set up test probe_all */ device_remove(parent, DM_REMOVE_NORMAL); -- cgit v1.1