mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2026-06-13 15:03:58 +03:00
power: regulator: qcom-rpmh-regulator: adjust probe for U-Boot
Refactor initialization to use U-Boot's driver model and API. Acked-by: Sumit Garg <sumit.garg@linaro.org> Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
This commit is contained in:
@@ -412,36 +412,104 @@ static const struct rpmh_vreg_init_data pm8150l_vreg_data[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
static int rpmh_regulator_probe(struct platform_device *pdev)
|
||||
/* probe an individual regulator */
|
||||
static int rpmh_regulator_probe(struct udevice *dev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
const struct rpmh_vreg_init_data *vreg_data;
|
||||
struct device_node *node;
|
||||
struct rpmh_vreg *vreg;
|
||||
const char *pmic_id;
|
||||
int ret;
|
||||
const struct rpmh_vreg_init_data *init_data;
|
||||
struct rpmh_vreg *priv;
|
||||
struct dm_regulator_uclass_plat *plat_data;
|
||||
|
||||
vreg_data = of_device_get_match_data(dev);
|
||||
if (!vreg_data)
|
||||
init_data = (const struct rpmh_vreg_init_data *)dev_get_driver_data(dev);
|
||||
priv = dev_get_priv(dev);
|
||||
plat_data = dev_get_uclass_plat(dev);
|
||||
|
||||
priv->dev = dev;
|
||||
priv->addr = cmd_db_read_addr(dev->name);
|
||||
if (!priv->addr) {
|
||||
dev_err(dev, "Failed to read RPMh address for %s\n", dev->name);
|
||||
return -ENODEV;
|
||||
|
||||
ret = of_property_read_string(dev->of_node, "qcom,pmic-id", &pmic_id);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "qcom,pmic-id missing in DT node\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
for_each_available_child_of_node(dev->of_node, node) {
|
||||
vreg = devm_kzalloc(dev, sizeof(*vreg), GFP_KERNEL);
|
||||
if (!vreg) {
|
||||
of_node_put(node);
|
||||
priv->hw_data = init_data->hw_data;
|
||||
priv->enabled = -EINVAL;
|
||||
priv->uv = -ENOTRECOVERABLE;
|
||||
if (ofnode_read_u32(dev_ofnode(dev), "regulator-initial-mode", &priv->mode))
|
||||
priv->mode = -EINVAL;
|
||||
|
||||
plat_data->mode = priv->hw_data->pmic_mode_map;
|
||||
plat_data->mode_count = priv->hw_data->n_modes;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* for non-drm, xob, or bypass regulators add additional driver definitions */
|
||||
U_BOOT_DRIVER(rpmh_regulator_drm) = {
|
||||
.name = "rpmh_regulator_drm",
|
||||
.id = UCLASS_REGULATOR,
|
||||
.probe = rpmh_regulator_probe,
|
||||
.priv_auto = sizeof(struct rpmh_vreg),
|
||||
.ops = &rpmh_regulator_vrm_drms_ops,
|
||||
};
|
||||
|
||||
/* This driver intentionally only supports a subset of the available regulators.
|
||||
* This function checks to see if a given regulator node in DT matches a regulator
|
||||
* defined in the driver.
|
||||
*/
|
||||
static const struct rpmh_vreg_init_data *
|
||||
vreg_get_init_data(const struct rpmh_vreg_init_data *init_data, ofnode node)
|
||||
{
|
||||
const struct rpmh_vreg_init_data *data;
|
||||
|
||||
for (data = init_data; data->name; data++) {
|
||||
if (!strcmp(data->name, ofnode_get_name(node)))
|
||||
return data;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int rpmh_regulators_bind(struct udevice *dev)
|
||||
{
|
||||
const struct rpmh_vreg_init_data *init_data, *data;
|
||||
const char *pmic_id;
|
||||
char *name;
|
||||
struct driver *drv;
|
||||
ofnode node;
|
||||
int ret;
|
||||
size_t namelen;
|
||||
|
||||
init_data = (const struct rpmh_vreg_init_data *)dev_get_driver_data(dev);
|
||||
if (!init_data) {
|
||||
dev_err(dev, "No RPMh regulator init data\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
pmic_id = ofnode_read_string(dev_ofnode(dev), "qcom,pmic-id");
|
||||
if (!pmic_id) {
|
||||
dev_err(dev, "No PMIC ID\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
drv = lists_driver_lookup_name("rpmh_regulator_drm");
|
||||
|
||||
ofnode_for_each_subnode(node, dev_ofnode(dev)) {
|
||||
data = vreg_get_init_data(init_data, node);
|
||||
if (!data)
|
||||
continue;
|
||||
|
||||
/* %s is replaced with pmic_id, so subtract 2, then add 1 for the null terminator */
|
||||
namelen = strlen(data->resource_name) + strlen(pmic_id) - 1;
|
||||
name = devm_kzalloc(dev, namelen, GFP_KERNEL);
|
||||
ret = snprintf(name, namelen, data->resource_name, pmic_id);
|
||||
if (ret < 0 || ret >= namelen) {
|
||||
dev_err(dev, "Failed to create RPMh regulator name\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = rpmh_regulator_init_vreg(vreg, dev, node, pmic_id,
|
||||
vreg_data);
|
||||
ret = device_bind_with_driver_data(dev, drv, name, (ulong)data,
|
||||
node, NULL);
|
||||
if (ret < 0) {
|
||||
of_node_put(node);
|
||||
dev_err(dev, "Failed to bind RPMh regulator %s: %d\n", name, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@@ -449,28 +517,28 @@ static int rpmh_regulator_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id __maybe_unused rpmh_regulator_match_table[] = {
|
||||
static const struct udevice_id rpmh_regulator_ids[] = {
|
||||
{
|
||||
.compatible = "qcom,pm8150-rpmh-regulators",
|
||||
.data = pm8150_vreg_data,
|
||||
.data = (ulong)pm8150_vreg_data,
|
||||
},
|
||||
{
|
||||
.compatible = "qcom,pm8150l-rpmh-regulators",
|
||||
.data = pm8150l_vreg_data,
|
||||
.data = (ulong)pm8150l_vreg_data,
|
||||
},
|
||||
{}
|
||||
{ /* sentinal */ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, rpmh_regulator_match_table);
|
||||
|
||||
static struct platform_driver rpmh_regulator_driver = {
|
||||
.driver = {
|
||||
.name = "qcom-rpmh-regulator",
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.of_match_table = of_match_ptr(rpmh_regulator_match_table),
|
||||
},
|
||||
.probe = rpmh_regulator_probe,
|
||||
/* Driver for a 'bank' of regulators. This creates devices for each
|
||||
* individual regulator
|
||||
*/
|
||||
U_BOOT_DRIVER(rpmh_regulators) = {
|
||||
.name = "rpmh_regulators",
|
||||
.id = UCLASS_MISC,
|
||||
.bind = rpmh_regulators_bind,
|
||||
.of_match = rpmh_regulator_ids,
|
||||
.ops = &rpmh_regulator_vrm_drms_ops,
|
||||
};
|
||||
module_platform_driver(rpmh_regulator_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Qualcomm RPMh regulator driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
||||
Reference in New Issue
Block a user