Skip to content

Commit

Permalink
regulator: qcom: Refactor of-parsing code
Browse files Browse the repository at this point in the history
Refactor out all custom property parsing code from the probe function
into a function suitable for regulator_desc->of_parse_cb usage.

Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
  • Loading branch information
Bjorn Andersson authored and Mark Brown committed Apr 8, 2015
1 parent 4d1e4d6 commit 469a951
Showing 1 changed file with 81 additions and 60 deletions.
141 changes: 81 additions & 60 deletions drivers/regulator/qcom_rpm-regulator.c
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,9 @@ static int rpm_reg_set(struct qcom_rpm_reg *vreg,
return 0;
}

static int rpm_reg_of_parse_freq(struct device *dev, struct qcom_rpm_reg *vreg)
static int rpm_reg_of_parse_freq(struct device *dev,
struct device_node *node,
struct qcom_rpm_reg *vreg)
{
static const int freq_table[] = {
19200000, 9600000, 6400000, 4800000, 3840000, 3200000, 2740000,
Expand All @@ -659,7 +661,7 @@ static int rpm_reg_of_parse_freq(struct device *dev, struct qcom_rpm_reg *vreg)
int i;

key = "qcom,switch-mode-frequency";
ret = of_property_read_u32(dev->of_node, key, &freq);
ret = of_property_read_u32(node, key, &freq);
if (ret) {
dev_err(dev, "regulator requires %s property\n", key);
return -EINVAL;
Expand All @@ -676,84 +678,40 @@ static int rpm_reg_of_parse_freq(struct device *dev, struct qcom_rpm_reg *vreg)
return -EINVAL;
}

static int rpm_reg_probe(struct platform_device *pdev)
static int rpm_reg_of_parse(struct device_node *node,
const struct regulator_desc *desc,
struct regulator_config *config)
{
struct regulator_init_data *initdata;
const struct qcom_rpm_reg *template;
const struct of_device_id *match;
struct regulator_config config = { };
struct regulator_dev *rdev;
struct qcom_rpm_reg *vreg;
struct qcom_rpm_reg *vreg = config->driver_data;
struct device *dev = config->dev;
const char *key;
u32 force_mode;
bool pwm;
u32 val;
int ret;

match = of_match_device(rpm_of_match, &pdev->dev);
template = match->data;

vreg = devm_kmalloc(&pdev->dev, sizeof(*vreg), GFP_KERNEL);
if (!vreg) {
dev_err(&pdev->dev, "failed to allocate vreg\n");
return -ENOMEM;
}
memcpy(vreg, template, sizeof(*vreg));
mutex_init(&vreg->lock);
vreg->dev = &pdev->dev;
vreg->desc.id = -1;
vreg->desc.owner = THIS_MODULE;
vreg->desc.type = REGULATOR_VOLTAGE;
vreg->desc.name = pdev->dev.of_node->name;
vreg->desc.supply_name = "vin";

vreg->rpm = dev_get_drvdata(pdev->dev.parent);
if (!vreg->rpm) {
dev_err(&pdev->dev, "unable to retrieve handle to rpm\n");
return -ENODEV;
}

initdata = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node,
&vreg->desc);
if (!initdata)
return -EINVAL;

key = "reg";
ret = of_property_read_u32(pdev->dev.of_node, key, &val);
if (ret) {
dev_err(&pdev->dev, "failed to read %s\n", key);
return ret;
}
vreg->resource = val;

if ((vreg->parts->uV.mask || vreg->parts->mV.mask) &&
(!initdata->constraints.min_uV || !initdata->constraints.max_uV)) {
dev_err(&pdev->dev, "no voltage specified for regulator\n");
return -EINVAL;
}

key = "bias-pull-down";
if (of_property_read_bool(pdev->dev.of_node, key)) {
if (of_property_read_bool(node, key)) {
ret = rpm_reg_set(vreg, &vreg->parts->pd, 1);
if (ret) {
dev_err(&pdev->dev, "%s is invalid", key);
dev_err(dev, "%s is invalid", key);
return ret;
}
}

if (vreg->parts->freq.mask) {
ret = rpm_reg_of_parse_freq(&pdev->dev, vreg);
ret = rpm_reg_of_parse_freq(dev, node, vreg);
if (ret < 0)
return ret;
}

if (vreg->parts->pm.mask) {
key = "qcom,power-mode-hysteretic";
pwm = !of_property_read_bool(pdev->dev.of_node, key);
pwm = !of_property_read_bool(node, key);

ret = rpm_reg_set(vreg, &vreg->parts->pm, pwm);
if (ret) {
dev_err(&pdev->dev, "failed to set power mode\n");
dev_err(dev, "failed to set power mode\n");
return ret;
}
}
Expand All @@ -762,11 +720,11 @@ static int rpm_reg_probe(struct platform_device *pdev)
force_mode = -1;

key = "qcom,force-mode";
ret = of_property_read_u32(pdev->dev.of_node, key, &val);
ret = of_property_read_u32(node, key, &val);
if (ret == -EINVAL) {
val = QCOM_RPM_FORCE_MODE_NONE;
} else if (ret < 0) {
dev_err(&pdev->dev, "failed to read %s\n", key);
dev_err(dev, "failed to read %s\n", key);
return ret;
}

Expand Down Expand Up @@ -801,21 +759,84 @@ static int rpm_reg_probe(struct platform_device *pdev)
}

if (force_mode == -1) {
dev_err(&pdev->dev, "invalid force mode\n");
dev_err(dev, "invalid force mode\n");
return -EINVAL;
}

ret = rpm_reg_set(vreg, &vreg->parts->fm, force_mode);
if (ret) {
dev_err(&pdev->dev, "failed to set force mode\n");
dev_err(dev, "failed to set force mode\n");
return ret;
}
}

return 0;
}

