diff options
38 files changed, 227 insertions, 682 deletions
diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c index 25fbbaf39cb9..21bae64e0451 100644 --- a/drivers/mfd/wm831x-core.c +++ b/drivers/mfd/wm831x-core.c @@ -34,7 +34,7 @@ /* Current settings - values are 2*2^(reg_val/4) microamps. These are * exported since they are used by multiple drivers. */ -int wm831x_isinkv_values[WM831X_ISINK_MAX_ISEL + 1] = { +const unsigned int wm831x_isinkv_values[WM831X_ISINK_MAX_ISEL + 1] = { 2, 2, 3, diff --git a/drivers/mfd/wm8400-core.c b/drivers/mfd/wm8400-core.c index 79756c83f5f0..cf067424a156 100644 --- a/drivers/mfd/wm8400-core.c +++ b/drivers/mfd/wm8400-core.c @@ -35,12 +35,6 @@ static bool wm8400_volatile(struct device *dev, unsigned int reg) } } -int wm8400_block_read(struct wm8400 *wm8400, u8 reg, int count, u16 *data) -{ - return regmap_bulk_read(wm8400->regmap, reg, data, count); -} -EXPORT_SYMBOL_GPL(wm8400_block_read); - static int wm8400_register_codec(struct wm8400 *wm8400) { const struct mfd_cell cell = { diff --git a/drivers/regulator/88pm800.c b/drivers/regulator/88pm800.c index 89bbd6e8bad1..9fd379732d18 100644 --- a/drivers/regulator/88pm800.c +++ b/drivers/regulator/88pm800.c @@ -77,11 +77,6 @@ struct pm800_regulator_info { int max_ua; }; -struct pm800_regulators { - struct pm80x_chip *chip; - struct regmap *map; -}; - /* * vreg - the buck regs string. * ereg - the string for the enable register. @@ -235,7 +230,6 @@ static int pm800_regulator_probe(struct platform_device *pdev) { struct pm80x_chip *chip = dev_get_drvdata(pdev->dev.parent); struct pm80x_platform_data *pdata = dev_get_platdata(pdev->dev.parent); - struct pm800_regulators *pm800_data; struct regulator_config config = { }; struct regulator_init_data *init_data; int i, ret; @@ -252,18 +246,8 @@ static int pm800_regulator_probe(struct platform_device *pdev) return -EINVAL; } - pm800_data = devm_kzalloc(&pdev->dev, sizeof(*pm800_data), - GFP_KERNEL); - if (!pm800_data) - return -ENOMEM; - - pm800_data->map = chip->subchip->regmap_power; - pm800_data->chip = chip; - - platform_set_drvdata(pdev, pm800_data); - config.dev = chip->dev; - config.regmap = pm800_data->map; + config.regmap = chip->subchip->regmap_power; for (i = 0; i < PM800_ID_RG_MAX; i++) { struct regulator_dev *regulator; diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c index 753a6a1b30c3..35d767aeeb57 100644 --- a/drivers/regulator/88pm8607.c +++ b/drivers/regulator/88pm8607.c @@ -235,6 +235,8 @@ static const struct regulator_ops pm8606_preg_ops = { { \ .desc = { \ .name = "PREG", \ + .of_match = of_match_ptr("PREG"), \ + .regulators_node = of_match_ptr("regulators"), \ .ops = &pm8606_preg_ops, \ .type = REGULATOR_CURRENT, \ .id = PM8606_ID_PREG, \ @@ -249,6 +251,8 @@ static const struct regulator_ops pm8606_preg_ops = { { \ .desc = { \ .name = #vreg, \ + .of_match = of_match_ptr(#vreg), \ + .regulators_node = of_match_ptr("regulators"), \ .ops = &pm8607_regulator_ops, \ .type = REGULATOR_VOLTAGE, \ .id = PM8607_ID_##vreg, \ @@ -270,6 +274,8 @@ static const struct regulator_ops pm8606_preg_ops = { { \ .desc = { \ .name = "LDO" #_id, \ + .of_match = of_match_ptr("LDO" #_id), \ + .regulators_node = of_match_ptr("regulators"), \ .ops = &pm8607_regulator_ops, \ .type = REGULATOR_VOLTAGE, \ .id = PM8607_ID_LDO##_id, \ @@ -309,36 +315,6 @@ static struct pm8607_regulator_info pm8606_regulator_info[] = { PM8606_PREG(PREREGULATORB, 5), }; -#ifdef CONFIG_OF -static int pm8607_regulator_dt_init(struct platform_device *pdev, - struct pm8607_regulator_info *info, - struct regulator_config *config) -{ - struct device_node *nproot, *np; - nproot = pdev->dev.parent->of_node; - if (!nproot) - return -ENODEV; - nproot = of_get_child_by_name(nproot, "regulators"); - if (!nproot) { - dev_err(&pdev->dev, "failed to find regulators node\n"); - return -ENODEV; - } - for_each_child_of_node(nproot, np) { - if (of_node_name_eq(np, info->desc.name)) { - config->init_data = - of_get_regulator_init_data(&pdev->dev, np, - &info->desc); - config->of_node = np; - break; - } - } - of_node_put(nproot); - return 0; -} -#else -#define pm8607_regulator_dt_init(x, y, z) (-1) -#endif - static int pm8607_regulator_probe(struct platform_device *pdev) { struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); @@ -373,12 +349,11 @@ static int pm8607_regulator_probe(struct platform_device *pdev) if ((i == PM8607_ID_BUCK3) && chip->buck3_double) info->slope_double = 1; - config.dev = &pdev->dev; + config.dev = chip->dev; config.driver_data = info; - if (pm8607_regulator_dt_init(pdev, info, &config)) - if (pdata) - config.init_data = pdata; + if (pdata) + config.init_data = pdata; if (chip->id == CHIP_PM8607) config.regmap = chip->regmap; diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index b7f249ee5e68..6d2651cd9887 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -223,6 +223,7 @@ config REGULATOR_CPCAP config REGULATOR_DA903X tristate "Dialog Semiconductor DA9030/DA9034 regulators" depends on PMIC_DA903X + depends on !CC_IS_CLANG # https://bugs.llvm.org/show_bug.cgi?id=38789 help Say y here to support the BUCKs and LDOs regulators found on Dialog Semiconductor DA9030/DA9034 PMIC. diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c index de2644490f0d..c92966a79a7e 100644 --- a/drivers/regulator/ab3100.c +++ b/drivers/regulator/ab3100.c @@ -48,7 +48,6 @@ * @regreg: regulator register number in the AB3100 */ struct ab3100_regulator { - struct regulator_dev *rdev; struct device *dev; struct ab3100_platform_data *plfdata; u8 regreg; @@ -545,8 +544,6 @@ static int ab3100_regulator_register(struct platform_device *pdev, return err; } - /* Then set a pointer back to the registered regulator */ - reg->rdev = rdev; return 0; } @@ -609,18 +606,6 @@ static const u8 ab3100_reg_initvals[] = { LDO_D_SETTING, }; -static int ab3100_regulators_remove(struct platform_device *pdev) -{ - int i; - - for (i = 0; i < AB3100_NUM_REGULATORS; i++) { - struct ab3100_regulator *reg = &ab3100_regulators[i]; - - reg->rdev = NULL; - } - return 0; -} - static int ab3100_regulator_of_probe(struct platform_device *pdev, struct device_node *np) { @@ -647,10 +632,8 @@ ab3100_regulator_of_probe(struct platform_device *pdev, struct device_node *np) pdev, NULL, ab3100_regulator_matches[i].init_data, ab3100_regulator_matches[i].of_node, (unsigned long)ab3100_regulator_matches[i].driver_data); - if (err) { - ab3100_regulators_remove(pdev); + if (err) return err; - } } return 0; @@ -709,10 +692,8 @@ static int ab3100_regulators_probe(struct platform_device *pdev) err = ab3100_regulator_register(pdev, plfdata, NULL, NULL, desc->id); - if (err) { - ab3100_regulators_remove(pdev); + if (err) return err; - } } return 0; @@ -723,7 +704,6 @@ static struct platform_driver ab3100_regulators_driver = { .name = "ab3100-regulators", }, .probe = ab3100_regulators_probe, - .remove = ab3100_regulators_remove, }; static __init int ab3100_regulators_init(void) diff --git a/drivers/regulator/as3711-regulator.c b/drivers/regulator/as3711-regulator.c index f7fe218bb3e4..ece88103f2fd 100644 --- a/drivers/regulator/as3711-regulator.c +++ b/drivers/regulator/as3711-regulator.c @@ -17,14 +17,6 @@ #include <linux/regulator/of_regulator.h> #include <linux/slab.h> -struct as3711_regulator_info { - struct regulator_desc desc; -}; - -struct as3711_regulator { - struct as3711_regulator_info *reg_info; -}; - /* * The regulator API supports 4 modes of operataion: FAST, NORMAL, IDLE and * STANDBY. We map them in the following way to AS3711 SD1-4 DCDC modes: @@ -129,7 +121,6 @@ static const struct regulator_linear_range as3711_dldo_ranges[] = { #define AS3711_REG(_id, _en_reg, _en_bit, _vmask, _sfx) \ [AS3711_REGULATOR_ ## _id] = { \ - .desc = { \ .name = "as3711-regulator-" # _id, \ .id = AS3711_REGULATOR_ ## _id, \ .n_voltages = (_vmask + 1), \ @@ -142,10 +133,9 @@ static const struct regulator_linear_range as3711_dldo_ranges[] = { .enable_mask = BIT(_en_bit), \ .linear_ranges = as3711_ ## _sfx ## _ranges, \ .n_linear_ranges = ARRAY_SIZE(as3711_ ## _sfx ## _ranges), \ - }, \ } -static struct as3711_regulator_info as3711_reg_info[] = { +static const struct regulator_desc as3711_reg_desc[] = { AS3711_REG(SD_1, SD_CONTROL, 0, 0x7f, sd), AS3711_REG(SD_2, SD_CONTROL, 1, 0x7f, sd), AS3711_REG(SD_3, SD_CONTROL, 2, 0x7f, sd), @@ -161,7 +151,7 @@ static struct as3711_regulator_info as3711_reg_info[] = { /* StepUp output voltage depends on supplying regulator */ }; -#define AS3711_REGULATOR_NUM ARRAY_SIZE(as3711_reg_info) +#define AS3711_REGULATOR_NUM ARRAY_SIZE(as3711_reg_desc) static struct of_regulator_match as3711_regulator_matches[AS3711_REGULATOR_NUM] = { @@ -215,11 +205,8 @@ 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_config config = {.dev = &pdev->dev,}; - struct as3711_regulator *reg = NULL; - struct as3711_regulator *regs; struct device_node *of_node[AS3711_REGULATOR_NUM] = {}; struct regulator_dev *rdev; - struct as3711_regulator_info *ri; int ret; int id; @@ -236,30 +223,20 @@ static int as3711_regulator_probe(struct platform_device *pdev) } } - regs = devm_kcalloc(&pdev->dev, - AS3711_REGULATOR_NUM, - sizeof(struct as3711_regulator), - GFP_KERNEL); - if (!regs) - return -ENOMEM; - - for (id = 0, ri = as3711_reg_info; id < AS3711_REGULATOR_NUM; ++id, ri++) { - reg = ®s[id]; - reg->reg_info = ri; - + for (id = 0; id < AS3711_REGULATOR_NUM; id++) { config.init_data = pdata->init_data[id]; - config.driver_data = reg; config.regmap = as3711->regmap; config.of_node = of_node[id]; - rdev = devm_regulator_register(&pdev->dev, &ri->desc, &config); + rdev = devm_regulator_register(&pdev->dev, &as3711_reg_desc[id], + &config); if (IS_ERR(rdev)) { dev_err(&pdev->dev, "Failed to register regulator %s\n", - ri->desc.name); + as3711_reg_desc[id].name); return PTR_ERR(rdev); } } - platform_set_drvdata(pdev, regs); + return 0; } diff --git a/drivers/regulator/as3722-regulator.c b/drivers/regulator/as3722-regulator.c index e5fed289b52d..7a315adbe6c4 100644 --- a/drivers/regulator/as3722-regulator.c +++ b/drivers/regulator/as3722-regulator.c @@ -81,7 +81,6 @@ struct as3722_regulator_config_data { struct as3722_regulators { struct device *dev; struct as3722 *as3722; - struct regulator_dev *rdevs[AS3722_REGULATOR_ID_MAX]; struct regulator_desc desc[AS3722_REGULATOR_ID_MAX]; struct as3722_regulator_config_data reg_config_data[AS3722_REGULATOR_ID_MAX]; @@ -929,7 +928,6 @@ static int as3722_regulator_probe(struct platform_device *pdev) return ret; } - as3722_regs->rdevs[id] = rdev; if (reg_config->ext_control) { ret = regulator_enable_regmap(rdev); if (ret < 0) { diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c index fba8f58ab769..07e10c8b0a22 100644 --- a/drivers/regulator/axp20x-regulator.c +++ b/drivers/regulator/axp20x-regulator.c @@ -367,16 +367,14 @@ static const int axp209_dcdc2_ldo3_slew_rates[] = { static int axp20x_set_ramp_delay(struct regulator_dev *rdev, int ramp) { struct axp20x_dev *axp20x = rdev_get_drvdata(rdev); - const struct regulator_desc *desc; + int id = rdev_get_id(rdev); u8 reg, mask, enable, cfg = 0xff; const int *slew_rates; int rate_count = 0; - desc = rdev->desc; - switch (axp20x->variant) { case AXP209_ID: - if (desc->id == AXP20X_DCDC2) { + if (id == AXP20X_DCDC2) { slew_rates = axp209_dcdc2_ldo3_slew_rates; rate_count = ARRAY_SIZE(axp209_dcdc2_ldo3_slew_rates); reg = AXP20X_DCDC2_LDO3_V_RAMP; @@ -388,7 +386,7 @@ static int axp20x_set_ramp_delay(struct regulator_dev *rdev, int ramp) break; } - if (desc->id == AXP20X_LDO3) { + if (id == AXP20X_LDO3) { slew_rates = axp209_dcdc2_ldo3_slew_rates; rate_count = ARRAY_SIZE(axp209_dcdc2_ldo3_slew_rates); reg = AXP20X_DCDC2_LDO3_V_RAMP; @@ -435,16 +433,11 @@ static int axp20x_set_ramp_delay(struct regulator_dev *rdev, int ramp) static int axp20x_regulator_enable_regmap(struct regulator_dev *rdev) { struct axp20x_dev *axp20x = rdev_get_drvdata(rdev); - const struct regulator_desc *desc; - - if (!rdev) - return -EINVAL; - - desc = rdev->desc; + int id = rdev_get_id(rdev); switch (axp20x->variant) { case AXP209_ID: - if ((desc->id == AXP20X_LDO3) && + if ((id == AXP20X_LDO3) && rdev->constraints && rdev->constraints->soft_start) { int v_out; int ret; diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 68473d0cc57e..5a9ebcf7fe7a 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1339,9 +1339,7 @@ static int set_machine_constraints(struct regulator_dev *rdev, * We'll only apply the initial system load if an * initial mode wasn't specified. */ - regulator_lock(rdev); drms_uA_update(rdev); - regulator_unlock(rdev); } if ((rdev->constraints->ramp_delay || rdev->constraints->ramp_disable) diff --git a/drivers/regulator/cpcap-regulator.c b/drivers/regulator/cpcap-regulator.c index e7dab5c4d1d1..d3284361e594 100644 --- a/drivers/regulator/cpcap-regulator.c +++ b/drivers/regulator/cpcap-regulator.c @@ -505,17 +505,12 @@ MODULE_DEVICE_TABLE(of, cpcap_regulator_id_table); static int cpcap_regulator_probe(struct platform_device *pdev) { struct cpcap_ddata *ddata; - const struct of_device_id *match; + const struct cpcap_regulator *match_data; struct regulator_config config; - struct regulator_init_data init_data; int i; - match = of_match_device(of_match_ptr(cpcap_regulator_id_table), - &pdev->dev); - if (!match) - return -EINVAL; - - if (!match->data) { + match_data = of_device_get_match_data(&pdev->dev); + if (!match_data) { dev_err(&pdev->dev, "no configuration data found\n"); return -ENODEV; @@ -530,14 +525,12 @@ static int cpcap_regulator_probe(struct platform_device *pdev) return -ENODEV; ddata->dev = &pdev->dev; - ddata->soc = match->data; + ddata->soc = match_data; platform_set_drvdata(pdev, ddata); memset(&config, 0, sizeof(config)); - memset(&init_data, 0, sizeof(init_data)); config.dev = &pdev->dev; config.regmap = ddata->reg; - config.init_data = &init_data; for (i = 0; i < CPCAP_NR_REGULATORS; i++) { const struct cpcap_regulator *regulator = &ddata->soc[i]; diff --git a/drivers/regulator/da9052-regulator.c b/drivers/regulator/da9052-regulator.c index cefa3558236d..b90a7ac3f3de 100644 --- a/drivers/regulator/da9052-regulator.c +++ b/drivers/regulator/da9052-regulator.c @@ -19,10 +19,8 @@ #include <linux/platform_device.h> #include <linux/regulator/driver.h> #include <linux/regulator/machine.h> -#ifdef CONFIG_OF #include <linux/of.h> #include <linux/regulator/of_regulator.h> -#endif #include <linux/mfd/da9052/da9052.h> #include <linux/mfd/da9052/reg.h> @@ -294,6 +292,8 @@ static const struct regulator_ops da9052_ldo_ops = { {\ .reg_desc = {\ .name = #_name,\ + .of_match = of_match_ptr(#_name),\ + .regulators_node = of_match_ptr("regulators"),\ .ops = &da9052_ldo_ops,\ .type = REGULATOR_VOLTAGE,\ .id = DA9052_ID_##_id,\ @@ -314,6 +314,8 @@ static const struct regulator_ops da9052_ldo_ops = { {\ .reg_desc = {\ .name = #_name,\ + .of_match = of_match_ptr(#_name),\ + .regulators_node = of_match_ptr("regulators"),\ .ops = &da9052_dcdc_ops,\ .type = REGULATOR_VOLTAGE,\ .id = DA9052_ID_##_id,\ @@ -417,36 +419,11 @@ static int da9052_regulator_probe(struct platform_device *pdev) return -EINVAL; } - config.dev = &pdev->dev; + config.dev = da9052->dev; config.driver_data = regulator; config.regmap = da9052->regmap; - if (pdata) { + if (pdata) config.init_data = pdata->regulators[cell->id]; - } else { -#ifdef CONFIG_OF - struct device_node *nproot = da9052->dev->of_node; - struct device_node *np; - - if (!nproot) - return -ENODEV; - - nproot = of_get_child_by_name(nproot, "regulators"); - if (!nproot) - return -ENODEV; - - for_each_child_of_node(nproot, np) { - if (of_node_name_eq(np, - regulator->info->reg_desc.name)) { - config.init_data = of_get_regulator_init_data( - &pdev->dev, np, - ®ulator->info->reg_desc); - config.of_node = np; - break; - } - } - of_node_put(nproot); -#endif - } regulator->rdev = devm_regulator_register(&pdev->dev, ®ulator->info->reg_desc, diff --git a/drivers/regulator/da9055-regulator.c b/drivers/regulator/da9055-regulator.c index 3c6fac793658..bcbc2fbd7fea 100644 --- a/drivers/regulator/da9055-regulator.c +++ b/drivers/regulator/da9055-regulator.c @@ -338,6 +338,8 @@ static const struct regulator_ops da9055_ldo_ops = { {\ .reg_desc = {\ .name = #_id,\ + .of_match = of_match_ptr(#_id),\ + .regulators_node = of_match_ptr("regulators"),\ .ops = &da9055_ldo_ops,\ .type = REGULATOR_VOLTAGE,\ .id = DA9055_ID_##_id,\ @@ -366,6 +368,8 @@ static const struct regulator_ops da9055_ldo_ops = { {\ .reg_desc = {\ .name = #_id,\ + .of_match = of_match_ptr(#_id),\ + .regulators_node = of_match_ptr("regulators"),\ .ops = &da9055_buck_ops,\ .type = REGULATOR_VOLTAGE,\ .id = DA9055_ID_##_id,\ @@ -487,8 +491,10 @@ static irqreturn_t da9055_ldo5_6_oc_irq(int irq, void *data) { struct da9055_regulator *regulator = data; + regulator_lock(regulator->rdev); regulator_notifier_call_chain(regulator->rdev, REGULATOR_EVENT_OVER_CURRENT, NULL); + regulator_unlock(regulator->rdev); return IRQ_HANDLED; } @@ -507,59 +513,6 @@ static inline struct da9055_regulator_info *find_regulator_info(int id) return NULL; } -#ifdef CONFIG_OF -static struct of_regulator_match da9055_reg_matches[] = { - { .name = "BUCK1", }, - { .name = "BUCK2", }, - { .name = "LDO1", }, - { .name = "LDO2", }, - { .name = "LDO3", }, - { .name = "LDO4", }, - { .name = "LDO5", }, - { .name = "LDO6", }, -}; - -static int da9055_regulator_dt_init(struct platform_device *pdev, - struct da9055_regulator *regulator, - struct regulator_config *config, - int regid) -{ - struct device_node *nproot, *np; - int ret; - - nproot = of_node_get(pdev->dev.parent->of_node); - if (!nproot) - return -ENODEV; - - np = of_get_child_by_name(nproot, "regulators"); - if (!np) - return -ENODEV; - - ret = of_regulator_match(&pdev->dev, np, &da9055_reg_matches[regid], 1); - of_node_put(nproot); - if (ret < 0) { - dev_err(&pdev->dev, "Error matching regulator: %d\n", ret); - return ret; - } - - config->init_data = da9055_reg_matches[regid].init_data; - config->of_node = da9055_reg_matches[regid].of_node; - - if (!config->of_node) - return -ENODEV; - - return 0; -} -#else -static inline int da9055_regulator_dt_init(struct platform_device *pdev, - struct da9055_regulator *regulator, - struct regulator_config *config, - int regid) -{ - return -ENODEV; -} -#endif /* CONFIG_OF */ - static int da9055_regulator_probe(struct platform_device *pdev) { struct regulator_config config = { }; @@ -580,18 +533,12 @@ static int da9055_regulator_probe(struct platform_device *pdev) } regulator->da9055 = da9055; - config.dev = &pdev->dev; + config.dev = da9055->dev; config.driver_data = regulator; config.regmap = da9055->regmap; - if (pdata) { + if (pdata) config.init_data = pdata->regulators[pdev->id]; - } else { - ret = da9055_regulator_dt_init(pdev, regulator, &config, - pdev->id); - if (ret < 0) - return ret; - } ret = da9055_gpio_init(regulator, &config, pdata, pdev->id); if (ret < 0) diff --git a/drivers/regulator/da9062-regulator.c b/drivers/regulator/da9062-regulator.c index b064d8a19d4c..a7d929b7776a 100644 --- a/drivers/regulator/da9062-regulator.c +++ b/drivers/regulator/da9062-regulator.c @@ -53,16 +53,12 @@ enum { /* Regulator capabilities and registers description */ struct da9062_regulator_info { struct regulator_desc desc; - /* Current limiting */ - unsigned int n_current_limits; - const int *current_limits; /* Main register fields */ struct reg_field mode; struct reg_field suspend; struct reg_field sleep; struct reg_field suspend_sleep; unsigned int suspend_vsel_reg; - struct reg_field ilimit; /* Event detection bit */ struct reg_field oc_event; }; @@ -78,7 +74,6 @@ struct da9062_regulator { struct regmap_field *suspend; struct regmap_field *sleep; struct regmap_field *suspend_sleep; - struct regmap_field *ilimit; }; /* Encapsulates all information for the regulators driver */ @@ -104,7 +99,7 @@ enum { * - DA9062_ID_[BUCK1|BUCK2|BUCK4] * Entry indexes corresponds to register values. */ -static const int da9062_buck_a_limits[] = { +static const unsigned int da9062_buck_a_limits[] = { 500000, 600000, 700000, 800000, 900000, 1000000, 1100000, 1200000, 1300000, 1400000, 1500000, 1600000, 1700000, 1800000, 1900000, 2000000 }; @@ -114,44 +109,11 @@ static const int da9062_buck_a_limits[] = { * - DA9062_ID_BUCK3 * Entry indexes corresponds to register values. */ -static const int da9062_buck_b_limits[] = { +static const unsigned int da9062_buck_b_limits[] = { 1500000, 1600000, 1700000, 1800000, 1900000, 2000000, 2100000, 2200000, 2300000, 2400000, 2500000, 2600000, 2700000, 2800000, 2900000, 3000000 }; -static int da9062_set_current_limit(struct regulator_dev *rdev, - int min_ua, int max_ua) -{ - struct da9062_regulator *regl = rdev_get_drvdata(rdev); - const struct da9062_regulator_info *rinfo = regl->info; - int n, tval; - - for (n = rinfo->n_current_limits - 1; n >= 0; n--) { - tval = rinfo->current_limits[n]; - if (tval >= min_ua && tval <= max_ua) - return regmap_field_write(regl->ilimit, n); - } - - return -EINVAL; -} - -static int da9062_get_current_limit(struct regulator_dev *rdev) -{ - struct da9062_regulator *regl = rdev_get_drvdata(rdev); - const struct da9062_regulator_info *rinfo = regl->info; - unsigned int sel; - int ret; - - ret = regmap_field_read(regl->ilimit, &sel); - if (ret < 0) - return ret; - - if (sel >= rinfo->n_current_limits) - sel = rinfo->n_current_limits - 1; - - return rinfo->current_limits[sel]; -} - static int da9062_buck_set_mode(struct regulator_dev *rdev, unsigned mode) { struct da9062_regulator *regl = rdev_get_drvdata(rdev); @@ -395,8 +357,8 @@ static const struct regulator_ops da9062_buck_ops = { .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, .list_voltage = regulator_list_voltage_linear, - .set_current_limit = da9062_set_current_limit, - .get_current_limit = da9062_get_current_limit, + .set_current_limit = regulator_set_current_limit_regmap, + .get_current_limit = regulator_get_current_limit_regmap, .set_mode = da9062_buck_set_mode, .get_mode = da9062_buck_get_mode, .get_status = da9062_buck_get_status, @@ -433,8 +395,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = { .desc.min_uV = (300) * 1000, .desc.uV_step = (10) * 1000, .desc.n_voltages = ((1570) - (300))/(10) + 1, - .current_limits = da9062_buck_a_limits, - .n_current_limits = ARRAY_SIZE(da9062_buck_a_limits), + .desc.curr_table = da9062_buck_a_limits, + .desc.n_current_limits = ARRAY_SIZE(da9062_buck_a_limits), + .desc.csel_reg = DA9062AA_BUCK_ILIM_C, + .desc.csel_mask = DA9062AA_BUCK1_ILIM_MASK, .desc.enable_reg = DA9062AA_BUCK1_CONT, .desc.enable_mask = DA9062AA_BUCK1_EN_MASK, .desc.vsel_reg = DA9062AA_VBUCK1_A, @@ -457,10 +421,6 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = { __builtin_ffs((int)DA9062AA_VBUCK1_SEL_MASK) - 1, sizeof(unsigned int) * 8 - __builtin_clz((DA9062AA_VBUCK1_SEL_MASK)) - 1), - .ilimit = REG_FIELD(DA9062AA_BUCK_ILIM_C, - __builtin_ffs((int)DA9062AA_BUCK1_ILIM_MASK) - 1, - sizeof(unsigned int) * 8 - - __builtin_clz((DA9062AA_BUCK1_ILIM_MASK)) - 1), }, { .desc.id = DA9061_ID_BUCK2, @@ -471,8 +431,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = { .desc.min_uV = (800) * 1000, .desc.uV_step = (20) * 1000, .desc.n_voltages = ((3340) - (800))/(20) + 1, - .current_limits = da9062_buck_b_limits, - .n_current_limits = ARRAY_SIZE(da9062_buck_b_limits), + .desc.curr_table = da9062_buck_b_limits, + .desc.n_current_limits = ARRAY_SIZE(da9062_buck_b_limits), + .desc.csel_reg = DA9062AA_BUCK_ILIM_A, + .desc.csel_mask = DA9062AA_BUCK3_ILIM_MASK, .desc.enable_reg = DA9062AA_BUCK3_CONT, .desc.enable_mask = DA9062AA_BUCK3_EN_MASK, .desc.vsel_reg = DA9062AA_VBUCK3_A, @@ -495,10 +457,6 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = { __builtin_ffs((int)DA9062AA_VBUCK3_SEL_MASK) - 1, sizeof(unsigned int) * 8 - __builtin_clz((DA9062AA_VBUCK3_SEL_MASK)) - 1), - .ilimit = REG_FIELD(DA9062AA_BUCK_ILIM_A, - __builtin_ffs((int)DA9062AA_BUCK3_ILIM_MASK) - 1, - sizeof(unsigned int) * 8 - - __builtin_clz((DA9062AA_BUCK3_ILIM_MASK)) - 1), }, { .desc.id = DA9061_ID_BUCK3, @@ -509,8 +467,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = { .desc.min_uV = (530) * 1000, .desc.uV_step = (10) * 1000, .desc.n_voltages = ((1800) - (530))/(10) + 1, - .current_limits = da9062_buck_a_limits, - .n_current_limits = ARRAY_SIZE(da9062_buck_a_limits), + .desc.curr_table = da9062_buck_a_limits, + .desc.n_current_limits = ARRAY_SIZE(da9062_buck_a_limits), + .desc.csel_reg = DA9062AA_BUCK_ILIM_B, + .desc.csel_mask = DA9062AA_BUCK4_ILIM_MASK, .desc.enable_reg = DA9062AA_BUCK4_CONT, .desc.enable_mask = DA9062AA_BUCK4_EN_MASK, .desc.vsel_reg = DA9062AA_VBUCK4_A, @@ -533,10 +493,6 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = { __builtin_ffs((int)DA9062AA_VBUCK4_SEL_MASK) - 1, sizeof(unsigned int) * 8 - __builtin_clz((DA9062AA_VBUCK4_SEL_MASK)) - 1), - .ilimit = REG_FIELD(DA9062AA_BUCK_ILIM_B, - __builtin_ffs((int)DA9062AA_BUCK4_ILIM_MASK) - 1, - sizeof(unsigned int) * 8 - - __builtin_clz((DA9062AA_BUCK4_ILIM_MASK)) - 1), }, { .desc.id = DA9061_ID_LDO1, @@ -679,8 +635,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = { .desc.min_uV = (300) * 1000, .desc.uV_step = (10) * 1000, .desc.n_voltages = ((1570) - (300))/(10) + 1, - .current_limits = da9062_buck_a_limits, - .n_current_limits = ARRAY_SIZE(da9062_buck_a_limits), + .desc.curr_table = da9062_buck_a_limits, + .desc.n_current_limits = ARRAY_SIZE(da9062_buck_a_limits), + .desc.csel_reg = DA9062AA_BUCK_ILIM_C, + .desc.csel_mask = DA9062AA_BUCK1_ILIM_MASK, .desc.enable_reg = DA9062AA_BUCK1_CONT, .desc.enable_mask = DA9062AA_BUCK1_EN_MASK, .desc.vsel_reg = DA9062AA_VBUCK1_A, @@ -703,10 +661,6 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = { __builtin_ffs((int)DA9062AA_VBUCK1_SEL_MASK) - 1, sizeof(unsigned int) * 8 - __builtin_clz((DA9062AA_VBUCK1_SEL_MASK)) - 1), - .ilimit = REG_FIELD(DA9062AA_BUCK_ILIM_C, - __builtin_ffs((int)DA9062AA_BUCK1_ILIM_MASK) - 1, - sizeof(unsigned int) * 8 - - __builtin_clz((DA9062AA_BUCK1_ILIM_MASK)) - 1), }, { .desc.id = DA9062_ID_BUCK2, @@ -717,8 +671,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = { .desc.min_uV = (300) * 1000, .desc.uV_step = (10) * 1000, .desc.n_voltages = ((1570) - (300))/(10) + 1, - .current_limits = da9062_buck_a_limits, - .n_current_limits = ARRAY_SIZE(da9062_buck_a_limits), + .desc.curr_table = da9062_buck_a_limits, + .desc.n_current_limits = ARRAY_SIZE(da9062_buck_a_limits), + .desc.csel_reg = DA9062AA_BUCK_ILIM_C, + .desc.csel_mask = DA9062AA_BUCK2_ILIM_MASK, .desc.enable_reg = DA9062AA_BUCK2_CONT, .desc.enable_mask = DA9062AA_BUCK2_EN_MASK, .desc.vsel_reg = DA9062AA_VBUCK2_A, @@ -741,10 +697,6 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = { __builtin_ffs((int)DA9062AA_VBUCK2_SEL_MASK) - 1, sizeof(unsigned int) * 8 - __builtin_clz((DA9062AA_VBUCK2_SEL_MASK)) - 1), - .ilimit = REG_FIELD(DA9062AA_BUCK_ILIM_C, - __builtin_ffs((int)DA9062AA_BUCK2_ILIM_MASK) - 1, - sizeof(unsigned int) * 8 - - __builtin_clz((DA9062AA_BUCK2_ILIM_MASK)) - 1), }, { .desc.id = DA9062_ID_BUCK3, @@ -755,8 +707,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = { .desc.min_uV = (800) * 1000, .desc.uV_step = (20) * 1000, .desc.n_voltages = ((3340) - (800))/(20) + 1, - .current_limits = da9062_buck_b_limits, - .n_current_limits = ARRAY_SIZE(da9062_buck_b_limits), + .desc.curr_table = da9062_buck_b_limits, + .desc.n_current_limits = ARRAY_SIZE(da9062_buck_b_limits), + .desc.csel_reg = DA9062AA_BUCK_ILIM_A, + .desc.csel_mask = DA9062AA_BUCK3_ILIM_MASK, .desc.enable_reg = DA9062AA_BUCK3_CONT, .desc.enable_mask = DA9062AA_BUCK3_EN_MASK, .desc.vsel_reg = DA9062AA_VBUCK3_A, @@ -779,10 +733,6 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = { __builtin_ffs((int)DA9062AA_VBUCK3_SEL_MASK) - 1, sizeof(unsigned int) * 8 - __builtin_clz((DA9062AA_VBUCK3_SEL_MASK)) - 1), - .ilimit = REG_FIELD(DA9062AA_BUCK_ILIM_A, - __builtin_ffs((int)DA9062AA_BUCK3_ILIM_MASK) - 1, - sizeof(unsigned int) * 8 - - __builtin_clz((DA9062AA_BUCK3_ILIM_MASK)) - 1), }, { .desc.id = DA9062_ID_BUCK4, @@ -793,8 +743,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = { .desc.min_uV = (530) * 1000, .desc.uV_step = (10) * 1000, .desc.n_voltages = ((1800) - (530))/(10) + 1, - .current_limits = da9062_buck_a_limits, - .n_current_limits = ARRAY_SIZE(da9062_buck_a_limits), + .desc.curr_table = da9062_buck_a_limits, + .desc.n_current_limits = ARRAY_SIZE(da9062_buck_a_limits), + .desc.csel_reg = DA9062AA_BUCK_ILIM_B, + .desc.csel_mask = DA9062AA_BUCK4_ILIM_MASK, .desc.enable_reg = DA9062AA_BUCK4_CONT, .desc.enable_mask = DA9062AA_BUCK4_EN_MASK, .desc.vsel_reg = DA9062AA_VBUCK4_A, @@ -817,10 +769,6 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = { __builtin_ffs((int)DA9062AA_VBUCK4_SEL_MASK) - 1, sizeof(unsigned int) * 8 - __builtin_clz((DA9062AA_VBUCK4_SEL_MASK)) - 1), - .ilimit = REG_FIELD(DA9062AA_BUCK_ILIM_B, - __builtin_ffs((int)DA9062AA_BUCK4_ILIM_MASK) - 1, - sizeof(unsigned int) * 8 - - __builtin_clz((DA9062AA_BUCK4_ILIM_MASK)) - 1), }, { .desc.id = DA9062_ID_LDO1, @@ -974,8 +922,10 @@ static irqreturn_t da9062_ldo_lim_event(int irq, void *data) continue; if (BIT(regl->info->oc_event.lsb) & bits) { + regulator_lock(regl->rdev); regulator_notifier_call_chain(regl->rdev, REGULATOR_EVENT_OVER_CURRENT, NULL); + regulator_unlock(regl->rdev); handled = IRQ_HANDLED; } } @@ -1063,15 +1013,6 @@ static int da9062_regulator_probe(struct platform_device *pdev) return PTR_ERR(regl->suspend_sleep); } - if (regl->info->ilimit.reg) { - regl->ilimit = devm_regmap_field_alloc( - &pdev->dev, - chip->regmap, - regl->info->ilimit); - if (IS_ERR(regl->ilimit)) - return PTR_ERR(regl->ilimit); - } - /* Register regulator */ memset(&config, 0, sizeof(config)); config.dev = chip->dev; diff --git a/drivers/regulator/da9063-regulator.c b/drivers/regulator/da9063-regulator.c index 2b0c7a85306a..c5d1ae5265ab 100644 --- a/drivers/regulator/da9063-regulator.c +++ b/drivers/regulator/da9063-regulator.c @@ -38,17 +38,12 @@ struct da9063_regulator_info { struct regulator_desc desc; - /* Current limiting */ - unsigned n_current_limits; - const int *current_limits; - /* DA9063 main register fields */ struct reg_field mode; /* buck mode of operation */ struct reg_field suspend; struct reg_field sleep; struct reg_field suspend_sleep; unsigned int suspend_vsel_reg; - struct reg_field ilimit; /* DA9063 event detection bit */ struct reg_field oc_event; @@ -73,15 +68,18 @@ struct da9063_regulator_info { .suspend_vsel_reg = DA9063_REG_V##regl_name##_B /* Macros for voltage DC/DC converters (BUCKs) */ -#define DA9063_BUCK(chip, regl_name, min_mV, step_mV, max_mV, limits_array) \ +#define DA9063_BUCK(chip, regl_name, min_mV, step_mV, max_mV, limits_array, \ + creg, cmask) \ .desc.id = chip##_ID_##regl_name, \ .desc.name = __stringify(chip##_##regl_name), \ .desc.ops = &da9063_buck_ops, \ .desc.min_uV = (min_mV) * 1000, \ .desc.uV_step = (step_mV) * 1000, \ .desc.n_voltages = ((max_mV) - (min_mV))/(step_mV) + 1, \ - .current_limits = limits_array, \ - .n_current_limits = ARRAY_SIZE(limits_array) + .desc.csel_reg = (creg), \ + .desc.csel_mask = (cmask), \ + .desc.curr_table = limits_array, \ + .desc.n_current_limits = ARRAY_SIZE(limits_array) #define DA9063_BUCK_COMMON_FIELDS(regl_name) \ .desc.enable_reg = DA9063_REG_##regl_name##_CONT, \ @@ -112,7 +110,6 @@ struct da9063_regulator { struct regmap_field *suspend; struct regmap_field *sleep; struct regmap_field *suspend_sleep; - struct regmap_field *ilimit; }; /* Encapsulates all information for the regulators driver */ @@ -134,65 +131,32 @@ enum { /* Current limits array (in uA) for BCORE1, BCORE2, BPRO. Entry indexes corresponds to register values. */ -static const int da9063_buck_a_limits[] = { +static const unsigned int da9063_buck_a_limits[] = { 500000, 600000, 700000, 800000, 900000, 1000000, 1100000, 1200000, 1300000, 1400000, 1500000, 1600000, 1700000, 1800000, 1900000, 2000000 }; /* Current limits array (in uA) for BMEM, BIO, BPERI. Entry indexes corresponds to register values. */ -static const int da9063_buck_b_limits[] = { +static const unsigned int da9063_buck_b_limits[] = { 1500000, 1600000, 1700000, 1800000, 1900000, 2000000, 2100000, 2200000, 2300000, 2400000, 2500000, 2600000, 2700000, 2800000, 2900000, 3000000 }; /* Current limits array (in uA) for merged BCORE1 and BCORE2. Entry indexes corresponds to register values. */ -static const int da9063_bcores_merged_limits[] = { +static const unsigned int da9063_bcores_merged_limits[] = { 1000000, 1200000, 1400000, 1600000, 1800000, 2000000, 2200000, 2400000, 2600000, 2800000, 3000000, 3200000, 3400000, 3600000, 3800000, 4000000 }; /* Current limits array (in uA) for merged BMEM and BIO. Entry indexes corresponds to register values. */ -static const int da9063_bmem_bio_merged_limits[] = { +static const unsigned int da9063_bmem_bio_merged_limits[] = { 3000000, 3200000, 3400000, 3600000, 3800000, 4000000, 4200000, 4400000, 4600000, 4800000, 5000000, 5200000, 5400000, 5600000, 5800000, 6000000 }; -static int da9063_set_current_limit(struct regulator_dev *rdev, - int min_uA, int max_uA) -{ - struct da9063_regulator *regl = rdev_get_drvdata(rdev); - const struct da9063_regulator_info *rinfo = regl->info; - int n, tval; - - for (n = rinfo->n_current_limits - 1; n >= 0; n--) { - tval = rinfo->current_limits[n]; - if (tval >= min_uA && tval <= max_uA) - return regmap_field_write(regl->ilimit, n); - } - - return -EINVAL; -} - -static int da9063_get_current_limit(struct regulator_dev *rdev) -{ - struct da9063_regulator *regl = rdev_get_drvdata(rdev); - const struct da9063_regulator_info *rinfo = regl->info; - unsigned int sel; - int ret; - - ret = regmap_field_read(regl->ilimit, &sel); - if (ret < 0) - return ret; - - if (sel >= rinfo->n_current_limits) - sel = rinfo->n_current_limits - 1; - - return rinfo->current_limits[sel]; -} - static int da9063_buck_set_mode(struct regulator_dev *rdev, unsigned mode) { struct da9063_regulator *regl = rdev_get_drvdata(rdev); @@ -434,8 +398,8 @@ static const struct regulator_ops da9063_buck_ops = { .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, .list_voltage = regulator_list_voltage_linear, - .set_current_limit = da9063_set_current_limit, - .get_current_limit = da9063_get_current_limit, + .set_current_limit = regulator_set_current_limit_regmap, + .get_current_limit = regulator_get_current_limit_regmap, .set_mode = da9063_buck_set_mode, .get_mode = da9063_buck_get_mode, .get_status = da9063_buck_get_status, @@ -465,69 +429,61 @@ static const struct regulator_ops da9063_ldo_ops = { static const struct da9063_regulator_info da9063_regulator_info[] = { { DA9063_BUCK(DA9063, BCORE1, 300, 10, 1570, - da9063_buck_a_limits), + da9063_buck_a_limits, + DA9063_REG_BUCK_ILIM_C, DA9063_BCORE1_ILIM_MASK), DA9063_BUCK_COMMON_FIELDS(BCORE1), .suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VBCORE1_SEL), - .ilimit = BFIELD(DA9063_REG_BUCK_ILIM_C, - DA9063_BCORE1_ILIM_MASK), }, { DA9063_BUCK(DA9063, BCORE2, 300, 10, 1570, - da9063_buck_a_limits), + da9063_buck_a_limits, + DA9063_REG_BUCK_ILIM_C, DA9063_BCORE2_ILIM_MASK), DA9063_BUCK_COMMON_FIELDS(BCORE2), .suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VBCORE2_SEL), - .ilimit = BFIELD(DA9063_REG_BUCK_ILIM_C, - DA9063_BCORE2_ILIM_MASK), }, { DA9063_BUCK(DA9063, BPRO, 530, 10, 1800, - da9063_buck_a_limits), + da9063_buck_a_limits, + DA9063_REG_BUCK_ILIM_B, DA9063_BPRO_ILIM_MASK), DA9063_BUCK_COMMON_FIELDS(BPRO), .suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VBPRO_SEL), - .ilimit = BFIELD(DA9063_REG_BUCK_ILIM_B, - DA9063_BPRO_ILIM_MASK), }, { DA9063_BUCK(DA9063, BMEM, 800, 20, 3340, - da9063_buck_b_limits), + da9063_buck_b_limits, + DA9063_REG_BUCK_ILIM_A, DA9063_BMEM_ILIM_MASK), DA9063_BUCK_COMMON_FIELDS(BMEM), .suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VBMEM_SEL), - .ilimit = BFIELD(DA9063_REG_BUCK_ILIM_A, - DA9063_BMEM_ILIM_MASK), }, { DA9063_BUCK(DA9063, BIO, 800, 20, 3340, - da9063_buck_b_limits), + da9063_buck_b_limits, + DA9063_REG_BUCK_ILIM_A, DA9063_BIO_ILIM_MASK), DA9063_BUCK_COMMON_FIELDS(BIO), .suspend = BFIELD(DA9063_REG_DVC_2, DA9063_VBIO_SEL), - .ilimit = BFIELD(DA9063_REG_BUCK_ILIM_A, - DA9063_BIO_ILIM_MASK), }, { DA9063_BUCK(DA9063, BPERI, 800, 20, 3340, - da9063_buck_b_limits), + da9063_buck_b_limits, + DA9063_REG_BUCK_ILIM_B, DA9063_BPERI_ILIM_MASK), DA9063_BUCK_COMMON_FIELDS(BPERI), .suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VBPERI_SEL), - .ilimit = BFIELD(DA9063_REG_BUCK_ILIM_B, - DA9063_BPERI_ILIM_MASK), }, { DA9063_BUCK(DA9063, BCORES_MERGED, 300, 10, 1570, - da9063_bcores_merged_limits), + da9063_bcores_merged_limits, + DA9063_REG_BUCK_ILIM_C, DA9063_BCORE1_ILIM_MASK), /* BCORES_MERGED uses the same register fields as BCORE1 */ DA9063_BUCK_COMMON_FIELDS(BCORE1), .suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VBCORE1_SEL), - .ilimit = BFIELD(DA9063_REG_BUCK_ILIM_C, - DA9063_BCORE1_ILIM_MASK), }, { DA9063_BUCK(DA9063, BMEM_BIO_MERGED, 800, 20, 3340, - da9063_bmem_bio_merged_limits), + da9063_bmem_bio_merged_limits, + DA9063_REG_BUCK_ILIM_A, DA9063_BMEM_ILIM_MASK), /* BMEM_BIO_MERGED uses the same register fields as BMEM */ DA9063_BUCK_COMMON_FIELDS(BMEM), .suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VBMEM_SEL), - .ilimit = BFIELD(DA9063_REG_BUCK_ILIM_A, - DA9063_BMEM_ILIM_MASK), }, { DA9063_LDO(DA9063, LDO3, 900, 20, 3440), @@ -615,9 +571,12 @@ static irqreturn_t da9063_ldo_lim_event(int irq, void *data) if (regl->info->oc_event.reg != DA9063_REG_STATUS_D) continue; - if (BIT(regl->info->oc_event.lsb) & bits) + if (BIT(regl->info->oc_event.lsb) & bits) { + regulator_lock(regl->rdev); regulator_notifier_call_chain(regl->rdev, REGULATOR_EVENT_OVER_CURRENT, NULL); + regulator_unlock(regl->rdev); + } } return IRQ_HANDLED; @@ -861,13 +820,6 @@ static int da9063_regulator_probe(struct platform_device *pdev) return PTR_ERR(regl->suspend_sleep); } - if (regl->info->ilimit.reg) { - regl->ilimit = devm_regmap_field_alloc(&pdev->dev, - da9063->regmap, regl->info->ilimit); - if (IS_ERR(regl->ilimit)) - return PTR_ERR(regl->ilimit); - } - /* Register regulator */ memset(&config, 0, sizeof(config)); config.dev = &pdev->dev; diff --git a/drivers/regulator/da9211-regulator.c b/drivers/regulator/da9211-regulator.c index 109ee12d4362..4d7fe4819c1c 100644 --- a/drivers/regulator/da9211-regulator.c +++ b/drivers/regulator/da9211-regulator.c @@ -322,8 +322,10 @@ static irqreturn_t da9211_irq_handler(int irq, void *data) goto error_i2c; if (reg_val & DA9211_E_OV_CURR_A) { + regulator_lock(chip->rdev[0]); regulator_notifier_call_chain(chip->rdev[0], REGULATOR_EVENT_OVER_CURRENT, NULL); + regulator_unlock(chip->rdev[0]); err = regmap_write(chip->regmap, DA9211_REG_EVENT_B, DA9211_E_OV_CURR_A); @@ -334,8 +336,10 @@ static irqreturn_t da9211_irq_handler(int irq, void *data) } if (reg_val & DA9211_E_OV_CURR_B) { + regulator_lock(chip->rdev[1]); regulator_notifier_call_chain(chip->rdev[1], REGULATOR_EVENT_OVER_CURRENT, NULL); + regulator_unlock(chip->rdev[1]); err = regmap_write(chip->regmap, DA9211_REG_EVENT_B, DA9211_E_OV_CURR_B); diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c index 6157001df0a4..f50d86a66138 100644 --- a/drivers/regulator/gpio-regulator.c +++ b/drivers/regulator/gpio-regulator.c @@ -36,7 +36,6 @@ struct gpio_regulator_data { struct regulator_desc desc; - struct regulator_dev *dev; struct gpio_desc **gpiods; int nr_gpios; @@ -125,7 +124,7 @@ static int gpio_regulator_set_current_limit(struct regulator_dev *dev, return 0; } -static struct regulator_ops gpio_regulator_voltage_ops = { +static const struct regulator_ops gpio_regulator_voltage_ops = { .get_voltage = gpio_regulator_get_value, .set_voltage = gpio_regulator_set_voltage, .list_voltage = gpio_regulator_list_voltage, @@ -221,7 +220,7 @@ of_get_gpio_regulator_config(struct device *dev, struct device_node *np, return config; } -static struct regulator_ops gpio_regulator_current_ops = { +static const struct regulator_ops gpio_regulator_current_ops = { .get_current_limit = gpio_regulator_get_value, .set_current_limit = gpio_regulator_set_current_limit, }; @@ -233,6 +232,7 @@ static int gpio_regulator_probe(struct platform_device *pdev) struct device_node *np = dev->of_node; struct gpio_regulator_data *drvdata; struct regulator_config cfg = { }; + struct regulator_dev *rdev; enum gpiod_flags gflags; int ptr, ret, state, i; @@ -326,9 +326,9 @@ static int gpio_regulator_probe(struct platform_device *pdev) if (IS_ERR(cfg.ena_gpiod)) return PTR_ERR(cfg.ena_gpiod); - drvdata->dev = regulator_register(&drvdata->desc, &cfg); - if (IS_ERR(drvdata->dev)) { - ret = PTR_ERR(drvdata->dev); + rdev = devm_regulator_register(dev, &drvdata->desc, &cfg); + if (IS_ERR(rdev)) { + ret = PTR_ERR(rdev); dev_err(dev, "Failed to register regulator: %d\n", ret); return ret; } @@ -338,15 +338,6 @@ static int gpio_regulator_probe(struct platform_device *pdev) return 0; } -static int gpio_regulator_remove(struct platform_device *pdev) -{ - struct gpio_regulator_data *drvdata = platform_get_drvdata(pdev); - - regulator_unregister(drvdata->dev); - - return 0; -} - #if defined(CONFIG_OF) static const struct of_device_id regulator_gpio_of_match[] = { { .compatible = "regulator-gpio", }, @@ -357,7 +348,6 @@ MODULE_DEVICE_TABLE(of, regulator_gpio_of_match); static struct platform_driver gpio_regulator_driver = { .probe = gpio_regulator_probe, - .remove = gpio_regulator_remove, .driver = { .name = "gpio-regulator", .of_match_table = of_match_ptr(regulator_gpio_of_match), diff --git a/drivers/regulator/lp8755.c b/drivers/regulator/lp8755.c index 14fd38807134..2e16a6ab491d 100644 --- a/drivers/regulator/lp8755.c +++ b/drivers/regulator/lp8755.c @@ -372,10 +372,13 @@ static irqreturn_t lp8755_irq_handler(int irq, void *data) for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++) if ((flag0 & (0x4 << icnt)) && (pchip->irqmask & (0x04 << icnt)) - && (pchip->rdev[icnt] != NULL)) + && (pchip->rdev[icnt] != NULL)) { + regulator_lock(pchip->rdev[icnt]); regulator_notifier_call_chain(pchip->rdev[icnt], LP8755_EVENT_PWR_FAULT, NULL); + regulator_unlock(pchip->rdev[icnt]); + } /* read flag1 register */ ret = lp8755_read(pchip, 0x0E, &flag1); @@ -389,18 +392,24 @@ static irqreturn_t lp8755_irq_handler(int irq, void *data) /* send OCP event to all regulator devices */ if ((flag1 & 0x01) && (pchip->irqmask & 0x01)) for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++) - if (pchip->rdev[icnt] != NULL) + if (pchip->rdev[icnt] != NULL) { + regulator_lock(pchip->rdev[icnt]); regulator_notifier_call_chain(pchip->rdev[icnt], LP8755_EVENT_OCP, NULL); + regulator_unlock(pchip->rdev[icnt]); + } /* send OVP event to all regulator devices */ if ((flag1 & 0x02) && (pchip->irqmask & 0x02)) for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++) - if (pchip->rdev[icnt] != NULL) + if (pchip->rdev[icnt] != NULL) { + regulator_lock(pchip->rdev[icnt]); regulator_notifier_call_chain(pchip->rdev[icnt], LP8755_EVENT_OVP, NULL); + regulator_unlock(pchip->rdev[icnt]); + } return IRQ_HANDLED; err_i2c: diff --git a/drivers/regulator/lp87565-regulator.c b/drivers/regulator/lp87565-regulator.c index 4ed41731a5b1..81eb4b890c0c 100644 --- a/drivers/regulator/lp87565-regulator.c +++ b/drivers/regulator/lp87565-regulator.c @@ -34,6 +34,10 @@ .ramp_delay = _delay, \ .linear_ranges = _lr, \ .n_linear_ranges = ARRAY_SIZE(_lr), \ + .curr_table = lp87565_buck_uA, \ + .n_current_limits = ARRAY_SIZE(lp87565_buck_uA),\ + .csel_reg = (_cr), \ + .csel_mask = LP87565_BUCK_CTRL_2_ILIM, \ }, \ .ctrl2_reg = _cr, \ } @@ -102,44 +106,7 @@ static int lp87565_buck_set_ramp_delay(struct regulator_dev *rdev, return 0; } -static int lp87565_buck_set_current_limit(struct regulator_dev *rdev, - int min_uA, int max_uA) -{ - int id = rdev_get_id(rdev); - struct lp87565 *lp87565 = rdev_get_drvdata(rdev); - int i; - - for (i = ARRAY_SIZE(lp87565_buck_uA) - 1; i >= 0; i--) { - if (lp87565_buck_uA[i] >= min_uA && - lp87565_buck_uA[i] <= max_uA) - return regmap_update_bits(lp87565->regmap, - regulators[id].ctrl2_reg, - LP87565_BUCK_CTRL_2_ILIM, - i << __ffs(LP87565_BUCK_CTRL_2_ILIM)); - } - - return -EINVAL; -} - -static int lp87565_buck_get_current_limit(struct regulator_dev *rdev) -{ - int id = rdev_get_id(rdev); - struct lp87565 *lp87565 = rdev_get_drvdata(rdev); - int ret; - unsigned int val; - - ret = regmap_read(lp87565->regmap, regulators[id].ctrl2_reg, &val); - if (ret) - return ret; - - val = (val & LP87565_BUCK_CTRL_2_ILIM) >> - __ffs(LP87565_BUCK_CTRL_2_ILIM); - - return (val < ARRAY_SIZE(lp87565_buck_uA)) ? - lp87565_buck_uA[val] : -EINVAL; -} - -/* Operations permitted on BUCK0, BUCK1 */ +/* Operations permitted on BUCKs */ static const struct regulator_ops lp87565_buck_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, @@ -150,8 +117,8 @@ static const struct regulator_ops lp87565_buck_ops = { .map_voltage = regulator_map_voltage_linear_range, .set_voltage_time_sel = regulator_set_voltage_time_sel, .set_ramp_delay = lp87565_buck_set_ramp_delay, - .set_current_limit = lp87565_buck_set_current_limit, - .get_current_limit = lp87565_buck_get_current_limit, + .set_current_limit = regulator_set_current_limit_regmap, + .get_current_limit = regulator_get_current_limit_regmap, }; static const struct lp87565_regulator regulators[] = { @@ -193,7 +160,7 @@ static int lp87565_regulator_probe(struct platform_device *pdev) struct lp87565 *lp87565 = dev_get_drvdata(pdev->dev.parent); struct regulator_config config = { }; struct regulator_dev *rdev; - int i, min_idx = LP87565_BUCK_1, max_idx = LP87565_BUCK_3; + int i, min_idx = LP87565_BUCK_0, max_idx = LP87565_BUCK_3; platform_set_drvdata(pdev, lp87565); diff --git a/drivers/regulator/ltc3589.c b/drivers/regulator/ltc3589.c index 63f724f260ef..75089b037b72 100644 --- a/drivers/regulator/ltc3589.c +++ b/drivers/regulator/ltc3589.c @@ -419,16 +419,22 @@ static irqreturn_t ltc3589_isr(int irq, void *dev_id) if (irqstat & LTC3589_IRQSTAT_THERMAL_WARN) { event = REGULATOR_EVENT_OVER_TEMP; - for (i = 0; i < LTC3589_NUM_REGULATORS; i++) + for (i = 0; i < LTC3589_NUM_REGULATORS; i++) { + regulator_lock(ltc3589->regulators[i]); regulator_notifier_call_chain(ltc3589->regulators[i], event, NULL); + regulator_unlock(ltc3589->regulators[i]); + } } if (irqstat & LTC3589_IRQSTAT_UNDERVOLT_WARN) { event = REGULATOR_EVENT_UNDER_VOLTAGE; - for (i = 0; i < LTC3589_NUM_REGULATORS; i++) + for (i = 0; i < LTC3589_NUM_REGULATORS; i++) { + regulator_lock(ltc3589->regulators[i]); regulator_notifier_call_chain(ltc3589->regulators[i], event, NULL); + regulator_unlock(ltc3589->regulators[i]); + } } /* Clear warning condition */ diff --git a/drivers/regulator/ltc3676.c b/drivers/regulator/ltc3676.c index e6d66e492b85..4be90c78c720 100644 --- a/drivers/regulator/ltc3676.c +++ b/drivers/regulator/ltc3676.c @@ -285,17 +285,23 @@ static irqreturn_t ltc3676_isr(int irq, void *dev_id) if (irqstat & LTC3676_IRQSTAT_THERMAL_WARN) { dev_warn(dev, "Over-temperature Warning\n"); event = REGULATOR_EVENT_OVER_TEMP; - for (i = 0; i < LTC3676_NUM_REGULATORS; i++) + for (i = 0; i < LTC3676_NUM_REGULATORS; i++) { + regulator_lock(ltc3676->regulators[i]); regulator_notifier_call_chain(ltc3676->regulators[i], event, NULL); + regulator_unlock(ltc3676->regulators[i]); + } } if (irqstat & LTC3676_IRQSTAT_UNDERVOLT_WARN) { dev_info(dev, "Undervoltage Warning\n"); event = REGULATOR_EVENT_UNDER_VOLTAGE; - for (i = 0; i < LTC3676_NUM_REGULATORS; i++) + for (i = 0; i < LTC3676_NUM_REGULATORS; i++) { + regulator_lock(ltc3676->regulators[i]); regulator_notifier_call_chain(ltc3676->regulators[i], event, NULL); + regulator_unlock(ltc3676->regulators[i]); + } } /* Clear warning condition */ diff --git a/drivers/regulator/max14577-regulator.c b/drivers/regulator/max14577-regulator.c index 85a88a9e4d42..07a150c9bbf2 100644 --- a/drivers/regulator/max14577-regulator.c +++ b/drivers/regulator/max14577-regulator.c @@ -155,58 +155,6 @@ static const struct regulator_desc max77836_supported_regulators[] = { [MAX77836_LDO2] = MAX77836_LDO_REG(2), }; -#ifdef CONFIG_OF -static struct of_regulator_match max14577_regulator_matches[] = { - { .name = "SAFEOUT", }, - { .name = "CHARGER", }, -}; - -static struct of_regulator_match max77836_regulator_matches[] = { - { .name = "SAFEOUT", }, - { .name = "CHARGER", }, - { .name = "LDO1", }, - { .name = "LDO2", }, -}; - -static inline struct regulator_init_data *match_init_data(int index, - enum maxim_device_type dev_type) -{ - switch (dev_type) { - case MAXIM_DEVICE_TYPE_MAX77836: - return max77836_regulator_matches[index].init_data; - - case MAXIM_DEVICE_TYPE_MAX14577: - default: - return max14577_regulator_matches[index].init_data; - } -} - -static inline struct device_node *match_of_node(int index, - enum maxim_device_type dev_type) -{ - switch (dev_type) { - case MAXIM_DEVICE_TYPE_MAX77836: - return max77836_regulator_matches[index].of_node; - - case MAXIM_DEVICE_TYPE_MAX14577: - default: - return max14577_regulator_matches[index].of_node; - } -} -#else /* CONFIG_OF */ -static inline struct regulator_init_data *match_init_data(int index, - enum maxim_device_type dev_type) -{ - return NULL; -} - -static inline struct device_node *match_of_node(int index, - enum maxim_device_type dev_type) -{ - return NULL; -} -#endif /* CONFIG_OF */ - /** * Registers for regulators of max77836 use different I2C slave addresses so * different regmaps must be used for them. @@ -265,9 +213,6 @@ static int max14577_regulator_probe(struct platform_device *pdev) if (pdata && pdata->regulators) { config.init_data = pdata->regulators[i].initdata; config.of_node = pdata->regulators[i].of_node; - } else { - config.init_data = match_init_data(i, dev_type); - config.of_node = match_of_node(i, dev_type); } config.regmap = max14577_get_regmap(max14577, supported_regulators[i].id); diff --git a/drivers/regulator/max77650-regulator.c b/drivers/regulator/max77650-regulator.c index 31ebf34b01ec..5c4f86c98510 100644 --- a/drivers/regulator/max77650-regulator.c +++ b/drivers/regulator/max77650-regulator.c @@ -41,7 +41,7 @@ struct max77650_regulator_desc { unsigned int regB; }; -static const u32 max77651_sbb1_regulator_volt_table[] = { +static const unsigned int max77651_sbb1_regulator_volt_table[] = { 2400000, 3200000, 4000000, 4800000, 2450000, 3250000, 4050000, 4850000, 2500000, 3300000, 4100000, 4900000, diff --git a/drivers/regulator/mt6323-regulator.c b/drivers/regulator/mt6323-regulator.c index b7b9670f0979..25b002328910 100644 --- a/drivers/regulator/mt6323-regulator.c +++ b/drivers/regulator/mt6323-regulator.c @@ -118,43 +118,43 @@ static const struct regulator_linear_range buck_volt_range3[] = { REGULATOR_LINEAR_RANGE(500000, 0, 0x3f, 50000), }; -static const u32 ldo_volt_table1[] = { +static const unsigned int ldo_volt_table1[] = { 3300000, 3400000, 3500000, 3600000, }; -static const u32 ldo_volt_table2[] = { +static const unsigned int ldo_volt_table2[] = { 1500000, 1800000, 2500000, 2800000, }; -static const u32 ldo_volt_table3[] = { +static const unsigned int ldo_volt_table3[] = { 1800000, 3300000, }; -static const u32 ldo_volt_table4[] = { +static const unsigned int ldo_volt_table4[] = { 3000000, 3300000, }; -static const u32 ldo_volt_table5[] = { +static const unsigned int ldo_volt_table5[] = { 1200000, 1300000, 1500000, 1800000, 2000000, 2800000, 3000000, 3300000, }; -static const u32 ldo_volt_table6[] = { +static const unsigned int ldo_volt_table6[] = { 1200000, 1300000, 1500000, 1800000, 2500000, 2800000, 3000000, 2000000, }; -static const u32 ldo_volt_table7[] = { +static const unsigned int ldo_volt_table7[] = { 1200000, 1300000, 1500000, 1800000, }; -static const u32 ldo_volt_table8[] = { +static const unsigned int ldo_volt_table8[] = { 1800000, 3000000, }; -static const u32 ldo_volt_table9[] = { +static const unsigned int ldo_volt_table9[] = { 1200000, 1350000, 1500000, 1800000, }; -static const u32 ldo_volt_table10[] = { +static const unsigned int ldo_volt_table10[] = { 1200000, 1300000, 1500000, 1800000, }; diff --git a/drivers/regulator/mt6380-regulator.c b/drivers/regulator/mt6380-regulator.c index 127dd720cbcc..86bc332df3f2 100644 --- a/drivers/regulator/mt6380-regulator.c +++ b/drivers/regulator/mt6380-regulator.c @@ -173,19 +173,19 @@ static const struct regulator_linear_range buck_volt_range3[] = { REGULATOR_LINEAR_RANGE(1200000, 0, 0x3c, 25000), }; -static const u32 ldo_volt_table1[] = { +static const unsigned int ldo_volt_table1[] = { 1400000, 1350000, 1300000, 1250000, 1200000, 1150000, 1100000, 1050000, }; -static const u32 ldo_volt_table2[] = { +static const unsigned int ldo_volt_table2[] = { 2200000, 3300000, }; -static const u32 ldo_volt_table3[] = { +static const unsigned int ldo_volt_table3[] = { 1240000, 1390000, 1540000, 1840000, }; -static const u32 ldo_volt_table4[] = { +static const unsigned int ldo_volt_table4[] = { 2200000, 3300000, }; diff --git a/drivers/regulator/mt6397-regulator.c b/drivers/regulator/mt6397-regulator.c index c6c6aa85e4e8..3e6c8d99ec0f 100644 --- a/drivers/regulator/mt6397-regulator.c +++ b/drivers/regulator/mt6397-regulator.c @@ -123,35 +123,35 @@ static const struct regulator_linear_range buck_volt_range3[] = { REGULATOR_LINEAR_RANGE(1500000, 0, 0x1f, 20000), }; -static const u32 ldo_volt_table1[] = { +static const unsigned int ldo_volt_table1[] = { 1500000, 1800000, 2500000, 2800000, }; -static const u32 ldo_volt_table2[] = { +static const unsigned int ldo_volt_table2[] = { 1800000, 3300000, }; -static const u32 ldo_volt_table3[] = { +static const unsigned int ldo_volt_table3[] = { 3000000, 3300000, }; -static const u32 ldo_volt_table4[] = { +static const unsigned int ldo_volt_table4[] = { 1220000, 1300000, 1500000, 1800000, 2500000, 2800000, 3000000, 3300000, }; -static const u32 ldo_volt_table5[] = { +static const unsigned int ldo_volt_table5[] = { 1200000, 1300000, 1500000, 1800000, 2500000, 2800000, 3000000, 3300000, }; -static const u32 ldo_volt_table5_v2[] = { +static const unsigned int ldo_volt_table5_v2[] = { 1200000, 1000000, 1500000, 1800000, 2500000, 2800000, 3000000, 3300000, }; -static const u32 ldo_volt_table6[] = { +static const unsigned int ldo_volt_table6[] = { 1200000, 1300000, 1500000, 1800000, 2500000, 2800000, 3000000, 2000000, }; -static const u32 ldo_volt_table7[] = { +static const unsigned int ldo_volt_table7[] = { 1300000, 1500000, 1800000, 2000000, 2500000, 2800000, 3000000, 3300000, }; diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index 7fb9e8dd834e..f13c7c8b1061 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -991,9 +991,6 @@ static int palmas_ldo_registration(struct palmas_pmic *pmic, return PTR_ERR(rdev); } - /* Save regulator for cleanup */ - pmic->rdev[id] = rdev; - /* Initialise sleep/init values from platform data */ if (pdata) { reg_init = pdata->reg_init[id]; @@ -1101,9 +1098,6 @@ static int tps65917_ldo_registration(struct palmas_pmic *pmic, return PTR_ERR(rdev); } - /* Save regulator for cleanup */ - pmic->rdev[id] = rdev; - /* Initialise sleep/init values from platform data */ if (pdata) { reg_init = pdata->reg_init[id]; @@ -1288,9 +1282,6 @@ static int palmas_smps_registration(struct palmas_pmic *pmic, pdev_name); return PTR_ERR(rdev); } - - /* Save regulator for cleanup */ - pmic->rdev[id] = rdev; } return 0; @@ -1395,9 +1386,6 @@ static int tps65917_smps_registration(struct palmas_pmic *pmic, pdev_name); return PTR_ERR(rdev); } - - /* Save regulator for cleanup */ - pmic->rdev[id] = rdev; } return 0; diff --git a/drivers/regulator/pv88060-regulator.c b/drivers/regulator/pv88060-regulator.c index 1600f9821891..810816e9df5d 100644 --- a/drivers/regulator/pv88060-regulator.c +++ b/drivers/regulator/pv88060-regulator.c @@ -244,9 +244,11 @@ static irqreturn_t pv88060_irq_handler(int irq, void *data) if (reg_val & PV88060_E_VDD_FLT) { for (i = 0; i < PV88060_MAX_REGULATORS; i++) { if (chip->rdev[i] != NULL) { + regulator_lock(chip->rdev[i]); regulator_notifier_call_chain(chip->rdev[i], REGULATOR_EVENT_UNDER_VOLTAGE, NULL); + regulator_unlock(chip->rdev[i]); } } @@ -261,9 +263,11 @@ static irqreturn_t pv88060_irq_handler(int irq, void *data) if (reg_val & PV88060_E_OVER_TEMP) { for (i = 0; i < PV88060_MAX_REGULATORS; i++) { if (chip->rdev[i] != NULL) { + regulator_lock(chip->rdev[i]); regulator_notifier_call_chain(chip->rdev[i], REGULATOR_EVENT_OVER_TEMP, NULL); + regulator_unlock(chip->rdev[i]); } } diff --git a/drivers/regulator/pv88080-regulator.c b/drivers/regulator/pv88080-regulator.c index bdddacdbeb99..6279216fb254 100644 --- a/drivers/regulator/pv88080-regulator.c +++ b/drivers/regulator/pv88080-regulator.c @@ -345,9 +345,11 @@ static irqreturn_t pv88080_irq_handler(int irq, void *data) if (reg_val & PV88080_E_VDD_FLT) { for (i = 0; i < PV88080_MAX_REGULATORS; i++) { if (chip->rdev[i] != NULL) { + regulator_lock(chip->rdev[i]); regulator_notifier_call_chain(chip->rdev[i], REGULATOR_EVENT_UNDER_VOLTAGE, NULL); + regulator_unlock(chip->rdev[i]); } } @@ -362,9 +364,11 @@ static irqreturn_t pv88080_irq_handler(int irq, void *data) if (reg_val & PV88080_E_OVER_TEMP) { for (i = 0; i < PV88080_MAX_REGULATORS; i++) { if (chip->rdev[i] != NULL) { + regulator_lock(chip->rdev[i]); regulator_notifier_call_chain(chip->rdev[i], REGULATOR_EVENT_OVER_TEMP, NULL); + regulator_unlock(chip->rdev[i]); } } diff --git a/drivers/regulator/pv88090-regulator.c b/drivers/regulator/pv88090-regulator.c index 6e97cc6df2ee..90f4f907fb3f 100644 --- a/drivers/regulator/pv88090-regulator.c +++ b/drivers/regulator/pv88090-regulator.c @@ -237,9 +237,11 @@ static irqreturn_t pv88090_irq_handler(int irq, void *data) if (reg_val & PV88090_E_VDD_FLT) { for (i = 0; i < PV88090_MAX_REGULATORS; i++) { if (chip->rdev[i] != NULL) { + regulator_lock(chip->rdev[i]); regulator_notifier_call_chain(chip->rdev[i], REGULATOR_EVENT_UNDER_VOLTAGE, NULL); + regulator_unlock(chip->rdev[i]); } } @@ -254,9 +256,11 @@ static irqreturn_t pv88090_irq_handler(int irq, void *data) if (reg_val & PV88090_E_OVER_TEMP) { for (i = 0; i < PV88090_MAX_REGULATORS; i++) { if (chip->rdev[i] != NULL) { + regulator_lock(chip->rdev[i]); regulator_notifier_call_chain(chip->rdev[i], REGULATOR_EVENT_OVER_TEMP, NULL); + regulator_unlock(chip->rdev[i]); } } diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c index 12b422373580..d1873f94bca7 100644 --- a/drivers/regulator/wm831x-dcdc.c +++ b/drivers/regulator/wm831x-dcdc.c @@ -183,9 +183,11 @@ static irqreturn_t wm831x_dcdc_uv_irq(int irq, void *data) { struct wm831x_dcdc *dcdc = data; + regulator_lock(dcdc->regulator); regulator_notifier_call_chain(dcdc->regulator, REGULATOR_EVENT_UNDER_VOLTAGE, NULL); + regulator_unlock(dcdc->regulator); return IRQ_HANDLED; } @@ -194,9 +196,11 @@ static irqreturn_t wm831x_dcdc_oc_irq(int irq, void *data) { struct wm831x_dcdc *dcdc = data; + regulator_lock(dcdc->regulator); regulator_notifier_call_chain(dcdc->regulator, REGULATOR_EVENT_OVER_CURRENT, NULL); + regulator_unlock(dcdc->regulator); return IRQ_HANDLED; } diff --git a/drivers/regulator/wm831x-isink.c b/drivers/regulator/wm831x-isink.c index 6dd891d7eee3..bdc521a6f048 100644 --- a/drivers/regulator/wm831x-isink.c +++ b/drivers/regulator/wm831x-isink.c @@ -92,57 +92,23 @@ static int wm831x_isink_is_enabled(struct regulator_dev *rdev) return 0; } -static int wm831x_isink_set_current(struct regulator_dev *rdev, - int min_uA, int max_uA) -{ - struct wm831x_isink *isink = rdev_get_drvdata(rdev); - struct wm831x *wm831x = isink->wm831x; - int ret, i; - - for (i = 0; i < ARRAY_SIZE(wm831x_isinkv_values); i++) { - int val = wm831x_isinkv_values[i]; - if (min_uA <= val && val <= max_uA) { - ret = wm831x_set_bits(wm831x, isink->reg, - WM831X_CS1_ISEL_MASK, i); - return ret; - } - } - - return -EINVAL; -} - -static int wm831x_isink_get_current(struct regulator_dev *rdev) -{ - struct wm831x_isink *isink = rdev_get_drvdata(rdev); - struct wm831x *wm831x = isink->wm831x; - int ret; - - ret = wm831x_reg_read(wm831x, isink->reg); - if (ret < 0) - return ret; - - ret &= WM831X_CS1_ISEL_MASK; - if (ret > WM831X_ISINK_MAX_ISEL) - ret = WM831X_ISINK_MAX_ISEL; - - return wm831x_isinkv_values[ret]; -} - static const struct regulator_ops wm831x_isink_ops = { .is_enabled = wm831x_isink_is_enabled, .enable = wm831x_isink_enable, .disable = wm831x_isink_disable, - .set_current_limit = wm831x_isink_set_current, - .get_current_limit = wm831x_isink_get_current, + .set_current_limit = regulator_set_current_limit_regmap, + .get_current_limit = regulator_get_current_limit_regmap, }; static irqreturn_t wm831x_isink_irq(int irq, void *data) { struct wm831x_isink *isink = data; + regulator_lock(isink->regulator); regulator_notifier_call_chain(isink->regulator, REGULATOR_EVENT_OVER_CURRENT, NULL); + regulator_unlock(isink->regulator); return IRQ_HANDLED; } @@ -187,10 +153,15 @@ static int wm831x_isink_probe(struct platform_device *pdev) isink->desc.ops = &wm831x_isink_ops; isink->desc.type = REGULATOR_CURRENT; isink->desc.owner = THIS_MODULE; + isink->desc.curr_table = wm831x_isinkv_values, + isink->desc.n_current_limits = ARRAY_SIZE(wm831x_isinkv_values), + isink->desc.csel_reg = isink->reg, + isink->desc.csel_mask = WM831X_CS1_ISEL_MASK, config.dev = pdev->dev.parent; config.init_data = pdata->isink[id]; config.driver_data = isink; + config.regmap = wm831x->regmap; isink->regulator = devm_regulator_register(&pdev->dev, &isink->desc, &config); diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c index e4a6f888484e..fcd038e7cd80 100644 --- a/drivers/regulator/wm831x-ldo.c +++ b/drivers/regulator/wm831x-ldo.c @@ -51,9 +51,11 @@ static irqreturn_t wm831x_ldo_uv_irq(int irq, void *data) { struct wm831x_ldo *ldo = data; + regulator_lock(ldo->regulator); regulator_notifier_call_chain(ldo->regulator, REGULATOR_EVENT_UNDER_VOLTAGE, NULL); + regulator_unlock(ldo->regulator); return IRQ_HANDLED; } diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c index a1c7dfee5c37..0eb3f3a33caa 100644 --- a/drivers/regulator/wm8350-regulator.c +++ b/drivers/regulator/wm8350-regulator.c @@ -28,7 +28,7 @@ #define WM8350_DCDC_MAX_VSEL 0x66 /* Microamps */ -static const int isink_cur[] = { +static const unsigned int isink_cur[] = { 4, 5, 6, @@ -95,73 +95,6 @@ static const int isink_cur[] = { 223191 }; -static int get_isink_val(int min_uA, int max_uA, u16 *setting) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(isink_cur); i++) { - if (min_uA <= isink_cur[i] && max_uA >= isink_cur[i]) { - *setting = i; - return 0; - } - } - return -EINVAL; -} - -static int wm8350_isink_set_current(struct regulator_dev *rdev, int min_uA, - int max_uA) -{ - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int isink = rdev_get_id(rdev); - u16 val, setting; - int ret; - - ret = get_isink_val(min_uA, max_uA, &setting); - if (ret != 0) - return ret; - - switch (isink) { - case WM8350_ISINK_A: - val = wm8350_reg_read(wm8350, WM8350_CURRENT_SINK_DRIVER_A) & - ~WM8350_CS1_ISEL_MASK; - wm8350_reg_write(wm8350, WM8350_CURRENT_SINK_DRIVER_A, - val | setting); - break; - case WM8350_ISINK_B: - val = wm8350_reg_read(wm8350, WM8350_CURRENT_SINK_DRIVER_B) & - ~WM8350_CS1_ISEL_MASK; - wm8350_reg_write(wm8350, WM8350_CURRENT_SINK_DRIVER_B, - val | setting); - break; - default: - return -EINVAL; - } - - return 0; -} - -static int wm8350_isink_get_current(struct regulator_dev *rdev) -{ - struct wm8350 *wm8350 = rdev_get_drvdata(rdev); - int isink = rdev_get_id(rdev); - u16 val; - - switch (isink) { - case WM8350_ISINK_A: - val = wm8350_reg_read(wm8350, WM8350_CURRENT_SINK_DRIVER_A) & - WM8350_CS1_ISEL_MASK; - break; - case WM8350_ISINK_B: - val = wm8350_reg_read(wm8350, WM8350_CURRENT_SINK_DRIVER_B) & - WM8350_CS1_ISEL_MASK; - break; - default: - return 0; - } - - return isink_cur[val]; -} - /* turn on ISINK followed by DCDC */ static int wm8350_isink_enable(struct regulator_dev *rdev) { @@ -982,8 +915,8 @@ static const struct regulator_ops wm8350_ldo_ops = { }; static const struct regulator_ops wm8350_isink_ops = { - .set_current_limit = wm8350_isink_set_current, - .get_current_limit = wm8350_isink_get_current, + .set_current_limit = regulator_set_current_limit_regmap, + .get_current_limit = regulator_get_current_limit_regmap, .enable = wm8350_isink_enable, .disable = wm8350_isink_disable, .is_enabled = wm8350_isink_is_enabled, @@ -1138,6 +1071,10 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { .irq = WM8350_IRQ_CS1, .type = REGULATOR_CURRENT, .owner = THIS_MODULE, + .curr_table = isink_cur, + .n_current_limits = ARRAY_SIZE(isink_cur), + .csel_reg = WM8350_CURRENT_SINK_DRIVER_A, + .csel_mask = WM8350_CS1_ISEL_MASK, }, { .name = "ISINKB", @@ -1146,6 +1083,10 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = { .irq = WM8350_IRQ_CS2, .type = REGULATOR_CURRENT, .owner = THIS_MODULE, + .curr_table = isink_cur, + .n_current_limits = ARRAY_SIZE(isink_cur), + .csel_reg = WM8350_CURRENT_SINK_DRIVER_B, + .csel_mask = WM8350_CS2_ISEL_MASK, }, }; diff --git a/drivers/regulator/wm8400-regulator.c b/drivers/regulator/wm8400-regulator.c index fb1837657b64..5ce86b92851b 100644 --- a/drivers/regulator/wm8400-regulator.c +++ b/drivers/regulator/wm8400-regulator.c @@ -36,13 +36,12 @@ static const struct regulator_ops wm8400_ldo_ops = { static unsigned int wm8400_dcdc_get_mode(struct regulator_dev *dev) { - struct wm8400 *wm8400 = rdev_get_drvdata(dev); + struct regmap *rmap = rdev_get_regmap(dev); int offset = (rdev_get_id(dev) - WM8400_DCDC1) * 2; u16 data[2]; int ret; - ret = wm8400_block_read(wm8400, WM8400_DCDC1_CONTROL_1 + offset, 2, - data); + ret = regmap_bulk_read(rmap, WM8400_DCDC1_CONTROL_1 + offset, data, 2); if (ret != 0) return 0; @@ -63,36 +62,36 @@ static unsigned int wm8400_dcdc_get_mode(struct regulator_dev *dev) static int wm8400_dcdc_set_mode(struct regulator_dev *dev, unsigned int mode) { - struct wm8400 *wm8400 = rdev_get_drvdata(dev); + struct regmap *rmap = rdev_get_regmap(dev); int offset = (rdev_get_id(dev) - WM8400_DCDC1) * 2; int ret; switch (mode) { case REGULATOR_MODE_FAST: /* Datasheet: active with force PWM */ - ret = wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_2 + offset, + ret = regmap_update_bits(rmap, WM8400_DCDC1_CONTROL_2 + offset, WM8400_DC1_FRC_PWM, WM8400_DC1_FRC_PWM); if (ret != 0) return ret; - return wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset, + return regmap_update_bits(rmap, WM8400_DCDC1_CONTROL_1 + offset, WM8400_DC1_ACTIVE | WM8400_DC1_SLEEP, WM8400_DC1_ACTIVE); case REGULATOR_MODE_NORMAL: /* Datasheet: active */ - ret = wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_2 + offset, + ret = regmap_update_bits(rmap, WM8400_DCDC1_CONTROL_2 + offset, WM8400_DC1_FRC_PWM, 0); if (ret != 0) return ret; - return wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset, + return regmap_update_bits(rmap, WM8400_DCDC1_CONTROL_1 + offset, WM8400_DC1_ACTIVE | WM8400_DC1_SLEEP, WM8400_DC1_ACTIVE); case REGULATOR_MODE_IDLE: /* Datasheet: standby */ - return wm8400_set_bits(wm8400, WM8400_DCDC1_CONTROL_1 + offset, + return regmap_update_bits(rmap, WM8400_DCDC1_CONTROL_1 + offset, WM8400_DC1_ACTIVE | WM8400_DC1_SLEEP, 0); default: return -EINVAL; @@ -195,7 +194,7 @@ static struct regulator_desc regulators[] = { .id = WM8400_DCDC2, .ops = &wm8400_dcdc_ops, .enable_reg = WM8400_DCDC2_CONTROL_1, - .enable_mask = WM8400_DC1_ENA_MASK, + .enable_mask = WM8400_DC2_ENA_MASK, .n_voltages = WM8400_DC2_VSEL_MASK + 1, .vsel_reg = WM8400_DCDC2_CONTROL_1, .vsel_mask = WM8400_DC2_VSEL_MASK, diff --git a/include/linux/mfd/palmas.h b/include/linux/mfd/palmas.h index 75e5c8ff85fc..c34d5f0d34d7 100644 --- a/include/linux/mfd/palmas.h +++ b/include/linux/mfd/palmas.h @@ -553,7 +553,6 @@ struct palmas_pmic { struct palmas *palmas; struct device *dev; struct regulator_desc desc[PALMAS_NUM_REGS]; - struct regulator_dev *rdev[PALMAS_NUM_REGS]; struct mutex mutex; int smps123; diff --git a/include/linux/mfd/wm831x/regulator.h b/include/linux/mfd/wm831x/regulator.h index 955d30fc6a27..30c587a0624c 100644 --- a/include/linux/mfd/wm831x/regulator.h +++ b/include/linux/mfd/wm831x/regulator.h @@ -1213,6 +1213,6 @@ #define WM831X_LDO1_OK_WIDTH 1 /* LDO1_OK */ #define WM831X_ISINK_MAX_ISEL 55 -extern int wm831x_isinkv_values[WM831X_ISINK_MAX_ISEL + 1]; +extern const unsigned int wm831x_isinkv_values[WM831X_ISINK_MAX_ISEL + 1]; #endif diff --git a/include/linux/mfd/wm8400-private.h b/include/linux/mfd/wm8400-private.h index 4ee908f5b834..43d0d307e2e3 100644 --- a/include/linux/mfd/wm8400-private.h +++ b/include/linux/mfd/wm8400-private.h @@ -923,12 +923,4 @@ struct wm8400 { #define WM8400_LINE_CMP_VTHD_SHIFT 0 /* LINE_CMP_VTHD - [3:0] */ #define WM8400_LINE_CMP_VTHD_WIDTH 4 /* LINE_CMP_VTHD - [3:0] */ -int wm8400_block_read(struct wm8400 *wm8400, u8 reg, int count, u16 *data); - -static inline int wm8400_set_bits(struct wm8400 *wm8400, u8 reg, - u16 mask, u16 val) -{ - return regmap_update_bits(wm8400->regmap, reg, mask, val); -} - #endif |