Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | // SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2020-2021, Linaro Limited */ #define LOG_CATEGORY UCLASS_MISC #include <clk.h> #include <dm.h> #include <log.h> #include <malloc.h> #include <reset.h> #include <asm/io.h> #include <asm/scmi_test.h> #include <dm/device_compat.h> #include <power/regulator.h> /* * Simulate to some extent a SCMI exchange. * This drivers gets SCMI resources and offers API function to the * SCMI test sequence manipulate the resources, currently clock * and reset controllers. */ #define SCMI_TEST_DEVICES_CLK_COUNT 2 #define SCMI_TEST_DEVICES_RD_COUNT 1 #define SCMI_TEST_DEVICES_VOLTD_COUNT 2 /* * struct sandbox_scmi_device_priv - Storage for device handles used by test * @pwdom: Power domain device * @clk: Array of clock instances used by tests * @reset_clt: Array of the reset controller instances used by tests * @regulators: Array of regulator device references used by the tests * @devices: Resources exposed by sandbox_scmi_devices_ctx() */ struct sandbox_scmi_device_priv { struct power_domain pwdom; struct clk clk[SCMI_TEST_DEVICES_CLK_COUNT]; struct reset_ctl reset_ctl[SCMI_TEST_DEVICES_RD_COUNT]; struct udevice *regulators[SCMI_TEST_DEVICES_VOLTD_COUNT]; struct sandbox_scmi_devices devices; }; struct sandbox_scmi_devices *sandbox_scmi_devices_ctx(struct udevice *dev) { struct sandbox_scmi_device_priv *priv = dev_get_priv(dev); if (priv) return &priv->devices; return NULL; } static int sandbox_scmi_devices_remove(struct udevice *dev) { struct sandbox_scmi_devices *devices = sandbox_scmi_devices_ctx(dev); int ret = 0; size_t n; if (!devices) return 0; if (CONFIG_IS_ENABLED(RESET_SCMI)) for (n = 0; n < SCMI_TEST_DEVICES_RD_COUNT; n++) { int ret2 = reset_free(devices->reset + n); if (ret2 && !ret) ret = ret2; } return ret; } static int sandbox_scmi_devices_probe(struct udevice *dev) { struct sandbox_scmi_device_priv *priv = dev_get_priv(dev); int ret; size_t n; priv->devices = (struct sandbox_scmi_devices){ .pwdom = &priv->pwdom, .pwdom_count = 1, .clk = priv->clk, .clk_count = SCMI_TEST_DEVICES_CLK_COUNT, .reset = priv->reset_ctl, .reset_count = SCMI_TEST_DEVICES_RD_COUNT, .regul = priv->regulators, .regul_count = SCMI_TEST_DEVICES_VOLTD_COUNT, }; if (CONFIG_IS_ENABLED(SCMI_POWER_DOMAIN)) { ret = power_domain_get_by_index(dev, priv->devices.pwdom, 0); if (ret) { dev_err(dev, "%s: Failed on power domain\n", __func__); return ret; } } if (CONFIG_IS_ENABLED(CLK_SCMI)) { for (n = 0; n < SCMI_TEST_DEVICES_CLK_COUNT; n++) { ret = clk_get_by_index(dev, n, priv->devices.clk + n); if (ret) { dev_err(dev, "%s: Failed on clk %zu\n", __func__, n); return ret; } } } if (CONFIG_IS_ENABLED(RESET_SCMI)) { for (n = 0; n < SCMI_TEST_DEVICES_RD_COUNT; n++) { ret = reset_get_by_index(dev, n, priv->devices.reset + n); if (ret) { dev_err(dev, "%s: Failed on reset %zu\n", __func__, n); goto err_reset; } } } if (CONFIG_IS_ENABLED(DM_REGULATOR_SCMI)) { for (n = 0; n < SCMI_TEST_DEVICES_VOLTD_COUNT; n++) { char name[32]; ret = snprintf(name, sizeof(name), "regul%zu-supply", n); assert(ret >= 0 && ret < sizeof(name)); ret = device_get_supply_regulator(dev, name, priv->devices.regul + n); if (ret) { dev_err(dev, "%s: Failed on voltd %zu\n", __func__, n); goto err_regul; } } } return 0; err_regul: n = SCMI_TEST_DEVICES_RD_COUNT; err_reset: if (CONFIG_IS_ENABLED(RESET_SCMI)) for (; n > 0; n--) reset_free(priv->devices.reset + n - 1); return ret; } static const struct udevice_id sandbox_scmi_devices_ids[] = { { .compatible = "sandbox,scmi-devices" }, { } }; U_BOOT_DRIVER(sandbox_scmi_devices) = { .name = "sandbox-scmi_devices", .id = UCLASS_MISC, .of_match = sandbox_scmi_devices_ids, .priv_auto = sizeof(struct sandbox_scmi_device_priv), .remove = sandbox_scmi_devices_remove, .probe = sandbox_scmi_devices_probe, .flags = DM_FLAG_DEFAULT_PD_CTRL_OFF, }; |