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
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
--- /dev/null
+// 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,
+};
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);
TEST_DEVRES_SIZE3 = 37,
};
+/**
+ * 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
*
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)
{
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));
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) {
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;
}
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;
};