[U-Boot] [PATCH 00/18] dm: test: Add test code for new uclasses

Several new uclasses have been written and we need tests for these before they can be merged. This series adds the test code.
Simon Glass (18): dm: Add platform data advice and admonishment dm: test: Allow test names to leave out the dm_test_ prefix dm: test: Add tests for the clk uclass dm: test: Add tests for the pinctrl uclass sandbox: Support multiple reset types dm: reset: Allow reset_walk() to return sandbox: Add a warm and cold reset driver sandbox: Use the reset driver to handle reset dm: test: Add a test for the reset uclass dm: test: Add a test for the ram uclass dm: test: Add a test for the mmc uclass led: Return -ENODEV if the LED device cannot be found dm: test: Add a test for the LED uclass dm: test: Add a test for the system controller uclass dm: test: Add a size to each reg property test: Add a macro to check that a value is not an error pointer dm: core: Add device checking to syscon_get_regmap() test: Add a test for regmap
arch/sandbox/cpu/cpu.c | 9 +-- arch/sandbox/cpu/state.c | 4 ++ arch/sandbox/dts/test.dts | 76 ++++++++++++++++++++--- arch/sandbox/include/asm/state.h | 3 + arch/sandbox/include/asm/test.h | 19 ++++++ arch/sandbox/include/asm/u-boot-sandbox.h | 3 + configs/sandbox_defconfig | 8 +++ doc/driver-model/README.txt | 17 ++++- drivers/clk/Makefile | 1 + drivers/clk/clk_sandbox.c | 85 +++++++++++++++++++++++++ drivers/core/syscon-uclass.c | 7 ++- drivers/led/led-uclass.c | 5 +- drivers/led/led_gpio.c | 6 ++ drivers/misc/Makefile | 2 + drivers/misc/reset-uclass.c | 31 +++++++-- drivers/misc/reset_sandbox.c | 100 ++++++++++++++++++++++++++++++ drivers/misc/syscon_sandbox.c | 27 ++++++++ drivers/mmc/Makefile | 1 + drivers/mmc/sandbox_mmc.c | 25 ++++++++ drivers/pinctrl/Makefile | 1 + drivers/pinctrl/pinctrl_sandbox.c | 80 ++++++++++++++++++++++++ drivers/ram/Makefile | 1 + drivers/ram/sandbox_ram.c | 38 ++++++++++++ include/dm/platdata.h | 9 +++ include/dt-bindings/clock/sandbox-clk.h | 10 +++ include/led.h | 2 +- include/reset.h | 11 +++- include/test/ut.h | 15 +++++ test/dm/Makefile | 8 +++ test/dm/clk.c | 59 ++++++++++++++++++ test/dm/led.c | 72 +++++++++++++++++++++ test/dm/mmc.c | 27 ++++++++ test/dm/pinctrl.c | 63 +++++++++++++++++++ test/dm/ram.c | 28 +++++++++ test/dm/regmap.c | 82 ++++++++++++++++++++++++ test/dm/reset.c | 74 ++++++++++++++++++++++ test/dm/syscon.c | 31 +++++++++ test/dm/test-main.c | 15 ++++- 38 files changed, 1021 insertions(+), 34 deletions(-) create mode 100644 drivers/clk/clk_sandbox.c create mode 100644 drivers/misc/reset_sandbox.c create mode 100644 drivers/misc/syscon_sandbox.c create mode 100644 drivers/mmc/sandbox_mmc.c create mode 100644 drivers/pinctrl/pinctrl_sandbox.c create mode 100644 drivers/ram/sandbox_ram.c create mode 100644 include/dt-bindings/clock/sandbox-clk.h create mode 100644 test/dm/clk.c create mode 100644 test/dm/led.c create mode 100644 test/dm/mmc.c create mode 100644 test/dm/pinctrl.c create mode 100644 test/dm/ram.c create mode 100644 test/dm/regmap.c create mode 100644 test/dm/reset.c create mode 100644 test/dm/syscon.c

We should guide people more strongly towards device tree to avoid the proliferation of platform data structures. Add documentation to the driver model README, and also the platform data header file.
Signed-off-by: Simon Glass sjg@chromium.org ---
doc/driver-model/README.txt | 17 +++++++++++++++-- include/dm/platdata.h | 9 +++++++++ 2 files changed, 24 insertions(+), 2 deletions(-)
diff --git a/doc/driver-model/README.txt b/doc/driver-model/README.txt index f0276b1..b891e84 100644 --- a/doc/driver-model/README.txt +++ b/doc/driver-model/README.txt @@ -301,6 +301,15 @@ device tree) and probe. Platform Data -------------
+*** Note: platform data is the old way of doing things. It is +*** basically a C structure which is passed to drivers to tell them about +*** platform-specific settings like the address of its registers, bus +*** speed, etc. Device tree is now the preferred way of handling this. +*** Unless you have a good reason not to use device tree (the main one +*** being you need serial support in SPL and don't have enough SRAM for +*** the cut-down device tree and libfdt libraries) you should stay away +*** from platform data. + Platform data is like Linux platform data, if you are familiar with that. It provides the board-specific information to start up a device.
@@ -366,8 +375,12 @@ Device Tree -----------
While platdata is useful, a more flexible way of providing device data is -by using device tree. With device tree we replace the above code with the -following device tree fragment: +by using device tree. In U-Boot you should use this where possible. Avoid +sending patches which make use of the U_BOOT_DEVICE() macro unless strictly +necessary. + +With device tree we replace the above code with the following device tree +fragment:
red-square { compatible = "demo-shape"; diff --git a/include/dm/platdata.h b/include/dm/platdata.h index fbc8a6b..6f4f001 100644 --- a/include/dm/platdata.h +++ b/include/dm/platdata.h @@ -16,6 +16,10 @@ /** * struct driver_info - Information required to instantiate a device * + * NOTE: Avoid using this 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. + * * @name: Driver name * @platdata: Driver-specific platform data */ @@ -24,6 +28,11 @@ struct driver_info { const void *platdata; };
+/** + * 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. + */ #define U_BOOT_DEVICE(__name) \ ll_entry_declare(struct driver_info, __name, driver_info)

On 6 July 2015 at 12:54, Simon Glass sjg@chromium.org wrote:
We should guide people more strongly towards device tree to avoid the proliferation of platform data structures. Add documentation to the driver model README, and also the platform data header file.
Signed-off-by: Simon Glass sjg@chromium.org
doc/driver-model/README.txt | 17 +++++++++++++++-- include/dm/platdata.h | 9 +++++++++ 2 files changed, 24 insertions(+), 2 deletions(-)
Applied to u-boot-dm.

All driver model tests have a dm_test_ prefix. Ignore it when matching a test name. This makes it easier to run individual tests, like this:
./sandbox/u-boot -d ./sandbox/arch/sandbox/dts/test.dtb \ -c "ut dm clk_periph"
We can use 'clk_periph' instead of 'dm_test_clk_periph'.
Also print a message if the requested test is not found.
Signed-off-by: Simon Glass sjg@chromium.org ---
test/dm/test-main.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/test/dm/test-main.c b/test/dm/test-main.c index 0477d2f..0e43ab9 100644 --- a/test/dm/test-main.c +++ b/test/dm/test-main.c @@ -76,6 +76,7 @@ static int dm_test_main(const char *test_name) struct unit_test_state *uts = &global_dm_test_state; uts->priv = &_global_priv_dm_test_state; struct unit_test *test; + int run_count;
/* * If we have no device tree, or it only has a root node, then these @@ -90,10 +91,17 @@ static int dm_test_main(const char *test_name) if (!test_name) printf("Running %d driver model tests\n", n_ents);
+ run_count = 0; for (test = tests; test < tests + n_ents; test++) { - if (test_name && strcmp(test_name, test->name)) + const char *name = test->name; + + /* All tests have this prefix */ + if (!strncmp(name, "dm_test_", 8)) + name += 8; + if (test_name && strcmp(test_name, name)) continue; printf("Test: %s\n", test->name); + run_count++; ut_assertok(dm_test_init(uts));
uts->start = mallinfo(); @@ -109,7 +117,10 @@ static int dm_test_main(const char *test_name) ut_assertok(dm_test_destroy(uts)); }
- printf("Failures: %d\n", uts->fail_count); + if (test_name && !run_count) + printf("Test '%s' not found\n", test_name); + else + printf("Failures: %d\n", uts->fail_count);
gd->dm_root = NULL; ut_assertok(dm_init());

On 6 July 2015 at 12:54, Simon Glass sjg@chromium.org wrote:
All driver model tests have a dm_test_ prefix. Ignore it when matching a test name. This makes it easier to run individual tests, like this:
./sandbox/u-boot -d ./sandbox/arch/sandbox/dts/test.dtb \ -c "ut dm clk_periph"
We can use 'clk_periph' instead of 'dm_test_clk_periph'.
Also print a message if the requested test is not found.
Signed-off-by: Simon Glass sjg@chromium.org
test/dm/test-main.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)
Applied to u-boot-dm.