static int rpm_reg_probe(struct platform_device *pdev)
{
struct regulator_init_data *initdata;
const struct qcom_rpm_reg *template;
const struct of_device_id *match;
struct regulator_config config = { };
struct regulator_dev *rdev;
struct qcom_rpm_reg *vreg;
const char *key;
u32 val;
int ret;

match = of_match_device(rpm_of_match, &pdev->dev);
template = match->data;

vreg = devm_kmalloc(&pdev->dev, sizeof(*vreg), GFP_KERNEL);
if (!vreg) {
dev_err(&pdev->dev, "failed to allocate vreg\n");
return -ENOMEM;
}
memcpy(vreg, template, sizeof(*vreg));
mutex_init(&vreg->lock);
vreg->dev = &pdev->dev;
vreg->desc.id = -1;
vreg->desc.owner = THIS_MODULE;
vreg->desc.type = REGULATOR_VOLTAGE;
vreg->desc.name = pdev->dev.of_node->name;
vreg->desc.supply_name = "vin";

vreg->rpm = dev_get_drvdata(pdev->dev.parent);
if (!vreg->rpm) {
dev_err(&pdev->dev, "unable to retrieve handle to rpm\n");
return -ENODEV;
}

initdata = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node,
&vreg->desc);
if (!initdata)
return -EINVAL;

key = "reg";
ret = of_property_read_u32(pdev->dev.of_node, key, &val);
if (ret) {
dev_err(&pdev->dev, "failed to read %s\n", key);
return ret;
}
vreg->resource = val;

if ((vreg->parts->uV.mask || vreg->parts->mV.mask) &&
(!initdata->constraints.min_uV || !initdata->constraints.max_uV)) {
dev_err(&pdev->dev, "no voltage specified for regulator\n");
return -EINVAL;
}


config.dev = &pdev->dev;
config.init_data = initdata;
config.driver_data = vreg;
config.of_node = pdev->dev.of_node;

ret = rpm_reg_of_parse(pdev->dev.of_node, &vreg->desc, &config);
if (ret)
return ret;

rdev = devm_regulator_register(&pdev->dev, &vreg->desc, &config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "can't register regulator\n");
Expand Down

0 comments on commit 469a951

Please sign in to comment.