From 20fd256deb055479c9c0c9f0b1a9f9098c96f310 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Wed, 26 Feb 2020 21:48:17 +0100 Subject: log: output for CONFIG_LOG=n If CONFIG_LOG=n, we should still output errors, warnings, notices, infos, and for DEBUG=1 also debug messages. Signed-off-by: Heinrich Schuchardt Reviewed-by: Simon Glass --- include/log.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/log.h b/include/log.h index 62fb8afbd0e..04538760012 100644 --- a/include/log.h +++ b/include/log.h @@ -115,11 +115,11 @@ static inline int _log_nop(enum log_category_t cat, enum log_level_t level, #define log_io(_fmt...) log(LOG_CATEGORY, LOGL_DEBUG_IO, ##_fmt) #else #define _LOG_MAX_LEVEL LOGL_INFO -#define log_err(_fmt...) log_nop(LOG_CATEGORY, LOGL_ERR, ##_fmt) -#define log_warning(_fmt...) log_nop(LOG_CATEGORY, LOGL_WARNING, ##_fmt) -#define log_notice(_fmt...) log_nop(LOG_CATEGORY, LOGL_NOTICE, ##_fmt) -#define log_info(_fmt...) log_nop(LOG_CATEGORY, LOGL_INFO, ##_fmt) -#define log_debug(_fmt...) log_nop(LOG_CATEGORY, LOGL_DEBUG, ##_fmt) +#define log_err(_fmt, ...) printf(_fmt, ##__VA_ARGS__) +#define log_warning(_fmt, ...) printf(_fmt, ##__VA_ARGS__) +#define log_notice(_fmt, ...) printf(_fmt, ##__VA_ARGS__) +#define log_info(_fmt, ...) printf(_fmt, ##__VA_ARGS__) +#define log_debug(_fmt, ...) debug(_fmt, ##__VA_ARGS__) #define log_content(_fmt...) log_nop(LOG_CATEGORY, \ LOGL_DEBUG_CONTENT, ##_fmt) #define log_io(_fmt...) log_nop(LOG_CATEGORY, LOGL_DEBUG_IO, ##_fmt) -- cgit v1.3.1 From 395041b2fd2f1cb2c84127acb18d87c27c29448c Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Wed, 26 Feb 2020 21:48:18 +0100 Subject: test: log functions with CONFIG_LOG=n If CONFIG_LOG=n, we still expect output for log_err(), log_warning(), log_notice(), log_info() and in case of DEBUG=1 also for log_debug(). Provide unit tests verifying this. The tests depend on: CONFIG_CONSOLE_RECORD=y CONFIG_LOG=n CONFIG_UT_LOG=y It may be necessary to increase the value of CONFIG_SYS_MALLOC_F_LEN to accommodate CONFIG_CONSOLE_RECORD=y. Signed-off-by: Heinrich Schuchardt Reviewed-by: Simon Glass --- MAINTAINERS | 2 +- include/test/log.h | 16 ++++++ include/test/suites.h | 1 + test/Kconfig | 9 ++++ test/Makefile | 2 +- test/cmd_ut.c | 6 +++ test/log/Makefile | 10 ++++ test/log/nolog_test.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++ test/log/test-main.c | 20 ++++++++ 9 files changed, 199 insertions(+), 2 deletions(-) create mode 100644 include/test/log.h create mode 100644 test/log/nolog_test.c create mode 100644 test/log/test-main.c (limited to 'include') diff --git a/MAINTAINERS b/MAINTAINERS index 0bafe5cabca..7ac7e21ba17 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -656,7 +656,7 @@ S: Maintained T: git https://gitlab.denx.de/u-boot/u-boot.git F: common/log* F: cmd/log.c -F: test/log/log_test.c +F: test/log/ F: test/py/tests/test_log.py MALI DISPLAY PROCESSORS diff --git a/include/test/log.h b/include/test/log.h new file mode 100644 index 00000000000..c661cde75a3 --- /dev/null +++ b/include/test/log.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020, Heinrich Schuchardt + * + * Tests for logging functions + */ + +#ifndef __TEST_LOG_H__ +#define __TEST_LOG_H__ + +#include + +/* Declare a new logging test */ +#define LOG_TEST(_name) UNIT_TEST(_name, 0, log_test) + +#endif /* __TEST_LOG_H__ */ diff --git a/include/test/suites.h b/include/test/suites.h index 0748185eaf7..39ad81a90f9 100644 --- a/include/test/suites.h +++ b/include/test/suites.h @@ -30,6 +30,7 @@ int do_ut_compression(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]); int do_ut_dm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); int do_ut_env(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); int do_ut_lib(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); +int do_ut_log(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); int do_ut_optee(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); int do_ut_overlay(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); int do_ut_time(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); diff --git a/test/Kconfig b/test/Kconfig index 0157e0b060a..28704a25b61 100644 --- a/test/Kconfig +++ b/test/Kconfig @@ -40,6 +40,15 @@ config UT_LIB_RSA endif +config UT_LOG + bool "Unit tests for logging functions" + depends on UNIT_TEST + default y + help + Enables the 'ut log' command which tests logging functions like + log_err(). + See also CONFIG_LOG_TEST which provides the 'log test' command. + config UT_TIME bool "Unit tests for time functions" depends on UNIT_TEST diff --git a/test/Makefile b/test/Makefile index 2fe41f489c3..2971d0d87fb 100644 --- a/test/Makefile +++ b/test/Makefile @@ -10,5 +10,5 @@ obj-$(CONFIG_SANDBOX) += compression.o obj-$(CONFIG_SANDBOX) += print_ut.o obj-$(CONFIG_UT_TIME) += time_ut.o obj-$(CONFIG_UT_UNICODE) += unicode_ut.o -obj-$(CONFIG_$(SPL_)LOG) += log/ +obj-y += log/ obj-$(CONFIG_UNIT_TEST) += lib/ diff --git a/test/cmd_ut.c b/test/cmd_ut.c index a3a9d49f7ec..7fdcdbb1a63 100644 --- a/test/cmd_ut.c +++ b/test/cmd_ut.c @@ -60,6 +60,9 @@ static cmd_tbl_t cmd_ut_sub[] = { #ifdef CONFIG_UT_LIB U_BOOT_CMD_MKENT(lib, CONFIG_SYS_MAXARGS, 1, do_ut_lib, "", ""), #endif +#ifdef CONFIG_UT_LOG + U_BOOT_CMD_MKENT(log, CONFIG_SYS_MAXARGS, 1, do_ut_log, "", ""), +#endif #ifdef CONFIG_UT_TIME U_BOOT_CMD_MKENT(time, CONFIG_SYS_MAXARGS, 1, do_ut_time, "", ""), #endif @@ -125,6 +128,9 @@ static char ut_help_text[] = #ifdef CONFIG_UT_LIB "ut lib [test-name] - test library functions\n" #endif +#ifdef CONFIG_UT_LOG + "ut log [test-name] - test logging functions\n" +#endif #ifdef CONFIG_UT_OPTEE "ut optee [test-name]\n" #endif diff --git a/test/log/Makefile b/test/log/Makefile index e0d0a4745f1..98178f5e2b3 100644 --- a/test/log/Makefile +++ b/test/log/Makefile @@ -3,3 +3,13 @@ # Copyright (c) 2017 Google, Inc obj-$(CONFIG_LOG_TEST) += log_test.o + +ifdef CONFIG_UT_LOG + +obj-y += test-main.o + +ifndef CONFIG_LOG +obj-$(CONFIG_CONSOLE_RECORD) += nolog_test.o +endif + +endif # CONFIG_UT_LOG diff --git a/test/log/nolog_test.c b/test/log/nolog_test.c new file mode 100644 index 00000000000..84619521c91 --- /dev/null +++ b/test/log/nolog_test.c @@ -0,0 +1,135 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2020, Heinrich Schuchardt + * + * Logging function tests for CONFIG_LOG=n. + */ + +/* Needed for testing log_debug() */ +#define DEBUG 1 + +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#define BUFFSIZE 32 + +static int nolog_test_log_err(struct unit_test_state *uts) +{ + char buf[BUFFSIZE]; + + memset(buf, 0, BUFFSIZE); + console_record_reset_enable(); + log_err("testing %s\n", "log_err"); + gd->flags &= ~GD_FLG_RECORD; + ut_assertok(ut_check_console_line(uts, "testing log_err")); + ut_assertok(ut_check_console_end(uts)); + return 0; +} +LOG_TEST(nolog_test_log_err); + +static int nolog_test_log_warning(struct unit_test_state *uts) +{ + char buf[BUFFSIZE]; + + memset(buf, 0, BUFFSIZE); + console_record_reset_enable(); + log_warning("testing %s\n", "log_warning"); + gd->flags &= ~GD_FLG_RECORD; + ut_assertok(ut_check_console_line(uts, "testing log_warning")); + ut_assertok(ut_check_console_end(uts)); + return 0; +} +LOG_TEST(nolog_test_log_warning); + +static int nolog_test_log_notice(struct unit_test_state *uts) +{ + char buf[BUFFSIZE]; + + memset(buf, 0, BUFFSIZE); + console_record_reset_enable(); + log_notice("testing %s\n", "log_notice"); + gd->flags &= ~GD_FLG_RECORD; + ut_assertok(ut_check_console_line(uts, "testing log_notice")); + ut_assertok(ut_check_console_end(uts)); + return 0; +} +LOG_TEST(nolog_test_log_notice); + +static int nolog_test_log_info(struct unit_test_state *uts) +{ + char buf[BUFFSIZE]; + + memset(buf, 0, BUFFSIZE); + console_record_reset_enable(); + log_err("testing %s\n", "log_info"); + gd->flags &= ~GD_FLG_RECORD; + ut_assertok(ut_check_console_line(uts, "testing log_info")); + ut_assertok(ut_check_console_end(uts)); + return 0; +} +LOG_TEST(nolog_test_log_info); + +#undef _DEBUG +#define _DEBUG 0 +static int nolog_test_nodebug(struct unit_test_state *uts) +{ + char buf[BUFFSIZE]; + + memset(buf, 0, BUFFSIZE); + console_record_reset_enable(); + debug("testing %s\n", "debug"); + gd->flags &= ~GD_FLG_RECORD; + ut_assertok(ut_check_console_end(uts)); + return 0; +} +LOG_TEST(nolog_test_nodebug); + +static int nolog_test_log_nodebug(struct unit_test_state *uts) +{ + char buf[BUFFSIZE]; + + memset(buf, 0, BUFFSIZE); + console_record_reset_enable(); + log_debug("testing %s\n", "log_debug"); + gd->flags &= ~GD_FLG_RECORD; + ut_assert(!strcmp(buf, "")); + ut_assertok(ut_check_console_end(uts)); + return 0; +} +LOG_TEST(nolog_test_log_nodebug); + +#undef _DEBUG +#define _DEBUG 1 +static int nolog_test_debug(struct unit_test_state *uts) +{ + char buf[BUFFSIZE]; + + memset(buf, 0, BUFFSIZE); + console_record_reset_enable(); + debug("testing %s\n", "debug"); + gd->flags &= ~GD_FLG_RECORD; + ut_assertok(ut_check_console_line(uts, "testing debug")); + ut_assertok(ut_check_console_end(uts)); + return 0; +} +LOG_TEST(nolog_test_debug); + +static int nolog_test_log_debug(struct unit_test_state *uts) +{ + char buf[BUFFSIZE]; + + memset(buf, 0, BUFFSIZE); + console_record_reset_enable(); + log_debug("testing %s\n", "log_debug"); + gd->flags &= ~GD_FLG_RECORD; + ut_assertok(ut_check_console_line(uts, "testing log_debug")); + ut_assertok(ut_check_console_end(uts)); + return 0; +} +LOG_TEST(nolog_test_log_debug); diff --git a/test/log/test-main.c b/test/log/test-main.c new file mode 100644 index 00000000000..855de47f337 --- /dev/null +++ b/test/log/test-main.c @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2020, Heinrich Schuchardt + * + * Logging function tests. + */ + +#include +#include +#include +#include + +int do_ut_log(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + struct unit_test *tests = ll_entry_start(struct unit_test, log_test); + const int n_ents = ll_entry_count(struct unit_test, log_test); + + return cmd_ut_category("log", "log_test_", + tests, n_ents, argc, argv); +} -- cgit v1.3.1 From ced1080489077ab9943c319a38c2d89adb215f1f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 28 Mar 2020 14:03:48 -0600 Subject: dm: core: Add a way to skip powering down power domains When removing a device the power domains it uses are generally powered off. But when we are trying to unbind all devices (e.g. for running tests) we don't want to probe a device in the 'remove' path. Add a new flag to skip this power-down step. Signed-off-by: Simon Glass --- drivers/core/device-remove.c | 3 ++- drivers/core/uclass.c | 2 +- include/dm/device.h | 11 +++++++---- 3 files changed, 10 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/drivers/core/device-remove.c b/drivers/core/device-remove.c index 8736fd9821e..efdb0f29058 100644 --- a/drivers/core/device-remove.c +++ b/drivers/core/device-remove.c @@ -198,7 +198,8 @@ int device_remove(struct udevice *dev, uint flags) } } - if (!(drv->flags & + if (!(flags & DM_REMOVE_NO_PD) && + !(drv->flags & (DM_FLAG_DEFAULT_PD_CTRL_OFF | DM_FLAG_REMOVE_WITH_PD_ON)) && dev != gd->cur_serial_dev) dev_power_domain_off(dev); diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c index b24b677c55d..68493029364 100644 --- a/drivers/core/uclass.c +++ b/drivers/core/uclass.c @@ -118,7 +118,7 @@ int uclass_destroy(struct uclass *uc) while (!list_empty(&uc->dev_head)) { dev = list_first_entry(&uc->dev_head, struct udevice, uclass_node); - ret = device_remove(dev, DM_REMOVE_NORMAL); + ret = device_remove(dev, DM_REMOVE_NORMAL | DM_REMOVE_NO_PD); if (ret) return log_msg_ret("remove", ret); ret = device_unbind(dev); diff --git a/include/dm/device.h b/include/dm/device.h index a56164b19bb..17e57bf829c 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -80,18 +80,21 @@ struct driver_info; */ enum { /* Normal remove, remove all devices */ - DM_REMOVE_NORMAL = 1 << 0, + DM_REMOVE_NORMAL = 1 << 0, /* Remove devices with active DMA */ - DM_REMOVE_ACTIVE_DMA = DM_FLAG_ACTIVE_DMA, + DM_REMOVE_ACTIVE_DMA = DM_FLAG_ACTIVE_DMA, /* Remove devices which need some final OS preparation steps */ - DM_REMOVE_OS_PREPARE = DM_FLAG_OS_PREPARE, + DM_REMOVE_OS_PREPARE = DM_FLAG_OS_PREPARE, /* Add more use cases here */ /* Remove devices with any active flag */ - DM_REMOVE_ACTIVE_ALL = DM_REMOVE_ACTIVE_DMA | DM_REMOVE_OS_PREPARE, + DM_REMOVE_ACTIVE_ALL = DM_REMOVE_ACTIVE_DMA | DM_REMOVE_OS_PREPARE, + + /* Don't power down any attached power domains */ + DM_REMOVE_NO_PD = 1 << 1, }; /** -- cgit v1.3.1 From 70573c6c46be96d2e60497d8484b9afb119da8c1 Mon Sep 17 00:00:00 2001 From: Dario Binacchi Date: Sun, 29 Mar 2020 18:04:40 +0200 Subject: dm: test: add test case for dev_read_u64 function Add test case to cover dev_read_u64 and dev_read_u64_default functions. Signed-off-by: Dario Binacchi Reviewed-by: Simon Glass --- arch/sandbox/dts/test.dts | 1 + include/test/ut.h | 16 ++++++++++++++++ test/dm/test-fdt.c | 10 ++++++++++ 3 files changed, 27 insertions(+) (limited to 'include') diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 2338064df77..8c6a48d195e 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -93,6 +93,7 @@ <&gpio_b 9 0xc 3 2 1>; int-value = <1234>; uint-value = <(-1234)>; + int64-value = /bits/ 64 <0x1111222233334444>; interrupts-extended = <&irq 3 0>; }; diff --git a/include/test/ut.h b/include/test/ut.h index 04df8ba3af3..ab861588a84 100644 --- a/include/test/ut.h +++ b/include/test/ut.h @@ -104,6 +104,22 @@ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes); } \ } +/* Assert that two 64 int expressions are equal */ +#define ut_asserteq_64(expr1, expr2) { \ + u64 _val1 = (expr1), _val2 = (expr2); \ + \ + if (_val1 != _val2) { \ + ut_failf(uts, __FILE__, __LINE__, __func__, \ + #expr1 " == " #expr2, \ + "Expected %#llx (%lld), got %#llx (%lld)", \ + (unsigned long long)_val1, \ + (unsigned long long)_val1, \ + (unsigned long long)_val2, \ + (unsigned long long)_val2); \ + return CMD_RET_FAILURE; \ + } \ +} + /* Assert that two string expressions are equal */ #define ut_asserteq_str(expr1, expr2) { \ const char *_val1 = (expr1), *_val2 = (expr2); \ diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c index 3500ab1b46c..b39777f082c 100644 --- a/test/dm/test-fdt.c +++ b/test/dm/test-fdt.c @@ -867,6 +867,7 @@ static int dm_test_read_int(struct unit_test_state *uts) u32 val32; s32 sval; uint val; + u64 val64; ut_assertok(uclass_first_device_err(UCLASS_TEST_FDT, &dev)); ut_asserteq_str("a-test", dev->name); @@ -891,6 +892,15 @@ static int dm_test_read_int(struct unit_test_state *uts) ut_assertok(dev_read_u32u(dev, "uint-value", &val)); ut_asserteq(-1234, val); + ut_assertok(dev_read_u64(dev, "int64-value", &val64)); + ut_asserteq_64(0x1111222233334444, val64); + + ut_asserteq_64(-EINVAL, dev_read_u64(dev, "missing", &val64)); + ut_asserteq_64(6, dev_read_u64_default(dev, "missing", 6)); + + ut_asserteq_64(0x1111222233334444, + dev_read_u64_default(dev, "int64-value", 6)); + return 0; } DM_TEST(dm_test_read_int, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); -- cgit v1.3.1 From 4bb7075c830c6f4e4512fe0277ff1f08c5a9e084 Mon Sep 17 00:00:00 2001 From: Dario Binacchi Date: Sun, 29 Mar 2020 18:04:41 +0200 Subject: dm: core: support reading a single indexed u32 value The patch adds helper functions to allow reading a single indexed u32 value from a device-tree property containing multiple u32 values, that is an array of integers. Signed-off-by: Dario Binacchi Reviewed-by: Simon Glass --- arch/sandbox/dts/test.dts | 1 + drivers/core/of_access.c | 22 ++++++++++++++++++++++ drivers/core/ofnode.c | 40 ++++++++++++++++++++++++++++++++++++++++ drivers/core/read.c | 13 +++++++++++++ include/dm/of_access.h | 19 +++++++++++++++++++ include/dm/ofnode.h | 25 +++++++++++++++++++++++++ include/dm/read.h | 40 ++++++++++++++++++++++++++++++++++++++++ test/dm/test-fdt.c | 29 +++++++++++++++++++++++++++++ 8 files changed, 189 insertions(+) (limited to 'include') diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 8c6a48d195e..1973623a992 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -94,6 +94,7 @@ int-value = <1234>; uint-value = <(-1234)>; int64-value = /bits/ 64 <0x1111222233334444>; + int-array = <5678 9123 4567>; interrupts-extended = <&irq 3 0>; }; diff --git a/drivers/core/of_access.c b/drivers/core/of_access.c index 29e705e0b66..8b2ce7a0c21 100644 --- a/drivers/core/of_access.c +++ b/drivers/core/of_access.c @@ -485,6 +485,28 @@ int of_read_u32_array(const struct device_node *np, const char *propname, return 0; } +int of_read_u32_index(const struct device_node *np, const char *propname, + int index, u32 *outp) +{ + const __be32 *val; + + debug("%s: %s: ", __func__, propname); + if (!np) + return -EINVAL; + + val = of_find_property_value_of_size(np, propname, + sizeof(*outp) * (index + 1)); + if (IS_ERR(val)) { + debug("(not found)\n"); + return PTR_ERR(val); + } + + *outp = be32_to_cpup(val + index); + debug("%#x (%d)\n", *outp, *outp); + + return 0; +} + int of_read_u64(const struct device_node *np, const char *propname, u64 *outp) { const __be64 *val; diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 96a5dd20bd1..5bc3b02996e 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -48,6 +48,46 @@ u32 ofnode_read_u32_default(ofnode node, const char *propname, u32 def) return def; } +int ofnode_read_u32_index(ofnode node, const char *propname, int index, + u32 *outp) +{ + const fdt32_t *cell; + int len; + + assert(ofnode_valid(node)); + debug("%s: %s: ", __func__, propname); + + if (ofnode_is_np(node)) + return of_read_u32_index(ofnode_to_np(node), propname, index, + outp); + + cell = fdt_getprop(gd->fdt_blob, ofnode_to_offset(node), propname, + &len); + if (!cell) { + debug("(not found)\n"); + return -EINVAL; + } + + if (len < (sizeof(int) * (index + 1))) { + debug("(not large enough)\n"); + return -EOVERFLOW; + } + + *outp = fdt32_to_cpu(cell[index]); + debug("%#x (%d)\n", *outp, *outp); + + return 0; +} + +u32 ofnode_read_u32_index_default(ofnode node, const char *propname, int index, + u32 def) +{ + assert(ofnode_valid(node)); + ofnode_read_u32_index(node, propname, index, &def); + + return def; +} + int ofnode_read_s32_default(ofnode node, const char *propname, s32 def) { assert(ofnode_valid(node)); diff --git a/drivers/core/read.c b/drivers/core/read.c index 1f999b1b316..ce78f09d286 100644 --- a/drivers/core/read.c +++ b/drivers/core/read.c @@ -22,6 +22,19 @@ int dev_read_u32_default(const struct udevice *dev, const char *propname, return ofnode_read_u32_default(dev_ofnode(dev), propname, def); } +int dev_read_u32_index(struct udevice *dev, const char *propname, int index, + u32 *outp) +{ + return ofnode_read_u32_index(dev_ofnode(dev), propname, index, outp); +} + +u32 dev_read_u32_index_default(struct udevice *dev, const char *propname, + int index, u32 def) +{ + return ofnode_read_u32_index_default(dev_ofnode(dev), propname, index, + def); +} + int dev_read_s32(const struct udevice *dev, const char *propname, s32 *outp) { return ofnode_read_u32(dev_ofnode(dev), propname, (u32 *)outp); diff --git a/include/dm/of_access.h b/include/dm/of_access.h index 13fedb7cf5e..92876b3ecb6 100644 --- a/include/dm/of_access.h +++ b/include/dm/of_access.h @@ -234,6 +234,25 @@ struct device_node *of_find_node_by_phandle(phandle handle); */ int of_read_u32(const struct device_node *np, const char *propname, u32 *outp); +/** + * of_read_u32_index() - Find and read a 32-bit value from a multi-value + * property + * + * Search for a property in a device node and read a 32-bit value from + * it. + * + * @np: device node from which the property value is to be read. + * @propname: name of the property to be searched. + * @index: index of the u32 in the list of values + * @outp: pointer to return value, modified only if return value is 0. + * + * @return 0 on success, -EINVAL if the property does not exist, + * -ENODATA if property does not have a value, and -EOVERFLOW if the + * property data isn't large enough. + */ +int of_read_u32_index(const struct device_node *np, const char *propname, + int index, u32 *outp); + /** * of_read_u64() - Find and read a 64-bit integer from a property * diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index b5a50e88499..ce5e366c062 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -202,6 +202,18 @@ static inline ofnode ofnode_null(void) */ int ofnode_read_u32(ofnode node, const char *propname, u32 *outp); +/** + * ofnode_read_u32_index() - Read a 32-bit integer from a multi-value property + * + * @ref: valid node reference to read property from + * @propname: name of the property to read from + * @index: index of the integer to return + * @outp: place to put value (if found) + * @return 0 if OK, -ve on error + */ +int ofnode_read_u32_index(ofnode node, const char *propname, int index, + u32 *outp); + /** * ofnode_read_s32() - Read a 32-bit integer from a property * @@ -226,6 +238,19 @@ static inline int ofnode_read_s32(ofnode node, const char *propname, */ u32 ofnode_read_u32_default(ofnode ref, const char *propname, u32 def); +/** + * ofnode_read_u32_index_default() - Read a 32-bit integer from a multi-value + * property + * + * @ref: valid node reference to read property from + * @propname: name of the property to read from + * @index: index of the integer to return + * @def: default value to return if the property has no value + * @return property value, or @def if not found + */ +u32 ofnode_read_u32_index_default(ofnode ref, const char *propname, int index, + u32 def); + /** * ofnode_read_s32_default() - Read a 32-bit integer from a property * diff --git a/include/dm/read.h b/include/dm/read.h index da8c7f25e7c..77d3bc8db5b 100644 --- a/include/dm/read.h +++ b/include/dm/read.h @@ -66,6 +66,32 @@ int dev_read_u32(const struct udevice *dev, const char *propname, u32 *outp); int dev_read_u32_default(const struct udevice *dev, const char *propname, int def); +/** + * dev_read_u32_index() - read an indexed 32-bit integer from a device's DT + * property + * + * @dev: device to read DT property from + * @propname: name of the property to read from + * @index: index of the integer to return + * @outp: place to put value (if found) + * @return 0 if OK, -ve on error + */ +int dev_read_u32_index(struct udevice *dev, const char *propname, int index, + u32 *outp); + +/** + * dev_read_u32_index_default() - read an indexed 32-bit integer from a device's + * DT property + * + * @dev: device to read DT property from + * @propname: name of the property to read from + * @index: index of the integer to return + * @def: default value to return if the property has no value + * @return property value, or @def if not found + */ +u32 dev_read_u32_index_default(struct udevice *dev, const char *propname, + int index, u32 def); + /** * dev_read_s32() - read a signed 32-bit integer from a device's DT property * @@ -621,6 +647,20 @@ static inline int dev_read_u32_default(const struct udevice *dev, return ofnode_read_u32_default(dev_ofnode(dev), propname, def); } +static inline int dev_read_u32_index(struct udevice *dev, + const char *propname, int index, u32 *outp) +{ + return ofnode_read_u32_index(dev_ofnode(dev), propname, index, outp); +} + +static inline u32 dev_read_u32_index_default(struct udevice *dev, + const char *propname, int index, + u32 def) +{ + return ofnode_read_u32_index_default(dev_ofnode(dev), propname, index, + def); +} + static inline int dev_read_s32(const struct udevice *dev, const char *propname, s32 *outp) { diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c index b39777f082c..7c9472a3588 100644 --- a/test/dm/test-fdt.c +++ b/test/dm/test-fdt.c @@ -905,6 +905,35 @@ static int dm_test_read_int(struct unit_test_state *uts) } DM_TEST(dm_test_read_int, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); +static int dm_test_read_int_index(struct unit_test_state *uts) +{ + struct udevice *dev; + u32 val32; + + ut_assertok(uclass_first_device_err(UCLASS_TEST_FDT, &dev)); + ut_asserteq_str("a-test", dev->name); + + ut_asserteq(-EINVAL, dev_read_u32_index(dev, "missing", 0, &val32)); + ut_asserteq(19, dev_read_u32_index_default(dev, "missing", 0, 19)); + + ut_assertok(dev_read_u32_index(dev, "int-array", 0, &val32)); + ut_asserteq(5678, val32); + ut_assertok(dev_read_u32_index(dev, "int-array", 1, &val32)); + ut_asserteq(9123, val32); + ut_assertok(dev_read_u32_index(dev, "int-array", 2, &val32)); + ut_asserteq(4567, val32); + ut_asserteq(-EOVERFLOW, dev_read_u32_index(dev, "int-array", 3, + &val32)); + + ut_asserteq(5678, dev_read_u32_index_default(dev, "int-array", 0, 2)); + ut_asserteq(9123, dev_read_u32_index_default(dev, "int-array", 1, 2)); + ut_asserteq(4567, dev_read_u32_index_default(dev, "int-array", 2, 2)); + ut_asserteq(2, dev_read_u32_index_default(dev, "int-array", 3, 2)); + + return 0; +} +DM_TEST(dm_test_read_int_index, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + /* Test iteration through devices by drvdata */ static int dm_test_uclass_drvdata(struct unit_test_state *uts) { -- cgit v1.3.1 From 5c9c9bc9571f23d4c8bab18fc50fc1238da0c6c1 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Fri, 3 Apr 2020 11:39:18 +0200 Subject: dm: core: remove the duplicated function dm_ofnode_pre_reloc The content dm_ofnode_pre_reloc() is identical with ofnode_pre_reloc() defined in drivers/core/ofnode.c and used only three times: - drivers/core/lists.c:lists_bind_fdt() - drivers/clk/at91/pmc.c::at91_clk_sub_device_bind - drivers/clk/altera/clk-arria10.c::socfpga_a10_clk_bind So this function dm_ofnode_pre_reloc can be removed and replaced by these function calls by ofnode_pre_reloc(). Signed-off-by: Patrick Delaunay Acked-by: Simon Glass --- drivers/clk/altera/clk-arria10.c | 2 +- drivers/clk/at91/pmc.c | 2 +- drivers/core/lists.c | 2 +- drivers/core/util.c | 28 ---------------------------- include/dm/util.h | 27 --------------------------- 5 files changed, 3 insertions(+), 58 deletions(-) (limited to 'include') diff --git a/drivers/clk/altera/clk-arria10.c b/drivers/clk/altera/clk-arria10.c index b7eed948a51..694a9427e1f 100644 --- a/drivers/clk/altera/clk-arria10.c +++ b/drivers/clk/altera/clk-arria10.c @@ -258,7 +258,7 @@ static int socfpga_a10_clk_bind(struct udevice *dev) continue; if (pre_reloc_only && - !dm_ofnode_pre_reloc(offset_to_ofnode(offset))) + !ofnode_pre_reloc(offset_to_ofnode(offset))) continue; ret = device_bind_driver_to_node(dev, "clk-a10", name, diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c index 6b55ec59d6d..f5808449a62 100644 --- a/drivers/clk/at91/pmc.c +++ b/drivers/clk/at91/pmc.c @@ -61,7 +61,7 @@ int at91_clk_sub_device_bind(struct udevice *dev, const char *drv_name) offset > 0; offset = fdt_next_subnode(fdt, offset)) { if (pre_reloc_only && - !dm_ofnode_pre_reloc(offset_to_ofnode(offset))) + !ofnode_pre_reloc(offset_to_ofnode(offset))) continue; /* * If this node has "compatible" property, this is not diff --git a/drivers/core/lists.c b/drivers/core/lists.c index 68204c303fb..c7db14ed56e 100644 --- a/drivers/core/lists.c +++ b/drivers/core/lists.c @@ -175,7 +175,7 @@ int lists_bind_fdt(struct udevice *parent, ofnode node, struct udevice **devp, continue; if (pre_reloc_only) { - if (!dm_ofnode_pre_reloc(node) && + if (!ofnode_pre_reloc(node) && !(entry->flags & DM_FLAG_PRE_RELOC)) { log_debug("Skipping device pre-relocation\n"); return 0; diff --git a/drivers/core/util.c b/drivers/core/util.c index 69f83755f05..25b0d76f430 100644 --- a/drivers/core/util.c +++ b/drivers/core/util.c @@ -33,34 +33,6 @@ int list_count_items(struct list_head *head) return count; } -#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) -bool dm_ofnode_pre_reloc(ofnode node) -{ -#if defined(CONFIG_SPL_BUILD) || defined(CONFIG_TPL_BUILD) - /* for SPL and TPL the remaining nodes after the fdtgrep 1st pass - * had property dm-pre-reloc or u-boot,dm-spl/tpl. - * They are removed in final dtb (fdtgrep 2nd pass) - */ - return true; -#else - if (ofnode_read_bool(node, "u-boot,dm-pre-reloc")) - return true; - if (ofnode_read_bool(node, "u-boot,dm-pre-proper")) - return true; - - /* - * In regular builds individual spl and tpl handling both - * count as handled pre-relocation for later second init. - */ - if (ofnode_read_bool(node, "u-boot,dm-spl") || - ofnode_read_bool(node, "u-boot,dm-tpl")) - return true; - - return false; -#endif -} -#endif - #if !CONFIG_IS_ENABLED(OF_PLATDATA) int pci_get_devfn(struct udevice *dev) { diff --git a/include/dm/util.h b/include/dm/util.h index 0ccb3fbadf4..23f8deb14e6 100644 --- a/include/dm/util.h +++ b/include/dm/util.h @@ -42,31 +42,4 @@ static inline void dm_dump_devres(void) /* Dump out a list of drivers */ void dm_dump_drivers(void); -/** - * Check if an of node should be or was bound before relocation. - * - * Devicetree nodes can be marked as needed to be bound - * in the loader stages via special devicetree properties. - * - * Before relocation this function can be used to check if nodes - * are required in either SPL or TPL stages. - * - * After relocation and jumping into the real U-Boot binary - * it is possible to determine if a node was bound in one of - * SPL/TPL stages. - * - * There are 4 settings currently in use - * - u-boot,dm-pre-proper: U-Boot proper pre-relocation only - * - u-boot,dm-pre-reloc: legacy and indicates any of TPL or SPL - * Existing platforms only use it to indicate nodes needed in - * SPL. Should probably be replaced by u-boot,dm-spl for - * existing platforms. - * - u-boot,dm-spl: SPL and U-Boot pre-relocation - * - u-boot,dm-tpl: TPL and U-Boot pre-relocation - * @node: of node - * - * Returns true if node is needed in SPL/TL, false otherwise. - */ -bool dm_ofnode_pre_reloc(ofnode node); - #endif -- cgit v1.3.1