Add tests of each API call using a sandbox clock device.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/sandbox/dts/test.dts | 4 ++ arch/sandbox/include/asm/test.h | 11 ++++++ configs/sandbox_defconfig | 1 + drivers/clk/Makefile | 1 + drivers/clk/clk_sandbox.c | 85 +++++++++++++++++++++++++++++++++++++++++ test/dm/Makefile | 1 + test/dm/clk.c | 59 ++++++++++++++++++++++++++++ 7 files changed, 162 insertions(+) create mode 100644 drivers/clk/clk_sandbox.c create mode 100644 test/dm/clk.c
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index c25614a..3c9abb3 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -105,6 +105,10 @@ compatible = "denx,u-boot-fdt-test"; };
+ clk@0 { + compatible = "sandbox,clk"; + }; + eth@10002000 { compatible = "sandbox,eth"; reg = <0x10002000 0x1000>; diff --git a/arch/sandbox/include/asm/test.h b/arch/sandbox/include/asm/test.h index 91a5c79..28e9c09 100644 --- a/arch/sandbox/include/asm/test.h +++ b/arch/sandbox/include/asm/test.h @@ -17,6 +17,17 @@ #define SANDBOX_PCI_CLASS_CODE PCI_CLASS_CODE_COMM #define SANDBOX_PCI_CLASS_SUB_CODE PCI_CLASS_SUB_CODE_COMM_SERIAL
+#define SANDBOX_CLK_RATE 32768 + +enum { + PERIPH_ID_FIRST = 0, + PERIPH_ID_SPI = PERIPH_ID_FIRST, + PERIPH_ID_I2C, + PERIPH_ID_PCI, + + PERIPH_ID_COUNT, +}; + /** * sandbox_i2c_set_test_mode() - set test mode for running unit tests * diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 3953ec3..290d7c4 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -43,3 +43,4 @@ CONFIG_UT_TIME=y CONFIG_UT_DM=y CONFIG_UT_ENV=y CONFIG_SANDBOX_SERIAL=y +CONFIG_CLK=y diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index f65bdb2..008ec10 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -7,3 +7,4 @@
obj-$(CONFIG_CLK) += clk-uclass.o obj-$(CONFIG_ROCKCHIP_RK3288) += clk_rk3288.o +obj-$(CONFIG_SANDBOX) += clk_sandbox.o diff --git a/drivers/clk/clk_sandbox.c b/drivers/clk/clk_sandbox.c new file mode 100644 index 0000000..058225a --- /dev/null +++ b/drivers/clk/clk_sandbox.c @@ -0,0 +1,85 @@ +/* + * (C) Copyright 2015 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include <common.h> +#include <clk.h> +#include <dm.h> +#include <errno.h> +#include <asm/test.h> + +struct sandbox_clk_priv { + ulong rate; + ulong periph_rate[PERIPH_ID_COUNT]; +}; + +static ulong sandbox_clk_get_rate(struct udevice *dev) +{ + struct sandbox_clk_priv *priv = dev_get_priv(dev); + + return priv->rate; +} + +static ulong sandbox_clk_set_rate(struct udevice *dev, ulong rate) +{ + struct sandbox_clk_priv *priv = dev_get_priv(dev); + + if (!rate) + return -EINVAL; + priv->rate = rate; + return 0; +} + +ulong sandbox_get_periph_rate(struct udevice *dev, int periph) +{ + struct sandbox_clk_priv *priv = dev_get_priv(dev); + + if (periph < PERIPH_ID_FIRST || periph >= PERIPH_ID_COUNT) + return -EINVAL; + return priv->periph_rate[periph]; +} + +ulong sandbox_set_periph_rate(struct udevice *dev, int periph, ulong rate) +{ + struct sandbox_clk_priv *priv = dev_get_priv(dev); + ulong old_rate; + + if (periph < PERIPH_ID_FIRST || periph >= PERIPH_ID_COUNT) + return -EINVAL; + old_rate = priv->periph_rate[periph]; + priv->periph_rate[periph] = rate; + + return old_rate; +} + +static int sandbox_clk_probe(struct udevice *dev) +{ + struct sandbox_clk_priv *priv = dev_get_priv(dev); + + priv->rate = SANDBOX_CLK_RATE; + + return 0; +} + +static struct clk_ops sandbox_clk_ops = { + .get_rate = sandbox_clk_get_rate, + .set_rate = sandbox_clk_set_rate, + .get_periph_rate = sandbox_get_periph_rate, + .set_periph_rate = sandbox_set_periph_rate, +}; + +static const struct udevice_id sandbox_clk_ids[] = { + { .compatible = "sandbox,clk" }, + { } +}; + +U_BOOT_DRIVER(clk_sandbox) = { + .name = "clk_sandbox", + .id = UCLASS_CLK, + .of_match = sandbox_clk_ids, + .ops = &sandbox_clk_ops, + .priv_auto_alloc_size = sizeof(struct sandbox_clk_priv), + .probe = sandbox_clk_probe, +}; diff --git a/test/dm/Makefile b/test/dm/Makefile index 19ad2fb..7947545 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_UT_DM) += test-uclass.o # subsystem you must add sandbox tests here. obj-$(CONFIG_UT_DM) += core.o ifneq ($(CONFIG_SANDBOX),) +obj-$(CONFIG_CLK) += clk.o obj-$(CONFIG_DM_ETH) += eth.o obj-$(CONFIG_DM_GPIO) += gpio.o obj-$(CONFIG_DM_I2C) += i2c.o diff --git a/test/dm/clk.c b/test/dm/clk.c new file mode 100644 index 0000000..9ff6d95 --- /dev/null +++ b/test/dm/clk.c @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2015 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <clk.h> +#include <dm.h> +#include <asm/test.h> +#include <dm/test.h> +#include <linux/err.h> +#include <test/ut.h> + +/* Test that we can find and adjust clocks */ +static int dm_test_clk_base(struct unit_test_state *uts) +{ + struct udevice *clk; + ulong rate; + + ut_assertok(uclass_get_device(UCLASS_CLK, 0, &clk)); + rate = clk_get_rate(clk); + ut_asserteq(SANDBOX_CLK_RATE, rate); + ut_asserteq(-EINVAL, clk_set_rate(clk, 0)); + ut_assertok(clk_set_rate(clk, rate * 2)); + ut_asserteq(SANDBOX_CLK_RATE * 2, clk_get_rate(clk)); + + return 0; +} +DM_TEST(dm_test_clk_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* Test that peripheral clocks work as expected */ +static int dm_test_clk_periph(struct unit_test_state *uts) +{ + struct udevice *clk; + ulong rate; + + ut_assertok(uclass_get_device(UCLASS_CLK, 0, &clk)); + rate = clk_set_periph_rate(clk, PERIPH_ID_COUNT, 123); + ut_asserteq(-EINVAL, rate); + ut_asserteq(1, IS_ERR_VALUE(rate)); + + rate = clk_set_periph_rate(clk, PERIPH_ID_SPI, 123); + ut_asserteq(0, rate); + ut_asserteq(123, clk_get_periph_rate(clk, PERIPH_ID_SPI)); + + rate = clk_set_periph_rate(clk, PERIPH_ID_SPI, 1234); + ut_asserteq(123, rate); + + rate = clk_set_periph_rate(clk, PERIPH_ID_I2C, 567); + + rate = clk_set_periph_rate(clk, PERIPH_ID_SPI, 1234); + ut_asserteq(1234, rate); + + ut_asserteq(567, clk_get_periph_rate(clk, PERIPH_ID_I2C)); + + return 0; +} +DM_TEST(dm_test_clk_periph, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);

On 6 July 2015 at 12:54, Simon Glass sjg@chromium.org wrote:
Add tests of each API call using a sandbox clock device.
Signed-off-by: Simon Glass sjg@chromium.org
arch/sandbox/dts/test.dts | 4 ++ arch/sandbox/include/asm/test.h | 11 ++++++ configs/sandbox_defconfig | 1 + drivers/clk/Makefile | 1 + drivers/clk/clk_sandbox.c | 85 +++++++++++++++++++++++++++++++++++++++++ test/dm/Makefile | 1 + test/dm/clk.c | 59 ++++++++++++++++++++++++++++ 7 files changed, 162 insertions(+) create mode 100644 drivers/clk/clk_sandbox.c create mode 100644 test/dm/clk.c
Applied to u-boot-dm.

Add tests of each API call using a sandbox pinctrl device.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/sandbox/dts/test.dts | 11 ++++- configs/sandbox_defconfig | 1 + drivers/pinctrl/Makefile | 1 + drivers/pinctrl/pinctrl_sandbox.c | 80 +++++++++++++++++++++++++++++++++ include/dt-bindings/clock/sandbox-clk.h | 10 +++++ test/dm/Makefile | 1 + test/dm/pinctrl.c | 63 ++++++++++++++++++++++++++ 7 files changed, 166 insertions(+), 1 deletion(-) create mode 100644 drivers/pinctrl/pinctrl_sandbox.c create mode 100644 include/dt-bindings/clock/sandbox-clk.h create mode 100644 test/dm/pinctrl.c
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 3c9abb3..7447f80 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -1,3 +1,5 @@ +#include <dt-bindings/clock/sandbox-clk.h> + /dts-v1/;
/ { @@ -105,7 +107,7 @@ compatible = "denx,u-boot-fdt-test"; };
- clk@0 { + clk: clk@0 { compatible = "sandbox,clk"; };
@@ -149,6 +151,7 @@ reg = <0>; compatible = "sandbox,i2c"; clock-frequency = <100000>; + clocks = <&clk SANDBOX_CLK_I2C>; eeprom@2c { reg = <0x2c>; compatible = "i2c-eeprom"; @@ -183,6 +186,7 @@ pci: pci-controller { compatible = "sandbox,pci"; device_type = "pci"; + clocks = <&clk SANDBOX_CLK_PCI>; #address-cells = <3>; #size-cells = <2>; ranges = <0x02000000 0 0x10000000 0x10000000 0 0x2000 @@ -196,10 +200,15 @@ }; };
+ pinctrl@0 { + compatible = "sandbox,pinctrl"; + }; + spi@0 { #address-cells = <1>; #size-cells = <0>; reg = <0>; + clocks = <&clk SANDBOX_CLK_SPI>; compatible = "sandbox,spi"; cs-gpios = <0>, <&gpio_a 0>; spi.bin@0 { diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 290d7c4..6fd4fa2 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -44,3 +44,4 @@ CONFIG_UT_DM=y CONFIG_UT_ENV=y CONFIG_SANDBOX_SERIAL=y CONFIG_CLK=y +CONFIG_PINCTRL=y diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index 764b1bf..0464a7b 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -7,3 +7,4 @@
obj-$(CONFIG_PINCTRL) += pinctrl-uclass.o obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ +obj-$(CONFIG_SANDBOX) += pinctrl_sandbox.o diff --git a/drivers/pinctrl/pinctrl_sandbox.c b/drivers/pinctrl/pinctrl_sandbox.c new file mode 100644 index 0000000..9a26b96 --- /dev/null +++ b/drivers/pinctrl/pinctrl_sandbox.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2015 Google, Inc + * Written by Simon Glass sjg@chromium.org + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <pinctrl.h> +#include <asm/test.h> +#include <dt-bindings/clock/sandbox-clk.h> + +DECLARE_GLOBAL_DATA_PTR; + +static int sandbox_pinctrl_request(struct udevice *dev, int func, int flags) +{ + debug("%s: func=%x, flags=%x\n", __func__, func, flags); + + /* We require particular flag values, just as a sanity check */ + switch (func) { + case PERIPH_ID_SPI: + if (flags != 1) + return -EINVAL; + break; + case PERIPH_ID_I2C: + if (flags != 0) + return -EINVAL; + break; + case PERIPH_ID_PCI: + if (flags != 7) + return -EINVAL; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int sandbox_pinctrl_get_periph_id(struct udevice *dev, + struct udevice *periph) +{ + u32 cell[2]; + int ret; + + ret = fdtdec_get_int_array(gd->fdt_blob, periph->of_offset, + "clocks", cell, ARRAY_SIZE(cell)); + if (ret < 0) + return -EINVAL; + + switch (cell[1]) { + case SANDBOX_CLK_SPI: + return PERIPH_ID_SPI; + case SANDBOX_CLK_I2C: + return PERIPH_ID_I2C; + case SANDBOX_CLK_PCI: + return PERIPH_ID_PCI; + } + + return -ENOENT; +} + +static struct pinctrl_ops sandbox_pinctrl_ops = { + .request = sandbox_pinctrl_request, + .get_periph_id = sandbox_pinctrl_get_periph_id, +}; + +static const struct udevice_id sandbox_pinctrl_ids[] = { + { .compatible = "sandbox,pinctrl" }, + { } +}; + +U_BOOT_DRIVER(pinctrl_sandbox) = { + .name = "pinctrl_sandbox", + .id = UCLASS_PINCTRL, + .of_match = sandbox_pinctrl_ids, + .ops = &sandbox_pinctrl_ops, +}; diff --git a/include/dt-bindings/clock/sandbox-clk.h b/include/dt-bindings/clock/sandbox-clk.h new file mode 100644 index 0000000..edc7c29 --- /dev/null +++ b/include/dt-bindings/clock/sandbox-clk.h @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2015 Google, Inc + * Author: Simon Glass sjg@chromium.org + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#define SANDBOX_CLK_SPI 42 +#define SANDBOX_CLK_PCI 43 +#define SANDBOX_CLK_I2C 44 diff --git a/test/dm/Makefile b/test/dm/Makefile index 7947545..d781535 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_DM_ETH) += eth.o obj-$(CONFIG_DM_GPIO) += gpio.o obj-$(CONFIG_DM_I2C) += i2c.o obj-$(CONFIG_DM_PCI) += pci.o +obj-$(CONFIG_PINCTRL) += pinctrl.o obj-$(CONFIG_DM_RTC) += rtc.o obj-$(CONFIG_DM_SPI_FLASH) += sf.o obj-$(CONFIG_DM_SPI) += spi.o diff --git a/test/dm/pinctrl.c b/test/dm/pinctrl.c new file mode 100644 index 0000000..f0fe6f2 --- /dev/null +++ b/test/dm/pinctrl.c @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2015 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <pinctrl.h> +#include <asm/io.h> +#include <asm/test.h> +#include <dm/test.h> +#include <linux/err.h> +#include <test/ut.h> + +/* Test that we can obtain peripheral IDs */ +static int dm_test_pinctrl_periph(struct unit_test_state *uts) +{ + struct udevice *pinctrl, *dev; + + ut_assertok(uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl)); + ut_assertok(uclass_get_device_by_seq(UCLASS_SPI, 0, &dev)); + ut_asserteq(PERIPH_ID_SPI, pinctrl_get_periph_id(pinctrl, dev)); + + ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, 0, &dev)); + ut_asserteq(PERIPH_ID_I2C, pinctrl_get_periph_id(pinctrl, dev)); + + ut_assertok(uclass_get_device_by_seq(UCLASS_PCI, 0, &dev)); + ut_asserteq(PERIPH_ID_PCI, pinctrl_get_periph_id(pinctrl, dev)); + + return 0; +} +DM_TEST(dm_test_pinctrl_periph, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* Test that we can adjust pinctrl settings */ +static int dm_test_pinctrl_request(struct unit_test_state *uts) +{ + struct udevice *pinctrl, *dev; + int id; + + ut_assertok(uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl)); + + ut_assertok(uclass_get_device_by_seq(UCLASS_SPI, 0, &dev)); + id = pinctrl_get_periph_id(pinctrl, dev); + ut_asserteq(-EINVAL, pinctrl_request(pinctrl, id, 0)); + ut_asserteq(-EINVAL, pinctrl_request_noflags(pinctrl, id)); + ut_assertok(pinctrl_request(pinctrl, id, 1)); + + ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, 0, &dev)); + id = pinctrl_get_periph_id(pinctrl, dev); + ut_asserteq(-EINVAL, pinctrl_request(pinctrl, id, 2)); + ut_assertok(pinctrl_request_noflags(pinctrl, id)); + ut_assertok(pinctrl_request(pinctrl, id, 0)); + + ut_assertok(uclass_get_device_by_seq(UCLASS_PCI, 0, &dev)); + id = pinctrl_get_periph_id(pinctrl, dev); + ut_asserteq(-EINVAL, pinctrl_request(pinctrl, id, 0)); + ut_asserteq(-EINVAL, pinctrl_request_noflags(pinctrl, id)); + ut_assertok(pinctrl_request(pinctrl, id, 7)); + + return 0; +} +DM_TEST(dm_test_pinctrl_request, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);

On 6 July 2015 at 12:54, Simon Glass sjg@chromium.org wrote:
Add tests of each API call using a sandbox pinctrl device.
Signed-off-by: Simon Glass sjg@chromium.org
arch/sandbox/dts/test.dts | 11 ++++- configs/sandbox_defconfig | 1 + drivers/pinctrl/Makefile | 1 + drivers/pinctrl/pinctrl_sandbox.c | 80 +++++++++++++++++++++++++++++++++ include/dt-bindings/clock/sandbox-clk.h | 10 +++++ test/dm/Makefile | 1 + test/dm/pinctrl.c | 63 ++++++++++++++++++++++++++ 7 files changed, 166 insertions(+), 1 deletion(-) create mode 100644 drivers/pinctrl/pinctrl_sandbox.c create mode 100644 include/dt-bindings/clock/sandbox-clk.h create mode 100644 test/dm/pinctrl.c
Applied to u-boot-dm.

Add settings for the last reset generated, and the types of resets which are permitted. This will be used for testing.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/sandbox/cpu/state.c | 4 ++++ arch/sandbox/include/asm/state.h | 3 +++ 2 files changed, 7 insertions(+)
diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c index cae731c..7e5d03e 100644 --- a/arch/sandbox/cpu/state.c +++ b/arch/sandbox/cpu/state.c @@ -345,6 +345,10 @@ int state_init(void) state->ram_buf = os_malloc(state->ram_size); assert(state->ram_buf);
+ /* No reset yet, so mark it as such. Always allow power reset */ + state->last_reset = RESET_COUNT; + state->reset_allowed[RESET_POWER] = true; + /* * Example of how to use GPIOs: * diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h index a57480a..2bd28f6 100644 --- a/arch/sandbox/include/asm/state.h +++ b/arch/sandbox/include/asm/state.h @@ -7,6 +7,7 @@ #define __SANDBOX_STATE_H
#include <config.h> +#include <reset.h> #include <stdbool.h> #include <linux/stringify.h>
@@ -59,6 +60,8 @@ struct sandbox_state { bool write_state; /* Write sandbox state on exit */ bool ignore_missing_state_on_read; /* No error if state missing */ bool show_lcd; /* Show LCD on start-up */ + enum reset_t last_reset; /* Last reset type */ + bool reset_allowed[RESET_COUNT]; /* Allowed reset types */ enum state_terminal_raw term_raw; /* Terminal raw/cooked */
/* Pointer to information for each SPI bus/cs */

On 6 July 2015 at 12:54, Simon Glass sjg@chromium.org wrote:
Add settings for the last reset generated, and the types of resets which are permitted. This will be used for testing.
Signed-off-by: Simon Glass sjg@chromium.org
arch/sandbox/cpu/state.c | 4 ++++ arch/sandbox/include/asm/state.h | 3 +++ 2 files changed, 7 insertions(+)
Applied to u-boot-dm.

Add a new reset_walk_halt() function to cause a reset and then halt on failure. The reset_walk() function returns an error code.
This is needed for testing since otherwise U-Boot will halt in the middle of a test.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/misc/reset-uclass.c | 31 +++++++++++++++++++++++++------ include/reset.h | 11 ++++++++++- 2 files changed, 35 insertions(+), 7 deletions(-)
diff --git a/drivers/misc/reset-uclass.c b/drivers/misc/reset-uclass.c index ba27757..fdb5c6f 100644 --- a/drivers/misc/reset-uclass.c +++ b/drivers/misc/reset-uclass.c @@ -25,23 +25,34 @@ int reset_request(struct udevice *dev, enum reset_t type) return ops->request(dev, type); }
-void reset_walk(enum reset_t type) +int reset_walk(enum reset_t type) { struct udevice *dev; - int ret = 0; + int ret = -ENOSYS;
while (ret != -EINPROGRESS && type < RESET_COUNT) { for (uclass_first_device(UCLASS_RESET, &dev); - dev; - uclass_next_device(&dev)) { + dev; + uclass_next_device(&dev)) { ret = reset_request(dev, type); if (ret == -EINPROGRESS) break; } + type++; }
+ return ret; +} + +void reset_walk_halt(enum reset_t type) +{ + int ret; + + ret = reset_walk(type); + /* Wait for the reset to take effect */ - mdelay(100); + if (ret == -EINPROGRESS) + mdelay(100);
/* Still no reset? Give up */ printf("Reset not supported on this platform\n"); @@ -53,7 +64,15 @@ void reset_walk(enum reset_t type) */ void reset_cpu(ulong addr) { - reset_walk(RESET_WARM); + reset_walk_halt(RESET_WARM); +} + + +int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + reset_walk_halt(RESET_WARM); + + return 0; }
UCLASS_DRIVER(reset) = { diff --git a/include/reset.h b/include/reset.h index d29e108..383761e 100644 --- a/include/reset.h +++ b/include/reset.h @@ -51,8 +51,17 @@ int reset_request(struct udevice *dev, enum reset_t type); * If this function fails to reset, it will display a message and halt * * @type: Reset type to request + * @return -EINPROGRESS if a reset is in progress, -ENOSYS if not available */ -void reset_walk(enum reset_t type); +int reset_walk(enum reset_t type); + +/** + * reset_walk_halt() - try to reset, otherwise halt + * + * This calls reset_walk(). If it returns, indicating that reset is not + * supported, it prints a message and halts. + */ +void reset_walk_halt(enum reset_t type);
/** * reset_cpu() - calls reset_walk(RESET_WARM)

On 6 July 2015 at 12:54, Simon Glass sjg@chromium.org wrote:
Add a new reset_walk_halt() function to cause a reset and then halt on failure. The reset_walk() function returns an error code.
This is needed for testing since otherwise U-Boot will halt in the middle of a test.
Signed-off-by: Simon Glass sjg@chromium.org
drivers/misc/reset-uclass.c | 31 +++++++++++++++++++++++++------ include/reset.h | 11 ++++++++++- 2 files changed, 35 insertions(+), 7 deletions(-)
Applied to u-boot-dm.

Add drivers for sandbox. One can only perform a warm reset (which does nothing). The other can perform a cold reset or a power reset (the latter will quit U-Boot). These can be used for testing the reset uclass.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/misc/Makefile | 1 + drivers/misc/reset_sandbox.c | 100 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 drivers/misc/reset_sandbox.c
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 5da5178..629de25 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_MXC_OCOTP) += mxc_ocotp.o obj-$(CONFIG_MXS_OCOTP) += mxs_ocotp.o obj-$(CONFIG_NS87308) += ns87308.o obj-$(CONFIG_PDSP188x) += pdsp188x.o +obj-$(CONFIG_SANDBOX) += reset_sandbox.o ifdef CONFIG_DM_I2C obj-$(CONFIG_SANDBOX) += i2c_eeprom_emul.o endif diff --git a/drivers/misc/reset_sandbox.c b/drivers/misc/reset_sandbox.c new file mode 100644 index 0000000..917121b --- /dev/null +++ b/drivers/misc/reset_sandbox.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2015 Google, Inc + * Written by Simon Glass sjg@chromium.org + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <reset.h> +#include <asm/state.h> +#include <asm/test.h> + +DECLARE_GLOBAL_DATA_PTR; + +static int sandbox_warm_reset_request(struct udevice *dev, enum reset_t type) +{ + struct sandbox_state *state = state_get_current(); + + switch (type) { + case RESET_WARM: + state->last_reset = type; + break; + default: + return -ENOSYS; + } + if (!state->reset_allowed[type]) + return -EACCES; + + return -EINPROGRESS; +} + +static int sandbox_reset_request(struct udevice *dev, enum reset_t type) +{ + struct sandbox_state *state = state_get_current(); + + /* + * If we have a device tree, the device we created from platform data + * (see the U_BOOT_DEVICE() declaration below) should not do anything. + * If we are that device, return an error. + */ + if (gd->fdt_blob && dev->of_offset == -1) + return -ENODEV; + + switch (type) { + case RESET_COLD: + state->last_reset = type; + break; + case RESET_POWER: + state->last_reset = type; + if (!state->reset_allowed[type]) + return -EACCES; + sandbox_exit(); + break; + default: + return -ENOSYS; + } + if (!state->reset_allowed[type]) + return -EACCES; + + return -EINPROGRESS; +} + +static struct reset_ops sandbox_reset_ops = { + .request = sandbox_reset_request, +}; + +static const struct udevice_id sandbox_reset_ids[] = { + { .compatible = "sandbox,reset" }, + { } +}; + +U_BOOT_DRIVER(reset_sandbox) = { + .name = "reset_sandbox", + .id = UCLASS_RESET, + .of_match = sandbox_reset_ids, + .ops = &sandbox_reset_ops, +}; + +static struct reset_ops sandbox_warm_reset_ops = { + .request = sandbox_warm_reset_request, +}; + +static const struct udevice_id sandbox_warm_reset_ids[] = { + { .compatible = "sandbox,warm-reset" }, + { } +}; + +U_BOOT_DRIVER(warm_reset_sandbox) = { + .name = "warm_reset_sandbox", + .id = UCLASS_RESET, + .of_match = sandbox_warm_reset_ids, + .ops = &sandbox_warm_reset_ops, +}; + +/* This is here in case we don't have a device tree */ +U_BOOT_DEVICE(reset_sandbox_non_fdt) = { + .name = "reset_sandbox", +};

On 6 July 2015 at 12:54, Simon Glass sjg@chromium.org wrote:
Add drivers for sandbox. One can only perform a warm reset (which does nothing). The other can perform a cold reset or a power reset (the latter will quit U-Boot). These can be used for testing the reset uclass.
Signed-off-by: Simon Glass sjg@chromium.org
drivers/misc/Makefile | 1 + drivers/misc/reset_sandbox.c | 100 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 drivers/misc/reset_sandbox.c
Applied to u-boot-dm.

Move sandbox over to use the reset uclass for reset, instead of a direct call to do_reset(). This allows us to add tests.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/sandbox/cpu/cpu.c | 9 +-------- arch/sandbox/dts/test.dts | 8 ++++++++ arch/sandbox/include/asm/u-boot-sandbox.h | 3 +++ configs/sandbox_defconfig | 1 + 4 files changed, 13 insertions(+), 8 deletions(-)
diff --git a/arch/sandbox/cpu/cpu.c b/arch/sandbox/cpu/cpu.c index e6ddb17..3a7f5a0 100644 --- a/arch/sandbox/cpu/cpu.c +++ b/arch/sandbox/cpu/cpu.c @@ -20,7 +20,7 @@ static struct udevice *map_dev; unsigned long map_len; #endif
-void reset_cpu(ulong ignored) +void sandbox_exit(void) { /* Do this here while it still has an effect */ os_fd_restore(); @@ -34,13 +34,6 @@ void reset_cpu(ulong ignored) os_exit(0); }
-int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ - reset_cpu(0); - - return 0; -} - /* delay x useconds */ void __udelay(unsigned long usec) { diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 7447f80..65bcf03 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -204,6 +204,14 @@ compatible = "sandbox,pinctrl"; };
+ reset@0 { + compatible = "sandbox,warm-reset"; + }; + + reset@1 { + compatible = "sandbox,reset"; + }; + spi@0 { #address-cells = <1>; #size-cells = <0>; diff --git a/arch/sandbox/include/asm/u-boot-sandbox.h b/arch/sandbox/include/asm/u-boot-sandbox.h index da87cc3..2f3c3f9 100644 --- a/arch/sandbox/include/asm/u-boot-sandbox.h +++ b/arch/sandbox/include/asm/u-boot-sandbox.h @@ -83,4 +83,7 @@ void sandbox_set_enable_pci_map(int enable); */ int sandbox_read_fdt_from_file(void);
+/* Exit sandbox (quit U-Boot) */ +void sandbox_exit(void); + #endif /* _U_BOOT_SANDBOX_H_ */ diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 6fd4fa2..feba8d9 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -45,3 +45,4 @@ CONFIG_UT_ENV=y CONFIG_SANDBOX_SERIAL=y CONFIG_CLK=y CONFIG_PINCTRL=y +CONFIG_RESET=y

On 6 July 2015 at 12:54, Simon Glass sjg@chromium.org wrote:
Move sandbox over to use the reset uclass for reset, instead of a direct call to do_reset(). This allows us to add tests.
Signed-off-by: Simon Glass sjg@chromium.org
arch/sandbox/cpu/cpu.c | 9 +-------- arch/sandbox/dts/test.dts | 8 ++++++++ arch/sandbox/include/asm/u-boot-sandbox.h | 3 +++ configs/sandbox_defconfig | 1 + 4 files changed, 13 insertions(+), 8 deletions(-)
Applied to u-boot-dm.

On 07/17/2015 05:58 PM, Simon Glass wrote:
On 6 July 2015 at 12:54, Simon Glass sjg@chromium.org wrote:
Move sandbox over to use the reset uclass for reset, instead of a direct call to do_reset(). This allows us to add tests.
Signed-off-by: Simon Glass sjg@chromium.org
arch/sandbox/cpu/cpu.c | 9 +-------- arch/sandbox/dts/test.dts | 8 ++++++++ arch/sandbox/include/asm/u-boot-sandbox.h | 3 +++ configs/sandbox_defconfig | 1 + 4 files changed, 13 insertions(+), 8 deletions(-)
Applied to u-boot-dm.
This patch causes the reset command to stop working in sandbox. It now prints:
=> reset Reset not supported on this platform ### ERROR ### Please RESET the board ###
Among other things, this causes ./test/fs/fs-test.sh to hang without any particular indication why. (In that test, running under expect/pyexpect might be nicer, so the user could see progress; the error above doesn't even show up in the test log files).

Hi Stephen,
On 10 August 2015 at 21:35, Stephen Warren swarren@wwwdotorg.org wrote:
On 07/17/2015 05:58 PM, Simon Glass wrote:
On 6 July 2015 at 12:54, Simon Glass sjg@chromium.org wrote:
Move sandbox over to use the reset uclass for reset, instead of a direct call to do_reset(). This allows us to add tests.
Signed-off-by: Simon Glass sjg@chromium.org
arch/sandbox/cpu/cpu.c | 9 +-------- arch/sandbox/dts/test.dts | 8 ++++++++ arch/sandbox/include/asm/u-boot-sandbox.h | 3 +++ configs/sandbox_defconfig | 1 + 4 files changed, 13 insertions(+), 8 deletions(-)
Applied to u-boot-dm.
This patch causes the reset command to stop working in sandbox. It now prints:
=> reset Reset not supported on this platform ### ERROR ### Please RESET the board ###
Among other things, this causes ./test/fs/fs-test.sh to hang without any particular indication why. (In that test, running under expect/pyexpect might be nicer, so the user could see progress; the error above doesn't even show up in the test log files).
Yes I noticed the reset problem recently but haven't got back to it yet sorry. Ctrl-C works if you are at the command line, but will not fix the test.
One problem is that sandbox.dts needs a reset node, one of the ones from test.dts. Then at least 'u-boot -D' will work.
The other is that we need a U_BOOT_DEVICE() declaration for the reset controller. This is how drivers/serial/sandbox.c gets around this problem.
It would be good if we could run all the tests easily. At present it involves lots of steps and the method used to run each is different.
Regards, Simon

On 08/10/2015 09:44 PM, Simon Glass wrote:
Hi Stephen,
On 10 August 2015 at 21:35, Stephen Warren swarren@wwwdotorg.org wrote:
On 07/17/2015 05:58 PM, Simon Glass wrote:
On 6 July 2015 at 12:54, Simon Glass sjg@chromium.org wrote:
Move sandbox over to use the reset uclass for reset, instead of a direct call to do_reset(). This allows us to add tests.
Signed-off-by: Simon Glass sjg@chromium.org
arch/sandbox/cpu/cpu.c | 9 +-------- arch/sandbox/dts/test.dts | 8 ++++++++ arch/sandbox/include/asm/u-boot-sandbox.h | 3 +++ configs/sandbox_defconfig | 1 + 4 files changed, 13 insertions(+), 8 deletions(-)
Applied to u-boot-dm.
This patch causes the reset command to stop working in sandbox. It now prints:
=> reset Reset not supported on this platform ### ERROR ### Please RESET the board ###
Among other things, this causes ./test/fs/fs-test.sh to hang without any particular indication why. (In that test, running under expect/pyexpect might be nicer, so the user could see progress; the error above doesn't even show up in the test log files).
Yes I noticed the reset problem recently but haven't got back to it yet sorry. Ctrl-C works if you are at the command line, but will not fix the test.
One problem is that sandbox.dts needs a reset node, one of the ones from test.dts. Then at least 'u-boot -D' will work.
The other is that we need a U_BOOT_DEVICE() declaration for the reset controller. This is how drivers/serial/sandbox.c gets around this problem.
It would be good if we could run all the tests easily. At present it involves lots of steps and the method used to run each is different.
Any update on this? I had forgotten about this issue and just debugged the exact same problem again. Unfortunately, reverting this commit seems to make U-Boot hang() at early init time now, so I can't work around the issue either (unless I made a mistake implementing the revert; I'll try again).

On 09/24/2015 11:13 PM, Stephen Warren wrote:
On 08/10/2015 09:44 PM, Simon Glass wrote:
Hi Stephen,
On 10 August 2015 at 21:35, Stephen Warren swarren@wwwdotorg.org wrote:
On 07/17/2015 05:58 PM, Simon Glass wrote:
On 6 July 2015 at 12:54, Simon Glass sjg@chromium.org wrote:
Move sandbox over to use the reset uclass for reset, instead of a direct call to do_reset(). This allows us to add tests.
Signed-off-by: Simon Glass sjg@chromium.org
arch/sandbox/cpu/cpu.c | 9 +-------- arch/sandbox/dts/test.dts | 8 ++++++++ arch/sandbox/include/asm/u-boot-sandbox.h | 3 +++ configs/sandbox_defconfig | 1 + 4 files changed, 13 insertions(+), 8 deletions(-)
Applied to u-boot-dm.
This patch causes the reset command to stop working in sandbox. It now prints:
=> reset Reset not supported on this platform ### ERROR ### Please RESET the board ###
Among other things, this causes ./test/fs/fs-test.sh to hang without any particular indication why. (In that test, running under expect/pyexpect might be nicer, so the user could see progress; the error above doesn't even show up in the test log files).
Yes I noticed the reset problem recently but haven't got back to it yet sorry. Ctrl-C works if you are at the command line, but will not fix the test.
One problem is that sandbox.dts needs a reset node, one of the ones from test.dts. Then at least 'u-boot -D' will work.
The other is that we need a U_BOOT_DEVICE() declaration for the reset controller. This is how drivers/serial/sandbox.c gets around this problem.
It would be good if we could run all the tests easily. At present it involves lots of steps and the method used to run each is different.
Any update on this? I had forgotten about this issue and just debugged the exact same problem again. Unfortunately, reverting this commit seems to make U-Boot hang() at early init time now, so I can't work around the issue either (unless I made a mistake implementing the revert; I'll try again).
The following hack makes reset work again. This sounds like something other than the issues you mentioned above?
https://github.com/swarren/u-boot/commit/2e41c317516e414326620374725a25b7b53...
diff --git a/drivers/misc/reset_sandbox.c b/drivers/misc/reset_sandbox.c index 917121bc5e80..0208e11dbf3a 100644 --- a/drivers/misc/reset_sandbox.c +++ b/drivers/misc/reset_sandbox.c @@ -40,8 +40,10 @@ static int sandbox_reset_request(struct udevice *dev, enum reset_t type) * (see the U_BOOT_DEVICE() declaration below) should not do anything. * If we are that device, return an error. */ +#if 0 if (gd->fdt_blob && dev->of_offset == -1) return -ENODEV; +#endif
switch (type) { case RESET_COLD:

Hi Stephen,
On 25 September 2015 at 06:32, Stephen Warren swarren@wwwdotorg.org wrote:
On 09/24/2015 11:13 PM, Stephen Warren wrote:
On 08/10/2015 09:44 PM, Simon Glass wrote:
Hi Stephen,
On 10 August 2015 at 21:35, Stephen Warren swarren@wwwdotorg.org wrote:
On 07/17/2015 05:58 PM, Simon Glass wrote:
On 6 July 2015 at 12:54, Simon Glass sjg@chromium.org wrote:
Move sandbox over to use the reset uclass for reset, instead of a direct call to do_reset(). This allows us to add tests.
Signed-off-by: Simon Glass sjg@chromium.org
arch/sandbox/cpu/cpu.c | 9 +-------- arch/sandbox/dts/test.dts | 8 ++++++++ arch/sandbox/include/asm/u-boot-sandbox.h | 3 +++ configs/sandbox_defconfig | 1 + 4 files changed, 13 insertions(+), 8 deletions(-)
Applied to u-boot-dm.
This patch causes the reset command to stop working in sandbox. It now prints:
=> reset Reset not supported on this platform ### ERROR ### Please RESET the board ###
Among other things, this causes ./test/fs/fs-test.sh to hang without any particular indication why. (In that test, running under expect/pyexpect might be nicer, so the user could see progress; the error above doesn't even show up in the test log files).
Yes I noticed the reset problem recently but haven't got back to it yet sorry. Ctrl-C works if you are at the command line, but will not fix the test.
One problem is that sandbox.dts needs a reset node, one of the ones from test.dts. Then at least 'u-boot -D' will work.
The other is that we need a U_BOOT_DEVICE() declaration for the reset controller. This is how drivers/serial/sandbox.c gets around this problem.
It would be good if we could run all the tests easily. At present it involves lots of steps and the method used to run each is different.
Any update on this? I had forgotten about this issue and just debugged the exact same problem again. Unfortunately, reverting this commit seems to make U-Boot hang() at early init time now, so I can't work around the issue either (unless I made a mistake implementing the revert; I'll try again).
The following hack makes reset work again. This sounds like something other than the issues you mentioned above?
https://github.com/swarren/u-boot/commit/2e41c317516e414326620374725a25b7b53...
diff --git a/drivers/misc/reset_sandbox.c b/drivers/misc/reset_sandbox.c index 917121bc5e80..0208e11dbf3a 100644 --- a/drivers/misc/reset_sandbox.c +++ b/drivers/misc/reset_sandbox.c @@ -40,8 +40,10 @@ static int sandbox_reset_request(struct udevice *dev, enum reset_t type) * (see the U_BOOT_DEVICE() declaration below) should not do anything. * If we are that device, return an error. */ +#if 0 if (gd->fdt_blob && dev->of_offset == -1) return -ENODEV; +#endif
switch (type) { case RESET_COLD:
I've sent a patch:
http://patchwork.ozlabs.org/patch/525967/
Regards, Simon

Add tests that confirm that the drivers work as expected, and we can walk through the available reset types trying to reset the board.
Signed-off-by: Simon Glass sjg@chromium.org ---
test/dm/Makefile | 1 + test/dm/reset.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 test/dm/reset.c
diff --git a/test/dm/Makefile b/test/dm/Makefile index d781535..ee0c70a 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -21,6 +21,7 @@ obj-$(CONFIG_DM_GPIO) += gpio.o obj-$(CONFIG_DM_I2C) += i2c.o obj-$(CONFIG_DM_PCI) += pci.o obj-$(CONFIG_PINCTRL) += pinctrl.o +obj-$(CONFIG_RESET) += reset.o obj-$(CONFIG_DM_RTC) += rtc.o obj-$(CONFIG_DM_SPI_FLASH) += sf.o obj-$(CONFIG_DM_SPI) += spi.o diff --git a/test/dm/reset.c b/test/dm/reset.c new file mode 100644 index 0000000..5d53f25 --- /dev/null +++ b/test/dm/reset.c @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2015 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <reset.h> +#include <asm/state.h> +#include <asm/test.h> +#include <dm/test.h> +#include <test/ut.h> + +/* Test that we can use particular reset devices */ +static int dm_test_reset_base(struct unit_test_state *uts) +{ + struct sandbox_state *state = state_get_current(); + struct udevice *dev; + + /* Device 0 is the platform data device - it should never respond */ + ut_assertok(uclass_get_device(UCLASS_RESET, 0, &dev)); + ut_asserteq(-ENODEV, reset_request(dev, RESET_WARM)); + ut_asserteq(-ENODEV, reset_request(dev, RESET_COLD)); + ut_asserteq(-ENODEV, reset_request(dev, RESET_POWER)); + + /* Device 1 is the warm reset device */ + ut_assertok(uclass_get_device(UCLASS_RESET, 1, &dev)); + ut_asserteq(-EACCES, reset_request(dev, RESET_WARM)); + ut_asserteq(-ENOSYS, reset_request(dev, RESET_COLD)); + ut_asserteq(-ENOSYS, reset_request(dev, RESET_POWER)); + + state->reset_allowed[RESET_WARM] = true; + ut_asserteq(-EINPROGRESS, reset_request(dev, RESET_WARM)); + state->reset_allowed[RESET_WARM] = false; + + /* Device 2 is the cold reset device */ + ut_assertok(uclass_get_device(UCLASS_RESET, 2, &dev)); + ut_asserteq(-ENOSYS, reset_request(dev, RESET_WARM)); + ut_asserteq(-EACCES, reset_request(dev, RESET_COLD)); + state->reset_allowed[RESET_POWER] = false; + ut_asserteq(-EACCES, reset_request(dev, RESET_POWER)); + state->reset_allowed[RESET_POWER] = true; + + return 0; +} +DM_TEST(dm_test_reset_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* Test that we can walk through the reset devices */ +static int dm_test_reset_walk(struct unit_test_state *uts) +{ + struct sandbox_state *state = state_get_current(); + + /* If we generate a power reset, we will exit sandbox! */ + state->reset_allowed[RESET_POWER] = false; + ut_asserteq(-EACCES, reset_walk(RESET_WARM)); + ut_asserteq(-EACCES, reset_walk(RESET_COLD)); + ut_asserteq(-EACCES, reset_walk(RESET_POWER)); + + /* + * Enable cold reset - this should make cold reset work, plus a warm + * reset should be promoted to cold, since this is the next step + * along. + */ + state->reset_allowed[RESET_COLD] = true; + ut_asserteq(-EINPROGRESS, reset_walk(RESET_WARM)); + ut_asserteq(-EINPROGRESS, reset_walk(RESET_COLD)); + ut_asserteq(-EACCES, reset_walk(RESET_POWER)); + state->reset_allowed[RESET_COLD] = false; + state->reset_allowed[RESET_POWER] = true; + + return 0; +} +DM_TEST(dm_test_reset_walk, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);

On 6 July 2015 at 12:54, Simon Glass sjg@chromium.org wrote:
Add tests that confirm that the drivers work as expected, and we can walk through the available reset types trying to reset the board.
Signed-off-by: Simon Glass sjg@chromium.org
test/dm/Makefile | 1 + test/dm/reset.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 test/dm/reset.c
Applied to u-boot-dm.

Add a test to confirm that we can probe this device and get information on the available RAM.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/sandbox/dts/test.dts | 4 ++++ configs/sandbox_defconfig | 1 + drivers/ram/Makefile | 1 + drivers/ram/sandbox_ram.c | 38 ++++++++++++++++++++++++++++++++++++++ test/dm/Makefile | 1 + test/dm/ram.c | 28 ++++++++++++++++++++++++++++ 6 files changed, 73 insertions(+) create mode 100644 drivers/ram/sandbox_ram.c create mode 100644 test/dm/ram.c
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 65bcf03..c884aeb 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -204,6 +204,10 @@ compatible = "sandbox,pinctrl"; };
+ ram { + compatible = "sandbox,ram"; + }; + reset@0 { compatible = "sandbox,warm-reset"; }; diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index feba8d9..2e4a0a7 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -46,3 +46,4 @@ CONFIG_SANDBOX_SERIAL=y CONFIG_CLK=y CONFIG_PINCTRL=y CONFIG_RESET=y +CONFIG_RAM=y diff --git a/drivers/ram/Makefile b/drivers/ram/Makefile index 4494d81..0e10249 100644 --- a/drivers/ram/Makefile +++ b/drivers/ram/Makefile @@ -5,3 +5,4 @@ # SPDX-License-Identifier: GPL-2.0+ # obj-$(CONFIG_RAM) += ram-uclass.o +obj-$(CONFIG_SANDBOX) += sandbox_ram.o diff --git a/drivers/ram/sandbox_ram.c b/drivers/ram/sandbox_ram.c new file mode 100644 index 0000000..06bf3ec --- /dev/null +++ b/drivers/ram/sandbox_ram.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2015 Google, Inc + * Written by Simon Glass sjg@chromium.org + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <ram.h> +#include <asm/test.h> + +DECLARE_GLOBAL_DATA_PTR; + +static int sandbox_get_info(struct udevice *dev, struct ram_info *info) +{ + info->base = 0; + info->size = gd->ram_size; + + return 0; +} + +static const struct ram_ops sandbox_ram_ops = { + .get_info = sandbox_get_info, +}; + +static const struct udevice_id sandbox_ram_ids[] = { + { .compatible = "sandbox,ram" }, + { } +}; + +U_BOOT_DRIVER(warm_ram_sandbox) = { + .name = "ram_sandbox", + .id = UCLASS_RAM, + .of_match = sandbox_ram_ids, + .ops = &sandbox_ram_ops, +}; diff --git a/test/dm/Makefile b/test/dm/Makefile index ee0c70a..f649486 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -21,6 +21,7 @@ obj-$(CONFIG_DM_GPIO) += gpio.o obj-$(CONFIG_DM_I2C) += i2c.o obj-$(CONFIG_DM_PCI) += pci.o obj-$(CONFIG_PINCTRL) += pinctrl.o +obj-$(CONFIG_RAM) += ram.o obj-$(CONFIG_RESET) += reset.o obj-$(CONFIG_DM_RTC) += rtc.o obj-$(CONFIG_DM_SPI_FLASH) += sf.o diff --git a/test/dm/ram.c b/test/dm/ram.c new file mode 100644 index 0000000..3a7c5ff --- /dev/null +++ b/test/dm/ram.c @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2015 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <ram.h> +#include <dm/test.h> +#include <test/ut.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* Basic test of the ram uclass */ +static int dm_test_ram_base(struct unit_test_state *uts) +{ + struct udevice *dev; + struct ram_info info; + + ut_assertok(uclass_get_device(UCLASS_RAM, 0, &dev)); + ut_assertok(ram_get_info(dev, &info)); + ut_asserteq(0, info.base); + ut_asserteq(gd->ram_size, info.size); + + return 0; +} +DM_TEST(dm_test_ram_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);

On 6 July 2015 at 12:54, Simon Glass sjg@chromium.org wrote:
Add a test to confirm that we can probe this device and get information on the available RAM.
Signed-off-by: Simon Glass sjg@chromium.org
arch/sandbox/dts/test.dts | 4 ++++ configs/sandbox_defconfig | 1 + drivers/ram/Makefile | 1 + drivers/ram/sandbox_ram.c | 38 ++++++++++++++++++++++++++++++++++++++ test/dm/Makefile | 1 + test/dm/ram.c | 28 ++++++++++++++++++++++++++++ 6 files changed, 73 insertions(+) create mode 100644 drivers/ram/sandbox_ram.c create mode 100644 test/dm/ram.c
Applied to u-boot-dm.

Add a test to confirm that we can probe this device. Since there is no MMC stack support in sandbox at present, this is as far as the test goes.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/sandbox/dts/test.dts | 4 ++++ configs/sandbox_defconfig | 1 + drivers/mmc/Makefile | 1 + drivers/mmc/sandbox_mmc.c | 25 +++++++++++++++++++++++++ test/dm/Makefile | 1 + test/dm/mmc.c | 27 +++++++++++++++++++++++++++ 6 files changed, 59 insertions(+) create mode 100644 drivers/mmc/sandbox_mmc.c create mode 100644 test/dm/mmc.c
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index c884aeb..3b4ce2e5 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -183,6 +183,10 @@ }; };
+ mmc { + compatible = "sandbox,mmc"; + }; + pci: pci-controller { compatible = "sandbox,pci"; device_type = "pci"; diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 2e4a0a7..159f6e0 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -47,3 +47,4 @@ CONFIG_CLK=y CONFIG_PINCTRL=y CONFIG_RESET=y CONFIG_RAM=y +CONFIG_DM_MMC=y diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index 83e1ff3..753353e 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -32,6 +32,7 @@ obj-$(CONFIG_ROCKCHIP_MMC) += rockchip_mmc.o obj-$(CONFIG_SUPPORT_EMMC_RPMB) += rpmb.o obj-$(CONFIG_S3C_SDI) += s3c_sdi.o obj-$(CONFIG_S5P_SDHCI) += s5p_sdhci.o +obj-$(CONFIG_SANDBOX) += sandbox_mmc.o obj-$(CONFIG_SDHCI) += sdhci.o obj-$(CONFIG_SH_MMCIF) += sh_mmcif.o obj-$(CONFIG_SH_SDHI) += sh_sdhi.o diff --git a/drivers/mmc/sandbox_mmc.c b/drivers/mmc/sandbox_mmc.c new file mode 100644 index 0000000..f4646a8 --- /dev/null +++ b/drivers/mmc/sandbox_mmc.c @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2015 Google, Inc + * Written by Simon Glass sjg@chromium.org + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <mmc.h> +#include <asm/test.h> + +DECLARE_GLOBAL_DATA_PTR; + +static const struct udevice_id sandbox_mmc_ids[] = { + { .compatible = "sandbox,mmc" }, + { } +}; + +U_BOOT_DRIVER(warm_mmc_sandbox) = { + .name = "mmc_sandbox", + .id = UCLASS_MMC, + .of_match = sandbox_mmc_ids, +}; diff --git a/test/dm/Makefile b/test/dm/Makefile index f649486..2238a0f 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_CLK) += clk.o obj-$(CONFIG_DM_ETH) += eth.o obj-$(CONFIG_DM_GPIO) += gpio.o obj-$(CONFIG_DM_I2C) += i2c.o +obj-$(CONFIG_DM_MMC) += mmc.o obj-$(CONFIG_DM_PCI) += pci.o obj-$(CONFIG_PINCTRL) += pinctrl.o obj-$(CONFIG_RAM) += ram.o diff --git a/test/dm/mmc.c b/test/dm/mmc.c new file mode 100644 index 0000000..0461423 --- /dev/null +++ b/test/dm/mmc.c @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2015 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <mmc.h> +#include <dm/test.h> +#include <test/ut.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* + * Basic test of the mmc uclass. We could expand this by implementing an MMC + * stack for sandbox, or at least implementing the basic operation. + */ +static int dm_test_mmc_base(struct unit_test_state *uts) +{ + struct udevice *dev; + + ut_assertok(uclass_get_device(UCLASS_MMC, 0, &dev)); + + return 0; +} +DM_TEST(dm_test_mmc_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);

On 6 July 2015 at 12:54, Simon Glass sjg@chromium.org wrote:
Add a test to confirm that we can probe this device. Since there is no MMC stack support in sandbox at present, this is as far as the test goes.
Signed-off-by: Simon Glass sjg@chromium.org
arch/sandbox/dts/test.dts | 4 ++++ configs/sandbox_defconfig | 1 + drivers/mmc/Makefile | 1 + drivers/mmc/sandbox_mmc.c | 25 +++++++++++++++++++++++++ test/dm/Makefile | 1 + test/dm/mmc.c | 27 +++++++++++++++++++++++++++ 6 files changed, 59 insertions(+) create mode 100644 drivers/mmc/sandbox_mmc.c create mode 100644 test/dm/mmc.c
Applied to u-boot-dm.

We normally use -ENODEV for a missing device, rather than -ENOENT. The latter is reserved for when we have a device but cannot find something within it.
Also avoid looking at the root LED device since it is only a container.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/led/led-uclass.c | 5 +++-- include/led.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/led/led-uclass.c b/drivers/led/led-uclass.c index a80ae93..784ac87 100644 --- a/drivers/led/led-uclass.c +++ b/drivers/led/led-uclass.c @@ -24,11 +24,12 @@ int led_get_by_label(const char *label, struct udevice **devp) uclass_foreach_dev(dev, uc) { struct led_uclass_plat *uc_plat = dev_get_uclass_platdata(dev);
- if (!strcmp(label, uc_plat->label)) + /* Ignore the top-level LED node */ + if (uc_plat->label && !strcmp(label, uc_plat->label)) return uclass_get_device_tail(dev, 0, devp); }
- return -ENOENT; + return -ENODEV; }
int led_set_on(struct udevice *dev, int on) diff --git a/include/led.h b/include/led.h index 8925d75..b929d0c 100644 --- a/include/led.h +++ b/include/led.h @@ -35,7 +35,7 @@ struct led_ops { * * @label: LED label to look up * @devp: Returns the associated device, if found - * @return 0 if found, -ve on error + * @return 0 if found, -ENODEV if not found, other -ve on error */ int led_get_by_label(const char *label, struct udevice **devp);

On 6 July 2015 at 12:54, Simon Glass sjg@chromium.org wrote:
We normally use -ENODEV for a missing device, rather than -ENOENT. The latter is reserved for when we have a device but cannot find something within it.
Also avoid looking at the root LED device since it is only a container.
Signed-off-by: Simon Glass sjg@chromium.org
drivers/led/led-uclass.c | 5 +++-- include/led.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-)
Applied to u-boot-dm.

Add a test to confirm that we can adjust LEDs using the led_gpio driver.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/sandbox/dts/test.dts | 14 +++++++++ configs/sandbox_defconfig | 2 ++ drivers/led/led_gpio.c | 6 ++++ test/dm/Makefile | 1 + test/dm/led.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 95 insertions(+) create mode 100644 test/dm/led.c
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 3b4ce2e5..6a41a08 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -183,6 +183,20 @@ }; };
+ leds { + compatible = "gpio-leds"; + + iracibble { + gpios = <&gpio_a 1 0>; + label = "sandbox:red"; + }; + + martinet { + gpios = <&gpio_a 2 0>; + label = "sandbox:green"; + }; + }; + mmc { compatible = "sandbox,mmc"; }; diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 159f6e0..a0da7ab 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -48,3 +48,5 @@ CONFIG_PINCTRL=y CONFIG_RESET=y CONFIG_RAM=y CONFIG_DM_MMC=y +CONFIG_LED=y +CONFIG_LED_GPIO=y diff --git a/drivers/led/led_gpio.c b/drivers/led/led_gpio.c index a4cd618..cb6e996 100644 --- a/drivers/led/led_gpio.c +++ b/drivers/led/led_gpio.c @@ -41,10 +41,16 @@ static int led_gpio_probe(struct udevice *dev)
static int led_gpio_remove(struct udevice *dev) { + /* + * The GPIO driver may have already been removed. We will need to + * address this more generally. + */ +#ifndef CONFIG_SANDBOX struct led_gpio_priv *priv = dev_get_priv(dev);
if (dm_gpio_is_valid(&priv->gpio)) dm_gpio_free(dev, &priv->gpio); +#endif
return 0; } diff --git a/test/dm/Makefile b/test/dm/Makefile index 2238a0f..d08cab5 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_CLK) += clk.o obj-$(CONFIG_DM_ETH) += eth.o obj-$(CONFIG_DM_GPIO) += gpio.o obj-$(CONFIG_DM_I2C) += i2c.o +obj-$(CONFIG_LED) += led.o obj-$(CONFIG_DM_MMC) += mmc.o obj-$(CONFIG_DM_PCI) += pci.o obj-$(CONFIG_PINCTRL) += pinctrl.o diff --git a/test/dm/led.c b/test/dm/led.c new file mode 100644 index 0000000..8ee075c --- /dev/null +++ b/test/dm/led.c @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2015 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <led.h> +#include <asm/gpio.h> +#include <dm/test.h> +#include <test/ut.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* Base test of the led uclass */ +static int dm_test_led_base(struct unit_test_state *uts) +{ + struct udevice *dev; + + /* Get the top-level device */ + ut_assertok(uclass_get_device(UCLASS_LED, 0, &dev)); + ut_assertok(uclass_get_device(UCLASS_LED, 1, &dev)); + ut_assertok(uclass_get_device(UCLASS_LED, 2, &dev)); + ut_asserteq(-ENODEV, uclass_get_device(UCLASS_LED, 3, &dev)); + + return 0; +} +DM_TEST(dm_test_led_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* Test of the led uclass using the led_gpio driver */ +static int dm_test_led_gpio(struct unit_test_state *uts) +{ + const int offset = 1; + struct udevice *dev, *gpio; + + /* + * Check that we can manipulate an LED. LED 1 is connected to GPIO + * bank gpio_a, offset 1. + */ + ut_assertok(uclass_get_device(UCLASS_LED, 1, &dev)); + ut_assertok(uclass_get_device(UCLASS_GPIO, 1, &gpio)); + ut_asserteq(0, sandbox_gpio_get_value(gpio, offset)); + led_set_on(dev, 1); + ut_asserteq(1, sandbox_gpio_get_value(gpio, offset)); + led_set_on(dev, 0); + ut_asserteq(0, sandbox_gpio_get_value(gpio, offset)); + + return 0; +} +DM_TEST(dm_test_led_gpio, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* Test obtaining an LED by label */ +static int dm_test_led_label(struct unit_test_state *uts) +{ + struct udevice *dev, *cmp; + + ut_assertok(led_get_by_label("sandbox:red", &dev)); + ut_asserteq(1, device_active(dev)); + ut_assertok(uclass_get_device(UCLASS_LED, 1, &cmp)); + ut_asserteq_ptr(dev, cmp); + + ut_assertok(led_get_by_label("sandbox:green", &dev)); + ut_asserteq(1, device_active(dev)); + ut_assertok(uclass_get_device(UCLASS_LED, 2, &cmp)); + ut_asserteq_ptr(dev, cmp); + + ut_asserteq(-ENODEV, led_get_by_label("sandbox:blue", &dev)); + + return 0; +} +DM_TEST(dm_test_led_label, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);

On 6 July 2015 at 12:54, Simon Glass sjg@chromium.org wrote:
Add a test to confirm that we can adjust LEDs using the led_gpio driver.
Signed-off-by: Simon Glass sjg@chromium.org
arch/sandbox/dts/test.dts | 14 +++++++++ configs/sandbox_defconfig | 2 ++ drivers/led/led_gpio.c | 6 ++++ test/dm/Makefile | 1 + test/dm/led.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 95 insertions(+) create mode 100644 test/dm/led.c
Applied to u-boot-dm.

Add a test to confirm that we can access system controllers and find their driver data.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/sandbox/dts/test.dts | 10 ++++++++++ arch/sandbox/include/asm/test.h | 8 ++++++++ configs/sandbox_defconfig | 1 + drivers/misc/Makefile | 1 + drivers/misc/syscon_sandbox.c | 27 +++++++++++++++++++++++++++ test/dm/Makefile | 1 + test/dm/syscon.c | 31 +++++++++++++++++++++++++++++++ 7 files changed, 79 insertions(+) create mode 100644 drivers/misc/syscon_sandbox.c create mode 100644 test/dm/syscon.c
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 6a41a08..4304319 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -249,6 +249,16 @@ }; };
+ syscon@0 { + compatible = "sandbox,syscon0"; + reg = <0x10>; + }; + + syscon@1 { + compatible = "sandbox,syscon1"; + reg = <0x20>; + }; + uart0: serial { compatible = "sandbox,serial"; u-boot,dm-pre-reloc; diff --git a/arch/sandbox/include/asm/test.h b/arch/sandbox/include/asm/test.h index 28e9c09..d3c7851 100644 --- a/arch/sandbox/include/asm/test.h +++ b/arch/sandbox/include/asm/test.h @@ -28,6 +28,14 @@ enum { PERIPH_ID_COUNT, };
+/* System controller driver data */ +enum { + SYSCON0 = 32, + SYSCON1, + + SYSCON_COUNT +}; + /** * sandbox_i2c_set_test_mode() - set test mode for running unit tests * diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index a0da7ab..7ba6dfe 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -50,3 +50,4 @@ CONFIG_RAM=y CONFIG_DM_MMC=y CONFIG_LED=y CONFIG_LED_GPIO=y +CONFIG_SYSCON=y diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 629de25..5218b91 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -29,6 +29,7 @@ endif obj-$(CONFIG_SMSC_LPC47M) += smsc_lpc47m.o obj-$(CONFIG_STATUS_LED) += status_led.o obj-$(CONFIG_SANDBOX) += swap_case.o +obj-$(CONFIG_SANDBOX) += syscon_sandbox.o obj-$(CONFIG_TWL4030_LED) += twl4030_led.o obj-$(CONFIG_FSL_IFC) += fsl_ifc.o obj-$(CONFIG_FSL_SEC_MON) += fsl_sec_mon.o diff --git a/drivers/misc/syscon_sandbox.c b/drivers/misc/syscon_sandbox.c new file mode 100644 index 0000000..ccfab3e --- /dev/null +++ b/drivers/misc/syscon_sandbox.c @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2015 Google, Inc + * Written by Simon Glass sjg@chromium.org + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <syscon.h> +#include <asm/test.h> +#include <dm/lists.h> + +DECLARE_GLOBAL_DATA_PTR; + +static const struct udevice_id sandbox_syscon_ids[] = { + { .compatible = "sandbox,syscon0", .data = SYSCON0 }, + { .compatible = "sandbox,syscon1", .data = SYSCON1 }, + { } +}; + +U_BOOT_DRIVER(sandbox_syscon) = { + .name = "sandbox_syscon", + .id = UCLASS_SYSCON, + .of_match = sandbox_syscon_ids, +}; diff --git a/test/dm/Makefile b/test/dm/Makefile index d08cab5..cbdab17 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_RESET) += reset.o obj-$(CONFIG_DM_RTC) += rtc.o obj-$(CONFIG_DM_SPI_FLASH) += sf.o obj-$(CONFIG_DM_SPI) += spi.o +obj-y += syscon.o obj-$(CONFIG_DM_USB) += usb.o obj-$(CONFIG_DM_PMIC) += pmic.o obj-$(CONFIG_DM_REGULATOR) += regulator.o diff --git a/test/dm/syscon.c b/test/dm/syscon.c new file mode 100644 index 0000000..3642481 --- /dev/null +++ b/test/dm/syscon.c @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2015 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <syscon.h> +#include <asm/test.h> +#include <dm/test.h> +#include <test/ut.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* Base test of system controllers */ +static int dm_test_syscon_base(struct unit_test_state *uts) +{ + struct udevice *dev; + + ut_assertok(uclass_get_device(UCLASS_SYSCON, 0, &dev)); + ut_asserteq(SYSCON0, dev->driver_data); + + ut_assertok(uclass_get_device(UCLASS_SYSCON, 1, &dev)); + ut_asserteq(SYSCON1, dev->driver_data); + + ut_asserteq(-ENODEV, uclass_get_device(UCLASS_SYSCON, 2, &dev)); + + return 0; +} +DM_TEST(dm_test_syscon_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);

On 6 July 2015 at 12:54, Simon Glass sjg@chromium.org wrote:
Add a test to confirm that we can access system controllers and find their driver data.
Signed-off-by: Simon Glass sjg@chromium.org
arch/sandbox/dts/test.dts | 10 ++++++++++ arch/sandbox/include/asm/test.h | 8 ++++++++ configs/sandbox_defconfig | 1 + drivers/misc/Makefile | 1 + drivers/misc/syscon_sandbox.c | 27 +++++++++++++++++++++++++++ test/dm/Makefile | 1 + test/dm/syscon.c | 31 +++++++++++++++++++++++++++++++ 7 files changed, 79 insertions(+) create mode 100644 drivers/misc/syscon_sandbox.c create mode 100644 test/dm/syscon.c
Applied to u-boot-dm.

Each sandbox peripheral should have a size as well as a base address. This is required for regmaps to work, so make this change for all nodes that have an address.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/sandbox/dts/test.dts | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-)
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 4304319..97b375a 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -6,7 +6,7 @@ model = "sandbox"; compatible = "sandbox"; #address-cells = <1>; - #size-cells = <0>; + #size-cells = <1>;
aliases { console = &uart0; @@ -30,7 +30,7 @@ };
a-test { - reg = <0>; + reg = <0 1>; compatible = "denx,u-boot-fdt-test"; ping-expect = <0>; ping-add = <0>; @@ -43,16 +43,16 @@ };
junk { - reg = <1>; + reg = <1 1>; compatible = "not,compatible"; };
no-compatible { - reg = <2>; + reg = <2 1>; };
b-test { - reg = <3>; + reg = <3 1>; compatible = "denx,u-boot-fdt-test"; ping-expect = <3>; ping-add = <3>; @@ -62,7 +62,7 @@ #address-cells = <1>; #size-cells = <0>; compatible = "denx,u-boot-test-bus"; - reg = <3>; + reg = <3 1>; ping-expect = <4>; ping-add = <4>; c-test@5 { @@ -86,14 +86,14 @@ };
d-test { - reg = <3>; + reg = <3 1>; ping-expect = <6>; ping-add = <6>; compatible = "google,another-fdt-test"; };
e-test { - reg = <3>; + reg = <3 1>; ping-expect = <6>; ping-add = <6>; compatible = "google,another-fdt-test"; @@ -148,7 +148,7 @@ i2c@0 { #address-cells = <1>; #size-cells = <0>; - reg = <0>; + reg = <0 1>; compatible = "sandbox,i2c"; clock-frequency = <100000>; clocks = <&clk SANDBOX_CLK_I2C>; @@ -237,7 +237,7 @@ spi@0 { #address-cells = <1>; #size-cells = <0>; - reg = <0>; + reg = <0 1>; clocks = <&clk SANDBOX_CLK_SPI>; compatible = "sandbox,spi"; cs-gpios = <0>, <&gpio_a 0>; @@ -251,12 +251,15 @@
syscon@0 { compatible = "sandbox,syscon0"; - reg = <0x10>; + reg = <0x10 4>; };
syscon@1 { compatible = "sandbox,syscon1"; - reg = <0x20>; + reg = <0x20 5 + 0x28 6 + 0x30 7 + 0x38 8>; };
uart0: serial {

On 6 July 2015 at 12:54, Simon Glass sjg@chromium.org wrote:
Each sandbox peripheral should have a size as well as a base address. This is required for regmaps to work, so make this change for all nodes that have an address.
Signed-off-by: Simon Glass sjg@chromium.org
arch/sandbox/dts/test.dts | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-)
Applied to u-boot-dm.

Some functions can return ERR_PTR(errval). Add a unit test macro to check that no error is returned in a pointer.
Signed-off-by: Simon Glass sjg@chromium.org ---
include/test/ut.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
diff --git a/include/test/ut.h b/include/test/ut.h index 5e5aa6c..da7c1a9 100644 --- a/include/test/ut.h +++ b/include/test/ut.h @@ -9,6 +9,8 @@ #ifndef __TEST_UT_H #define __TEST_UT_H
+#include <linux/err.h> + struct unit_test_state;
/** @@ -101,6 +103,19 @@ void ut_failf(struct unit_test_state *uts, const char *fname, int line, } \ }
+/* Assert that a pointer is not an error pointer */ +#define ut_assertok_ptr(expr) { \ + const void *val = (expr); \ + \ + if (IS_ERR(val)) { \ + ut_failf(uts, __FILE__, __LINE__, __func__, \ + #expr " = NULL", \ + "Expected pointer, got error %ld", \ + PTR_ERR(val)); \ + return CMD_RET_FAILURE; \ + } \ +} + /* Assert that an operation succeeds (returns 0) */ #define ut_assertok(cond) ut_asserteq(0, cond)

On 6 July 2015 at 12:54, Simon Glass sjg@chromium.org wrote:
Some functions can return ERR_PTR(errval). Add a unit test macro to check that no error is returned in a pointer.
Signed-off-by: Simon Glass sjg@chromium.org
include/test/ut.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
Applied to u-boot-dm.

This function can only handle a syscon device. It is possible that someone will make a mistake, so add a check for this.
Also we should return -ENODEV when a device cannot be found, so update the syscon_get_regmap_by_driver_data() to follow this convention.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/core/syscon-uclass.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/core/syscon-uclass.c b/drivers/core/syscon-uclass.c index 4d66bb5..686c320 100644 --- a/drivers/core/syscon-uclass.c +++ b/drivers/core/syscon-uclass.c @@ -17,8 +17,11 @@
struct regmap *syscon_get_regmap(struct udevice *dev) { - struct syscon_uc_info *priv = dev_get_uclass_priv(dev); + struct syscon_uc_info *priv;
+ if (device_get_uclass_id(dev) != UCLASS_SYSCON) + return ERR_PTR(-ENOEXEC); + priv = dev_get_uclass_priv(dev); return priv->regmap; }
@@ -52,7 +55,7 @@ struct regmap *syscon_get_regmap_by_driver_data(ulong driver_data) } }
- return ERR_PTR(-ENOENT); + return ERR_PTR(-ENODEV); }
void *syscon_get_first_range(ulong driver_data)

On 6 July 2015 at 12:54, Simon Glass sjg@chromium.org wrote:
This function can only handle a syscon device. It is possible that someone will make a mistake, so add a check for this.
Also we should return -ENODEV when a device cannot be found, so update the syscon_get_regmap_by_driver_data() to follow this convention.
Signed-off-by: Simon Glass sjg@chromium.org
drivers/core/syscon-uclass.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
Applied to u-boot-dm.

We use syscon to test that the regmap functions work as expected.
Signed-off-by: Simon Glass sjg@chromium.org ---
test/dm/Makefile | 1 + test/dm/regmap.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 test/dm/regmap.c
diff --git a/test/dm/Makefile b/test/dm/Makefile index cbdab17..d6ae6d6 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_DM_MMC) += mmc.o obj-$(CONFIG_DM_PCI) += pci.o obj-$(CONFIG_PINCTRL) += pinctrl.o obj-$(CONFIG_RAM) += ram.o +obj-y += regmap.o obj-$(CONFIG_RESET) += reset.o obj-$(CONFIG_DM_RTC) += rtc.o obj-$(CONFIG_DM_SPI_FLASH) += sf.o diff --git a/test/dm/regmap.c b/test/dm/regmap.c new file mode 100644 index 0000000..7f66058 --- /dev/null +++ b/test/dm/regmap.c @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2015 Google, Inc +2 * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <mapmem.h> +#include <regmap.h> +#include <syscon.h> +#include <asm/test.h> +#include <dm/test.h> +#include <test/ut.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* Base test of register maps */ +static int dm_test_regmap_base(struct unit_test_state *uts) +{ + struct udevice *dev; + struct regmap *map; + int i; + + ut_assertok(uclass_get_device(UCLASS_SYSCON, 0, &dev)); + map = syscon_get_regmap(dev); + ut_assertok_ptr(map); + ut_asserteq(1, map->range_count); + ut_asserteq(0x10, map->base); + ut_asserteq(0x10, map->range->start); + ut_asserteq(4, map->range->size); + ut_asserteq_ptr(&map->base_range, map->range); + ut_asserteq(0x10, map_to_sysmem(regmap_get_range(map, 0))); + + ut_assertok(uclass_get_device(UCLASS_SYSCON, 1, &dev)); + map = syscon_get_regmap(dev); + ut_assertok_ptr(map); + ut_asserteq(4, map->range_count); + ut_asserteq(0x20, map->base); + ut_assert(&map->base_range != map->range); + for (i = 0; i < 4; i++) { + const unsigned long addr = 0x20 + 8 * i; + + ut_asserteq(addr, map->range[i].start); + ut_asserteq(5 + i, map->range[i].size); + ut_asserteq(addr, map_to_sysmem(regmap_get_range(map, i))); + } + + /* Check that we can't pretend a different device is a syscon */ + ut_assertok(uclass_get_device(UCLASS_I2C, 0, &dev)); + map = syscon_get_regmap(dev); + ut_asserteq_ptr(ERR_PTR(-ENOEXEC), map); + + return 0; +} +DM_TEST(dm_test_regmap_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + +/* Test we can access a regmap through syscon */ +static int dm_test_regmap_syscon(struct unit_test_state *uts) +{ + struct regmap *map; + + map = syscon_get_regmap_by_driver_data(SYSCON0); + ut_assertok_ptr(map); + ut_asserteq(1, map->range_count); + + map = syscon_get_regmap_by_driver_data(SYSCON1); + ut_assertok_ptr(map); + ut_asserteq(4, map->range_count); + + map = syscon_get_regmap_by_driver_data(SYSCON_COUNT); + ut_asserteq_ptr(ERR_PTR(-ENODEV), map); + + ut_asserteq(0x10, map_to_sysmem(syscon_get_first_range(SYSCON0))); + ut_asserteq(0x20, map_to_sysmem(syscon_get_first_range(SYSCON1))); + ut_asserteq_ptr(ERR_PTR(-ENODEV), + syscon_get_first_range(SYSCON_COUNT)); + + return 0; +} + +DM_TEST(dm_test_regmap_syscon, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);

On 6 July 2015 at 12:54, Simon Glass sjg@chromium.org wrote:
We use syscon to test that the regmap functions work as expected.
Signed-off-by: Simon Glass sjg@chromium.org
test/dm/Makefile | 1 + test/dm/regmap.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 test/dm/regmap.c
Applied to u-boot-dm.
participants (2)
-
Simon Glass
-
Stephen Warren