diff options
author | Ingo Molnar <mingo@kernel.org> | 2019-05-16 10:04:48 +0300 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2019-05-16 10:04:48 +0300 |
commit | 00f5764dbb040188e5dce2cd9e648360886b045c (patch) | |
tree | 2dc969bb165a27a7cebdd1798b7a697243a790de /drivers/regulator | |
parent | 409ca45526a428620d8efb362ccfd4b1e6b80642 (diff) | |
parent | 5ac94332248ee017964ba368cdda4ce647e3aba7 (diff) | |
download | linux-00f5764dbb040188e5dce2cd9e648360886b045c.tar.xz |
Merge branch 'linus' into x86/urgent, to pick up dependent changes
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'drivers/regulator')
81 files changed, 1258 insertions, 2753 deletions
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..6c37f0df9323 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. @@ -839,6 +840,13 @@ config REGULATOR_STM32_VREFBUF This driver can also be built as a module. If so, the module will be called stm32-vrefbuf. +config REGULATOR_STM32_PWR + bool "STMicroelectronics STM32 PWR" + depends on ARCH_STM32 || COMPILE_TEST + help + This driver supports internal regulators (1V1, 1V8, 3V3) in the + STMicroelectronics STM32 chips. + config REGULATOR_STPMIC1 tristate "STMicroelectronics STPMIC1 PMIC Regulators" depends on MFD_STPMIC1 @@ -1010,7 +1018,8 @@ config REGULATOR_TWL4030 config REGULATOR_UNIPHIER tristate "UniPhier regulator driver" depends on ARCH_UNIPHIER || COMPILE_TEST - depends on OF && MFD_SYSCON + depends on OF + select REGMAP_MMIO default ARCH_UNIPHIER help Support for regulators implemented on Socionext UniPhier SoCs. diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 1169f8a27d91..93f53840e8f1 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -105,6 +105,7 @@ obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o obj-$(CONFIG_REGULATOR_SC2731) += sc2731-regulator.o obj-$(CONFIG_REGULATOR_SKY81452) += sky81452-regulator.o obj-$(CONFIG_REGULATOR_STM32_VREFBUF) += stm32-vrefbuf.o +obj-$(CONFIG_REGULATOR_STM32_PWR) += stm32-pwr.o obj-$(CONFIG_REGULATOR_STPMIC1) += stpmic1_regulator.o obj-$(CONFIG_REGULATOR_STW481X_VMMC) += stw481x-vmmc.o obj-$(CONFIG_REGULATOR_SY8106A) += sy8106a-regulator.o diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c index de2644490f0d..438509f55f05 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; @@ -354,14 +353,13 @@ static int ab3100_get_voltage_regulator_external(struct regulator_dev *reg) return 0; } -static struct regulator_ops regulator_ops_fixed = { - .list_voltage = regulator_list_voltage_linear, +static const struct regulator_ops regulator_ops_fixed = { .enable = ab3100_enable_regulator, .disable = ab3100_disable_regulator, .is_enabled = ab3100_is_enabled_regulator, }; -static struct regulator_ops regulator_ops_variable = { +static const struct regulator_ops regulator_ops_variable = { .enable = ab3100_enable_regulator, .disable = ab3100_disable_regulator, .is_enabled = ab3100_is_enabled_regulator, @@ -370,7 +368,7 @@ static struct regulator_ops regulator_ops_variable = { .list_voltage = regulator_list_voltage_table, }; -static struct regulator_ops regulator_ops_variable_sleepable = { +static const struct regulator_ops regulator_ops_variable_sleepable = { .enable = ab3100_enable_regulator, .disable = ab3100_disable_regulator, .is_enabled = ab3100_is_enabled_regulator, @@ -386,14 +384,14 @@ static struct regulator_ops regulator_ops_variable_sleepable = { * is an on/off switch plain an simple. The external * voltage is defined in the board set-up if any. */ -static struct regulator_ops regulator_ops_external = { +static const struct regulator_ops regulator_ops_external = { .enable = ab3100_enable_regulator, .disable = ab3100_disable_regulator, .is_enabled = ab3100_is_enabled_regulator, .get_voltage = ab3100_get_voltage_regulator_external, }; -static struct regulator_desc +static const struct regulator_desc ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { { .name = "LDO_A", @@ -402,7 +400,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { .n_voltages = 1, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, - .min_uV = LDO_A_VOLTAGE, + .fixed_uV = LDO_A_VOLTAGE, .enable_time = 200, }, { @@ -412,7 +410,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { .n_voltages = 1, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, - .min_uV = LDO_C_VOLTAGE, + .fixed_uV = LDO_C_VOLTAGE, .enable_time = 200, }, { @@ -422,7 +420,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { .n_voltages = 1, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, - .min_uV = LDO_D_VOLTAGE, + .fixed_uV = LDO_D_VOLTAGE, .enable_time = 200, }, { @@ -500,7 +498,7 @@ static int ab3100_regulator_register(struct platform_device *pdev, struct device_node *np, unsigned long id) { - struct regulator_desc *desc; + const struct regulator_desc *desc; struct ab3100_regulator *reg; struct regulator_dev *rdev; struct regulator_config config = { }; @@ -545,8 +543,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 +605,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 +631,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; @@ -705,14 +687,12 @@ static int ab3100_regulators_probe(struct platform_device *pdev) /* Register the regulators */ for (i = 0; i < AB3100_NUM_REGULATORS; i++) { - struct regulator_desc *desc = &ab3100_regulator_desc[i]; + const struct regulator_desc *desc = &ab3100_regulator_desc[i]; err = ab3100_regulator_register(pdev, plfdata, NULL, NULL, desc->id); - if (err) { - ab3100_regulators_remove(pdev); + if (err) return err; - } } return 0; @@ -723,7 +703,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/ab8500-ext.c b/drivers/regulator/ab8500-ext.c index 2ca00045eb99..95704446d89e 100644 --- a/drivers/regulator/ab8500-ext.c +++ b/drivers/regulator/ab8500-ext.c @@ -479,7 +479,6 @@ static struct ab8500_regulator_platform_data ab8500_regulator_plat_data = { * struct ab8500_ext_regulator_info - ab8500 regulator information * @dev: device pointer * @desc: regulator description - * @rdev: regulator device * @cfg: regulator configuration (extension of regulator FW configuration) * @update_bank: bank to control on/off * @update_reg: register to control on/off @@ -495,7 +494,6 @@ static struct ab8500_regulator_platform_data ab8500_regulator_plat_data = { struct ab8500_ext_regulator_info { struct device *dev; struct regulator_desc desc; - struct regulator_dev *rdev; struct ab8500_ext_regulator_cfg *cfg; u8 update_bank; u8 update_reg; @@ -530,7 +528,7 @@ static int ab8500_ext_regulator_enable(struct regulator_dev *rdev) info->update_bank, info->update_reg, info->update_mask, regval); if (ret < 0) { - dev_err(rdev_get_dev(info->rdev), + dev_err(rdev_get_dev(rdev), "couldn't set enable bits for regulator\n"); return ret; } @@ -566,7 +564,7 @@ static int ab8500_ext_regulator_disable(struct regulator_dev *rdev) info->update_bank, info->update_reg, info->update_mask, regval); if (ret < 0) { - dev_err(rdev_get_dev(info->rdev), + dev_err(rdev_get_dev(rdev), "couldn't set disable bits for regulator\n"); return ret; } @@ -720,7 +718,7 @@ static int ab8500_ext_list_voltage(struct regulator_dev *rdev, return -EINVAL; } -static struct regulator_ops ab8500_ext_regulator_ops = { +static const struct regulator_ops ab8500_ext_regulator_ops = { .enable = ab8500_ext_regulator_enable, .disable = ab8500_ext_regulator_disable, .is_enabled = ab8500_ext_regulator_is_enabled, @@ -735,6 +733,7 @@ static struct ab8500_ext_regulator_info [AB8500_EXT_SUPPLY1] = { .desc = { .name = "VEXTSUPPLY1", + .of_match = of_match_ptr("ab8500_ext1"), .ops = &ab8500_ext_regulator_ops, .type = REGULATOR_VOLTAGE, .id = AB8500_EXT_SUPPLY1, @@ -752,6 +751,7 @@ static struct ab8500_ext_regulator_info [AB8500_EXT_SUPPLY2] = { .desc = { .name = "VEXTSUPPLY2", + .of_match = of_match_ptr("ab8500_ext2"), .ops = &ab8500_ext_regulator_ops, .type = REGULATOR_VOLTAGE, .id = AB8500_EXT_SUPPLY2, @@ -769,6 +769,7 @@ static struct ab8500_ext_regulator_info [AB8500_EXT_SUPPLY3] = { .desc = { .name = "VEXTSUPPLY3", + .of_match = of_match_ptr("ab8500_ext3"), .ops = &ab8500_ext_regulator_ops, .type = REGULATOR_VOLTAGE, .id = AB8500_EXT_SUPPLY3, @@ -785,30 +786,13 @@ static struct ab8500_ext_regulator_info }, }; -static struct of_regulator_match ab8500_ext_regulator_match[] = { - { .name = "ab8500_ext1", .driver_data = (void *) AB8500_EXT_SUPPLY1, }, - { .name = "ab8500_ext2", .driver_data = (void *) AB8500_EXT_SUPPLY2, }, - { .name = "ab8500_ext3", .driver_data = (void *) AB8500_EXT_SUPPLY3, }, -}; - static int ab8500_ext_regulator_probe(struct platform_device *pdev) { struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); struct ab8500_regulator_platform_data *pdata = &ab8500_regulator_plat_data; - struct device_node *np = pdev->dev.of_node; struct regulator_config config = { }; - int i, err; - - if (np) { - err = of_regulator_match(&pdev->dev, np, - ab8500_ext_regulator_match, - ARRAY_SIZE(ab8500_ext_regulator_match)); - if (err < 0) { - dev_err(&pdev->dev, - "Error parsing regulator init data: %d\n", err); - return err; - } - } + struct regulator_dev *rdev; + int i; if (!ab8500) { dev_err(&pdev->dev, "null mfd parent\n"); @@ -844,23 +828,18 @@ static int ab8500_ext_regulator_probe(struct platform_device *pdev) config.dev = &pdev->dev; config.driver_data = info; - config.of_node = ab8500_ext_regulator_match[i].of_node; - config.init_data = (np) ? - ab8500_ext_regulator_match[i].init_data : - &pdata->ext_regulator[i]; + config.init_data = &pdata->ext_regulator[i]; /* register regulator with framework */ - info->rdev = devm_regulator_register(&pdev->dev, &info->desc, - &config); - if (IS_ERR(info->rdev)) { - err = PTR_ERR(info->rdev); + rdev = devm_regulator_register(&pdev->dev, &info->desc, + &config); + if (IS_ERR(rdev)) { dev_err(&pdev->dev, "failed to register regulator %s\n", info->desc.name); - return err; + return PTR_ERR(rdev); } - dev_dbg(rdev_get_dev(info->rdev), - "%s-probed\n", info->desc.name); + dev_dbg(&pdev->dev, "%s-probed\n", info->desc.name); } return 0; diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index 83dba3fbfe0c..3fcb4cbaab02 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c @@ -44,7 +44,6 @@ struct ab8500_shared_mode { * struct ab8500_regulator_info - ab8500 regulator information * @dev: device pointer * @desc: regulator description - * @regulator_dev: regulator device * @shared_mode: used when mode is shared between two regulators * @load_lp_uA: maximum load in idle (low power) mode * @update_bank: bank to control on/off @@ -65,7 +64,6 @@ struct ab8500_shared_mode { struct ab8500_regulator_info { struct device *dev; struct regulator_desc desc; - struct regulator_dev *regulator; struct ab8500_shared_mode *shared_mode; int load_lp_uA; u8 update_bank; @@ -510,7 +508,7 @@ static int ab8500_regulator_set_voltage_sel(struct regulator_dev *rdev, return ret; } -static struct regulator_ops ab8500_regulator_volt_mode_ops = { +static const struct regulator_ops ab8500_regulator_volt_mode_ops = { .enable = ab8500_regulator_enable, .disable = ab8500_regulator_disable, .is_enabled = ab8500_regulator_is_enabled, @@ -522,7 +520,7 @@ static struct regulator_ops ab8500_regulator_volt_mode_ops = { .list_voltage = regulator_list_voltage_table, }; -static struct regulator_ops ab8500_regulator_volt_ops = { +static const struct regulator_ops ab8500_regulator_volt_ops = { .enable = ab8500_regulator_enable, .disable = ab8500_regulator_disable, .is_enabled = ab8500_regulator_is_enabled, @@ -531,7 +529,7 @@ static struct regulator_ops ab8500_regulator_volt_ops = { .list_voltage = regulator_list_voltage_table, }; -static struct regulator_ops ab8500_regulator_mode_ops = { +static const struct regulator_ops ab8500_regulator_mode_ops = { .enable = ab8500_regulator_enable, .disable = ab8500_regulator_disable, .is_enabled = ab8500_regulator_is_enabled, @@ -541,14 +539,14 @@ static struct regulator_ops ab8500_regulator_mode_ops = { .list_voltage = regulator_list_voltage_table, }; -static struct regulator_ops ab8500_regulator_ops = { +static const struct regulator_ops ab8500_regulator_ops = { .enable = ab8500_regulator_enable, .disable = ab8500_regulator_disable, .is_enabled = ab8500_regulator_is_enabled, .list_voltage = regulator_list_voltage_table, }; -static struct regulator_ops ab8500_regulator_anamic_mode_ops = { +static const struct regulator_ops ab8500_regulator_anamic_mode_ops = { .enable = ab8500_regulator_enable, .disable = ab8500_regulator_disable, .is_enabled = ab8500_regulator_is_enabled, @@ -1600,6 +1598,7 @@ static int ab8500_regulator_register(struct platform_device *pdev, struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); struct ab8500_regulator_info *info = NULL; struct regulator_config config = { }; + struct regulator_dev *rdev; /* assign per-regulator data */ info = &abx500_regulator.info[id]; @@ -1621,12 +1620,11 @@ static int ab8500_regulator_register(struct platform_device *pdev, } /* register regulator with framework */ - info->regulator = devm_regulator_register(&pdev->dev, &info->desc, - &config); - if (IS_ERR(info->regulator)) { + rdev = devm_regulator_register(&pdev->dev, &info->desc, &config); + if (IS_ERR(rdev)) { dev_err(&pdev->dev, "failed to register regulator %s\n", info->desc.name); - return PTR_ERR(info->regulator); + return PTR_ERR(rdev); } return 0; diff --git a/drivers/regulator/act8865-regulator.c b/drivers/regulator/act8865-regulator.c index e0239cf3f56d..19d9ee2dac1f 100644 --- a/drivers/regulator/act8865-regulator.c +++ b/drivers/regulator/act8865-regulator.c @@ -226,7 +226,7 @@ static const struct regulator_linear_range act8600_sudcdc_voltage_ranges[] = { REGULATOR_LINEAR_RANGE(41400000, 248, 255, 0), }; -static struct regulator_ops act8865_ops = { +static const struct regulator_ops act8865_ops = { .list_voltage = regulator_list_voltage_linear_range, .map_voltage = regulator_map_voltage_linear_range, .get_voltage_sel = regulator_get_voltage_sel_regmap, @@ -236,7 +236,7 @@ static struct regulator_ops act8865_ops = { .is_enabled = regulator_is_enabled_regmap, }; -static struct regulator_ops act8865_ldo_ops = { +static const struct regulator_ops act8865_ldo_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, @@ -245,6 +245,8 @@ static struct regulator_ops act8865_ldo_ops = { #define ACT88xx_REG(_name, _family, _id, _vsel_reg, _supply) \ [_family##_ID_##_id] = { \ .name = _name, \ + .of_match = of_match_ptr(_name), \ + .regulators_node = of_match_ptr("regulators"), \ .supply_name = _supply, \ .id = _family##_ID_##_id, \ .type = REGULATOR_VOLTAGE, \ @@ -265,6 +267,8 @@ static const struct regulator_desc act8600_regulators[] = { ACT88xx_REG("DCDC3", ACT8600, DCDC3, VSET, "vp3"), { .name = "SUDCDC_REG4", + .of_match = of_match_ptr("SUDCDC_REG4"), + .regulators_node = of_match_ptr("regulators"), .id = ACT8600_ID_SUDCDC4, .ops = &act8865_ops, .type = REGULATOR_VOLTAGE, @@ -283,6 +287,8 @@ static const struct regulator_desc act8600_regulators[] = { ACT88xx_REG("LDO8", ACT8600, LDO8, VSET, "inl"), { .name = "LDO_REG9", + .of_match = of_match_ptr("LDO_REG9"), + .regulators_node = of_match_ptr("regulators"), .id = ACT8600_ID_LDO9, .ops = &act8865_ldo_ops, .type = REGULATOR_VOLTAGE, @@ -294,6 +300,8 @@ static const struct regulator_desc act8600_regulators[] = { }, { .name = "LDO_REG10", + .of_match = of_match_ptr("LDO_REG10"), + .regulators_node = of_match_ptr("regulators"), .id = ACT8600_ID_LDO10, .ops = &act8865_ldo_ops, .type = REGULATOR_VOLTAGE, @@ -348,110 +356,6 @@ static const struct of_device_id act8865_dt_ids[] = { { } }; MODULE_DEVICE_TABLE(of, act8865_dt_ids); - -static struct of_regulator_match act8846_matches[] = { - [ACT8846_ID_REG1] = { .name = "REG1" }, - [ACT8846_ID_REG2] = { .name = "REG2" }, - [ACT8846_ID_REG3] = { .name = "REG3" }, - [ACT8846_ID_REG4] = { .name = "REG4" }, - [ACT8846_ID_REG5] = { .name = "REG5" }, - [ACT8846_ID_REG6] = { .name = "REG6" }, - [ACT8846_ID_REG7] = { .name = "REG7" }, - [ACT8846_ID_REG8] = { .name = "REG8" }, - [ACT8846_ID_REG9] = { .name = "REG9" }, - [ACT8846_ID_REG10] = { .name = "REG10" }, - [ACT8846_ID_REG11] = { .name = "REG11" }, - [ACT8846_ID_REG12] = { .name = "REG12" }, -}; - -static struct of_regulator_match act8865_matches[] = { - [ACT8865_ID_DCDC1] = { .name = "DCDC_REG1"}, - [ACT8865_ID_DCDC2] = { .name = "DCDC_REG2"}, - [ACT8865_ID_DCDC3] = { .name = "DCDC_REG3"}, - [ACT8865_ID_LDO1] = { .name = "LDO_REG1"}, - [ACT8865_ID_LDO2] = { .name = "LDO_REG2"}, - [ACT8865_ID_LDO3] = { .name = "LDO_REG3"}, - [ACT8865_ID_LDO4] = { .name = "LDO_REG4"}, -}; - -static struct of_regulator_match act8600_matches[] = { - [ACT8600_ID_DCDC1] = { .name = "DCDC_REG1"}, - [ACT8600_ID_DCDC2] = { .name = "DCDC_REG2"}, - [ACT8600_ID_DCDC3] = { .name = "DCDC_REG3"}, - [ACT8600_ID_SUDCDC4] = { .name = "SUDCDC_REG4"}, - [ACT8600_ID_LDO5] = { .name = "LDO_REG5"}, - [ACT8600_ID_LDO6] = { .name = "LDO_REG6"}, - [ACT8600_ID_LDO7] = { .name = "LDO_REG7"}, - [ACT8600_ID_LDO8] = { .name = "LDO_REG8"}, - [ACT8600_ID_LDO9] = { .name = "LDO_REG9"}, - [ACT8600_ID_LDO10] = { .name = "LDO_REG10"}, -}; - -static int act8865_pdata_from_dt(struct device *dev, - struct act8865_platform_data *pdata, - unsigned long type) -{ - int matched, i, num_matches; - struct device_node *np; - struct act8865_regulator_data *regulator; - struct of_regulator_match *matches; - - switch (type) { - case ACT8600: - matches = act8600_matches; - num_matches = ARRAY_SIZE(act8600_matches); - break; - case ACT8846: - matches = act8846_matches; - num_matches = ARRAY_SIZE(act8846_matches); - break; - case ACT8865: - matches = act8865_matches; - num_matches = ARRAY_SIZE(act8865_matches); - break; - default: - dev_err(dev, "invalid device id %lu\n", type); - return -EINVAL; - } - - np = of_get_child_by_name(dev->of_node, "regulators"); - if (!np) { - dev_err(dev, "missing 'regulators' subnode in DT\n"); - return -EINVAL; - } - - matched = of_regulator_match(dev, np, matches, num_matches); - of_node_put(np); - if (matched <= 0) - return matched; - - pdata->regulators = devm_kcalloc(dev, - num_matches, - sizeof(struct act8865_regulator_data), - GFP_KERNEL); - if (!pdata->regulators) - return -ENOMEM; - - pdata->num_regulators = num_matches; - regulator = pdata->regulators; - - for (i = 0; i < num_matches; i++) { - regulator->id = i; - regulator->name = matches[i].name; - regulator->init_data = matches[i].init_data; - regulator->of_node = matches[i].of_node; - regulator++; - } - - return 0; -} -#else -static inline int act8865_pdata_from_dt(struct device *dev, - struct act8865_platform_data *pdata, - unsigned long type) -{ - return 0; -} #endif static struct act8865_regulator_data *act8865_get_regulator_data( @@ -459,9 +363,6 @@ static struct act8865_regulator_data *act8865_get_regulator_data( { int i; - if (!pdata) - return NULL; - for (i = 0; i < pdata->num_regulators; i++) { if (pdata->regulators[i].id == id) return &pdata->regulators[i]; @@ -484,7 +385,7 @@ static int act8865_pmic_probe(struct i2c_client *client, const struct i2c_device_id *i2c_id) { const struct regulator_desc *regulators; - struct act8865_platform_data pdata_of, *pdata; + struct act8865_platform_data *pdata = NULL; struct device *dev = &client->dev; int i, ret, num_regulators; struct act8865 *act8865; @@ -493,9 +394,7 @@ static int act8865_pmic_probe(struct i2c_client *client, int off_reg, off_mask; int voltage_select = 0; - pdata = dev_get_platdata(dev); - - if (dev->of_node && !pdata) { + if (dev->of_node) { const struct of_device_id *id; id = of_match_device(of_match_ptr(act8865_dt_ids), dev); @@ -509,6 +408,7 @@ static int act8865_pmic_probe(struct i2c_client *client, NULL); } else { type = i2c_id->driver_data; + pdata = dev_get_platdata(dev); } switch (type) { @@ -543,14 +443,6 @@ static int act8865_pmic_probe(struct i2c_client *client, return -EINVAL; } - if (dev->of_node && !pdata) { - ret = act8865_pdata_from_dt(dev, &pdata_of, type); - if (ret < 0) - return ret; - - pdata = &pdata_of; - } - act8865 = devm_kzalloc(dev, sizeof(struct act8865), GFP_KERNEL); if (!act8865) return -ENOMEM; @@ -577,17 +469,20 @@ static int act8865_pmic_probe(struct i2c_client *client, for (i = 0; i < num_regulators; i++) { const struct regulator_desc *desc = ®ulators[i]; struct regulator_config config = { }; - struct act8865_regulator_data *rdata; struct regulator_dev *rdev; config.dev = dev; config.driver_data = act8865; config.regmap = act8865->regmap; - rdata = act8865_get_regulator_data(desc->id, pdata); - if (rdata) { - config.init_data = rdata->init_data; - config.of_node = rdata->of_node; + if (pdata) { + struct act8865_regulator_data *rdata; + + rdata = act8865_get_regulator_data(desc->id, pdata); + if (rdata) { + config.init_data = rdata->init_data; + config.of_node = rdata->of_node; + } } rdev = devm_regulator_register(dev, desc, &config); diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c index d9d8155ed8cb..754739d004e5 100644 --- a/drivers/regulator/anatop-regulator.c +++ b/drivers/regulator/anatop-regulator.c @@ -23,18 +23,10 @@ #define LDO_FET_FULL_ON 0x1f struct anatop_regulator { - u32 control_reg; - struct regmap *anatop; - int vol_bit_shift; - int vol_bit_width; u32 delay_reg; int delay_bit_shift; int delay_bit_width; - int min_bit_val; - int min_voltage; - int max_voltage; struct regulator_desc rdesc; - struct regulator_init_data *initdata; bool bypass; int sel; }; @@ -55,7 +47,7 @@ static int anatop_regmap_set_voltage_time_sel(struct regulator_dev *reg, * to calculate how many steps LDO need to * ramp up, and how much delay needed. (us) */ - regmap_read(anatop_reg->anatop, anatop_reg->delay_reg, &val); + regmap_read(reg->regmap, anatop_reg->delay_reg, &val); val = (val >> anatop_reg->delay_bit_shift) & ((1 << anatop_reg->delay_bit_width) - 1); ret = (new_sel - old_sel) * (LDO_RAMP_UP_UNIT_IN_CYCLES << @@ -170,6 +162,13 @@ static int anatop_regulator_probe(struct platform_device *pdev) struct anatop_regulator *sreg; struct regulator_init_data *initdata; struct regulator_config config = { }; + struct regmap *regmap; + u32 control_reg; + u32 vol_bit_shift; + u32 vol_bit_width; + u32 min_bit_val; + u32 min_voltage; + u32 max_voltage; int ret = 0; u32 val; @@ -192,48 +191,41 @@ static int anatop_regulator_probe(struct platform_device *pdev) return -ENOMEM; initdata->supply_regulator = "vin"; - sreg->initdata = initdata; anatop_np = of_get_parent(np); if (!anatop_np) return -ENODEV; - sreg->anatop = syscon_node_to_regmap(anatop_np); + regmap = syscon_node_to_regmap(anatop_np); of_node_put(anatop_np); - if (IS_ERR(sreg->anatop)) - return PTR_ERR(sreg->anatop); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); - ret = of_property_read_u32(np, "anatop-reg-offset", - &sreg->control_reg); + ret = of_property_read_u32(np, "anatop-reg-offset", &control_reg); if (ret) { dev_err(dev, "no anatop-reg-offset property set\n"); return ret; } - ret = of_property_read_u32(np, "anatop-vol-bit-width", - &sreg->vol_bit_width); + ret = of_property_read_u32(np, "anatop-vol-bit-width", &vol_bit_width); if (ret) { dev_err(dev, "no anatop-vol-bit-width property set\n"); return ret; } - ret = of_property_read_u32(np, "anatop-vol-bit-shift", - &sreg->vol_bit_shift); + ret = of_property_read_u32(np, "anatop-vol-bit-shift", &vol_bit_shift); if (ret) { dev_err(dev, "no anatop-vol-bit-shift property set\n"); return ret; } - ret = of_property_read_u32(np, "anatop-min-bit-val", - &sreg->min_bit_val); + ret = of_property_read_u32(np, "anatop-min-bit-val", &min_bit_val); if (ret) { dev_err(dev, "no anatop-min-bit-val property set\n"); return ret; } - ret = of_property_read_u32(np, "anatop-min-voltage", - &sreg->min_voltage); + ret = of_property_read_u32(np, "anatop-min-voltage", &min_voltage); if (ret) { dev_err(dev, "no anatop-min-voltage property set\n"); return ret; } - ret = of_property_read_u32(np, "anatop-max-voltage", - &sreg->max_voltage); + ret = of_property_read_u32(np, "anatop-max-voltage", &max_voltage); if (ret) { dev_err(dev, "no anatop-max-voltage property set\n"); return ret; @@ -247,24 +239,23 @@ static int anatop_regulator_probe(struct platform_device *pdev) of_property_read_u32(np, "anatop-delay-bit-shift", &sreg->delay_bit_shift); - rdesc->n_voltages = (sreg->max_voltage - sreg->min_voltage) / 25000 + 1 - + sreg->min_bit_val; - rdesc->min_uV = sreg->min_voltage; + rdesc->n_voltages = (max_voltage - min_voltage) / 25000 + 1 + + min_bit_val; + rdesc->min_uV = min_voltage; rdesc->uV_step = 25000; - rdesc->linear_min_sel = sreg->min_bit_val; - rdesc->vsel_reg = sreg->control_reg; - rdesc->vsel_mask = ((1 << sreg->vol_bit_width) - 1) << - sreg->vol_bit_shift; + rdesc->linear_min_sel = min_bit_val; + rdesc->vsel_reg = control_reg; + rdesc->vsel_mask = ((1 << vol_bit_width) - 1) << vol_bit_shift; rdesc->min_dropout_uV = 125000; config.dev = &pdev->dev; config.init_data = initdata; config.driver_data = sreg; config.of_node = pdev->dev.of_node; - config.regmap = sreg->anatop; + config.regmap = regmap; /* Only core regulators have the ramp up delay configuration. */ - if (sreg->control_reg && sreg->delay_bit_width) { + if (control_reg && sreg->delay_bit_width) { rdesc->ops = &anatop_core_rops; ret = regmap_read(config.regmap, rdesc->vsel_reg, &val); @@ -273,7 +264,7 @@ static int anatop_regulator_probe(struct platform_device *pdev) return ret; } - sreg->sel = (val & rdesc->vsel_mask) >> sreg->vol_bit_shift; + sreg->sel = (val & rdesc->vsel_mask) >> vol_bit_shift; if (sreg->sel == LDO_FET_FULL_ON) { sreg->sel = 0; sreg->bypass = true; @@ -306,7 +297,7 @@ static int anatop_regulator_probe(struct platform_device *pdev) anatop_rops.disable = regulator_disable_regmap; anatop_rops.is_enabled = regulator_is_enabled_regmap; - rdesc->enable_reg = sreg->control_reg; + rdesc->enable_reg = control_reg; rdesc->enable_mask = BIT(enable_bit); } } diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c index bf3ab405eed1..e4bc7b1e5ccd 100644 --- a/drivers/regulator/arizona-ldo1.c +++ b/drivers/regulator/arizona-ldo1.c @@ -1,15 +1,10 @@ -/* - * arizona-ldo1.c -- LDO1 supply for Arizona devices - * - * Copyright 2012 Wolfson Microelectronics PLC. - * - * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// arizona-ldo1.c -- LDO1 supply for Arizona devices +// +// Copyright 2012 Wolfson Microelectronics PLC. +// +// Author: Mark Brown <broonie@opensource.wolfsonmicro.com> #include <linux/module.h> #include <linux/moduleparam.h> diff --git a/drivers/regulator/arizona-micsupp.c b/drivers/regulator/arizona-micsupp.c index 120de94caf02..be0d46da51a1 100644 --- a/drivers/regulator/arizona-micsupp.c +++ b/drivers/regulator/arizona-micsupp.c @@ -1,15 +1,10 @@ -/* - * arizona-micsupp.c -- Microphone supply for Arizona devices - * - * Copyright 2012 Wolfson Microelectronics PLC. - * - * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// arizona-micsupp.c -- Microphone supply for Arizona devices +// +// Copyright 2012 Wolfson Microelectronics PLC. +// +// Author: Mark Brown <broonie@opensource.wolfsonmicro.com> #include <linux/module.h> #include <linux/moduleparam.h> 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..dc75c33bd950 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]; @@ -314,63 +313,10 @@ static const struct as3722_register_mapping as3722_reg_lookup[] = { }, }; - -static const int as3722_ldo_current[] = { 150000, 300000 }; -static const int as3722_sd016_current[] = { 2500000, 3000000, 3500000 }; - -static int as3722_current_to_index(int min_uA, int max_uA, - const int *curr_table, int n_currents) -{ - int i; - - for (i = n_currents - 1; i >= 0; i--) { - if ((min_uA <= curr_table[i]) && (curr_table[i] <= max_uA)) - return i; - } - return -EINVAL; -} - -static int as3722_ldo_get_current_limit(struct regulator_dev *rdev) -{ - struct as3722_regulators *as3722_regs = rdev_get_drvdata(rdev); - struct as3722 *as3722 = as3722_regs->as3722; - int id = rdev_get_id(rdev); - u32 val; - int ret; - - ret = as3722_read(as3722, as3722_reg_lookup[id].vsel_reg, &val); - if (ret < 0) { - dev_err(as3722_regs->dev, "Reg 0x%02x read failed: %d\n", - as3722_reg_lookup[id].vsel_reg, ret); - return ret; - } - if (val & AS3722_LDO_ILIMIT_MASK) - return 300000; - return 150000; -} - -static int as3722_ldo_set_current_limit(struct regulator_dev *rdev, - int min_uA, int max_uA) -{ - struct as3722_regulators *as3722_regs = rdev_get_drvdata(rdev); - struct as3722 *as3722 = as3722_regs->as3722; - int id = rdev_get_id(rdev); - int ret; - u32 reg = 0; - - ret = as3722_current_to_index(min_uA, max_uA, as3722_ldo_current, - ARRAY_SIZE(as3722_ldo_current)); - if (ret < 0) { - dev_err(as3722_regs->dev, - "Current range min:max = %d:%d does not support\n", - min_uA, max_uA); - return ret; - } - if (ret) - reg = AS3722_LDO_ILIMIT_BIT; - return as3722_update_bits(as3722, as3722_reg_lookup[id].vsel_reg, - AS3722_LDO_ILIMIT_MASK, reg); -} +static const unsigned int as3722_ldo_current[] = { 150000, 300000 }; +static const unsigned int as3722_sd016_current[] = { + 2500000, 3000000, 3500000 +}; static const struct regulator_ops as3722_ldo0_ops = { .is_enabled = regulator_is_enabled_regmap, @@ -379,16 +325,16 @@ static const struct regulator_ops as3722_ldo0_ops = { .list_voltage = regulator_list_voltage_linear, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, - .get_current_limit = as3722_ldo_get_current_limit, - .set_current_limit = as3722_ldo_set_current_limit, + .get_current_limit = regulator_get_current_limit_regmap, + .set_current_limit = regulator_set_current_limit_regmap, }; static const struct regulator_ops as3722_ldo0_extcntrl_ops = { .list_voltage = regulator_list_voltage_linear, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, - .get_current_limit = as3722_ldo_get_current_limit, - .set_current_limit = as3722_ldo_set_current_limit, + .get_current_limit = regulator_get_current_limit_regmap, + .set_current_limit = regulator_set_current_limit_regmap, }; static int as3722_ldo3_set_tracking_mode(struct as3722_regulators *as3722_reg, @@ -440,8 +386,8 @@ static const struct regulator_ops as3722_ldo6_ops = { .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, .list_voltage = regulator_list_voltage_linear_range, - .get_current_limit = as3722_ldo_get_current_limit, - .set_current_limit = as3722_ldo_set_current_limit, + .get_current_limit = regulator_get_current_limit_regmap, + .set_current_limit = regulator_set_current_limit_regmap, .get_bypass = regulator_get_bypass_regmap, .set_bypass = regulator_set_bypass_regmap, }; @@ -451,8 +397,8 @@ static const struct regulator_ops as3722_ldo6_extcntrl_ops = { .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, .list_voltage = regulator_list_voltage_linear_range, - .get_current_limit = as3722_ldo_get_current_limit, - .set_current_limit = as3722_ldo_set_current_limit, + .get_current_limit = regulator_get_current_limit_regmap, + .set_current_limit = regulator_set_current_limit_regmap, .get_bypass = regulator_get_bypass_regmap, .set_bypass = regulator_set_bypass_regmap, }; @@ -471,8 +417,8 @@ static const struct regulator_ops as3722_ldo_ops = { .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, .list_voltage = regulator_list_voltage_linear_range, - .get_current_limit = as3722_ldo_get_current_limit, - .set_current_limit = as3722_ldo_set_current_limit, + .get_current_limit = regulator_get_current_limit_regmap, + .set_current_limit = regulator_set_current_limit_regmap, }; static const struct regulator_ops as3722_ldo_extcntrl_ops = { @@ -480,8 +426,8 @@ static const struct regulator_ops as3722_ldo_extcntrl_ops = { .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, .list_voltage = regulator_list_voltage_linear_range, - .get_current_limit = as3722_ldo_get_current_limit, - .set_current_limit = as3722_ldo_set_current_limit, + .get_current_limit = regulator_get_current_limit_regmap, + .set_current_limit = regulator_set_current_limit_regmap, }; static unsigned int as3722_sd_get_mode(struct regulator_dev *rdev) @@ -539,85 +485,6 @@ static int as3722_sd_set_mode(struct regulator_dev *rdev, return ret; } -static int as3722_sd016_get_current_limit(struct regulator_dev *rdev) -{ - struct as3722_regulators *as3722_regs = rdev_get_drvdata(rdev); - struct as3722 *as3722 = as3722_regs->as3722; - int id = rdev_get_id(rdev); - u32 val, reg; - int mask; - int ret; - - switch (id) { - case AS3722_REGULATOR_ID_SD0: - reg = AS3722_OVCURRENT_REG; - mask = AS3722_OVCURRENT_SD0_TRIP_MASK; - break; - case AS3722_REGULATOR_ID_SD1: - reg = AS3722_OVCURRENT_REG; - mask = AS3722_OVCURRENT_SD1_TRIP_MASK; - break; - case AS3722_REGULATOR_ID_SD6: - reg = AS3722_OVCURRENT_DEB_REG; - mask = AS3722_OVCURRENT_SD6_TRIP_MASK; - break; - default: - return -EINVAL; - } - ret = as3722_read(as3722, reg, &val); - if (ret < 0) { - dev_err(as3722_regs->dev, "Reg 0x%02x read failed: %d\n", - reg, ret); - return ret; - } - val &= mask; - val >>= ffs(mask) - 1; - if (val == 3) - return -EINVAL; - return as3722_sd016_current[val]; -} - -static int as3722_sd016_set_current_limit(struct regulator_dev *rdev, - int min_uA, int max_uA) -{ - struct as3722_regulators *as3722_regs = rdev_get_drvdata(rdev); - struct as3722 *as3722 = as3722_regs->as3722; - int id = rdev_get_id(rdev); - int ret; - int val; - int mask; - u32 reg; - - ret = as3722_current_to_index(min_uA, max_uA, as3722_sd016_current, - ARRAY_SIZE(as3722_sd016_current)); - if (ret < 0) { - dev_err(as3722_regs->dev, - "Current range min:max = %d:%d does not support\n", - min_uA, max_uA); - return ret; - } - - switch (id) { - case AS3722_REGULATOR_ID_SD0: - reg = AS3722_OVCURRENT_REG; - mask = AS3722_OVCURRENT_SD0_TRIP_MASK; - break; - case AS3722_REGULATOR_ID_SD1: - reg = AS3722_OVCURRENT_REG; - mask = AS3722_OVCURRENT_SD1_TRIP_MASK; - break; - case AS3722_REGULATOR_ID_SD6: - reg = AS3722_OVCURRENT_DEB_REG; - mask = AS3722_OVCURRENT_SD6_TRIP_MASK; - break; - default: - return -EINVAL; - } - ret <<= ffs(mask) - 1; - val = ret & mask; - return as3722_update_bits(as3722, reg, mask, val); -} - static bool as3722_sd0_is_low_voltage(struct as3722_regulators *as3722_regs) { int err; @@ -649,8 +516,8 @@ static const struct regulator_ops as3722_sd016_ops = { .map_voltage = regulator_map_voltage_linear, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, - .get_current_limit = as3722_sd016_get_current_limit, - .set_current_limit = as3722_sd016_set_current_limit, + .get_current_limit = regulator_get_current_limit_regmap, + .set_current_limit = regulator_set_current_limit_regmap, .get_mode = as3722_sd_get_mode, .set_mode = as3722_sd_set_mode, }; @@ -660,8 +527,8 @@ static const struct regulator_ops as3722_sd016_extcntrl_ops = { .map_voltage = regulator_map_voltage_linear, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, - .get_current_limit = as3722_sd016_get_current_limit, - .set_current_limit = as3722_sd016_set_current_limit, + .get_current_limit = regulator_get_current_limit_regmap, + .set_current_limit = regulator_set_current_limit_regmap, .get_mode = as3722_sd_get_mode, .set_mode = as3722_sd_set_mode, }; @@ -807,42 +674,45 @@ static int as3722_regulator_probe(struct platform_device *pdev) config.regmap = as3722->regmap; for (id = 0; id < AS3722_REGULATOR_ID_MAX; id++) { + struct regulator_desc *desc; + + desc = &as3722_regs->desc[id]; reg_config = &as3722_regs->reg_config_data[id]; - as3722_regs->desc[id].name = as3722_reg_lookup[id].name; - as3722_regs->desc[id].supply_name = as3722_reg_lookup[id].sname; - as3722_regs->desc[id].id = as3722_reg_lookup[id].regulator_id; - as3722_regs->desc[id].n_voltages = - as3722_reg_lookup[id].n_voltages; - as3722_regs->desc[id].type = REGULATOR_VOLTAGE; - as3722_regs->desc[id].owner = THIS_MODULE; - as3722_regs->desc[id].enable_reg = - as3722_reg_lookup[id].enable_reg; - as3722_regs->desc[id].enable_mask = - as3722_reg_lookup[id].enable_mask; - as3722_regs->desc[id].vsel_reg = as3722_reg_lookup[id].vsel_reg; - as3722_regs->desc[id].vsel_mask = - as3722_reg_lookup[id].vsel_mask; + desc->name = as3722_reg_lookup[id].name; + desc->supply_name = as3722_reg_lookup[id].sname; + desc->id = as3722_reg_lookup[id].regulator_id; + desc->n_voltages = as3722_reg_lookup[id].n_voltages; + desc->type = REGULATOR_VOLTAGE; + desc->owner = THIS_MODULE; + desc->enable_reg = as3722_reg_lookup[id].enable_reg; + desc->enable_mask = as3722_reg_lookup[id].enable_mask; + desc->vsel_reg = as3722_reg_lookup[id].vsel_reg; + desc->vsel_mask = as3722_reg_lookup[id].vsel_mask; switch (id) { case AS3722_REGULATOR_ID_LDO0: if (reg_config->ext_control) ops = &as3722_ldo0_extcntrl_ops; else ops = &as3722_ldo0_ops; - as3722_regs->desc[id].min_uV = 825000; - as3722_regs->desc[id].uV_step = 25000; - as3722_regs->desc[id].linear_min_sel = 1; - as3722_regs->desc[id].enable_time = 500; + desc->min_uV = 825000; + desc->uV_step = 25000; + desc->linear_min_sel = 1; + desc->enable_time = 500; + desc->curr_table = as3722_ldo_current; + desc->n_current_limits = ARRAY_SIZE(as3722_ldo_current); + desc->csel_reg = as3722_reg_lookup[id].vsel_reg; + desc->csel_mask = AS3722_LDO_ILIMIT_MASK; break; case AS3722_REGULATOR_ID_LDO3: if (reg_config->ext_control) ops = &as3722_ldo3_extcntrl_ops; else ops = &as3722_ldo3_ops; - as3722_regs->desc[id].min_uV = 620000; - as3722_regs->desc[id].uV_step = 20000; - as3722_regs->desc[id].linear_min_sel = 1; - as3722_regs->desc[id].enable_time = 500; + desc->min_uV = 620000; + desc->uV_step = 20000; + desc->linear_min_sel = 1; + desc->enable_time = 500; if (reg_config->enable_tracking) { ret = as3722_ldo3_set_tracking_mode(as3722_regs, id, AS3722_LDO3_MODE_PMOS_TRACKING); @@ -859,18 +729,17 @@ static int as3722_regulator_probe(struct platform_device *pdev) ops = &as3722_ldo6_extcntrl_ops; else ops = &as3722_ldo6_ops; - as3722_regs->desc[id].enable_time = 500; - as3722_regs->desc[id].bypass_reg = - AS3722_LDO6_VOLTAGE_REG; - as3722_regs->desc[id].bypass_mask = - AS3722_LDO_VSEL_MASK; - as3722_regs->desc[id].bypass_val_on = - AS3722_LDO6_VSEL_BYPASS; - as3722_regs->desc[id].bypass_val_off = - AS3722_LDO6_VSEL_BYPASS; - as3722_regs->desc[id].linear_ranges = as3722_ldo_ranges; - as3722_regs->desc[id].n_linear_ranges = - ARRAY_SIZE(as3722_ldo_ranges); + desc->enable_time = 500; + desc->bypass_reg = AS3722_LDO6_VOLTAGE_REG; + desc->bypass_mask = AS3722_LDO_VSEL_MASK; + desc->bypass_val_on = AS3722_LDO6_VSEL_BYPASS; + desc->bypass_val_off = AS3722_LDO6_VSEL_BYPASS; + desc->linear_ranges = as3722_ldo_ranges; + desc->n_linear_ranges = ARRAY_SIZE(as3722_ldo_ranges); + desc->curr_table = as3722_ldo_current; + desc->n_current_limits = ARRAY_SIZE(as3722_ldo_current); + desc->csel_reg = as3722_reg_lookup[id].vsel_reg; + desc->csel_mask = AS3722_LDO_ILIMIT_MASK; break; case AS3722_REGULATOR_ID_SD0: case AS3722_REGULATOR_ID_SD1: @@ -889,9 +758,25 @@ static int as3722_regulator_probe(struct platform_device *pdev) AS3722_SD0_VSEL_MAX + 1; as3722_regs->desc[id].min_uV = 610000; } - as3722_regs->desc[id].uV_step = 10000; - as3722_regs->desc[id].linear_min_sel = 1; - as3722_regs->desc[id].enable_time = 600; + desc->uV_step = 10000; + desc->linear_min_sel = 1; + desc->enable_time = 600; + desc->curr_table = as3722_sd016_current; + desc->n_current_limits = + ARRAY_SIZE(as3722_sd016_current); + if (id == AS3722_REGULATOR_ID_SD0) { + desc->csel_reg = AS3722_OVCURRENT_REG; + desc->csel_mask = + AS3722_OVCURRENT_SD0_TRIP_MASK; + } else if (id == AS3722_REGULATOR_ID_SD1) { + desc->csel_reg = AS3722_OVCURRENT_REG; + desc->csel_mask = + AS3722_OVCURRENT_SD1_TRIP_MASK; + } else if (id == AS3722_REGULATOR_ID_SD6) { + desc->csel_reg = AS3722_OVCURRENT_DEB_REG; + desc->csel_mask = + AS3722_OVCURRENT_SD6_TRIP_MASK; + } break; case AS3722_REGULATOR_ID_SD2: case AS3722_REGULATOR_ID_SD3: @@ -901,9 +786,8 @@ static int as3722_regulator_probe(struct platform_device *pdev) ops = &as3722_sd2345_extcntrl_ops; else ops = &as3722_sd2345_ops; - as3722_regs->desc[id].linear_ranges = - as3722_sd2345_ranges; - as3722_regs->desc[id].n_linear_ranges = + desc->linear_ranges = as3722_sd2345_ranges; + desc->n_linear_ranges = ARRAY_SIZE(as3722_sd2345_ranges); break; default: @@ -911,17 +795,19 @@ static int as3722_regulator_probe(struct platform_device *pdev) ops = &as3722_ldo_extcntrl_ops; else ops = &as3722_ldo_ops; - as3722_regs->desc[id].enable_time = 500; - as3722_regs->desc[id].linear_ranges = as3722_ldo_ranges; - as3722_regs->desc[id].n_linear_ranges = - ARRAY_SIZE(as3722_ldo_ranges); + desc->enable_time = 500; + desc->linear_ranges = as3722_ldo_ranges; + desc->n_linear_ranges = ARRAY_SIZE(as3722_ldo_ranges); + desc->curr_table = as3722_ldo_current; + desc->n_current_limits = ARRAY_SIZE(as3722_ldo_current); + desc->csel_reg = as3722_reg_lookup[id].vsel_reg; + desc->csel_mask = AS3722_LDO_ILIMIT_MASK; break; } - as3722_regs->desc[id].ops = ops; + desc->ops = ops; config.init_data = reg_config->reg_init; config.of_node = as3722_regulator_matches[id].of_node; - rdev = devm_regulator_register(&pdev->dev, - &as3722_regs->desc[id], &config); + rdev = devm_regulator_register(&pdev->dev, desc, &config); if (IS_ERR(rdev)) { ret = PTR_ERR(rdev); dev_err(&pdev->dev, "regulator %d register failed %d\n", @@ -929,7 +815,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..152053361862 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; @@ -1028,7 +1021,7 @@ static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq) * (See include/linux/mfd/axp20x.h) */ reg = AXP803_DCDC_FREQ_CTRL; - /* Fall through to the check below.*/ + /* Fall through - to the check below.*/ case AXP806_ID: /* * AXP806 also have DCDC work frequency setting register at a @@ -1119,12 +1112,12 @@ static int axp20x_set_dcdc_workmode(struct regulator_dev *rdev, int id, u32 work break; case AXP806_ID: - reg = AXP806_DCDC_MODE_CTRL2; /* * AXP806 DCDC regulator IDs have the same range as AXP22X. - * Fall through to the check below. * (See include/linux/mfd/axp20x.h) */ + reg = AXP806_DCDC_MODE_CTRL2; + /* Fall through - to the check below. */ case AXP221_ID: case AXP223_ID: case AXP809_ID: diff --git a/drivers/regulator/bcm590xx-regulator.c b/drivers/regulator/bcm590xx-regulator.c index e49c0a7d5dd5..85ccc93b2bb6 100644 --- a/drivers/regulator/bcm590xx-regulator.c +++ b/drivers/regulator/bcm590xx-regulator.c @@ -103,10 +103,6 @@ ((n > BCM590XX_REG_VSR) && (n < BCM590XX_REG_VBUS)) #define BCM590XX_REG_IS_VBUS(n) (n == BCM590XX_REG_VBUS) -struct bcm590xx_board { - struct regulator_init_data *bcm590xx_pmu_init_data[BCM590XX_NUM_REGS]; -}; - /* LDO group A: supported voltages in microvolts */ static const unsigned int ldo_a_table[] = { 1200000, 1800000, 2500000, 2700000, 2800000, @@ -280,105 +276,15 @@ static const struct regulator_ops bcm590xx_ops_vbus = { .disable = regulator_disable_regmap, }; -#define BCM590XX_MATCH(_name, _id) \ - { \ - .name = #_name, \ - .driver_data = (void *)&bcm590xx_regs[BCM590XX_REG_##_id], \ - } - -static struct of_regulator_match bcm590xx_matches[] = { - BCM590XX_MATCH(rfldo, RFLDO), - BCM590XX_MATCH(camldo1, CAMLDO1), - BCM590XX_MATCH(camldo2, CAMLDO2), - BCM590XX_MATCH(simldo1, SIMLDO1), - BCM590XX_MATCH(simldo2, SIMLDO2), - BCM590XX_MATCH(sdldo, SDLDO), - BCM590XX_MATCH(sdxldo, SDXLDO), - BCM590XX_MATCH(mmcldo1, MMCLDO1), - BCM590XX_MATCH(mmcldo2, MMCLDO2), - BCM590XX_MATCH(audldo, AUDLDO), - BCM590XX_MATCH(micldo, MICLDO), - BCM590XX_MATCH(usbldo, USBLDO), - BCM590XX_MATCH(vibldo, VIBLDO), - BCM590XX_MATCH(csr, CSR), - BCM590XX_MATCH(iosr1, IOSR1), - BCM590XX_MATCH(iosr2, IOSR2), - BCM590XX_MATCH(msr, MSR), - BCM590XX_MATCH(sdsr1, SDSR1), - BCM590XX_MATCH(sdsr2, SDSR2), - BCM590XX_MATCH(vsr, VSR), - BCM590XX_MATCH(gpldo1, GPLDO1), - BCM590XX_MATCH(gpldo2, GPLDO2), - BCM590XX_MATCH(gpldo3, GPLDO3), - BCM590XX_MATCH(gpldo4, GPLDO4), - BCM590XX_MATCH(gpldo5, GPLDO5), - BCM590XX_MATCH(gpldo6, GPLDO6), - BCM590XX_MATCH(vbus, VBUS), -}; - -static struct bcm590xx_board *bcm590xx_parse_dt_reg_data( - struct platform_device *pdev, - struct of_regulator_match **bcm590xx_reg_matches) -{ - struct bcm590xx_board *data; - struct device_node *np = pdev->dev.parent->of_node; - struct device_node *regulators; - struct of_regulator_match *matches = bcm590xx_matches; - int count = ARRAY_SIZE(bcm590xx_matches); - int idx = 0; - int ret; - - if (!np) { - dev_err(&pdev->dev, "of node not found\n"); - return NULL; - } - - data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); - if (!data) - return NULL; - - np = of_node_get(np); - regulators = of_get_child_by_name(np, "regulators"); - if (!regulators) { - dev_warn(&pdev->dev, "regulator node not found\n"); - return NULL; - } - - ret = of_regulator_match(&pdev->dev, regulators, matches, count); - of_node_put(regulators); - if (ret < 0) { - dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", - ret); - return NULL; - } - - *bcm590xx_reg_matches = matches; - - for (idx = 0; idx < count; idx++) { - if (!matches[idx].init_data || !matches[idx].of_node) - continue; - - data->bcm590xx_pmu_init_data[idx] = matches[idx].init_data; - } - - return data; -} - static int bcm590xx_probe(struct platform_device *pdev) { struct bcm590xx *bcm590xx = dev_get_drvdata(pdev->dev.parent); - struct bcm590xx_board *pmu_data = NULL; struct bcm590xx_reg *pmu; struct regulator_config config = { }; struct bcm590xx_info *info; - struct regulator_init_data *reg_data; struct regulator_dev *rdev; - struct of_regulator_match *bcm590xx_reg_matches = NULL; int i; - pmu_data = bcm590xx_parse_dt_reg_data(pdev, - &bcm590xx_reg_matches); - pmu = devm_kzalloc(&pdev->dev, sizeof(*pmu), GFP_KERNEL); if (!pmu) return -ENOMEM; @@ -397,13 +303,10 @@ static int bcm590xx_probe(struct platform_device *pdev) info = bcm590xx_regs; for (i = 0; i < BCM590XX_NUM_REGS; i++, info++) { - if (pmu_data) - reg_data = pmu_data->bcm590xx_pmu_init_data[i]; - else - reg_data = NULL; - /* Register the regulators */ pmu->desc[i].name = info->name; + pmu->desc[i].of_match = of_match_ptr(info->name); + pmu->desc[i].regulators_node = of_match_ptr("regulators"); pmu->desc[i].supply_name = info->vin_name; pmu->desc[i].id = i; pmu->desc[i].volt_table = info->volt_table; @@ -433,16 +336,12 @@ static int bcm590xx_probe(struct platform_device *pdev) pmu->desc[i].owner = THIS_MODULE; config.dev = bcm590xx->dev; - config.init_data = reg_data; config.driver_data = pmu; if (BCM590XX_REG_IS_GPLDO(i) || BCM590XX_REG_IS_VBUS(i)) config.regmap = bcm590xx->regmap_sec; else config.regmap = bcm590xx->regmap_pri; - if (bcm590xx_reg_matches) - config.of_node = bcm590xx_reg_matches[i].of_node; - rdev = devm_regulator_register(&pdev->dev, &pmu->desc[i], &config); if (IS_ERR(rdev)) { diff --git a/drivers/regulator/bd718x7-regulator.c b/drivers/regulator/bd718x7-regulator.c index b2191be49670..fde4264da6ff 100644 --- a/drivers/regulator/bd718x7-regulator.c +++ b/drivers/regulator/bd718x7-regulator.c @@ -27,8 +27,8 @@ static int bd718xx_buck1234_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) { - int id = rdev->desc->id; - unsigned int ramp_value = BUCK_RAMPRATE_10P00MV; + int id = rdev_get_id(rdev); + unsigned int ramp_value; dev_dbg(&rdev->dev, "Buck[%d] Set Ramp = %d\n", id + 1, ramp_delay); diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 68473d0cc57e..955a0a15b9cb 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) @@ -2256,6 +2254,7 @@ static void regulator_ena_gpio_free(struct regulator_dev *rdev) if (pin->gpiod == rdev->ena_pin->gpiod) { if (pin->request_count <= 1) { pin->request_count = 0; + gpiod_put(pin->gpiod); list_del(&pin->list); kfree(pin); rdev->ena_pin = NULL; @@ -3004,7 +3003,7 @@ EXPORT_SYMBOL_GPL(regulator_get_linear_step); * @min_uV: Minimum required voltage in uV. * @max_uV: Maximum required voltage in uV. * - * Returns a boolean or a negative error code. + * Returns a boolean. */ int regulator_is_supported_voltage(struct regulator *regulator, int min_uV, int max_uV) @@ -3028,7 +3027,7 @@ int regulator_is_supported_voltage(struct regulator *regulator, ret = regulator_count_voltages(regulator); if (ret < 0) - return ret; + return 0; voltages = ret; for (i = 0; i < voltages; i++) { @@ -3322,15 +3321,12 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator, /* for not coupled regulators this will just set the voltage */ ret = regulator_balance_voltage(rdev, state); - if (ret < 0) - goto out2; + if (ret < 0) { + voltage->min_uV = old_min_uV; + voltage->max_uV = old_max_uV; + } out: - return 0; -out2: - voltage->min_uV = old_min_uV; - voltage->max_uV = old_max_uV; - return ret; } @@ -4347,8 +4343,6 @@ int regulator_bulk_get(struct device *dev, int num_consumers, consumers[i].supply); if (IS_ERR(consumers[i].consumer)) { ret = PTR_ERR(consumers[i].consumer); - dev_err(dev, "Failed to get supply '%s': %d\n", - consumers[i].supply, ret); consumers[i].consumer = NULL; goto err; } @@ -4357,6 +4351,13 @@ int regulator_bulk_get(struct device *dev, int num_consumers, return 0; err: + if (ret != -EPROBE_DEFER) + dev_err(dev, "Failed to get supply '%s': %d\n", + consumers[i].supply, ret); + else + dev_dbg(dev, "Failed to get supply '%s', deferring\n", + consumers[i].supply); + while (--i >= 0) regulator_put(consumers[i].consumer); @@ -5064,10 +5065,11 @@ void regulator_unregister(struct regulator_dev *rdev) regulator_put(rdev->supply); } + flush_work(&rdev->disable_work.work); + mutex_lock(®ulator_list_mutex); debugfs_remove_recursive(rdev->debugfs); - flush_work(&rdev->disable_work.work); WARN_ON(rdev->open_count); regulator_remove_coupling(rdev); unset_regulator_supplies(rdev); 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/da903x.c b/drivers/regulator/da903x.c index 33e8f3b8d2bd..5493c3a86426 100644 --- a/drivers/regulator/da903x.c +++ b/drivers/regulator/da903x.c @@ -1,13 +1,9 @@ -/* - * Regulators driver for Dialog Semiconductor DA903x - * - * Copyright (C) 2006-2008 Marvell International Ltd. - * Copyright (C) 2008 Compulab Ltd. - * - * 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 - * published by the Free Software Foundation. - */ +// SPDX-License-Identifier: GPL-2.0 +// +// Regulators driver for Dialog Semiconductor DA903x +// +// Copyright (C) 2006-2008 Marvell International Ltd. +// Copyright (C) 2008 Compulab Ltd. #include <linux/kernel.h> #include <linux/init.h> diff --git a/drivers/regulator/da9052-regulator.c b/drivers/regulator/da9052-regulator.c index cefa3558236d..e18d291c7f21 100644 --- a/drivers/regulator/da9052-regulator.c +++ b/drivers/regulator/da9052-regulator.c @@ -1,16 +1,10 @@ -/* -* da9052-regulator.c: Regulator driver for DA9052 -* -* Copyright(c) 2011 Dialog Semiconductor Ltd. -* -* Author: David Dajun Chen <dchen@diasemi.com> -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -*/ +// SPDX-License-Identifier: GPL-2.0+ +// +// da9052-regulator.c: Regulator driver for DA9052 +// +// Copyright(c) 2011 Dialog Semiconductor Ltd. +// +// Author: David Dajun Chen <dchen@diasemi.com> #include <linux/module.h> #include <linux/moduleparam.h> @@ -19,10 +13,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 +286,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 +308,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 +413,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..c025ccb1a30a 100644 --- a/drivers/regulator/da9055-regulator.c +++ b/drivers/regulator/da9055-regulator.c @@ -1,16 +1,10 @@ -/* -* Regulator driver for DA9055 PMIC -* -* Copyright(c) 2012 Dialog Semiconductor Ltd. -* -* Author: David Dajun Chen <dchen@diasemi.com> -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -*/ +// SPDX-License-Identifier: GPL-2.0+ +// +// Regulator driver for DA9055 PMIC +// +// Copyright(c) 2012 Dialog Semiconductor Ltd. +// +// Author: David Dajun Chen <dchen@diasemi.com> #include <linux/module.h> #include <linux/init.h> @@ -338,6 +332,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 +362,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 +485,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 +507,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 +527,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..a02e0488410f 100644 --- a/drivers/regulator/da9062-regulator.c +++ b/drivers/regulator/da9062-regulator.c @@ -1,17 +1,8 @@ -/* - * Regulator device driver for DA9061 and DA9062. - * Copyright (C) 2015-2017 Dialog Semiconductor - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// Regulator device driver for DA9061 and DA9062. +// Copyright (C) 2015-2017 Dialog Semiconductor + #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> @@ -53,16 +44,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 +65,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 +90,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 +100,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 +348,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 +386,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 +412,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 +422,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 +448,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 +458,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 +484,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 +626,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 +652,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 +662,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 +688,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 +698,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 +724,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 +734,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 +760,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 +913,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 +1004,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..6f9ce1a6e44d 100644 --- a/drivers/regulator/da9063-regulator.c +++ b/drivers/regulator/da9063-regulator.c @@ -1,18 +1,12 @@ +// SPDX-License-Identifier: GPL-2.0+ +// +// Regulator driver for DA9063 PMIC series +// +// Copyright 2012 Dialog Semiconductors Ltd. +// Copyright 2013 Philipp Zabel, Pengutronix +// +// Author: Krystian Garbaciak <krystian.garbaciak@diasemi.com> -/* - * Regulator driver for DA9063 PMIC series - * - * Copyright 2012 Dialog Semiconductors Ltd. - * Copyright 2013 Philipp Zabel, Pengutronix - * - * Author: Krystian Garbaciak <krystian.garbaciak@diasemi.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> @@ -38,17 +32,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 +62,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 +104,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 +125,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 +392,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 +423,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 +565,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 +814,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/da9210-regulator.c b/drivers/regulator/da9210-regulator.c index 528303771723..f9448ed50e05 100644 --- a/drivers/regulator/da9210-regulator.c +++ b/drivers/regulator/da9210-regulator.c @@ -1,22 +1,7 @@ -/* - * da9210-regulator.c - Regulator device driver for DA9210 - * Copyright (C) 2013 Dialog Semiconductor Ltd. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// da9210-regulator.c - Regulator device driver for DA9210 +// Copyright (C) 2013 Dialog Semiconductor Ltd. #include <linux/err.h> #include <linux/i2c.h> diff --git a/drivers/regulator/da9210-regulator.h b/drivers/regulator/da9210-regulator.h index 749c550808b6..b1f1a607c208 100644 --- a/drivers/regulator/da9210-regulator.h +++ b/drivers/regulator/da9210-regulator.h @@ -1,22 +1,7 @@ - +/* SPDX-License-Identifier: GPL-2.0+ */ /* * da9210-regulator.h - Regulator definitions for DA9210 * Copyright (C) 2013 Dialog Semiconductor Ltd. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. */ #ifndef __DA9210_REGISTERS_H__ diff --git a/drivers/regulator/da9211-regulator.c b/drivers/regulator/da9211-regulator.c index 109ee12d4362..da37b4ccd834 100644 --- a/drivers/regulator/da9211-regulator.c +++ b/drivers/regulator/da9211-regulator.c @@ -1,18 +1,8 @@ -/* - * da9211-regulator.c - Regulator device driver for DA9211/DA9212 - * /DA9213/DA9223/DA9214/DA9224/DA9215/DA9225 - * Copyright (C) 2015 Dialog Semiconductor Ltd. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// da9211-regulator.c - Regulator device driver for DA9211/DA9212 +// /DA9213/DA9223/DA9214/DA9224/DA9215/DA9225 +// Copyright (C) 2015 Dialog Semiconductor Ltd. #include <linux/err.h> #include <linux/i2c.h> @@ -322,8 +312,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 +326,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/da9211-regulator.h b/drivers/regulator/da9211-regulator.h index 2cb32aab4f82..1201e7cc056c 100644 --- a/drivers/regulator/da9211-regulator.h +++ b/drivers/regulator/da9211-regulator.h @@ -1,17 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * da9211-regulator.h - Regulator definitions for DA9211/DA9212 * /DA9213/DA9223/DA9214/DA9224/DA9215/DA9225 * Copyright (C) 2015 Dialog Semiconductor Ltd. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __DA9211_REGISTERS_H__ diff --git a/drivers/regulator/db8500-prcmu.c b/drivers/regulator/db8500-prcmu.c index 7cec535cf0bc..eb317663f875 100644 --- a/drivers/regulator/db8500-prcmu.c +++ b/drivers/regulator/db8500-prcmu.c @@ -75,7 +75,7 @@ static int db8500_regulator_is_enabled(struct regulator_dev *rdev) } /* db8500 regulator operations */ -static struct regulator_ops db8500_regulator_ops = { +static const struct regulator_ops db8500_regulator_ops = { .enable = db8500_regulator_enable, .disable = db8500_regulator_disable, .is_enabled = db8500_regulator_is_enabled, @@ -200,7 +200,7 @@ static int db8500_regulator_switch_is_enabled(struct regulator_dev *rdev) return info->is_enabled; } -static struct regulator_ops db8500_regulator_switch_ops = { +static const struct regulator_ops db8500_regulator_switch_ops = { .enable = db8500_regulator_switch_enable, .disable = db8500_regulator_switch_disable, .is_enabled = db8500_regulator_switch_is_enabled, @@ -214,6 +214,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_VAPE] = { .desc = { .name = "db8500-vape", + .of_match = of_match_ptr("db8500_vape"), .id = DB8500_REGULATOR_VAPE, .ops = &db8500_regulator_ops, .type = REGULATOR_VOLTAGE, @@ -223,6 +224,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_VARM] = { .desc = { .name = "db8500-varm", + .of_match = of_match_ptr("db8500_varm"), .id = DB8500_REGULATOR_VARM, .ops = &db8500_regulator_ops, .type = REGULATOR_VOLTAGE, @@ -232,6 +234,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_VMODEM] = { .desc = { .name = "db8500-vmodem", + .of_match = of_match_ptr("db8500_vmodem"), .id = DB8500_REGULATOR_VMODEM, .ops = &db8500_regulator_ops, .type = REGULATOR_VOLTAGE, @@ -241,6 +244,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_VPLL] = { .desc = { .name = "db8500-vpll", + .of_match = of_match_ptr("db8500_vpll"), .id = DB8500_REGULATOR_VPLL, .ops = &db8500_regulator_ops, .type = REGULATOR_VOLTAGE, @@ -250,6 +254,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_VSMPS1] = { .desc = { .name = "db8500-vsmps1", + .of_match = of_match_ptr("db8500_vsmps1"), .id = DB8500_REGULATOR_VSMPS1, .ops = &db8500_regulator_ops, .type = REGULATOR_VOLTAGE, @@ -259,6 +264,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_VSMPS2] = { .desc = { .name = "db8500-vsmps2", + .of_match = of_match_ptr("db8500_vsmps2"), .id = DB8500_REGULATOR_VSMPS2, .ops = &db8500_regulator_ops, .type = REGULATOR_VOLTAGE, @@ -271,6 +277,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_VSMPS3] = { .desc = { .name = "db8500-vsmps3", + .of_match = of_match_ptr("db8500_vsmps3"), .id = DB8500_REGULATOR_VSMPS3, .ops = &db8500_regulator_ops, .type = REGULATOR_VOLTAGE, @@ -280,6 +287,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_VRF1] = { .desc = { .name = "db8500-vrf1", + .of_match = of_match_ptr("db8500_vrf1"), .id = DB8500_REGULATOR_VRF1, .ops = &db8500_regulator_ops, .type = REGULATOR_VOLTAGE, @@ -289,6 +297,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_SWITCH_SVAMMDSP] = { .desc = { .name = "db8500-sva-mmdsp", + .of_match = of_match_ptr("db8500_sva_mmdsp"), .id = DB8500_REGULATOR_SWITCH_SVAMMDSP, .ops = &db8500_regulator_switch_ops, .type = REGULATOR_VOLTAGE, @@ -299,6 +308,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_SWITCH_SVAMMDSPRET] = { .desc = { .name = "db8500-sva-mmdsp-ret", + .of_match = of_match_ptr("db8500_sva_mmdsp_ret"), .id = DB8500_REGULATOR_SWITCH_SVAMMDSPRET, .ops = &db8500_regulator_switch_ops, .type = REGULATOR_VOLTAGE, @@ -310,6 +320,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_SWITCH_SVAPIPE] = { .desc = { .name = "db8500-sva-pipe", + .of_match = of_match_ptr("db8500_sva_pipe"), .id = DB8500_REGULATOR_SWITCH_SVAPIPE, .ops = &db8500_regulator_switch_ops, .type = REGULATOR_VOLTAGE, @@ -320,6 +331,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_SWITCH_SIAMMDSP] = { .desc = { .name = "db8500-sia-mmdsp", + .of_match = of_match_ptr("db8500_sia_mmdsp"), .id = DB8500_REGULATOR_SWITCH_SIAMMDSP, .ops = &db8500_regulator_switch_ops, .type = REGULATOR_VOLTAGE, @@ -330,6 +342,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_SWITCH_SIAMMDSPRET] = { .desc = { .name = "db8500-sia-mmdsp-ret", + .of_match = of_match_ptr("db8500_sia_mmdsp_ret"), .id = DB8500_REGULATOR_SWITCH_SIAMMDSPRET, .ops = &db8500_regulator_switch_ops, .type = REGULATOR_VOLTAGE, @@ -341,6 +354,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_SWITCH_SIAPIPE] = { .desc = { .name = "db8500-sia-pipe", + .of_match = of_match_ptr("db8500_sia_pipe"), .id = DB8500_REGULATOR_SWITCH_SIAPIPE, .ops = &db8500_regulator_switch_ops, .type = REGULATOR_VOLTAGE, @@ -351,6 +365,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_SWITCH_SGA] = { .desc = { .name = "db8500-sga", + .of_match = of_match_ptr("db8500_sga"), .id = DB8500_REGULATOR_SWITCH_SGA, .ops = &db8500_regulator_switch_ops, .type = REGULATOR_VOLTAGE, @@ -361,6 +376,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_SWITCH_B2R2_MCDE] = { .desc = { .name = "db8500-b2r2-mcde", + .of_match = of_match_ptr("db8500_b2r2_mcde"), .id = DB8500_REGULATOR_SWITCH_B2R2_MCDE, .ops = &db8500_regulator_switch_ops, .type = REGULATOR_VOLTAGE, @@ -371,6 +387,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_SWITCH_ESRAM12] = { .desc = { .name = "db8500-esram12", + .of_match = of_match_ptr("db8500_esram12"), .id = DB8500_REGULATOR_SWITCH_ESRAM12, .ops = &db8500_regulator_switch_ops, .type = REGULATOR_VOLTAGE, @@ -382,6 +399,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_SWITCH_ESRAM12RET] = { .desc = { .name = "db8500-esram12-ret", + .of_match = of_match_ptr("db8500_esram12_ret"), .id = DB8500_REGULATOR_SWITCH_ESRAM12RET, .ops = &db8500_regulator_switch_ops, .type = REGULATOR_VOLTAGE, @@ -393,6 +411,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_SWITCH_ESRAM34] = { .desc = { .name = "db8500-esram34", + .of_match = of_match_ptr("db8500_esram34"), .id = DB8500_REGULATOR_SWITCH_ESRAM34, .ops = &db8500_regulator_switch_ops, .type = REGULATOR_VOLTAGE, @@ -404,6 +423,7 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_SWITCH_ESRAM34RET] = { .desc = { .name = "db8500-esram34-ret", + .of_match = of_match_ptr("db8500_esram34_ret"), .id = DB8500_REGULATOR_SWITCH_ESRAM34RET, .ops = &db8500_regulator_switch_ops, .type = REGULATOR_VOLTAGE, @@ -414,113 +434,38 @@ dbx500_regulator_info[DB8500_NUM_REGULATORS] = { }, }; -static int db8500_regulator_register(struct platform_device *pdev, - struct regulator_init_data *init_data, - int id, - struct device_node *np) +static int db8500_regulator_probe(struct platform_device *pdev) { + struct regulator_init_data *db8500_init_data; struct dbx500_regulator_info *info; struct regulator_config config = { }; - int err; - - /* assign per-regulator data */ - info = &dbx500_regulator_info[id]; - info->dev = &pdev->dev; - - config.dev = &pdev->dev; - config.init_data = init_data; - config.driver_data = info; - config.of_node = np; - - /* register with the regulator framework */ - info->rdev = devm_regulator_register(&pdev->dev, &info->desc, &config); - if (IS_ERR(info->rdev)) { - err = PTR_ERR(info->rdev); - dev_err(&pdev->dev, "failed to register %s: err %i\n", - info->desc.name, err); - return err; - } - - dev_dbg(rdev_get_dev(info->rdev), - "regulator-%s-probed\n", info->desc.name); + struct regulator_dev *rdev; + int err, i; - return 0; -} - -static struct of_regulator_match db8500_regulator_matches[] = { - { .name = "db8500_vape", .driver_data = (void *) DB8500_REGULATOR_VAPE, }, - { .name = "db8500_varm", .driver_data = (void *) DB8500_REGULATOR_VARM, }, - { .name = "db8500_vmodem", .driver_data = (void *) DB8500_REGULATOR_VMODEM, }, - { .name = "db8500_vpll", .driver_data = (void *) DB8500_REGULATOR_VPLL, }, - { .name = "db8500_vsmps1", .driver_data = (void *) DB8500_REGULATOR_VSMPS1, }, - { .name = "db8500_vsmps2", .driver_data = (void *) DB8500_REGULATOR_VSMPS2, }, - { .name = "db8500_vsmps3", .driver_data = (void *) DB8500_REGULATOR_VSMPS3, }, - { .name = "db8500_vrf1", .driver_data = (void *) DB8500_REGULATOR_VRF1, }, - { .name = "db8500_sva_mmdsp", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSP, }, - { .name = "db8500_sva_mmdsp_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSPRET, }, - { .name = "db8500_sva_pipe", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAPIPE, }, - { .name = "db8500_sia_mmdsp", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSP, }, - { .name = "db8500_sia_mmdsp_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSPRET, }, - { .name = "db8500_sia_pipe", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAPIPE, }, - { .name = "db8500_sga", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SGA, }, - { .name = "db8500_b2r2_mcde", .driver_data = (void *) DB8500_REGULATOR_SWITCH_B2R2_MCDE, }, - { .name = "db8500_esram12", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12, }, - { .name = "db8500_esram12_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12RET, }, - { .name = "db8500_esram34", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34, }, - { .name = "db8500_esram34_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34RET, }, -}; - -static int -db8500_regulator_of_probe(struct platform_device *pdev, - struct device_node *np) -{ - int i, err; + db8500_init_data = dev_get_platdata(&pdev->dev); for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) { - err = db8500_regulator_register( - pdev, db8500_regulator_matches[i].init_data, - i, db8500_regulator_matches[i].of_node); - if (err) + /* assign per-regulator data */ + info = &dbx500_regulator_info[i]; + + config.driver_data = info; + config.dev = &pdev->dev; + if (db8500_init_data) + config.init_data = &db8500_init_data[i]; + + rdev = devm_regulator_register(&pdev->dev, &info->desc, + &config); + if (IS_ERR(rdev)) { + err = PTR_ERR(rdev); + dev_err(&pdev->dev, "failed to register %s: err %i\n", + info->desc.name, err); return err; - } - - return 0; -} - -static int db8500_regulator_probe(struct platform_device *pdev) -{ - struct regulator_init_data *db8500_init_data = - dev_get_platdata(&pdev->dev); - struct device_node *np = pdev->dev.of_node; - int i, err; - - /* register all regulators */ - if (np) { - err = of_regulator_match(&pdev->dev, np, - db8500_regulator_matches, - ARRAY_SIZE(db8500_regulator_matches)); - if (err < 0) { - dev_err(&pdev->dev, - "Error parsing regulator init data: %d\n", err); - return err; - } - - err = db8500_regulator_of_probe(pdev, np); - if (err) - return err; - } else { - for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) { - err = db8500_regulator_register(pdev, - &db8500_init_data[i], - i, NULL); - if (err) - return err; } + dev_dbg(&pdev->dev, "regulator-%s-probed\n", info->desc.name); } - err = ux500_regulator_debug_init(pdev, - dbx500_regulator_info, - ARRAY_SIZE(dbx500_regulator_info)); + ux500_regulator_debug_init(pdev, dbx500_regulator_info, + ARRAY_SIZE(dbx500_regulator_info)); return 0; } diff --git a/drivers/regulator/dbx500-prcmu.h b/drivers/regulator/dbx500-prcmu.h index c8e51ace9f06..6e20dab611ac 100644 --- a/drivers/regulator/dbx500-prcmu.h +++ b/drivers/regulator/dbx500-prcmu.h @@ -15,18 +15,14 @@ /** * struct dbx500_regulator_info - dbx500 regulator information - * @dev: device pointer * @desc: regulator description - * @rdev: regulator device pointer * @is_enabled: status of the regulator * @epod_id: id for EPOD (power domain) * @is_ramret: RAM retention switch for EPOD (power domain) * */ struct dbx500_regulator_info { - struct device *dev; struct regulator_desc desc; - struct regulator_dev *rdev; bool is_enabled; u16 epod_id; bool is_ramret; diff --git a/drivers/regulator/fan53555.c b/drivers/regulator/fan53555.c index 771a06d1900d..dbe477da4e55 100644 --- a/drivers/regulator/fan53555.c +++ b/drivers/regulator/fan53555.c @@ -1,17 +1,13 @@ -/* - * FAN53555 Fairchild Digitally Programmable TinyBuck Regulator Driver. - * - * Supported Part Numbers: - * FAN53555UC00X/01X/03X/04X/05X - * - * Copyright (c) 2012 Marvell Technology Ltd. - * Yunfan Zhang <yfzhang@marvell.com> - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ +// SPDX-License-Identifier: GPL-2.0 +// +// FAN53555 Fairchild Digitally Programmable TinyBuck Regulator Driver. +// +// Supported Part Numbers: +// FAN53555UC00X/01X/03X/04X/05X +// +// Copyright (c) 2012 Marvell Technology Ltd. +// Yunfan Zhang <yfzhang@marvell.com> + #include <linux/module.h> #include <linux/param.h> #include <linux/err.h> @@ -91,10 +87,8 @@ enum { struct fan53555_device_info { enum fan53555_vendor vendor; - struct regmap *regmap; struct device *dev; struct regulator_desc desc; - struct regulator_dev *rdev; struct regulator_init_data *regulator; /* IC Type and Rev */ int chip_id; @@ -106,8 +100,6 @@ struct fan53555_device_info { unsigned int vsel_min; unsigned int vsel_step; unsigned int vsel_count; - /* Voltage slew rate limiting */ - unsigned int slew_rate; /* Mode */ unsigned int mode_reg; unsigned int mode_mask; @@ -125,7 +117,7 @@ static int fan53555_set_suspend_voltage(struct regulator_dev *rdev, int uV) ret = regulator_map_voltage_linear(rdev, uV, uV); if (ret < 0) return ret; - ret = regmap_update_bits(di->regmap, di->sleep_reg, + ret = regmap_update_bits(rdev->regmap, di->sleep_reg, di->desc.vsel_mask, ret); if (ret < 0) return ret; @@ -140,7 +132,7 @@ static int fan53555_set_suspend_enable(struct regulator_dev *rdev) { struct fan53555_device_info *di = rdev_get_drvdata(rdev); - return regmap_update_bits(di->regmap, di->sleep_reg, + return regmap_update_bits(rdev->regmap, di->sleep_reg, VSEL_BUCK_EN, VSEL_BUCK_EN); } @@ -148,7 +140,7 @@ static int fan53555_set_suspend_disable(struct regulator_dev *rdev) { struct fan53555_device_info *di = rdev_get_drvdata(rdev); - return regmap_update_bits(di->regmap, di->sleep_reg, + return regmap_update_bits(rdev->regmap, di->sleep_reg, VSEL_BUCK_EN, 0); } @@ -158,11 +150,11 @@ static int fan53555_set_mode(struct regulator_dev *rdev, unsigned int mode) switch (mode) { case REGULATOR_MODE_FAST: - regmap_update_bits(di->regmap, di->mode_reg, + regmap_update_bits(rdev->regmap, di->mode_reg, di->mode_mask, di->mode_mask); break; case REGULATOR_MODE_NORMAL: - regmap_update_bits(di->regmap, di->vol_reg, di->mode_mask, 0); + regmap_update_bits(rdev->regmap, di->vol_reg, di->mode_mask, 0); break; default: return -EINVAL; @@ -176,7 +168,7 @@ static unsigned int fan53555_get_mode(struct regulator_dev *rdev) unsigned int val; int ret = 0; - ret = regmap_read(di->regmap, di->mode_reg, &val); + ret = regmap_read(rdev->regmap, di->mode_reg, &val); if (ret < 0) return ret; if (val & di->mode_mask) @@ -213,7 +205,7 @@ static int fan53555_set_ramp(struct regulator_dev *rdev, int ramp) return -EINVAL; } - return regmap_update_bits(di->regmap, FAN53555_CONTROL, + return regmap_update_bits(rdev->regmap, FAN53555_CONTROL, CTL_SLEW_MASK, regval << CTL_SLEW_SHIFT); } @@ -396,6 +388,7 @@ static int fan53555_regulator_register(struct fan53555_device_info *di, struct regulator_config *config) { struct regulator_desc *rdesc = &di->desc; + struct regulator_dev *rdev; rdesc->name = "fan53555-reg"; rdesc->supply_name = "vin"; @@ -410,8 +403,8 @@ static int fan53555_regulator_register(struct fan53555_device_info *di, rdesc->vsel_mask = di->vsel_count - 1; rdesc->owner = THIS_MODULE; - di->rdev = devm_regulator_register(di->dev, &di->desc, config); - return PTR_ERR_OR_ZERO(di->rdev); + rdev = devm_regulator_register(di->dev, &di->desc, config); + return PTR_ERR_OR_ZERO(rdev); } static const struct regmap_config fan53555_regmap_config = { @@ -466,6 +459,7 @@ static int fan53555_regulator_probe(struct i2c_client *client, struct fan53555_device_info *di; struct fan53555_platform_data *pdata; struct regulator_config config = { }; + struct regmap *regmap; unsigned int val; int ret; @@ -502,22 +496,22 @@ static int fan53555_regulator_probe(struct i2c_client *client, di->vendor = id->driver_data; } - di->regmap = devm_regmap_init_i2c(client, &fan53555_regmap_config); - if (IS_ERR(di->regmap)) { + regmap = devm_regmap_init_i2c(client, &fan53555_regmap_config); + if (IS_ERR(regmap)) { dev_err(&client->dev, "Failed to allocate regmap!\n"); - return PTR_ERR(di->regmap); + return PTR_ERR(regmap); } di->dev = &client->dev; i2c_set_clientdata(client, di); /* Get chip ID */ - ret = regmap_read(di->regmap, FAN53555_ID1, &val); + ret = regmap_read(regmap, FAN53555_ID1, &val); if (ret < 0) { dev_err(&client->dev, "Failed to get chip ID!\n"); return ret; } di->chip_id = val & DIE_ID; /* Get chip revision */ - ret = regmap_read(di->regmap, FAN53555_ID2, &val); + ret = regmap_read(regmap, FAN53555_ID2, &val); if (ret < 0) { dev_err(&client->dev, "Failed to get chip Rev!\n"); return ret; @@ -534,7 +528,7 @@ static int fan53555_regulator_probe(struct i2c_client *client, /* Register regulator */ config.dev = di->dev; config.init_data = di->regulator; - config.regmap = di->regmap; + config.regmap = regmap; config.driver_data = di; config.of_node = np; 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/hi6421-regulator.c b/drivers/regulator/hi6421-regulator.c index 259c3a865ac6..5ac3d7c29725 100644 --- a/drivers/regulator/hi6421-regulator.c +++ b/drivers/regulator/hi6421-regulator.c @@ -1,17 +1,13 @@ -/* - * Device driver for regulators in Hi6421 IC - * - * Copyright (c) <2011-2014> HiSilicon Technologies Co., Ltd. - * http://www.hisilicon.com - * Copyright (c) <2013-2014> Linaro Ltd. - * http://www.linaro.org - * - * Author: Guodong Xu <guodong.xu@linaro.org> - * - * 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 - * published by the Free Software Foundation. - */ +// SPDX-License-Identifier: GPL-2.0 +// +// Device driver for regulators in Hi6421 IC +// +// Copyright (c) <2011-2014> HiSilicon Technologies Co., Ltd. +// http://www.hisilicon.com +// Copyright (c) <2013-2014> Linaro Ltd. +// http://www.linaro.org +// +// Author: Guodong Xu <guodong.xu@linaro.org> #include <linux/slab.h> #include <linux/device.h> @@ -78,43 +74,6 @@ enum hi6421_regulator_id { HI6421_NUM_REGULATORS, }; -#define HI6421_REGULATOR_OF_MATCH(_name, id) \ -{ \ - .name = #_name, \ - .driver_data = (void *) HI6421_##id, \ -} - -static struct of_regulator_match hi6421_regulator_match[] = { - HI6421_REGULATOR_OF_MATCH(hi6421_vout0, LDO0), - HI6421_REGULATOR_OF_MATCH(hi6421_vout1, LDO1), - HI6421_REGULATOR_OF_MATCH(hi6421_vout2, LDO2), - HI6421_REGULATOR_OF_MATCH(hi6421_vout3, LDO3), - HI6421_REGULATOR_OF_MATCH(hi6421_vout4, LDO4), - HI6421_REGULATOR_OF_MATCH(hi6421_vout5, LDO5), - HI6421_REGULATOR_OF_MATCH(hi6421_vout6, LDO6), - HI6421_REGULATOR_OF_MATCH(hi6421_vout7, LDO7), - HI6421_REGULATOR_OF_MATCH(hi6421_vout8, LDO8), - HI6421_REGULATOR_OF_MATCH(hi6421_vout9, LDO9), - HI6421_REGULATOR_OF_MATCH(hi6421_vout10, LDO10), - HI6421_REGULATOR_OF_MATCH(hi6421_vout11, LDO11), - HI6421_REGULATOR_OF_MATCH(hi6421_vout12, LDO12), - HI6421_REGULATOR_OF_MATCH(hi6421_vout13, LDO13), - HI6421_REGULATOR_OF_MATCH(hi6421_vout14, LDO14), - HI6421_REGULATOR_OF_MATCH(hi6421_vout15, LDO15), - HI6421_REGULATOR_OF_MATCH(hi6421_vout16, LDO16), - HI6421_REGULATOR_OF_MATCH(hi6421_vout17, LDO17), - HI6421_REGULATOR_OF_MATCH(hi6421_vout18, LDO18), - HI6421_REGULATOR_OF_MATCH(hi6421_vout19, LDO19), - HI6421_REGULATOR_OF_MATCH(hi6421_vout20, LDO20), - HI6421_REGULATOR_OF_MATCH(hi6421_vout_audio, LDOAUDIO), - HI6421_REGULATOR_OF_MATCH(hi6421_buck0, BUCK0), - HI6421_REGULATOR_OF_MATCH(hi6421_buck1, BUCK1), - HI6421_REGULATOR_OF_MATCH(hi6421_buck2, BUCK2), - HI6421_REGULATOR_OF_MATCH(hi6421_buck3, BUCK3), - HI6421_REGULATOR_OF_MATCH(hi6421_buck4, BUCK4), - HI6421_REGULATOR_OF_MATCH(hi6421_buck5, BUCK5), -}; - /* LDO 0, 4~7, 9~14, 16~20 have same voltage table. */ static const unsigned int ldo_0_voltages[] = { 1500000, 1800000, 2400000, 2500000, @@ -157,6 +116,7 @@ static const struct regulator_ops hi6421_buck345_ops; #define HI6421_LDO_ENABLE_TIME (350) /* * _id - LDO id name string + * _match - of match name string * v_table - voltage table * vreg - voltage select register * vmask - voltage select mask @@ -166,11 +126,13 @@ static const struct regulator_ops hi6421_buck345_ops; * ecomask - eco mode mask * ecoamp - eco mode load uppler limit in uA */ -#define HI6421_LDO(_id, v_table, vreg, vmask, ereg, emask, \ +#define HI6421_LDO(_id, _match, v_table, vreg, vmask, ereg, emask, \ odelay, ecomask, ecoamp) \ [HI6421_##_id] = { \ .desc = { \ .name = #_id, \ + .of_match = of_match_ptr(#_match), \ + .regulators_node = of_match_ptr("regulators"), \ .ops = &hi6421_ldo_ops, \ .type = REGULATOR_VOLTAGE, \ .id = HI6421_##_id, \ @@ -191,6 +153,7 @@ static const struct regulator_ops hi6421_buck345_ops; /* HI6421 LDO1~3 are linear voltage regulators at fixed uV_step * * _id - LDO id name string + * _match - of match name string * _min_uV - minimum voltage supported in uV * n_volt - number of votages available * vstep - voltage increase in each linear step in uV @@ -202,11 +165,13 @@ static const struct regulator_ops hi6421_buck345_ops; * ecomask - eco mode mask * ecoamp - eco mode load uppler limit in uA */ -#define HI6421_LDO_LINEAR(_id, _min_uV, n_volt, vstep, vreg, vmask, \ +#define HI6421_LDO_LINEAR(_id, _match, _min_uV, n_volt, vstep, vreg, vmask,\ ereg, emask, odelay, ecomask, ecoamp) \ [HI6421_##_id] = { \ .desc = { \ .name = #_id, \ + .of_match = of_match_ptr(#_match), \ + .regulators_node = of_match_ptr("regulators"), \ .ops = &hi6421_ldo_linear_ops, \ .type = REGULATOR_VOLTAGE, \ .id = HI6421_##_id, \ @@ -228,6 +193,7 @@ static const struct regulator_ops hi6421_buck345_ops; /* HI6421 LDOAUDIO is a linear voltage regulator with two 4-step ranges * * _id - LDO id name string + * _match - of match name string * n_volt - number of votages available * volt_ranges - array of regulator_linear_range * vstep - voltage increase in each linear step in uV @@ -239,11 +205,13 @@ static const struct regulator_ops hi6421_buck345_ops; * ecomask - eco mode mask * ecoamp - eco mode load uppler limit in uA */ -#define HI6421_LDO_LINEAR_RANGE(_id, n_volt, volt_ranges, vreg, vmask, \ +#define HI6421_LDO_LINEAR_RANGE(_id, _match, n_volt, volt_ranges, vreg, vmask,\ ereg, emask, odelay, ecomask, ecoamp) \ [HI6421_##_id] = { \ .desc = { \ .name = #_id, \ + .of_match = of_match_ptr(#_match), \ + .regulators_node = of_match_ptr("regulators"), \ .ops = &hi6421_ldo_linear_range_ops, \ .type = REGULATOR_VOLTAGE, \ .id = HI6421_##_id, \ @@ -265,6 +233,7 @@ static const struct regulator_ops hi6421_buck345_ops; /* HI6421 BUCK0/1/2 are linear voltage regulators at fixed uV_step * * _id - BUCK0/1/2 id name string + * _match - of match name string * vreg - voltage select register * vmask - voltage select mask * ereg - enable register @@ -273,11 +242,13 @@ static const struct regulator_ops hi6421_buck345_ops; * etime - enable time * odelay - off/on delay time in uS */ -#define HI6421_BUCK012(_id, vreg, vmask, ereg, emask, sleepmask, \ +#define HI6421_BUCK012(_id, _match, vreg, vmask, ereg, emask, sleepmask,\ etime, odelay) \ [HI6421_##_id] = { \ .desc = { \ .name = #_id, \ + .of_match = of_match_ptr(#_match), \ + .regulators_node = of_match_ptr("regulators"), \ .ops = &hi6421_buck012_ops, \ .type = REGULATOR_VOLTAGE, \ .id = HI6421_##_id, \ @@ -299,6 +270,7 @@ static const struct regulator_ops hi6421_buck345_ops; * that it supports SLEEP mode, so has different .ops. * * _id - LDO id name string + * _match - of match name string * v_table - voltage table * vreg - voltage select register * vmask - voltage select mask @@ -307,11 +279,13 @@ static const struct regulator_ops hi6421_buck345_ops; * odelay - off/on delay time in uS * sleepmask - mask of sleep mode */ -#define HI6421_BUCK345(_id, v_table, vreg, vmask, ereg, emask, \ +#define HI6421_BUCK345(_id, _match, v_table, vreg, vmask, ereg, emask, \ odelay, sleepmask) \ [HI6421_##_id] = { \ .desc = { \ .name = #_id, \ + .of_match = of_match_ptr(#_match), \ + .regulators_node = of_match_ptr("regulators"), \ .ops = &hi6421_buck345_ops, \ .type = REGULATOR_VOLTAGE, \ .id = HI6421_##_id, \ @@ -331,59 +305,63 @@ static const struct regulator_ops hi6421_buck345_ops; /* HI6421 regulator information */ static struct hi6421_regulator_info hi6421_regulator_info[HI6421_NUM_REGULATORS] = { - HI6421_LDO(LDO0, ldo_0_voltages, 0x20, 0x07, 0x20, 0x10, + HI6421_LDO(LDO0, hi6421_vout0, ldo_0_voltages, 0x20, 0x07, 0x20, 0x10, 10000, 0x20, 8000), - HI6421_LDO_LINEAR(LDO1, 1700000, 4, 100000, 0x21, 0x03, 0x21, 0x10, - 10000, 0x20, 5000), - HI6421_LDO_LINEAR(LDO2, 1050000, 8, 50000, 0x22, 0x07, 0x22, 0x10, - 20000, 0x20, 8000), - HI6421_LDO_LINEAR(LDO3, 1050000, 8, 50000, 0x23, 0x07, 0x23, 0x10, - 20000, 0x20, 8000), - HI6421_LDO(LDO4, ldo_0_voltages, 0x24, 0x07, 0x24, 0x10, + HI6421_LDO_LINEAR(LDO1, hi6421_vout1, 1700000, 4, 100000, 0x21, 0x03, + 0x21, 0x10, 10000, 0x20, 5000), + HI6421_LDO_LINEAR(LDO2, hi6421_vout2, 1050000, 8, 50000, 0x22, 0x07, + 0x22, 0x10, 20000, 0x20, 8000), + HI6421_LDO_LINEAR(LDO3, hi6421_vout3, 1050000, 8, 50000, 0x23, 0x07, + 0x23, 0x10, 20000, 0x20, 8000), + HI6421_LDO(LDO4, hi6421_vout4, ldo_0_voltages, 0x24, 0x07, 0x24, 0x10, 20000, 0x20, 8000), - HI6421_LDO(LDO5, ldo_0_voltages, 0x25, 0x07, 0x25, 0x10, + HI6421_LDO(LDO5, hi6421_vout5, ldo_0_voltages, 0x25, 0x07, 0x25, 0x10, 20000, 0x20, 8000), - HI6421_LDO(LDO6, ldo_0_voltages, 0x26, 0x07, 0x26, 0x10, + HI6421_LDO(LDO6, hi6421_vout6, ldo_0_voltages, 0x26, 0x07, 0x26, 0x10, 20000, 0x20, 8000), - HI6421_LDO(LDO7, ldo_0_voltages, 0x27, 0x07, 0x27, 0x10, + HI6421_LDO(LDO7, hi6421_vout7, ldo_0_voltages, 0x27, 0x07, 0x27, 0x10, 20000, 0x20, 5000), - HI6421_LDO(LDO8, ldo_8_voltages, 0x28, 0x07, 0x28, 0x10, + HI6421_LDO(LDO8, hi6421_vout8, ldo_8_voltages, 0x28, 0x07, 0x28, 0x10, 20000, 0x20, 8000), - HI6421_LDO(LDO9, ldo_0_voltages, 0x29, 0x07, 0x29, 0x10, + HI6421_LDO(LDO9, hi6421_vout9, ldo_0_voltages, 0x29, 0x07, 0x29, 0x10, 40000, 0x20, 8000), - HI6421_LDO(LDO10, ldo_0_voltages, 0x2a, 0x07, 0x2a, 0x10, + HI6421_LDO(LDO10, hi6421_vout10, ldo_0_voltages, 0x2a, 0x07, 0x2a, 0x10, 40000, 0x20, 8000), - HI6421_LDO(LDO11, ldo_0_voltages, 0x2b, 0x07, 0x2b, 0x10, + HI6421_LDO(LDO11, hi6421_vout11, ldo_0_voltages, 0x2b, 0x07, 0x2b, 0x10, 40000, 0x20, 8000), - HI6421_LDO(LDO12, ldo_0_voltages, 0x2c, 0x07, 0x2c, 0x10, + HI6421_LDO(LDO12, hi6421_vout12, ldo_0_voltages, 0x2c, 0x07, 0x2c, 0x10, 40000, 0x20, 8000), - HI6421_LDO(LDO13, ldo_0_voltages, 0x2d, 0x07, 0x2d, 0x10, + HI6421_LDO(LDO13, hi6421_vout13, ldo_0_voltages, 0x2d, 0x07, 0x2d, 0x10, 40000, 0x20, 8000), - HI6421_LDO(LDO14, ldo_0_voltages, 0x2e, 0x07, 0x2e, 0x10, + HI6421_LDO(LDO14, hi6421_vout14, ldo_0_voltages, 0x2e, 0x07, 0x2e, 0x10, 40000, 0x20, 8000), - HI6421_LDO(LDO15, ldo_8_voltages, 0x2f, 0x07, 0x2f, 0x10, + HI6421_LDO(LDO15, hi6421_vout15, ldo_8_voltages, 0x2f, 0x07, 0x2f, 0x10, 40000, 0x20, 8000), - HI6421_LDO(LDO16, ldo_0_voltages, 0x30, 0x07, 0x30, 0x10, + HI6421_LDO(LDO16, hi6421_vout16, ldo_0_voltages, 0x30, 0x07, 0x30, 0x10, 40000, 0x20, 8000), - HI6421_LDO(LDO17, ldo_0_voltages, 0x31, 0x07, 0x31, 0x10, + HI6421_LDO(LDO17, hi6421_vout17, ldo_0_voltages, 0x31, 0x07, 0x31, 0x10, 40000, 0x20, 8000), - HI6421_LDO(LDO18, ldo_0_voltages, 0x32, 0x07, 0x32, 0x10, + HI6421_LDO(LDO18, hi6421_vout18, ldo_0_voltages, 0x32, 0x07, 0x32, 0x10, 40000, 0x20, 8000), - HI6421_LDO(LDO19, ldo_0_voltages, 0x33, 0x07, 0x33, 0x10, + HI6421_LDO(LDO19, hi6421_vout19, ldo_0_voltages, 0x33, 0x07, 0x33, 0x10, 40000, 0x20, 8000), - HI6421_LDO(LDO20, ldo_0_voltages, 0x34, 0x07, 0x34, 0x10, + HI6421_LDO(LDO20, hi6421_vout20, ldo_0_voltages, 0x34, 0x07, 0x34, 0x10, 40000, 0x20, 8000), - HI6421_LDO_LINEAR_RANGE(LDOAUDIO, 8, ldo_audio_volt_range, 0x36, - 0x70, 0x36, 0x01, 40000, 0x02, 5000), - HI6421_BUCK012(BUCK0, 0x0d, 0x7f, 0x0c, 0x01, 0x10, 400, 20000), - HI6421_BUCK012(BUCK1, 0x0f, 0x7f, 0x0e, 0x01, 0x10, 400, 20000), - HI6421_BUCK012(BUCK2, 0x11, 0x7f, 0x10, 0x01, 0x10, 350, 100), - HI6421_BUCK345(BUCK3, buck_3_voltages, 0x13, 0x07, 0x12, 0x01, - 20000, 0x10), - HI6421_BUCK345(BUCK4, buck_4_voltages, 0x15, 0x07, 0x14, 0x01, - 20000, 0x10), - HI6421_BUCK345(BUCK5, buck_5_voltages, 0x17, 0x07, 0x16, 0x01, - 20000, 0x10), + HI6421_LDO_LINEAR_RANGE(LDOAUDIO, hi6421_vout_audio, 8, + ldo_audio_volt_range, 0x36, 0x70, 0x36, 0x01, + 40000, 0x02, 5000), + HI6421_BUCK012(BUCK0, hi6421_buck0, 0x0d, 0x7f, 0x0c, 0x01, 0x10, 400, + 20000), + HI6421_BUCK012(BUCK1, hi6421_buck1, 0x0f, 0x7f, 0x0e, 0x01, 0x10, 400, + 20000), + HI6421_BUCK012(BUCK2, hi6421_buck2, 0x11, 0x7f, 0x10, 0x01, 0x10, 350, + 100), + HI6421_BUCK345(BUCK3, hi6421_buck3, buck_3_voltages, 0x13, 0x07, 0x12, + 0x01, 20000, 0x10), + HI6421_BUCK345(BUCK4, hi6421_buck4, buck_4_voltages, 0x15, 0x07, 0x14, + 0x01, 20000, 0x10), + HI6421_BUCK345(BUCK5, hi6421_buck5, buck_5_voltages, 0x17, 0x07, 0x16, + 0x01, 20000, 0x10), }; static int hi6421_regulator_enable(struct regulator_dev *rdev) @@ -552,42 +530,14 @@ static const struct regulator_ops hi6421_buck345_ops = { .set_mode = hi6421_regulator_buck_set_mode, }; -static int hi6421_regulator_register(struct platform_device *pdev, - struct regmap *rmap, - struct regulator_init_data *init_data, - int id, struct device_node *np) -{ - struct hi6421_regulator_info *info = NULL; - struct regulator_config config = { }; - struct regulator_dev *rdev; - - /* assign per-regulator data */ - info = &hi6421_regulator_info[id]; - - config.dev = &pdev->dev; - config.init_data = init_data; - config.driver_data = info; - config.regmap = rmap; - config.of_node = np; - - /* register regulator with framework */ - rdev = devm_regulator_register(&pdev->dev, &info->desc, &config); - if (IS_ERR(rdev)) { - dev_err(&pdev->dev, "failed to register regulator %s\n", - info->desc.name); - return PTR_ERR(rdev); - } - - return 0; -} - static int hi6421_regulator_probe(struct platform_device *pdev) { - struct device *dev = &pdev->dev; - struct device_node *np; - struct hi6421_pmic *pmic; + struct hi6421_pmic *pmic = dev_get_drvdata(pdev->dev.parent); struct hi6421_regulator_pdata *pdata; - int i, ret = 0; + struct hi6421_regulator_info *info; + struct regulator_config config = { }; + struct regulator_dev *rdev; + int i; pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) @@ -595,27 +545,21 @@ static int hi6421_regulator_probe(struct platform_device *pdev) mutex_init(&pdata->lock); platform_set_drvdata(pdev, pdata); - np = of_get_child_by_name(dev->parent->of_node, "regulators"); - if (!np) - return -ENODEV; - - ret = of_regulator_match(dev, np, - hi6421_regulator_match, - ARRAY_SIZE(hi6421_regulator_match)); - of_node_put(np); - if (ret < 0) { - dev_err(dev, "Error parsing regulator init data: %d\n", ret); - return ret; - } - - pmic = dev_get_drvdata(dev->parent); - for (i = 0; i < ARRAY_SIZE(hi6421_regulator_info); i++) { - ret = hi6421_regulator_register(pdev, pmic->regmap, - hi6421_regulator_match[i].init_data, i, - hi6421_regulator_match[i].of_node); - if (ret) - return ret; + /* assign per-regulator data */ + info = &hi6421_regulator_info[i]; + + config.dev = pdev->dev.parent; + config.driver_data = info; + config.regmap = pmic->regmap; + + rdev = devm_regulator_register(&pdev->dev, &info->desc, + &config); + if (IS_ERR(rdev)) { + dev_err(&pdev->dev, "failed to register regulator %s\n", + info->desc.name); + return PTR_ERR(rdev); + } } return 0; diff --git a/drivers/regulator/hi6421v530-regulator.c b/drivers/regulator/hi6421v530-regulator.c index c09bc71538a5..06ae65199afd 100644 --- a/drivers/regulator/hi6421v530-regulator.c +++ b/drivers/regulator/hi6421v530-regulator.c @@ -1,18 +1,14 @@ -/* - * Device driver for regulators in Hi6421V530 IC - * - * Copyright (c) <2017> HiSilicon Technologies Co., Ltd. - * http://www.hisilicon.com - * Copyright (c) <2017> Linaro Ltd. - * http://www.linaro.org - * - * Author: Wang Xiaoyin <hw.wangxiaoyin@hisilicon.com> - * Guodong Xu <guodong.xu@linaro.org> - * - * 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 - * published by the Free Software Foundation. - */ +// SPDX-License-Identifier: GPL-2.0 +// +// Device driver for regulators in Hi6421V530 IC +// +// Copyright (c) <2017> HiSilicon Technologies Co., Ltd. +// http://www.hisilicon.com +// Copyright (c) <2017> Linaro Ltd. +// http://www.linaro.org +// +// Author: Wang Xiaoyin <hw.wangxiaoyin@hisilicon.com> +// Guodong Xu <guodong.xu@linaro.org> #include <linux/mfd/hi6421-pmic.h> #include <linux/module.h> diff --git a/drivers/regulator/hi655x-regulator.c b/drivers/regulator/hi655x-regulator.c index bba24a6fdb1e..ac2ee2030211 100644 --- a/drivers/regulator/hi655x-regulator.c +++ b/drivers/regulator/hi655x-regulator.c @@ -1,16 +1,12 @@ -/* - * Device driver for regulators in Hi655x IC - * - * Copyright (c) 2016 Hisilicon. - * - * Authors: - * Chen Feng <puck.chen@hisilicon.com> - * Fei Wang <w.f@huawei.com> - * - * 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 - * published by the Free Software Foundation. - */ +// SPDX-License-Identifier: GPL-2.0 +// +// Device driver for regulators in Hi655x IC +// +// Copyright (c) 2016 Hisilicon. +// +// Authors: +// Chen Feng <puck.chen@hisilicon.com> +// Fei Wang <w.f@huawei.com> #include <linux/bitops.h> #include <linux/device.h> @@ -28,7 +24,6 @@ struct hi655x_regulator { unsigned int disable_reg; unsigned int status_reg; - unsigned int ctrl_mask; struct regulator_desc rdesc; }; @@ -77,22 +72,18 @@ enum hi655x_regulator_id { static int hi655x_is_enabled(struct regulator_dev *rdev) { unsigned int value = 0; - struct hi655x_regulator *regulator = rdev_get_drvdata(rdev); regmap_read(rdev->regmap, regulator->status_reg, &value); - return (value & BIT(regulator->ctrl_mask)); + return (value & rdev->desc->enable_mask); } static int hi655x_disable(struct regulator_dev *rdev) { - int ret = 0; - struct hi655x_regulator *regulator = rdev_get_drvdata(rdev); - ret = regmap_write(rdev->regmap, regulator->disable_reg, - BIT(regulator->ctrl_mask)); - return ret; + return regmap_write(rdev->regmap, regulator->disable_reg, + rdev->desc->enable_mask); } static const struct regulator_ops hi655x_regulator_ops = { @@ -132,7 +123,6 @@ static const struct regulator_ops hi655x_ldo_linear_ops = { }, \ .disable_reg = HI655X_BUS_ADDR(dreg), \ .status_reg = HI655X_BUS_ADDR(sreg), \ - .ctrl_mask = cmask, \ } #define HI655X_LDO_LINEAR(_ID, vreg, vmask, ereg, dreg, \ @@ -155,10 +145,9 @@ static const struct regulator_ops hi655x_ldo_linear_ops = { }, \ .disable_reg = HI655X_BUS_ADDR(dreg), \ .status_reg = HI655X_BUS_ADDR(sreg), \ - .ctrl_mask = cmask, \ } -static struct hi655x_regulator regulators[] = { +static const struct hi655x_regulator regulators[] = { HI655X_LDO_LINEAR(LDO2, 0x72, 0x07, 0x29, 0x2a, 0x2b, 0x01, 2500000, 8, 100000), HI655X_LDO(LDO7, 0x78, 0x07, 0x29, 0x2a, 0x2b, 0x06, ldo7_voltages), diff --git a/drivers/regulator/lm363x-regulator.c b/drivers/regulator/lm363x-regulator.c index c876e161052a..e02fdd1dd092 100644 --- a/drivers/regulator/lm363x-regulator.c +++ b/drivers/regulator/lm363x-regulator.c @@ -48,7 +48,7 @@ static const int ldo_cont_enable_time[] = { static int lm363x_regulator_enable_time(struct regulator_dev *rdev) { enum lm363x_regulator_id id = rdev_get_id(rdev); - u8 val, addr, mask; + unsigned int val, addr, mask; switch (id) { case LM3631_LDO_CONT: @@ -71,7 +71,7 @@ static int lm363x_regulator_enable_time(struct regulator_dev *rdev) return 0; } - if (regmap_read(rdev->regmap, addr, (unsigned int *)&val)) + if (regmap_read(rdev->regmap, addr, &val)) return -EINVAL; val = (val & mask) >> LM3631_ENTIME_SHIFT; @@ -82,13 +82,13 @@ static int lm363x_regulator_enable_time(struct regulator_dev *rdev) return ENABLE_TIME_USEC * val; } -static struct regulator_ops lm363x_boost_voltage_table_ops = { +static const struct regulator_ops lm363x_boost_voltage_table_ops = { .list_voltage = regulator_list_voltage_linear, .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, }; -static struct regulator_ops lm363x_regulator_voltage_table_ops = { +static const struct regulator_ops lm363x_regulator_voltage_table_ops = { .list_voltage = regulator_list_voltage_linear, .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, 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..9a037fdc5fc5 100644 --- a/drivers/regulator/ltc3589.c +++ b/drivers/regulator/ltc3589.c @@ -1,21 +1,9 @@ -/* - * Linear Technology LTC3589,LTC3589-1 regulator support - * - * Copyright (c) 2014 Philipp Zabel <p.zabel@pengutronix.de>, Pengutronix - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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 published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ +// SPDX-License-Identifier: GPL-2.0 +// +// Linear Technology LTC3589,LTC3589-1 regulator support +// +// Copyright (c) 2014 Philipp Zabel <p.zabel@pengutronix.de>, Pengutronix + #include <linux/i2c.h> #include <linux/init.h> #include <linux/interrupt.h> @@ -84,19 +72,11 @@ enum ltc3589_reg { LTC3589_NUM_REGULATORS, }; -struct ltc3589_regulator { - struct regulator_desc desc; - - /* External feedback voltage divider */ - unsigned int r1; - unsigned int r2; -}; - struct ltc3589 { struct regmap *regmap; struct device *dev; enum ltc3589_variant variant; - struct ltc3589_regulator regulator_descs[LTC3589_NUM_REGULATORS]; + struct regulator_desc regulator_descs[LTC3589_NUM_REGULATORS]; struct regulator_dev *regulators[LTC3589_NUM_REGULATORS]; }; @@ -196,131 +176,90 @@ static const struct regulator_ops ltc3589_table_regulator_ops = { .get_voltage_sel = regulator_get_voltage_sel_regmap, }; +static inline unsigned int ltc3589_scale(unsigned int uV, u32 r1, u32 r2) +{ + uint64_t tmp; -#define LTC3589_REG(_name, _ops, en_bit, dtv1_reg, dtv_mask, go_bit) \ - [LTC3589_ ## _name] = { \ - .desc = { \ - .name = #_name, \ - .n_voltages = (dtv_mask) + 1, \ - .min_uV = (go_bit) ? 362500 : 0, \ - .uV_step = (go_bit) ? 12500 : 0, \ - .ramp_delay = (go_bit) ? 1750 : 0, \ - .fixed_uV = (dtv_mask) ? 0 : 800000, \ - .ops = <c3589_ ## _ops ## _regulator_ops, \ - .type = REGULATOR_VOLTAGE, \ - .id = LTC3589_ ## _name, \ - .owner = THIS_MODULE, \ - .vsel_reg = (dtv1_reg), \ - .vsel_mask = (dtv_mask), \ - .apply_reg = (go_bit) ? LTC3589_VCCR : 0, \ - .apply_bit = (go_bit), \ - .enable_reg = (en_bit) ? LTC3589_OVEN : 0, \ - .enable_mask = (en_bit), \ - }, \ - } - -#define LTC3589_LINEAR_REG(_name, _dtv1) \ - LTC3589_REG(_name, linear, LTC3589_OVEN_ ## _name, \ - LTC3589_ ## _dtv1, 0x1f, \ - LTC3589_VCCR_ ## _name ## _GO) - -#define LTC3589_FIXED_REG(_name) \ - LTC3589_REG(_name, fixed, LTC3589_OVEN_ ## _name, 0, 0, 0) - -static struct ltc3589_regulator ltc3589_regulators[LTC3589_NUM_REGULATORS] = { - LTC3589_LINEAR_REG(SW1, B1DTV1), - LTC3589_LINEAR_REG(SW2, B2DTV1), - LTC3589_LINEAR_REG(SW3, B3DTV1), - LTC3589_FIXED_REG(BB_OUT), - LTC3589_REG(LDO1, fixed_standby, 0, 0, 0, 0), - LTC3589_LINEAR_REG(LDO2, L2DTV1), - LTC3589_FIXED_REG(LDO3), - LTC3589_REG(LDO4, table, LTC3589_OVEN_LDO4, LTC3589_L2DTV2, 0x60, 0), -}; + if (uV == 0) + return 0; -#ifdef CONFIG_OF -static struct of_regulator_match ltc3589_matches[LTC3589_NUM_REGULATORS] = { - { .name = "sw1", }, - { .name = "sw2", }, - { .name = "sw3", }, - { .name = "bb-out", }, - { .name = "ldo1", }, /* standby */ - { .name = "ldo2", }, - { .name = "ldo3", }, - { .name = "ldo4", }, -}; + tmp = (uint64_t)uV * r1; + do_div(tmp, r2); + return uV + (unsigned int)tmp; +} -static int ltc3589_parse_regulators_dt(struct ltc3589 *ltc3589) +static int ltc3589_of_parse_cb(struct device_node *np, + const struct regulator_desc *desc, + struct regulator_config *config) { - struct device *dev = ltc3589->dev; - struct device_node *node; - int i, ret; + struct ltc3589 *ltc3589 = config->driver_data; + struct regulator_desc *rdesc = <c3589->regulator_descs[desc->id]; + u32 r[2]; + int ret; - node = of_get_child_by_name(dev->of_node, "regulators"); - if (!node) { - dev_err(dev, "regulators node not found\n"); - return -EINVAL; - } + /* Parse feedback voltage dividers. LDO3 and LDO4 don't have them */ + if (desc->id >= LTC3589_LDO3) + return 0; - ret = of_regulator_match(dev, node, ltc3589_matches, - ARRAY_SIZE(ltc3589_matches)); - of_node_put(node); - if (ret < 0) { - dev_err(dev, "Error parsing regulator init data: %d\n", ret); - return ret; - } - if (ret != LTC3589_NUM_REGULATORS) { - dev_err(dev, "Only %d regulators described in device tree\n", + ret = of_property_read_u32_array(np, "lltc,fb-voltage-divider", r, 2); + if (ret) { + dev_err(ltc3589->dev, "Failed to parse voltage divider: %d\n", ret); - return -EINVAL; + return ret; } - /* Parse feedback voltage dividers. LDO3 and LDO4 don't have them */ - for (i = 0; i < LTC3589_LDO3; i++) { - struct ltc3589_regulator *desc = <c3589->regulator_descs[i]; - struct device_node *np = ltc3589_matches[i].of_node; - u32 vdiv[2]; - - ret = of_property_read_u32_array(np, "lltc,fb-voltage-divider", - vdiv, 2); - if (ret) { - dev_err(dev, "Failed to parse voltage divider: %d\n", - ret); - return ret; - } + if (!r[0] || !r[1]) + return 0; - desc->r1 = vdiv[0]; - desc->r2 = vdiv[1]; - } + rdesc->min_uV = ltc3589_scale(desc->min_uV, r[0], r[1]); + rdesc->uV_step = ltc3589_scale(desc->uV_step, r[0], r[1]); + rdesc->fixed_uV = ltc3589_scale(desc->fixed_uV, r[0], r[1]); return 0; } -static inline struct regulator_init_data *match_init_data(int index) -{ - return ltc3589_matches[index].init_data; -} - -static inline struct device_node *match_of_node(int index) -{ - return ltc3589_matches[index].of_node; -} -#else -static inline int ltc3589_parse_regulators_dt(struct ltc3589 *ltc3589) -{ - return 0; -} +#define LTC3589_REG(_name, _of_name, _ops, en_bit, dtv1_reg, dtv_mask, go_bit)\ + [LTC3589_ ## _name] = { \ + .name = #_name, \ + .of_match = of_match_ptr(#_of_name), \ + .regulators_node = of_match_ptr("regulators"), \ + .of_parse_cb = ltc3589_of_parse_cb, \ + .n_voltages = (dtv_mask) + 1, \ + .min_uV = (go_bit) ? 362500 : 0, \ + .uV_step = (go_bit) ? 12500 : 0, \ + .ramp_delay = (go_bit) ? 1750 : 0, \ + .fixed_uV = (dtv_mask) ? 0 : 800000, \ + .ops = <c3589_ ## _ops ## _regulator_ops, \ + .type = REGULATOR_VOLTAGE, \ + .id = LTC3589_ ## _name, \ + .owner = THIS_MODULE, \ + .vsel_reg = (dtv1_reg), \ + .vsel_mask = (dtv_mask), \ + .apply_reg = (go_bit) ? LTC3589_VCCR : 0, \ + .apply_bit = (go_bit), \ + .enable_reg = (en_bit) ? LTC3589_OVEN : 0, \ + .enable_mask = (en_bit), \ + } -static inline struct regulator_init_data *match_init_data(int index) -{ - return NULL; -} +#define LTC3589_LINEAR_REG(_name, _of_name, _dtv1) \ + LTC3589_REG(_name, _of_name, linear, LTC3589_OVEN_ ## _name, \ + LTC3589_ ## _dtv1, 0x1f, \ + LTC3589_VCCR_ ## _name ## _GO) -static inline struct device_node *match_of_node(int index) -{ - return NULL; -} -#endif +#define LTC3589_FIXED_REG(_name, _of_name) \ + LTC3589_REG(_name, _of_name, fixed, LTC3589_OVEN_ ## _name, 0, 0, 0) + +static const struct regulator_desc ltc3589_regulators[] = { + LTC3589_LINEAR_REG(SW1, sw1, B1DTV1), + LTC3589_LINEAR_REG(SW2, sw2, B2DTV1), + LTC3589_LINEAR_REG(SW3, sw3, B3DTV1), + LTC3589_FIXED_REG(BB_OUT, bb-out), + LTC3589_REG(LDO1, ldo1, fixed_standby, 0, 0, 0, 0), + LTC3589_LINEAR_REG(LDO2, ldo2, L2DTV1), + LTC3589_FIXED_REG(LDO3, ldo3), + LTC3589_REG(LDO4, ldo4, table, LTC3589_OVEN_LDO4, LTC3589_L2DTV2, + 0x60, 0), +}; static bool ltc3589_writeable_reg(struct device *dev, unsigned int reg) { @@ -409,7 +348,6 @@ static const struct regmap_config ltc3589_regmap_config = { .cache_type = REGCACHE_RBTREE, }; - static irqreturn_t ltc3589_isr(int irq, void *dev_id) { struct ltc3589 *ltc3589 = dev_id; @@ -419,16 +357,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 */ @@ -437,33 +381,11 @@ static irqreturn_t ltc3589_isr(int irq, void *dev_id) return IRQ_HANDLED; } -static inline unsigned int ltc3589_scale(unsigned int uV, u32 r1, u32 r2) -{ - uint64_t tmp; - if (uV == 0) - return 0; - tmp = (uint64_t)uV * r1; - do_div(tmp, r2); - return uV + (unsigned int)tmp; -} - -static void ltc3589_apply_fb_voltage_divider(struct ltc3589_regulator *rdesc) -{ - struct regulator_desc *desc = &rdesc->desc; - - if (!rdesc->r1 || !rdesc->r2) - return; - - desc->min_uV = ltc3589_scale(desc->min_uV, rdesc->r1, rdesc->r2); - desc->uV_step = ltc3589_scale(desc->uV_step, rdesc->r1, rdesc->r2); - desc->fixed_uV = ltc3589_scale(desc->fixed_uV, rdesc->r1, rdesc->r2); -} - static int ltc3589_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct device *dev = &client->dev; - struct ltc3589_regulator *descs; + struct regulator_desc *descs; struct ltc3589 *ltc3589; int i, ret; @@ -482,11 +404,11 @@ static int ltc3589_probe(struct i2c_client *client, descs = ltc3589->regulator_descs; memcpy(descs, ltc3589_regulators, sizeof(ltc3589_regulators)); if (ltc3589->variant == LTC3589) { - descs[LTC3589_LDO3].desc.fixed_uV = 1800000; - descs[LTC3589_LDO4].desc.volt_table = ltc3589_ldo4; + descs[LTC3589_LDO3].fixed_uV = 1800000; + descs[LTC3589_LDO4].volt_table = ltc3589_ldo4; } else { - descs[LTC3589_LDO3].desc.fixed_uV = 2800000; - descs[LTC3589_LDO4].desc.volt_table = ltc3589_12_ldo4; + descs[LTC3589_LDO3].fixed_uV = 2800000; + descs[LTC3589_LDO4].volt_table = ltc3589_12_ldo4; } ltc3589->regmap = devm_regmap_init_i2c(client, <c3589_regmap_config); @@ -496,25 +418,12 @@ static int ltc3589_probe(struct i2c_client *client, return ret; } - ret = ltc3589_parse_regulators_dt(ltc3589); - if (ret) - return ret; - for (i = 0; i < LTC3589_NUM_REGULATORS; i++) { - struct ltc3589_regulator *rdesc = <c3589->regulator_descs[i]; - struct regulator_desc *desc = &rdesc->desc; - struct regulator_init_data *init_data; + struct regulator_desc *desc = <c3589->regulator_descs[i]; struct regulator_config config = { }; - init_data = match_init_data(i); - - if (i < LTC3589_LDO3) - ltc3589_apply_fb_voltage_divider(rdesc); - config.dev = dev; - config.init_data = init_data; config.driver_data = ltc3589; - config.of_node = match_of_node(i); ltc3589->regulators[i] = devm_regulator_register(dev, desc, &config); 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/max77620-regulator.c b/drivers/regulator/max77620-regulator.c index 1607ac673e44..0ad91a7f9cb9 100644 --- a/drivers/regulator/max77620-regulator.c +++ b/drivers/regulator/max77620-regulator.c @@ -803,7 +803,7 @@ static int max77620_regulator_probe(struct platform_device *pdev) continue; rdesc = &rinfo[id].desc; - pmic->rinfo[id] = &max77620_regs_info[id]; + pmic->rinfo[id] = &rinfo[id]; pmic->enable_power_mode[id] = MAX77620_POWER_MODE_NORMAL; pmic->reg_pdata[id].active_fps_src = -1; pmic->reg_pdata[id].active_fps_pd_slot = -1; 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/max8925-regulator.c b/drivers/regulator/max8925-regulator.c index 39b63ddefeb2..aed6727982cd 100644 --- a/drivers/regulator/max8925-regulator.c +++ b/drivers/regulator/max8925-regulator.c @@ -159,6 +159,8 @@ static const struct regulator_ops max8925_regulator_ldo_ops = { { \ .desc = { \ .name = "SDV" #_id, \ + .of_match = of_match_ptr("SDV" #_id), \ + .regulators_node = of_match_ptr("regulators"), \ .ops = &max8925_regulator_sdv_ops, \ .type = REGULATOR_VOLTAGE, \ .id = MAX8925_ID_SD##_id, \ @@ -175,6 +177,8 @@ static const struct regulator_ops max8925_regulator_ldo_ops = { { \ .desc = { \ .name = "LDO" #_id, \ + .of_match = of_match_ptr("LDO" #_id), \ + .regulators_node = of_match_ptr("regulators"), \ .ops = &max8925_regulator_ldo_ops, \ .type = REGULATOR_VOLTAGE, \ .id = MAX8925_ID_LDO##_id, \ @@ -187,34 +191,6 @@ static const struct regulator_ops max8925_regulator_ldo_ops = { .enable_reg = MAX8925_LDOCTL##_id, \ } -#ifdef CONFIG_OF -static struct of_regulator_match max8925_regulator_matches[] = { - { .name = "SDV1",}, - { .name = "SDV2",}, - { .name = "SDV3",}, - { .name = "LDO1",}, - { .name = "LDO2",}, - { .name = "LDO3",}, - { .name = "LDO4",}, - { .name = "LDO5",}, - { .name = "LDO6",}, - { .name = "LDO7",}, - { .name = "LDO8",}, - { .name = "LDO9",}, - { .name = "LDO10",}, - { .name = "LDO11",}, - { .name = "LDO12",}, - { .name = "LDO13",}, - { .name = "LDO14",}, - { .name = "LDO15",}, - { .name = "LDO16",}, - { .name = "LDO17",}, - { .name = "LDO18",}, - { .name = "LDO19",}, - { .name = "LDO20",}, -}; -#endif - static struct max8925_regulator_info max8925_regulator_info[] = { MAX8925_SDV(1, 637.5, 1425, 12.5), MAX8925_SDV(2, 650, 2225, 25), @@ -242,37 +218,6 @@ static struct max8925_regulator_info max8925_regulator_info[] = { MAX8925_LDO(20, 750, 3900, 50), }; -#ifdef CONFIG_OF -static int max8925_regulator_dt_init(struct platform_device *pdev, - struct regulator_config *config, - int ridx) -{ - struct device_node *nproot, *np; - int rcount; - - nproot = pdev->dev.parent->of_node; - if (!nproot) - return -ENODEV; - np = of_get_child_by_name(nproot, "regulators"); - if (!np) { - dev_err(&pdev->dev, "failed to find regulators node\n"); - return -ENODEV; - } - - rcount = of_regulator_match(&pdev->dev, np, - &max8925_regulator_matches[ridx], 1); - of_node_put(np); - if (rcount < 0) - return rcount; - config->init_data = max8925_regulator_matches[ridx].init_data; - config->of_node = max8925_regulator_matches[ridx].of_node; - - return 0; -} -#else -#define max8925_regulator_dt_init(x, y, z) (-1) -#endif - static int max8925_regulator_probe(struct platform_device *pdev) { struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent); @@ -281,7 +226,7 @@ static int max8925_regulator_probe(struct platform_device *pdev) struct max8925_regulator_info *ri; struct resource *res; struct regulator_dev *rdev; - int i, regulator_idx; + int i; res = platform_get_resource(pdev, IORESOURCE_REG, 0); if (!res) { @@ -290,10 +235,8 @@ static int max8925_regulator_probe(struct platform_device *pdev) } for (i = 0; i < ARRAY_SIZE(max8925_regulator_info); i++) { ri = &max8925_regulator_info[i]; - if (ri->vol_reg == res->start) { - regulator_idx = i; + if (ri->vol_reg == res->start) break; - } } if (i == ARRAY_SIZE(max8925_regulator_info)) { @@ -303,12 +246,11 @@ static int max8925_regulator_probe(struct platform_device *pdev) } ri->i2c = chip->i2c; - config.dev = &pdev->dev; + config.dev = chip->dev; config.driver_data = ri; - if (max8925_regulator_dt_init(pdev, &config, regulator_idx)) - if (pdata) - config.init_data = pdata; + if (pdata) + config.init_data = pdata; rdev = devm_regulator_register(&pdev->dev, &ri->desc, &config); if (IS_ERR(rdev)) { diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c index 271bb736f3f5..60599c3bb845 100644 --- a/drivers/regulator/max8998.c +++ b/drivers/regulator/max8998.c @@ -33,72 +33,6 @@ struct max8998_data { unsigned int buck2_idx; }; -struct voltage_map_desc { - int min; - int max; - int step; -}; - -/* Voltage maps in uV*/ -static const struct voltage_map_desc ldo23_voltage_map_desc = { - .min = 800000, .step = 50000, .max = 1300000, -}; -static const struct voltage_map_desc ldo456711_voltage_map_desc = { - .min = 1600000, .step = 100000, .max = 3600000, -}; -static const struct voltage_map_desc ldo8_voltage_map_desc = { - .min = 3000000, .step = 100000, .max = 3600000, -}; -static const struct voltage_map_desc ldo9_voltage_map_desc = { - .min = 2800000, .step = 100000, .max = 3100000, -}; -static const struct voltage_map_desc ldo10_voltage_map_desc = { - .min = 950000, .step = 50000, .max = 1300000, -}; -static const struct voltage_map_desc ldo1213_voltage_map_desc = { - .min = 800000, .step = 100000, .max = 3300000, -}; -static const struct voltage_map_desc ldo1415_voltage_map_desc = { - .min = 1200000, .step = 100000, .max = 3300000, -}; -static const struct voltage_map_desc ldo1617_voltage_map_desc = { - .min = 1600000, .step = 100000, .max = 3600000, -}; -static const struct voltage_map_desc buck12_voltage_map_desc = { - .min = 750000, .step = 25000, .max = 1525000, -}; -static const struct voltage_map_desc buck3_voltage_map_desc = { - .min = 1600000, .step = 100000, .max = 3600000, -}; -static const struct voltage_map_desc buck4_voltage_map_desc = { - .min = 800000, .step = 100000, .max = 2300000, -}; - -static const struct voltage_map_desc *ldo_voltage_map[] = { - NULL, - NULL, - &ldo23_voltage_map_desc, /* LDO2 */ - &ldo23_voltage_map_desc, /* LDO3 */ - &ldo456711_voltage_map_desc, /* LDO4 */ - &ldo456711_voltage_map_desc, /* LDO5 */ - &ldo456711_voltage_map_desc, /* LDO6 */ - &ldo456711_voltage_map_desc, /* LDO7 */ - &ldo8_voltage_map_desc, /* LDO8 */ - &ldo9_voltage_map_desc, /* LDO9 */ - &ldo10_voltage_map_desc, /* LDO10 */ - &ldo456711_voltage_map_desc, /* LDO11 */ - &ldo1213_voltage_map_desc, /* LDO12 */ - &ldo1213_voltage_map_desc, /* LDO13 */ - &ldo1415_voltage_map_desc, /* LDO14 */ - &ldo1415_voltage_map_desc, /* LDO15 */ - &ldo1617_voltage_map_desc, /* LDO16 */ - &ldo1617_voltage_map_desc, /* LDO17 */ - &buck12_voltage_map_desc, /* BUCK1 */ - &buck12_voltage_map_desc, /* BUCK2 */ - &buck3_voltage_map_desc, /* BUCK3 */ - &buck4_voltage_map_desc, /* BUCK4 */ -}; - static int max8998_get_enable_register(struct regulator_dev *rdev, int *reg, int *shift) { @@ -400,7 +334,6 @@ static int max8998_set_voltage_buck_time_sel(struct regulator_dev *rdev, { struct max8998_data *max8998 = rdev_get_drvdata(rdev); struct i2c_client *i2c = max8998->iodev->i2c; - const struct voltage_map_desc *desc; int buck = rdev_get_id(rdev); u8 val = 0; int difference, ret; @@ -408,8 +341,6 @@ static int max8998_set_voltage_buck_time_sel(struct regulator_dev *rdev, if (buck < MAX8998_BUCK1 || buck > MAX8998_BUCK4) return -EINVAL; - desc = ldo_voltage_map[buck]; - /* Voltage stabilization */ ret = max8998_read_reg(i2c, MAX8998_REG_ONOFF4, &val); if (ret) @@ -420,14 +351,14 @@ static int max8998_set_voltage_buck_time_sel(struct regulator_dev *rdev, if (max8998->iodev->type == TYPE_MAX8998 && !(val & MAX8998_ENRAMP)) return 0; - difference = (new_selector - old_selector) * desc->step / 1000; + difference = (new_selector - old_selector) * rdev->desc->uV_step / 1000; if (difference > 0) return DIV_ROUND_UP(difference, (val & 0x0f) + 1); return 0; } -static struct regulator_ops max8998_ldo_ops = { +static const struct regulator_ops max8998_ldo_ops = { .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, .is_enabled = max8998_ldo_is_enabled, @@ -437,7 +368,7 @@ static struct regulator_ops max8998_ldo_ops = { .set_voltage_sel = max8998_set_voltage_ldo_sel, }; -static struct regulator_ops max8998_buck_ops = { +static const struct regulator_ops max8998_buck_ops = { .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, .is_enabled = max8998_ldo_is_enabled, @@ -448,164 +379,59 @@ static struct regulator_ops max8998_buck_ops = { .set_voltage_time_sel = max8998_set_voltage_buck_time_sel, }; -static struct regulator_ops max8998_others_ops = { +static const struct regulator_ops max8998_others_ops = { .is_enabled = max8998_ldo_is_enabled, .enable = max8998_ldo_enable, .disable = max8998_ldo_disable, }; -static struct regulator_desc regulators[] = { - { - .name = "LDO2", - .id = MAX8998_LDO2, - .ops = &max8998_ldo_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "LDO3", - .id = MAX8998_LDO3, - .ops = &max8998_ldo_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "LDO4", - .id = MAX8998_LDO4, - .ops = &max8998_ldo_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "LDO5", - .id = MAX8998_LDO5, - .ops = &max8998_ldo_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "LDO6", - .id = MAX8998_LDO6, - .ops = &max8998_ldo_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "LDO7", - .id = MAX8998_LDO7, - .ops = &max8998_ldo_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "LDO8", - .id = MAX8998_LDO8, - .ops = &max8998_ldo_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "LDO9", - .id = MAX8998_LDO9, - .ops = &max8998_ldo_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "LDO10", - .id = MAX8998_LDO10, - .ops = &max8998_ldo_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "LDO11", - .id = MAX8998_LDO11, - .ops = &max8998_ldo_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "LDO12", - .id = MAX8998_LDO12, - .ops = &max8998_ldo_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "LDO13", - .id = MAX8998_LDO13, - .ops = &max8998_ldo_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "LDO14", - .id = MAX8998_LDO14, - .ops = &max8998_ldo_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "LDO15", - .id = MAX8998_LDO15, - .ops = &max8998_ldo_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "LDO16", - .id = MAX8998_LDO16, - .ops = &max8998_ldo_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "LDO17", - .id = MAX8998_LDO17, - .ops = &max8998_ldo_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "BUCK1", - .id = MAX8998_BUCK1, - .ops = &max8998_buck_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "BUCK2", - .id = MAX8998_BUCK2, - .ops = &max8998_buck_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "BUCK3", - .id = MAX8998_BUCK3, - .ops = &max8998_buck_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "BUCK4", - .id = MAX8998_BUCK4, - .ops = &max8998_buck_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "EN32KHz-AP", - .id = MAX8998_EN32KHZ_AP, - .ops = &max8998_others_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "EN32KHz-CP", - .id = MAX8998_EN32KHZ_CP, - .ops = &max8998_others_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "ENVICHG", - .id = MAX8998_ENVICHG, - .ops = &max8998_others_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "ESAFEOUT1", - .id = MAX8998_ESAFEOUT1, - .ops = &max8998_others_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - }, { - .name = "ESAFEOUT2", - .id = MAX8998_ESAFEOUT2, - .ops = &max8998_others_ops, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, +#define MAX8998_LINEAR_REG(_name, _ops, _min, _step, _max) \ + { \ + .name = #_name, \ + .id = MAX8998_##_name, \ + .ops = _ops, \ + .min_uV = (_min), \ + .uV_step = (_step), \ + .n_voltages = ((_max) - (_min)) / (_step) + 1, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ } + +#define MAX8998_OTHERS_REG(_name, _id) \ + { \ + .name = #_name, \ + .id = _id, \ + .ops = &max8998_others_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + } + +static const struct regulator_desc regulators[] = { + MAX8998_LINEAR_REG(LDO2, &max8998_ldo_ops, 800000, 50000, 1300000), + MAX8998_LINEAR_REG(LDO3, &max8998_ldo_ops, 800000, 50000, 1300000), + MAX8998_LINEAR_REG(LDO4, &max8998_ldo_ops, 1600000, 100000, 3600000), + MAX8998_LINEAR_REG(LDO5, &max8998_ldo_ops, 1600000, 100000, 3600000), + MAX8998_LINEAR_REG(LDO6, &max8998_ldo_ops, 1600000, 100000, 3600000), + MAX8998_LINEAR_REG(LDO7, &max8998_ldo_ops, 1600000, 100000, 3600000), + MAX8998_LINEAR_REG(LDO8, &max8998_ldo_ops, 3000000, 100000, 3600000), + MAX8998_LINEAR_REG(LDO9, &max8998_ldo_ops, 2800000, 100000, 3100000), + MAX8998_LINEAR_REG(LDO10, &max8998_ldo_ops, 950000, 50000, 1300000), + MAX8998_LINEAR_REG(LDO11, &max8998_ldo_ops, 1600000, 100000, 3600000), + MAX8998_LINEAR_REG(LDO12, &max8998_ldo_ops, 800000, 100000, 3300000), + MAX8998_LINEAR_REG(LDO13, &max8998_ldo_ops, 800000, 100000, 3300000), + MAX8998_LINEAR_REG(LDO14, &max8998_ldo_ops, 1200000, 100000, 3300000), + MAX8998_LINEAR_REG(LDO15, &max8998_ldo_ops, 1200000, 100000, 3300000), + MAX8998_LINEAR_REG(LDO16, &max8998_ldo_ops, 1600000, 100000, 3600000), + MAX8998_LINEAR_REG(LDO17, &max8998_ldo_ops, 1600000, 100000, 3600000), + MAX8998_LINEAR_REG(BUCK1, &max8998_buck_ops, 750000, 25000, 1525000), + MAX8998_LINEAR_REG(BUCK2, &max8998_buck_ops, 750000, 25000, 1525000), + MAX8998_LINEAR_REG(BUCK3, &max8998_buck_ops, 1600000, 100000, 3600000), + MAX8998_LINEAR_REG(BUCK4, &max8998_buck_ops, 800000, 100000, 2300000), + MAX8998_OTHERS_REG(EN32KHz-AP, MAX8998_EN32KHZ_AP), + MAX8998_OTHERS_REG(EN32KHz-CP, MAX8998_EN32KHZ_CP), + MAX8998_OTHERS_REG(ENVICHG, MAX8998_ENVICHG), + MAX8998_OTHERS_REG(ESAFEOUT1, MAX8998_ESAFEOUT1), + MAX8998_OTHERS_REG(ESAFEOUT2, MAX8998_ESAFEOUT2), }; static int max8998_pmic_dt_parse_dvs_gpio(struct max8998_dev *iodev, @@ -796,9 +622,11 @@ static int max8998_pmic_probe(struct platform_device *pdev) /* Set predefined values for BUCK1 registers */ for (v = 0; v < ARRAY_SIZE(pdata->buck1_voltage); ++v) { + int index = MAX8998_BUCK1 - MAX8998_LDO2; + i = 0; - while (buck12_voltage_map_desc.min + - buck12_voltage_map_desc.step*i + while (regulators[index].min_uV + + regulators[index].uV_step * i < pdata->buck1_voltage[v]) i++; @@ -824,9 +652,11 @@ static int max8998_pmic_probe(struct platform_device *pdev) /* Set predefined values for BUCK2 registers */ for (v = 0; v < ARRAY_SIZE(pdata->buck2_voltage); ++v) { + int index = MAX8998_BUCK2 - MAX8998_LDO2; + i = 0; - while (buck12_voltage_map_desc.min + - buck12_voltage_map_desc.step*i + while (regulators[index].min_uV + + regulators[index].uV_step * i < pdata->buck2_voltage[v]) i++; @@ -839,18 +669,7 @@ static int max8998_pmic_probe(struct platform_device *pdev) } for (i = 0; i < pdata->num_regulators; i++) { - const struct voltage_map_desc *desc; - int id = pdata->regulators[i].id; - int index = id - MAX8998_LDO2; - - desc = ldo_voltage_map[id]; - if (desc && regulators[index].ops != &max8998_others_ops) { - int count = (desc->max - desc->min) / desc->step + 1; - - regulators[index].n_voltages = count; - regulators[index].min_uV = desc->min; - regulators[index].uV_step = desc->step; - } + int index = pdata->regulators[i].id - MAX8998_LDO2; config.dev = max8998->dev; config.of_node = pdata->regulators[i].reg_node; @@ -867,7 +686,6 @@ static int max8998_pmic_probe(struct platform_device *pdev) } } - return 0; } diff --git a/drivers/regulator/mcp16502.c b/drivers/regulator/mcp16502.c index 3a8004abe044..e5a02711cb46 100644 --- a/drivers/regulator/mcp16502.c +++ b/drivers/regulator/mcp16502.c @@ -119,8 +119,6 @@ enum { * @lpm: LPM GPIO descriptor */ struct mcp16502 { - struct regulator_dev *rdev[NUM_REGULATORS]; - struct regmap *rmap; struct gpio_desc *lpm; }; @@ -179,13 +177,12 @@ static unsigned int mcp16502_get_mode(struct regulator_dev *rdev) { unsigned int val; int ret, reg; - struct mcp16502 *mcp = rdev_get_drvdata(rdev); reg = mcp16502_get_reg(rdev, MCP16502_OPMODE_ACTIVE); if (reg < 0) return reg; - ret = regmap_read(mcp->rmap, reg, &val); + ret = regmap_read(rdev->regmap, reg, &val); if (ret) return ret; @@ -211,7 +208,6 @@ static int _mcp16502_set_mode(struct regulator_dev *rdev, unsigned int mode, { int val; int reg; - struct mcp16502 *mcp = rdev_get_drvdata(rdev); reg = mcp16502_get_reg(rdev, op_mode); if (reg < 0) @@ -228,7 +224,7 @@ static int _mcp16502_set_mode(struct regulator_dev *rdev, unsigned int mode, return -EINVAL; } - reg = regmap_update_bits(mcp->rmap, reg, MCP16502_MODE, val); + reg = regmap_update_bits(rdev->regmap, reg, MCP16502_MODE, val); return reg; } @@ -247,9 +243,8 @@ static int mcp16502_get_status(struct regulator_dev *rdev) { int ret; unsigned int val; - struct mcp16502 *mcp = rdev_get_drvdata(rdev); - ret = regmap_read(mcp->rmap, MCP16502_STAT_BASE(rdev_get_id(rdev)), + ret = regmap_read(rdev->regmap, MCP16502_STAT_BASE(rdev_get_id(rdev)), &val); if (ret) return ret; @@ -290,7 +285,6 @@ static int mcp16502_suspend_get_target_reg(struct regulator_dev *rdev) */ static int mcp16502_set_suspend_voltage(struct regulator_dev *rdev, int uV) { - struct mcp16502 *mcp = rdev_get_drvdata(rdev); int sel = regulator_map_voltage_linear_range(rdev, uV, uV); int reg = mcp16502_suspend_get_target_reg(rdev); @@ -300,7 +294,7 @@ static int mcp16502_set_suspend_voltage(struct regulator_dev *rdev, int uV) if (reg < 0) return reg; - return regmap_update_bits(mcp->rmap, reg, MCP16502_VSEL, sel); + return regmap_update_bits(rdev->regmap, reg, MCP16502_VSEL, sel); } /* @@ -328,13 +322,12 @@ static int mcp16502_set_suspend_mode(struct regulator_dev *rdev, */ static int mcp16502_set_suspend_enable(struct regulator_dev *rdev) { - struct mcp16502 *mcp = rdev_get_drvdata(rdev); int reg = mcp16502_suspend_get_target_reg(rdev); if (reg < 0) return reg; - return regmap_update_bits(mcp->rmap, reg, MCP16502_EN, MCP16502_EN); + return regmap_update_bits(rdev->regmap, reg, MCP16502_EN, MCP16502_EN); } /* @@ -342,13 +335,12 @@ static int mcp16502_set_suspend_enable(struct regulator_dev *rdev) */ static int mcp16502_set_suspend_disable(struct regulator_dev *rdev) { - struct mcp16502 *mcp = rdev_get_drvdata(rdev); int reg = mcp16502_suspend_get_target_reg(rdev); if (reg < 0) return reg; - return regmap_update_bits(mcp->rmap, reg, MCP16502_EN, 0); + return regmap_update_bits(rdev->regmap, reg, MCP16502_EN, 0); } #endif /* CONFIG_SUSPEND */ @@ -435,36 +427,15 @@ static const struct regmap_config mcp16502_regmap_config = { .wr_table = &mcp16502_yes_reg_table, }; -/* - * set_up_regulators() - initialize all regulators - */ -static int setup_regulators(struct mcp16502 *mcp, struct device *dev, - struct regulator_config config) -{ - int i; - - for (i = 0; i < NUM_REGULATORS; i++) { - mcp->rdev[i] = devm_regulator_register(dev, - &mcp16502_desc[i], - &config); - if (IS_ERR(mcp->rdev[i])) { - dev_err(dev, - "failed to register %s regulator %ld\n", - mcp16502_desc[i].name, PTR_ERR(mcp->rdev[i])); - return PTR_ERR(mcp->rdev[i]); - } - } - - return 0; -} - static int mcp16502_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct regulator_config config = { }; + struct regulator_dev *rdev; struct device *dev; struct mcp16502 *mcp; - int ret = 0; + struct regmap *rmap; + int i, ret; dev = &client->dev; config.dev = dev; @@ -473,15 +444,15 @@ static int mcp16502_probe(struct i2c_client *client, if (!mcp) return -ENOMEM; - mcp->rmap = devm_regmap_init_i2c(client, &mcp16502_regmap_config); - if (IS_ERR(mcp->rmap)) { - ret = PTR_ERR(mcp->rmap); + rmap = devm_regmap_init_i2c(client, &mcp16502_regmap_config); + if (IS_ERR(rmap)) { + ret = PTR_ERR(rmap); dev_err(dev, "regmap init failed: %d\n", ret); return ret; } i2c_set_clientdata(client, mcp); - config.regmap = mcp->rmap; + config.regmap = rmap; config.driver_data = mcp; mcp->lpm = devm_gpiod_get(dev, "lpm", GPIOD_OUT_LOW); @@ -490,9 +461,15 @@ static int mcp16502_probe(struct i2c_client *client, return PTR_ERR(mcp->lpm); } - ret = setup_regulators(mcp, dev, config); - if (ret != 0) - return ret; + for (i = 0; i < NUM_REGULATORS; i++) { + rdev = devm_regulator_register(dev, &mcp16502_desc[i], &config); + if (IS_ERR(rdev)) { + dev_err(dev, + "failed to register %s regulator %ld\n", + mcp16502_desc[i].name, PTR_ERR(rdev)); + return PTR_ERR(rdev); + } + } mcp16502_gpio_set_mode(mcp, MCP16502_OPMODE_ACTIVE); diff --git a/drivers/regulator/mt6311-regulator.c b/drivers/regulator/mt6311-regulator.c index 01d69f43d2b0..af95449d3590 100644 --- a/drivers/regulator/mt6311-regulator.c +++ b/drivers/regulator/mt6311-regulator.c @@ -1,16 +1,7 @@ -/* - * Copyright (c) 2015 MediaTek Inc. - * Author: Henry Chen <henryc.chen@mediatek.com> - * - * 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 - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (c) 2015 MediaTek Inc. +// Author: Henry Chen <henryc.chen@mediatek.com> #include <linux/err.h> #include <linux/gpio.h> diff --git a/drivers/regulator/mt6311-regulator.h b/drivers/regulator/mt6311-regulator.h index 5218db46a798..4904d6751714 100644 --- a/drivers/regulator/mt6311-regulator.h +++ b/drivers/regulator/mt6311-regulator.h @@ -1,15 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2015 MediaTek Inc. * Author: Henry Chen <henryc.chen@mediatek.com> - * - * 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 - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __MT6311_REGULATOR_H__ diff --git a/drivers/regulator/mt6323-regulator.c b/drivers/regulator/mt6323-regulator.c index b7b9670f0979..893ea190788a 100644 --- a/drivers/regulator/mt6323-regulator.c +++ b/drivers/regulator/mt6323-regulator.c @@ -1,11 +1,7 @@ -/* - * Copyright (c) 2016 MediaTek Inc. - * Author: Chen Zhong <chen.zhong@mediatek.com> - * - * 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 - * published by the Free Software Foundation. - */ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (c) 2016 MediaTek Inc. +// Author: Chen Zhong <chen.zhong@mediatek.com> #include <linux/module.h> #include <linux/of.h> @@ -118,43 +114,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..b6aed090b5e0 100644 --- a/drivers/regulator/mt6380-regulator.c +++ b/drivers/regulator/mt6380-regulator.c @@ -1,16 +1,7 @@ -/* - * Copyright (c) 2017 MediaTek Inc. - * Author: Chenglin Xu <chenglin.xu@mediatek.com> - * - * 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 - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (c) 2017 MediaTek Inc. +// Author: Chenglin Xu <chenglin.xu@mediatek.com> #include <linux/module.h> #include <linux/of.h> @@ -173,19 +164,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..fd9ed864a0c1 100644 --- a/drivers/regulator/mt6397-regulator.c +++ b/drivers/regulator/mt6397-regulator.c @@ -1,16 +1,7 @@ -/* - * Copyright (c) 2014 MediaTek Inc. - * Author: Flora Fu <flora.fu@mediatek.com> - * - * 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 - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (c) 2014 MediaTek Inc. +// Author: Flora Fu <flora.fu@mediatek.com> #include <linux/module.h> #include <linux/of.h> @@ -123,35 +114,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/of_regulator.c b/drivers/regulator/of_regulator.c index 7b6bf3536271..6dca0ba044d8 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c @@ -371,8 +371,9 @@ int of_regulator_match(struct device *dev, struct device_node *node, } EXPORT_SYMBOL_GPL(of_regulator_match); -struct device_node *regulator_of_get_init_node(struct device *dev, - const struct regulator_desc *desc) +static struct +device_node *regulator_of_get_init_node(struct device *dev, + const struct regulator_desc *desc) { struct device_node *search, *child; const char *name; 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..3d3415839ba2 100644 --- a/drivers/regulator/pv88060-regulator.c +++ b/drivers/regulator/pv88060-regulator.c @@ -1,17 +1,7 @@ -/* - * pv88060-regulator.c - Regulator device driver for PV88060 - * Copyright (C) 2015 Powerventure Semiconductor Ltd. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// pv88060-regulator.c - Regulator device driver for PV88060 +// Copyright (C) 2015 Powerventure Semiconductor Ltd. #include <linux/err.h> #include <linux/i2c.h> @@ -244,9 +234,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 +253,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/pv88060-regulator.h b/drivers/regulator/pv88060-regulator.h index 02ca9203a172..d333dbf3be94 100644 --- a/drivers/regulator/pv88060-regulator.h +++ b/drivers/regulator/pv88060-regulator.h @@ -1,16 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * pv88060-regulator.h - Regulator definitions for PV88060 * Copyright (C) 2015 Powerventure Semiconductor Ltd. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __PV88060_REGISTERS_H__ diff --git a/drivers/regulator/pv88080-regulator.c b/drivers/regulator/pv88080-regulator.c index bdddacdbeb99..a444f68af1a8 100644 --- a/drivers/regulator/pv88080-regulator.c +++ b/drivers/regulator/pv88080-regulator.c @@ -1,17 +1,7 @@ -/* - * pv88080-regulator.c - Regulator device driver for PV88080 - * Copyright (C) 2016 Powerventure Semiconductor Ltd. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// pv88080-regulator.c - Regulator device driver for PV88080 +// Copyright (C) 2016 Powerventure Semiconductor Ltd. #include <linux/err.h> #include <linux/i2c.h> @@ -345,9 +335,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 +354,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/pv88080-regulator.h b/drivers/regulator/pv88080-regulator.h index ae25ff360e3d..7d7f8f11a75a 100644 --- a/drivers/regulator/pv88080-regulator.h +++ b/drivers/regulator/pv88080-regulator.h @@ -1,16 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * pv88080-regulator.h - Regulator definitions for PV88080 * Copyright (C) 2016 Powerventure Semiconductor Ltd. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __PV88080_REGISTERS_H__ diff --git a/drivers/regulator/pv88090-regulator.c b/drivers/regulator/pv88090-regulator.c index 6e97cc6df2ee..b1d0d97ae935 100644 --- a/drivers/regulator/pv88090-regulator.c +++ b/drivers/regulator/pv88090-regulator.c @@ -1,17 +1,7 @@ -/* - * pv88090-regulator.c - Regulator device driver for PV88090 - * Copyright (C) 2015 Powerventure Semiconductor Ltd. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// pv88090-regulator.c - Regulator device driver for PV88090 +// Copyright (C) 2015 Powerventure Semiconductor Ltd. #include <linux/err.h> #include <linux/i2c.h> @@ -237,9 +227,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 +246,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/pv88090-regulator.h b/drivers/regulator/pv88090-regulator.h index 62d9029277f4..f814ee52cff3 100644 --- a/drivers/regulator/pv88090-regulator.h +++ b/drivers/regulator/pv88090-regulator.h @@ -1,16 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * pv88090-regulator.h - Regulator definitions for PV88090 * Copyright (C) 2015 Powerventure Semiconductor Ltd. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __PV88090_REGISTERS_H__ diff --git a/drivers/regulator/rc5t583-regulator.c b/drivers/regulator/rc5t583-regulator.c index 2ec51af43673..9446653e7a89 100644 --- a/drivers/regulator/rc5t583-regulator.c +++ b/drivers/regulator/rc5t583-regulator.c @@ -47,18 +47,13 @@ struct rc5t583_regulator_info { struct regulator_desc desc; }; -struct rc5t583_regulator { - struct rc5t583_regulator_info *reg_info; - struct regulator_dev *rdev; -}; - static int rc5t583_regulator_enable_time(struct regulator_dev *rdev) { - struct rc5t583_regulator *reg = rdev_get_drvdata(rdev); + struct rc5t583_regulator_info *reg_info = rdev_get_drvdata(rdev); int vsel = regulator_get_voltage_sel_regmap(rdev); int curr_uV = regulator_list_voltage_linear(rdev, vsel); - return DIV_ROUND_UP(curr_uV, reg->reg_info->enable_uv_per_us); + return DIV_ROUND_UP(curr_uV, reg_info->enable_uv_per_us); } static const struct regulator_ops rc5t583_ops = { @@ -120,8 +115,6 @@ static int rc5t583_regulator_probe(struct platform_device *pdev) struct rc5t583 *rc5t583 = dev_get_drvdata(pdev->dev.parent); struct rc5t583_platform_data *pdata = dev_get_platdata(rc5t583->dev); struct regulator_config config = { }; - struct rc5t583_regulator *reg = NULL; - struct rc5t583_regulator *regs; struct regulator_dev *rdev; struct rc5t583_regulator_info *ri; int ret; @@ -132,18 +125,8 @@ static int rc5t583_regulator_probe(struct platform_device *pdev) return -ENODEV; } - regs = devm_kcalloc(&pdev->dev, - RC5T583_REGULATOR_MAX, - sizeof(struct rc5t583_regulator), - GFP_KERNEL); - if (!regs) - return -ENOMEM; - - for (id = 0; id < RC5T583_REGULATOR_MAX; ++id) { - reg = ®s[id]; ri = &rc5t583_reg_info[id]; - reg->reg_info = ri; if (ri->deepsleep_id == RC5T583_DS_NONE) goto skip_ext_pwr_config; @@ -163,7 +146,7 @@ static int rc5t583_regulator_probe(struct platform_device *pdev) skip_ext_pwr_config: config.dev = &pdev->dev; config.init_data = pdata->reg_init_data[id]; - config.driver_data = reg; + config.driver_data = ri; config.regmap = rc5t583->regmap; rdev = devm_regulator_register(&pdev->dev, &ri->desc, &config); @@ -172,9 +155,7 @@ skip_ext_pwr_config: ri->desc.name); return PTR_ERR(rdev); } - reg->rdev = rdev; } - platform_set_drvdata(pdev, regs); return 0; } diff --git a/drivers/regulator/rn5t618-regulator.c b/drivers/regulator/rn5t618-regulator.c index 790a4a73ea2c..a79c0c43b9f8 100644 --- a/drivers/regulator/rn5t618-regulator.c +++ b/drivers/regulator/rn5t618-regulator.c @@ -46,7 +46,7 @@ static const struct regulator_ops rn5t618_reg_ops = { .vsel_mask = (vmask), \ } -static struct regulator_desc rn5t567_regulators[] = { +static const struct regulator_desc rn5t567_regulators[] = { /* DCDC */ REG(DCDC1, DC1CTL, BIT(0), DC1DAC, 0xff, 600000, 3500000, 12500), REG(DCDC2, DC2CTL, BIT(0), DC2DAC, 0xff, 600000, 3500000, 12500), @@ -63,7 +63,7 @@ static struct regulator_desc rn5t567_regulators[] = { REG(LDORTC2, LDOEN2, BIT(5), LDORTC2DAC, 0x7f, 900000, 3500000, 25000), }; -static struct regulator_desc rn5t618_regulators[] = { +static const struct regulator_desc rn5t618_regulators[] = { /* DCDC */ REG(DCDC1, DC1CTL, BIT(0), DC1DAC, 0xff, 600000, 3500000, 12500), REG(DCDC2, DC2CTL, BIT(0), DC2DAC, 0xff, 600000, 3500000, 12500), @@ -79,7 +79,7 @@ static struct regulator_desc rn5t618_regulators[] = { REG(LDORTC2, LDOEN2, BIT(5), LDORTC2DAC, 0x7f, 900000, 3500000, 25000), }; -static struct regulator_desc rc5t619_regulators[] = { +static const struct regulator_desc rc5t619_regulators[] = { /* DCDC */ REG(DCDC1, DC1CTL, BIT(0), DC1DAC, 0xff, 600000, 3500000, 12500), REG(DCDC2, DC2CTL, BIT(0), DC2DAC, 0xff, 600000, 3500000, 12500), @@ -107,7 +107,7 @@ static int rn5t618_regulator_probe(struct platform_device *pdev) struct rn5t618 *rn5t618 = dev_get_drvdata(pdev->dev.parent); struct regulator_config config = { }; struct regulator_dev *rdev; - struct regulator_desc *regulators; + const struct regulator_desc *regulators; int i; int num_regulators = 0; diff --git a/drivers/regulator/s2mpa01.c b/drivers/regulator/s2mpa01.c index 58a1fe583a6c..51f7e8b74d8c 100644 --- a/drivers/regulator/s2mpa01.c +++ b/drivers/regulator/s2mpa01.c @@ -17,10 +17,7 @@ #include <linux/mfd/samsung/core.h> #include <linux/mfd/samsung/s2mpa01.h> -#define S2MPA01_REGULATOR_CNT ARRAY_SIZE(regulators) - struct s2mpa01_info { - struct of_regulator_match rdata[S2MPA01_REGULATOR_MAX]; int ramp_delay24; int ramp_delay3; int ramp_delay5; @@ -232,6 +229,8 @@ static const struct regulator_ops s2mpa01_buck_ops = { #define regulator_desc_ldo(num, step) { \ .name = "LDO"#num, \ + .of_match = of_match_ptr("LDO"#num), \ + .regulators_node = of_match_ptr("regulators"), \ .id = S2MPA01_LDO##num, \ .ops = &s2mpa01_ldo_ops, \ .type = REGULATOR_VOLTAGE, \ @@ -247,6 +246,8 @@ static const struct regulator_ops s2mpa01_buck_ops = { #define regulator_desc_buck1_4(num) { \ .name = "BUCK"#num, \ + .of_match = of_match_ptr("BUCK"#num), \ + .regulators_node = of_match_ptr("regulators"), \ .id = S2MPA01_BUCK##num, \ .ops = &s2mpa01_buck_ops, \ .type = REGULATOR_VOLTAGE, \ @@ -263,6 +264,8 @@ static const struct regulator_ops s2mpa01_buck_ops = { #define regulator_desc_buck5 { \ .name = "BUCK5", \ + .of_match = of_match_ptr("BUCK5"), \ + .regulators_node = of_match_ptr("regulators"), \ .id = S2MPA01_BUCK5, \ .ops = &s2mpa01_buck_ops, \ .type = REGULATOR_VOLTAGE, \ @@ -279,6 +282,8 @@ static const struct regulator_ops s2mpa01_buck_ops = { #define regulator_desc_buck6_10(num, min, step) { \ .name = "BUCK"#num, \ + .of_match = of_match_ptr("BUCK"#num), \ + .regulators_node = of_match_ptr("regulators"), \ .id = S2MPA01_BUCK##num, \ .ops = &s2mpa01_buck_ops, \ .type = REGULATOR_VOLTAGE, \ @@ -336,9 +341,7 @@ static int s2mpa01_pmic_probe(struct platform_device *pdev) { struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); struct sec_platform_data *pdata = dev_get_platdata(iodev->dev); - struct device_node *reg_np = NULL; struct regulator_config config = { }; - struct of_regulator_match *rdata; struct s2mpa01_info *s2mpa01; int i; @@ -346,39 +349,15 @@ static int s2mpa01_pmic_probe(struct platform_device *pdev) if (!s2mpa01) return -ENOMEM; - rdata = s2mpa01->rdata; - for (i = 0; i < S2MPA01_REGULATOR_CNT; i++) - rdata[i].name = regulators[i].name; - - if (iodev->dev->of_node) { - reg_np = of_get_child_by_name(iodev->dev->of_node, - "regulators"); - if (!reg_np) { - dev_err(&pdev->dev, - "could not find regulators sub-node\n"); - return -EINVAL; - } - - of_regulator_match(&pdev->dev, reg_np, rdata, - S2MPA01_REGULATOR_MAX); - of_node_put(reg_np); - } - - platform_set_drvdata(pdev, s2mpa01); - - config.dev = &pdev->dev; + config.dev = iodev->dev; config.regmap = iodev->regmap_pmic; config.driver_data = s2mpa01; for (i = 0; i < S2MPA01_REGULATOR_MAX; i++) { struct regulator_dev *rdev; + if (pdata) config.init_data = pdata->regulators[i].initdata; - else - config.init_data = rdata[i].init_data; - - if (reg_np) - config.of_node = rdata[i].of_node; rdev = devm_regulator_register(&pdev->dev, ®ulators[i], &config); diff --git a/drivers/regulator/sc2731-regulator.c b/drivers/regulator/sc2731-regulator.c index eb2bdf060b7b..0f21f95c8981 100644 --- a/drivers/regulator/sc2731-regulator.c +++ b/drivers/regulator/sc2731-regulator.c @@ -146,7 +146,7 @@ static const struct regulator_ops sc2731_regu_linear_ops = { .vsel_mask = vmask, \ } -static struct regulator_desc regulators[] = { +static const struct regulator_desc regulators[] = { SC2731_REGU_LINEAR(BUCK_CPU0, SC2731_POWER_PD_SW, SC2731_DCDC_CPU0_PD_MASK, SC2731_DCDC_CPU0_VOL, SC2731_DCDC_CPU0_VOL_MASK, 3125, 400000, 1996875), diff --git a/drivers/regulator/sky81452-regulator.c b/drivers/regulator/sky81452-regulator.c index 647860611916..177dede82a61 100644 --- a/drivers/regulator/sky81452-regulator.c +++ b/drivers/regulator/sky81452-regulator.c @@ -1,21 +1,9 @@ -/* - * sky81452-regulator.c SKY81452 regulator driver - * - * Copyright 2014 Skyworks Solutions Inc. - * Author : Gyungoh Yoo <jack.yoo@skyworksinc.com> - * - * 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 published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see <http://www.gnu.org/licenses/>. - */ +// SPDX-License-Identifier: GPL-2.0 +// +// sky81452-regulator.c SKY81452 regulator driver +// +// Copyright 2014 Skyworks Solutions Inc. +// Author : Gyungoh Yoo <jack.yoo@skyworksinc.com> #include <linux/module.h> #include <linux/kernel.h> @@ -34,7 +22,7 @@ #define SKY81452_LEN 0x40 #define SKY81452_LOUT 0x1F -static struct regulator_ops sky81452_reg_ops = { +static const struct regulator_ops sky81452_reg_ops = { .list_voltage = regulator_list_voltage_linear_range, .map_voltage = regulator_map_voltage_linear_range, .get_voltage_sel = regulator_get_voltage_sel_regmap, diff --git a/drivers/regulator/stm32-pwr.c b/drivers/regulator/stm32-pwr.c new file mode 100644 index 000000000000..e0e627b0106e --- /dev/null +++ b/drivers/regulator/stm32-pwr.c @@ -0,0 +1,186 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) STMicroelectronics 2019 +// Authors: Gabriel Fernandez <gabriel.fernandez@st.com> +// Pascal Paillet <p.paillet@st.com>. + +#include <linux/io.h> +#include <linux/iopoll.h> +#include <linux/module.h> +#include <linux/of_address.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> +#include <linux/regulator/driver.h> +#include <linux/regulator/of_regulator.h> + +/* + * Registers description + */ +#define REG_PWR_CR3 0x0C + +#define USB_3_3_EN BIT(24) +#define USB_3_3_RDY BIT(26) +#define REG_1_8_EN BIT(28) +#define REG_1_8_RDY BIT(29) +#define REG_1_1_EN BIT(30) +#define REG_1_1_RDY BIT(31) + +/* list of supported regulators */ +enum { + PWR_REG11, + PWR_REG18, + PWR_USB33, + STM32PWR_REG_NUM_REGS +}; + +static u32 ready_mask_table[STM32PWR_REG_NUM_REGS] = { + [PWR_REG11] = REG_1_1_RDY, + [PWR_REG18] = REG_1_8_RDY, + [PWR_USB33] = USB_3_3_RDY, +}; + +struct stm32_pwr_reg { + void __iomem *base; + u32 ready_mask; +}; + +static int stm32_pwr_reg_is_ready(struct regulator_dev *rdev) +{ + struct stm32_pwr_reg *priv = rdev_get_drvdata(rdev); + u32 val; + + val = readl_relaxed(priv->base + REG_PWR_CR3); + + return (val & priv->ready_mask); +} + +static int stm32_pwr_reg_is_enabled(struct regulator_dev *rdev) +{ + struct stm32_pwr_reg *priv = rdev_get_drvdata(rdev); + u32 val; + + val = readl_relaxed(priv->base + REG_PWR_CR3); + + return (val & rdev->desc->enable_mask); +} + +static int stm32_pwr_reg_enable(struct regulator_dev *rdev) +{ + struct stm32_pwr_reg *priv = rdev_get_drvdata(rdev); + int ret; + u32 val; + + val = readl_relaxed(priv->base + REG_PWR_CR3); + val |= rdev->desc->enable_mask; + writel_relaxed(val, priv->base + REG_PWR_CR3); + + /* use an arbitrary timeout of 20ms */ + ret = readx_poll_timeout(stm32_pwr_reg_is_ready, rdev, val, val, + 100, 20 * 1000); + if (ret) + dev_err(&rdev->dev, "regulator enable timed out!\n"); + + return ret; +} + +static int stm32_pwr_reg_disable(struct regulator_dev *rdev) +{ + struct stm32_pwr_reg *priv = rdev_get_drvdata(rdev); + int ret; + u32 val; + + val = readl_relaxed(priv->base + REG_PWR_CR3); + val &= ~rdev->desc->enable_mask; + writel_relaxed(val, priv->base + REG_PWR_CR3); + + /* use an arbitrary timeout of 20ms */ + ret = readx_poll_timeout(stm32_pwr_reg_is_ready, rdev, val, !val, + 100, 20 * 1000); + if (ret) + dev_err(&rdev->dev, "regulator disable timed out!\n"); + + return ret; +} + +static const struct regulator_ops stm32_pwr_reg_ops = { + .enable = stm32_pwr_reg_enable, + .disable = stm32_pwr_reg_disable, + .is_enabled = stm32_pwr_reg_is_enabled, +}; + +#define PWR_REG(_id, _name, _volt, _en, _supply) \ + [_id] = { \ + .id = _id, \ + .name = _name, \ + .of_match = of_match_ptr(_name), \ + .n_voltages = 1, \ + .type = REGULATOR_VOLTAGE, \ + .fixed_uV = _volt, \ + .ops = &stm32_pwr_reg_ops, \ + .enable_mask = _en, \ + .owner = THIS_MODULE, \ + .supply_name = _supply, \ + } \ + +static const struct regulator_desc stm32_pwr_desc[] = { + PWR_REG(PWR_REG11, "reg11", 1100000, REG_1_1_EN, "vdd"), + PWR_REG(PWR_REG18, "reg18", 1800000, REG_1_8_EN, "vdd"), + PWR_REG(PWR_USB33, "usb33", 3300000, USB_3_3_EN, "vdd_3v3_usbfs"), +}; + +static int stm32_pwr_regulator_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct stm32_pwr_reg *priv; + void __iomem *base; + struct regulator_dev *rdev; + struct regulator_config config = { }; + int i, ret = 0; + + base = of_iomap(np, 0); + if (!base) { + dev_err(&pdev->dev, "Unable to map IO memory\n"); + return -ENOMEM; + } + + config.dev = &pdev->dev; + + for (i = 0; i < STM32PWR_REG_NUM_REGS; i++) { + priv = devm_kzalloc(&pdev->dev, sizeof(struct stm32_pwr_reg), + GFP_KERNEL); + if (!priv) + return -ENOMEM; + priv->base = base; + priv->ready_mask = ready_mask_table[i]; + config.driver_data = priv; + + rdev = devm_regulator_register(&pdev->dev, + &stm32_pwr_desc[i], + &config); + if (IS_ERR(rdev)) { + ret = PTR_ERR(rdev); + dev_err(&pdev->dev, + "Failed to register regulator: %d\n", ret); + break; + } + } + return ret; +} + +static const struct of_device_id stm32_pwr_of_match[] = { + { .compatible = "st,stm32mp1,pwr-reg", }, + {}, +}; +MODULE_DEVICE_TABLE(of, stm32_pwr_of_match); + +static struct platform_driver stm32_pwr_driver = { + .probe = stm32_pwr_regulator_probe, + .driver = { + .name = "stm32-pwr-regulator", + .of_match_table = of_match_ptr(stm32_pwr_of_match), + }, +}; +module_platform_driver(stm32_pwr_driver); + +MODULE_DESCRIPTION("STM32MP1 PWR voltage regulator driver"); +MODULE_AUTHOR("Pascal Paillet <p.paillet@st.com>"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/regulator/sy8106a-regulator.c b/drivers/regulator/sy8106a-regulator.c index 65fbd1f0b612..42e03b2c10a0 100644 --- a/drivers/regulator/sy8106a-regulator.c +++ b/drivers/regulator/sy8106a-regulator.c @@ -22,12 +22,6 @@ */ #define SY8106A_GO_BIT BIT(7) -struct sy8106a { - struct regulator_dev *rdev; - struct regmap *regmap; - u32 fixed_voltage; -}; - static const struct regmap_config sy8106a_regmap_config = { .reg_bits = 8, .val_bits = 8, @@ -70,36 +64,32 @@ static const struct regulator_desc sy8106a_reg = { static int sy8106a_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { - struct sy8106a *chip; struct device *dev = &i2c->dev; - struct regulator_dev *rdev = NULL; + struct regulator_dev *rdev; struct regulator_config config = { }; + struct regmap *regmap; unsigned int reg, vsel; + u32 fixed_voltage; int error; - chip = devm_kzalloc(&i2c->dev, sizeof(struct sy8106a), GFP_KERNEL); - if (!chip) - return -ENOMEM; - error = of_property_read_u32(dev->of_node, "silergy,fixed-microvolt", - &chip->fixed_voltage); + &fixed_voltage); if (error) return error; - if (chip->fixed_voltage < SY8106A_MIN_MV * 1000 || - chip->fixed_voltage > SY8106A_MAX_MV * 1000) + if (fixed_voltage < SY8106A_MIN_MV * 1000 || + fixed_voltage > SY8106A_MAX_MV * 1000) return -EINVAL; - chip->regmap = devm_regmap_init_i2c(i2c, &sy8106a_regmap_config); - if (IS_ERR(chip->regmap)) { - error = PTR_ERR(chip->regmap); + regmap = devm_regmap_init_i2c(i2c, &sy8106a_regmap_config); + if (IS_ERR(regmap)) { + error = PTR_ERR(regmap); dev_err(dev, "Failed to allocate register map: %d\n", error); return error; } config.dev = &i2c->dev; - config.regmap = chip->regmap; - config.driver_data = chip; + config.regmap = regmap; config.of_node = dev->of_node; config.init_data = of_get_regulator_init_data(dev, dev->of_node, @@ -109,15 +99,15 @@ static int sy8106a_i2c_probe(struct i2c_client *i2c, return -ENOMEM; /* Ensure GO_BIT is enabled when probing */ - error = regmap_read(chip->regmap, SY8106A_REG_VOUT1_SEL, ®); + error = regmap_read(regmap, SY8106A_REG_VOUT1_SEL, ®); if (error) return error; if (!(reg & SY8106A_GO_BIT)) { - vsel = (chip->fixed_voltage / 1000 - SY8106A_MIN_MV) / + vsel = (fixed_voltage / 1000 - SY8106A_MIN_MV) / SY8106A_STEP_MV; - error = regmap_write(chip->regmap, SY8106A_REG_VOUT1_SEL, + error = regmap_write(regmap, SY8106A_REG_VOUT1_SEL, vsel | SY8106A_GO_BIT); if (error) return error; @@ -131,10 +121,6 @@ static int sy8106a_i2c_probe(struct i2c_client *i2c, return error; } - chip->rdev = rdev; - - i2c_set_clientdata(i2c, chip); - return 0; } diff --git a/drivers/regulator/tps6507x-regulator.c b/drivers/regulator/tps6507x-regulator.c index c179a3a221af..a1b7fab91dd4 100644 --- a/drivers/regulator/tps6507x-regulator.c +++ b/drivers/regulator/tps6507x-regulator.c @@ -115,7 +115,6 @@ static struct tps_info tps6507x_pmic_regs[] = { struct tps6507x_pmic { struct regulator_desc desc[TPS6507X_NUM_REGULATOR]; struct tps6507x_dev *mfd; - struct regulator_dev *rdev[TPS6507X_NUM_REGULATOR]; struct tps_info *info[TPS6507X_NUM_REGULATOR]; struct mutex io_lock; }; @@ -349,7 +348,7 @@ static int tps6507x_pmic_set_voltage_sel(struct regulator_dev *dev, return tps6507x_pmic_reg_write(tps, reg, data); } -static struct regulator_ops tps6507x_pmic_ops = { +static const struct regulator_ops tps6507x_pmic_ops = { .is_enabled = tps6507x_pmic_is_enabled, .enable = tps6507x_pmic_enable, .disable = tps6507x_pmic_disable, @@ -359,66 +358,20 @@ static struct regulator_ops tps6507x_pmic_ops = { .map_voltage = regulator_map_voltage_ascend, }; -static struct of_regulator_match tps6507x_matches[] = { - { .name = "VDCDC1"}, - { .name = "VDCDC2"}, - { .name = "VDCDC3"}, - { .name = "LDO1"}, - { .name = "LDO2"}, -}; - -static struct tps6507x_board *tps6507x_parse_dt_reg_data( - struct platform_device *pdev, - struct of_regulator_match **tps6507x_reg_matches) +static int tps6507x_pmic_of_parse_cb(struct device_node *np, + const struct regulator_desc *desc, + struct regulator_config *config) { - struct tps6507x_board *tps_board; - struct device_node *np = pdev->dev.parent->of_node; - struct device_node *regulators; - struct of_regulator_match *matches; - struct regulator_init_data *reg_data; - int idx = 0, count, ret; - - tps_board = devm_kzalloc(&pdev->dev, sizeof(*tps_board), - GFP_KERNEL); - if (!tps_board) - return NULL; - - regulators = of_get_child_by_name(np, "regulators"); - if (!regulators) { - dev_err(&pdev->dev, "regulator node not found\n"); - return NULL; - } - - count = ARRAY_SIZE(tps6507x_matches); - matches = tps6507x_matches; - - ret = of_regulator_match(&pdev->dev, regulators, matches, count); - of_node_put(regulators); - if (ret < 0) { - dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", - ret); - return NULL; - } + struct tps6507x_pmic *tps = config->driver_data; + struct tps_info *info = tps->info[desc->id]; + u32 prop; + int ret; - *tps6507x_reg_matches = matches; - - reg_data = devm_kzalloc(&pdev->dev, (sizeof(struct regulator_init_data) - * TPS6507X_NUM_REGULATOR), GFP_KERNEL); - if (!reg_data) - return NULL; - - tps_board->tps6507x_pmic_init_data = reg_data; - - for (idx = 0; idx < count; idx++) { - if (!matches[idx].init_data || !matches[idx].of_node) - continue; - - memcpy(®_data[idx], matches[idx].init_data, - sizeof(struct regulator_init_data)); - - } + ret = of_property_read_u32(np, "ti,defdcdc_default", &prop); + if (!ret) + info->defdcdc_default = prop; - return tps_board; + return 0; } static int tps6507x_pmic_probe(struct platform_device *pdev) @@ -426,14 +379,11 @@ static int tps6507x_pmic_probe(struct platform_device *pdev) struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent); struct tps_info *info = &tps6507x_pmic_regs[0]; struct regulator_config config = { }; - struct regulator_init_data *init_data; + struct regulator_init_data *init_data = NULL; struct regulator_dev *rdev; struct tps6507x_pmic *tps; struct tps6507x_board *tps_board; - struct of_regulator_match *tps6507x_reg_matches = NULL; int i; - int error; - unsigned int prop; /** * tps_board points to pmic related constants @@ -441,20 +391,8 @@ static int tps6507x_pmic_probe(struct platform_device *pdev) */ tps_board = dev_get_platdata(tps6507x_dev->dev); - if (IS_ENABLED(CONFIG_OF) && !tps_board && - tps6507x_dev->dev->of_node) - tps_board = tps6507x_parse_dt_reg_data(pdev, - &tps6507x_reg_matches); - if (!tps_board) - return -EINVAL; - - /** - * init_data points to array of regulator_init structures - * coming from the board-evm file. - */ - init_data = tps_board->tps6507x_pmic_init_data; - if (!init_data) - return -EINVAL; + if (tps_board) + init_data = tps_board->tps6507x_pmic_init_data; tps = devm_kzalloc(&pdev->dev, sizeof(*tps), GFP_KERNEL); if (!tps) @@ -468,13 +406,16 @@ static int tps6507x_pmic_probe(struct platform_device *pdev) for (i = 0; i < TPS6507X_NUM_REGULATOR; i++, info++, init_data++) { /* Register the regulators */ tps->info[i] = info; - if (init_data->driver_data) { + if (init_data && init_data->driver_data) { struct tps6507x_reg_platform_data *data = init_data->driver_data; - tps->info[i]->defdcdc_default = data->defdcdc_default; + info->defdcdc_default = data->defdcdc_default; } tps->desc[i].name = info->name; + tps->desc[i].of_match = of_match_ptr(info->name); + tps->desc[i].regulators_node = of_match_ptr("regulators"); + tps->desc[i].of_parse_cb = tps6507x_pmic_of_parse_cb; tps->desc[i].id = i; tps->desc[i].n_voltages = info->table_len; tps->desc[i].volt_table = info->table; @@ -486,17 +427,6 @@ static int tps6507x_pmic_probe(struct platform_device *pdev) config.init_data = init_data; config.driver_data = tps; - if (tps6507x_reg_matches) { - error = of_property_read_u32( - tps6507x_reg_matches[i].of_node, - "ti,defdcdc_default", &prop); - - if (!error) - tps->info[i]->defdcdc_default = prop; - - config.of_node = tps6507x_reg_matches[i].of_node; - } - rdev = devm_regulator_register(&pdev->dev, &tps->desc[i], &config); if (IS_ERR(rdev)) { @@ -505,9 +435,6 @@ static int tps6507x_pmic_probe(struct platform_device *pdev) pdev->name); return PTR_ERR(rdev); } - - /* Save regulator for cleanup */ - tps->rdev[i] = rdev; } tps6507x_dev->pmic = tps; diff --git a/drivers/regulator/tps65086-regulator.c b/drivers/regulator/tps65086-regulator.c index 45e96e154690..5a5e9b5bf4be 100644 --- a/drivers/regulator/tps65086-regulator.c +++ b/drivers/regulator/tps65086-regulator.c @@ -90,8 +90,8 @@ static const struct regulator_linear_range tps65086_buck345_25mv_ranges[] = { static const struct regulator_linear_range tps65086_ldoa1_ranges[] = { REGULATOR_LINEAR_RANGE(1350000, 0x0, 0x0, 0), REGULATOR_LINEAR_RANGE(1500000, 0x1, 0x7, 100000), - REGULATOR_LINEAR_RANGE(2300000, 0x8, 0xA, 100000), - REGULATOR_LINEAR_RANGE(2700000, 0xB, 0xD, 150000), + REGULATOR_LINEAR_RANGE(2300000, 0x8, 0xB, 100000), + REGULATOR_LINEAR_RANGE(2850000, 0xC, 0xD, 150000), REGULATOR_LINEAR_RANGE(3300000, 0xE, 0xE, 0), }; diff --git a/drivers/regulator/tps65132-regulator.c b/drivers/regulator/tps65132-regulator.c index 73978dd440f7..6e22f5ebba2e 100644 --- a/drivers/regulator/tps65132-regulator.c +++ b/drivers/regulator/tps65132-regulator.c @@ -55,10 +55,7 @@ struct tps65132_reg_pdata { struct tps65132_regulator { struct device *dev; - struct regmap *rmap; - struct regulator_desc *rdesc[TPS65132_MAX_REGULATORS]; struct tps65132_reg_pdata reg_pdata[TPS65132_MAX_REGULATORS]; - struct regulator_dev *rdev[TPS65132_MAX_REGULATORS]; }; static int tps65132_regulator_enable(struct regulator_dev *rdev) @@ -120,7 +117,7 @@ static int tps65132_regulator_is_enabled(struct regulator_dev *rdev) return 1; } -static struct regulator_ops tps65132_regulator_ops = { +static const struct regulator_ops tps65132_regulator_ops = { .enable = tps65132_regulator_enable, .disable = tps65132_regulator_disable, .is_enabled = tps65132_regulator_is_enabled, @@ -196,7 +193,7 @@ static int tps65132_of_parse_cb(struct device_node *np, .owner = THIS_MODULE, \ } -static struct regulator_desc tps_regs_desc[TPS65132_MAX_REGULATORS] = { +static const struct regulator_desc tps_regs_desc[TPS65132_MAX_REGULATORS] = { TPS65132_REGULATOR_DESC(VPOS, outp), TPS65132_REGULATOR_DESC(VNEG, outn), }; @@ -225,6 +222,8 @@ static int tps65132_probe(struct i2c_client *client, { struct device *dev = &client->dev; struct tps65132_regulator *tps; + struct regulator_dev *rdev; + struct regmap *rmap; struct regulator_config config = { }; int id; int ret; @@ -233,9 +232,9 @@ static int tps65132_probe(struct i2c_client *client, if (!tps) return -ENOMEM; - tps->rmap = devm_regmap_init_i2c(client, &tps65132_regmap_config); - if (IS_ERR(tps->rmap)) { - ret = PTR_ERR(tps->rmap); + rmap = devm_regmap_init_i2c(client, &tps65132_regmap_config); + if (IS_ERR(rmap)) { + ret = PTR_ERR(rmap); dev_err(dev, "regmap init failed: %d\n", ret); return ret; } @@ -244,18 +243,16 @@ static int tps65132_probe(struct i2c_client *client, tps->dev = dev; for (id = 0; id < TPS65132_MAX_REGULATORS; ++id) { - tps->rdesc[id] = &tps_regs_desc[id]; - - config.regmap = tps->rmap; + config.regmap = rmap; config.dev = dev; config.driver_data = tps; - tps->rdev[id] = devm_regulator_register(dev, - tps->rdesc[id], &config); - if (IS_ERR(tps->rdev[id])) { - ret = PTR_ERR(tps->rdev[id]); + rdev = devm_regulator_register(dev, &tps_regs_desc[id], + &config); + if (IS_ERR(rdev)) { + ret = PTR_ERR(rdev); dev_err(dev, "regulator %s register failed: %d\n", - tps->rdesc[id]->name, ret); + tps_regs_desc[id].name, ret); return ret; } } diff --git a/drivers/regulator/tps65217-regulator.c b/drivers/regulator/tps65217-regulator.c index d84fab616abf..67ba78da77ec 100644 --- a/drivers/regulator/tps65217-regulator.c +++ b/drivers/regulator/tps65217-regulator.c @@ -58,10 +58,9 @@ static const unsigned int LDO1_VSEL_table[] = { static const struct regulator_linear_range tps65217_uv1_ranges[] = { REGULATOR_LINEAR_RANGE(900000, 0, 24, 25000), - REGULATOR_LINEAR_RANGE(1550000, 25, 30, 50000), - REGULATOR_LINEAR_RANGE(1850000, 31, 52, 50000), + REGULATOR_LINEAR_RANGE(1550000, 25, 52, 50000), REGULATOR_LINEAR_RANGE(3000000, 53, 55, 100000), - REGULATOR_LINEAR_RANGE(3300000, 56, 62, 0), + REGULATOR_LINEAR_RANGE(3300000, 56, 63, 0), }; static const struct regulator_linear_range tps65217_uv2_ranges[] = { @@ -150,7 +149,7 @@ static int tps65217_pmic_set_suspend_disable(struct regulator_dev *dev) } /* Operations permitted on DCDCx, LDO2, LDO3 and LDO4 */ -static struct regulator_ops tps65217_pmic_ops = { +static const struct regulator_ops tps65217_pmic_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = tps65217_pmic_enable, .disable = tps65217_pmic_disable, @@ -163,7 +162,7 @@ static struct regulator_ops tps65217_pmic_ops = { }; /* Operations permitted on LDO1 */ -static struct regulator_ops tps65217_pmic_ldo1_ops = { +static const struct regulator_ops tps65217_pmic_ldo1_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = tps65217_pmic_enable, .disable = tps65217_pmic_disable, diff --git a/drivers/regulator/tps65218-regulator.c b/drivers/regulator/tps65218-regulator.c index 95708d34876b..b72035610013 100644 --- a/drivers/regulator/tps65218-regulator.c +++ b/drivers/regulator/tps65218-regulator.c @@ -29,7 +29,8 @@ #include <linux/mfd/tps65218.h> #define TPS65218_REGULATOR(_name, _of, _id, _type, _ops, _n, _vr, _vm, _er, \ - _em, _cr, _cm, _lr, _nlr, _delay, _fuv, _sr, _sm) \ + _em, _cr, _cm, _lr, _nlr, _delay, _fuv, _sr, _sm, \ + _ct, _ncl) \ { \ .name = _name, \ .of_match = _of, \ @@ -42,6 +43,8 @@ .vsel_mask = _vm, \ .csel_reg = _cr, \ .csel_mask = _cm, \ + .curr_table = _ct, \ + .n_current_limits = _ncl, \ .enable_reg = _er, \ .enable_mask = _em, \ .volt_table = NULL, \ @@ -162,7 +165,7 @@ static int tps65218_pmic_set_suspend_disable(struct regulator_dev *dev) } /* Operations permitted on DCDC1, DCDC2 */ -static struct regulator_ops tps65218_dcdc12_ops = { +static const struct regulator_ops tps65218_dcdc12_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = tps65218_pmic_enable, .disable = tps65218_pmic_disable, @@ -176,7 +179,7 @@ static struct regulator_ops tps65218_dcdc12_ops = { }; /* Operations permitted on DCDC3, DCDC4 and LDO1 */ -static struct regulator_ops tps65218_ldo1_dcdc34_ops = { +static const struct regulator_ops tps65218_ldo1_dcdc34_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = tps65218_pmic_enable, .disable = tps65218_pmic_disable, @@ -188,8 +191,7 @@ static struct regulator_ops tps65218_ldo1_dcdc34_ops = { .set_suspend_disable = tps65218_pmic_set_suspend_disable, }; -static const int ls3_currents[] = { 100000, 200000, 500000, 1000000 }; - +static const unsigned int ls3_currents[] = { 100000, 200000, 500000, 1000000 }; static int tps65218_pmic_set_input_current_lim(struct regulator_dev *dev, int lim_uA) @@ -229,33 +231,17 @@ static int tps65218_pmic_set_current_limit(struct regulator_dev *dev, TPS65218_PROTECT_L1); } -static int tps65218_pmic_get_current_limit(struct regulator_dev *dev) -{ - int retval; - unsigned int index; - struct tps65218 *tps = rdev_get_drvdata(dev); - - retval = regmap_read(tps->regmap, dev->desc->csel_reg, &index); - if (retval < 0) - return retval; - - index = (index & dev->desc->csel_mask) >> - __builtin_ctz(dev->desc->csel_mask); - - return ls3_currents[index]; -} - -static struct regulator_ops tps65218_ls23_ops = { +static const struct regulator_ops tps65218_ls23_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = tps65218_pmic_enable, .disable = tps65218_pmic_disable, .set_input_current_limit = tps65218_pmic_set_input_current_lim, .set_current_limit = tps65218_pmic_set_current_limit, - .get_current_limit = tps65218_pmic_get_current_limit, + .get_current_limit = regulator_get_current_limit_regmap, }; /* Operations permitted on DCDC5, DCDC6 */ -static struct regulator_ops tps65218_dcdc56_pmic_ops = { +static const struct regulator_ops tps65218_dcdc56_pmic_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = tps65218_pmic_enable, .disable = tps65218_pmic_disable, @@ -270,53 +256,57 @@ static const struct regulator_desc regulators[] = { TPS65218_CONTROL_DCDC1_MASK, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC1_EN, 0, 0, dcdc1_dcdc2_ranges, 2, 4000, 0, TPS65218_REG_SEQ3, - TPS65218_SEQ3_DC1_SEQ_MASK), + TPS65218_SEQ3_DC1_SEQ_MASK, NULL, 0), TPS65218_REGULATOR("DCDC2", "regulator-dcdc2", TPS65218_DCDC_2, REGULATOR_VOLTAGE, tps65218_dcdc12_ops, 64, TPS65218_REG_CONTROL_DCDC2, TPS65218_CONTROL_DCDC2_MASK, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC2_EN, 0, 0, dcdc1_dcdc2_ranges, 2, 4000, 0, TPS65218_REG_SEQ3, - TPS65218_SEQ3_DC2_SEQ_MASK), + TPS65218_SEQ3_DC2_SEQ_MASK, NULL, 0), TPS65218_REGULATOR("DCDC3", "regulator-dcdc3", TPS65218_DCDC_3, REGULATOR_VOLTAGE, tps65218_ldo1_dcdc34_ops, 64, TPS65218_REG_CONTROL_DCDC3, TPS65218_CONTROL_DCDC3_MASK, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC3_EN, 0, 0, ldo1_dcdc3_ranges, 2, - 0, 0, TPS65218_REG_SEQ4, TPS65218_SEQ4_DC3_SEQ_MASK), + 0, 0, TPS65218_REG_SEQ4, TPS65218_SEQ4_DC3_SEQ_MASK, + NULL, 0), TPS65218_REGULATOR("DCDC4", "regulator-dcdc4", TPS65218_DCDC_4, REGULATOR_VOLTAGE, tps65218_ldo1_dcdc34_ops, 53, TPS65218_REG_CONTROL_DCDC4, TPS65218_CONTROL_DCDC4_MASK, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC4_EN, 0, 0, dcdc4_ranges, 2, - 0, 0, TPS65218_REG_SEQ4, TPS65218_SEQ4_DC4_SEQ_MASK), + 0, 0, TPS65218_REG_SEQ4, TPS65218_SEQ4_DC4_SEQ_MASK, + NULL, 0), TPS65218_REGULATOR("DCDC5", "regulator-dcdc5", TPS65218_DCDC_5, REGULATOR_VOLTAGE, tps65218_dcdc56_pmic_ops, 1, -1, -1, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC5_EN, 0, 0, NULL, 0, 0, 1000000, TPS65218_REG_SEQ5, - TPS65218_SEQ5_DC5_SEQ_MASK), + TPS65218_SEQ5_DC5_SEQ_MASK, NULL, 0), TPS65218_REGULATOR("DCDC6", "regulator-dcdc6", TPS65218_DCDC_6, REGULATOR_VOLTAGE, tps65218_dcdc56_pmic_ops, 1, -1, -1, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC6_EN, 0, 0, NULL, 0, 0, 1800000, TPS65218_REG_SEQ5, - TPS65218_SEQ5_DC6_SEQ_MASK), + TPS65218_SEQ5_DC6_SEQ_MASK, NULL, 0), TPS65218_REGULATOR("LDO1", "regulator-ldo1", TPS65218_LDO_1, REGULATOR_VOLTAGE, tps65218_ldo1_dcdc34_ops, 64, TPS65218_REG_CONTROL_LDO1, TPS65218_CONTROL_LDO1_MASK, TPS65218_REG_ENABLE2, TPS65218_ENABLE2_LDO1_EN, 0, 0, ldo1_dcdc3_ranges, 2, 0, 0, TPS65218_REG_SEQ6, - TPS65218_SEQ6_LDO1_SEQ_MASK), + TPS65218_SEQ6_LDO1_SEQ_MASK, NULL, 0), TPS65218_REGULATOR("LS2", "regulator-ls2", TPS65218_LS_2, REGULATOR_CURRENT, tps65218_ls23_ops, 0, 0, 0, TPS65218_REG_ENABLE2, TPS65218_ENABLE2_LS2_EN, TPS65218_REG_CONFIG2, TPS65218_CONFIG2_LS2ILIM_MASK, - NULL, 0, 0, 0, 0, 0), + NULL, 0, 0, 0, 0, 0, ls3_currents, + ARRAY_SIZE(ls3_currents)), TPS65218_REGULATOR("LS3", "regulator-ls3", TPS65218_LS_3, REGULATOR_CURRENT, tps65218_ls23_ops, 0, 0, 0, TPS65218_REG_ENABLE2, TPS65218_ENABLE2_LS3_EN, TPS65218_REG_CONFIG2, TPS65218_CONFIG2_LS3ILIM_MASK, - NULL, 0, 0, 0, 0, 0), + NULL, 0, 0, 0, 0, 0, ls3_currents, + ARRAY_SIZE(ls3_currents)), }; static int tps65218_regulator_probe(struct platform_device *pdev) diff --git a/drivers/regulator/tps6524x-regulator.c b/drivers/regulator/tps6524x-regulator.c index 67cac2682f50..740aeccdfb1f 100644 --- a/drivers/regulator/tps6524x-regulator.c +++ b/drivers/regulator/tps6524x-regulator.c @@ -137,7 +137,6 @@ struct tps6524x { struct spi_device *spi; struct mutex lock; struct regulator_desc desc[N_REGULATORS]; - struct regulator_dev *rdev[N_REGULATORS]; }; static int __read_reg(struct tps6524x *hw, int reg) @@ -565,7 +564,7 @@ static int is_supply_enabled(struct regulator_dev *rdev) return read_field(hw, &info->enable); } -static struct regulator_ops regulator_ops = { +static const struct regulator_ops regulator_ops = { .is_enabled = is_supply_enabled, .enable = enable_supply, .disable = disable_supply, @@ -584,6 +583,7 @@ static int pmic_probe(struct spi_device *spi) const struct supply_info *info = supply_info; struct regulator_init_data *init_data; struct regulator_config config = { }; + struct regulator_dev *rdev; int i; init_data = dev_get_platdata(dev); @@ -616,10 +616,9 @@ static int pmic_probe(struct spi_device *spi) config.init_data = init_data; config.driver_data = hw; - hw->rdev[i] = devm_regulator_register(dev, &hw->desc[i], - &config); - if (IS_ERR(hw->rdev[i])) - return PTR_ERR(hw->rdev[i]); + rdev = devm_regulator_register(dev, &hw->desc[i], &config); + if (IS_ERR(rdev)) + return PTR_ERR(rdev); } return 0; diff --git a/drivers/regulator/tps80031-regulator.c b/drivers/regulator/tps80031-regulator.c index 1001147404c3..85a6a8ca8c1b 100644 --- a/drivers/regulator/tps80031-regulator.c +++ b/drivers/regulator/tps80031-regulator.c @@ -1,27 +1,13 @@ -/* - * tps80031-regulator.c -- TI TPS80031 regulator driver. - * - * Regulator driver for TI TPS80031/TPS80032 Fully Integrated Power - * Management with Power Path and Battery Charger. - * - * Copyright (c) 2012, NVIDIA Corporation. - * - * Author: Laxman Dewangan <ldewangan@nvidia.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation version 2. - * - * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, - * whether express or implied; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307, USA - */ +// SPDX-License-Identifier: GPL-2.0 +// +// tps80031-regulator.c -- TI TPS80031 regulator driver. +// +// Regulator driver for TI TPS80031/TPS80032 Fully Integrated Power +// Management with Power Path and Battery Charger. +// +// Copyright (c) 2012, NVIDIA Corporation. +// +// Author: Laxman Dewangan <ldewangan@nvidia.com> #include <linux/delay.h> #include <linux/err.h> @@ -85,7 +71,6 @@ struct tps80031_regulator_info { struct tps80031_regulator { struct device *dev; - struct regulator_dev *rdev; struct tps80031_regulator_info *rinfo; u8 device_flags; @@ -155,7 +140,7 @@ static int tps80031_reg_disable(struct regulator_dev *rdev) } /* DCDC voltages for the selector of 58 to 63 */ -static int tps80031_dcdc_voltages[4][5] = { +static const int tps80031_dcdc_voltages[4][5] = { { 1350, 1500, 1800, 1900, 2100}, { 1350, 1500, 1800, 1900, 2100}, { 2084, 2315, 2778, 2932, 3241}, @@ -378,7 +363,7 @@ static int tps80031_vbus_disable(struct regulator_dev *rdev) return ret; } -static struct regulator_ops tps80031_dcdc_ops = { +static const struct regulator_ops tps80031_dcdc_ops = { .list_voltage = tps80031_dcdc_list_voltage, .set_voltage_sel = tps80031_dcdc_set_voltage_sel, .get_voltage_sel = tps80031_dcdc_get_voltage_sel, @@ -387,7 +372,7 @@ static struct regulator_ops tps80031_dcdc_ops = { .is_enabled = tps80031_reg_is_enabled, }; -static struct regulator_ops tps80031_ldo_ops = { +static const struct regulator_ops tps80031_ldo_ops = { .list_voltage = tps80031_ldo_list_voltage, .map_voltage = tps80031_ldo_map_voltage, .set_voltage_sel = regulator_set_voltage_sel_regmap, @@ -397,18 +382,18 @@ static struct regulator_ops tps80031_ldo_ops = { .is_enabled = tps80031_reg_is_enabled, }; -static struct regulator_ops tps80031_vbus_sw_ops = { +static const struct regulator_ops tps80031_vbus_sw_ops = { .list_voltage = regulator_list_voltage_linear, .enable = tps80031_vbus_enable, .disable = tps80031_vbus_disable, .is_enabled = tps80031_vbus_is_enabled, }; -static struct regulator_ops tps80031_vbus_hw_ops = { +static const struct regulator_ops tps80031_vbus_hw_ops = { .list_voltage = regulator_list_voltage_linear, }; -static struct regulator_ops tps80031_ext_reg_ops = { +static const struct regulator_ops tps80031_ext_reg_ops = { .list_voltage = regulator_list_voltage_linear, .enable = tps80031_reg_enable, .disable = tps80031_reg_disable, @@ -736,7 +721,6 @@ static int tps80031_regulator_probe(struct platform_device *pdev) ri->rinfo->desc.name); return PTR_ERR(rdev); } - ri->rdev = rdev; } platform_set_drvdata(pdev, pmic); diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index 402ea43c77d1..cdd81e1985ff 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c @@ -392,7 +392,7 @@ static int twl4030ldo_get_voltage_sel(struct regulator_dev *rdev) return vsel; } -static struct regulator_ops twl4030ldo_ops = { +static const struct regulator_ops twl4030ldo_ops = { .list_voltage = twl4030ldo_list_voltage, .set_voltage_sel = twl4030ldo_set_voltage_sel, @@ -430,14 +430,14 @@ static int twl4030smps_get_voltage(struct regulator_dev *rdev) return vsel * 12500 + 600000; } -static struct regulator_ops twl4030smps_ops = { +static const struct regulator_ops twl4030smps_ops = { .set_voltage = twl4030smps_set_voltage, .get_voltage = twl4030smps_get_voltage, }; /*----------------------------------------------------------------------*/ -static struct regulator_ops twl4030fixed_ops = { +static const struct regulator_ops twl4030fixed_ops = { .list_voltage = regulator_list_voltage_linear, .enable = twl4030reg_enable, diff --git a/drivers/regulator/vctrl-regulator.c b/drivers/regulator/vctrl-regulator.c index 78de002037c7..259864520a06 100644 --- a/drivers/regulator/vctrl-regulator.c +++ b/drivers/regulator/vctrl-regulator.c @@ -334,10 +334,8 @@ static int vctrl_init_vtable(struct platform_device *pdev) ctrl_uV = regulator_list_voltage(ctrl_reg, i); if (ctrl_uV < vrange_ctrl->min_uV || - ctrl_uV > vrange_ctrl->max_uV) { + ctrl_uV > vrange_ctrl->max_uV) rdesc->n_voltages--; - continue; - } } if (rdesc->n_voltages == 0) { diff --git a/drivers/regulator/vexpress-regulator.c b/drivers/regulator/vexpress-regulator.c index c810cbbd463f..1235f46e633e 100644 --- a/drivers/regulator/vexpress-regulator.c +++ b/drivers/regulator/vexpress-regulator.c @@ -1,15 +1,6 @@ -/* - * 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 - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * Copyright (C) 2012 ARM Limited - */ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (C) 2012 ARM Limited #define DRVNAME "vexpress-regulator" #define pr_fmt(fmt) DRVNAME ": " fmt @@ -23,17 +14,10 @@ #include <linux/regulator/of_regulator.h> #include <linux/vexpress.h> -struct vexpress_regulator { - struct regulator_desc desc; - struct regulator_dev *regdev; - struct regmap *regmap; -}; - static int vexpress_regulator_get_voltage(struct regulator_dev *regdev) { - struct vexpress_regulator *reg = rdev_get_drvdata(regdev); - u32 uV; - int err = regmap_read(reg->regmap, 0, &uV); + unsigned int uV; + int err = regmap_read(regdev->regmap, 0, &uV); return err ? err : uV; } @@ -41,60 +25,58 @@ static int vexpress_regulator_get_voltage(struct regulator_dev *regdev) static int vexpress_regulator_set_voltage(struct regulator_dev *regdev, int min_uV, int max_uV, unsigned *selector) { - struct vexpress_regulator *reg = rdev_get_drvdata(regdev); - - return regmap_write(reg->regmap, 0, min_uV); + return regmap_write(regdev->regmap, 0, min_uV); } -static struct regulator_ops vexpress_regulator_ops_ro = { +static const struct regulator_ops vexpress_regulator_ops_ro = { .get_voltage = vexpress_regulator_get_voltage, }; -static struct regulator_ops vexpress_regulator_ops = { +static const struct regulator_ops vexpress_regulator_ops = { .get_voltage = vexpress_regulator_get_voltage, .set_voltage = vexpress_regulator_set_voltage, }; static int vexpress_regulator_probe(struct platform_device *pdev) { - struct vexpress_regulator *reg; + struct regulator_desc *desc; struct regulator_init_data *init_data; struct regulator_config config = { }; + struct regulator_dev *rdev; + struct regmap *regmap; - reg = devm_kzalloc(&pdev->dev, sizeof(*reg), GFP_KERNEL); - if (!reg) + desc = devm_kzalloc(&pdev->dev, sizeof(*desc), GFP_KERNEL); + if (!desc) return -ENOMEM; - reg->regmap = devm_regmap_init_vexpress_config(&pdev->dev); - if (IS_ERR(reg->regmap)) - return PTR_ERR(reg->regmap); + regmap = devm_regmap_init_vexpress_config(&pdev->dev); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); - reg->desc.name = dev_name(&pdev->dev); - reg->desc.type = REGULATOR_VOLTAGE; - reg->desc.owner = THIS_MODULE; - reg->desc.continuous_voltage_range = true; + desc->name = dev_name(&pdev->dev); + desc->type = REGULATOR_VOLTAGE; + desc->owner = THIS_MODULE; + desc->continuous_voltage_range = true; init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node, - ®->desc); + desc); if (!init_data) return -EINVAL; init_data->constraints.apply_uV = 0; if (init_data->constraints.min_uV && init_data->constraints.max_uV) - reg->desc.ops = &vexpress_regulator_ops; + desc->ops = &vexpress_regulator_ops; else - reg->desc.ops = &vexpress_regulator_ops_ro; + desc->ops = &vexpress_regulator_ops_ro; + config.regmap = regmap; config.dev = &pdev->dev; config.init_data = init_data; - config.driver_data = reg; config.of_node = pdev->dev.of_node; - reg->regdev = devm_regulator_register(&pdev->dev, ®->desc, &config); - if (IS_ERR(reg->regdev)) - return PTR_ERR(reg->regdev); - - platform_set_drvdata(pdev, reg); + rdev = devm_regulator_register(&pdev->dev, desc, &config); + if (IS_ERR(rdev)) + return PTR_ERR(rdev); return 0; } diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c index 12b422373580..b422eef97b77 100644 --- a/drivers/regulator/wm831x-dcdc.c +++ b/drivers/regulator/wm831x-dcdc.c @@ -1,15 +1,10 @@ -/* - * wm831x-dcdc.c -- DC-DC buck convertor driver for the WM831x series - * - * Copyright 2009 Wolfson Microelectronics PLC. - * - * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// wm831x-dcdc.c -- DC-DC buck converter driver for the WM831x series +// +// Copyright 2009 Wolfson Microelectronics PLC. +// +// Author: Mark Brown <broonie@opensource.wolfsonmicro.com> #include <linux/module.h> #include <linux/moduleparam.h> @@ -183,9 +178,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 +191,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..ff3d2bf50410 100644 --- a/drivers/regulator/wm831x-isink.c +++ b/drivers/regulator/wm831x-isink.c @@ -1,15 +1,10 @@ -/* - * wm831x-isink.c -- Current sink driver for the WM831x series - * - * Copyright 2009 Wolfson Microelectronics PLC. - * - * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// wm831x-isink.c -- Current sink driver for the WM831x series +// +// Copyright 2009 Wolfson Microelectronics PLC. +// +// Author: Mark Brown <broonie@opensource.wolfsonmicro.com> #include <linux/module.h> #include <linux/moduleparam.h> @@ -92,57 +87,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 +148,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..56754686c982 100644 --- a/drivers/regulator/wm831x-ldo.c +++ b/drivers/regulator/wm831x-ldo.c @@ -1,15 +1,10 @@ -/* - * wm831x-ldo.c -- LDO driver for the WM831x series - * - * Copyright 2009 Wolfson Microelectronics PLC. - * - * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// wm831x-ldo.c -- LDO driver for the WM831x series +// +// Copyright 2009 Wolfson Microelectronics PLC. +// +// Author: Mark Brown <broonie@opensource.wolfsonmicro.com> #include <linux/module.h> #include <linux/moduleparam.h> @@ -51,9 +46,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..56d6168a888d 100644 --- a/drivers/regulator/wm8350-regulator.c +++ b/drivers/regulator/wm8350-regulator.c @@ -1,16 +1,11 @@ -/* - * wm8350.c -- Voltage and current regulation for the Wolfson WM8350 PMIC - * - * Copyright 2007, 2008 Wolfson Microelectronics PLC. - * - * Author: Liam Girdwood - * linux@wolfsonmicro.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// wm8350.c -- Voltage and current regulation for the Wolfson WM8350 PMIC +// +// Copyright 2007, 2008 Wolfson Microelectronics PLC. +// +// Author: Liam Girdwood +// linux@wolfsonmicro.com #include <linux/module.h> #include <linux/moduleparam.h> @@ -28,7 +23,7 @@ #define WM8350_DCDC_MAX_VSEL 0x66 /* Microamps */ -static const int isink_cur[] = { +static const unsigned int isink_cur[] = { 4, 5, 6, @@ -95,73 +90,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 +910,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 +1066,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 +1078,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..6f331b51e479 100644 --- a/drivers/regulator/wm8400-regulator.c +++ b/drivers/regulator/wm8400-regulator.c @@ -1,16 +1,10 @@ -/* - * Regulator support for WM8400 - * - * Copyright 2008 Wolfson Microelectronics PLC. - * - * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// Regulator support for WM8400 +// +// Copyright 2008 Wolfson Microelectronics PLC. +// +// Author: Mark Brown <broonie@opensource.wolfsonmicro.com> #include <linux/bug.h> #include <linux/err.h> @@ -36,13 +30,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 +56,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 +188,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/drivers/regulator/wm8994-regulator.c b/drivers/regulator/wm8994-regulator.c index 38928cdcb6e6..cadea0344486 100644 --- a/drivers/regulator/wm8994-regulator.c +++ b/drivers/regulator/wm8994-regulator.c @@ -1,15 +1,10 @@ -/* - * wm8994-regulator.c -- Regulator driver for the WM8994 - * - * Copyright 2009 Wolfson Microelectronics PLC. - * - * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// wm8994-regulator.c -- Regulator driver for the WM8994 +// +// Copyright 2009 Wolfson Microelectronics PLC. +// +// Author: Mark Brown <broonie@opensource.wolfsonmicro.com> #include <linux/module.h> #include <linux/moduleparam.h> |