uboot/drivers/misc/test_drv.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (c) 2014 Google, Inc
   4 */
   5
   6#include <common.h>
   7#include <dm.h>
   8#include <dm/test.h>
   9#include <asm/global_data.h>
  10
  11/* Records the last testbus device that was removed */
  12static struct udevice *testbus_removed;
  13
  14struct udevice *testbus_get_clear_removed(void)
  15{
  16        struct udevice *removed = testbus_removed;
  17
  18        testbus_removed = NULL;
  19
  20        return removed;
  21}
  22
  23static int testbus_drv_probe(struct udevice *dev)
  24{
  25        if (!CONFIG_IS_ENABLED(OF_PLATDATA)) {
  26                int ret;
  27
  28                ret = dm_scan_fdt_dev(dev);
  29                if (ret)
  30                        return ret;
  31        }
  32
  33        return 0;
  34}
  35
  36static int testbus_child_post_bind(struct udevice *dev)
  37{
  38        struct dm_test_parent_plat *plat;
  39
  40        plat = dev_get_parent_plat(dev);
  41        plat->bind_flag = 1;
  42        plat->uclass_bind_flag = 2;
  43
  44        return 0;
  45}
  46
  47static int testbus_child_pre_probe(struct udevice *dev)
  48{
  49        struct dm_test_parent_data *parent_data = dev_get_parent_priv(dev);
  50
  51        parent_data->flag += TEST_FLAG_CHILD_PROBED;
  52
  53        return 0;
  54}
  55
  56static int testbus_child_pre_probe_uclass(struct udevice *dev)
  57{
  58        struct dm_test_priv *priv = dev_get_priv(dev);
  59
  60        priv->uclass_flag++;
  61
  62        return 0;
  63}
  64
  65static int testbus_child_post_probe_uclass(struct udevice *dev)
  66{
  67        struct dm_test_priv *priv = dev_get_priv(dev);
  68
  69        priv->uclass_postp++;
  70
  71        return 0;
  72}
  73
  74static int testbus_child_post_remove(struct udevice *dev)
  75{
  76        struct dm_test_parent_data *parent_data = dev_get_parent_priv(dev);
  77
  78        parent_data->flag += TEST_FLAG_CHILD_REMOVED;
  79        testbus_removed = dev;
  80
  81        return 0;
  82}
  83
  84static const struct udevice_id testbus_ids[] = {
  85        { .compatible = "denx,u-boot-test-bus", .data = DM_TEST_TYPE_FIRST },
  86        { }
  87};
  88
  89U_BOOT_DRIVER(denx_u_boot_test_bus) = {
  90        .name   = "testbus_drv",
  91        .of_match       = testbus_ids,
  92        .id     = UCLASS_TEST_BUS,
  93        .probe  = testbus_drv_probe,
  94        .child_post_bind = testbus_child_post_bind,
  95        .priv_auto      = sizeof(struct dm_test_priv),
  96        .plat_auto      = sizeof(struct dm_test_pdata),
  97        .per_child_auto = sizeof(struct dm_test_parent_data),
  98        .per_child_plat_auto    = sizeof(struct dm_test_parent_plat),
  99        .child_pre_probe = testbus_child_pre_probe,
 100        .child_post_remove = testbus_child_post_remove,
 101        DM_HEADER(<test.h>)
 102};
 103
 104UCLASS_DRIVER(testbus) = {
 105        .name           = "testbus",
 106        .id             = UCLASS_TEST_BUS,
 107        .flags          = DM_UC_FLAG_SEQ_ALIAS,
 108        .child_pre_probe = testbus_child_pre_probe_uclass,
 109        .child_post_probe = testbus_child_post_probe_uclass,
 110
 111        /* This is for dtoc testing only */
 112        .per_device_plat_auto   = sizeof(struct dm_test_uclass_priv),
 113};
 114
 115static int testfdt_drv_ping(struct udevice *dev, int pingval, int *pingret)
 116{
 117        const struct dm_test_pdata *pdata = dev_get_plat(dev);
 118        struct dm_test_priv *priv = dev_get_priv(dev);
 119
 120        *pingret = pingval + pdata->ping_add;
 121        priv->ping_total += *pingret;
 122
 123        return 0;
 124}
 125
 126static const struct test_ops test_ops = {
 127        .ping = testfdt_drv_ping,
 128};
 129
 130static int testfdt_of_to_plat(struct udevice *dev)
 131{
 132        struct dm_test_pdata *pdata = dev_get_plat(dev);
 133
 134        pdata->ping_add = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 135                                         "ping-add", -1);
 136        pdata->base = fdtdec_get_addr(gd->fdt_blob, dev_of_offset(dev),
 137                                      "ping-expect");
 138
 139        return 0;
 140}
 141
 142static int testfdt_drv_probe(struct udevice *dev)
 143{
 144        struct dm_test_priv *priv = dev_get_priv(dev);
 145
 146        priv->ping_total += DM_TEST_START_TOTAL;
 147
 148        /*
 149         * If this device is on a bus, the uclass_flag will be set before
 150         * calling this function. In the meantime the uclass_postp is
 151         * initlized to a value -1. These are used respectively by
 152         * dm_test_bus_child_pre_probe_uclass() and
 153         * dm_test_bus_child_post_probe_uclass().
 154         */
 155        priv->uclass_total += priv->uclass_flag;
 156        priv->uclass_postp = -1;
 157
 158        return 0;
 159}
 160
 161static const struct udevice_id testfdt_ids[] = {
 162        { .compatible = "denx,u-boot-fdt-test", .data = DM_TEST_TYPE_FIRST },
 163        { .compatible = "google,another-fdt-test", .data = DM_TEST_TYPE_SECOND },
 164        { }
 165};
 166
 167DM_DRIVER_ALIAS(denx_u_boot_fdt_test, google_another_fdt_test)
 168
 169U_BOOT_DRIVER(denx_u_boot_fdt_test) = {
 170        .name   = "testfdt_drv",
 171        .of_match       = testfdt_ids,
 172        .id     = UCLASS_TEST_FDT,
 173        .of_to_plat = testfdt_of_to_plat,
 174        .probe  = testfdt_drv_probe,
 175        .ops    = &test_ops,
 176        .priv_auto      = sizeof(struct dm_test_priv),
 177        .plat_auto      = sizeof(struct dm_test_pdata),
 178};
 179
 180static const struct udevice_id testfdt1_ids[] = {
 181        { .compatible = "denx,u-boot-fdt-test1", .data = DM_TEST_TYPE_FIRST },
 182        { }
 183};
 184
 185U_BOOT_DRIVER(testfdt1_drv) = {
 186        .name   = "testfdt1_drv",
 187        .of_match       = testfdt1_ids,
 188        .id     = UCLASS_TEST_FDT,
 189        .of_to_plat = testfdt_of_to_plat,
 190        .probe  = testfdt_drv_probe,
 191        .ops    = &test_ops,
 192        .priv_auto      = sizeof(struct dm_test_priv),
 193        .plat_auto      = sizeof(struct dm_test_pdata),
 194        .flags = DM_FLAG_PRE_RELOC,
 195};
 196
 197/* From here is the testfdt uclass code */
 198int testfdt_ping(struct udevice *dev, int pingval, int *pingret)
 199{
 200        const struct test_ops *ops = device_get_ops(dev);
 201
 202        if (!ops->ping)
 203                return -ENOSYS;
 204
 205        return ops->ping(dev, pingval, pingret);
 206}
 207
 208UCLASS_DRIVER(testfdt) = {
 209        .name           = "testfdt",
 210        .id             = UCLASS_TEST_FDT,
 211        .flags          = DM_UC_FLAG_SEQ_ALIAS,
 212        .priv_auto      = sizeof(struct dm_test_uc_priv),
 213};
 214
 215static const struct udevice_id testfdtm_ids[] = {
 216        { .compatible = "denx,u-boot-fdtm-test" },
 217        { }
 218};
 219
 220U_BOOT_DRIVER(testfdtm_drv) = {
 221        .name   = "testfdtm_drv",
 222        .of_match       = testfdtm_ids,
 223        .id     = UCLASS_TEST_FDT_MANUAL,
 224};
 225
 226UCLASS_DRIVER(testfdtm) = {
 227        .name           = "testfdtm",
 228        .id             = UCLASS_TEST_FDT_MANUAL,
 229        .flags          = DM_UC_FLAG_SEQ_ALIAS | DM_UC_FLAG_NO_AUTO_SEQ,
 230};
 231