diff options
-rw-r--r-- | drivers/misc/Kconfig | 9 | ||||
-rw-r--r-- | drivers/misc/Makefile | 1 | ||||
-rw-r--r-- | drivers/misc/test_drv.c | 222 | ||||
-rw-r--r-- | include/dm/test.h | 18 | ||||
-rw-r--r-- | include/test/test.h | 9 | ||||
-rw-r--r-- | test/dm/bus.c | 105 | ||||
-rw-r--r-- | test/dm/test-fdt.c | 120 |
7 files changed, 263 insertions, 221 deletions
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 29432ae..7d2a299 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -343,6 +343,15 @@ config TEGRA186_BPMP can make requests to the BPMP. This driver is similar to an MFD driver in the Linux kernel. +config TEST_DRV + bool "Enable support for test drivers" + default y if SANDBOX + help + This enables drivers and uclasses that provides a way of testing the + operations of memory allocation and driver/uclass methods in driver + model. This should only be enabled for testing as it is not useful for + anything else. + config TWL4030_LED bool "Enable TWL4030 LED controller" help diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 947bd3a..d737203 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -67,6 +67,7 @@ obj-$(CONFIG_STM32_RCC) += stm32_rcc.o obj-$(CONFIG_SYS_DPAA_QBMAN) += fsl_portals.o obj-$(CONFIG_TEGRA186_BPMP) += tegra186_bpmp.o obj-$(CONFIG_TEGRA_CAR) += tegra_car.o +obj-$(CONFIG_TEST_DRV) += test_drv.o obj-$(CONFIG_TWL4030_LED) += twl4030_led.o obj-$(CONFIG_VEXPRESS_CONFIG) += vexpress_config.o obj-$(CONFIG_WINBOND_W83627) += winbond_w83627.o diff --git a/drivers/misc/test_drv.c b/drivers/misc/test_drv.c new file mode 100644 index 0000000..7dd3de3 --- /dev/null +++ b/drivers/misc/test_drv.c @@ -0,0 +1,222 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2014 Google, Inc + */ + +#include <common.h> +#include <dm.h> +#include <dm/test.h> + +/* Records the last testbus device that was removed */ +static struct udevice *testbus_removed; + +struct udevice *testbus_get_clear_removed(void) +{ + struct udevice *removed = testbus_removed; + + testbus_removed = NULL; + + return removed; +} + +static int testbus_drv_probe(struct udevice *dev) +{ + if (!CONFIG_IS_ENABLED(OF_PLATDATA)) { + int ret; + + ret = dm_scan_fdt_dev(dev); + if (ret) + return ret; + } + + return 0; +} + +static int testbus_child_post_bind(struct udevice *dev) +{ + struct dm_test_parent_plat *plat; + + plat = dev_get_parent_plat(dev); + plat->bind_flag = 1; + plat->uclass_bind_flag = 2; + + return 0; +} + +static int testbus_child_pre_probe(struct udevice *dev) +{ + struct dm_test_parent_data *parent_data = dev_get_parent_priv(dev); + + parent_data->flag += TEST_FLAG_CHILD_PROBED; + + return 0; +} + +static int testbus_child_pre_probe_uclass(struct udevice *dev) +{ + struct dm_test_priv *priv = dev_get_priv(dev); + + priv->uclass_flag++; + + return 0; +} + +static int testbus_child_post_probe_uclass(struct udevice *dev) +{ + struct dm_test_priv *priv = dev_get_priv(dev); + + priv->uclass_postp++; + + return 0; +} + +static int testbus_child_post_remove(struct udevice *dev) +{ + struct dm_test_parent_data *parent_data = dev_get_parent_priv(dev); + + parent_data->flag += TEST_FLAG_CHILD_REMOVED; + testbus_removed = dev; + + return 0; +} + +static const struct udevice_id testbus_ids[] = { + { .compatible = "denx,u-boot-test-bus", .data = DM_TEST_TYPE_FIRST }, + { } +}; + +U_BOOT_DRIVER(testbus_drv) = { + .name = "testbus_drv", + .of_match = testbus_ids, + .id = UCLASS_TEST_BUS, + .probe = testbus_drv_probe, + .child_post_bind = testbus_child_post_bind, + .priv_auto = sizeof(struct dm_test_priv), + .plat_auto = sizeof(struct dm_test_pdata), + .per_child_auto = sizeof(struct dm_test_parent_data), + .per_child_plat_auto = sizeof(struct dm_test_parent_plat), + .child_pre_probe = testbus_child_pre_probe, + .child_post_remove = testbus_child_post_remove, +}; + +UCLASS_DRIVER(testbus) = { + .name = "testbus", + .id = UCLASS_TEST_BUS, + .flags = DM_UC_FLAG_SEQ_ALIAS, + .child_pre_probe = testbus_child_pre_probe_uclass, + .child_post_probe = testbus_child_post_probe_uclass, +}; + +static int testfdt_drv_ping(struct udevice *dev, int pingval, int *pingret) +{ + const struct dm_test_pdata *pdata = dev_get_plat(dev); + struct dm_test_priv *priv = dev_get_priv(dev); + + *pingret = pingval + pdata->ping_add; + priv->ping_total += *pingret; + + return 0; +} + +static const struct test_ops test_ops = { + .ping = testfdt_drv_ping, +}; + +static int testfdt_of_to_plat(struct udevice *dev) +{ + struct dm_test_pdata *pdata = dev_get_plat(dev); + + pdata->ping_add = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), + "ping-add", -1); + pdata->base = fdtdec_get_addr(gd->fdt_blob, dev_of_offset(dev), + "ping-expect"); + + return 0; +} + +static int testfdt_drv_probe(struct udevice *dev) +{ + struct dm_test_priv *priv = dev_get_priv(dev); + + priv->ping_total += DM_TEST_START_TOTAL; + + /* + * If this device is on a bus, the uclass_flag will be set before + * calling this function. In the meantime the uclass_postp is + * initlized to a value -1. These are used respectively by + * dm_test_bus_child_pre_probe_uclass() and + * dm_test_bus_child_post_probe_uclass(). + */ + priv->uclass_total += priv->uclass_flag; + priv->uclass_postp = -1; + + return 0; +} + +static const struct udevice_id testfdt_ids[] = { + { .compatible = "denx,u-boot-fdt-test", .data = DM_TEST_TYPE_FIRST }, + { .compatible = "google,another-fdt-test", .data = DM_TEST_TYPE_SECOND }, + { } +}; + +U_BOOT_DRIVER(testfdt_drv) = { + .name = "testfdt_drv", + .of_match = testfdt_ids, + .id = UCLASS_TEST_FDT, + .of_to_plat = testfdt_of_to_plat, + .probe = testfdt_drv_probe, + .ops = &test_ops, + .priv_auto = sizeof(struct dm_test_priv), + .plat_auto = sizeof(struct dm_test_pdata), +}; + +static const struct udevice_id testfdt1_ids[] = { + { .compatible = "denx,u-boot-fdt-test1", .data = DM_TEST_TYPE_FIRST }, + { } +}; + +U_BOOT_DRIVER(testfdt1_drv) = { + .name = "testfdt1_drv", + .of_match = testfdt1_ids, + .id = UCLASS_TEST_FDT, + .of_to_plat = testfdt_of_to_plat, + .probe = testfdt_drv_probe, + .ops = &test_ops, + .priv_auto = sizeof(struct dm_test_priv), + .plat_auto = sizeof(struct dm_test_pdata), + .flags = DM_FLAG_PRE_RELOC, +}; + +/* From here is the testfdt uclass code */ +int testfdt_ping(struct udevice *dev, int pingval, int *pingret) +{ + const struct test_ops *ops = device_get_ops(dev); + + if (!ops->ping) + return -ENOSYS; + + return ops->ping(dev, pingval, pingret); +} + +UCLASS_DRIVER(testfdt) = { + .name = "testfdt", + .id = UCLASS_TEST_FDT, + .flags = DM_UC_FLAG_SEQ_ALIAS, +}; + +static const struct udevice_id testfdtm_ids[] = { + { .compatible = "denx,u-boot-fdtm-test" }, + { } +}; + +U_BOOT_DRIVER(testfdtm_drv) = { + .name = "testfdtm_drv", + .of_match = testfdtm_ids, + .id = UCLASS_TEST_FDT_MANUAL, +}; + +UCLASS_DRIVER(testfdtm) = { + .name = "testfdtm", + .id = UCLASS_TEST_FDT_MANUAL, + .flags = DM_UC_FLAG_SEQ_ALIAS | DM_UC_FLAG_NO_AUTO_SEQ, +}; diff --git a/include/dm/test.h b/include/dm/test.h index cbe1b57..6ac6672 100644 --- a/include/dm/test.h +++ b/include/dm/test.h @@ -167,6 +167,24 @@ struct sandbox_sdl_plat { int font_size; }; +/** + * struct dm_test_parent_plat - Used to track state in bus tests + * + * @count: + * @bind_flag: Indicates that the child post-bind method was called + * @uclass_bind_flag: Also indicates that the child post-bind method was called + */ +struct dm_test_parent_plat { + int count; + int bind_flag; + int uclass_bind_flag; +}; + +enum { + TEST_FLAG_CHILD_PROBED = 10, + TEST_FLAG_CHILD_REMOVED = -7, +}; + /* Declare ping methods for the drivers */ int test_ping(struct udevice *dev, int pingval, int *pingret); int testfdt_ping(struct udevice *dev, int pingval, int *pingret); diff --git a/include/test/test.h b/include/test/test.h index 03e2929..3fdaa2b 100644 --- a/include/test/test.h +++ b/include/test/test.h @@ -95,6 +95,15 @@ enum { }; /** + * testbus_get_clear_removed() - Test function to obtain removed device + * + * This is used in testbus to find out which device was removed. Calling this + * function returns a pointer to the device and then clears it back to NULL, so + * that a future test can check it. + */ +struct udevice *testbus_get_clear_removed(void); + +/** * dm_test_main() - Run driver model tests * * Run all the available driver model tests, or a selection diff --git a/test/dm/bus.c b/test/dm/bus.c index b95c106..785ccfc 100644 --- a/test/dm/bus.c +++ b/test/dm/bus.c @@ -19,102 +19,6 @@ DECLARE_GLOBAL_DATA_PTR; -struct dm_test_parent_plat { - int count; - int bind_flag; - int uclass_bind_flag; -}; - -enum { - FLAG_CHILD_PROBED = 10, - FLAG_CHILD_REMOVED = -7, -}; - -/* Records the last testbus device that was removed */ -static struct udevice *testbus_removed; - -static int testbus_drv_probe(struct udevice *dev) -{ - return dm_scan_fdt_dev(dev); -} - -static int testbus_child_post_bind(struct udevice *dev) -{ - struct dm_test_parent_plat *plat; - - plat = dev_get_parent_plat(dev); - plat->bind_flag = 1; - plat->uclass_bind_flag = 2; - - return 0; -} - -static int testbus_child_pre_probe(struct udevice *dev) -{ - struct dm_test_parent_data *parent_data = dev_get_parent_priv(dev); - - parent_data->flag += FLAG_CHILD_PROBED; - - return 0; -} - -static int testbus_child_pre_probe_uclass(struct udevice *dev) -{ - struct dm_test_priv *priv = dev_get_priv(dev); - - priv->uclass_flag++; - - return 0; -} - -static int testbus_child_post_probe_uclass(struct udevice *dev) -{ - struct dm_test_priv *priv = dev_get_priv(dev); - - priv->uclass_postp++; - - return 0; -} - -static int testbus_child_post_remove(struct udevice *dev) -{ - struct dm_test_parent_data *parent_data = dev_get_parent_priv(dev); - - parent_data->flag += FLAG_CHILD_REMOVED; - testbus_removed = dev; - - return 0; -} - -static const struct udevice_id testbus_ids[] = { - { - .compatible = "denx,u-boot-test-bus", - .data = DM_TEST_TYPE_FIRST }, - { } -}; - -U_BOOT_DRIVER(testbus_drv) = { - .name = "testbus_drv", - .of_match = testbus_ids, - .id = UCLASS_TEST_BUS, - .probe = testbus_drv_probe, - .child_post_bind = testbus_child_post_bind, - .priv_auto = sizeof(struct dm_test_priv), - .plat_auto = sizeof(struct dm_test_pdata), - .per_child_auto = sizeof(struct dm_test_parent_data), - .per_child_plat_auto = sizeof(struct dm_test_parent_plat), - .child_pre_probe = testbus_child_pre_probe, - .child_post_remove = testbus_child_post_remove, -}; - -UCLASS_DRIVER(testbus) = { - .name = "testbus", - .id = UCLASS_TEST_BUS, - .flags = DM_UC_FLAG_SEQ_ALIAS, - .child_pre_probe = testbus_child_pre_probe_uclass, - .child_post_probe = testbus_child_post_probe_uclass, -}; - /* Test that we can probe for children */ static int dm_test_bus_children(struct unit_test_state *uts) { @@ -337,7 +241,7 @@ static int dm_test_bus_parent_ops(struct unit_test_state *uts) struct udevice *bus, *dev; struct uclass *uc; - testbus_removed = NULL; + testbus_get_clear_removed(); ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus)); ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc)); @@ -349,7 +253,7 @@ static int dm_test_bus_parent_ops(struct unit_test_state *uts) ut_assertok(device_probe(dev)); parent_data = dev_get_parent_priv(dev); - ut_asserteq(FLAG_CHILD_PROBED, parent_data->flag); + ut_asserteq(TEST_FLAG_CHILD_PROBED, parent_data->flag); } uclass_foreach_dev(dev, uc) { @@ -357,12 +261,11 @@ static int dm_test_bus_parent_ops(struct unit_test_state *uts) if (dev->parent != bus) continue; parent_data = dev_get_parent_priv(dev); - ut_asserteq(FLAG_CHILD_PROBED, parent_data->flag); + ut_asserteq(TEST_FLAG_CHILD_PROBED, parent_data->flag); ut_assertok(device_remove(dev, DM_REMOVE_NORMAL)); ut_asserteq_ptr(NULL, dev_get_parent_priv(dev)); - ut_asserteq_ptr(testbus_removed, dev); + ut_asserteq_ptr(testbus_get_clear_removed(), dev); } - testbus_removed = NULL; return 0; } diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c index 9e8c290..6332568 100644 --- a/test/dm/test-fdt.c +++ b/test/dm/test-fdt.c @@ -23,126 +23,6 @@ DECLARE_GLOBAL_DATA_PTR; -static int testfdt_drv_ping(struct udevice *dev, int pingval, int *pingret) -{ - const struct dm_test_pdata *pdata = dev_get_plat(dev); - struct dm_test_priv *priv = dev_get_priv(dev); - - *pingret = pingval + pdata->ping_add; - priv->ping_total += *pingret; - - return 0; -} - -static const struct test_ops test_ops = { - .ping = testfdt_drv_ping, -}; - -static int testfdt_of_to_plat(struct udevice *dev) -{ - struct dm_test_pdata *pdata = dev_get_plat(dev); - - pdata->ping_add = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), - "ping-add", -1); - pdata->base = fdtdec_get_addr(gd->fdt_blob, dev_of_offset(dev), - "ping-expect"); - - return 0; -} - -static int testfdt_drv_probe(struct udevice *dev) -{ - struct dm_test_priv *priv = dev_get_priv(dev); - - priv->ping_total += DM_TEST_START_TOTAL; - - /* - * If this device is on a bus, the uclass_flag will be set before - * calling this function. In the meantime the uclass_postp is - * initlized to a value -1. These are used respectively by - * dm_test_bus_child_pre_probe_uclass() and - * dm_test_bus_child_post_probe_uclass(). - */ - priv->uclass_total += priv->uclass_flag; - priv->uclass_postp = -1; - - return 0; -} - -static const struct udevice_id testfdt_ids[] = { - { - .compatible = "denx,u-boot-fdt-test", - .data = DM_TEST_TYPE_FIRST }, - { - .compatible = "google,another-fdt-test", - .data = DM_TEST_TYPE_SECOND }, - { } -}; - -U_BOOT_DRIVER(testfdt_drv) = { - .name = "testfdt_drv", - .of_match = testfdt_ids, - .id = UCLASS_TEST_FDT, - .of_to_plat = testfdt_of_to_plat, - .probe = testfdt_drv_probe, - .ops = &test_ops, - .priv_auto = sizeof(struct dm_test_priv), - .plat_auto = sizeof(struct dm_test_pdata), -}; - -static const struct udevice_id testfdt1_ids[] = { - { - .compatible = "denx,u-boot-fdt-test1", - .data = DM_TEST_TYPE_FIRST }, - { } -}; - -U_BOOT_DRIVER(testfdt1_drv) = { - .name = "testfdt1_drv", - .of_match = testfdt1_ids, - .id = UCLASS_TEST_FDT, - .of_to_plat = testfdt_of_to_plat, - .probe = testfdt_drv_probe, - .ops = &test_ops, - .priv_auto = sizeof(struct dm_test_priv), - .plat_auto = sizeof(struct dm_test_pdata), - .flags = DM_FLAG_PRE_RELOC, -}; - -/* From here is the testfdt uclass code */ -int testfdt_ping(struct udevice *dev, int pingval, int *pingret) -{ - const struct test_ops *ops = device_get_ops(dev); - - if (!ops->ping) - return -ENOSYS; - - return ops->ping(dev, pingval, pingret); -} - -UCLASS_DRIVER(testfdt) = { - .name = "testfdt", - .id = UCLASS_TEST_FDT, - .flags = DM_UC_FLAG_SEQ_ALIAS, -}; - -static const struct udevice_id testfdtm_ids[] = { - { .compatible = "denx,u-boot-fdtm-test" }, - { } -}; - -U_BOOT_DRIVER(testfdtm_drv) = { - .name = "testfdtm_drv", - .of_match = testfdtm_ids, - .id = UCLASS_TEST_FDT_MANUAL, -}; - -UCLASS_DRIVER(testfdtm) = { - .name = "testfdtm", - .id = UCLASS_TEST_FDT_MANUAL, - .flags = DM_UC_FLAG_SEQ_ALIAS | DM_UC_FLAG_NO_AUTO_SEQ, -}; - struct dm_testprobe_pdata { int probe_err; }; |