diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 70356461959..5522be3a274 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -285,6 +285,10 @@ mbox-names = "other", "test"; }; + misc-test { + compatible = "sandbox,misc_sandbox"; + }; + mmc2 { compatible = "sandbox,mmc"; }; diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 4ce9d213f06..f66c9e8839d 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -39,7 +39,7 @@ ifdef CONFIG_SPL_BUILD obj-$(CONFIG_SANDBOX) += spltest_sandbox.o endif endif -obj-$(CONFIG_SANDBOX) += syscon_sandbox.o +obj-$(CONFIG_SANDBOX) += syscon_sandbox.o misc_sandbox.o obj-$(CONFIG_TEGRA_CAR) += tegra_car.o obj-$(CONFIG_TEGRA186_BPMP) += tegra186_bpmp.o obj-$(CONFIG_TWL4030_LED) += twl4030_led.o diff --git a/drivers/misc/misc_sandbox.c b/drivers/misc/misc_sandbox.c new file mode 100644 index 00000000000..e4164f76fba --- /dev/null +++ b/drivers/misc/misc_sandbox.c @@ -0,0 +1,133 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2018 + * Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc + */ + +#include +#include +#include + +struct misc_sandbox_priv { + u8 mem[128]; + ulong last_ioctl; + bool enabled; +}; + +int misc_sandbox_read(struct udevice *dev, int offset, void *buf, int size) +{ + struct misc_sandbox_priv *priv = dev_get_priv(dev); + + memcpy(buf, priv->mem + offset, size); + + return 0; +} + +int misc_sandbox_write(struct udevice *dev, int offset, const void *buf, + int size) +{ + struct misc_sandbox_priv *priv = dev_get_priv(dev); + + memcpy(priv->mem + offset, buf, size); + + return 0; +} + +int misc_sandbox_ioctl(struct udevice *dev, unsigned long request, void *buf) +{ + struct misc_sandbox_priv *priv = dev_get_priv(dev); + + priv->last_ioctl = request; + + return 0; +} + +int misc_sandbox_call(struct udevice *dev, int msgid, void *tx_msg, + int tx_size, void *rx_msg, int rx_size) +{ + struct misc_sandbox_priv *priv = dev_get_priv(dev); + + if (msgid == 0) { + int num = *(int *)tx_msg; + + switch (num) { + case 0: + strncpy(rx_msg, "Zero", rx_size); + break; + case 1: + strncpy(rx_msg, "One", rx_size); + break; + case 2: + strncpy(rx_msg, "Two", rx_size); + break; + default: + return -EINVAL; + } + } + + if (msgid == 1) { + int num = *(int *)tx_msg; + + switch (num) { + case 0: + strncpy(rx_msg, "Forty", rx_size); + break; + case 1: + strncpy(rx_msg, "Forty-one", rx_size); + break; + case 2: + strncpy(rx_msg, "Forty-two", rx_size); + break; + default: + return -EINVAL; + } + } + + if (msgid == 2) + memcpy(rx_msg, &priv->last_ioctl, sizeof(priv->last_ioctl)); + + if (msgid == 3) + memcpy(rx_msg, &priv->enabled, sizeof(priv->enabled)); + + return 0; +} + +int misc_sandbox_set_enabled(struct udevice *dev, bool val) +{ + struct misc_sandbox_priv *priv = dev_get_priv(dev); + + priv->enabled = !priv->enabled; + + return 0; +} + +static const struct misc_ops misc_sandbox_ops = { + .read = misc_sandbox_read, + .write = misc_sandbox_write, + .ioctl = misc_sandbox_ioctl, + .call = misc_sandbox_call, + .set_enabled = misc_sandbox_set_enabled, +}; + +int misc_sandbox_probe(struct udevice *dev) +{ + struct misc_sandbox_priv *priv = dev_get_priv(dev); + + priv->enabled = true; + + return 0; +} + +static const struct udevice_id misc_sandbox_ids[] = { + { .compatible = "sandbox,misc_sandbox" }, + { } +}; + +U_BOOT_DRIVER(misc_sandbox) = { + .name = "misc_sandbox", + .id = UCLASS_MISC, + .ops = &misc_sandbox_ops, + .of_match = misc_sandbox_ids, + .probe = misc_sandbox_probe, + .priv_auto_alloc_size = sizeof(struct misc_sandbox_priv), +}; diff --git a/test/dm/Makefile b/test/dm/Makefile index d2ed96c6153..ff0807873b0 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -44,4 +44,5 @@ obj-$(CONFIG_DM_VIDEO) += video.o obj-$(CONFIG_ADC) += adc.o obj-$(CONFIG_SPMI) += spmi.o obj-$(CONFIG_WDT) += wdt.o +obj-$(CONFIG_MISC) += misc.o endif diff --git a/test/dm/misc.c b/test/dm/misc.c new file mode 100644 index 00000000000..61279665ef2 --- /dev/null +++ b/test/dm/misc.c @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2018 + * Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc + */ + +#include +#include +#include +#include +#include + +static int dm_test_misc(struct unit_test_state *uts) +{ + struct udevice *dev; + u8 buf[16]; + int id; + ulong last_ioctl; + bool enabled; + + ut_assertok(uclass_get_device_by_name(UCLASS_MISC, "misc-test", &dev)); + + /* Read / write tests */ + ut_assertok(misc_write(dev, 0, "TEST", 4)); + ut_assertok(misc_write(dev, 4, "WRITE", 5)); + ut_assertok(misc_read(dev, 0, buf, 9)); + + ut_assertok(memcmp(buf, "TESTWRITE", 9)); + + /* Call tests */ + + id = 0; + ut_assertok(misc_call(dev, 0, &id, 4, buf, 16)); + ut_assertok(memcmp(buf, "Zero", 4)); + + id = 2; + ut_assertok(misc_call(dev, 0, &id, 4, buf, 16)); + ut_assertok(memcmp(buf, "Two", 3)); + + ut_assertok(misc_call(dev, 1, &id, 4, buf, 16)); + ut_assertok(memcmp(buf, "Forty-two", 9)); + + id = 1; + ut_assertok(misc_call(dev, 1, &id, 4, buf, 16)); + ut_assertok(memcmp(buf, "Forty-one", 9)); + + /* IOCTL tests */ + + ut_assertok(misc_ioctl(dev, 6, NULL)); + /* Read back last issued ioctl */ + ut_assertok(misc_call(dev, 2, NULL, 0, &last_ioctl, + sizeof(last_ioctl))); + ut_asserteq(6, last_ioctl) + + ut_assertok(misc_ioctl(dev, 23, NULL)); + /* Read back last issued ioctl */ + ut_assertok(misc_call(dev, 2, NULL, 0, &last_ioctl, + sizeof(last_ioctl))); + ut_asserteq(23, last_ioctl) + + /* Enable / disable tests */ + + /* Read back enable/disable status */ + ut_assertok(misc_call(dev, 3, NULL, 0, &enabled, + sizeof(enabled))); + ut_asserteq(true, enabled); + + ut_assertok(misc_set_enabled(dev, false)); + /* Read back enable/disable status */ + ut_assertok(misc_call(dev, 3, NULL, 0, &enabled, + sizeof(enabled))); + ut_asserteq(false, enabled); + + ut_assertok(misc_set_enabled(dev, true)); + /* Read back enable/disable status */ + ut_assertok(misc_call(dev, 3, NULL, 0, &enabled, + sizeof(enabled))); + ut_asserteq(true, enabled); + + return 0; +} + +DM_TEST(dm_test_misc, DM_TESTF_SCAN_FDT);