// SPDX-License-Identifier: GPL-2.0 // // System Control and Management Interface (SCMI) based regulator driver // // Copyright (C) 2020-2021 ARM Ltd. // // Implements a regulator driver on top of the SCMI Voltage Protocol. // // The ARM SCMI Protocol aims in general to hide as much as possible all the // underlying operational details while providing an abstracted interface for // its users to operate upon: as a consequence the resulting operational // capabilities and configurability of this regulator device are much more // limited than the ones usually available on a standard physical regulator. // // The supported SCMI regulator ops are restricted to the bare minimum: // // - 'status_ops': enable/disable/is_enabled // - 'voltage_ops': get_voltage_sel/set_voltage_sel // list_voltage/map_voltage // // Each SCMI regulator instance is associated, through the means of a proper DT // entry description, to a specific SCMI Voltage Domain.
/* * Note that SCMI voltage domains describable by linear ranges * (segments) {low, high, step} are guaranteed to come in one single * triplet by the SCMI Voltage Domain protocol support itself.
*/
vinfo = voltage_ops->info_get(sreg->ph, sreg->id); if (!vinfo) {
dev_warn(dev, "Failure to get voltage domain %d\n",
sreg->id); return -ENODEV;
}
/* * Regulator framework does not fully support negative voltages * so we discard any voltage domain reported as supporting negative * voltages: as a consequence each levels_uv entry is guaranteed to * be non-negative from here on.
*/ if (vinfo->negative_volts_allowed) {
dev_warn(dev, "Negative voltages NOT supported...skip %s\n",
sreg->of_node->full_name); return -EOPNOTSUPP;
}
sreg->desc.name = devm_kasprintf(dev, GFP_KERNEL, "%s", vinfo->name); if (!sreg->desc.name) return -ENOMEM;
sreg->desc.id = sreg->id;
sreg->desc.type = REGULATOR_VOLTAGE;
sreg->desc.owner = THIS_MODULE;
sreg->desc.of_match_full_name = true;
sreg->desc.of_match = sreg->of_node->full_name;
sreg->desc.regulators_node = "regulators"; if (vinfo->segmented)
ret = scmi_config_linear_regulator_mappings(sreg, vinfo); else
ret = scmi_config_discrete_regulator_mappings(sreg, vinfo); if (ret) return ret;
/* * Using the scmi device here to have DT searched from Voltage * protocol node down.
*/
sreg->conf.dev = dev;
/* Store for later retrieval via rdev_get_drvdata() */
sreg->conf.driver_data = sreg;
voltage_ops = handle->devm_protocol_get(sdev,
SCMI_PROTOCOL_VOLTAGE, &ph); if (IS_ERR(voltage_ops)) return PTR_ERR(voltage_ops);
num_doms = voltage_ops->num_domains_get(ph); if (!num_doms) return 0;
if (num_doms < 0) {
dev_err(&sdev->dev, "failed to get voltage domains - err:%d\n",
num_doms);
return num_doms;
}
rinfo = devm_kzalloc(&sdev->dev, sizeof(*rinfo), GFP_KERNEL); if (!rinfo) return -ENOMEM;
/* Allocate pointers array for all possible domains */
rinfo->sregv = devm_kcalloc(&sdev->dev, num_doms, sizeof(void *), GFP_KERNEL); if (!rinfo->sregv) return -ENOMEM;
rinfo->num_doms = num_doms;
/* * Start collecting into rinfo->sregv possibly good SCMI Regulators as * described by a well-formed DT entry and associated with an existing * plausible SCMI Voltage Domain number, all belonging to this SCMI * platform instance node (handle->dev->of_node).
*/
of_node_get(handle->dev->of_node);
np = of_find_node_by_name(handle->dev->of_node, "regulators");
for_each_child_of_node_scoped(np, child) {
ret = process_scmi_regulator_of_node(sdev, ph, child, rinfo); /* abort on any mem issue */ if (ret == -ENOMEM) return ret;
}
of_node_put(np); /* * Register a regulator for each valid regulator-DT-entry that we * can successfully reach via SCMI and has a valid associated voltage * domain.
*/ for (d = 0; d < num_doms; d++) { struct scmi_regulator *sreg = rinfo->sregv[d];
/* Skip empty slots */ if (!sreg) continue;
ret = scmi_regulator_common_init(sreg); /* Skip invalid voltage domains */ if (ret) continue;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.