diff --git a/drivers/regulator/88pm800.c b/drivers/regulator/88pm800.c index d333f7eac106..7a721d67e6ac 100644 --- a/drivers/regulator/88pm800.c +++ b/drivers/regulator/88pm800.c @@ -310,10 +310,8 @@ static int pm800_regulator_probe(struct platform_device *pdev) pm800_data = devm_kzalloc(&pdev->dev, sizeof(*pm800_data), GFP_KERNEL); - if (!pm800_data) { - dev_err(&pdev->dev, "Failed to allocate pm800_regualtors"); + if (!pm800_data) return -ENOMEM; - } pm800_data->map = chip->subchip->regmap_power; pm800_data->chip = chip; diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c index f704d83c93c4..337634ad0562 100644 --- a/drivers/regulator/88pm8607.c +++ b/drivers/regulator/88pm8607.c @@ -2,7 +2,7 @@ * Regulators driver for Marvell 88PM8607 * * Copyright (C) 2009 Marvell International Ltd. - * Haojian Zhuang + * Haojian Zhuang * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -78,7 +78,7 @@ static const unsigned int BUCK2_suspend_table[] = { }; static const unsigned int BUCK3_table[] = { - 0, 25000, 50000, 75000, 100000, 125000, 150000, 175000, + 0, 25000, 50000, 75000, 100000, 125000, 150000, 175000, 200000, 225000, 250000, 275000, 300000, 325000, 350000, 375000, 400000, 425000, 450000, 475000, 500000, 525000, 550000, 575000, 600000, 625000, 650000, 675000, 700000, 725000, 750000, 775000, @@ -89,7 +89,7 @@ static const unsigned int BUCK3_table[] = { }; static const unsigned int BUCK3_suspend_table[] = { - 0, 25000, 50000, 75000, 100000, 125000, 150000, 175000, + 0, 25000, 50000, 75000, 100000, 125000, 150000, 175000, 200000, 225000, 250000, 275000, 300000, 325000, 350000, 375000, 400000, 425000, 450000, 475000, 500000, 525000, 550000, 575000, 600000, 625000, 650000, 675000, 700000, 725000, 750000, 775000, @@ -322,7 +322,7 @@ static int pm8607_regulator_dt_init(struct platform_device *pdev, nproot = of_node_get(pdev->dev.parent->of_node); if (!nproot) return -ENODEV; - nproot = of_find_node_by_name(nproot, "regulators"); + nproot = of_get_child_by_name(nproot, "regulators"); if (!nproot) { dev_err(&pdev->dev, "failed to find regulators node\n"); return -ENODEV; diff --git a/drivers/regulator/aat2870-regulator.c b/drivers/regulator/aat2870-regulator.c index f70a9bfa5ff2..c873ee0082cf 100644 --- a/drivers/regulator/aat2870-regulator.c +++ b/drivers/regulator/aat2870-regulator.c @@ -99,6 +99,7 @@ static int aat2870_ldo_is_enabled(struct regulator_dev *rdev) static struct regulator_ops aat2870_ldo_ops = { .list_voltage = regulator_list_voltage_table, + .map_voltage = regulator_map_voltage_ascend, .set_voltage_sel = aat2870_ldo_set_voltage_sel, .get_voltage_sel = aat2870_ldo_get_voltage_sel, .enable = aat2870_ldo_enable, diff --git a/drivers/regulator/act8865-regulator.c b/drivers/regulator/act8865-regulator.c index 084cc0819a52..b92d7dd01a18 100644 --- a/drivers/regulator/act8865-regulator.c +++ b/drivers/regulator/act8865-regulator.c @@ -62,7 +62,6 @@ #define ACT8865_VOLTAGE_NUM 64 struct act8865 { - struct regulator_dev *rdev[ACT8865_REG_NUM]; struct regmap *regmap; }; @@ -213,7 +212,7 @@ static int act8865_pdata_from_dt(struct device *dev, struct device_node *np; struct act8865_regulator_data *regulator; - np = of_find_node_by_name(dev->of_node, "regulators"); + np = of_get_child_by_name(dev->of_node, "regulators"); if (!np) { dev_err(dev, "missing 'regulators' subnode in DT\n"); return -EINVAL; @@ -221,17 +220,15 @@ static int act8865_pdata_from_dt(struct device *dev, matched = of_regulator_match(dev, np, act8865_matches, ARRAY_SIZE(act8865_matches)); + of_node_put(np); if (matched <= 0) return matched; pdata->regulators = devm_kzalloc(dev, sizeof(struct act8865_regulator_data) * ARRAY_SIZE(act8865_matches), GFP_KERNEL); - if (!pdata->regulators) { - dev_err(dev, "%s: failed to allocate act8865 registor\n", - __func__); + if (!pdata->regulators) return -ENOMEM; - } pdata->num_regulators = matched; regulator = pdata->regulators; @@ -258,7 +255,7 @@ static inline int act8865_pdata_from_dt(struct device *dev, static int act8865_pmic_probe(struct i2c_client *client, const struct i2c_device_id *i2c_id) { - struct regulator_dev **rdev; + struct regulator_dev *rdev; struct device *dev = &client->dev; struct act8865_platform_data *pdata = dev_get_platdata(dev); struct regulator_config config = { }; @@ -292,8 +289,6 @@ static int act8865_pmic_probe(struct i2c_client *client, if (!act8865) return -ENOMEM; - rdev = act8865->rdev; - act8865->regmap = devm_regmap_init_i2c(client, &act8865_regmap_config); if (IS_ERR(act8865->regmap)) { error = PTR_ERR(act8865->regmap); @@ -313,12 +308,12 @@ static int act8865_pmic_probe(struct i2c_client *client, config.driver_data = act8865; config.regmap = act8865->regmap; - rdev[i] = devm_regulator_register(&client->dev, - &act8865_reg[i], &config); - if (IS_ERR(rdev[i])) { + rdev = devm_regulator_register(&client->dev, &act8865_reg[i], + &config); + if (IS_ERR(rdev)) { dev_err(dev, "failed to register %s\n", act8865_reg[id].name); - return PTR_ERR(rdev[i]); + return PTR_ERR(rdev); } } diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c index 862e63e451d0..7c397bb81e01 100644 --- a/drivers/regulator/anatop-regulator.c +++ b/drivers/regulator/anatop-regulator.c @@ -34,6 +34,9 @@ #define LDO_RAMP_UP_UNIT_IN_CYCLES 64 /* 64 cycles per step */ #define LDO_RAMP_UP_FREQ_IN_MHZ 24 /* cycle based on 24M OSC */ +#define LDO_POWER_GATE 0x00 +#define LDO_FET_FULL_ON 0x1f + struct anatop_regulator { const char *name; u32 control_reg; @@ -48,19 +51,10 @@ struct anatop_regulator { int max_voltage; struct regulator_desc rdesc; struct regulator_init_data *initdata; + bool bypass; + int sel; }; -static int anatop_regmap_set_voltage_sel(struct regulator_dev *reg, - unsigned selector) -{ - struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); - - if (!anatop_reg->control_reg) - return -ENOTSUPP; - - return regulator_set_voltage_sel_regmap(reg, selector); -} - static int anatop_regmap_set_voltage_time_sel(struct regulator_dev *reg, unsigned int old_sel, unsigned int new_sel) @@ -87,24 +81,101 @@ static int anatop_regmap_set_voltage_time_sel(struct regulator_dev *reg, return ret; } -static int anatop_regmap_get_voltage_sel(struct regulator_dev *reg) +static int anatop_regmap_enable(struct regulator_dev *reg) +{ + struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); + int sel; + + sel = anatop_reg->bypass ? LDO_FET_FULL_ON : anatop_reg->sel; + return regulator_set_voltage_sel_regmap(reg, sel); +} + +static int anatop_regmap_disable(struct regulator_dev *reg) +{ + return regulator_set_voltage_sel_regmap(reg, LDO_POWER_GATE); +} + +static int anatop_regmap_is_enabled(struct regulator_dev *reg) +{ + return regulator_get_voltage_sel_regmap(reg) != LDO_POWER_GATE; +} + +static int anatop_regmap_core_set_voltage_sel(struct regulator_dev *reg, + unsigned selector) +{ + struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); + int ret; + + if (anatop_reg->bypass || !anatop_regmap_is_enabled(reg)) { + anatop_reg->sel = selector; + return 0; + } + + ret = regulator_set_voltage_sel_regmap(reg, selector); + if (!ret) + anatop_reg->sel = selector; + return ret; +} + +static int anatop_regmap_core_get_voltage_sel(struct regulator_dev *reg) { struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); - if (!anatop_reg->control_reg) - return -ENOTSUPP; + if (anatop_reg->bypass || !anatop_regmap_is_enabled(reg)) + return anatop_reg->sel; return regulator_get_voltage_sel_regmap(reg); } +static int anatop_regmap_get_bypass(struct regulator_dev *reg, bool *enable) +{ + struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); + int sel; + + sel = regulator_get_voltage_sel_regmap(reg); + if (sel == LDO_FET_FULL_ON) + WARN_ON(!anatop_reg->bypass); + else if (sel != LDO_POWER_GATE) + WARN_ON(anatop_reg->bypass); + + *enable = anatop_reg->bypass; + return 0; +} + +static int anatop_regmap_set_bypass(struct regulator_dev *reg, bool enable) +{ + struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); + int sel; + + if (enable == anatop_reg->bypass) + return 0; + + sel = enable ? LDO_FET_FULL_ON : anatop_reg->sel; + anatop_reg->bypass = enable; + + return regulator_set_voltage_sel_regmap(reg, sel); +} + static struct regulator_ops anatop_rops = { - .set_voltage_sel = anatop_regmap_set_voltage_sel, - .set_voltage_time_sel = anatop_regmap_set_voltage_time_sel, - .get_voltage_sel = anatop_regmap_get_voltage_sel, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, }; +static struct regulator_ops anatop_core_rops = { + .enable = anatop_regmap_enable, + .disable = anatop_regmap_disable, + .is_enabled = anatop_regmap_is_enabled, + .set_voltage_sel = anatop_regmap_core_set_voltage_sel, + .set_voltage_time_sel = anatop_regmap_set_voltage_time_sel, + .get_voltage_sel = anatop_regmap_core_get_voltage_sel, + .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, + .get_bypass = anatop_regmap_get_bypass, + .set_bypass = anatop_regmap_set_bypass, +}; + static int anatop_regulator_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -116,6 +187,7 @@ static int anatop_regulator_probe(struct platform_device *pdev) struct regulator_init_data *initdata; struct regulator_config config = { }; int ret = 0; + u32 val; initdata = of_get_regulator_init_data(dev, np); sreg = devm_kzalloc(dev, sizeof(*sreg), GFP_KERNEL); @@ -125,7 +197,6 @@ static int anatop_regulator_probe(struct platform_device *pdev) sreg->name = of_get_property(np, "regulator-name", NULL); rdesc = &sreg->rdesc; rdesc->name = sreg->name; - rdesc->ops = &anatop_rops; rdesc->type = REGULATOR_VOLTAGE; rdesc->owner = THIS_MODULE; @@ -197,6 +268,25 @@ static int anatop_regulator_probe(struct platform_device *pdev) config.of_node = pdev->dev.of_node; config.regmap = sreg->anatop; + /* Only core regulators have the ramp up delay configuration. */ + if (sreg->control_reg && sreg->delay_bit_width) { + rdesc->ops = &anatop_core_rops; + + ret = regmap_read(config.regmap, rdesc->vsel_reg, &val); + if (ret) { + dev_err(dev, "failed to read initial state\n"); + return ret; + } + + sreg->sel = (val & rdesc->vsel_mask) >> sreg->vol_bit_shift; + if (sreg->sel == LDO_FET_FULL_ON) { + sreg->sel = 0; + sreg->bypass = true; + } + } else { + rdesc->ops = &anatop_rops; + } + /* register regulator */ rdev = devm_regulator_register(dev, rdesc, &config); if (IS_ERR(rdev)) { diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c index 4f6c2055f6b2..b1033d30b504 100644 --- a/drivers/regulator/arizona-ldo1.c +++ b/drivers/regulator/arizona-ldo1.c @@ -153,11 +153,9 @@ static const struct regulator_desc arizona_ldo1 = { .vsel_reg = ARIZONA_LDO1_CONTROL_1, .vsel_mask = ARIZONA_LDO1_VSEL_MASK, - .bypass_reg = ARIZONA_LDO1_CONTROL_1, - .bypass_mask = ARIZONA_LDO1_BYPASS, .min_uV = 900000, - .uV_step = 50000, - .n_voltages = 7, + .uV_step = 25000, + .n_voltages = 13, .enable_time = 500, .owner = THIS_MODULE, @@ -189,10 +187,8 @@ static int arizona_ldo1_probe(struct platform_device *pdev) int ret; ldo1 = devm_kzalloc(&pdev->dev, sizeof(*ldo1), GFP_KERNEL); - if (ldo1 == NULL) { - dev_err(&pdev->dev, "Unable to allocate private data\n"); + if (!ldo1) return -ENOMEM; - } ldo1->arizona = arizona; @@ -203,6 +199,7 @@ static int arizona_ldo1_probe(struct platform_device *pdev) */ switch (arizona->type) { case WM5102: + case WM8997: desc = &arizona_ldo1_hc; ldo1->init_data = arizona_ldo1_dvfs; break; diff --git a/drivers/regulator/arizona-micsupp.c b/drivers/regulator/arizona-micsupp.c index 034ece707083..6fdd9bf6927f 100644 --- a/drivers/regulator/arizona-micsupp.c +++ b/drivers/regulator/arizona-micsupp.c @@ -204,10 +204,8 @@ static int arizona_micsupp_probe(struct platform_device *pdev) int ret; micsupp = devm_kzalloc(&pdev->dev, sizeof(*micsupp), GFP_KERNEL); - if (micsupp == NULL) { - dev_err(&pdev->dev, "Unable to allocate private data\n"); + if (!micsupp) return -ENOMEM; - } micsupp->arizona = arizona; INIT_WORK(&micsupp->check_cp_work, arizona_micsupp_check_cp); diff --git a/drivers/regulator/as3711-regulator.c b/drivers/regulator/as3711-regulator.c index c77a58478cca..b47283f91e2d 100644 --- a/drivers/regulator/as3711-regulator.c +++ b/drivers/regulator/as3711-regulator.c @@ -191,7 +191,7 @@ static int as3711_regulator_parse_dt(struct device *dev, { struct as3711_regulator_pdata *pdata = dev_get_platdata(dev); struct device_node *regulators = - of_find_node_by_name(dev->parent->of_node, "regulators"); + of_get_child_by_name(dev->parent->of_node, "regulators"); struct of_regulator_match *match; int ret, i; @@ -221,7 +221,6 @@ static int as3711_regulator_probe(struct platform_device *pdev) { struct as3711_regulator_pdata *pdata = dev_get_platdata(&pdev->dev); struct as3711 *as3711 = dev_get_drvdata(pdev->dev.parent); - struct regulator_init_data *reg_data; struct regulator_config config = {.dev = &pdev->dev,}; struct as3711_regulator *reg = NULL; struct as3711_regulator *regs; @@ -246,22 +245,14 @@ static int as3711_regulator_probe(struct platform_device *pdev) regs = devm_kzalloc(&pdev->dev, AS3711_REGULATOR_NUM * sizeof(struct as3711_regulator), GFP_KERNEL); - if (!regs) { - dev_err(&pdev->dev, "Memory allocation failed exiting..\n"); + if (!regs) return -ENOMEM; - } for (id = 0, ri = as3711_reg_info; id < AS3711_REGULATOR_NUM; ++id, ri++) { - reg_data = pdata->init_data[id]; - - /* No need to register if there is no regulator data */ - if (!reg_data) - continue; - reg = ®s[id]; reg->reg_info = ri; - config.init_data = reg_data; + config.init_data = pdata->init_data[id]; config.driver_data = reg; config.regmap = as3711->regmap; config.of_node = of_node[id]; diff --git a/drivers/regulator/as3722-regulator.c b/drivers/regulator/as3722-regulator.c index 8b17d786cb71..85585219ce82 100644 --- a/drivers/regulator/as3722-regulator.c +++ b/drivers/regulator/as3722-regulator.c @@ -719,6 +719,7 @@ static int as3722_get_regulator_dt_data(struct platform_device *pdev, ret = of_regulator_match(&pdev->dev, np, as3722_regulator_matches, ARRAY_SIZE(as3722_regulator_matches)); + of_node_put(np); if (ret < 0) { dev_err(&pdev->dev, "Parsing of regulator node failed: %d\n", ret);