From 8f4490e09694efaf7fe60ac6a1135530aa8c05ad Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Wed, 11 Feb 2015 19:39:12 -0800 Subject: regulator: core: Introduce set_load op Expose the requested load directly to the regulator implementation for hardware that does not support the normal enum based set_mode(). Signed-off-by: Bjorn Andersson Signed-off-by: Mark Brown --- drivers/regulator/core.c | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index b899947..f245214 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -648,10 +648,12 @@ static int drms_uA_update(struct regulator_dev *rdev) if (err < 0) return 0; - if (!rdev->desc->ops->get_optimum_mode) + if (!rdev->desc->ops->get_optimum_mode && + !rdev->desc->ops->set_load) return 0; - if (!rdev->desc->ops->set_mode) + if (!rdev->desc->ops->set_mode && + !rdev->desc->ops->set_load) return -EINVAL; /* get output voltage */ @@ -676,22 +678,29 @@ static int drms_uA_update(struct regulator_dev *rdev) list_for_each_entry(sibling, &rdev->consumer_list, list) current_uA += sibling->uA_load; - /* now get the optimum mode for our new total regulator load */ - mode = rdev->desc->ops->get_optimum_mode(rdev, input_uV, - output_uV, current_uA); + if (rdev->desc->ops->set_load) { + /* set the optimum mode for our new total regulator load */ + err = rdev->desc->ops->set_load(rdev, current_uA); + if (err < 0) + rdev_err(rdev, "failed to set load %d\n", current_uA); + } else { + /* now get the optimum mode for our new total regulator load */ + mode = rdev->desc->ops->get_optimum_mode(rdev, input_uV, + output_uV, current_uA); + + /* check the new mode is allowed */ + err = regulator_mode_constrain(rdev, &mode); + if (err < 0) { + rdev_err(rdev, "failed to get optimum mode @ %d uA %d -> %d uV\n", + current_uA, input_uV, output_uV); + return err; + } - /* check the new mode is allowed */ - err = regulator_mode_constrain(rdev, &mode); - if (err < 0) { - rdev_err(rdev, "failed to get optimum mode @ %d uA %d -> %d uV\n", - current_uA, input_uV, output_uV); - return err; + err = rdev->desc->ops->set_mode(rdev, mode); + if (err < 0) + rdev_err(rdev, "failed to set optimum mode %x\n", mode); } - err = rdev->desc->ops->set_mode(rdev, mode); - if (err < 0) - rdev_err(rdev, "failed to set optimum mode %x\n", mode); - return err; } -- cgit v1.1 From 2b85c28a5a7cb0f6bf5899125437812e67e02f70 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Wed, 11 Feb 2015 19:39:13 -0800 Subject: regulator: qcom-rpm: Implement set_load and enable drms Pass the requested load directly to the rpm. Signed-off-by: Bjorn Andersson Signed-off-by: Mark Brown --- drivers/regulator/qcom_rpm-regulator.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'drivers/regulator') diff --git a/drivers/regulator/qcom_rpm-regulator.c b/drivers/regulator/qcom_rpm-regulator.c index 00c5cc3..15e07c2 100644 --- a/drivers/regulator/qcom_rpm-regulator.c +++ b/drivers/regulator/qcom_rpm-regulator.c @@ -393,6 +393,28 @@ static int rpm_reg_is_enabled(struct regulator_dev *rdev) return vreg->is_enabled; } +static int rpm_reg_set_load(struct regulator_dev *rdev, int load_uA) +{ + struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev); + const struct rpm_reg_parts *parts = vreg->parts; + const struct request_member *req = &parts->ia; + int load_mA = load_uA / 1000; + int max_mA = req->mask >> req->shift; + int ret; + + if (req->mask == 0) + return -EINVAL; + + if (load_mA > max_mA) + load_mA = max_mA; + + mutex_lock(&vreg->lock); + ret = rpm_reg_write(vreg, req, load_mA); + mutex_unlock(&vreg->lock); + + return ret; +} + static struct regulator_ops uV_ops = { .list_voltage = regulator_list_voltage_linear_range, @@ -402,6 +424,8 @@ static struct regulator_ops uV_ops = { .enable = rpm_reg_uV_enable, .disable = rpm_reg_uV_disable, .is_enabled = rpm_reg_is_enabled, + + .set_load = rpm_reg_set_load, }; static struct regulator_ops mV_ops = { @@ -413,6 +437,8 @@ static struct regulator_ops mV_ops = { .enable = rpm_reg_mV_enable, .disable = rpm_reg_mV_disable, .is_enabled = rpm_reg_is_enabled, + + .set_load = rpm_reg_set_load, }; static struct regulator_ops switch_ops = { @@ -706,6 +732,10 @@ static int rpm_reg_probe(struct platform_device *pdev) return -EINVAL; } + /* Regulators with ia property suppports drms */ + if (vreg->parts->ia.mask) + initdata->constraints.valid_ops_mask |= REGULATOR_CHANGE_DRMS; + key = "bias-pull-down"; if (of_property_read_bool(pdev->dev.of_node, key)) { ret = rpm_reg_set(vreg, &vreg->parts->pd, 1); -- cgit v1.1 From af78114ec757cea281aafa3433a3a2e211e2eb67 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 21 Feb 2015 18:53:54 -0800 Subject: regulator: dbx500: Remove use of seq_puts/seq_printf return value The seq_puts/seq_printf return value, because it's frequently misused, will eventually be converted to void. See: commit 1f33c41c03da ("seq_file: Rename seq_overflow() to seq_has_overflowed() and make public") Miscellanea: o Remove unnecessary dev_err("seq_ overflow\n") messages Signed-off-by: Joe Perches Signed-off-by: Mark Brown --- drivers/regulator/dbx500-prcmu.c | 32 +++++++++----------------------- 1 file changed, 9 insertions(+), 23 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/dbx500-prcmu.c b/drivers/regulator/dbx500-prcmu.c index 2d16b9f..3963dfa 100644 --- a/drivers/regulator/dbx500-prcmu.c +++ b/drivers/regulator/dbx500-prcmu.c @@ -95,14 +95,9 @@ void ux500_regulator_resume_debug(void) static int ux500_regulator_power_state_cnt_print(struct seq_file *s, void *p) { - struct device *dev = s->private; - int err; - /* print power state count */ - err = seq_printf(s, "ux500-regulator power state count: %i\n", - power_state_active_get()); - if (err < 0) - dev_err(dev, "seq_printf overflow\n"); + seq_printf(s, "ux500-regulator power state count: %i\n", + power_state_active_get()); return 0; } @@ -124,19 +119,11 @@ static const struct file_operations ux500_regulator_power_state_cnt_fops = { static int ux500_regulator_status_print(struct seq_file *s, void *p) { - struct device *dev = s->private; - int err; int i; /* print dump header */ - err = seq_puts(s, "ux500-regulator status:\n"); - if (err < 0) - dev_err(dev, "seq_puts overflow\n"); - - err = seq_printf(s, "%31s : %8s : %8s\n", "current", - "before", "after"); - if (err < 0) - dev_err(dev, "seq_printf overflow\n"); + seq_puts(s, "ux500-regulator status:\n"); + seq_printf(s, "%31s : %8s : %8s\n", "current", "before", "after"); for (i = 0; i < rdebug.num_regulators; i++) { struct dbx500_regulator_info *info; @@ -144,12 +131,11 @@ static int ux500_regulator_status_print(struct seq_file *s, void *p) info = &rdebug.regulator_array[i]; /* print status */ - err = seq_printf(s, "%20s : %8s : %8s : %8s\n", info->desc.name, - info->is_enabled ? "enabled" : "disabled", - rdebug.state_before_suspend[i] ? "enabled" : "disabled", - rdebug.state_after_suspend[i] ? "enabled" : "disabled"); - if (err < 0) - dev_err(dev, "seq_printf overflow\n"); + seq_printf(s, "%20s : %8s : %8s : %8s\n", + info->desc.name, + info->is_enabled ? "enabled" : "disabled", + rdebug.state_before_suspend[i] ? "enabled" : "disabled", + rdebug.state_after_suspend[i] ? "enabled" : "disabled"); } return 0; -- cgit v1.1 From 222d0f04340c686b136ec3a610cc50ba46baaea1 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 26 Mar 2015 11:35:58 +0100 Subject: regulator: max77693: Let core parse DT and drop board files support Simplify the driver by removing board file support and letting regulator core to parse DT. The max77693 regulator driver is used only on Exynos based boards which are DT-only. Board files for Exynos are not supported. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Mark Brown --- drivers/regulator/max77693.c | 93 +++++--------------------------------------- 1 file changed, 9 insertions(+), 84 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/max77693.c b/drivers/regulator/max77693.c index 07b313e..9665a48 100644 --- a/drivers/regulator/max77693.c +++ b/drivers/regulator/max77693.c @@ -128,6 +128,8 @@ static struct regulator_ops max77693_charger_ops = { #define regulator_desc_esafeout(_num) { \ .name = "ESAFEOUT"#_num, \ .id = MAX77693_ESAFEOUT##_num, \ + .of_match = of_match_ptr("ESAFEOUT"#_num), \ + .regulators_node = of_match_ptr("regulators"), \ .n_voltages = 4, \ .ops = &max77693_safeout_ops, \ .type = REGULATOR_VOLTAGE, \ @@ -145,6 +147,8 @@ static const struct regulator_desc regulators[] = { { .name = "CHARGER", .id = MAX77693_CHARGER, + .of_match = of_match_ptr("CHARGER"), + .regulators_node = of_match_ptr("regulators"), .ops = &max77693_charger_ops, .type = REGULATOR_CURRENT, .owner = THIS_MODULE, @@ -154,102 +158,23 @@ static const struct regulator_desc regulators[] = { }, }; -#ifdef CONFIG_OF -static int max77693_pmic_dt_parse_rdata(struct device *dev, - struct max77693_regulator_data **rdata) -{ - struct device_node *np; - struct of_regulator_match *rmatch; - struct max77693_regulator_data *tmp; - int i, matched = 0; - - np = of_get_child_by_name(dev->parent->of_node, "regulators"); - if (!np) - return -EINVAL; - - rmatch = devm_kzalloc(dev, - sizeof(*rmatch) * ARRAY_SIZE(regulators), GFP_KERNEL); - if (!rmatch) { - of_node_put(np); - return -ENOMEM; - } - - for (i = 0; i < ARRAY_SIZE(regulators); i++) - rmatch[i].name = regulators[i].name; - - matched = of_regulator_match(dev, np, rmatch, ARRAY_SIZE(regulators)); - of_node_put(np); - if (matched <= 0) - return matched; - *rdata = devm_kzalloc(dev, sizeof(**rdata) * matched, GFP_KERNEL); - if (!(*rdata)) - return -ENOMEM; - - tmp = *rdata; - - for (i = 0; i < matched; i++) { - tmp->initdata = rmatch[i].init_data; - tmp->of_node = rmatch[i].of_node; - tmp->id = regulators[i].id; - tmp++; - } - - return matched; -} -#else -static int max77693_pmic_dt_parse_rdata(struct device *dev, - struct max77693_regulator_data **rdata) -{ - return 0; -} -#endif /* CONFIG_OF */ - -static int max77693_pmic_init_rdata(struct device *dev, - struct max77693_regulator_data **rdata) -{ - struct max77693_platform_data *pdata; - int num_regulators = 0; - - pdata = dev_get_platdata(dev->parent); - if (pdata) { - *rdata = pdata->regulators; - num_regulators = pdata->num_regulators; - } - - if (!(*rdata) && dev->parent->of_node) - num_regulators = max77693_pmic_dt_parse_rdata(dev, rdata); - - return num_regulators; -} - static int max77693_pmic_probe(struct platform_device *pdev) { struct max77693_dev *iodev = dev_get_drvdata(pdev->dev.parent); - struct max77693_regulator_data *rdata = NULL; - int num_rdata, i; + int i; struct regulator_config config = { }; - num_rdata = max77693_pmic_init_rdata(&pdev->dev, &rdata); - if (!rdata || num_rdata <= 0) { - dev_err(&pdev->dev, "No init data supplied.\n"); - return -ENODEV; - } - - config.dev = &pdev->dev; + config.dev = iodev->dev; config.regmap = iodev->regmap; - for (i = 0; i < num_rdata; i++) { - int id = rdata[i].id; + for (i = 0; i < ARRAY_SIZE(regulators); i++) { struct regulator_dev *rdev; - config.init_data = rdata[i].initdata; - config.of_node = rdata[i].of_node; - rdev = devm_regulator_register(&pdev->dev, - ®ulators[id], &config); + ®ulators[i], &config); if (IS_ERR(rdev)) { dev_err(&pdev->dev, - "Failed to initialize regulator-%d\n", id); + "Failed to initialize regulator-%d\n", i); return PTR_ERR(rdev); } } -- cgit v1.1 From dfb85ba1140ab649f6f0bf3e502ac37c0f69dbcb Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Tue, 7 Apr 2015 23:06:46 +0100 Subject: regulator: max8660: fix assignment of pdata to data that becomes dead pdata is assigned to &pdata_of, however, pdata_of becomes dead (when it goes out of scope) so pdata effectively becomes a dead pointer to the out of scope object. This is detected by static analysis: [drivers/regulator/max8660.c:411]: (error) Dead pointer usage. Pointer 'pdata' is dead if it has been assigned '&pdata_of' at line 404. Move declaration of pdata_of so it is always in scope. Signed-off-by: Colin Ian King Signed-off-by: Mark Brown --- drivers/regulator/max8660.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/max8660.c b/drivers/regulator/max8660.c index 7eee2ca..f187c8f 100644 --- a/drivers/regulator/max8660.c +++ b/drivers/regulator/max8660.c @@ -382,7 +382,7 @@ static int max8660_probe(struct i2c_client *client, const struct i2c_device_id *i2c_id) { struct device *dev = &client->dev; - struct max8660_platform_data *pdata = dev_get_platdata(dev); + struct max8660_platform_data pdata_of, *pdata = dev_get_platdata(dev); struct regulator_config config = { }; struct max8660 *max8660; int boot_on, i, id, ret = -EINVAL; @@ -391,7 +391,6 @@ static int max8660_probe(struct i2c_client *client, if (dev->of_node && !pdata) { const struct of_device_id *id; - struct max8660_platform_data pdata_of; id = of_match_device(of_match_ptr(max8660_dt_ids), dev); if (!id) -- cgit v1.1 From c0cf5a59fb69527151eb8e332a1b9660200f66c6 Mon Sep 17 00:00:00 2001 From: Markus Pargmann Date: Fri, 10 Apr 2015 15:23:42 +0200 Subject: regulator: max8660: Handle empty regulator data It is not necessary to have regulator init data for a regulator. This patch removes the necessity of this data and handles a NULL pointer properly. Signed-off-by: Markus Pargmann Signed-off-by: Mark Brown --- drivers/regulator/max8660.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/max8660.c b/drivers/regulator/max8660.c index f187c8f..4071d74 100644 --- a/drivers/regulator/max8660.c +++ b/drivers/regulator/max8660.c @@ -442,9 +442,9 @@ static int max8660_probe(struct i2c_client *client, for (i = 0; i < pdata->num_subdevs; i++) { if (!pdata->subdevs[i].platform_data) - return ret; - - boot_on = pdata->subdevs[i].platform_data->constraints.boot_on; + boot_on = false; + else + boot_on = pdata->subdevs[i].platform_data->constraints.boot_on; switch (pdata->subdevs[i].id) { case MAX8660_V3: -- cgit v1.1