|
@@ -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,
|
|
|
+};
|