From 0eddcf0267f913cb6336af64cadaf5acf6b19b7b Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Wed, 29 Jul 2020 13:09:13 +0800 Subject: regulator: mp886x: implement set_ramp_delay Implement the .set_ramp_delay for MP8867 and MP8869. MP8867 and MP8869 could share the implementation, the only difference is the slew_rates array. Signed-off-by: Jisheng Zhang Link: https://lore.kernel.org/r/20200729130913.3ac38b32@xhacker Signed-off-by: Mark Brown --- drivers/regulator/mp886x.c | 67 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 64 insertions(+), 3 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/mp886x.c b/drivers/regulator/mp886x.c index d3d475f717f4..1305bf217df1 100644 --- a/drivers/regulator/mp886x.c +++ b/drivers/regulator/mp886x.c @@ -18,18 +18,48 @@ #define MP886X_V_BOOT (1 << 7) #define MP886X_SYSCNTLREG1 0x01 #define MP886X_MODE (1 << 0) +#define MP886X_SLEW_SHIFT 3 +#define MP886X_SLEW_MASK (0x7 << MP886X_SLEW_SHIFT) #define MP886X_GO (1 << 6) #define MP886X_EN (1 << 7) +struct mp886x_cfg_info { + const struct regulator_ops *rops; + const int slew_rates[8]; +}; + struct mp886x_device_info { struct device *dev; struct regulator_desc desc; struct regulator_init_data *regulator; struct gpio_desc *en_gpio; + const struct mp886x_cfg_info *ci; u32 r[2]; unsigned int sel; }; +static int mp886x_set_ramp(struct regulator_dev *rdev, int ramp) +{ + struct mp886x_device_info *di = rdev_get_drvdata(rdev); + const struct mp886x_cfg_info *ci = di->ci; + int reg = -1, i; + + for (i = 0; i < ARRAY_SIZE(ci->slew_rates); i++) { + if (ramp <= ci->slew_rates[i]) + reg = i; + else + break; + } + + if (reg < 0) { + dev_err(di->dev, "unsupported ramp value %d\n", ramp); + return -EINVAL; + } + + return regmap_update_bits(rdev->regmap, MP886X_SYSCNTLREG1, + MP886X_SLEW_MASK, reg << MP886X_SLEW_SHIFT); +} + static int mp886x_set_mode(struct regulator_dev *rdev, unsigned int mode) { switch (mode) { @@ -117,6 +147,21 @@ static const struct regulator_ops mp8869_regulator_ops = { .is_enabled = regulator_is_enabled_regmap, .set_mode = mp886x_set_mode, .get_mode = mp886x_get_mode, + .set_ramp_delay = mp886x_set_ramp, +}; + +static const struct mp886x_cfg_info mp8869_ci = { + .rops = &mp8869_regulator_ops, + .slew_rates = { + 40000, + 30000, + 20000, + 10000, + 5000, + 2500, + 1250, + 625, + }, }; static int mp8867_set_voltage_sel(struct regulator_dev *rdev, unsigned int sel) @@ -173,6 +218,21 @@ static const struct regulator_ops mp8867_regulator_ops = { .is_enabled = regulator_is_enabled_regmap, .set_mode = mp886x_set_mode, .get_mode = mp886x_get_mode, + .set_ramp_delay = mp886x_set_ramp, +}; + +static const struct mp886x_cfg_info mp8867_ci = { + .rops = &mp8867_regulator_ops, + .slew_rates = { + 64000, + 32000, + 16000, + 8000, + 4000, + 2000, + 1000, + 500, + }, }; static int mp886x_regulator_register(struct mp886x_device_info *di, @@ -183,7 +243,7 @@ static int mp886x_regulator_register(struct mp886x_device_info *di, rdesc->name = "mp886x-reg"; rdesc->supply_name = "vin"; - rdesc->ops = of_device_get_match_data(di->dev); + rdesc->ops = di->ci->rops; rdesc->type = REGULATOR_VOLTAGE; rdesc->n_voltages = 128; rdesc->enable_reg = MP886X_SYSCNTLREG1; @@ -234,6 +294,7 @@ static int mp886x_i2c_probe(struct i2c_client *client) if (IS_ERR(di->en_gpio)) return PTR_ERR(di->en_gpio); + di->ci = of_device_get_match_data(dev); di->dev = dev; regmap = devm_regmap_init_i2c(client, &mp886x_regmap_config); @@ -258,11 +319,11 @@ static int mp886x_i2c_probe(struct i2c_client *client) static const struct of_device_id mp886x_dt_ids[] = { { .compatible = "mps,mp8867", - .data = &mp8867_regulator_ops + .data = &mp8867_ci }, { .compatible = "mps,mp8869", - .data = &mp8869_regulator_ops + .data = &mp8869_ci }, { } }; -- cgit v1.2.3 From ee6ad5a24575071b66bd37ffb2d8747a64fcb45f Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Wed, 29 Jul 2020 13:10:23 +0800 Subject: regulator: mp886x: support setting switch freq Both MP8867 and MP8869 support different switch frequency. Signed-off-by: Jisheng Zhang Link: https://lore.kernel.org/r/20200729131023.77cc1dd2@xhacker Signed-off-by: Mark Brown --- drivers/regulator/mp886x.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'drivers/regulator') diff --git a/drivers/regulator/mp886x.c b/drivers/regulator/mp886x.c index 1305bf217df1..97dc44c0d663 100644 --- a/drivers/regulator/mp886x.c +++ b/drivers/regulator/mp886x.c @@ -22,10 +22,14 @@ #define MP886X_SLEW_MASK (0x7 << MP886X_SLEW_SHIFT) #define MP886X_GO (1 << 6) #define MP886X_EN (1 << 7) +#define MP8869_SYSCNTLREG2 0x02 struct mp886x_cfg_info { const struct regulator_ops *rops; const int slew_rates[8]; + const int switch_freq[4]; + const u8 fs_reg; + const u8 fs_shift; }; struct mp886x_device_info { @@ -60,6 +64,24 @@ static int mp886x_set_ramp(struct regulator_dev *rdev, int ramp) MP886X_SLEW_MASK, reg << MP886X_SLEW_SHIFT); } +static void mp886x_set_switch_freq(struct mp886x_device_info *di, + struct regmap *regmap, + u32 freq) +{ + const struct mp886x_cfg_info *ci = di->ci; + int i; + + for (i = 0; i < ARRAY_SIZE(ci->switch_freq); i++) { + if (freq == ci->switch_freq[i]) { + regmap_update_bits(regmap, ci->fs_reg, + 0x3 << ci->fs_shift, i << ci->fs_shift); + return; + } + } + + dev_err(di->dev, "invalid frequency %d\n", freq); +} + static int mp886x_set_mode(struct regulator_dev *rdev, unsigned int mode) { switch (mode) { @@ -162,6 +184,14 @@ static const struct mp886x_cfg_info mp8869_ci = { 1250, 625, }, + .switch_freq = { + 500000, + 750000, + 1000000, + 1250000, + }, + .fs_reg = MP8869_SYSCNTLREG2, + .fs_shift = 4, }; static int mp8867_set_voltage_sel(struct regulator_dev *rdev, unsigned int sel) @@ -233,6 +263,14 @@ static const struct mp886x_cfg_info mp8867_ci = { 1000, 500, }, + .switch_freq = { + 500000, + 750000, + 1000000, + 1500000, + }, + .fs_reg = MP886X_SYSCNTLREG1, + .fs_shift = 1, }; static int mp886x_regulator_register(struct mp886x_device_info *di, @@ -273,6 +311,7 @@ static int mp886x_i2c_probe(struct i2c_client *client) struct mp886x_device_info *di; struct regulator_config config = { }; struct regmap *regmap; + u32 freq; int ret; di = devm_kzalloc(dev, sizeof(struct mp886x_device_info), GFP_KERNEL); @@ -310,6 +349,9 @@ static int mp886x_i2c_probe(struct i2c_client *client) config.driver_data = di; config.of_node = np; + if (!of_property_read_u32(np, "mps,switch-frequency", &freq)) + mp886x_set_switch_freq(di, regmap, freq); + ret = mp886x_regulator_register(di, &config); if (ret < 0) dev_err(dev, "Failed to register regulator!\n"); -- cgit v1.2.3 From 5bbbfc7f7f0a44b7a85ab3872dd2ccce7019f7b1 Mon Sep 17 00:00:00 2001 From: ChiYuan Huang Date: Sat, 15 Aug 2020 11:14:20 +0800 Subject: regulator: rt4801: Add support for RT4801 Display Bias regulator driver Adds support for the RT4801 DSV. It has two regulators (DSVP/DSVN) with an I2C interface. DSVP/DSVN can provide the display panel module for the positive/negative voltage range from (+/-)4V to (+/-)6V. Signed-off-by: ChiYuan Huang Link: https://lore.kernel.org/r/1597461262-25878-1-git-send-email-u0084500@gmail.com Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 7 ++ drivers/regulator/Makefile | 1 + drivers/regulator/rt4801-regulator.c | 223 +++++++++++++++++++++++++++++++++++ 3 files changed, 231 insertions(+) create mode 100644 drivers/regulator/rt4801-regulator.c (limited to 'drivers/regulator') diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index de17ef7e18f0..2786f11cc91e 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -894,6 +894,13 @@ config REGULATOR_RN5T618 config REGULATOR_ROHM tristate +config REGULATOR_RT4801 + tristate "Richtek RT4801 Regulators" + depends on I2C + help + This adds support for voltage regulators in Richtek RT4801 Display Bias IC. + The device supports two regulators (DSVP/DSVN). + config REGULATOR_RT5033 tristate "Richtek RT5033 Regulators" depends on MFD_RT5033 diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index d8d3ecf526a8..d091e52db25d 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -111,6 +111,7 @@ obj-$(CONFIG_REGULATOR_RC5T583) += rc5t583-regulator.o obj-$(CONFIG_REGULATOR_RK808) += rk808-regulator.o obj-$(CONFIG_REGULATOR_RN5T618) += rn5t618-regulator.o obj-$(CONFIG_REGULATOR_ROHM) += rohm-regulator.o +obj-$(CONFIG_REGULATOR_RT4801) += rt4801-regulator.o obj-$(CONFIG_REGULATOR_RT5033) += rt5033-regulator.o obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o diff --git a/drivers/regulator/rt4801-regulator.c b/drivers/regulator/rt4801-regulator.c new file mode 100644 index 000000000000..0ddc670a3888 --- /dev/null +++ b/drivers/regulator/rt4801-regulator.c @@ -0,0 +1,223 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include +#include +#include +#include +#include +#include +#include + +#define RT4801_REG_VOP 0x00 +#define RT4801_REG_VON 0x01 +#define RT4801_REG_APPS 0x03 + +#define VOUT_MASK 0x1F + +#define MIN_UV 4000000 +#define STEP_UV 100000 +#define MAX_UV 6000000 +#define N_VOLTAGES ((MAX_UV - MIN_UV) / STEP_UV + 1) + +#define DSV_OUT_POS 0 +#define DSV_OUT_NEG 1 +#define DSV_OUT_MAX 2 + +#define DSVP_ENABLE BIT(0) +#define DSVN_ENABLE BIT(1) +#define DSVALL_ENABLE (DSVP_ENABLE | DSVN_ENABLE) + +struct rt4801_priv { + struct device *dev; + struct gpio_descs *enable_gpios; + unsigned int enable_flag; + unsigned int volt_sel[DSV_OUT_MAX]; +}; + +static int rt4801_set_voltage_sel(struct regulator_dev *rdev, unsigned int selector) +{ + struct rt4801_priv *priv = rdev_get_drvdata(rdev); + int id = rdev_get_id(rdev), ret; + + if (priv->enable_flag & BIT(id)) { + ret = regulator_set_voltage_sel_regmap(rdev, selector); + if (ret) + return ret; + } + + priv->volt_sel[id] = selector; + return 0; +} + +static int rt4801_get_voltage_sel(struct regulator_dev *rdev) +{ + struct rt4801_priv *priv = rdev_get_drvdata(rdev); + int id = rdev_get_id(rdev); + + if (priv->enable_flag & BIT(id)) + return regulator_get_voltage_sel_regmap(rdev); + + return priv->volt_sel[id]; +} + +static int rt4801_enable(struct regulator_dev *rdev) +{ + struct rt4801_priv *priv = rdev_get_drvdata(rdev); + struct gpio_descs *gpios = priv->enable_gpios; + int id = rdev_get_id(rdev), ret; + + if (gpios->ndescs <= id) { + dev_warn(&rdev->dev, "no dedicated gpio can control\n"); + goto bypass_gpio; + } + + gpiod_set_value(gpios->desc[id], 1); + +bypass_gpio: + ret = regmap_write(rdev->regmap, rdev->desc->vsel_reg, priv->volt_sel[id]); + if (ret) + return ret; + + priv->enable_flag |= BIT(id); + return 0; +} + +static int rt4801_disable(struct regulator_dev *rdev) +{ + struct rt4801_priv *priv = rdev_get_drvdata(rdev); + struct gpio_descs *gpios = priv->enable_gpios; + int id = rdev_get_id(rdev); + + if (gpios->ndescs <= id) { + dev_warn(&rdev->dev, "no dedicated gpio can control\n"); + goto bypass_gpio; + } + + gpiod_set_value(gpios->desc[id], 0); + +bypass_gpio: + priv->enable_flag &= ~BIT(id); + return 0; +} + +static int rt4801_is_enabled(struct regulator_dev *rdev) +{ + struct rt4801_priv *priv = rdev_get_drvdata(rdev); + int id = rdev_get_id(rdev); + + return !!(priv->enable_flag & BIT(id)); +} + +static const struct regulator_ops rt4801_regulator_ops = { + .list_voltage = regulator_list_voltage_linear, + .set_voltage_sel = rt4801_set_voltage_sel, + .get_voltage_sel = rt4801_get_voltage_sel, + .enable = rt4801_enable, + .disable = rt4801_disable, + .is_enabled = rt4801_is_enabled, +}; + +static const struct regulator_desc rt4801_regulator_descs[] = { + { + .name = "DSVP", + .ops = &rt4801_regulator_ops, + .of_match = of_match_ptr("DSVP"), + .type = REGULATOR_VOLTAGE, + .id = DSV_OUT_POS, + .min_uV = MIN_UV, + .uV_step = STEP_UV, + .n_voltages = N_VOLTAGES, + .owner = THIS_MODULE, + .vsel_reg = RT4801_REG_VOP, + .vsel_mask = VOUT_MASK, + }, + { + .name = "DSVN", + .ops = &rt4801_regulator_ops, + .of_match = of_match_ptr("DSVN"), + .type = REGULATOR_VOLTAGE, + .id = DSV_OUT_NEG, + .min_uV = MIN_UV, + .uV_step = STEP_UV, + .n_voltages = N_VOLTAGES, + .owner = THIS_MODULE, + .vsel_reg = RT4801_REG_VON, + .vsel_mask = VOUT_MASK, + }, +}; + +static const struct regmap_config rt4801_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = RT4801_REG_APPS, +}; + +static int rt4801_probe(struct i2c_client *i2c) +{ + struct rt4801_priv *priv; + struct regmap *regmap; + int i; + + priv = devm_kzalloc(&i2c->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->dev = &i2c->dev; + /* bootloader will on, driver only reconfigure enable to all output high */ + priv->enable_flag = DSVALL_ENABLE; + + regmap = devm_regmap_init_i2c(i2c, &rt4801_regmap_config); + if (IS_ERR(regmap)) { + dev_err(&i2c->dev, "Failed to init regmap\n"); + return PTR_ERR(regmap); + } + + priv->enable_gpios = devm_gpiod_get_array_optional(&i2c->dev, "enable", GPIOD_OUT_HIGH); + if (IS_ERR(priv->enable_gpios)) { + dev_err(&i2c->dev, "Failed to get gpios\n"); + return PTR_ERR(priv->enable_gpios); + } + + for (i = 0; i < DSV_OUT_MAX; i++) { + const struct regulator_desc *desc = rt4801_regulator_descs + i; + struct regulator_config config = { .dev = &i2c->dev, .driver_data = priv, + .regmap = regmap, }; + struct regulator_dev *rdev; + unsigned int val; + int ret; + + /* initialize volt_sel variable */ + ret = regmap_read(regmap, desc->vsel_reg, &val); + if (ret) + return ret; + + priv->volt_sel[i] = val & desc->vsel_mask; + + rdev = devm_regulator_register(&i2c->dev, desc, &config); + if (IS_ERR(rdev)) { + dev_err(&i2c->dev, "Failed to register [%d] regulator\n", i); + return PTR_ERR(rdev); + } + } + + return 0; +} + +static const struct of_device_id rt4801_of_id[] = { + { .compatible = "richtek,rt4801", }, + { }, +}; +MODULE_DEVICE_TABLE(of, rt4801_of_id); + +static struct i2c_driver rt4801_driver = { + .driver = { + .name = "rt4801", + .of_match_table = of_match_ptr(rt4801_of_id), + }, + .probe_new = rt4801_probe, +}; +module_i2c_driver(rt4801_driver); + +MODULE_AUTHOR("ChiYuan Hwang "); +MODULE_DESCRIPTION("Richtek RT4801 Display Bias Driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 4cf12735de56d2bfd058af82492b06eed761e111 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 2 Aug 2020 17:06:38 +0800 Subject: regulator: lp8755: Get rid of lp8755_read/lp8755_write/lp8755_update_bits Just use regmap_read/regmap_write/regmap_update_bits instead. Signed-off-by: Axel Lin Link: https://lore.kernel.org/r/20200802090638.380589-1-axel.lin@ingics.com Signed-off-by: Mark Brown --- drivers/regulator/lp8755.c | 82 ++++++++++++---------------------------------- 1 file changed, 21 insertions(+), 61 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/lp8755.c b/drivers/regulator/lp8755.c index 4291df077c39..8cc9963023f2 100644 --- a/drivers/regulator/lp8755.c +++ b/drivers/regulator/lp8755.c @@ -49,53 +49,15 @@ struct lp8755_chip { struct regulator_dev *rdev[LP8755_BUCK_MAX]; }; -/** - *lp8755_read : read a single register value from lp8755. - *@pchip : device to read from - *@reg : register to read from - *@val : pointer to store read value - */ -static int lp8755_read(struct lp8755_chip *pchip, unsigned int reg, - unsigned int *val) -{ - return regmap_read(pchip->regmap, reg, val); -} - -/** - *lp8755_write : write a single register value to lp8755. - *@pchip : device to write to - *@reg : register to write to - *@val : value to be written - */ -static int lp8755_write(struct lp8755_chip *pchip, unsigned int reg, - unsigned int val) -{ - return regmap_write(pchip->regmap, reg, val); -} - -/** - *lp8755_update_bits : set the values of bit fields in lp8755 register. - *@pchip : device to read from - *@reg : register to update - *@mask : bitmask to be changed - *@val : value for bitmask - */ -static int lp8755_update_bits(struct lp8755_chip *pchip, unsigned int reg, - unsigned int mask, unsigned int val) -{ - return regmap_update_bits(pchip->regmap, reg, mask, val); -} - static int lp8755_buck_enable_time(struct regulator_dev *rdev) { int ret; unsigned int regval; enum lp8755_bucks id = rdev_get_id(rdev); - struct lp8755_chip *pchip = rdev_get_drvdata(rdev); - ret = lp8755_read(pchip, 0x12 + id, ®val); + ret = regmap_read(rdev->regmap, 0x12 + id, ®val); if (ret < 0) { - dev_err(pchip->dev, "i2c access error %s\n", __func__); + dev_err(&rdev->dev, "i2c access error %s\n", __func__); return ret; } return (regval & 0xff) * 100; @@ -115,17 +77,17 @@ static int lp8755_buck_set_mode(struct regulator_dev *rdev, unsigned int mode) break; case REGULATOR_MODE_NORMAL: /* enable automatic pwm/pfm mode */ - ret = lp8755_update_bits(pchip, 0x08 + id, 0x20, 0x00); + ret = regmap_update_bits(rdev->regmap, 0x08 + id, 0x20, 0x00); if (ret < 0) goto err_i2c; break; case REGULATOR_MODE_IDLE: /* enable automatic pwm/pfm/lppfm mode */ - ret = lp8755_update_bits(pchip, 0x08 + id, 0x20, 0x20); + ret = regmap_update_bits(rdev->regmap, 0x08 + id, 0x20, 0x20); if (ret < 0) goto err_i2c; - ret = lp8755_update_bits(pchip, 0x10, 0x01, 0x01); + ret = regmap_update_bits(rdev->regmap, 0x10, 0x01, 0x01); if (ret < 0) goto err_i2c; break; @@ -135,12 +97,12 @@ static int lp8755_buck_set_mode(struct regulator_dev *rdev, unsigned int mode) regbval = (0x01 << id); } - ret = lp8755_update_bits(pchip, 0x06, 0x01 << id, regbval); + ret = regmap_update_bits(rdev->regmap, 0x06, 0x01 << id, regbval); if (ret < 0) goto err_i2c; return ret; err_i2c: - dev_err(pchip->dev, "i2c access error %s\n", __func__); + dev_err(&rdev->dev, "i2c access error %s\n", __func__); return ret; } @@ -149,9 +111,8 @@ static unsigned int lp8755_buck_get_mode(struct regulator_dev *rdev) int ret; unsigned int regval; enum lp8755_bucks id = rdev_get_id(rdev); - struct lp8755_chip *pchip = rdev_get_drvdata(rdev); - ret = lp8755_read(pchip, 0x06, ®val); + ret = regmap_read(rdev->regmap, 0x06, ®val); if (ret < 0) goto err_i2c; @@ -159,7 +120,7 @@ static unsigned int lp8755_buck_get_mode(struct regulator_dev *rdev) if (regval & (0x01 << id)) return REGULATOR_MODE_FAST; - ret = lp8755_read(pchip, 0x08 + id, ®val); + ret = regmap_read(rdev->regmap, 0x08 + id, ®val); if (ret < 0) goto err_i2c; @@ -171,7 +132,7 @@ static unsigned int lp8755_buck_get_mode(struct regulator_dev *rdev) return REGULATOR_MODE_NORMAL; err_i2c: - dev_err(pchip->dev, "i2c access error %s\n", __func__); + dev_err(&rdev->dev, "i2c access error %s\n", __func__); return 0; } @@ -180,7 +141,6 @@ static int lp8755_buck_set_ramp(struct regulator_dev *rdev, int ramp) int ret; unsigned int regval = 0x00; enum lp8755_bucks id = rdev_get_id(rdev); - struct lp8755_chip *pchip = rdev_get_drvdata(rdev); /* uV/us */ switch (ramp) { @@ -209,17 +169,17 @@ static int lp8755_buck_set_ramp(struct regulator_dev *rdev, int ramp) regval = 0x00; break; default: - dev_err(pchip->dev, + dev_err(&rdev->dev, "Not supported ramp value %d %s\n", ramp, __func__); return -EINVAL; } - ret = lp8755_update_bits(pchip, 0x07 + id, 0x07, regval); + ret = regmap_update_bits(rdev->regmap, 0x07 + id, 0x07, regval); if (ret < 0) goto err_i2c; return ret; err_i2c: - dev_err(pchip->dev, "i2c access error %s\n", __func__); + dev_err(&rdev->dev, "i2c access error %s\n", __func__); return ret; } @@ -278,7 +238,7 @@ static int lp8755_init_data(struct lp8755_chip *pchip) struct lp8755_platform_data *pdata = pchip->pdata; /* read back muti-phase configuration */ - ret = lp8755_read(pchip, 0x3D, ®val); + ret = regmap_read(pchip->regmap, 0x3D, ®val); if (ret < 0) goto out_i2c_error; pchip->mphase = regval & 0x0F; @@ -356,11 +316,11 @@ static irqreturn_t lp8755_irq_handler(int irq, void *data) struct lp8755_chip *pchip = data; /* read flag0 register */ - ret = lp8755_read(pchip, 0x0D, &flag0); + ret = regmap_read(pchip->regmap, 0x0D, &flag0); if (ret < 0) goto err_i2c; /* clear flag register to pull up int. pin */ - ret = lp8755_write(pchip, 0x0D, 0x00); + ret = regmap_write(pchip->regmap, 0x0D, 0x00); if (ret < 0) goto err_i2c; @@ -377,11 +337,11 @@ static irqreturn_t lp8755_irq_handler(int irq, void *data) } /* read flag1 register */ - ret = lp8755_read(pchip, 0x0E, &flag1); + ret = regmap_read(pchip->regmap, 0x0E, &flag1); if (ret < 0) goto err_i2c; /* clear flag register to pull up int. pin */ - ret = lp8755_write(pchip, 0x0E, 0x00); + ret = regmap_write(pchip->regmap, 0x0E, 0x00); if (ret < 0) goto err_i2c; @@ -423,7 +383,7 @@ static int lp8755_int_config(struct lp8755_chip *pchip) return 0; } - ret = lp8755_read(pchip, 0x0F, ®val); + ret = regmap_read(pchip->regmap, 0x0F, ®val); if (ret < 0) { dev_err(pchip->dev, "i2c access error %s\n", __func__); return ret; @@ -502,7 +462,7 @@ static int lp8755_probe(struct i2c_client *client, err: /* output disable */ for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++) - lp8755_write(pchip, icnt, 0x00); + regmap_write(pchip->regmap, icnt, 0x00); return ret; } @@ -513,7 +473,7 @@ static int lp8755_remove(struct i2c_client *client) struct lp8755_chip *pchip = i2c_get_clientdata(client); for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++) - lp8755_write(pchip, icnt, 0x00); + regmap_write(pchip->regmap, icnt, 0x00); return 0; } -- cgit v1.2.3 From 989e08c3d0044fc707c26c0329ed49e33e8e4c7b Mon Sep 17 00:00:00 2001 From: Hsin-Yi Wang Date: Wed, 12 Aug 2020 21:31:02 +0800 Subject: regulator: da9211: add cache_type Add regmap_cache to reduce wakeups events of interrupt if regulator is accessed frequently. This results in saving more power. Suggested-by: Daniel Kurtz Signed-off-by: Hsin-Yi Wang Acked-by: Adam Thomson Link: https://lore.kernel.org/r/20200812133101.2513317-1-hsinyi@chromium.org Signed-off-by: Mark Brown --- drivers/regulator/da9211-regulator.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers/regulator') diff --git a/drivers/regulator/da9211-regulator.c b/drivers/regulator/da9211-regulator.c index 297b3aa7c753..cffcefd0538d 100644 --- a/drivers/regulator/da9211-regulator.c +++ b/drivers/regulator/da9211-regulator.c @@ -51,10 +51,24 @@ static const struct regmap_range_cfg da9211_regmap_range[] = { }, }; +static bool da9211_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case DA9211_REG_STATUS_A: + case DA9211_REG_STATUS_B: + case DA9211_REG_EVENT_A: + case DA9211_REG_EVENT_B: + return true; + } + return false; +} + static const struct regmap_config da9211_regmap_config = { .reg_bits = 8, .val_bits = 8, .max_register = 5 * 128, + .volatile_reg = da9211_volatile_reg, + .cache_type = REGCACHE_RBTREE, .ranges = da9211_regmap_range, .num_ranges = ARRAY_SIZE(da9211_regmap_range), }; -- cgit v1.2.3 From a16138a32eeeca01e2603193288ff0714bead11d Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Mon, 10 Aug 2020 09:57:53 +0800 Subject: regulator: sy8827n: Fix W=1 build warning when CONFIG_OF=n Fixing W=1 build warning when no support for device tree is there. Reported-by: kernel test robot Signed-off-by: Jisheng Zhang Link: https://lore.kernel.org/r/20200810095753.59ce9f75@xhacker.debian Signed-off-by: Mark Brown --- drivers/regulator/sy8827n.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/regulator') diff --git a/drivers/regulator/sy8827n.c b/drivers/regulator/sy8827n.c index b207217f74d8..52e8c17afe24 100644 --- a/drivers/regulator/sy8827n.c +++ b/drivers/regulator/sy8827n.c @@ -156,6 +156,7 @@ static int sy8827n_i2c_probe(struct i2c_client *client) return ret; } +#ifdef CONFIG_OF static const struct of_device_id sy8827n_dt_ids[] = { { .compatible = "silergy,sy8827n", @@ -163,6 +164,7 @@ static const struct of_device_id sy8827n_dt_ids[] = { { } }; MODULE_DEVICE_TABLE(of, sy8827n_dt_ids); +#endif static const struct i2c_device_id sy8827n_id[] = { { "sy8827n", }, -- cgit v1.2.3 From 0955f5be4337c0ada82e49389249eb99199f8db2 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 4 Aug 2020 00:08:37 -0700 Subject: regulator: Avoid grabbing regulator lock during suspend/resume I see it takes about 5us per regulator to grab the lock, check that this regulator isn't going to do anything for suspend, and then release the lock. When that is combined with PMICs that have dozens of regulators we get into a state where we spend a few miliseconds doing a bunch of locking operations synchronously to figure out that there's nothing to do. Let's reorganize the code here a bit so that we don't grab the lock until we're actually going to do something so that suspend is a little faster. Signed-off-by: Stephen Boyd Reviewed-by: Douglas Anderson Cc: Matthias Kaehlcke Cc: Douglas Anderson Link: https://lore.kernel.org/r/20200804070837.1084024-1-swboyd@chromium.org Signed-off-by: Mark Brown --- drivers/regulator/core.c | 75 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 51 insertions(+), 24 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 75ff7c563c5d..76e9ed884afa 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -565,6 +565,30 @@ regulator_get_suspend_state(struct regulator_dev *rdev, suspend_state_t state) } } +static const struct regulator_state * +regulator_get_suspend_state_check(struct regulator_dev *rdev, suspend_state_t state) +{ + const struct regulator_state *rstate; + + rstate = regulator_get_suspend_state(rdev, state); + if (rstate == NULL) + return NULL; + + /* If we have no suspend mode configuration don't set anything; + * only warn if the driver implements set_suspend_voltage or + * set_suspend_mode callback. + */ + if (rstate->enabled != ENABLE_IN_SUSPEND && + rstate->enabled != DISABLE_IN_SUSPEND) { + if (rdev->desc->ops->set_suspend_voltage || + rdev->desc->ops->set_suspend_mode) + rdev_warn(rdev, "No configuration\n"); + return NULL; + } + + return rstate; +} + static ssize_t regulator_uV_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -982,27 +1006,10 @@ static int drms_uA_update(struct regulator_dev *rdev) return err; } -static int suspend_set_state(struct regulator_dev *rdev, - suspend_state_t state) +static int __suspend_set_state(struct regulator_dev *rdev, + const struct regulator_state *rstate) { int ret = 0; - struct regulator_state *rstate; - - rstate = regulator_get_suspend_state(rdev, state); - if (rstate == NULL) - return 0; - - /* If we have no suspend mode configuration don't set anything; - * only warn if the driver implements set_suspend_voltage or - * set_suspend_mode callback. - */ - if (rstate->enabled != ENABLE_IN_SUSPEND && - rstate->enabled != DISABLE_IN_SUSPEND) { - if (rdev->desc->ops->set_suspend_voltage || - rdev->desc->ops->set_suspend_mode) - rdev_warn(rdev, "No configuration\n"); - return 0; - } if (rstate->enabled == ENABLE_IN_SUSPEND && rdev->desc->ops->set_suspend_enable) @@ -1037,6 +1044,18 @@ static int suspend_set_state(struct regulator_dev *rdev, return ret; } +static int suspend_set_initial_state(struct regulator_dev *rdev) +{ + const struct regulator_state *rstate; + + rstate = regulator_get_suspend_state_check(rdev, + rdev->constraints->initial_state); + if (!rstate) + return 0; + + return __suspend_set_state(rdev, rstate); +} + static void print_constraints(struct regulator_dev *rdev) { struct regulation_constraints *constraints = rdev->constraints; @@ -1319,7 +1338,7 @@ static int set_machine_constraints(struct regulator_dev *rdev, /* do we need to setup our suspend state */ if (rdev->constraints->initial_state) { - ret = suspend_set_state(rdev, rdev->constraints->initial_state); + ret = suspend_set_initial_state(rdev); if (ret < 0) { rdev_err(rdev, "failed to set suspend state\n"); return ret; @@ -5362,9 +5381,14 @@ static int regulator_suspend(struct device *dev) struct regulator_dev *rdev = dev_to_rdev(dev); suspend_state_t state = pm_suspend_target_state; int ret; + const struct regulator_state *rstate; + + rstate = regulator_get_suspend_state_check(rdev, state); + if (!rstate) + return 0; regulator_lock(rdev); - ret = suspend_set_state(rdev, state); + ret = __suspend_set_state(rdev, rstate); regulator_unlock(rdev); return ret; @@ -5381,11 +5405,14 @@ static int regulator_resume(struct device *dev) if (rstate == NULL) return 0; + /* Avoid grabbing the lock if we don't need to */ + if (!rdev->desc->ops->resume) + return 0; + regulator_lock(rdev); - if (rdev->desc->ops->resume && - (rstate->enabled == ENABLE_IN_SUSPEND || - rstate->enabled == DISABLE_IN_SUSPEND)) + if (rstate->enabled == ENABLE_IN_SUSPEND || + rstate->enabled == DISABLE_IN_SUSPEND) ret = rdev->desc->ops->resume(rdev); regulator_unlock(rdev); -- cgit v1.2.3 From 38573472278da49e2ab588062d88bc2f0c11a325 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 9 Aug 2020 12:59:38 +0200 Subject: regulator: rpi-panel: Add regulator/backlight driver for RPi panel This regulator/backlight driver handles the ATTINY88 present on the RPi 7" touchscreen panel and exposes the power/backlight interfaces. Signed-off-by: Marek Vasut Cc: Eric Anholt Cc: Mark Brown Cc: Sam Ravnborg To: dri-devel@lists.freedesktop.org Link: https://lore.kernel.org/r/20200809105938.6388-2-marex@denx.de Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 10 ++ drivers/regulator/Makefile | 1 + drivers/regulator/rpi-panel-attiny-regulator.c | 214 +++++++++++++++++++++++++ 3 files changed, 225 insertions(+) create mode 100644 drivers/regulator/rpi-panel-attiny-regulator.c (limited to 'drivers/regulator') diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 2786f11cc91e..ebce11cbab44 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -864,6 +864,16 @@ config REGULATOR_QCOM_USB_VBUS Say M here if you want to include support for enabling the VBUS output as a module. The module will be named "qcom_usb_vbus_regulator". +config REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY + tristate "Raspberry Pi 7-inch touchscreen panel ATTINY regulator" + depends on BACKLIGHT_CLASS_DEVICE + depends on I2C + select REGMAP_I2C + help + This driver supports ATTINY regulator on the Raspberry Pi 7-inch + touchscreen unit. The regulator is used to enable power to the + TC358762, display and to control backlight. + config REGULATOR_RC5T583 tristate "RICOH RC5T583 Power regulators" depends on MFD_RC5T583 diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index d091e52db25d..9f478e5687b6 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -107,6 +107,7 @@ obj-$(CONFIG_REGULATOR_TPS51632) += tps51632-regulator.o obj-$(CONFIG_REGULATOR_PBIAS) += pbias-regulator.o obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o +obj-$(CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY) += rpi-panel-attiny-regulator.o obj-$(CONFIG_REGULATOR_RC5T583) += rc5t583-regulator.o obj-$(CONFIG_REGULATOR_RK808) += rk808-regulator.o obj-$(CONFIG_REGULATOR_RN5T618) += rn5t618-regulator.o diff --git a/drivers/regulator/rpi-panel-attiny-regulator.c b/drivers/regulator/rpi-panel-attiny-regulator.c new file mode 100644 index 000000000000..ee46bfbf5eee --- /dev/null +++ b/drivers/regulator/rpi-panel-attiny-regulator.c @@ -0,0 +1,214 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2020 Marek Vasut + * + * Based on rpi_touchscreen.c by Eric Anholt + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* I2C registers of the Atmel microcontroller. */ +#define REG_ID 0x80 +#define REG_PORTA 0x81 +#define REG_PORTA_HF BIT(2) +#define REG_PORTA_VF BIT(3) +#define REG_PORTB 0x82 +#define REG_POWERON 0x85 +#define REG_PWM 0x86 + +static const struct regmap_config attiny_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = REG_PWM, + .cache_type = REGCACHE_NONE, +}; + +static int attiny_lcd_power_enable(struct regulator_dev *rdev) +{ + unsigned int data; + + regmap_write(rdev->regmap, REG_POWERON, 1); + /* Wait for nPWRDWN to go low to indicate poweron is done. */ + regmap_read_poll_timeout(rdev->regmap, REG_PORTB, data, + data & BIT(0), 10, 1000000); + + /* Default to the same orientation as the closed source + * firmware used for the panel. Runtime rotation + * configuration will be supported using VC4's plane + * orientation bits. + */ + regmap_write(rdev->regmap, REG_PORTA, BIT(2)); + + return 0; +} + +static int attiny_lcd_power_disable(struct regulator_dev *rdev) +{ + regmap_write(rdev->regmap, REG_PWM, 0); + regmap_write(rdev->regmap, REG_POWERON, 0); + udelay(1); + return 0; +} + +static int attiny_lcd_power_is_enabled(struct regulator_dev *rdev) +{ + unsigned int data; + int ret; + + ret = regmap_read(rdev->regmap, REG_POWERON, &data); + if (ret < 0) + return ret; + + if (!(data & BIT(0))) + return 0; + + ret = regmap_read(rdev->regmap, REG_PORTB, &data); + if (ret < 0) + return ret; + + return data & BIT(0); +} + +static const struct regulator_init_data attiny_regulator_default = { + .constraints = { + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, +}; + +static const struct regulator_ops attiny_regulator_ops = { + .enable = attiny_lcd_power_enable, + .disable = attiny_lcd_power_disable, + .is_enabled = attiny_lcd_power_is_enabled, +}; + +static const struct regulator_desc attiny_regulator = { + .name = "tc358762-power", + .ops = &attiny_regulator_ops, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, +}; + +static int attiny_update_status(struct backlight_device *bl) +{ + struct regmap *regmap = bl_get_data(bl); + int brightness = bl->props.brightness; + + if (bl->props.power != FB_BLANK_UNBLANK || + bl->props.fb_blank != FB_BLANK_UNBLANK) + brightness = 0; + + return regmap_write(regmap, REG_PWM, brightness); +} + +static int attiny_get_brightness(struct backlight_device *bl) +{ + struct regmap *regmap = bl_get_data(bl); + int ret, brightness; + + ret = regmap_read(regmap, REG_PWM, &brightness); + if (ret) + return ret; + + return brightness; +} + +static const struct backlight_ops attiny_bl = { + .update_status = attiny_update_status, + .get_brightness = attiny_get_brightness, +}; + +/* + * I2C driver interface functions + */ +static int attiny_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct backlight_properties props = { }; + struct regulator_config config = { }; + struct backlight_device *bl; + struct regulator_dev *rdev; + struct regmap *regmap; + unsigned int data; + int ret; + + regmap = devm_regmap_init_i2c(i2c, &attiny_regmap_config); + if (IS_ERR(regmap)) { + ret = PTR_ERR(regmap); + dev_err(&i2c->dev, "Failed to allocate register map: %d\n", + ret); + return ret; + } + + ret = regmap_read(regmap, REG_ID, &data); + if (ret < 0) { + dev_err(&i2c->dev, "Failed to read REG_ID reg: %d\n", ret); + return ret; + } + + switch (data) { + case 0xde: /* ver 1 */ + case 0xc3: /* ver 2 */ + break; + default: + dev_err(&i2c->dev, "Unknown Atmel firmware revision: 0x%02x\n", data); + return -ENODEV; + } + + regmap_write(regmap, REG_POWERON, 0); + mdelay(1); + + config.dev = &i2c->dev; + config.regmap = regmap; + config.of_node = i2c->dev.of_node; + config.init_data = &attiny_regulator_default; + + rdev = devm_regulator_register(&i2c->dev, &attiny_regulator, &config); + if (IS_ERR(rdev)) { + dev_err(&i2c->dev, "Failed to register ATTINY regulator\n"); + return PTR_ERR(rdev); + } + + props.type = BACKLIGHT_RAW; + props.max_brightness = 0xff; + bl = devm_backlight_device_register(&i2c->dev, + "7inch-touchscreen-panel-bl", + &i2c->dev, regmap, &attiny_bl, + &props); + if (IS_ERR(bl)) + return PTR_ERR(bl); + + bl->props.brightness = 0xff; + + return 0; +} + +static const struct of_device_id attiny_dt_ids[] = { + { .compatible = "raspberrypi,7inch-touchscreen-panel-regulator" }, + {}, +}; +MODULE_DEVICE_TABLE(of, attiny_dt_ids); + +static struct i2c_driver attiny_regulator_driver = { + .driver = { + .name = "rpi_touchscreen_attiny", + .of_match_table = of_match_ptr(attiny_dt_ids), + }, + .probe = attiny_i2c_probe, +}; + +module_i2c_driver(attiny_regulator_driver); + +MODULE_AUTHOR("Marek Vasut "); +MODULE_DESCRIPTION("Regulator device driver for Raspberry Pi 7-inch touchscreen"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 7d8196641ee1eea6223e68ff92362652b1c8346b Mon Sep 17 00:00:00 2001 From: Michał Mirosław Date: Sun, 9 Aug 2020 21:21:16 +0200 Subject: regulator: Remove pointer table overallocation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The code allocates sizeof(regulator_dev) for a pointer. Make it less generous. Let kcalloc() calculate the size, while at it. Signed-off-by: Michał Mirosław Reviewed-by: Dmitry Osipenko Link: https://lore.kernel.org/r/407fbd06a02caf038a9ba3baa51c7d6d47cd6517.1597000795.git.mirq-linux@rere.qmqm.pl Signed-off-by: Mark Brown --- drivers/regulator/core.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 76e9ed884afa..98777d720063 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -5030,20 +5030,20 @@ static void regulator_remove_coupling(struct regulator_dev *rdev) static int regulator_init_coupling(struct regulator_dev *rdev) { + struct regulator_dev **coupled; int err, n_phandles; - size_t alloc_size; if (!IS_ENABLED(CONFIG_OF)) n_phandles = 0; else n_phandles = of_get_n_coupled(rdev); - alloc_size = sizeof(*rdev) * (n_phandles + 1); - - rdev->coupling_desc.coupled_rdevs = kzalloc(alloc_size, GFP_KERNEL); - if (!rdev->coupling_desc.coupled_rdevs) + coupled = kcalloc(n_phandles + 1, sizeof(*coupled), GFP_KERNEL); + if (!coupled) return -ENOMEM; + rdev->coupling_desc.coupled_rdevs = coupled; + /* * Every regulator should always have coupling descriptor filled with * at least pointer to itself. -- cgit v1.2.3 From 6a1fe83bf14b87fd8b02f391ea629f69624d9c34 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 1 Aug 2020 13:48:20 +0800 Subject: regulator: qcom_spmi: Improve readability for setting up enable/mode pin control By checking data->pin_ctrl_enable / data->pin_ctrl_hpm flags first, then use switch-case to improve readability. Signed-off-by: Axel Lin Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20200801054820.134859-1-axel.lin@ingics.com Signed-off-by: Mark Brown --- drivers/regulator/qcom_spmi-regulator.c | 70 ++++++++++++++++----------------- 1 file changed, 34 insertions(+), 36 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/qcom_spmi-regulator.c b/drivers/regulator/qcom_spmi-regulator.c index 5ee7c5305d95..05080483fe1b 100644 --- a/drivers/regulator/qcom_spmi-regulator.c +++ b/drivers/regulator/qcom_spmi-regulator.c @@ -1633,45 +1633,43 @@ static int spmi_regulator_init_registers(struct spmi_regulator *vreg, return ret; /* Set up enable pin control. */ - if ((type == SPMI_REGULATOR_LOGICAL_TYPE_SMPS - || type == SPMI_REGULATOR_LOGICAL_TYPE_LDO - || type == SPMI_REGULATOR_LOGICAL_TYPE_VS) - && !(data->pin_ctrl_enable - & SPMI_REGULATOR_PIN_CTRL_ENABLE_HW_DEFAULT)) { - ctrl_reg[SPMI_COMMON_IDX_ENABLE] &= - ~SPMI_COMMON_ENABLE_FOLLOW_ALL_MASK; - ctrl_reg[SPMI_COMMON_IDX_ENABLE] |= - data->pin_ctrl_enable & SPMI_COMMON_ENABLE_FOLLOW_ALL_MASK; + if (!(data->pin_ctrl_enable & SPMI_REGULATOR_PIN_CTRL_ENABLE_HW_DEFAULT)) { + switch (type) { + case SPMI_REGULATOR_LOGICAL_TYPE_SMPS: + case SPMI_REGULATOR_LOGICAL_TYPE_LDO: + case SPMI_REGULATOR_LOGICAL_TYPE_VS: + ctrl_reg[SPMI_COMMON_IDX_ENABLE] &= + ~SPMI_COMMON_ENABLE_FOLLOW_ALL_MASK; + ctrl_reg[SPMI_COMMON_IDX_ENABLE] |= + data->pin_ctrl_enable & SPMI_COMMON_ENABLE_FOLLOW_ALL_MASK; + break; + default: + break; + } } /* Set up mode pin control. */ - if ((type == SPMI_REGULATOR_LOGICAL_TYPE_SMPS - || type == SPMI_REGULATOR_LOGICAL_TYPE_LDO) - && !(data->pin_ctrl_hpm - & SPMI_REGULATOR_PIN_CTRL_HPM_HW_DEFAULT)) { - ctrl_reg[SPMI_COMMON_IDX_MODE] &= - ~SPMI_COMMON_MODE_FOLLOW_ALL_MASK; - ctrl_reg[SPMI_COMMON_IDX_MODE] |= - data->pin_ctrl_hpm & SPMI_COMMON_MODE_FOLLOW_ALL_MASK; - } - - if (type == SPMI_REGULATOR_LOGICAL_TYPE_VS - && !(data->pin_ctrl_hpm & SPMI_REGULATOR_PIN_CTRL_HPM_HW_DEFAULT)) { - ctrl_reg[SPMI_COMMON_IDX_MODE] &= - ~SPMI_COMMON_MODE_FOLLOW_AWAKE_MASK; - ctrl_reg[SPMI_COMMON_IDX_MODE] |= - data->pin_ctrl_hpm & SPMI_COMMON_MODE_FOLLOW_AWAKE_MASK; - } - - if ((type == SPMI_REGULATOR_LOGICAL_TYPE_ULT_LO_SMPS - || type == SPMI_REGULATOR_LOGICAL_TYPE_ULT_HO_SMPS - || type == SPMI_REGULATOR_LOGICAL_TYPE_ULT_LDO) - && !(data->pin_ctrl_hpm - & SPMI_REGULATOR_PIN_CTRL_HPM_HW_DEFAULT)) { - ctrl_reg[SPMI_COMMON_IDX_MODE] &= - ~SPMI_COMMON_MODE_FOLLOW_AWAKE_MASK; - ctrl_reg[SPMI_COMMON_IDX_MODE] |= - data->pin_ctrl_hpm & SPMI_COMMON_MODE_FOLLOW_AWAKE_MASK; + if (!(data->pin_ctrl_hpm & SPMI_REGULATOR_PIN_CTRL_HPM_HW_DEFAULT)) { + switch (type) { + case SPMI_REGULATOR_LOGICAL_TYPE_SMPS: + case SPMI_REGULATOR_LOGICAL_TYPE_LDO: + ctrl_reg[SPMI_COMMON_IDX_MODE] &= + ~SPMI_COMMON_MODE_FOLLOW_ALL_MASK; + ctrl_reg[SPMI_COMMON_IDX_MODE] |= + data->pin_ctrl_hpm & SPMI_COMMON_MODE_FOLLOW_ALL_MASK; + break; + case SPMI_REGULATOR_LOGICAL_TYPE_VS: + case SPMI_REGULATOR_LOGICAL_TYPE_ULT_LO_SMPS: + case SPMI_REGULATOR_LOGICAL_TYPE_ULT_HO_SMPS: + case SPMI_REGULATOR_LOGICAL_TYPE_ULT_LDO: + ctrl_reg[SPMI_COMMON_IDX_MODE] &= + ~SPMI_COMMON_MODE_FOLLOW_AWAKE_MASK; + ctrl_reg[SPMI_COMMON_IDX_MODE] |= + data->pin_ctrl_hpm & SPMI_COMMON_MODE_FOLLOW_AWAKE_MASK; + break; + default: + break; + } } /* Write back any control register values that were modified. */ -- cgit v1.2.3 From 66c3b96a7bd042427d2e0eaa8704536828f8235f Mon Sep 17 00:00:00 2001 From: Jonathan Marek Date: Tue, 18 Aug 2020 12:25:08 -0400 Subject: regulator: set of_node for qcom vbus regulator This allows the regulator to be found by devm_regulator_get(). Fixes: 4fe66d5a62fb ("regulator: Add support for QCOM PMIC VBUS booster") Signed-off-by: Jonathan Marek Link: https://lore.kernel.org/r/20200818162508.5246-1-jonathan@marek.ca Signed-off-by: Mark Brown --- drivers/regulator/qcom_usb_vbus-regulator.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/regulator') diff --git a/drivers/regulator/qcom_usb_vbus-regulator.c b/drivers/regulator/qcom_usb_vbus-regulator.c index 8ba947f3585f..457788b50572 100644 --- a/drivers/regulator/qcom_usb_vbus-regulator.c +++ b/drivers/regulator/qcom_usb_vbus-regulator.c @@ -63,6 +63,7 @@ static int qcom_usb_vbus_regulator_probe(struct platform_device *pdev) qcom_usb_vbus_rdesc.enable_mask = OTG_EN; config.dev = dev; config.init_data = init_data; + config.of_node = dev->of_node; config.regmap = regmap; rdev = devm_regulator_register(dev, &qcom_usb_vbus_rdesc, &config); -- cgit v1.2.3 From 8bdaa43808b7481eb61b251ae0e4ca308ee1093d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 18 Aug 2020 15:37:01 +0200 Subject: regulator: dbx500: no need to check return value of debugfs_create functions When calling debugfs functions, there is no need to ever check the return value. The function can work or not, but the code logic should never do something different based on this. Signed-off-by: Greg Kroah-Hartman Cc: Liam Girdwood Cc: Mark Brown Cc: linux-kernel@vger.kernel.org Link: https://lore.kernel.org/r/20200818133701.462958-1-gregkh@linuxfoundation.org Signed-off-by: Mark Brown --- drivers/regulator/dbx500-prcmu.c | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/dbx500-prcmu.c b/drivers/regulator/dbx500-prcmu.c index c3ad6aa6b5d3..7395ad2105ab 100644 --- a/drivers/regulator/dbx500-prcmu.c +++ b/drivers/regulator/dbx500-prcmu.c @@ -67,8 +67,6 @@ static int power_state_active_get(void) static struct ux500_regulator_debug { struct dentry *dir; - struct dentry *status_file; - struct dentry *power_state_cnt_file; struct dbx500_regulator_info *regulator_array; int num_regulators; u8 *state_before_suspend; @@ -117,22 +115,14 @@ ux500_regulator_debug_init(struct platform_device *pdev, { /* create directory */ rdebug.dir = debugfs_create_dir("ux500-regulator", NULL); - if (!rdebug.dir) - goto exit_no_debugfs; /* create "status" file */ - rdebug.status_file = debugfs_create_file("status", - S_IRUGO, rdebug.dir, &pdev->dev, - &ux500_regulator_status_fops); - if (!rdebug.status_file) - goto exit_destroy_dir; + debugfs_create_file("status", S_IRUGO, rdebug.dir, &pdev->dev, + &ux500_regulator_status_fops); /* create "power-state-count" file */ - rdebug.power_state_cnt_file = debugfs_create_file("power-state-count", - S_IRUGO, rdebug.dir, &pdev->dev, - &ux500_regulator_power_state_cnt_fops); - if (!rdebug.power_state_cnt_file) - goto exit_destroy_status; + debugfs_create_file("power-state-count", S_IRUGO, rdebug.dir, + &pdev->dev, &ux500_regulator_power_state_cnt_fops); rdebug.regulator_array = regulator_info; rdebug.num_regulators = num_regulators; @@ -150,11 +140,7 @@ ux500_regulator_debug_init(struct platform_device *pdev, exit_free: kfree(rdebug.state_before_suspend); exit_destroy_power_state: - debugfs_remove(rdebug.power_state_cnt_file); -exit_destroy_status: - debugfs_remove(rdebug.status_file); -exit_destroy_dir: - debugfs_remove(rdebug.dir); + debugfs_remove_recursive(rdebug.dir); exit_no_debugfs: dev_err(&pdev->dev, "failed to create debugfs entries.\n"); return -ENOMEM; -- cgit v1.2.3 From 02532cb80543b50611656a6017bfec7477e2e200 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 19 Aug 2020 16:59:59 +0800 Subject: regulator: rt4801: Select REGMAP_I2C to fix build error Fix build error when CONFIG_REGMAP_I2C is not set. Signed-off-by: Axel Lin Link: https://lore.kernel.org/r/20200819085959.1914471-1-axel.lin@ingics.com Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/regulator') diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index ebce11cbab44..f719ed5a8c33 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -907,6 +907,7 @@ config REGULATOR_ROHM config REGULATOR_RT4801 tristate "Richtek RT4801 Regulators" depends on I2C + select REGMAP_I2C help This adds support for voltage regulators in Richtek RT4801 Display Bias IC. The device supports two regulators (DSVP/DSVN). -- cgit v1.2.3 From e11e068ccbdb038e21e24ad2ee0157c902e3c9fc Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Fri, 21 Aug 2020 11:12:10 +0800 Subject: regulator: 88pg86x: Fix W=1 build warning when CONFIG_OF=n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix below warning when CONFIG_OF=n: drivers/regulator/88pg86x.c:87:34: warning: ‘pg86x_dt_ids’ defined but not used [-Wunused-const-variable=] 87 | static const struct of_device_id pg86x_dt_ids [] = { | ^~~~~~~~~~~~ Signed-off-by: Jisheng Zhang Link: https://lore.kernel.org/r/20200821111210.0a0bed94@xhacker.debian Signed-off-by: Mark Brown --- drivers/regulator/88pg86x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/88pg86x.c b/drivers/regulator/88pg86x.c index 71cfa2c5de5e..e91d5885c5ef 100644 --- a/drivers/regulator/88pg86x.c +++ b/drivers/regulator/88pg86x.c @@ -84,7 +84,7 @@ static int pg86x_i2c_probe(struct i2c_client *i2c) return 0; } -static const struct of_device_id pg86x_dt_ids [] = { +static const struct of_device_id __maybe_unused pg86x_dt_ids[] = { { .compatible = "marvell,88pg867" }, { .compatible = "marvell,88pg868" }, { } -- cgit v1.2.3 From 2d2a84ae30a3bda57a22b283c55be8e9e6fd158b Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Fri, 21 Aug 2020 11:12:35 +0800 Subject: regulator: da9210: Fix W=1 build warning when CONFIG_OF=n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix below warning when CONFIG_OF=n: drivers/regulator/da9210-regulator.c:128:34: warning: ‘da9210_dt_ids’ defined but not used [-Wunused-const-variable=] 128 | static const struct of_device_id da9210_dt_ids[] = { | ^~~~~~~~~~~~~ Signed-off-by: Jisheng Zhang Acked-by: Adam Thomson Link: https://lore.kernel.org/r/20200821111235.14473a88@xhacker.debian Signed-off-by: Mark Brown --- drivers/regulator/da9210-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/da9210-regulator.c b/drivers/regulator/da9210-regulator.c index 0cdeb6186529..2aea442b62fe 100644 --- a/drivers/regulator/da9210-regulator.c +++ b/drivers/regulator/da9210-regulator.c @@ -125,7 +125,7 @@ error_i2c: * I2C driver interface functions */ -static const struct of_device_id da9210_dt_ids[] = { +static const struct of_device_id __maybe_unused da9210_dt_ids[] = { { .compatible = "dlg,da9210", }, { } }; -- cgit v1.2.3 From 5e97d7e809a1fd8a2401429df13e0410b77d2142 Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Fri, 21 Aug 2020 11:13:24 +0800 Subject: regulator: fan53555: Fix W=1 build warning when CONFIG_OF=n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix below warning when CONFIG_OF=n: drivers/regulator/fan53555.c:439:34: warning: ‘fan53555_dt_ids’ defined but not used [-Wunused-const-variable=] 439 | static const struct of_device_id fan53555_dt_ids[] = { | ^~~~~~~~~~~~~~~ Signed-off-by: Jisheng Zhang Link: https://lore.kernel.org/r/20200821111324.430fe1da@xhacker.debian Signed-off-by: Mark Brown --- drivers/regulator/fan53555.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/fan53555.c b/drivers/regulator/fan53555.c index 00c83492f774..aa426183b6a1 100644 --- a/drivers/regulator/fan53555.c +++ b/drivers/regulator/fan53555.c @@ -436,7 +436,7 @@ static struct fan53555_platform_data *fan53555_parse_dt(struct device *dev, return pdata; } -static const struct of_device_id fan53555_dt_ids[] = { +static const struct of_device_id __maybe_unused fan53555_dt_ids[] = { { .compatible = "fcs,fan53526", .data = (void *)FAN53526_VENDOR_FAIRCHILD, -- cgit v1.2.3 From 0f037255008386f4ac15a201678e8e4565cd91a3 Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Fri, 21 Aug 2020 11:14:03 +0800 Subject: regulator: fixed: Fix W=1 build warnings when CONFIG_OF=n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix below warnings when CONFIG_OF=n: drivers/regulator/fixed.c:48:36: warning: ‘fixed_clkenable_data’ defined but not used [-Wunused-const-variable=] 48 | static const struct fixed_dev_type fixed_clkenable_data = { | ^~~~~~~~~~~~~~~~~~~~ drivers/regulator/fixed.c:44:36: warning: ‘fixed_voltage_data’ defined but not used [-Wunused-const-variable=] 44 | static const struct fixed_dev_type fixed_voltage_data = { | ^~~~~~~~~~~~~~~~~~ Signed-off-by: Jisheng Zhang Link: https://lore.kernel.org/r/20200821111403.3e8b58a3@xhacker.debian Signed-off-by: Mark Brown --- drivers/regulator/fixed.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c index 142a70a89153..5a03fd86ad0a 100644 --- a/drivers/regulator/fixed.c +++ b/drivers/regulator/fixed.c @@ -41,14 +41,6 @@ struct fixed_dev_type { bool has_enable_clock; }; -static const struct fixed_dev_type fixed_voltage_data = { - .has_enable_clock = false, -}; - -static const struct fixed_dev_type fixed_clkenable_data = { - .has_enable_clock = true, -}; - static int reg_clock_enable(struct regulator_dev *rdev) { struct fixed_voltage_data *priv = rdev_get_drvdata(rdev); @@ -260,6 +252,14 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev) } #if defined(CONFIG_OF) +static const struct fixed_dev_type fixed_voltage_data = { + .has_enable_clock = false, +}; + +static const struct fixed_dev_type fixed_clkenable_data = { + .has_enable_clock = true, +}; + static const struct of_device_id fixed_of_match[] = { { .compatible = "regulator-fixed", -- cgit v1.2.3 From 8ece31564f1964d52eb1180ee33314c63533947e Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Fri, 21 Aug 2020 11:14:49 +0800 Subject: regulator: ltc3589: Fix W=1 build warning when CONFIG_OF=n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix below warning when CONFIG_OF=n: drivers/regulator/ltc3589.c:460:34: warning: ‘ltc3589_of_match’ defined but not used [-Wunused-const-variable=] 460 | static const struct of_device_id ltc3589_of_match[] = { | ^~~~~~~~~~~~~~~~ Signed-off-by: Jisheng Zhang Link: https://lore.kernel.org/r/20200821111449.7cf580f2@xhacker.debian Signed-off-by: Mark Brown --- drivers/regulator/ltc3589.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/ltc3589.c b/drivers/regulator/ltc3589.c index 9a037fdc5fc5..fa563aacf742 100644 --- a/drivers/regulator/ltc3589.c +++ b/drivers/regulator/ltc3589.c @@ -457,7 +457,7 @@ static const struct i2c_device_id ltc3589_i2c_id[] = { }; MODULE_DEVICE_TABLE(i2c, ltc3589_i2c_id); -static const struct of_device_id ltc3589_of_match[] = { +static const struct of_device_id __maybe_unused ltc3589_of_match[] = { { .compatible = "lltc,ltc3589", .data = (void *)LTC3589, -- cgit v1.2.3 From 1d4c1e02b96ea579f68412980ee1fe5f2ce57d8c Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Fri, 21 Aug 2020 11:15:17 +0800 Subject: regulator: ltc3676: Fix W=1 build warning when CONFIG_OF=n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix below warning when CONFIG_OF=n: drivers/regulator/ltc3676.c:371:34: warning: ‘ltc3676_of_match’ defined but not used [-Wunused-const-variable=] 371 | static const struct of_device_id ltc3676_of_match[] = { | ^~~~~~~~~~~~~~~~ Signed-off-by: Jisheng Zhang Link: https://lore.kernel.org/r/20200821111517.59d7b8c8@xhacker.debian Signed-off-by: Mark Brown --- drivers/regulator/ltc3676.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/ltc3676.c b/drivers/regulator/ltc3676.c index 093b3e4a6303..557727b54f0e 100644 --- a/drivers/regulator/ltc3676.c +++ b/drivers/regulator/ltc3676.c @@ -368,7 +368,7 @@ static const struct i2c_device_id ltc3676_i2c_id[] = { }; MODULE_DEVICE_TABLE(i2c, ltc3676_i2c_id); -static const struct of_device_id ltc3676_of_match[] = { +static const struct of_device_id __maybe_unused ltc3676_of_match[] = { { .compatible = "lltc,ltc3676" }, { }, }; -- cgit v1.2.3 From 44bc5d168dc209bddafb3269f72a74c3cbb0d820 Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Fri, 21 Aug 2020 11:16:01 +0800 Subject: regulator: max1586: Fix W=1 build warning when CONFIG_OF=n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix below warning when CONFIG_OF=n: drivers/regulator/max1586.c:204:34: warning: ‘max1586_of_match’ defined but not used [-Wunused-const-variable=] 204 | static const struct of_device_id max1586_of_match[] = { | ^~~~~~~~~~~~~~~~ Signed-off-by: Jisheng Zhang Link: https://lore.kernel.org/r/20200821111601.26243417@xhacker.debian Signed-off-by: Mark Brown --- drivers/regulator/max1586.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c index f8941025780b..d4958394e608 100644 --- a/drivers/regulator/max1586.c +++ b/drivers/regulator/max1586.c @@ -201,7 +201,7 @@ static int of_get_max1586_platform_data(struct device *dev, return 0; } -static const struct of_device_id max1586_of_match[] = { +static const struct of_device_id __maybe_unused max1586_of_match[] = { { .compatible = "maxim,max1586", }, {}, }; -- cgit v1.2.3 From 7bf0a29c354fc1855dc478916211b5194bab4393 Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Fri, 21 Aug 2020 11:16:31 +0800 Subject: regulator: max77826: Fix W=1 build warning when CONFIG_OF=n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix below warning when CONFIG_OF=n: drivers/regulator/max77826-regulator.c:277:34: warning: ‘max77826_of_match’ defined but not used [-Wunused-const-variable=] 277 | static const struct of_device_id max77826_of_match[] = { | ^~~~~~~~~~~~~~~~~ Signed-off-by: Jisheng Zhang Link: https://lore.kernel.org/r/20200821111631.4e799c86@xhacker.debian Signed-off-by: Mark Brown --- drivers/regulator/max77826-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/max77826-regulator.c b/drivers/regulator/max77826-regulator.c index 502ab6afc814..f9e2e884ff54 100644 --- a/drivers/regulator/max77826-regulator.c +++ b/drivers/regulator/max77826-regulator.c @@ -274,7 +274,7 @@ static int max77826_i2c_probe(struct i2c_client *client) return max77826_read_device_id(regmap, dev); } -static const struct of_device_id max77826_of_match[] = { +static const struct of_device_id __maybe_unused max77826_of_match[] = { { .compatible = "maxim,max77826" }, { /* sentinel */ } }; -- cgit v1.2.3 From dc8c5ea3574e08e3c7105bbba5af5bb9c055903b Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Fri, 21 Aug 2020 11:16:57 +0800 Subject: regulator: pwm: Fix W=1 build warning when CONFIG_OF=n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix below warning when CONFIG_OF=n: drivers/regulator/pwm-regulator.c:393:34: warning: ‘pwm_of_match’ defined but not used [-Wunused-const-variable=] 393 | static const struct of_device_id pwm_of_match[] = { | ^~~~~~~~~~~~ Signed-off-by: Jisheng Zhang Link: https://lore.kernel.org/r/20200821111658.59a7218b@xhacker.debian Signed-off-by: Mark Brown --- drivers/regulator/pwm-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/pwm-regulator.c b/drivers/regulator/pwm-regulator.c index 3234b118b53e..d250e60f1625 100644 --- a/drivers/regulator/pwm-regulator.c +++ b/drivers/regulator/pwm-regulator.c @@ -390,7 +390,7 @@ static int pwm_regulator_probe(struct platform_device *pdev) return 0; } -static const struct of_device_id pwm_of_match[] = { +static const struct of_device_id __maybe_unused pwm_of_match[] = { { .compatible = "pwm-regulator" }, { }, }; -- cgit v1.2.3 From a94a11ce0d5235e53bb74d54bbd5399c23abfd87 Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Fri, 21 Aug 2020 11:17:26 +0800 Subject: regulator: stm32-pwr: Fix W=1 build warning when CONFIG_OF=n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix below warning when CONFIG_OF=n: drivers/regulator/stm32-pwr.c:169:34: warning: ‘stm32_pwr_of_match’ defined but not used [-Wunused-const-variable=] 169 | static const struct of_device_id stm32_pwr_of_match[] = { | ^~~~~~~~~~~~~~~~~~ Signed-off-by: Jisheng Zhang Link: https://lore.kernel.org/r/20200821111726.38e0e746@xhacker.debian Signed-off-by: Mark Brown --- drivers/regulator/stm32-pwr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/stm32-pwr.c b/drivers/regulator/stm32-pwr.c index e0e627b0106e..2a42acb7c24e 100644 --- a/drivers/regulator/stm32-pwr.c +++ b/drivers/regulator/stm32-pwr.c @@ -166,7 +166,7 @@ static int stm32_pwr_regulator_probe(struct platform_device *pdev) return ret; } -static const struct of_device_id stm32_pwr_of_match[] = { +static const struct of_device_id __maybe_unused stm32_pwr_of_match[] = { { .compatible = "st,stm32mp1,pwr-reg", }, {}, }; -- cgit v1.2.3 From d5579e7a2c6aa49a183440eb4e199f4a71543762 Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Fri, 21 Aug 2020 11:17:55 +0800 Subject: regulator: stm32-vrefbuf: Fix W=1 build warning when CONFIG_OF=n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix below warning when CONFIG_OF=n: drivers/regulator/stm32-vrefbuf.c:287:34: warning: ‘stm32_vrefbuf_of_match’ defined but not used [-Wunused-const-variable=] 287 | static const struct of_device_id stm32_vrefbuf_of_match[] = { | ^~~~~~~~~~~~~~~~~~~~~~ Signed-off-by: Jisheng Zhang Acked-by: Fabrice Gasnier Link: https://lore.kernel.org/r/20200821111755.4c461039@xhacker.debian Signed-off-by: Mark Brown --- drivers/regulator/stm32-vrefbuf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/stm32-vrefbuf.c b/drivers/regulator/stm32-vrefbuf.c index 992bc18101ef..161622ea7259 100644 --- a/drivers/regulator/stm32-vrefbuf.c +++ b/drivers/regulator/stm32-vrefbuf.c @@ -284,7 +284,7 @@ static const struct dev_pm_ops stm32_vrefbuf_pm_ops = { NULL) }; -static const struct of_device_id stm32_vrefbuf_of_match[] = { +static const struct of_device_id __maybe_unused stm32_vrefbuf_of_match[] = { { .compatible = "st,stm32-vrefbuf", }, {}, }; -- cgit v1.2.3 From bbe26107204eb64e7be1b3433e8b2252edc0b375 Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Fri, 21 Aug 2020 11:18:20 +0800 Subject: regulator: sy8106a: Fix W=1 build warning when CONFIG_OF=n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix below warning when CONFIG_OF=n: drivers/regulator/sy8106a-regulator.c:126:34: warning: ‘sy8106a_i2c_of_match’ defined but not used [-Wunused-const-variable=] 126 | static const struct of_device_id sy8106a_i2c_of_match[] = { | ^~~~~~~~~~~~~~~~~~~~ Signed-off-by: Jisheng Zhang Link: https://lore.kernel.org/r/20200821111820.5c6ddb04@xhacker.debian Signed-off-by: Mark Brown --- drivers/regulator/sy8106a-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/sy8106a-regulator.c b/drivers/regulator/sy8106a-regulator.c index 2222e739e62b..c119f85259a5 100644 --- a/drivers/regulator/sy8106a-regulator.c +++ b/drivers/regulator/sy8106a-regulator.c @@ -123,7 +123,7 @@ static int sy8106a_i2c_probe(struct i2c_client *i2c) return 0; } -static const struct of_device_id sy8106a_i2c_of_match[] = { +static const struct of_device_id __maybe_unused sy8106a_i2c_of_match[] = { { .compatible = "silergy,sy8106a" }, { }, }; -- cgit v1.2.3 From a2508eeb8dbdf621518f8c3538d3adcb6960619c Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Fri, 21 Aug 2020 11:19:13 +0800 Subject: regulator: qcom-rpmh: Fix W=1 build warning when CONFIG_OF=n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix below warning when CONFIG_OF=n: drivers/regulator/qcom-rpmh-regulator.c:970:34: warning: ‘rpmh_regulator_match_table’ defined but not used [-Wunused-const-variable=] 970 | static const struct of_device_id rpmh_regulator_match_table[] = { | ^~~~~~~~~~~~~~~~~~~~~~~~~~ Signed-off-by: Jisheng Zhang Link: https://lore.kernel.org/r/20200821111913.1096f7cc@xhacker.debian Signed-off-by: Mark Brown --- drivers/regulator/qcom-rpmh-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/qcom-rpmh-regulator.c b/drivers/regulator/qcom-rpmh-regulator.c index 08dcc614efa7..d488325499a9 100644 --- a/drivers/regulator/qcom-rpmh-regulator.c +++ b/drivers/regulator/qcom-rpmh-regulator.c @@ -967,7 +967,7 @@ static int rpmh_regulator_probe(struct platform_device *pdev) return 0; } -static const struct of_device_id rpmh_regulator_match_table[] = { +static const struct of_device_id __maybe_unused rpmh_regulator_match_table[] = { { .compatible = "qcom,pm8005-rpmh-regulators", .data = pm8005_vreg_data, -- cgit v1.2.3 From b461ac1cc6c0a0bc4a788d5d65cfd82e5f3bd856 Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Fri, 21 Aug 2020 11:19:43 +0800 Subject: regulator: stm32-booster: Fix W=1 build warning when CONFIG_OF=n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix below warning when CONFIG_OF=n: drivers/regulator/stm32-booster.c:104:34: warning: ‘stm32_booster_of_match’ defined but not used [-Wunused-const-variable=] 104 | static const struct of_device_id stm32_booster_of_match[] = { | ^~~~~~~~~~~~~~~~~~~~~~ Signed-off-by: Jisheng Zhang Acked-by: Fabrice Gasnier Link: https://lore.kernel.org/r/20200821111943.29b2b4ca@xhacker.debian Signed-off-by: Mark Brown --- drivers/regulator/stm32-booster.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/stm32-booster.c b/drivers/regulator/stm32-booster.c index 03f162ffd144..3136ea8a35d5 100644 --- a/drivers/regulator/stm32-booster.c +++ b/drivers/regulator/stm32-booster.c @@ -101,7 +101,7 @@ static int stm32_booster_probe(struct platform_device *pdev) return 0; } -static const struct of_device_id stm32_booster_of_match[] = { +static const struct of_device_id __maybe_unused stm32_booster_of_match[] = { { .compatible = "st,stm32h7-booster", .data = (void *)&stm32h7_booster_desc -- cgit v1.2.3 From 8536bf811dd7a25d90d9128f9db98b5ed8e5bd5c Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Fri, 21 Aug 2020 11:20:09 +0800 Subject: regulator: tps65023: Fix W=1 build warning when CONFIG_OF=n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix below warning when CONFIG_OF=n: drivers/regulator/tps65023-regulator.c:319:34: warning: ‘tps65023_of_match’ defined but not used [-Wunused-const-variable=] 319 | static const struct of_device_id tps65023_of_match[] = { | ^~~~~~~~~~~~~~~~~ Signed-off-by: Jisheng Zhang Link: https://lore.kernel.org/r/20200821112009.58ee8511@xhacker.debian Signed-off-by: Mark Brown --- drivers/regulator/tps65023-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c index 795d459ff3cf..f25806531c7e 100644 --- a/drivers/regulator/tps65023-regulator.c +++ b/drivers/regulator/tps65023-regulator.c @@ -316,7 +316,7 @@ static int tps_65023_probe(struct i2c_client *client, return 0; } -static const struct of_device_id tps65023_of_match[] = { +static const struct of_device_id __maybe_unused tps65023_of_match[] = { { .compatible = "ti,tps65020", .data = &tps65020_drv_data}, { .compatible = "ti,tps65021", .data = &tps65021_drv_data}, { .compatible = "ti,tps65023", .data = &tps65023_drv_data}, -- cgit v1.2.3 From c0e53a448637366064d4b9ce586b68ced679cd22 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 21 Aug 2020 11:48:23 -0300 Subject: regulator: dbx500: Remove unused debugfs goto label The following build warning is seen after commit 8bdaa43808b7 ("regulator: dbx500: no need to check return value of debugfs_create functions"): drivers/regulator/dbx500-prcmu.c:144:1: warning: label 'exit_no_debugfs' defined but not used [-Wunused-label] Remove the unused label and its associated error message. Fixes: 8bdaa43808b7 ("regulator: dbx500: no need to check return value of debugfs_create functions") Reported-by: Olof's autobuilder Signed-off-by: Fabio Estevam Link: https://lore.kernel.org/r/20200821144823.13404-1-festevam@gmail.com Signed-off-by: Mark Brown --- drivers/regulator/dbx500-prcmu.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/dbx500-prcmu.c b/drivers/regulator/dbx500-prcmu.c index 7395ad2105ab..8b70bfe88019 100644 --- a/drivers/regulator/dbx500-prcmu.c +++ b/drivers/regulator/dbx500-prcmu.c @@ -141,8 +141,6 @@ exit_free: kfree(rdebug.state_before_suspend); exit_destroy_power_state: debugfs_remove_recursive(rdebug.dir); -exit_no_debugfs: - dev_err(&pdev->dev, "failed to create debugfs entries.\n"); return -ENOMEM; } -- cgit v1.2.3 From a5f7949570dc7262d3239739b0cdaa001f935d4b Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Mon, 24 Aug 2020 10:32:14 +0800 Subject: regulator: mp886x: use "mps,switch-frequency-hz" As Rob suggested, use the "mps,switch-frequency-hz" instead of the "mps,switch-frequency" for switch frequency. Fortunately, the switch frequency support isn't released, so we can modify it now without any concern. Signed-off-by: Jisheng Zhang Link: https://lore.kernel.org/r/20200824102402.4047fa5f@xhacker.debian Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/regulator/mp886x.txt | 2 +- drivers/regulator/mp886x.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/regulator') diff --git a/Documentation/devicetree/bindings/regulator/mp886x.txt b/Documentation/devicetree/bindings/regulator/mp886x.txt index e747000cebba..b05307bbb0d9 100644 --- a/Documentation/devicetree/bindings/regulator/mp886x.txt +++ b/Documentation/devicetree/bindings/regulator/mp886x.txt @@ -10,7 +10,7 @@ Required properties: values R1 and R2 of the feedback voltage divider in kilo ohms. Optional properties: -- mps,switch-frequency: The valid switch frequency in Hertz. Available values +- mps,switch-frequency-hz: The valid switch frequency in Hertz. Available values are: 500000, 750000, 1000000, 1250000, 1500000 Any property defined as part of the core regulator binding, defined in diff --git a/drivers/regulator/mp886x.c b/drivers/regulator/mp886x.c index 97dc44c0d663..a84fd74081de 100644 --- a/drivers/regulator/mp886x.c +++ b/drivers/regulator/mp886x.c @@ -349,7 +349,7 @@ static int mp886x_i2c_probe(struct i2c_client *client) config.driver_data = di; config.of_node = np; - if (!of_property_read_u32(np, "mps,switch-frequency", &freq)) + if (!of_property_read_u32(np, "mps,switch-frequency-hz", &freq)) mp886x_set_switch_freq(di, regmap, freq); ret = mp886x_regulator_register(di, &config); -- cgit v1.2.3 From c8b2c8949c45b01d75237331fc1387036b952d58 Mon Sep 17 00:00:00 2001 From: ChiYuan Huang Date: Mon, 24 Aug 2020 10:05:13 +0800 Subject: regulator: rt4801: Fix W=1 build warning when CONFIG_OF=n Fix below warning when CONFIG_OF=n: drivers/regulator/rt4801-regulator.c:206:34: warning: unused variable 'rt4801_of_id' [-Wunused-const-variable] 206 | static const struct of_device_id rt4801_of_id[] = { | ^~~~~~~~~~~~ Signed-off-by: ChiYuan Huang Reported-by: kernel test robot Link: https://lore.kernel.org/r/1598234713-8532-1-git-send-email-u0084500@gmail.com Signed-off-by: Mark Brown --- drivers/regulator/rt4801-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/rt4801-regulator.c b/drivers/regulator/rt4801-regulator.c index 0ddc670a3888..2055a9cb13ba 100644 --- a/drivers/regulator/rt4801-regulator.c +++ b/drivers/regulator/rt4801-regulator.c @@ -203,7 +203,7 @@ static int rt4801_probe(struct i2c_client *i2c) return 0; } -static const struct of_device_id rt4801_of_id[] = { +static const struct of_device_id __maybe_unused rt4801_of_id[] = { { .compatible = "richtek,rt4801", }, { }, }; -- cgit v1.2.3 From d321571d5e4c2d5511b75e6cf1a910e0a0c2a2e9 Mon Sep 17 00:00:00 2001 From: Gene Chen Date: Wed, 26 Aug 2020 18:49:17 +0800 Subject: regulator: mt6360: Add support for MT6360 regulator Add MT6360 regulator driver that contains two BUCKs and six LDOs Signed-off-by: Gene Chen Link: https://lore.kernel.org/r/1598438958-26802-2-git-send-email-gene.chen.richtek@gmail.com Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 9 + drivers/regulator/Makefile | 1 + drivers/regulator/mt6360-regulator.c | 459 +++++++++++++++++++++ .../regulator/mediatek,mt6360-regulator.h | 16 + 4 files changed, 485 insertions(+) create mode 100644 drivers/regulator/mt6360-regulator.c create mode 100644 include/dt-bindings/regulator/mediatek,mt6360-regulator.h (limited to 'drivers/regulator') diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index f719ed5a8c33..0c0b4f3652fb 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -711,6 +711,15 @@ config REGULATOR_MT6358 This driver supports the control of different power rails of device through regulator interface. +config REGULATOR_MT6360 + tristate "MT6360 SubPMIC Regulator" + depends on MFD_MT6360 + help + Say Y here to enable MT6360 regulator support. + This is support MT6360 PMIC/LDO part include + 2-channel buck with Thermal Shutdown and Overload Protection + 6-channel High PSRR and Low Dropout LDO. + config REGULATOR_MT6380 tristate "MediaTek MT6380 PMIC" depends on MTK_PMIC_WRAP diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 9f478e5687b6..d958cc8c5360 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -88,6 +88,7 @@ obj-$(CONFIG_REGULATOR_MPQ7920) += mpq7920.o obj-$(CONFIG_REGULATOR_MT6311) += mt6311-regulator.o obj-$(CONFIG_REGULATOR_MT6323) += mt6323-regulator.o obj-$(CONFIG_REGULATOR_MT6358) += mt6358-regulator.o +obj-$(CONFIG_REGULATOR_MT6360) += mt6360-regulator.o obj-$(CONFIG_REGULATOR_MT6380) += mt6380-regulator.o obj-$(CONFIG_REGULATOR_MT6397) += mt6397-regulator.o obj-$(CONFIG_REGULATOR_QCOM_LABIBB) += qcom-labibb-regulator.o diff --git a/drivers/regulator/mt6360-regulator.c b/drivers/regulator/mt6360-regulator.c new file mode 100644 index 000000000000..89ce379520ed --- /dev/null +++ b/drivers/regulator/mt6360-regulator.c @@ -0,0 +1,459 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright (C) 2020 MediaTek Inc. +// +// Author: Gene Chen + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +enum { + MT6360_REGULATOR_BUCK1 = 0, + MT6360_REGULATOR_BUCK2, + MT6360_REGULATOR_LDO6, + MT6360_REGULATOR_LDO7, + MT6360_REGULATOR_LDO1, + MT6360_REGULATOR_LDO2, + MT6360_REGULATOR_LDO3, + MT6360_REGULATOR_LDO5, + MT6360_REGULATOR_MAX, +}; + +struct mt6360_irq_mapping { + const char *name; + irq_handler_t handler; +}; + +struct mt6360_regulator_desc { + const struct regulator_desc desc; + unsigned int mode_reg; + unsigned int mode_mask; + unsigned int state_reg; + unsigned int state_mask; + const struct mt6360_irq_mapping *irq_tables; + int irq_table_size; +}; + +struct mt6360_regulator_data { + struct device *dev; + struct regmap *regmap; +}; + +static irqreturn_t mt6360_pgb_event_handler(int irq, void *data) +{ + struct regulator_dev *rdev = data; + + regulator_notifier_call_chain(rdev, REGULATOR_EVENT_FAIL, NULL); + return IRQ_HANDLED; +} + +static irqreturn_t mt6360_oc_event_handler(int irq, void *data) +{ + struct regulator_dev *rdev = data; + + regulator_notifier_call_chain(rdev, REGULATOR_EVENT_OVER_CURRENT, NULL); + return IRQ_HANDLED; +} + +static irqreturn_t mt6360_ov_event_handler(int irq, void *data) +{ + struct regulator_dev *rdev = data; + + regulator_notifier_call_chain(rdev, REGULATOR_EVENT_REGULATION_OUT, NULL); + return IRQ_HANDLED; +} + +static irqreturn_t mt6360_uv_event_handler(int irq, void *data) +{ + struct regulator_dev *rdev = data; + + regulator_notifier_call_chain(rdev, REGULATOR_EVENT_UNDER_VOLTAGE, NULL); + return IRQ_HANDLED; +} + +static const struct mt6360_irq_mapping buck1_irq_tbls[] = { + { "buck1_pgb_evt", mt6360_pgb_event_handler }, + { "buck1_oc_evt", mt6360_oc_event_handler }, + { "buck1_ov_evt", mt6360_ov_event_handler }, + { "buck1_uv_evt", mt6360_uv_event_handler }, +}; + +static const struct mt6360_irq_mapping buck2_irq_tbls[] = { + { "buck2_pgb_evt", mt6360_pgb_event_handler }, + { "buck2_oc_evt", mt6360_oc_event_handler }, + { "buck2_ov_evt", mt6360_ov_event_handler }, + { "buck2_uv_evt", mt6360_uv_event_handler }, +}; + +static const struct mt6360_irq_mapping ldo6_irq_tbls[] = { + { "ldo6_pgb_evt", mt6360_pgb_event_handler }, + { "ldo6_oc_evt", mt6360_oc_event_handler }, +}; + +static const struct mt6360_irq_mapping ldo7_irq_tbls[] = { + { "ldo7_pgb_evt", mt6360_pgb_event_handler }, + { "ldo7_oc_evt", mt6360_oc_event_handler }, +}; + +static const struct mt6360_irq_mapping ldo1_irq_tbls[] = { + { "ldo1_pgb_evt", mt6360_pgb_event_handler }, + { "ldo1_oc_evt", mt6360_oc_event_handler }, +}; + +static const struct mt6360_irq_mapping ldo2_irq_tbls[] = { + { "ldo2_pgb_evt", mt6360_pgb_event_handler }, + { "ldo2_oc_evt", mt6360_oc_event_handler }, +}; + +static const struct mt6360_irq_mapping ldo3_irq_tbls[] = { + { "ldo3_pgb_evt", mt6360_pgb_event_handler }, + { "ldo3_oc_evt", mt6360_oc_event_handler }, +}; + +static const struct mt6360_irq_mapping ldo5_irq_tbls[] = { + { "ldo5_pgb_evt", mt6360_pgb_event_handler }, + { "ldo5_oc_evt", mt6360_oc_event_handler }, +}; + +static const struct linear_range buck_vout_ranges[] = { + REGULATOR_LINEAR_RANGE(300000, 0x00, 0xc7, 5000), + REGULATOR_LINEAR_RANGE(1300000, 0xc8, 0xff, 0), +}; + +static const struct linear_range ldo_vout_ranges1[] = { + REGULATOR_LINEAR_RANGE(500000, 0x00, 0x09, 10000), + REGULATOR_LINEAR_RANGE(600000, 0x0a, 0x10, 0), + REGULATOR_LINEAR_RANGE(610000, 0x11, 0x19, 10000), + REGULATOR_LINEAR_RANGE(700000, 0x1a, 0x20, 0), + REGULATOR_LINEAR_RANGE(710000, 0x21, 0x29, 10000), + REGULATOR_LINEAR_RANGE(800000, 0x2a, 0x30, 0), + REGULATOR_LINEAR_RANGE(810000, 0x31, 0x39, 10000), + REGULATOR_LINEAR_RANGE(900000, 0x3a, 0x40, 0), + REGULATOR_LINEAR_RANGE(910000, 0x41, 0x49, 10000), + REGULATOR_LINEAR_RANGE(1000000, 0x4a, 0x50, 0), + REGULATOR_LINEAR_RANGE(1010000, 0x51, 0x59, 10000), + REGULATOR_LINEAR_RANGE(1100000, 0x5a, 0x60, 0), + REGULATOR_LINEAR_RANGE(1110000, 0x61, 0x69, 10000), + REGULATOR_LINEAR_RANGE(1200000, 0x6a, 0x70, 0), + REGULATOR_LINEAR_RANGE(1210000, 0x71, 0x79, 10000), + REGULATOR_LINEAR_RANGE(1300000, 0x7a, 0x80, 0), + REGULATOR_LINEAR_RANGE(1310000, 0x81, 0x89, 10000), + REGULATOR_LINEAR_RANGE(1400000, 0x8a, 0x90, 0), + REGULATOR_LINEAR_RANGE(1410000, 0x91, 0x99, 10000), + REGULATOR_LINEAR_RANGE(1500000, 0x9a, 0xa0, 0), + REGULATOR_LINEAR_RANGE(1510000, 0xa1, 0xa9, 10000), + REGULATOR_LINEAR_RANGE(1600000, 0xaa, 0xb0, 0), + REGULATOR_LINEAR_RANGE(1610000, 0xb1, 0xb9, 10000), + REGULATOR_LINEAR_RANGE(1700000, 0xba, 0xc0, 0), + REGULATOR_LINEAR_RANGE(1710000, 0xc1, 0xc9, 10000), + REGULATOR_LINEAR_RANGE(1800000, 0xca, 0xd0, 0), + REGULATOR_LINEAR_RANGE(1810000, 0xd1, 0xd9, 10000), + REGULATOR_LINEAR_RANGE(1900000, 0xda, 0xe0, 0), + REGULATOR_LINEAR_RANGE(1910000, 0xe1, 0xe9, 10000), + REGULATOR_LINEAR_RANGE(2000000, 0xea, 0xf0, 0), + REGULATOR_LINEAR_RANGE(2010000, 0xf1, 0xf9, 10000), + REGULATOR_LINEAR_RANGE(2100000, 0xfa, 0xff, 0), +}; + +static const struct linear_range ldo_vout_ranges2[] = { + REGULATOR_LINEAR_RANGE(1200000, 0x00, 0x09, 10000), + REGULATOR_LINEAR_RANGE(1300000, 0x0a, 0x10, 0), + REGULATOR_LINEAR_RANGE(1310000, 0x11, 0x19, 10000), + REGULATOR_LINEAR_RANGE(1400000, 0x1a, 0x1f, 0), + REGULATOR_LINEAR_RANGE(1500000, 0x20, 0x29, 10000), + REGULATOR_LINEAR_RANGE(1600000, 0x2a, 0x2f, 0), + REGULATOR_LINEAR_RANGE(1700000, 0x30, 0x39, 10000), + REGULATOR_LINEAR_RANGE(1800000, 0x3a, 0x40, 0), + REGULATOR_LINEAR_RANGE(1810000, 0x41, 0x49, 10000), + REGULATOR_LINEAR_RANGE(1900000, 0x4a, 0x4f, 0), + REGULATOR_LINEAR_RANGE(2000000, 0x50, 0x59, 10000), + REGULATOR_LINEAR_RANGE(2100000, 0x5a, 0x60, 0), + REGULATOR_LINEAR_RANGE(2110000, 0x61, 0x69, 10000), + REGULATOR_LINEAR_RANGE(2200000, 0x6a, 0x6f, 0), + REGULATOR_LINEAR_RANGE(2500000, 0x70, 0x79, 10000), + REGULATOR_LINEAR_RANGE(2600000, 0x7a, 0x7f, 0), + REGULATOR_LINEAR_RANGE(2700000, 0x80, 0x89, 10000), + REGULATOR_LINEAR_RANGE(2800000, 0x8a, 0x90, 0), + REGULATOR_LINEAR_RANGE(2810000, 0x91, 0x99, 10000), + REGULATOR_LINEAR_RANGE(2900000, 0x9a, 0xa0, 0), + REGULATOR_LINEAR_RANGE(2910000, 0xa1, 0xa9, 10000), + REGULATOR_LINEAR_RANGE(3000000, 0xaa, 0xb0, 0), + REGULATOR_LINEAR_RANGE(3010000, 0xb1, 0xb9, 10000), + REGULATOR_LINEAR_RANGE(3100000, 0xba, 0xc0, 0), + REGULATOR_LINEAR_RANGE(3110000, 0xc1, 0xc9, 10000), + REGULATOR_LINEAR_RANGE(3200000, 0xca, 0xcf, 0), + REGULATOR_LINEAR_RANGE(3300000, 0xd0, 0xd9, 10000), + REGULATOR_LINEAR_RANGE(3400000, 0xda, 0xe0, 0), + REGULATOR_LINEAR_RANGE(3410000, 0xe1, 0xe9, 10000), + REGULATOR_LINEAR_RANGE(3500000, 0xea, 0xf0, 0), + REGULATOR_LINEAR_RANGE(3510000, 0xf1, 0xf9, 10000), + REGULATOR_LINEAR_RANGE(3600000, 0xfa, 0xff, 0), +}; + +static const struct linear_range ldo_vout_ranges3[] = { + REGULATOR_LINEAR_RANGE(2700000, 0x00, 0x09, 10000), + REGULATOR_LINEAR_RANGE(2800000, 0x0a, 0x10, 0), + REGULATOR_LINEAR_RANGE(2810000, 0x11, 0x19, 10000), + REGULATOR_LINEAR_RANGE(2900000, 0x1a, 0x20, 0), + REGULATOR_LINEAR_RANGE(2910000, 0x21, 0x29, 10000), + REGULATOR_LINEAR_RANGE(3000000, 0x2a, 0x30, 0), + REGULATOR_LINEAR_RANGE(3010000, 0x31, 0x39, 10000), + REGULATOR_LINEAR_RANGE(3100000, 0x3a, 0x40, 0), + REGULATOR_LINEAR_RANGE(3110000, 0x41, 0x49, 10000), + REGULATOR_LINEAR_RANGE(3200000, 0x4a, 0x4f, 0), + REGULATOR_LINEAR_RANGE(3300000, 0x50, 0x59, 10000), + REGULATOR_LINEAR_RANGE(3400000, 0x5a, 0x60, 0), + REGULATOR_LINEAR_RANGE(3410000, 0x61, 0x69, 10000), + REGULATOR_LINEAR_RANGE(3500000, 0x6a, 0x70, 0), + REGULATOR_LINEAR_RANGE(3510000, 0x71, 0x79, 10000), + REGULATOR_LINEAR_RANGE(3600000, 0x7a, 0x7f, 0), +}; + +static int mt6360_regulator_set_mode(struct regulator_dev *rdev, + unsigned int mode) +{ + const struct mt6360_regulator_desc *rdesc = (struct mt6360_regulator_desc *)rdev->desc; + struct regmap *regmap = rdev_get_regmap(rdev); + int shift = ffs(rdesc->mode_mask) - 1; + unsigned int val; + int ret; + + switch (mode) { + case REGULATOR_MODE_NORMAL: + val = MT6360_OPMODE_NORMAL; + break; + case REGULATOR_MODE_STANDBY: + val = MT6360_OPMODE_ULP; + break; + case REGULATOR_MODE_IDLE: + val = MT6360_OPMODE_LP; + break; + default: + return -EINVAL; + } + + ret = regmap_update_bits(regmap, rdesc->mode_reg, rdesc->mode_mask, val << shift); + if (ret) { + dev_err(&rdev->dev, "%s: fail (%d)\n", __func__, ret); + return ret; + } + + return 0; +} + +static unsigned int mt6360_regulator_get_mode(struct regulator_dev *rdev) +{ + const struct mt6360_regulator_desc *rdesc = (struct mt6360_regulator_desc *)rdev->desc; + struct regmap *regmap = rdev_get_regmap(rdev); + int shift = ffs(rdesc->mode_mask) - 1; + unsigned int val; + int ret; + + ret = regmap_read(regmap, rdesc->mode_reg, &val); + if (ret) + return ret; + + val &= rdesc->mode_mask; + val >>= shift; + + switch (val) { + case MT6360_OPMODE_LP: + return REGULATOR_MODE_IDLE; + case MT6360_OPMODE_ULP: + return REGULATOR_MODE_STANDBY; + case MT6360_OPMODE_NORMAL: + return REGULATOR_MODE_NORMAL; + default: + return -EINVAL; + } +} + +static int mt6360_regulator_get_status(struct regulator_dev *rdev) +{ + const struct mt6360_regulator_desc *rdesc = (struct mt6360_regulator_desc *)rdev->desc; + struct regmap *regmap = rdev_get_regmap(rdev); + unsigned int val; + int ret; + + ret = regmap_read(regmap, rdesc->state_reg, &val); + if (ret) + return ret; + + if (val & rdesc->state_mask) + return REGULATOR_STATUS_ON; + + return REGULATOR_STATUS_OFF; +} + +static const struct regulator_ops mt6360_regulator_ops = { + .list_voltage = regulator_list_voltage_linear_range, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_mode = mt6360_regulator_set_mode, + .get_mode = mt6360_regulator_get_mode, + .get_status = mt6360_regulator_get_status, +}; + +static unsigned int mt6360_regulator_of_map_mode(unsigned int hw_mode) +{ + switch (hw_mode) { + case MT6360_OPMODE_NORMAL: + return REGULATOR_MODE_NORMAL; + case MT6360_OPMODE_LP: + return REGULATOR_MODE_IDLE; + case MT6360_OPMODE_ULP: + return REGULATOR_MODE_STANDBY; + default: + return REGULATOR_MODE_INVALID; + } +} + +#define MT6360_REGULATOR_DESC(_name, _sname, ereg, emask, vreg, vmask, \ + mreg, mmask, streg, stmask, vranges, \ + vcnts, offon_delay, irq_tbls) \ +{ \ + .desc = { \ + .name = #_name, \ + .supply_name = #_sname, \ + .id = MT6360_REGULATOR_##_name, \ + .of_match = of_match_ptr(#_name), \ + .regulators_node = of_match_ptr("regulator"), \ + .of_map_mode = mt6360_regulator_of_map_mode, \ + .owner = THIS_MODULE, \ + .ops = &mt6360_regulator_ops, \ + .type = REGULATOR_VOLTAGE, \ + .vsel_reg = vreg, \ + .vsel_mask = vmask, \ + .enable_reg = ereg, \ + .enable_mask = emask, \ + .linear_ranges = vranges, \ + .n_linear_ranges = ARRAY_SIZE(vranges), \ + .n_voltages = vcnts, \ + .off_on_delay = offon_delay, \ + }, \ + .mode_reg = mreg, \ + .mode_mask = mmask, \ + .state_reg = streg, \ + .state_mask = stmask, \ + .irq_tables = irq_tbls, \ + .irq_table_size = ARRAY_SIZE(irq_tbls), \ +} + +static const struct mt6360_regulator_desc mt6360_regulator_descs[] = { + MT6360_REGULATOR_DESC(BUCK1, BUCK1_VIN, 0x117, 0x40, 0x110, 0xff, 0x117, 0x30, 0x117, 0x04, + buck_vout_ranges, 256, 0, buck1_irq_tbls), + MT6360_REGULATOR_DESC(BUCK2, BUCK2_VIN, 0x127, 0x40, 0x120, 0xff, 0x127, 0x30, 0x127, 0x04, + buck_vout_ranges, 256, 0, buck2_irq_tbls), + MT6360_REGULATOR_DESC(LDO6, LDO_VIN3, 0x137, 0x40, 0x13B, 0xff, 0x137, 0x30, 0x137, 0x04, + ldo_vout_ranges1, 256, 0, ldo6_irq_tbls), + MT6360_REGULATOR_DESC(LDO7, LDO_VIN3, 0x131, 0x40, 0x135, 0xff, 0x131, 0x30, 0x131, 0x04, + ldo_vout_ranges1, 256, 0, ldo7_irq_tbls), + MT6360_REGULATOR_DESC(LDO1, LDO_VIN1, 0x217, 0x40, 0x21B, 0xff, 0x217, 0x30, 0x217, 0x04, + ldo_vout_ranges2, 256, 0, ldo1_irq_tbls), + MT6360_REGULATOR_DESC(LDO2, LDO_VIN1, 0x211, 0x40, 0x215, 0xff, 0x211, 0x30, 0x211, 0x04, + ldo_vout_ranges2, 256, 0, ldo2_irq_tbls), + MT6360_REGULATOR_DESC(LDO3, LDO_VIN1, 0x205, 0x40, 0x209, 0xff, 0x205, 0x30, 0x205, 0x04, + ldo_vout_ranges2, 256, 100, ldo3_irq_tbls), + MT6360_REGULATOR_DESC(LDO5, LDO_VIN2, 0x20B, 0x40, 0x20F, 0x7f, 0x20B, 0x30, 0x20B, 0x04, + ldo_vout_ranges3, 128, 100, ldo5_irq_tbls), +}; + +static int mt6360_regulator_irq_register(struct platform_device *pdev, + struct regulator_dev *rdev, + const struct mt6360_irq_mapping *tbls, + int tbl_size) +{ + int i, irq, ret; + + for (i = 0; i < tbl_size; i++) { + const struct mt6360_irq_mapping *irq_desc = tbls + i; + + irq = platform_get_irq_byname(pdev, irq_desc->name); + if (irq < 0) { + dev_err(&pdev->dev, "Fail to get %s irq\n", irq_desc->name); + return irq; + } + + ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, irq_desc->handler, 0, + irq_desc->name, rdev); + if (ret) { + dev_err(&pdev->dev, "Fail to request %s irq\n", irq_desc->name); + return ret; + } + } + + return 0; +} + +static int mt6360_regulator_probe(struct platform_device *pdev) +{ + struct mt6360_regulator_data *mrd; + struct regulator_config config = {}; + int i, ret; + + mrd = devm_kzalloc(&pdev->dev, sizeof(*mrd), GFP_KERNEL); + if (!mrd) + return -ENOMEM; + + mrd->dev = &pdev->dev; + + mrd->regmap = dev_get_regmap(pdev->dev.parent, NULL); + if (!mrd->regmap) { + dev_err(&pdev->dev, "Failed to get parent regmap\n"); + return -ENODEV; + } + + config.dev = pdev->dev.parent; + config.driver_data = mrd; + config.regmap = mrd->regmap; + + for (i = 0; i < ARRAY_SIZE(mt6360_regulator_descs); i++) { + const struct mt6360_regulator_desc *rdesc = mt6360_regulator_descs + i; + struct regulator_dev *rdev; + + rdev = devm_regulator_register(&pdev->dev, &rdesc->desc, &config); + if (IS_ERR(rdev)) { + dev_err(&pdev->dev, "Failed to register %d regulaotr\n", i); + return PTR_ERR(rdev); + } + + ret = mt6360_regulator_irq_register(pdev, rdev, rdesc->irq_tables, + rdesc->irq_table_size); + if (ret) { + dev_err(&pdev->dev, "Failed to register %d regulaotr irqs\n", i); + return ret; + } + } + + return 0; +} + +static const struct platform_device_id mt6360_regulator_id_table[] = { + { "mt6360-regulator", 0 }, + {}, +}; +MODULE_DEVICE_TABLE(platform, mt6360_regulator_id_table); + +static struct platform_driver mt6360_regulator_driver = { + .driver = { + .name = "mt6360-regulator", + }, + .probe = mt6360_regulator_probe, + .id_table = mt6360_regulator_id_table, +}; +module_platform_driver(mt6360_regulator_driver); + +MODULE_AUTHOR("Gene Chen "); +MODULE_DESCRIPTION("MT6360 Regulator Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/include/dt-bindings/regulator/mediatek,mt6360-regulator.h b/include/dt-bindings/regulator/mediatek,mt6360-regulator.h new file mode 100644 index 000000000000..21c75de700c0 --- /dev/null +++ b/include/dt-bindings/regulator/mediatek,mt6360-regulator.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __DT_BINDINGS_MEDIATEK_MT6360_REGULATOR_H__ +#define __DT_BINDINGS_MEDIATEK_MT6360_REGULATOR_H__ + +/* + * BUCK/LDO mode constants which may be used in devicetree properties + * (eg. regulator-allowed-modes). + * See the manufacturer's datasheet for more information on these modes. + */ + +#define MT6360_OPMODE_LP 2 +#define MT6360_OPMODE_ULP 3 +#define MT6360_OPMODE_NORMAL 0 + +#endif -- cgit v1.2.3 From 18ccf8b9f8645e82c65c8c9c9095f456a4eb56a3 Mon Sep 17 00:00:00 2001 From: Piyush Goyal Date: Thu, 27 Aug 2020 19:04:19 +0530 Subject: regulator: mt6360: fix spelling mistake: "regulaotr" -> "regulator" There are some spelling mistakes in two dev_err messages. Fix these. Signed-off-by: Piyush Goyal Link: https://lore.kernel.org/r/20200827133419.36151-1-piyushgoyaliit@gmail.com Signed-off-by: Mark Brown --- drivers/regulator/mt6360-regulator.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/mt6360-regulator.c b/drivers/regulator/mt6360-regulator.c index 89ce379520ed..15308ee29c13 100644 --- a/drivers/regulator/mt6360-regulator.c +++ b/drivers/regulator/mt6360-regulator.c @@ -424,14 +424,14 @@ static int mt6360_regulator_probe(struct platform_device *pdev) rdev = devm_regulator_register(&pdev->dev, &rdesc->desc, &config); if (IS_ERR(rdev)) { - dev_err(&pdev->dev, "Failed to register %d regulaotr\n", i); + dev_err(&pdev->dev, "Failed to register %d regulator\n", i); return PTR_ERR(rdev); } ret = mt6360_regulator_irq_register(pdev, rdev, rdesc->irq_tables, rdesc->irq_table_size); if (ret) { - dev_err(&pdev->dev, "Failed to register %d regulaotr irqs\n", i); + dev_err(&pdev->dev, "Failed to register %d regulator irqs\n", i); return ret; } } -- cgit v1.2.3 From dcb97c10f967c2cfea4c6316f026bc4a4a165f1e Mon Sep 17 00:00:00 2001 From: Rikard Falkeborn Date: Sun, 30 Aug 2020 00:10:57 +0200 Subject: regulator: tps51632: Constify tps51632_dcdc_ops The only usage of tps51632_dcdc_ops is to assign its address to the ops field in the regulator_desc struct, which is a const pointer. Make it const to allow the compiler to put it in read-only memory. Signed-off-by: Rikard Falkeborn Link: https://lore.kernel.org/r/20200829221104.20870-2-rikard.falkeborn@gmail.com Signed-off-by: Mark Brown --- drivers/regulator/tps51632-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/tps51632-regulator.c b/drivers/regulator/tps51632-regulator.c index c139890c1514..a15e415e61d5 100644 --- a/drivers/regulator/tps51632-regulator.c +++ b/drivers/regulator/tps51632-regulator.c @@ -108,7 +108,7 @@ static int tps51632_dcdc_set_ramp_delay(struct regulator_dev *rdev, return ret; } -static struct regulator_ops tps51632_dcdc_ops = { +static const struct regulator_ops tps51632_dcdc_ops = { .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, .list_voltage = regulator_list_voltage_linear, -- cgit v1.2.3 From 55c81934e7040c1e0c26b72ee752203ccf190b51 Mon Sep 17 00:00:00 2001 From: Rikard Falkeborn Date: Sun, 30 Aug 2020 00:10:58 +0200 Subject: regulator: tps6105x: Constify tps6105x_regulator_ops The only usage of tps6105x_regulator_ops is to assign its address to the ops field in the regulator_desc struct, which is a const pointer. Make it const to allow the compiler to put it in read-only memory. Signed-off-by: Rikard Falkeborn Link: https://lore.kernel.org/r/20200829221104.20870-3-rikard.falkeborn@gmail.com Signed-off-by: Mark Brown --- drivers/regulator/tps6105x-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/tps6105x-regulator.c b/drivers/regulator/tps6105x-regulator.c index f8939af0bd2c..a6469fe05635 100644 --- a/drivers/regulator/tps6105x-regulator.c +++ b/drivers/regulator/tps6105x-regulator.c @@ -26,7 +26,7 @@ static const unsigned int tps6105x_voltages[] = { 5000000, /* There is an additional 5V */ }; -static struct regulator_ops tps6105x_regulator_ops = { +static const struct regulator_ops tps6105x_regulator_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, -- cgit v1.2.3 From 01167e88e9372f9748e94a7322b0d43ccb980d9f Mon Sep 17 00:00:00 2001 From: Rikard Falkeborn Date: Sun, 30 Aug 2020 00:10:59 +0200 Subject: regulator: tps62360: Constify tps62360_dcdc_ops The only usage of tps62360_dcdc_ops is to assign its address to the ops field in the regulator_desc struct, which is a const pointer. Make it const to allow the compiler to put it in read-only memory. Signed-off-by: Rikard Falkeborn Link: https://lore.kernel.org/r/20200829221104.20870-4-rikard.falkeborn@gmail.com Signed-off-by: Mark Brown --- drivers/regulator/tps62360-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/tps62360-regulator.c b/drivers/regulator/tps62360-regulator.c index f6a6d36a6533..315cd5daf480 100644 --- a/drivers/regulator/tps62360-regulator.c +++ b/drivers/regulator/tps62360-regulator.c @@ -233,7 +233,7 @@ static unsigned int tps62360_get_mode(struct regulator_dev *rdev) REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL; } -static struct regulator_ops tps62360_dcdc_ops = { +static const struct regulator_ops tps62360_dcdc_ops = { .get_voltage_sel = tps62360_dcdc_get_voltage_sel, .set_voltage_sel = tps62360_dcdc_set_voltage_sel, .list_voltage = regulator_list_voltage_linear, -- cgit v1.2.3 From 2e6d9db83ac7c65b986d3037620dc735dee7383f Mon Sep 17 00:00:00 2001 From: Rikard Falkeborn Date: Sun, 30 Aug 2020 00:11:00 +0200 Subject: regulator: tps65086: Constify static regulator_ops The only usage of reg_ops and switch_ops is to assign their addresses to the ops field in the regulator_desc struct, which is a const pointer. Make them const to allow the compiler to put them in read-only memory. Signed-off-by: Rikard Falkeborn Link: https://lore.kernel.org/r/20200829221104.20870-5-rikard.falkeborn@gmail.com Signed-off-by: Mark Brown --- drivers/regulator/tps65086-regulator.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/tps65086-regulator.c b/drivers/regulator/tps65086-regulator.c index 23528475a962..070c956216b0 100644 --- a/drivers/regulator/tps65086-regulator.c +++ b/drivers/regulator/tps65086-regulator.c @@ -101,7 +101,7 @@ static const struct linear_range tps65086_ldoa23_ranges[] = { }; /* Operations permitted on regulators */ -static struct regulator_ops reg_ops = { +static const struct regulator_ops reg_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, @@ -112,7 +112,7 @@ static struct regulator_ops reg_ops = { }; /* Operations permitted on load switches */ -static struct regulator_ops switch_ops = { +static const struct regulator_ops switch_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, -- cgit v1.2.3 From 7d844ac3b5a8a97ae4a05d9f545346a4fca77cea Mon Sep 17 00:00:00 2001 From: Rikard Falkeborn Date: Sun, 30 Aug 2020 00:11:01 +0200 Subject: regulator: tps65090: constify static regulator_ops The only usages of these are to assign their address to the ops field in the regulator_desc struct, which is a const pointer. Make them const to allow the compiler to put them in read-only memory. Signed-off-by: Rikard Falkeborn Link: https://lore.kernel.org/r/20200829221104.20870-6-rikard.falkeborn@gmail.com Signed-off-by: Mark Brown --- drivers/regulator/tps65090-regulator.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/tps65090-regulator.c b/drivers/regulator/tps65090-regulator.c index f0b660e9f15f..1d2e04f452d4 100644 --- a/drivers/regulator/tps65090-regulator.c +++ b/drivers/regulator/tps65090-regulator.c @@ -47,7 +47,7 @@ struct tps65090_regulator { int overcurrent_wait; }; -static struct regulator_ops tps65090_ext_control_ops = { +static const struct regulator_ops tps65090_ext_control_ops = { }; /** @@ -167,19 +167,19 @@ err: return ret; } -static struct regulator_ops tps65090_reg_control_ops = { +static const struct regulator_ops tps65090_reg_control_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, }; -static struct regulator_ops tps65090_fet_control_ops = { +static const struct regulator_ops tps65090_fet_control_ops = { .enable = tps65090_fet_enable, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, }; -static struct regulator_ops tps65090_ldo_ops = { +static const struct regulator_ops tps65090_ldo_ops = { }; #define tps65090_REG_DESC(_id, _sname, _en_reg, _en_bits, _nvolt, _volt, _ops) \ -- cgit v1.2.3 From 25c8044502ca9fb684fe7a0612985069e27e01eb Mon Sep 17 00:00:00 2001 From: Rikard Falkeborn Date: Sun, 30 Aug 2020 00:11:02 +0200 Subject: regulator: tps6586x: Constify static regulator_ops The only usage of these are to assign their address to the ops field in the regulator_desc struct, which is a const pointer. Make them const to allow the compiler to put them in read-only memory. Signed-off-by: Rikard Falkeborn Link: https://lore.kernel.org/r/20200829221104.20870-7-rikard.falkeborn@gmail.com Signed-off-by: Mark Brown --- drivers/regulator/tps6586x-regulator.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c index 09e994e1f9a9..18bf4b885b08 100644 --- a/drivers/regulator/tps6586x-regulator.c +++ b/drivers/regulator/tps6586x-regulator.c @@ -60,7 +60,7 @@ struct tps6586x_regulator { int enable_reg[2]; }; -static struct regulator_ops tps6586x_rw_regulator_ops = { +static const struct regulator_ops tps6586x_rw_regulator_ops = { .list_voltage = regulator_list_voltage_table, .map_voltage = regulator_map_voltage_ascend, .get_voltage_sel = regulator_get_voltage_sel_regmap, @@ -71,7 +71,7 @@ static struct regulator_ops tps6586x_rw_regulator_ops = { .disable = regulator_disable_regmap, }; -static struct regulator_ops tps6586x_rw_linear_regulator_ops = { +static const struct regulator_ops tps6586x_rw_linear_regulator_ops = { .list_voltage = regulator_list_voltage_linear, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, @@ -81,7 +81,7 @@ static struct regulator_ops tps6586x_rw_linear_regulator_ops = { .disable = regulator_disable_regmap, }; -static struct regulator_ops tps6586x_ro_regulator_ops = { +static const struct regulator_ops tps6586x_ro_regulator_ops = { .list_voltage = regulator_list_voltage_table, .map_voltage = regulator_map_voltage_ascend, .get_voltage_sel = regulator_get_voltage_sel_regmap, @@ -91,7 +91,7 @@ static struct regulator_ops tps6586x_ro_regulator_ops = { .disable = regulator_disable_regmap, }; -static struct regulator_ops tps6586x_sys_regulator_ops = { +static const struct regulator_ops tps6586x_sys_regulator_ops = { }; static const unsigned int tps6586x_ldo0_voltages[] = { -- cgit v1.2.3 From e92b8ef87a8a4a95056d6b5852bd4b5288f34540 Mon Sep 17 00:00:00 2001 From: Rikard Falkeborn Date: Sun, 30 Aug 2020 00:11:03 +0200 Subject: regulator: tps65912: Constify static regulator_ops The only usage of tps65912_ops_dcdc and tps65912_ops_ldo is to assign their address to the ops field in the regulator_desc struct, which is a const pointer. Make them const to allow the compiler to put them in read-only memory. Signed-off-by: Rikard Falkeborn Link: https://lore.kernel.org/r/20200829221104.20870-8-rikard.falkeborn@gmail.com Signed-off-by: Mark Brown --- drivers/regulator/tps65912-regulator.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/tps65912-regulator.c b/drivers/regulator/tps65912-regulator.c index 63d6bbd4969b..b52d4f2874b7 100644 --- a/drivers/regulator/tps65912-regulator.c +++ b/drivers/regulator/tps65912-regulator.c @@ -57,7 +57,7 @@ static const struct linear_range tps65912_ldo_ranges[] = { }; /* Operations permitted on DCDCx */ -static struct regulator_ops tps65912_ops_dcdc = { +static const struct regulator_ops tps65912_ops_dcdc = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, @@ -67,7 +67,7 @@ static struct regulator_ops tps65912_ops_dcdc = { }; /* Operations permitted on LDOx */ -static struct regulator_ops tps65912_ops_ldo = { +static const struct regulator_ops tps65912_ops_ldo = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, -- cgit v1.2.3 From 385d41d7edbc37d6b30197672b744021ce3baccf Mon Sep 17 00:00:00 2001 From: Rikard Falkeborn Date: Sun, 30 Aug 2020 00:11:04 +0200 Subject: regulator: tps65910: Constify static regulator_ops The only usage of these is to assign their address to the ops field in the regulator_desc struct, which is a const pointer. Make them const to allow the compiler to put them in read-only memory. Signed-off-by: Rikard Falkeborn Link: https://lore.kernel.org/r/20200829221104.20870-9-rikard.falkeborn@gmail.com Signed-off-by: Mark Brown --- drivers/regulator/tps65910-regulator.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 4eb5b19d2344..faa5b3538167 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -757,7 +757,7 @@ static int tps65911_list_voltage(struct regulator_dev *dev, unsigned selector) } /* Regulator ops (except VRTC) */ -static struct regulator_ops tps65910_ops_dcdc = { +static const struct regulator_ops tps65910_ops_dcdc = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, @@ -770,7 +770,7 @@ static struct regulator_ops tps65910_ops_dcdc = { .map_voltage = regulator_map_voltage_ascend, }; -static struct regulator_ops tps65910_ops_vdd3 = { +static const struct regulator_ops tps65910_ops_vdd3 = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, @@ -781,7 +781,7 @@ static struct regulator_ops tps65910_ops_vdd3 = { .map_voltage = regulator_map_voltage_ascend, }; -static struct regulator_ops tps65910_ops_vbb = { +static const struct regulator_ops tps65910_ops_vbb = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, @@ -793,7 +793,7 @@ static struct regulator_ops tps65910_ops_vbb = { .map_voltage = regulator_map_voltage_iterate, }; -static struct regulator_ops tps65910_ops = { +static const struct regulator_ops tps65910_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, @@ -805,7 +805,7 @@ static struct regulator_ops tps65910_ops = { .map_voltage = regulator_map_voltage_ascend, }; -static struct regulator_ops tps65911_ops = { +static const struct regulator_ops tps65911_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, -- cgit v1.2.3 From df9db2541a82ec18c474942a93729420d37fac81 Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Thu, 3 Sep 2020 21:38:19 +0300 Subject: regulator: bd718x7 initialize regulator config only once The BD718x7 driver initialized common configs for all regulators. Simplify initialization by moving the initialization of common configs out of the loop. Signed-off-by: Matti Vaittinen Link: https://lore.kernel.org/r/2d3e68c94d4813410da8c4c7eac3332d167d19a8.1599029334.git.matti.vaittinen@fi.rohmeurope.com Signed-off-by: Mark Brown --- drivers/regulator/bd718x7-regulator.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/bd718x7-regulator.c b/drivers/regulator/bd718x7-regulator.c index 7b311389f925..a72031595b9e 100644 --- a/drivers/regulator/bd718x7-regulator.c +++ b/drivers/regulator/bd718x7-regulator.c @@ -1319,6 +1319,9 @@ static int bd718xx_probe(struct platform_device *pdev) } } + config.dev = pdev->dev.parent; + config.regmap = mfd->chip.regmap; + for (i = 0; i < num_reg_data; i++) { const struct regulator_desc *desc; @@ -1328,8 +1331,6 @@ static int bd718xx_probe(struct platform_device *pdev) r = ®_data[i]; desc = &r->desc; - config.dev = pdev->dev.parent; - config.regmap = mfd->chip.regmap; rdev = devm_regulator_register(&pdev->dev, desc, &config); if (IS_ERR(rdev)) { -- cgit v1.2.3 From 1d848d681c4d4e148193b699a6e5f222e8621519 Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Thu, 3 Sep 2020 21:39:02 +0300 Subject: regulator: bd718x7 fix regulator states at SUSPEND The BD718(37/47/50) regulator enable states can be controlled either by SW or by PMIC internal state machine. The bd718x7 driver has not supported leaving the regulators under HW state machine control (except for cases where this is required to avoid boot-up problems due to critical regulators being turned OFF at reset when SNVS used as reset state). On some systems this is undesirable as there now are setups where mixture of SW and HW state machine controlled regulators is needed. Specifically, some SoCs signal SUSPEND state change to PMIC via STBY_REQ line. Now there are setups that expect certain regulators then to be disabled (by PMIC state machine) while other regulators should stay enabled (regardless of HW state => SW control required). Add support for a new device-tree property "rohm,no-regulator-enable-control" which can be used to leave regulator(s) under HW state machine control. Signed-off-by: Matti Vaittinen Link: https://lore.kernel.org/r/6ebba33dd08f2dcc9f1137bbff4d2dc905278a5a.1599029335.git.matti.vaittinen@fi.rohmeurope.com Signed-off-by: Mark Brown --- drivers/regulator/bd718x7-regulator.c | 417 ++++++++++++++++++++++------------ 1 file changed, 268 insertions(+), 149 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/bd718x7-regulator.c b/drivers/regulator/bd718x7-regulator.c index a72031595b9e..159c917b9c4c 100644 --- a/drivers/regulator/bd718x7-regulator.c +++ b/drivers/regulator/bd718x7-regulator.c @@ -15,6 +15,39 @@ #include #include +/* + * BD718(37/47/50) have two "enable control modes". ON/OFF can either be + * controlled by software - or by PMIC internal HW state machine. Whether + * regulator should be under SW or HW control can be defined from device-tree. + * Let's provide separate ops for regulators to use depending on the "enable + * control mode". + */ +#define BD718XX_HWOPNAME(swopname) swopname##_hwcontrol + +#define BD718XX_OPS(name, _list_voltage, _map_voltage, _set_voltage_sel, \ + _get_voltage_sel, _set_voltage_time_sel, _set_ramp_delay) \ +static const struct regulator_ops name = { \ + .enable = regulator_enable_regmap, \ + .disable = regulator_disable_regmap, \ + .is_enabled = regulator_is_enabled_regmap, \ + .list_voltage = (_list_voltage), \ + .map_voltage = (_map_voltage), \ + .set_voltage_sel = (_set_voltage_sel), \ + .get_voltage_sel = (_get_voltage_sel), \ + .set_voltage_time_sel = (_set_voltage_time_sel), \ + .set_ramp_delay = (_set_ramp_delay), \ +}; \ + \ +static const struct regulator_ops BD718XX_HWOPNAME(name) = { \ + .is_enabled = always_enabled_by_hwstate, \ + .list_voltage = (_list_voltage), \ + .map_voltage = (_map_voltage), \ + .set_voltage_sel = (_set_voltage_sel), \ + .get_voltage_sel = (_get_voltage_sel), \ + .set_voltage_time_sel = (_set_voltage_time_sel), \ + .set_ramp_delay = (_set_ramp_delay), \ +} \ + /* * BUCK1/2/3/4 * BUCK1RAMPRATE[1:0] BUCK1 DVS ramp rate setting @@ -55,6 +88,38 @@ static int bd718xx_buck1234_set_ramp_delay(struct regulator_dev *rdev, BUCK_RAMPRATE_MASK, ramp_value << 6); } +/* These functions are used when regulators are under HW state machine control. + * We assume PMIC is in RUN state because SW running and able to query the + * status. Most of the regulators have fixed ON or OFF state at RUN/IDLE so for + * them we just return a constant. BD71837 BUCK3 and BUCK4 are exceptions as + * they support configuring the ON/OFF state for RUN. + * + * Note for next hacker - these PMICs have a register where the HW state can be + * read. If assuming RUN appears to be false in your use-case - you can + * implement state reading (although that is not going to be atomic) before + * returning the enable state. + */ +static int always_enabled_by_hwstate(struct regulator_dev *rdev) +{ + return 1; +} + +static int never_enabled_by_hwstate(struct regulator_dev *rdev) +{ + return 0; +} + +static int bd71837_get_buck34_enable_hwctrl(struct regulator_dev *rdev) +{ + int ret; + unsigned int val; + + ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val); + if (ret) + return ret; + + return !!(BD718XX_BUCK_RUN_ON & val); +} /* * On BD71837 (not on BD71847, BD71850, ...) * Bucks 1 to 4 support DVS. PWM mode is used when voltage is changed. @@ -71,7 +136,7 @@ static int bd718xx_buck1234_set_ramp_delay(struct regulator_dev *rdev, static int bd71837_set_voltage_sel_restricted(struct regulator_dev *rdev, unsigned int sel) { - if (regulator_is_enabled_regmap(rdev)) + if (rdev->desc->ops->is_enabled(rdev)) return -EBUSY; return regulator_set_voltage_sel_regmap(rdev, sel); @@ -113,7 +178,7 @@ static int voltage_change_prepare(struct regulator_dev *rdev, unsigned int sel, int ret; *mask = 0; - if (regulator_is_enabled_regmap(rdev)) { + if (rdev->desc->ops->is_enabled(rdev)) { int now, new; now = rdev->desc->ops->get_voltage_sel(rdev); @@ -195,133 +260,90 @@ static int bd718xx_set_voltage_sel_pickable_restricted( static int bd71837_set_voltage_sel_pickable_restricted( struct regulator_dev *rdev, unsigned int sel) { - if (regulator_is_enabled_regmap(rdev)) + if (rdev->desc->ops->is_enabled(rdev)) return -EBUSY; return regulator_set_voltage_sel_pickable_regmap(rdev, sel); } -static const struct regulator_ops bd718xx_pickable_range_ldo_ops = { - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, - .is_enabled = regulator_is_enabled_regmap, +/* + * OPS common for BD71847 and BD71850 + */ +BD718XX_OPS(bd718xx_pickable_range_ldo_ops, + regulator_list_voltage_pickable_linear_range, NULL, + bd718xx_set_voltage_sel_pickable_restricted, + regulator_get_voltage_sel_pickable_regmap, NULL, NULL); + +/* BD71847 and BD71850 LDO 5 is by default OFF at RUN state */ +static const struct regulator_ops bd718xx_ldo5_ops_hwstate = { + .is_enabled = never_enabled_by_hwstate, .list_voltage = regulator_list_voltage_pickable_linear_range, .set_voltage_sel = bd718xx_set_voltage_sel_pickable_restricted, .get_voltage_sel = regulator_get_voltage_sel_pickable_regmap, - }; -static const struct regulator_ops bd71837_pickable_range_ldo_ops = { - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, - .is_enabled = regulator_is_enabled_regmap, - .list_voltage = regulator_list_voltage_pickable_linear_range, - .set_voltage_sel = bd71837_set_voltage_sel_pickable_restricted, - .get_voltage_sel = regulator_get_voltage_sel_pickable_regmap, -}; - -static const struct regulator_ops bd718xx_pickable_range_buck_ops = { - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, - .is_enabled = regulator_is_enabled_regmap, - .list_voltage = regulator_list_voltage_pickable_linear_range, - .set_voltage_sel = regulator_set_voltage_sel_pickable_regmap, - .get_voltage_sel = regulator_get_voltage_sel_pickable_regmap, - .set_voltage_time_sel = regulator_set_voltage_time_sel, -}; +BD718XX_OPS(bd718xx_pickable_range_buck_ops, + regulator_list_voltage_pickable_linear_range, NULL, + regulator_set_voltage_sel_pickable_regmap, + regulator_get_voltage_sel_pickable_regmap, + regulator_set_voltage_time_sel, NULL); -static const struct regulator_ops bd71837_pickable_range_buck_ops = { - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, - .is_enabled = regulator_is_enabled_regmap, - .list_voltage = regulator_list_voltage_pickable_linear_range, - .set_voltage_sel = bd71837_set_voltage_sel_pickable_restricted, - .get_voltage_sel = regulator_get_voltage_sel_pickable_regmap, - .set_voltage_time_sel = regulator_set_voltage_time_sel, -}; - -static const struct regulator_ops bd71837_ldo_regulator_ops = { - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, - .is_enabled = regulator_is_enabled_regmap, - .list_voltage = regulator_list_voltage_linear_range, - .set_voltage_sel = bd71837_set_voltage_sel_restricted, - .get_voltage_sel = regulator_get_voltage_sel_regmap, -}; +BD718XX_OPS(bd718xx_ldo_regulator_ops, regulator_list_voltage_linear_range, + NULL, bd718xx_set_voltage_sel_restricted, + regulator_get_voltage_sel_regmap, NULL, NULL); -static const struct regulator_ops bd718xx_ldo_regulator_ops = { - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, - .is_enabled = regulator_is_enabled_regmap, - .list_voltage = regulator_list_voltage_linear_range, - .set_voltage_sel = bd718xx_set_voltage_sel_restricted, - .get_voltage_sel = regulator_get_voltage_sel_regmap, -}; +BD718XX_OPS(bd718xx_ldo_regulator_nolinear_ops, regulator_list_voltage_table, + NULL, bd718xx_set_voltage_sel_restricted, + regulator_get_voltage_sel_regmap, NULL, NULL); -static const struct regulator_ops bd71837_ldo_regulator_nolinear_ops = { - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, - .is_enabled = regulator_is_enabled_regmap, - .list_voltage = regulator_list_voltage_table, - .set_voltage_sel = bd71837_set_voltage_sel_restricted, - .get_voltage_sel = regulator_get_voltage_sel_regmap, -}; +BD718XX_OPS(bd718xx_buck_regulator_ops, regulator_list_voltage_linear_range, + NULL, regulator_set_voltage_sel_regmap, + regulator_get_voltage_sel_regmap, regulator_set_voltage_time_sel, + NULL); -static const struct regulator_ops bd718xx_ldo_regulator_nolinear_ops = { - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, - .is_enabled = regulator_is_enabled_regmap, - .list_voltage = regulator_list_voltage_table, - .set_voltage_sel = bd718xx_set_voltage_sel_restricted, - .get_voltage_sel = regulator_get_voltage_sel_regmap, -}; +BD718XX_OPS(bd718xx_buck_regulator_nolinear_ops, regulator_list_voltage_table, + regulator_map_voltage_ascend, regulator_set_voltage_sel_regmap, + regulator_get_voltage_sel_regmap, regulator_set_voltage_time_sel, + NULL); -static const struct regulator_ops bd718xx_buck_regulator_ops = { - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, - .is_enabled = regulator_is_enabled_regmap, - .list_voltage = regulator_list_voltage_linear_range, - .set_voltage_sel = regulator_set_voltage_sel_regmap, - .get_voltage_sel = regulator_get_voltage_sel_regmap, - .set_voltage_time_sel = regulator_set_voltage_time_sel, -}; - -static const struct regulator_ops bd71837_buck_regulator_ops = { - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, - .is_enabled = regulator_is_enabled_regmap, - .list_voltage = regulator_list_voltage_linear_range, - .set_voltage_sel = bd71837_set_voltage_sel_restricted, - .get_voltage_sel = regulator_get_voltage_sel_regmap, - .set_voltage_time_sel = regulator_set_voltage_time_sel, -}; - -static const struct regulator_ops bd718xx_buck_regulator_nolinear_ops = { - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, - .is_enabled = regulator_is_enabled_regmap, - .list_voltage = regulator_list_voltage_table, - .map_voltage = regulator_map_voltage_ascend, - .set_voltage_sel = regulator_set_voltage_sel_regmap, - .get_voltage_sel = regulator_get_voltage_sel_regmap, - .set_voltage_time_sel = regulator_set_voltage_time_sel, -}; - -static const struct regulator_ops bd71837_buck_regulator_nolinear_ops = { - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, - .is_enabled = regulator_is_enabled_regmap, - .list_voltage = regulator_list_voltage_table, - .map_voltage = regulator_map_voltage_ascend, - .set_voltage_sel = bd718xx_set_voltage_sel_restricted, - .get_voltage_sel = regulator_get_voltage_sel_regmap, - .set_voltage_time_sel = regulator_set_voltage_time_sel, -}; - -static const struct regulator_ops bd718xx_dvs_buck_regulator_ops = { - .enable = regulator_enable_regmap, - .disable = regulator_disable_regmap, - .is_enabled = regulator_is_enabled_regmap, +/* + * OPS for BD71837 + */ +BD718XX_OPS(bd71837_pickable_range_ldo_ops, + regulator_list_voltage_pickable_linear_range, NULL, + bd71837_set_voltage_sel_pickable_restricted, + regulator_get_voltage_sel_pickable_regmap, NULL, NULL); + +BD718XX_OPS(bd71837_pickable_range_buck_ops, + regulator_list_voltage_pickable_linear_range, NULL, + bd71837_set_voltage_sel_pickable_restricted, + regulator_get_voltage_sel_pickable_regmap, + regulator_set_voltage_time_sel, NULL); + +BD718XX_OPS(bd71837_ldo_regulator_ops, regulator_list_voltage_linear_range, + NULL, bd71837_set_voltage_sel_restricted, + regulator_get_voltage_sel_regmap, NULL, NULL); + +BD718XX_OPS(bd71837_ldo_regulator_nolinear_ops, regulator_list_voltage_table, + NULL, bd71837_set_voltage_sel_restricted, + regulator_get_voltage_sel_regmap, NULL, NULL); + +BD718XX_OPS(bd71837_buck_regulator_ops, regulator_list_voltage_linear_range, + NULL, bd71837_set_voltage_sel_restricted, + regulator_get_voltage_sel_regmap, regulator_set_voltage_time_sel, + NULL); + +BD718XX_OPS(bd71837_buck_regulator_nolinear_ops, regulator_list_voltage_table, + regulator_map_voltage_ascend, bd718xx_set_voltage_sel_restricted, + regulator_get_voltage_sel_regmap, regulator_set_voltage_time_sel, + NULL); +/* + * BD71837 bucks 3 and 4 support defining their enable/disable state also + * when buck enable state is under HW state machine control. In that case the + * bit [2] in CTRL register is used to indicate if regulator should be ON. + */ +static const struct regulator_ops bd71837_buck34_ops_hwctrl = { + .is_enabled = bd71837_get_buck34_enable_hwctrl, .list_voltage = regulator_list_voltage_linear_range, .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, @@ -329,6 +351,14 @@ static const struct regulator_ops bd718xx_dvs_buck_regulator_ops = { .set_ramp_delay = bd718xx_buck1234_set_ramp_delay, }; +/* + * OPS for all of the ICs - BD718(37/47/50) + */ +BD718XX_OPS(bd718xx_dvs_buck_regulator_ops, regulator_list_voltage_linear_range, + NULL, regulator_set_voltage_sel_regmap, + regulator_get_voltage_sel_regmap, regulator_set_voltage_time_sel, + bd718xx_buck1234_set_ramp_delay); + /* * BD71837 BUCK1/2/3/4 * BD71847 BUCK1/2 @@ -543,14 +573,37 @@ static int buck_set_hw_dvs_levels(struct device_node *np, return rohm_regulator_set_dvs_levels(&data->dvs, np, desc, cfg->regmap); } -static const struct bd718xx_regulator_data bd71847_regulators[] = { +const struct regulator_ops *bd71847_swcontrol_ops[] = { + &bd718xx_dvs_buck_regulator_ops, &bd718xx_dvs_buck_regulator_ops, + &bd718xx_pickable_range_buck_ops, &bd718xx_pickable_range_buck_ops, + &bd718xx_buck_regulator_nolinear_ops, &bd718xx_buck_regulator_ops, + &bd718xx_pickable_range_ldo_ops, &bd718xx_ldo_regulator_nolinear_ops, + &bd718xx_ldo_regulator_ops, &bd718xx_ldo_regulator_ops, + &bd718xx_pickable_range_ldo_ops, &bd718xx_ldo_regulator_ops, +}; + +const struct regulator_ops *bd71847_hwcontrol_ops[] = { + &BD718XX_HWOPNAME(bd718xx_dvs_buck_regulator_ops), + &BD718XX_HWOPNAME(bd718xx_dvs_buck_regulator_ops), + &BD718XX_HWOPNAME(bd718xx_pickable_range_buck_ops), + &BD718XX_HWOPNAME(bd718xx_pickable_range_buck_ops), + &BD718XX_HWOPNAME(bd718xx_buck_regulator_nolinear_ops), + &BD718XX_HWOPNAME(bd718xx_buck_regulator_ops), + &BD718XX_HWOPNAME(bd718xx_pickable_range_ldo_ops), + &BD718XX_HWOPNAME(bd718xx_ldo_regulator_nolinear_ops), + &BD718XX_HWOPNAME(bd718xx_ldo_regulator_ops), + &BD718XX_HWOPNAME(bd718xx_ldo_regulator_ops), + &bd718xx_ldo5_ops_hwstate, + &BD718XX_HWOPNAME(bd718xx_ldo_regulator_ops), +}; + +static struct bd718xx_regulator_data bd71847_regulators[] = { { .desc = { .name = "buck1", .of_match = of_match_ptr("BUCK1"), .regulators_node = of_match_ptr("regulators"), .id = BD718XX_BUCK1, - .ops = &bd718xx_dvs_buck_regulator_ops, .type = REGULATOR_VOLTAGE, .n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM, .linear_ranges = bd718xx_dvs_buck_volts, @@ -585,7 +638,6 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = { .of_match = of_match_ptr("BUCK2"), .regulators_node = of_match_ptr("regulators"), .id = BD718XX_BUCK2, - .ops = &bd718xx_dvs_buck_regulator_ops, .type = REGULATOR_VOLTAGE, .n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM, .linear_ranges = bd718xx_dvs_buck_volts, @@ -616,7 +668,6 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = { .of_match = of_match_ptr("BUCK3"), .regulators_node = of_match_ptr("regulators"), .id = BD718XX_BUCK3, - .ops = &bd718xx_pickable_range_buck_ops, .type = REGULATOR_VOLTAGE, .n_voltages = BD71847_BUCK3_VOLTAGE_NUM, .linear_ranges = bd71847_buck3_volts, @@ -643,7 +694,6 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = { .of_match = of_match_ptr("BUCK4"), .regulators_node = of_match_ptr("regulators"), .id = BD718XX_BUCK4, - .ops = &bd718xx_pickable_range_buck_ops, .type = REGULATOR_VOLTAGE, .n_voltages = BD71847_BUCK4_VOLTAGE_NUM, .linear_ranges = bd71847_buck4_volts, @@ -670,7 +720,6 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = { .of_match = of_match_ptr("BUCK5"), .regulators_node = of_match_ptr("regulators"), .id = BD718XX_BUCK5, - .ops = &bd718xx_buck_regulator_nolinear_ops, .type = REGULATOR_VOLTAGE, .volt_table = &bd718xx_3rd_nodvs_buck_volts[0], .n_voltages = ARRAY_SIZE(bd718xx_3rd_nodvs_buck_volts), @@ -692,7 +741,6 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = { .of_match = of_match_ptr("BUCK6"), .regulators_node = of_match_ptr("regulators"), .id = BD718XX_BUCK6, - .ops = &bd718xx_buck_regulator_ops, .type = REGULATOR_VOLTAGE, .n_voltages = BD718XX_4TH_NODVS_BUCK_VOLTAGE_NUM, .linear_ranges = bd718xx_4th_nodvs_buck_volts, @@ -716,7 +764,6 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = { .of_match = of_match_ptr("LDO1"), .regulators_node = of_match_ptr("regulators"), .id = BD718XX_LDO1, - .ops = &bd718xx_pickable_range_ldo_ops, .type = REGULATOR_VOLTAGE, .n_voltages = BD718XX_LDO1_VOLTAGE_NUM, .linear_ranges = bd718xx_ldo1_volts, @@ -742,7 +789,6 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = { .of_match = of_match_ptr("LDO2"), .regulators_node = of_match_ptr("regulators"), .id = BD718XX_LDO2, - .ops = &bd718xx_ldo_regulator_nolinear_ops, .type = REGULATOR_VOLTAGE, .volt_table = &ldo_2_volts[0], .vsel_reg = BD718XX_REG_LDO2_VOLT, @@ -764,7 +810,6 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = { .of_match = of_match_ptr("LDO3"), .regulators_node = of_match_ptr("regulators"), .id = BD718XX_LDO3, - .ops = &bd718xx_ldo_regulator_ops, .type = REGULATOR_VOLTAGE, .n_voltages = BD718XX_LDO3_VOLTAGE_NUM, .linear_ranges = bd718xx_ldo3_volts, @@ -787,7 +832,6 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = { .of_match = of_match_ptr("LDO4"), .regulators_node = of_match_ptr("regulators"), .id = BD718XX_LDO4, - .ops = &bd718xx_ldo_regulator_ops, .type = REGULATOR_VOLTAGE, .n_voltages = BD718XX_LDO4_VOLTAGE_NUM, .linear_ranges = bd718xx_ldo4_volts, @@ -810,7 +854,6 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = { .of_match = of_match_ptr("LDO5"), .regulators_node = of_match_ptr("regulators"), .id = BD718XX_LDO5, - .ops = &bd718xx_pickable_range_ldo_ops, .type = REGULATOR_VOLTAGE, .n_voltages = BD71847_LDO5_VOLTAGE_NUM, .linear_ranges = bd71847_ldo5_volts, @@ -836,7 +879,6 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = { .of_match = of_match_ptr("LDO6"), .regulators_node = of_match_ptr("regulators"), .id = BD718XX_LDO6, - .ops = &bd718xx_ldo_regulator_ops, .type = REGULATOR_VOLTAGE, .n_voltages = BD718XX_LDO6_VOLTAGE_NUM, .linear_ranges = bd718xx_ldo6_volts, @@ -857,14 +899,41 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = { }, }; -static const struct bd718xx_regulator_data bd71837_regulators[] = { +const struct regulator_ops *bd71837_swcontrol_ops[] = { + &bd718xx_dvs_buck_regulator_ops, &bd718xx_dvs_buck_regulator_ops, + &bd718xx_dvs_buck_regulator_ops, &bd718xx_dvs_buck_regulator_ops, + &bd71837_pickable_range_buck_ops, &bd71837_buck_regulator_ops, + &bd71837_buck_regulator_nolinear_ops, &bd71837_buck_regulator_ops, + &bd71837_pickable_range_ldo_ops, &bd71837_ldo_regulator_nolinear_ops, + &bd71837_ldo_regulator_ops, &bd71837_ldo_regulator_ops, + &bd71837_ldo_regulator_ops, &bd71837_ldo_regulator_ops, + &bd71837_ldo_regulator_ops, +}; + +const struct regulator_ops *bd71837_hwcontrol_ops[] = { + &BD718XX_HWOPNAME(bd718xx_dvs_buck_regulator_ops), + &BD718XX_HWOPNAME(bd718xx_dvs_buck_regulator_ops), + &bd71837_buck34_ops_hwctrl, &bd71837_buck34_ops_hwctrl, + &BD718XX_HWOPNAME(bd71837_pickable_range_buck_ops), + &BD718XX_HWOPNAME(bd71837_buck_regulator_ops), + &BD718XX_HWOPNAME(bd71837_buck_regulator_nolinear_ops), + &BD718XX_HWOPNAME(bd71837_buck_regulator_ops), + &BD718XX_HWOPNAME(bd71837_pickable_range_ldo_ops), + &BD718XX_HWOPNAME(bd71837_ldo_regulator_nolinear_ops), + &BD718XX_HWOPNAME(bd71837_ldo_regulator_ops), + &BD718XX_HWOPNAME(bd71837_ldo_regulator_ops), + &BD718XX_HWOPNAME(bd71837_ldo_regulator_ops), + &BD718XX_HWOPNAME(bd71837_ldo_regulator_ops), + &BD718XX_HWOPNAME(bd71837_ldo_regulator_ops), +}; + +static struct bd718xx_regulator_data bd71837_regulators[] = { { .desc = { .name = "buck1", .of_match = of_match_ptr("BUCK1"), .regulators_node = of_match_ptr("regulators"), .id = BD718XX_BUCK1, - .ops = &bd718xx_dvs_buck_regulator_ops, .type = REGULATOR_VOLTAGE, .n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM, .linear_ranges = bd718xx_dvs_buck_volts, @@ -898,7 +967,6 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = { .of_match = of_match_ptr("BUCK2"), .regulators_node = of_match_ptr("regulators"), .id = BD718XX_BUCK2, - .ops = &bd718xx_dvs_buck_regulator_ops, .type = REGULATOR_VOLTAGE, .n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM, .linear_ranges = bd718xx_dvs_buck_volts, @@ -929,7 +997,6 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = { .of_match = of_match_ptr("BUCK3"), .regulators_node = of_match_ptr("regulators"), .id = BD718XX_BUCK3, - .ops = &bd718xx_dvs_buck_regulator_ops, .type = REGULATOR_VOLTAGE, .n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM, .linear_ranges = bd718xx_dvs_buck_volts, @@ -958,7 +1025,6 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = { .of_match = of_match_ptr("BUCK4"), .regulators_node = of_match_ptr("regulators"), .id = BD718XX_BUCK4, - .ops = &bd718xx_dvs_buck_regulator_ops, .type = REGULATOR_VOLTAGE, .n_voltages = BD718XX_DVS_BUCK_VOLTAGE_NUM, .linear_ranges = bd718xx_dvs_buck_volts, @@ -987,7 +1053,6 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = { .of_match = of_match_ptr("BUCK5"), .regulators_node = of_match_ptr("regulators"), .id = BD718XX_BUCK5, - .ops = &bd71837_pickable_range_buck_ops, .type = REGULATOR_VOLTAGE, .n_voltages = BD71837_BUCK5_VOLTAGE_NUM, .linear_ranges = bd71837_buck5_volts, @@ -1014,7 +1079,6 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = { .of_match = of_match_ptr("BUCK6"), .regulators_node = of_match_ptr("regulators"), .id = BD718XX_BUCK6, - .ops = &bd71837_buck_regulator_ops, .type = REGULATOR_VOLTAGE, .n_voltages = BD71837_BUCK6_VOLTAGE_NUM, .linear_ranges = bd71837_buck6_volts, @@ -1038,7 +1102,6 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = { .of_match = of_match_ptr("BUCK7"), .regulators_node = of_match_ptr("regulators"), .id = BD718XX_BUCK7, - .ops = &bd71837_buck_regulator_nolinear_ops, .type = REGULATOR_VOLTAGE, .volt_table = &bd718xx_3rd_nodvs_buck_volts[0], .n_voltages = ARRAY_SIZE(bd718xx_3rd_nodvs_buck_volts), @@ -1060,7 +1123,6 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = { .of_match = of_match_ptr("BUCK8"), .regulators_node = of_match_ptr("regulators"), .id = BD718XX_BUCK8, - .ops = &bd71837_buck_regulator_ops, .type = REGULATOR_VOLTAGE, .n_voltages = BD718XX_4TH_NODVS_BUCK_VOLTAGE_NUM, .linear_ranges = bd718xx_4th_nodvs_buck_volts, @@ -1084,7 +1146,6 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = { .of_match = of_match_ptr("LDO1"), .regulators_node = of_match_ptr("regulators"), .id = BD718XX_LDO1, - .ops = &bd71837_pickable_range_ldo_ops, .type = REGULATOR_VOLTAGE, .n_voltages = BD718XX_LDO1_VOLTAGE_NUM, .linear_ranges = bd718xx_ldo1_volts, @@ -1110,7 +1171,6 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = { .of_match = of_match_ptr("LDO2"), .regulators_node = of_match_ptr("regulators"), .id = BD718XX_LDO2, - .ops = &bd71837_ldo_regulator_nolinear_ops, .type = REGULATOR_VOLTAGE, .volt_table = &ldo_2_volts[0], .vsel_reg = BD718XX_REG_LDO2_VOLT, @@ -1132,7 +1192,6 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = { .of_match = of_match_ptr("LDO3"), .regulators_node = of_match_ptr("regulators"), .id = BD718XX_LDO3, - .ops = &bd71837_ldo_regulator_ops, .type = REGULATOR_VOLTAGE, .n_voltages = BD718XX_LDO3_VOLTAGE_NUM, .linear_ranges = bd718xx_ldo3_volts, @@ -1155,7 +1214,6 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = { .of_match = of_match_ptr("LDO4"), .regulators_node = of_match_ptr("regulators"), .id = BD718XX_LDO4, - .ops = &bd71837_ldo_regulator_ops, .type = REGULATOR_VOLTAGE, .n_voltages = BD718XX_LDO4_VOLTAGE_NUM, .linear_ranges = bd718xx_ldo4_volts, @@ -1178,7 +1236,6 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = { .of_match = of_match_ptr("LDO5"), .regulators_node = of_match_ptr("regulators"), .id = BD718XX_LDO5, - .ops = &bd71837_ldo_regulator_ops, .type = REGULATOR_VOLTAGE, .n_voltages = BD71837_LDO5_VOLTAGE_NUM, .linear_ranges = bd71837_ldo5_volts, @@ -1205,7 +1262,6 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = { .of_match = of_match_ptr("LDO6"), .regulators_node = of_match_ptr("regulators"), .id = BD718XX_LDO6, - .ops = &bd71837_ldo_regulator_ops, .type = REGULATOR_VOLTAGE, .n_voltages = BD718XX_LDO6_VOLTAGE_NUM, .linear_ranges = bd718xx_ldo6_volts, @@ -1232,7 +1288,6 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = { .of_match = of_match_ptr("LDO7"), .regulators_node = of_match_ptr("regulators"), .id = BD718XX_LDO7, - .ops = &bd71837_ldo_regulator_ops, .type = REGULATOR_VOLTAGE, .n_voltages = BD71837_LDO7_VOLTAGE_NUM, .linear_ranges = bd71837_ldo7_volts, @@ -1251,15 +1306,57 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = { }, }; +static void mark_hw_controlled(struct device *dev, struct device_node *np, + struct bd718xx_regulator_data *reg_data, + unsigned int num_reg_data, int *info) +{ + int i; + + for (i = 1; i <= num_reg_data; i++) { + if (!of_node_name_eq(np, reg_data[i-1].desc.of_match)) + continue; + + *info |= 1 << (i - 1); + dev_dbg(dev, "regulator %d runlevel controlled\n", i); + return; + } + dev_warn(dev, "Bad regulator node\n"); +} + +static int get_hw_controlled_regulators(struct device *dev, + struct bd718xx_regulator_data *reg_data, + unsigned int num_reg_data, int *info) +{ + struct device_node *np; + struct device_node *nproot = dev->of_node; + const char *prop = "rohm,no-regulator-enable-control"; + + *info = 0; + + nproot = of_get_child_by_name(nproot, "regulators"); + if (!nproot) { + dev_err(dev, "failed to find regulators node\n"); + return -ENODEV; + } + for_each_child_of_node(nproot, np) + if (of_property_read_bool(np, prop)) + mark_hw_controlled(dev, np, reg_data, num_reg_data, + info); + + of_node_put(nproot); + return 0; +} + static int bd718xx_probe(struct platform_device *pdev) { struct bd718xx *mfd; struct regulator_config config = { 0 }; - int i, j, err; + int i, j, err, omit_enable; bool use_snvs; - const struct bd718xx_regulator_data *reg_data; + struct bd718xx_regulator_data *reg_data; unsigned int num_reg_data; enum rohm_chip_type chip = platform_get_device_id(pdev)->driver_data; + const struct regulator_ops **swops, **hwops; mfd = dev_get_drvdata(pdev->dev.parent); if (!mfd) { @@ -1272,10 +1369,14 @@ static int bd718xx_probe(struct platform_device *pdev) case ROHM_CHIP_TYPE_BD71837: reg_data = bd71837_regulators; num_reg_data = ARRAY_SIZE(bd71837_regulators); + swops = &bd71837_swcontrol_ops[0]; + hwops = &bd71837_hwcontrol_ops[0]; break; case ROHM_CHIP_TYPE_BD71847: reg_data = bd71847_regulators; num_reg_data = ARRAY_SIZE(bd71847_regulators); + swops = &bd71847_swcontrol_ops[0]; + hwops = &bd71847_hwcontrol_ops[0]; break; default: dev_err(&pdev->dev, "Unsupported chip type\n"); @@ -1321,16 +1422,33 @@ static int bd718xx_probe(struct platform_device *pdev) config.dev = pdev->dev.parent; config.regmap = mfd->chip.regmap; + /* + * There are cases when we want to leave the enable-control for + * the HW state machine and use this driver only for voltage control. + * One special case is when we use PMIC_STBY_REQ line from SoC to PMIC + * in order to set the system to SUSPEND state. + * + * If regulator is taken under SW control the regulator state will not + * be affected by PMIC state machine - Eg. regulator is likely to stay + * on even in SUSPEND + */ + get_hw_controlled_regulators(pdev->dev.parent, reg_data, num_reg_data, + &omit_enable); for (i = 0; i < num_reg_data; i++) { - const struct regulator_desc *desc; + struct regulator_desc *desc; struct regulator_dev *rdev; - const struct bd718xx_regulator_data *r; + struct bd718xx_regulator_data *r; + int no_enable_control = omit_enable & (1 << i); r = ®_data[i]; desc = &r->desc; + if (no_enable_control) + desc->ops = hwops[i]; + else + desc->ops = swops[i]; rdev = devm_regulator_register(&pdev->dev, desc, &config); if (IS_ERR(rdev)) { @@ -1357,8 +1475,9 @@ static int bd718xx_probe(struct platform_device *pdev) * enable SW control for crucial regulators if snvs state is * used */ - if (!use_snvs || !rdev->constraints->always_on || - !rdev->constraints->boot_on) { + if (!no_enable_control && (!use_snvs || + !rdev->constraints->always_on || + !rdev->constraints->boot_on)) { err = regmap_update_bits(mfd->chip.regmap, r->init.reg, r->init.mask, r->init.val); if (err) { -- cgit v1.2.3 From 3bca239d6184df61a619d78764e0481242d844b4 Mon Sep 17 00:00:00 2001 From: Michał Mirosław Date: Mon, 10 Aug 2020 06:33:32 +0200 Subject: regulator: don't require mutex for regulator_notifier_call_chain() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since 3801b86aa482 ("regulator: Refactor supply implementation to work as regular consumers") we no longer cascade notifications and so notifier head's built-in rwsem is enough to protect the notifier chain. Remove the requirement to fix one case where rdev->mutex might be forced to be taken recursively. Signed-off-by: Michał Mirosław Reviewed-by: Dmitry Osipenko Link: https://lore.kernel.org/r/5a0da9017c69a4dbc3f9b50f44476fce80a73387.1597032945.git.mirq-linux@rere.qmqm.pl Signed-off-by: Mark Brown --- drivers/regulator/core.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 07edbd8ebb98..2ed035114ee8 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -4725,14 +4725,11 @@ EXPORT_SYMBOL_GPL(regulator_bulk_free); * @data: callback-specific data. * * Called by regulator drivers to notify clients a regulator event has - * occurred. We also notify regulator clients downstream. - * Note lock must be held by caller. + * occurred. */ int regulator_notifier_call_chain(struct regulator_dev *rdev, unsigned long event, void *data) { - lockdep_assert_held_once(&rdev->mutex.base); - _notifier_call_chain(rdev, event, data); return NOTIFY_DONE; -- cgit v1.2.3 From e9c142b0d2c08178a9e146d47d8fe397373bda3e Mon Sep 17 00:00:00 2001 From: Michał Mirosław Date: Mon, 10 Aug 2020 06:33:32 +0200 Subject: regulator: remove locking around regulator_notifier_call_chain() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit regulator_notifier_call_chain() doesn't need rdev lock and rdev's existence is assumed in the code anyway. Remove the locks from drivers. Signed-off-by: Michał Mirosław Acked-by: Adam Thomson Reviewed-by: Dmitry Osipenko Link: https://lore.kernel.org/r/42393f66dcc4d80dcd9797be45216b4035aa96cb.1597032945.git.mirq-linux@rere.qmqm.pl Signed-off-by: Mark Brown --- drivers/regulator/da9055-regulator.c | 2 -- drivers/regulator/da9062-regulator.c | 2 -- drivers/regulator/da9063-regulator.c | 2 -- drivers/regulator/da9210-regulator.c | 4 ---- drivers/regulator/da9211-regulator.c | 4 ---- drivers/regulator/lp8755.c | 6 ------ drivers/regulator/ltc3589.c | 10 ++-------- drivers/regulator/ltc3676.c | 10 ++-------- drivers/regulator/pv88060-regulator.c | 10 ++-------- drivers/regulator/pv88080-regulator.c | 10 ++-------- drivers/regulator/pv88090-regulator.c | 10 ++-------- drivers/regulator/slg51000-regulator.c | 4 ---- drivers/regulator/stpmic1_regulator.c | 4 ---- drivers/regulator/wm831x-dcdc.c | 4 ---- drivers/regulator/wm831x-isink.c | 2 -- drivers/regulator/wm831x-ldo.c | 2 -- drivers/regulator/wm8350-regulator.c | 2 -- 17 files changed, 10 insertions(+), 78 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/da9055-regulator.c b/drivers/regulator/da9055-regulator.c index c025ccb1a30a..73ff5fc7d8d7 100644 --- a/drivers/regulator/da9055-regulator.c +++ b/drivers/regulator/da9055-regulator.c @@ -485,10 +485,8 @@ 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; } diff --git a/drivers/regulator/da9062-regulator.c b/drivers/regulator/da9062-regulator.c index d8112f56e94e..1a6324001027 100644 --- a/drivers/regulator/da9062-regulator.c +++ b/drivers/regulator/da9062-regulator.c @@ -907,10 +907,8 @@ 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; } } diff --git a/drivers/regulator/da9063-regulator.c b/drivers/regulator/da9063-regulator.c index fe65b5acaf28..cf7d5341750e 100644 --- a/drivers/regulator/da9063-regulator.c +++ b/drivers/regulator/da9063-regulator.c @@ -574,10 +574,8 @@ static irqreturn_t da9063_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); } } diff --git a/drivers/regulator/da9210-regulator.c b/drivers/regulator/da9210-regulator.c index 2aea442b62fe..7493af0b5c04 100644 --- a/drivers/regulator/da9210-regulator.c +++ b/drivers/regulator/da9210-regulator.c @@ -77,8 +77,6 @@ static irqreturn_t da9210_irq_handler(int irq, void *data) if (error < 0) goto error_i2c; - regulator_lock(chip->rdev); - if (val & DA9210_E_OVCURR) { regulator_notifier_call_chain(chip->rdev, REGULATOR_EVENT_OVER_CURRENT, @@ -103,8 +101,6 @@ static irqreturn_t da9210_irq_handler(int irq, void *data) handled |= DA9210_E_VMAX; } - regulator_unlock(chip->rdev); - if (handled) { /* Clear handled events */ error = regmap_write(chip->regmap, DA9210_REG_EVENT_B, handled); diff --git a/drivers/regulator/da9211-regulator.c b/drivers/regulator/da9211-regulator.c index cffcefd0538d..e01b32d1fa17 100644 --- a/drivers/regulator/da9211-regulator.c +++ b/drivers/regulator/da9211-regulator.c @@ -346,10 +346,8 @@ 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); @@ -360,10 +358,8 @@ 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/lp8755.c b/drivers/regulator/lp8755.c index 8cc9963023f2..13c535711265 100644 --- a/drivers/regulator/lp8755.c +++ b/drivers/regulator/lp8755.c @@ -329,11 +329,9 @@ static irqreturn_t lp8755_irq_handler(int irq, void *data) if ((flag0 & (0x4 << icnt)) && (pchip->irqmask & (0x04 << icnt)) && (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 */ @@ -349,22 +347,18 @@ static irqreturn_t lp8755_irq_handler(int irq, void *data) if ((flag1 & 0x01) && (pchip->irqmask & 0x01)) for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++) 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) { - regulator_lock(pchip->rdev[icnt]); regulator_notifier_call_chain(pchip->rdev[icnt], LP8755_EVENT_OVP, NULL); - regulator_unlock(pchip->rdev[icnt]); } return IRQ_HANDLED; diff --git a/drivers/regulator/ltc3589.c b/drivers/regulator/ltc3589.c index fa563aacf742..38f7ccb63b52 100644 --- a/drivers/regulator/ltc3589.c +++ b/drivers/regulator/ltc3589.c @@ -357,22 +357,16 @@ 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++) { - regulator_lock(ltc3589->regulators[i]); + for (i = 0; i < LTC3589_NUM_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++) { - regulator_lock(ltc3589->regulators[i]); + for (i = 0; i < LTC3589_NUM_REGULATORS; i++) regulator_notifier_call_chain(ltc3589->regulators[i], event, NULL); - regulator_unlock(ltc3589->regulators[i]); - } } /* Clear warning condition */ diff --git a/drivers/regulator/ltc3676.c b/drivers/regulator/ltc3676.c index 557727b54f0e..eb3d6bed6d54 100644 --- a/drivers/regulator/ltc3676.c +++ b/drivers/regulator/ltc3676.c @@ -276,23 +276,17 @@ 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++) { - regulator_lock(ltc3676->regulators[i]); + for (i = 0; i < LTC3676_NUM_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++) { - regulator_lock(ltc3676->regulators[i]); + for (i = 0; i < LTC3676_NUM_REGULATORS; i++) regulator_notifier_call_chain(ltc3676->regulators[i], event, NULL); - regulator_unlock(ltc3676->regulators[i]); - } } /* Clear warning condition */ diff --git a/drivers/regulator/pv88060-regulator.c b/drivers/regulator/pv88060-regulator.c index 787ced918372..48238846f45c 100644 --- a/drivers/regulator/pv88060-regulator.c +++ b/drivers/regulator/pv88060-regulator.c @@ -233,13 +233,10 @@ 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]); + if (chip->rdev[i] != NULL) regulator_notifier_call_chain(chip->rdev[i], REGULATOR_EVENT_UNDER_VOLTAGE, NULL); - regulator_unlock(chip->rdev[i]); - } } err = regmap_write(chip->regmap, PV88060_REG_EVENT_A, @@ -252,13 +249,10 @@ 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]); + if (chip->rdev[i] != NULL) regulator_notifier_call_chain(chip->rdev[i], REGULATOR_EVENT_OVER_TEMP, NULL); - regulator_unlock(chip->rdev[i]); - } } err = regmap_write(chip->regmap, PV88060_REG_EVENT_A, diff --git a/drivers/regulator/pv88080-regulator.c b/drivers/regulator/pv88080-regulator.c index a444f68af1a8..2a74cc05acfe 100644 --- a/drivers/regulator/pv88080-regulator.c +++ b/drivers/regulator/pv88080-regulator.c @@ -334,13 +334,10 @@ 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]); + if (chip->rdev[i] != NULL) regulator_notifier_call_chain(chip->rdev[i], REGULATOR_EVENT_UNDER_VOLTAGE, NULL); - regulator_unlock(chip->rdev[i]); - } } err = regmap_write(chip->regmap, PV88080_REG_EVENT_A, @@ -353,13 +350,10 @@ 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]); + if (chip->rdev[i] != NULL) regulator_notifier_call_chain(chip->rdev[i], REGULATOR_EVENT_OVER_TEMP, NULL); - regulator_unlock(chip->rdev[i]); - } } err = regmap_write(chip->regmap, PV88080_REG_EVENT_A, diff --git a/drivers/regulator/pv88090-regulator.c b/drivers/regulator/pv88090-regulator.c index 784729ec2182..a80176bdf8ec 100644 --- a/drivers/regulator/pv88090-regulator.c +++ b/drivers/regulator/pv88090-regulator.c @@ -226,13 +226,10 @@ 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]); + if (chip->rdev[i] != NULL) regulator_notifier_call_chain(chip->rdev[i], REGULATOR_EVENT_UNDER_VOLTAGE, NULL); - regulator_unlock(chip->rdev[i]); - } } err = regmap_write(chip->regmap, PV88090_REG_EVENT_A, @@ -245,13 +242,10 @@ 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]); + if (chip->rdev[i] != NULL) regulator_notifier_call_chain(chip->rdev[i], REGULATOR_EVENT_OVER_TEMP, NULL); - regulator_unlock(chip->rdev[i]); - } } err = regmap_write(chip->regmap, PV88090_REG_EVENT_A, diff --git a/drivers/regulator/slg51000-regulator.c b/drivers/regulator/slg51000-regulator.c index 44e4cecbf6de..0f8041981436 100644 --- a/drivers/regulator/slg51000-regulator.c +++ b/drivers/regulator/slg51000-regulator.c @@ -386,10 +386,8 @@ static irqreturn_t slg51000_irq_handler(int irq, void *data) for (i = 0; i < SLG51000_MAX_REGULATORS; i++) { if (!(evt[i][R2] & SLG51000_IRQ_ILIM_FLAG_MASK) && (evt[i][R0] & SLG51000_EVT_ILIM_FLAG_MASK)) { - regulator_lock(chip->rdev[i]); regulator_notifier_call_chain(chip->rdev[i], REGULATOR_EVENT_OVER_CURRENT, NULL); - regulator_unlock(chip->rdev[i]); if (evt[i][R1] & SLG51000_STA_ILIM_FLAG_MASK) dev_warn(chip->dev, @@ -403,10 +401,8 @@ static irqreturn_t slg51000_irq_handler(int irq, void *data) for (i = 0; i < SLG51000_MAX_REGULATORS; i++) { if (!(evt[i][R1] & SLG51000_STA_ILIM_FLAG_MASK) && (evt[i][R1] & SLG51000_STA_VOUT_OK_FLAG_MASK)) { - regulator_lock(chip->rdev[i]); regulator_notifier_call_chain(chip->rdev[i], REGULATOR_EVENT_OVER_TEMP, NULL); - regulator_unlock(chip->rdev[i]); } } handled = IRQ_HANDLED; diff --git a/drivers/regulator/stpmic1_regulator.c b/drivers/regulator/stpmic1_regulator.c index 73e0ab2baeaa..cf10fdb72e32 100644 --- a/drivers/regulator/stpmic1_regulator.c +++ b/drivers/regulator/stpmic1_regulator.c @@ -505,15 +505,11 @@ static irqreturn_t stpmic1_curlim_irq_handler(int irq, void *data) { struct regulator_dev *rdev = (struct regulator_dev *)data; - regulator_lock(rdev); - /* Send an overcurrent notification */ regulator_notifier_call_chain(rdev, REGULATOR_EVENT_OVER_CURRENT, NULL); - regulator_unlock(rdev); - return IRQ_HANDLED; } diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c index ad2203d11a88..e43ed4d93f71 100644 --- a/drivers/regulator/wm831x-dcdc.c +++ b/drivers/regulator/wm831x-dcdc.c @@ -178,11 +178,9 @@ 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; } @@ -191,11 +189,9 @@ 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 ff3d2bf50410..eade3ae3e333 100644 --- a/drivers/regulator/wm831x-isink.c +++ b/drivers/regulator/wm831x-isink.c @@ -99,11 +99,9 @@ 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; } diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c index 7b6cf4810cb7..e091b189ecc0 100644 --- a/drivers/regulator/wm831x-ldo.c +++ b/drivers/regulator/wm831x-ldo.c @@ -46,11 +46,9 @@ 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 2e7bfdf7c87b..6579bfdb0c26 100644 --- a/drivers/regulator/wm8350-regulator.c +++ b/drivers/regulator/wm8350-regulator.c @@ -1089,7 +1089,6 @@ static irqreturn_t pmic_uv_handler(int irq, void *data) { struct regulator_dev *rdev = (struct regulator_dev *)data; - regulator_lock(rdev); if (irq == WM8350_IRQ_CS1 || irq == WM8350_IRQ_CS2) regulator_notifier_call_chain(rdev, REGULATOR_EVENT_REGULATION_OUT, @@ -1098,7 +1097,6 @@ static irqreturn_t pmic_uv_handler(int irq, void *data) regulator_notifier_call_chain(rdev, REGULATOR_EVENT_UNDER_VOLTAGE, NULL); - regulator_unlock(rdev); return IRQ_HANDLED; } -- cgit v1.2.3 From 6dc9674d95b8a8a81b85a4bed77f86d1b039be10 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Fri, 4 Sep 2020 13:25:06 +0100 Subject: regulator: lochnagar: Add additional VDDCORE range In the case of an unrecognised mini-card the Lochnagar will not initialise the VDDCORE voltage register leading to a value outside of the current range. Add an additional range to cover these values, initially this wasn't done since they are duplicates of the existing minimum value. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20200904122506.28017-1-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- drivers/regulator/lochnagar-regulator.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/regulator') diff --git a/drivers/regulator/lochnagar-regulator.c b/drivers/regulator/lochnagar-regulator.c index 5ea3e4141684..cb71fa5f43c3 100644 --- a/drivers/regulator/lochnagar-regulator.c +++ b/drivers/regulator/lochnagar-regulator.c @@ -98,6 +98,7 @@ static const struct regulator_ops lochnagar_vddcore_ops = { }; static const struct linear_range lochnagar_vddcore_ranges[] = { + REGULATOR_LINEAR_RANGE(600000, 0, 0x7, 0), REGULATOR_LINEAR_RANGE(600000, 0x8, 0x41, 12500), }; -- cgit v1.2.3 From 02f8eaab0cb644478c170237f354db32b718e5ff Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Thu, 10 Sep 2020 11:42:40 +0800 Subject: regulator: bd718x7: Make some variable static Fix sparse warnings: drivers/regulator/bd718x7-regulator.c:576:28: warning: symbol 'bd71847_swcontrol_ops' was not declared. Should it be static? drivers/regulator/bd718x7-regulator.c:585:28: warning: symbol 'bd71847_hwcontrol_ops' was not declared. Should it be static? drivers/regulator/bd718x7-regulator.c:902:28: warning: symbol 'bd71837_swcontrol_ops' was not declared. Should it be static? drivers/regulator/bd718x7-regulator.c:913:28: warning: symbol 'bd71837_hwcontrol_ops' was not declared. Should it be static? Reported-by: Hulk Robot Signed-off-by: YueHaibing Acked-By: Matti Vaittinen Link: https://lore.kernel.org/r/20200910034240.37268-1-yuehaibing@huawei.com Signed-off-by: Mark Brown --- drivers/regulator/bd718x7-regulator.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/bd718x7-regulator.c b/drivers/regulator/bd718x7-regulator.c index 159c917b9c4c..0774467994fb 100644 --- a/drivers/regulator/bd718x7-regulator.c +++ b/drivers/regulator/bd718x7-regulator.c @@ -573,7 +573,7 @@ static int buck_set_hw_dvs_levels(struct device_node *np, return rohm_regulator_set_dvs_levels(&data->dvs, np, desc, cfg->regmap); } -const struct regulator_ops *bd71847_swcontrol_ops[] = { +static const struct regulator_ops *bd71847_swcontrol_ops[] = { &bd718xx_dvs_buck_regulator_ops, &bd718xx_dvs_buck_regulator_ops, &bd718xx_pickable_range_buck_ops, &bd718xx_pickable_range_buck_ops, &bd718xx_buck_regulator_nolinear_ops, &bd718xx_buck_regulator_ops, @@ -582,7 +582,7 @@ const struct regulator_ops *bd71847_swcontrol_ops[] = { &bd718xx_pickable_range_ldo_ops, &bd718xx_ldo_regulator_ops, }; -const struct regulator_ops *bd71847_hwcontrol_ops[] = { +static const struct regulator_ops *bd71847_hwcontrol_ops[] = { &BD718XX_HWOPNAME(bd718xx_dvs_buck_regulator_ops), &BD718XX_HWOPNAME(bd718xx_dvs_buck_regulator_ops), &BD718XX_HWOPNAME(bd718xx_pickable_range_buck_ops), @@ -899,7 +899,7 @@ static struct bd718xx_regulator_data bd71847_regulators[] = { }, }; -const struct regulator_ops *bd71837_swcontrol_ops[] = { +static const struct regulator_ops *bd71837_swcontrol_ops[] = { &bd718xx_dvs_buck_regulator_ops, &bd718xx_dvs_buck_regulator_ops, &bd718xx_dvs_buck_regulator_ops, &bd718xx_dvs_buck_regulator_ops, &bd71837_pickable_range_buck_ops, &bd71837_buck_regulator_ops, @@ -910,7 +910,7 @@ const struct regulator_ops *bd71837_swcontrol_ops[] = { &bd71837_ldo_regulator_ops, }; -const struct regulator_ops *bd71837_hwcontrol_ops[] = { +static const struct regulator_ops *bd71837_hwcontrol_ops[] = { &BD718XX_HWOPNAME(bd718xx_dvs_buck_regulator_ops), &BD718XX_HWOPNAME(bd718xx_dvs_buck_regulator_ops), &bd71837_buck34_ops_hwctrl, &bd71837_buck34_ops_hwctrl, -- cgit v1.2.3 From 087c09c2d273823bac906d590280f7e8052f7eff Mon Sep 17 00:00:00 2001 From: Rikard Falkeborn Date: Sun, 13 Sep 2020 10:41:10 +0200 Subject: regulator: dummy: Constify dummy_initdata and dummy_ops The only usage of dummy_initdata is to assign its address to the init_data field of the regulator_config struct and the only usage dummy_ops is to assign its address to the ops field in the regulator_desc struct, both which are const pointers. Make them const to allow the compiler to put them in read-only memory. Signed-off-by: Rikard Falkeborn Link: https://lore.kernel.org/r/20200913084114.8851-2-rikard.falkeborn@gmail.com Signed-off-by: Mark Brown --- drivers/regulator/dummy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/dummy.c b/drivers/regulator/dummy.c index 74de6983c61a..d8059f596391 100644 --- a/drivers/regulator/dummy.c +++ b/drivers/regulator/dummy.c @@ -21,13 +21,13 @@ struct regulator_dev *dummy_regulator_rdev; -static struct regulator_init_data dummy_initdata = { +static const struct regulator_init_data dummy_initdata = { .constraints = { .always_on = 1, }, }; -static struct regulator_ops dummy_ops; +static const struct regulator_ops dummy_ops; static const struct regulator_desc dummy_desc = { .name = "regulator-dummy", -- cgit v1.2.3 From 96ee75ffd4f63a3d5f9d6a3ea592b2c0ee97acb0 Mon Sep 17 00:00:00 2001 From: Rikard Falkeborn Date: Sun, 13 Sep 2020 10:41:11 +0200 Subject: regulator: fixed: Constify static regulator_ops The only usage of fixed_voltage_ops and fixed_voltage_clkenabled_ops is to assign their address the ops field in the regulator_desc struct, which is a const pointer. Make them const to allow the compiler to put them in read-only memory. make them const to allow the compiler to put them in read-only memory. Signed-off-by: Rikard Falkeborn Link: https://lore.kernel.org/r/20200913084114.8851-3-rikard.falkeborn@gmail.com Signed-off-by: Mark Brown --- drivers/regulator/fixed.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c index 5a03fd86ad0a..3de7709bdcd4 100644 --- a/drivers/regulator/fixed.c +++ b/drivers/regulator/fixed.c @@ -123,10 +123,10 @@ of_get_fixed_voltage_config(struct device *dev, return config; } -static struct regulator_ops fixed_voltage_ops = { +static const struct regulator_ops fixed_voltage_ops = { }; -static struct regulator_ops fixed_voltage_clkenabled_ops = { +static const struct regulator_ops fixed_voltage_clkenabled_ops = { .enable = reg_clock_enable, .disable = reg_clock_disable, .is_enabled = reg_clock_is_enabled, -- cgit v1.2.3 From 9032693e218e69a9527fd5d08c4ce5cdbe90820f Mon Sep 17 00:00:00 2001 From: Rikard Falkeborn Date: Sun, 13 Sep 2020 10:41:12 +0200 Subject: regulator: stw481x-vmmc: Constify static structs The only usage of stw481x_vmmc_ops is to assign its address to the ops field in the regulator_desc struct which is a const pointer. The only usage of vmmc_regulator is to pass its address to of_get_regulator_init_data() and devm_regulator_register(), both which take const pointers. Make both of them const to allow the compiler to put them in read-only memory. Signed-off-by: Rikard Falkeborn Link: https://lore.kernel.org/r/20200913084114.8851-4-rikard.falkeborn@gmail.com Signed-off-by: Mark Brown --- drivers/regulator/stw481x-vmmc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/stw481x-vmmc.c b/drivers/regulator/stw481x-vmmc.c index 6dc2316daad3..127ab43add49 100644 --- a/drivers/regulator/stw481x-vmmc.c +++ b/drivers/regulator/stw481x-vmmc.c @@ -27,7 +27,7 @@ static const unsigned int stw481x_vmmc_voltages[] = { 3300000, }; -static struct regulator_ops stw481x_vmmc_ops = { +static const struct regulator_ops stw481x_vmmc_ops = { .list_voltage = regulator_list_voltage_table, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, @@ -36,7 +36,7 @@ static struct regulator_ops stw481x_vmmc_ops = { .set_voltage_sel = regulator_set_voltage_sel_regmap, }; -static struct regulator_desc vmmc_regulator = { +static const struct regulator_desc vmmc_regulator = { .name = "VMMC", .id = 0, .ops = &stw481x_vmmc_ops, -- cgit v1.2.3 From 72f2746c52e3fa6c0f6740df2d4fb70419533084 Mon Sep 17 00:00:00 2001 From: Rikard Falkeborn Date: Sun, 13 Sep 2020 10:41:13 +0200 Subject: regulator: pca9450: Constify static regulator_ops The only usages of these is to assign their address to the ops field in the regulator_desc struct, which is a const pointer. Make them const to allow the compiler to put them in read-only memory. Signed-off-by: Rikard Falkeborn Link: https://lore.kernel.org/r/20200913084114.8851-5-rikard.falkeborn@gmail.com Signed-off-by: Mark Brown --- drivers/regulator/pca9450-regulator.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/pca9450-regulator.c b/drivers/regulator/pca9450-regulator.c index eb5822bf53e0..cb29421d745a 100644 --- a/drivers/regulator/pca9450-regulator.c +++ b/drivers/regulator/pca9450-regulator.c @@ -90,7 +90,7 @@ static int pca9450_dvs_set_ramp_delay(struct regulator_dev *rdev, BUCK1_RAMP_MASK, ramp_value << 6); } -static struct regulator_ops pca9450_dvs_buck_regulator_ops = { +static const struct regulator_ops pca9450_dvs_buck_regulator_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, @@ -101,7 +101,7 @@ static struct regulator_ops pca9450_dvs_buck_regulator_ops = { .set_ramp_delay = pca9450_dvs_set_ramp_delay, }; -static struct regulator_ops pca9450_buck_regulator_ops = { +static const struct regulator_ops pca9450_buck_regulator_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, @@ -111,7 +111,7 @@ static struct regulator_ops pca9450_buck_regulator_ops = { .set_voltage_time_sel = regulator_set_voltage_time_sel, }; -static struct regulator_ops pca9450_ldo_regulator_ops = { +static const struct regulator_ops pca9450_ldo_regulator_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, -- cgit v1.2.3 From 2b37a18b58ed12b711591ec54c2b2a0e2068cf6e Mon Sep 17 00:00:00 2001 From: Rikard Falkeborn Date: Sun, 13 Sep 2020 10:41:14 +0200 Subject: regulator: ti-abb: Constify ti_abb_reg_ops The only usage of ti_abb_reg_ops is to assign its address to the ops field in the regulator_desc struct, which is a const pointer. Make it const to allow the compiler to put it in read-only memory. Signed-off-by: Rikard Falkeborn Link: https://lore.kernel.org/r/20200913084114.8851-6-rikard.falkeborn@gmail.com Signed-off-by: Mark Brown --- drivers/regulator/ti-abb-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/ti-abb-regulator.c b/drivers/regulator/ti-abb-regulator.c index af9abcd9c166..3e60bff76194 100644 --- a/drivers/regulator/ti-abb-regulator.c +++ b/drivers/regulator/ti-abb-regulator.c @@ -619,7 +619,7 @@ check_abb: return 0; } -static struct regulator_ops ti_abb_reg_ops = { +static const struct regulator_ops ti_abb_reg_ops = { .list_voltage = regulator_list_voltage_table, .set_voltage_sel = ti_abb_set_voltage_sel, -- cgit v1.2.3 From b014e9fae7e7de4329a7092ade4256982c5ce974 Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Thu, 17 Sep 2020 11:03:31 +0300 Subject: regulator: Support ROHM BD9576MUF and BD9573MUF Add initial support for ROHM BD9576MUF and BD9573MUF PMICs regulators. These PMICs are mainly used to power the R-Car series processors. The BD9576 includes some functional-safety features which are not present on BD9573. Signed-off-by: Matti Vaittinen Link: https://lore.kernel.org/r/78baea1d7922506827ca717e277e4e6b391bbb78.1600329307.git.matti.vaittinen@fi.rohmeurope.com Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 10 ++ drivers/regulator/Makefile | 1 + drivers/regulator/bd9576-regulator.c | 337 +++++++++++++++++++++++++++++++++++ 3 files changed, 348 insertions(+) create mode 100644 drivers/regulator/bd9576-regulator.c (limited to 'drivers/regulator') diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index de17ef7e18f0..49e698c042b8 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -231,6 +231,16 @@ config REGULATOR_BD9571MWV This driver can also be built as a module. If so, the module will be called bd9571mwv-regulator. +config REGULATOR_BD957XMUF + tristate "ROHM BD9576MUF and BD9573MUF Regulators" + depends on MFD_ROHM_BD957XMUF + help + This driver supports voltage regulators on ROHM BD9576MUF and + BD9573MUF PMICs. + + This driver can also be built as a module. If so, the module + will be called bd9576-regulator. + config REGULATOR_CPCAP tristate "Motorola CPCAP regulator" depends on MFD_CPCAP diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index d8d3ecf526a8..92f50f12ca6d 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -32,6 +32,7 @@ obj-$(CONFIG_REGULATOR_BD70528) += bd70528-regulator.o obj-$(CONFIG_REGULATOR_BD71828) += bd71828-regulator.o obj-$(CONFIG_REGULATOR_BD718XX) += bd718x7-regulator.o obj-$(CONFIG_REGULATOR_BD9571MWV) += bd9571mwv-regulator.o +obj-$(CONFIG_REGULATOR_BD957XMUF) += bd9576-regulator.o obj-$(CONFIG_REGULATOR_DA903X) += da903x-regulator.o obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o obj-$(CONFIG_REGULATOR_DA9055) += da9055-regulator.o diff --git a/drivers/regulator/bd9576-regulator.c b/drivers/regulator/bd9576-regulator.c new file mode 100644 index 000000000000..4137fa9a73bb --- /dev/null +++ b/drivers/regulator/bd9576-regulator.c @@ -0,0 +1,337 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2020 ROHM Semiconductors +// ROHM BD9576MUF/BD9573MUF regulator driver + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BD957X_VOUTS1_VOLT 3300000 +#define BD957X_VOUTS4_BASE_VOLT 1030000 +#define BD957X_VOUTS34_NUM_VOLT 32 + +static int vout1_volt_table[] = {5000000, 4900000, 4800000, 4700000, 4600000, + 4500000, 4500000, 4500000, 5000000, 5100000, + 5200000, 5300000, 5400000, 5500000, 5500000, + 5500000}; + +static int vout2_volt_table[] = {1800000, 1780000, 1760000, 1740000, 1720000, + 1700000, 1680000, 1660000, 1800000, 1820000, + 1840000, 1860000, 1880000, 1900000, 1920000, + 1940000}; + +static int voutl1_volt_table[] = {2500000, 2540000, 2580000, 2620000, 2660000, + 2700000, 2740000, 2780000, 2500000, 2460000, + 2420000, 2380000, 2340000, 2300000, 2260000, + 2220000}; + +struct bd957x_regulator_data { + struct regulator_desc desc; + int base_voltage; +}; + +static int bd957x_vout34_list_voltage(struct regulator_dev *rdev, + unsigned int selector) +{ + const struct regulator_desc *desc = rdev->desc; + int multiplier = selector & desc->vsel_mask & 0x7f; + int tune; + + /* VOUT3 and 4 has 10mV step */ + tune = multiplier * 10000; + + if (!(selector & 0x80)) + return desc->fixed_uV - tune; + + return desc->fixed_uV + tune; +} + +static int bd957x_list_voltage(struct regulator_dev *rdev, + unsigned int selector) +{ + const struct regulator_desc *desc = rdev->desc; + int index = selector & desc->vsel_mask & 0x7f; + + if (!(selector & 0x80)) + index += desc->n_voltages/2; + + if (index >= desc->n_voltages) + return -EINVAL; + + return desc->volt_table[index]; +} + +static const struct regulator_ops bd957x_vout34_ops = { + .is_enabled = regulator_is_enabled_regmap, + .list_voltage = bd957x_vout34_list_voltage, + .get_voltage_sel = regulator_get_voltage_sel_regmap, +}; + +static const struct regulator_ops bd957X_vouts1_regulator_ops = { + .is_enabled = regulator_is_enabled_regmap, +}; + +static const struct regulator_ops bd957x_ops = { + .is_enabled = regulator_is_enabled_regmap, + .list_voltage = bd957x_list_voltage, + .get_voltage_sel = regulator_get_voltage_sel_regmap, +}; + +static struct bd957x_regulator_data bd9576_regulators[] = { + { + .desc = { + .name = "VD50", + .of_match = of_match_ptr("regulator-vd50"), + .regulators_node = of_match_ptr("regulators"), + .id = BD957X_VD50, + .type = REGULATOR_VOLTAGE, + .ops = &bd957x_ops, + .volt_table = &vout1_volt_table[0], + .n_voltages = ARRAY_SIZE(vout1_volt_table), + .vsel_reg = BD957X_REG_VOUT1_TUNE, + .vsel_mask = BD957X_MASK_VOUT1_TUNE, + .enable_reg = BD957X_REG_POW_TRIGGER1, + .enable_mask = BD957X_REGULATOR_EN_MASK, + .enable_val = BD957X_REGULATOR_DIS_VAL, + .enable_is_inverted = true, + .owner = THIS_MODULE, + }, + }, + { + .desc = { + .name = "VD18", + .of_match = of_match_ptr("regulator-vd18"), + .regulators_node = of_match_ptr("regulators"), + .id = BD957X_VD18, + .type = REGULATOR_VOLTAGE, + .ops = &bd957x_ops, + .volt_table = &vout2_volt_table[0], + .n_voltages = ARRAY_SIZE(vout2_volt_table), + .vsel_reg = BD957X_REG_VOUT2_TUNE, + .vsel_mask = BD957X_MASK_VOUT2_TUNE, + .enable_reg = BD957X_REG_POW_TRIGGER2, + .enable_mask = BD957X_REGULATOR_EN_MASK, + .enable_val = BD957X_REGULATOR_DIS_VAL, + .enable_is_inverted = true, + .owner = THIS_MODULE, + }, + }, + { + .desc = { + .name = "VDDDR", + .of_match = of_match_ptr("regulator-vdddr"), + .regulators_node = of_match_ptr("regulators"), + .id = BD957X_VDDDR, + .ops = &bd957x_vout34_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = BD957X_VOUTS34_NUM_VOLT, + .vsel_reg = BD957X_REG_VOUT3_TUNE, + .vsel_mask = BD957X_MASK_VOUT3_TUNE, + .enable_reg = BD957X_REG_POW_TRIGGER3, + .enable_mask = BD957X_REGULATOR_EN_MASK, + .enable_val = BD957X_REGULATOR_DIS_VAL, + .enable_is_inverted = true, + .owner = THIS_MODULE, + }, + }, + { + .desc = { + .name = "VD10", + .of_match = of_match_ptr("regulator-vd10"), + .regulators_node = of_match_ptr("regulators"), + .id = BD957X_VD10, + .ops = &bd957x_vout34_ops, + .type = REGULATOR_VOLTAGE, + .fixed_uV = BD957X_VOUTS4_BASE_VOLT, + .n_voltages = BD957X_VOUTS34_NUM_VOLT, + .vsel_reg = BD957X_REG_VOUT4_TUNE, + .vsel_mask = BD957X_MASK_VOUT4_TUNE, + .enable_reg = BD957X_REG_POW_TRIGGER4, + .enable_mask = BD957X_REGULATOR_EN_MASK, + .enable_val = BD957X_REGULATOR_DIS_VAL, + .enable_is_inverted = true, + .owner = THIS_MODULE, + }, + }, + { + .desc = { + .name = "VOUTL1", + .of_match = of_match_ptr("regulator-voutl1"), + .regulators_node = of_match_ptr("regulators"), + .id = BD957X_VOUTL1, + .ops = &bd957x_ops, + .type = REGULATOR_VOLTAGE, + .volt_table = &voutl1_volt_table[0], + .n_voltages = ARRAY_SIZE(voutl1_volt_table), + .vsel_reg = BD957X_REG_VOUTL1_TUNE, + .vsel_mask = BD957X_MASK_VOUTL1_TUNE, + .enable_reg = BD957X_REG_POW_TRIGGERL1, + .enable_mask = BD957X_REGULATOR_EN_MASK, + .enable_val = BD957X_REGULATOR_DIS_VAL, + .enable_is_inverted = true, + .owner = THIS_MODULE, + }, + }, + { + .desc = { + .name = "VOUTS1", + .of_match = of_match_ptr("regulator-vouts1"), + .regulators_node = of_match_ptr("regulators"), + .id = BD957X_VOUTS1, + .ops = &bd957X_vouts1_regulator_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = 1, + .fixed_uV = BD957X_VOUTS1_VOLT, + .enable_reg = BD957X_REG_POW_TRIGGERS1, + .enable_mask = BD957X_REGULATOR_EN_MASK, + .enable_val = BD957X_REGULATOR_DIS_VAL, + .enable_is_inverted = true, + .owner = THIS_MODULE, + }, + }, +}; + +static int bd957x_probe(struct platform_device *pdev) +{ + struct regmap *regmap; + struct regulator_config config = { 0 }; + int i, err; + bool vout_mode, ddr_sel; + const struct bd957x_regulator_data *reg_data = &bd9576_regulators[0]; + unsigned int num_reg_data = ARRAY_SIZE(bd9576_regulators); + enum rohm_chip_type chip = platform_get_device_id(pdev)->driver_data; + + regmap = dev_get_regmap(pdev->dev.parent, NULL); + if (!regmap) { + dev_err(&pdev->dev, "No regmap\n"); + return -EINVAL; + } + vout_mode = of_property_read_bool(pdev->dev.parent->of_node, + "rohm,vout1-en-low"); + if (vout_mode) { + struct gpio_desc *en; + + dev_dbg(&pdev->dev, "GPIO controlled mode\n"); + + /* VOUT1 enable state judged by VOUT1_EN pin */ + /* See if we have GPIO defined */ + en = devm_gpiod_get_from_of_node(&pdev->dev, + pdev->dev.parent->of_node, + "rohm,vout1-en-gpios", 0, + GPIOD_OUT_LOW, "vout1-en"); + if (!IS_ERR(en)) { + /* VOUT1_OPS gpio ctrl */ + /* + * Regulator core prioritizes the ena_gpio over + * enable/disable/is_enabled callbacks so no need to + * clear them. We can still use same ops + */ + config.ena_gpiod = en; + } else { + /* + * In theory it is possible someone wants to set + * vout1-en LOW during OTP loading and set VOUT1 to be + * controlled by GPIO - but control the GPIO from some + * where else than this driver. For that to work we + * should unset the is_enabled callback here. + * + * I believe such case where rohm,vout1-en-low is set + * and vout1-en-gpios is not is likely to be a + * misconfiguration. So let's just err out for now. + */ + dev_err(&pdev->dev, + "Failed to get VOUT1 control GPIO\n"); + return PTR_ERR(en); + } + } + + /* + * If more than one PMIC needs to be controlled by same processor then + * allocate the regulator data array here and use bd9576_regulators as + * template. At the moment I see no such use-case so I spare some + * bytes and use bd9576_regulators directly for non-constant configs + * like DDR voltage selection. + */ + ddr_sel = of_property_read_bool(pdev->dev.parent->of_node, + "rohm,ddr-sel-low"); + if (ddr_sel) + bd9576_regulators[2].desc.fixed_uV = 1350000; + else + bd9576_regulators[2].desc.fixed_uV = 1500000; + + switch (chip) { + case ROHM_CHIP_TYPE_BD9576: + dev_dbg(&pdev->dev, "Found BD9576MUF\n"); + break; + case ROHM_CHIP_TYPE_BD9573: + pr_info(&pdev->dev, "Found BD9573MUF\n"); + break; + default: + dev_err(&pdev->dev, "Unsupported chip type\n"); + err = -EINVAL; + goto err; + } + + config.dev = pdev->dev.parent; + config.regmap = regmap; + + for (i = 0; i < num_reg_data; i++) { + + const struct regulator_desc *desc; + struct regulator_dev *rdev; + const struct bd957x_regulator_data *r; + + r = ®_data[i]; + desc = &r->desc; + + rdev = devm_regulator_register(&pdev->dev, desc, &config); + if (IS_ERR(rdev)) { + dev_err(&pdev->dev, + "failed to register %s regulator\n", + desc->name); + err = PTR_ERR(rdev); + goto err; + } + /* + * Clear the VOUT1 GPIO setting - rest of the regulators do not + * support GPIO control + */ + config.ena_gpiod = NULL; + } + +err: + return err; +} + +static const struct platform_device_id bd957x_pmic_id[] = { + { "bd9573-pmic", ROHM_CHIP_TYPE_BD9573 }, + { "bd9576-pmic", ROHM_CHIP_TYPE_BD9576 }, + { }, +}; +MODULE_DEVICE_TABLE(platform, bd957x_pmic_id); + +static struct platform_driver bd957x_regulator = { + .driver = { + .name = "bd957x-pmic", + }, + .probe = bd957x_probe, + .id_table = bd957x_pmic_id, +}; + +module_platform_driver(bd957x_regulator); + +MODULE_AUTHOR("Matti Vaittinen "); +MODULE_DESCRIPTION("ROHM BD9576/BD9573 voltage regulator driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:bd957x-pmic"); -- cgit v1.2.3 From 4c9db39361da5dcf0e77f4aeb4817be3bf7d626b Mon Sep 17 00:00:00 2001 From: Michał Mirosław Date: Sat, 19 Sep 2020 23:28:25 +0200 Subject: regulator: unexport regulator_lock/unlock() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit regulator_lock/unlock() was used only to guard regulator_notifier_call_chain(). As no users remain, make the functions internal. Signed-off-by: Michał Mirosław Link: https://lore.kernel.org/r/d3381aabd2632aff5e7b839d55868bec6e85c811.1600550732.git.mirq-linux@rere.qmqm.pl Signed-off-by: Mark Brown --- drivers/regulator/core.c | 6 ++---- include/linux/regulator/driver.h | 3 --- 2 files changed, 2 insertions(+), 7 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index a9c97c88f50e..6600949d08f8 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -190,11 +190,10 @@ static inline int regulator_lock_nested(struct regulator_dev *rdev, * than the one, which initially locked the mutex, it will * wait on mutex. */ -void regulator_lock(struct regulator_dev *rdev) +static void regulator_lock(struct regulator_dev *rdev) { regulator_lock_nested(rdev, NULL); } -EXPORT_SYMBOL_GPL(regulator_lock); /** * regulator_unlock - unlock a single regulator @@ -203,7 +202,7 @@ EXPORT_SYMBOL_GPL(regulator_lock); * This function unlocks the mutex when the * reference counter reaches 0. */ -void regulator_unlock(struct regulator_dev *rdev) +static void regulator_unlock(struct regulator_dev *rdev) { mutex_lock(®ulator_nesting_mutex); @@ -216,7 +215,6 @@ void regulator_unlock(struct regulator_dev *rdev) mutex_unlock(®ulator_nesting_mutex); } -EXPORT_SYMBOL_GPL(regulator_unlock); static bool regulator_supply_is_couple(struct regulator_dev *rdev) { diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index 8539f34ae42b..11cade73726c 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -533,9 +533,6 @@ int regulator_set_current_limit_regmap(struct regulator_dev *rdev, int regulator_get_current_limit_regmap(struct regulator_dev *rdev); void *regulator_get_init_drvdata(struct regulator_init_data *reg_init_data); -void regulator_lock(struct regulator_dev *rdev); -void regulator_unlock(struct regulator_dev *rdev); - /* * Helper functions intended to be used by regulator drivers prior registering * their regulators. -- cgit v1.2.3 From be35cc4695aa1b26d00b30bfd1d8408eddd357ec Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Sun, 20 Sep 2020 15:24:54 +0100 Subject: regulator: fix indentation issue There is a return statement that is indented with an extra space, fix this by removing it. Signed-off-by: Colin Ian King Link: https://lore.kernel.org/r/20200920142454.33352-1-colin.king@canonical.com Signed-off-by: Mark Brown --- drivers/regulator/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 6600949d08f8..6ef99df1a7d2 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -3065,7 +3065,7 @@ int regulator_get_hardware_vsel_register(struct regulator *regulator, *vsel_reg = rdev->desc->vsel_reg; *vsel_mask = rdev->desc->vsel_mask; - return 0; + return 0; } EXPORT_SYMBOL_GPL(regulator_get_hardware_vsel_register); -- cgit v1.2.3 From 0c7d1b4d0c1e7c4309e01532b811392b11b81693 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 20 Sep 2020 23:41:07 +0200 Subject: regulator: enable compile testing for Maxim and Samsung PMIC drivers Most of Maxim and Samsung PMIC/MUIC regulator drivers can be compile tested to increase build coverage. This allows to build them on configurations without I2C (as I2C is required by dependency - parent MFD driver). Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20200920214107.6299-1-krzk@kernel.org Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 4efa27b0f9f5..278ae0b06aee 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -510,7 +510,7 @@ config REGULATOR_MAX1586 config REGULATOR_MAX77620 tristate "Maxim 77620/MAX20024 voltage regulator" - depends on MFD_MAX77620 + depends on MFD_MAX77620 || COMPILE_TEST help This driver controls Maxim MAX77620 voltage output regulator via I2C bus. The provided regulator is suitable for Tegra @@ -519,7 +519,7 @@ config REGULATOR_MAX77620 config REGULATOR_MAX77650 tristate "Maxim MAX77650/77651 regulator support" - depends on MFD_MAX77650 + depends on MFD_MAX77650 || COMPILE_TEST help Regulator driver for MAX77650/77651 PMIC from Maxim Semiconductor. This device has a SIMO with three independent @@ -542,7 +542,7 @@ config REGULATOR_MAX8660 config REGULATOR_MAX8907 tristate "Maxim 8907 voltage regulator" - depends on MFD_MAX8907 + depends on MFD_MAX8907 || COMPILE_TEST help This driver controls a Maxim 8907 voltage output regulator via I2C bus. The provided regulator is suitable for Tegra @@ -592,7 +592,7 @@ config REGULATOR_MAX8998 config REGULATOR_MAX77686 tristate "Maxim 77686 regulator" - depends on MFD_MAX77686 + depends on MFD_MAX77686 || COMPILE_TEST help This driver controls a Maxim 77686 regulator via I2C bus. The provided regulator is suitable for @@ -600,7 +600,7 @@ config REGULATOR_MAX77686 config REGULATOR_MAX77693 tristate "Maxim 77693/77843 regulator" - depends on (MFD_MAX77693 || MFD_MAX77843) + depends on MFD_MAX77693 || MFD_MAX77843 || COMPILE_TEST help This driver controls a Maxim 77693/77843 regulators via I2C bus. The regulators include two LDOs, 'SAFEOUT1', 'SAFEOUT2' @@ -609,7 +609,7 @@ config REGULATOR_MAX77693 config REGULATOR_MAX77802 tristate "Maxim 77802 regulator" - depends on MFD_MAX77686 + depends on MFD_MAX77686 || COMPILE_TEST help This driver controls a Maxim 77802 regulator via I2C bus. The provided regulator is suitable for @@ -941,14 +941,14 @@ config REGULATOR_RT5033 config REGULATOR_S2MPA01 tristate "Samsung S2MPA01 voltage regulator" - depends on MFD_SEC_CORE + depends on MFD_SEC_CORE || COMPILE_TEST help This driver controls Samsung S2MPA01 voltage output regulator via I2C bus. S2MPA01 has 10 Bucks and 26 LDO outputs. config REGULATOR_S2MPS11 tristate "Samsung S2MPS11/13/14/15/S2MPU02 voltage regulator" - depends on MFD_SEC_CORE + depends on MFD_SEC_CORE || COMPILE_TEST help This driver supports a Samsung S2MPS11/13/14/15/S2MPU02 voltage output regulator via I2C bus. The chip is comprised of high efficient @@ -957,7 +957,7 @@ config REGULATOR_S2MPS11 config REGULATOR_S5M8767 tristate "Samsung S5M8767A voltage regulator" - depends on MFD_SEC_CORE + depends on MFD_SEC_CORE || COMPILE_TEST help This driver supports a Samsung S5M8767A voltage output regulator via I2C bus. S5M8767A have 9 Bucks and 28 LDOs output and -- cgit v1.2.3 From 8d23b0b8fc950cba2046840c46b21db9b5c0573c Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 21 Sep 2020 22:36:16 +0200 Subject: regulator: s5m8767: initialize driver via module_platform_driver The driver was using subsys_initcall() because in old times deferred probe was not supported everywhere and specific ordering was needed. Since probe deferral works fine and specific ordering is discouraged (hides dependencies between drivers and couples their boot order), the driver can be converted to regular module_platform_driver. Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20200921203616.19623-1-krzk@kernel.org Signed-off-by: Mark Brown --- drivers/regulator/s5m8767.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index 4abd3ed31f60..3fa472127e9a 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c @@ -1000,18 +1000,7 @@ static struct platform_driver s5m8767_pmic_driver = { .probe = s5m8767_pmic_probe, .id_table = s5m8767_pmic_id, }; - -static int __init s5m8767_pmic_init(void) -{ - return platform_driver_register(&s5m8767_pmic_driver); -} -subsys_initcall(s5m8767_pmic_init); - -static void __exit s5m8767_pmic_exit(void) -{ - platform_driver_unregister(&s5m8767_pmic_driver); -} -module_exit(s5m8767_pmic_exit); +module_platform_driver(s5m8767_pmic_driver); /* Module information */ MODULE_AUTHOR("Sangbeom Kim "); -- cgit v1.2.3 From 99ad5f6ec0cd776e34295ec9fc82bfb004c3fad5 Mon Sep 17 00:00:00 2001 From: Michał Mirosław Date: Sat, 26 Sep 2020 23:32:40 +0200 Subject: regulator: print state at boot MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make the initial state of the regulator shown when debugging. Signed-off-by: Michał Mirosław Link: https://lore.kernel.org/r/53c4f3d394d68f0989174f89e3b0882cebbbd787.1601155770.git.mirq-linux@rere.qmqm.pl Signed-off-by: Mark Brown --- drivers/regulator/core.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 6ef99df1a7d2..42cffbe84080 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1111,10 +1111,15 @@ static void print_constraints(struct regulator_dev *rdev) if (constraints->valid_modes_mask & REGULATOR_MODE_IDLE) count += scnprintf(buf + count, len - count, "idle "); if (constraints->valid_modes_mask & REGULATOR_MODE_STANDBY) - count += scnprintf(buf + count, len - count, "standby"); + count += scnprintf(buf + count, len - count, "standby "); if (!count) - scnprintf(buf, len, "no parameters"); + count = scnprintf(buf, len, "no parameters"); + else + --count; + + count += scnprintf(buf + count, len - count, ", %s", + _regulator_is_enabled(rdev) ? "enabled" : "disabled"); rdev_dbg(rdev, "%s\n", buf); -- cgit v1.2.3 From 61aab5ad27d551f1535861e871dd9b03f5fbfd76 Mon Sep 17 00:00:00 2001 From: Michał Mirosław Date: Sat, 26 Sep 2020 23:32:40 +0200 Subject: regulator: print symbolic errors in kernel messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change all error-printing messages to include error name via %pe instead of numeric error or nothing. Signed-off-by: Michał Mirosław Link: https://lore.kernel.org/r/1dcf25f39188882eb56918a9aa281ab17b792aa5.1601155770.git.mirq-linux@rere.qmqm.pl Signed-off-by: Mark Brown --- drivers/regulator/core.c | 94 +++++++++++++++++++++++++----------------------- 1 file changed, 49 insertions(+), 45 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 42cffbe84080..ff8e99ca0306 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -964,7 +964,8 @@ static int drms_uA_update(struct regulator_dev *rdev) /* set the optimum mode for our new total regulator load */ err = rdev->desc->ops->set_load(rdev, current_uA); if (err < 0) - rdev_err(rdev, "failed to set load %d\n", current_uA); + rdev_err(rdev, "failed to set load %d: %pe\n", + current_uA, ERR_PTR(err)); } else { /* get output voltage */ output_uV = regulator_get_voltage_rdev(rdev); @@ -991,14 +992,15 @@ static int drms_uA_update(struct regulator_dev *rdev) /* check the new mode is allowed */ err = regulator_mode_constrain(rdev, &mode); if (err < 0) { - rdev_err(rdev, "failed to get optimum mode @ %d uA %d -> %d uV\n", - current_uA, input_uV, output_uV); + rdev_err(rdev, "failed to get optimum mode @ %d uA %d -> %d uV: %pe\n", + current_uA, input_uV, output_uV, ERR_PTR(err)); return err; } err = rdev->desc->ops->set_mode(rdev, mode); if (err < 0) - rdev_err(rdev, "failed to set optimum mode %x\n", mode); + rdev_err(rdev, "failed to set optimum mode %x: %pe\n", + mode, ERR_PTR(err)); } return err; @@ -1019,14 +1021,14 @@ static int __suspend_set_state(struct regulator_dev *rdev, ret = 0; if (ret < 0) { - rdev_err(rdev, "failed to enabled/disable\n"); + rdev_err(rdev, "failed to enabled/disable: %pe\n", ERR_PTR(ret)); return ret; } if (rdev->desc->ops->set_suspend_voltage && rstate->uV > 0) { ret = rdev->desc->ops->set_suspend_voltage(rdev, rstate->uV); if (ret < 0) { - rdev_err(rdev, "failed to set voltage\n"); + rdev_err(rdev, "failed to set voltage: %pe\n", ERR_PTR(ret)); return ret; } } @@ -1034,7 +1036,7 @@ static int __suspend_set_state(struct regulator_dev *rdev, if (rdev->desc->ops->set_suspend_mode && rstate->mode > 0) { ret = rdev->desc->ops->set_suspend_mode(rdev, rstate->mode); if (ret < 0) { - rdev_err(rdev, "failed to set mode\n"); + rdev_err(rdev, "failed to set mode: %pe\n", ERR_PTR(ret)); return ret; } } @@ -1154,8 +1156,8 @@ static int machine_constraints_voltage(struct regulator_dev *rdev, if (current_uV < 0) { rdev_err(rdev, - "failed to get the current voltage(%d)\n", - current_uV); + "failed to get the current voltage: %pe\n", + ERR_PTR(current_uV)); return current_uV; } @@ -1184,8 +1186,8 @@ static int machine_constraints_voltage(struct regulator_dev *rdev, rdev, target_min, target_max); if (ret < 0) { rdev_err(rdev, - "failed to apply %d-%duV constraint(%d)\n", - target_min, target_max, ret); + "failed to apply %d-%duV constraint: %pe\n", + target_min, target_max, ERR_PTR(ret)); return ret; } } @@ -1334,7 +1336,7 @@ static int set_machine_constraints(struct regulator_dev *rdev, ret = ops->set_input_current_limit(rdev, rdev->constraints->ilim_uA); if (ret < 0) { - rdev_err(rdev, "failed to set input limit\n"); + rdev_err(rdev, "failed to set input limit: %pe\n", ERR_PTR(ret)); return ret; } } @@ -1343,7 +1345,7 @@ static int set_machine_constraints(struct regulator_dev *rdev, if (rdev->constraints->initial_state) { ret = suspend_set_initial_state(rdev); if (ret < 0) { - rdev_err(rdev, "failed to set suspend state\n"); + rdev_err(rdev, "failed to set suspend state: %pe\n", ERR_PTR(ret)); return ret; } } @@ -1356,7 +1358,7 @@ static int set_machine_constraints(struct regulator_dev *rdev, ret = ops->set_mode(rdev, rdev->constraints->initial_mode); if (ret < 0) { - rdev_err(rdev, "failed to set initial mode: %d\n", ret); + rdev_err(rdev, "failed to set initial mode: %pe\n", ERR_PTR(ret)); return ret; } } else if (rdev->constraints->system_load) { @@ -1371,7 +1373,7 @@ static int set_machine_constraints(struct regulator_dev *rdev, && ops->set_ramp_delay) { ret = ops->set_ramp_delay(rdev, rdev->constraints->ramp_delay); if (ret < 0) { - rdev_err(rdev, "failed to set ramp_delay\n"); + rdev_err(rdev, "failed to set ramp_delay: %pe\n", ERR_PTR(ret)); return ret; } } @@ -1379,7 +1381,7 @@ static int set_machine_constraints(struct regulator_dev *rdev, if (rdev->constraints->pull_down && ops->set_pull_down) { ret = ops->set_pull_down(rdev); if (ret < 0) { - rdev_err(rdev, "failed to set pull down\n"); + rdev_err(rdev, "failed to set pull down: %pe\n", ERR_PTR(ret)); return ret; } } @@ -1387,7 +1389,7 @@ static int set_machine_constraints(struct regulator_dev *rdev, if (rdev->constraints->soft_start && ops->set_soft_start) { ret = ops->set_soft_start(rdev); if (ret < 0) { - rdev_err(rdev, "failed to set soft start\n"); + rdev_err(rdev, "failed to set soft start: %pe\n", ERR_PTR(ret)); return ret; } } @@ -1396,7 +1398,8 @@ static int set_machine_constraints(struct regulator_dev *rdev, && ops->set_over_current_protection) { ret = ops->set_over_current_protection(rdev); if (ret < 0) { - rdev_err(rdev, "failed to set over current protection\n"); + rdev_err(rdev, "failed to set over current protection: %pe\n", + ERR_PTR(ret)); return ret; } } @@ -1407,7 +1410,7 @@ static int set_machine_constraints(struct regulator_dev *rdev, ret = ops->set_active_discharge(rdev, ad_state); if (ret < 0) { - rdev_err(rdev, "failed to set active discharge\n"); + rdev_err(rdev, "failed to set active discharge: %pe\n", ERR_PTR(ret)); return ret; } } @@ -1427,7 +1430,7 @@ static int set_machine_constraints(struct regulator_dev *rdev, ret = _regulator_do_enable(rdev); if (ret < 0 && ret != -EINVAL) { - rdev_err(rdev, "failed to enable\n"); + rdev_err(rdev, "failed to enable: %pe\n", ERR_PTR(ret)); return ret; } @@ -1651,8 +1654,8 @@ static struct regulator *create_regulator(struct regulator_dev *rdev, err = sysfs_create_link_nowarn(&rdev->dev.kobj, &dev->kobj, supply_name); if (err) { - rdev_dbg(rdev, "could not add device link %s err %d\n", - dev->kobj.name, err); + rdev_dbg(rdev, "could not add device link %s: %pe\n", + dev->kobj.name, ERR_PTR(err)); /* non-fatal */ } } @@ -2440,7 +2443,7 @@ static int _regulator_do_enable(struct regulator_dev *rdev) if (ret >= 0) { delay = ret; } else { - rdev_warn(rdev, "enable_time() failed: %d\n", ret); + rdev_warn(rdev, "enable_time() failed: %pe\n", ERR_PTR(ret)); delay = 0; } @@ -2629,7 +2632,7 @@ static int _regulator_enable(struct regulator *regulator) _notifier_call_chain(rdev, REGULATOR_EVENT_ENABLE, NULL); } else if (ret < 0) { - rdev_err(rdev, "is_enabled() failed: %d\n", ret); + rdev_err(rdev, "is_enabled() failed: %pe\n", ERR_PTR(ret)); goto err_consumer_disable; } /* Fallthrough on positive return values - already enabled */ @@ -2731,7 +2734,7 @@ static int _regulator_disable(struct regulator *regulator) ret = _regulator_do_disable(rdev); if (ret < 0) { - rdev_err(rdev, "failed to disable\n"); + rdev_err(rdev, "failed to disable: %pe\n", ERR_PTR(ret)); _notifier_call_chain(rdev, REGULATOR_EVENT_ABORT_DISABLE, NULL); @@ -2798,7 +2801,7 @@ static int _regulator_force_disable(struct regulator_dev *rdev) ret = _regulator_do_disable(rdev); if (ret < 0) { - rdev_err(rdev, "failed to force disable\n"); + rdev_err(rdev, "failed to force disable: %pe\n", ERR_PTR(ret)); _notifier_call_chain(rdev, REGULATOR_EVENT_FORCE_DISABLE | REGULATOR_EVENT_ABORT_DISABLE, NULL); return ret; @@ -2877,7 +2880,8 @@ static void regulator_disable_work(struct work_struct *work) for (i = 0; i < count; i++) { ret = _regulator_disable(regulator); if (ret != 0) - rdev_err(rdev, "Deferred disable failed: %d\n", ret); + rdev_err(rdev, "Deferred disable failed: %pe\n", + ERR_PTR(ret)); } } WARN_ON(!total_count); @@ -3402,7 +3406,7 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, } if (delay < 0) { - rdev_warn(rdev, "failed to get delay: %d\n", delay); + rdev_warn(rdev, "failed to get delay: %pe\n", ERR_PTR(delay)); delay = 0; } @@ -3554,8 +3558,8 @@ int regulator_set_voltage_rdev(struct regulator_dev *rdev, int min_uV, ret = regulator_set_voltage_unlocked(rdev->supply, best_supply_uV, INT_MAX, state); if (ret) { - dev_err(&rdev->dev, "Failed to increase supply voltage: %d\n", - ret); + dev_err(&rdev->dev, "Failed to increase supply voltage: %pe\n", + ERR_PTR(ret)); goto out; } } @@ -3572,8 +3576,8 @@ int regulator_set_voltage_rdev(struct regulator_dev *rdev, int min_uV, ret = regulator_set_voltage_unlocked(rdev->supply, best_supply_uV, INT_MAX, state); if (ret) - dev_warn(&rdev->dev, "Failed to decrease supply voltage: %d\n", - ret); + dev_warn(&rdev->dev, "Failed to decrease supply voltage: %pe\n", + ERR_PTR(ret)); /* No need to fail here */ ret = 0; } @@ -4559,8 +4563,8 @@ int regulator_bulk_get(struct device *dev, int num_consumers, err: if (ret != -EPROBE_DEFER) - dev_err(dev, "Failed to get supply '%s': %d\n", - consumers[i].supply, ret); + dev_err(dev, "Failed to get supply '%s': %pe\n", + consumers[i].supply, ERR_PTR(ret)); else dev_dbg(dev, "Failed to get supply '%s', deferring\n", consumers[i].supply); @@ -4618,8 +4622,8 @@ int regulator_bulk_enable(int num_consumers, err: for (i = 0; i < num_consumers; i++) { if (consumers[i].ret < 0) - pr_err("Failed to enable %s: %d\n", consumers[i].supply, - consumers[i].ret); + pr_err("Failed to enable %s: %pe\n", consumers[i].supply, + ERR_PTR(consumers[i].ret)); else regulator_disable(consumers[i].consumer); } @@ -4655,12 +4659,12 @@ int regulator_bulk_disable(int num_consumers, return 0; err: - pr_err("Failed to disable %s: %d\n", consumers[i].supply, ret); + pr_err("Failed to disable %s: %pe\n", consumers[i].supply, ERR_PTR(ret)); for (++i; i < num_consumers; ++i) { r = regulator_enable(consumers[i].consumer); if (r != 0) - pr_err("Failed to re-enable %s: %d\n", - consumers[i].supply, r); + pr_err("Failed to re-enable %s: %pe\n", + consumers[i].supply, ERR_PTR(r)); } return ret; @@ -5043,8 +5047,8 @@ static void regulator_remove_coupling(struct regulator_dev *rdev) if (coupler && coupler->detach_regulator) { err = coupler->detach_regulator(coupler, rdev); if (err) - rdev_err(rdev, "failed to detach from coupler: %d\n", - err); + rdev_err(rdev, "failed to detach from coupler: %pe\n", + ERR_PTR(err)); } kfree(rdev->coupling_desc.coupled_rdevs); @@ -5088,7 +5092,7 @@ static int regulator_init_coupling(struct regulator_dev *rdev) if (IS_ERR(rdev->coupling_desc.coupler)) { err = PTR_ERR(rdev->coupling_desc.coupler); - rdev_err(rdev, "failed to get coupler: %d\n", err); + rdev_err(rdev, "failed to get coupler: %pe\n", ERR_PTR(err)); return err; } @@ -5251,8 +5255,8 @@ regulator_register(const struct regulator_desc *regulator_desc, if (config->ena_gpiod) { ret = regulator_ena_gpio_request(rdev, config); if (ret != 0) { - rdev_err(rdev, "Failed to request enable GPIO: %d\n", - ret); + rdev_err(rdev, "Failed to request enable GPIO: %pe\n", + ERR_PTR(ret)); goto clean; } /* The regulator core took over the GPIO descriptor */ @@ -5837,7 +5841,7 @@ static int regulator_late_cleanup(struct device *dev, void *data) rdev_info(rdev, "disabling\n"); ret = _regulator_do_disable(rdev); if (ret != 0) - rdev_err(rdev, "couldn't disable: %d\n", ret); + rdev_err(rdev, "couldn't disable: %pe\n", ERR_PTR(ret)); } else { /* The intention is that in future we will * assume that full constraints are provided -- cgit v1.2.3 From aea6cb99703e17019e025aa71643b4d3e0a24413 Mon Sep 17 00:00:00 2001 From: Michał Mirosław Date: Sat, 26 Sep 2020 23:32:41 +0200 Subject: regulator: resolve supply after creating regulator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When creating a new regulator its supply cannot create the sysfs link because the device is not yet published. Remove early supply resolving since it will be done later anyway. This makes the following error disappear and the symlinks get created instead. DCDC_REG1: supplied by VSYS VSYS: could not add device link regulator.3 err -2 Note: It doesn't fix the problem for bypassed regulators, though. Fixes: 45389c47526d ("regulator: core: Add early supply resolution for regulators") Signed-off-by: Michał Mirosław Link: https://lore.kernel.org/r/ba09e0a8617ffeeb25cb4affffe6f3149319cef8.1601155770.git.mirq-linux@rere.qmqm.pl Signed-off-by: Mark Brown --- drivers/regulator/core.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index ff8e99ca0306..9f704a6c4802 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -5280,15 +5280,20 @@ regulator_register(const struct regulator_desc *regulator_desc, else if (regulator_desc->supply_name) rdev->supply_name = regulator_desc->supply_name; - /* - * Attempt to resolve the regulator supply, if specified, - * but don't return an error if we fail because we will try - * to resolve it again later as more regulators are added. - */ - if (regulator_resolve_supply(rdev)) - rdev_dbg(rdev, "unable to resolve supply\n"); - ret = set_machine_constraints(rdev, constraints); + if (ret == -EPROBE_DEFER) { + /* Regulator might be in bypass mode and so needs its supply + * to set the constraints */ + /* FIXME: this currently triggers a chicken-and-egg problem + * when creating -SUPPLY symlink in sysfs to a regulator + * that is just being created */ + ret = regulator_resolve_supply(rdev); + if (!ret) + ret = set_machine_constraints(rdev, constraints); + else + rdev_dbg(rdev, "unable to resolve supply early: %pe\n", + ERR_PTR(ret)); + } if (ret < 0) goto wash; -- cgit v1.2.3 From b8c054a5eaf0cf2b9532969e5168ce5e2d78c284 Mon Sep 17 00:00:00 2001 From: ChiYuan Huang Date: Mon, 28 Sep 2020 15:19:43 +0800 Subject: regulator: rtmv20: Adds support for Richtek RTMV20 load switch regulator Add support for Richtek RTMV20 load switch regulator. Signed-off-by: ChiYuan Huang Link: https://lore.kernel.org/r/1601277584-5526-1-git-send-email-u0084500@gmail.com Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 9 + drivers/regulator/Makefile | 1 + drivers/regulator/rtmv20-regulator.c | 392 +++++++++++++++++++++++++++++++++++ 3 files changed, 402 insertions(+) create mode 100644 drivers/regulator/rtmv20-regulator.c (limited to 'drivers/regulator') diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 278ae0b06aee..020a00d6696b 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -939,6 +939,15 @@ config REGULATOR_RT5033 RT5033 PMIC. The device supports multiple regulators like current source, LDO and Buck. +config REGULATOR_RTMV20 + tristate "RTMV20 Laser Diode Regulator" + depends on I2C + select REGMAP_I2C + help + This driver adds support for the load switch current regulator on + the Richtek RTMV20. It can support the load current up to 6A and + integrate strobe/vsync/fsin signal to synchronize the IR camera. + config REGULATOR_S2MPA01 tristate "Samsung S2MPA01 voltage regulator" depends on MFD_SEC_CORE || COMPILE_TEST diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index cf908f67b486..6ebae516258e 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -116,6 +116,7 @@ obj-$(CONFIG_REGULATOR_RN5T618) += rn5t618-regulator.o obj-$(CONFIG_REGULATOR_ROHM) += rohm-regulator.o obj-$(CONFIG_REGULATOR_RT4801) += rt4801-regulator.o obj-$(CONFIG_REGULATOR_RT5033) += rt5033-regulator.o +obj-$(CONFIG_REGULATOR_RTMV20) += rtmv20-regulator.o obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o diff --git a/drivers/regulator/rtmv20-regulator.c b/drivers/regulator/rtmv20-regulator.c new file mode 100644 index 000000000000..1075b102e58e --- /dev/null +++ b/drivers/regulator/rtmv20-regulator.c @@ -0,0 +1,392 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define RTMV20_REG_DEVINFO 0x00 +#define RTMV20_REG_PULSEDELAY 0x01 +#define RTMV20_REG_PULSEWIDTH 0x03 +#define RTMV20_REG_LDCTRL1 0x05 +#define RTMV20_REG_ESPULSEWIDTH 0x06 +#define RTMV20_REG_ESLDCTRL1 0x08 +#define RTMV20_REG_LBP 0x0A +#define RTMV20_REG_LDCTRL2 0x0B +#define RTMV20_REG_FSIN1CTRL1 0x0D +#define RTMV20_REG_FSIN1CTRL3 0x0F +#define RTMV20_REG_FSIN2CTRL1 0x10 +#define RTMV20_REG_FSIN2CTRL3 0x12 +#define RTMV20_REG_ENCTRL 0x13 +#define RTMV20_REG_STRBVSYNDLYL 0x29 +#define RTMV20_REG_LDIRQ 0x30 +#define RTMV20_REG_LDSTAT 0x40 +#define RTMV20_REG_LDMASK 0x50 + +#define RTMV20_VID_MASK GENMASK(7, 4) +#define RICHTEK_VID 0x80 +#define RTMV20_LDCURR_MASK GENMASK(7, 0) +#define RTMV20_DELAY_MASK GENMASK(9, 0) +#define RTMV20_WIDTH_MASK GENMASK(13, 0) +#define RTMV20_WIDTH2_MASK GENMASK(7, 0) +#define RTMV20_LBPLVL_MASK GENMASK(3, 0) +#define RTMV20_LBPEN_MASK BIT(7) +#define RTMV20_STROBEPOL_MASK BIT(1) +#define RTMV20_VSYNPOL_MASK BIT(1) +#define RTMV20_FSINEN_MASK BIT(7) +#define RTMV20_ESEN_MASK BIT(6) +#define RTMV20_FSINOUT_MASK BIT(2) +#define LDENABLE_MASK (BIT(3) | BIT(0)) + +#define OTPEVT_MASK BIT(4) +#define SHORTEVT_MASK BIT(3) +#define OPENEVT_MASK BIT(2) +#define LBPEVT_MASK BIT(1) +#define OCPEVT_MASK BIT(0) +#define FAILEVT_MASK (SHORTEVT_MASK | OPENEVT_MASK | LBPEVT_MASK) + +#define RTMV20_LSW_MINUA 0 +#define RTMV20_LSW_MAXUA 6000000 +#define RTMV20_LSW_STEPUA 30000 + +#define RTMV20_LSW_DEFAULTUA 3000000 + +#define RTMV20_I2CRDY_TIMEUS 200 +#define RTMV20_CSRDY_TIMEUS 2000 + +struct rtmv20_priv { + struct device *dev; + struct regmap *regmap; + struct gpio_desc *enable_gpio; + struct regulator_dev *rdev; +}; + +static int rtmv20_lsw_enable(struct regulator_dev *rdev) +{ + struct rtmv20_priv *priv = rdev_get_drvdata(rdev); + int ret; + + gpiod_set_value(priv->enable_gpio, 1); + + /* Wait for I2C can be accessed */ + usleep_range(RTMV20_I2CRDY_TIMEUS, RTMV20_I2CRDY_TIMEUS + 100); + + /* HW re-enable, disable cache only and sync regcache here */ + regcache_cache_only(priv->regmap, false); + ret = regcache_sync(priv->regmap); + if (ret) + return ret; + + return regulator_enable_regmap(rdev); +} + +static int rtmv20_lsw_disable(struct regulator_dev *rdev) +{ + struct rtmv20_priv *priv = rdev_get_drvdata(rdev); + int ret; + + ret = regulator_disable_regmap(rdev); + if (ret) + return ret; + + /* Mark the regcache as dirty and cache only before HW disabled */ + regcache_cache_only(priv->regmap, true); + regcache_mark_dirty(priv->regmap); + + gpiod_set_value(priv->enable_gpio, 0); + + return 0; +} + +static const struct regulator_ops rtmv20_regulator_ops = { + .set_current_limit = regulator_set_current_limit_regmap, + .get_current_limit = regulator_get_current_limit_regmap, + .enable = rtmv20_lsw_enable, + .disable = rtmv20_lsw_disable, + .is_enabled = regulator_is_enabled_regmap, +}; + +static const struct regulator_desc rtmv20_lsw_desc = { + .name = "rtmv20,lsw", + .of_match = of_match_ptr("lsw"), + .type = REGULATOR_CURRENT, + .owner = THIS_MODULE, + .ops = &rtmv20_regulator_ops, + .csel_reg = RTMV20_REG_LDCTRL1, + .csel_mask = RTMV20_LDCURR_MASK, + .enable_reg = RTMV20_REG_ENCTRL, + .enable_mask = LDENABLE_MASK, + .enable_time = RTMV20_CSRDY_TIMEUS, +}; + +static irqreturn_t rtmv20_irq_handler(int irq, void *data) +{ + struct rtmv20_priv *priv = data; + unsigned int val; + int ret; + + ret = regmap_read(priv->regmap, RTMV20_REG_LDIRQ, &val); + if (ret) { + dev_err(priv->dev, "Failed to get irq flags\n"); + return IRQ_NONE; + } + + if (val & OTPEVT_MASK) + regulator_notifier_call_chain(priv->rdev, REGULATOR_EVENT_OVER_TEMP, NULL); + + if (val & OCPEVT_MASK) + regulator_notifier_call_chain(priv->rdev, REGULATOR_EVENT_OVER_CURRENT, NULL); + + if (val & FAILEVT_MASK) + regulator_notifier_call_chain(priv->rdev, REGULATOR_EVENT_FAIL, NULL); + + return IRQ_HANDLED; +} + +static u32 clamp_to_selector(u32 val, u32 min, u32 max, u32 step) +{ + u32 retval = clamp_val(val, min, max); + + return (retval - min) / step; +} + +static int rtmv20_properties_init(struct rtmv20_priv *priv) +{ + const struct { + const char *name; + u32 def; + u32 min; + u32 max; + u32 step; + u32 addr; + u32 mask; + } props[] = { + { "ld-pulse-delay-us", 0, 0, 100000, 100, RTMV20_REG_PULSEDELAY, + RTMV20_DELAY_MASK }, + { "ld-pulse-width-us", 1200, 0, 10000, 1, RTMV20_REG_PULSEWIDTH, + RTMV20_WIDTH_MASK }, + { "fsin1-delay-us", 23000, 0, 100000, 100, RTMV20_REG_FSIN1CTRL1, + RTMV20_DELAY_MASK }, + { "fsin1-width-us", 160, 40, 10000, 40, RTMV20_REG_FSIN1CTRL3, RTMV20_WIDTH2_MASK }, + { "fsin2-delay-us", 23000, 0, 100000, 100, RTMV20_REG_FSIN2CTRL1, + RTMV20_DELAY_MASK }, + { "fsin2-width-us", 160, 40, 10000, 40, RTMV20_REG_FSIN2CTRL3, RTMV20_WIDTH2_MASK }, + { "es-pulse-width-us", 1200, 0, 10000, 1, RTMV20_REG_ESPULSEWIDTH, + RTMV20_WIDTH_MASK }, + { "es-ld-current-microamp", 3000000, 0, 6000000, 30000, RTMV20_REG_ESLDCTRL1, + RTMV20_LDCURR_MASK }, + { "lbp-level-microvolt", 2700000, 2400000, 3700000, 100000, RTMV20_REG_LBP, + RTMV20_LBPLVL_MASK }, + { "lbp-enable", 0, 0, 1, 1, RTMV20_REG_LBP, RTMV20_LBPEN_MASK }, + { "strobe-polarity-high", 1, 0, 1, 1, RTMV20_REG_LDCTRL2, RTMV20_STROBEPOL_MASK }, + { "vsync-polarity-high", 1, 0, 1, 1, RTMV20_REG_LDCTRL2, RTMV20_VSYNPOL_MASK }, + { "fsin-enable", 0, 0, 1, 1, RTMV20_REG_ENCTRL, RTMV20_FSINEN_MASK }, + { "fsin-output", 0, 0, 1, 1, RTMV20_REG_ENCTRL, RTMV20_FSINOUT_MASK }, + { "es-enable", 0, 0, 1, 1, RTMV20_REG_ENCTRL, RTMV20_ESEN_MASK }, + }; + int i, ret; + + for (i = 0; i < ARRAY_SIZE(props); i++) { + __be16 bval16; + u16 val16; + u32 temp; + int significant_bit = fls(props[i].mask); + int shift = ffs(props[i].mask) - 1; + + if (props[i].max > 1) { + ret = device_property_read_u32(priv->dev, props[i].name, &temp); + if (ret) + temp = props[i].def; + } else + temp = device_property_read_bool(priv->dev, props[i].name); + + temp = clamp_to_selector(temp, props[i].min, props[i].max, props[i].step); + + /* If significant bit is over 8, two byte access, others one */ + if (significant_bit > 8) { + ret = regmap_raw_read(priv->regmap, props[i].addr, &bval16, sizeof(bval16)); + if (ret) + return ret; + + val16 = be16_to_cpu(bval16); + val16 &= ~props[i].mask; + val16 |= (temp << shift); + bval16 = cpu_to_be16(val16); + + ret = regmap_raw_write(priv->regmap, props[i].addr, &bval16, + sizeof(bval16)); + } else { + ret = regmap_update_bits(priv->regmap, props[i].addr, props[i].mask, + temp << shift); + } + + if (ret) + return ret; + } + + return 0; +} + +static int rtmv20_check_chip_exist(struct rtmv20_priv *priv) +{ + unsigned int val; + int ret; + + ret = regmap_read(priv->regmap, RTMV20_REG_DEVINFO, &val); + if (ret) + return ret; + + if ((val & RTMV20_VID_MASK) != RICHTEK_VID) + return -ENODEV; + + return 0; +} + +static bool rtmv20_is_accessible_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case RTMV20_REG_DEVINFO ... RTMV20_REG_STRBVSYNDLYL: + case RTMV20_REG_LDIRQ: + case RTMV20_REG_LDSTAT: + case RTMV20_REG_LDMASK: + return true; + } + return false; +} + +static bool rtmv20_is_volatile_reg(struct device *dev, unsigned int reg) +{ + if (reg == RTMV20_REG_LDIRQ || reg == RTMV20_REG_LDSTAT) + return true; + return false; +} + +static const struct regmap_config rtmv20_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .cache_type = REGCACHE_RBTREE, + .max_register = RTMV20_REG_LDMASK, + + .writeable_reg = rtmv20_is_accessible_reg, + .readable_reg = rtmv20_is_accessible_reg, + .volatile_reg = rtmv20_is_volatile_reg, +}; + +static int rtmv20_probe(struct i2c_client *i2c) +{ + struct rtmv20_priv *priv; + struct regulator_config config = {}; + int ret; + + priv = devm_kzalloc(&i2c->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->dev = &i2c->dev; + + /* Before regmap register, configure HW enable to make I2C accessible */ + priv->enable_gpio = devm_gpiod_get(&i2c->dev, "enable", GPIOD_OUT_HIGH); + if (IS_ERR(priv->enable_gpio)) { + dev_err(&i2c->dev, "Failed to get enable gpio\n"); + return PTR_ERR(priv->enable_gpio); + } + + /* Wait for I2C can be accessed */ + usleep_range(RTMV20_I2CRDY_TIMEUS, RTMV20_I2CRDY_TIMEUS + 100); + + priv->regmap = devm_regmap_init_i2c(i2c, &rtmv20_regmap_config); + if (IS_ERR(priv->regmap)) { + dev_err(&i2c->dev, "Failed to allocate register map\n"); + return PTR_ERR(priv->regmap); + } + + ret = rtmv20_check_chip_exist(priv); + if (ret) { + dev_err(&i2c->dev, "Chip vendor info is not matched\n"); + return ret; + } + + ret = rtmv20_properties_init(priv); + if (ret) { + dev_err(&i2c->dev, "Failed to init properties\n"); + return ret; + } + + /* + * keep in shutdown mode to minimize the current consumption + * and also mark regcache as dirty + */ + regcache_mark_dirty(priv->regmap); + gpiod_set_value(priv->enable_gpio, 0); + + config.dev = &i2c->dev; + config.regmap = priv->regmap; + config.driver_data = priv; + priv->rdev = devm_regulator_register(&i2c->dev, &rtmv20_lsw_desc, &config); + if (IS_ERR(priv->rdev)) { + dev_err(&i2c->dev, "Failed to register regulator\n"); + return PTR_ERR(priv->rdev); + } + + /* Unmask all events before IRQ registered */ + ret = regmap_write(priv->regmap, RTMV20_REG_LDMASK, 0); + if (ret) + return ret; + + return devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL, rtmv20_irq_handler, + IRQF_ONESHOT, dev_name(&i2c->dev), priv); +} + +static int __maybe_unused rtmv20_suspend(struct device *dev) +{ + struct i2c_client *i2c = to_i2c_client(dev); + + /* + * When system suspend, disable irq to prevent interrupt trigger + * during I2C bus suspend + */ + disable_irq(i2c->irq); + if (device_may_wakeup(dev)) + enable_irq_wake(i2c->irq); + + return 0; +} + +static int __maybe_unused rtmv20_resume(struct device *dev) +{ + struct i2c_client *i2c = to_i2c_client(dev); + + /* Enable irq after I2C bus already resume */ + enable_irq(i2c->irq); + if (device_may_wakeup(dev)) + disable_irq_wake(i2c->irq); + + return 0; +} + +static SIMPLE_DEV_PM_OPS(rtmv20_pm, rtmv20_suspend, rtmv20_resume); + +static const struct of_device_id __maybe_unused rtmv20_of_id[] = { + { .compatible = "richtek,rtmv20", }, + {} +}; +MODULE_DEVICE_TABLE(of, rtmv20_of_id); + +static struct i2c_driver rtmv20_driver = { + .driver = { + .name = "rtmv20", + .of_match_table = of_match_ptr(rtmv20_of_id), + .pm = &rtmv20_pm, + }, + .probe_new = rtmv20_probe, +}; +module_i2c_driver(rtmv20_driver); + +MODULE_AUTHOR("ChiYuan Huang "); +MODULE_DESCRIPTION("Richtek RTMV20 Regulator Driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 89a5f77e3f3a7fb8d6cf25668489d66069ebe4b7 Mon Sep 17 00:00:00 2001 From: ChiYuan Huang Date: Wed, 30 Sep 2020 18:08:00 +0800 Subject: regulator: rtmv20: Update DT binding document and property name parsing 1. Add vendor suffix to all proprietary properties. 2. Fix typo. 3. Change lsw to normal property, not pattern property. 4. Due to item 1, modify source code for property parsing. Signed-off-by: ChiYuan Huang Link: https://lore.kernel.org/r/1601460480-4259-1-git-send-email-u0084500@gmail.com Signed-off-by: Mark Brown --- .../regulator/richtek,rtmv20-regulator.yaml | 53 +++++++++------------- drivers/regulator/rtmv20-regulator.c | 36 ++++++++------- 2 files changed, 42 insertions(+), 47 deletions(-) (limited to 'drivers/regulator') diff --git a/Documentation/devicetree/bindings/regulator/richtek,rtmv20-regulator.yaml b/Documentation/devicetree/bindings/regulator/richtek,rtmv20-regulator.yaml index 4cb4b688612d..a8ccb5cb8d77 100644 --- a/Documentation/devicetree/bindings/regulator/richtek,rtmv20-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/richtek,rtmv20-regulator.yaml @@ -26,108 +26,99 @@ properties: wakeup-source: true - interrupts-extend: + interrupts: maxItems: 1 enable-gpios: description: A connection of the 'enable' gpio line. maxItems: 1 - ld-pulse-delay-us: + richtek,ld-pulse-delay-us: description: | load current pulse delay in microsecond after strobe pin pulse high. - $ref: "/schemas/types.yaml#/definitions/uint32" minimum: 0 maximum: 100000 default: 0 - ld-pulse-width-us: + richtek,ld-pulse-width-us: description: | Load current pulse width in microsecond after strobe pin pulse high. - $ref: "/schemas/types.yaml#/definitions/uint32" minimum: 0 maximum: 10000 default: 1200 - fsin1-delay-us: + richtek,fsin1-delay-us: description: | Fsin1 pulse high delay in microsecond after vsync signal pulse high. - $ref: "/schemas/types.yaml#/definitions/uint32" minimum: 0 maximum: 100000 default: 23000 - fsin1-width-us: + richtek,fsin1-width-us: description: | Fsin1 pulse high width in microsecond after vsync signal pulse high. - $ref: "/schemas/types.yaml#/definitions/uint32" minimum: 40 maximum: 10000 default: 160 - fsin2-delay-us: + richtek,fsin2-delay-us: description: | Fsin2 pulse high delay in microsecond after vsync signal pulse high. - $ref: "/schemas/types.yaml#/definitions/uint32" minimum: 0 maximum: 100000 default: 23000 - fsin2-width-us: + richtek,fsin2-width-us: description: | Fsin2 pulse high width in microsecond after vsync signal pulse high. - $ref: "/schemas/types.yaml#/definitions/uint32" minimum: 40 maximum: 10000 default: 160 - es-pulse-width-us: + richtek,es-pulse-width-us: description: Eye safety function pulse width limit in microsecond. - $ref: "/schemas/types.yaml#/definitions/uint32" minimum: 0 maximum: 10000 default: 1200 - es-ld-current-microamp: + richtek,es-ld-current-microamp: description: Eye safety function load current limit in microamp. - $ref: "/schemas/types.yaml#/definitions/uint32" minimum: 0 maximum: 6000000 default: 3000000 - lbp-level-microvolt: + richtek,lbp-level-microvolt: description: Low battery protection level in microvolt. - $ref: "/schemas/types.yaml#/definitions/uint32" minimum: 2400000 maximum: 3700000 default: 2700000 - lbp-enable: + richtek,lbp-enable: description: Low battery protection function enable control. type: boolean - strobe-polarity-high: + richtek,strobe-polarity-high: description: Strobe pin active polarity control. type: boolean - vsync-polarity-high: + richtek,vsync-polarity-high: description: Vsync pin active polarity control. type: boolean - fsin-enable: + richtek,fsin-enable: description: Fsin function enable control. type: boolean - fsin-output: + richtek,fsin-output: description: Fsin function output control. type: boolean - es-enable: + richtek,es-enable: description: Eye safety function enable control. type: boolean -patternProperties: - "lsw": + lsw: + description: load switch current regulator description. type: object $ref: "regulator.yaml#" @@ -135,7 +126,7 @@ required: - compatible - reg - wakeup-source - - interrupts-extend + - interrupts - enable-gpios - lsw @@ -152,11 +143,11 @@ examples: compatible = "richtek,rtmv20"; reg = <0x34>; wakeup-source; - interrupts-extend = <&gpio26 2 IRQ_TYPE_LEVEL_LOW>; + interrupts-extended = <&gpio26 2 IRQ_TYPE_LEVEL_LOW>; enable-gpios = <&gpio26 3 0>; - strobe-polarity-high; - vsync-polarity-high; + richtek,strobe-polarity-high; + richtek,vsync-polarity-high; lsw { regulator-name = "rtmv20,lsw"; diff --git a/drivers/regulator/rtmv20-regulator.c b/drivers/regulator/rtmv20-regulator.c index 1075b102e58e..05fd8e7ccea5 100644 --- a/drivers/regulator/rtmv20-regulator.c +++ b/drivers/regulator/rtmv20-regulator.c @@ -166,28 +166,32 @@ static int rtmv20_properties_init(struct rtmv20_priv *priv) u32 addr; u32 mask; } props[] = { - { "ld-pulse-delay-us", 0, 0, 100000, 100, RTMV20_REG_PULSEDELAY, + { "richtek,ld-pulse-delay-us", 0, 0, 100000, 100, RTMV20_REG_PULSEDELAY, RTMV20_DELAY_MASK }, - { "ld-pulse-width-us", 1200, 0, 10000, 1, RTMV20_REG_PULSEWIDTH, + { "richtek,ld-pulse-width-us", 1200, 0, 10000, 1, RTMV20_REG_PULSEWIDTH, RTMV20_WIDTH_MASK }, - { "fsin1-delay-us", 23000, 0, 100000, 100, RTMV20_REG_FSIN1CTRL1, + { "richtek,fsin1-delay-us", 23000, 0, 100000, 100, RTMV20_REG_FSIN1CTRL1, RTMV20_DELAY_MASK }, - { "fsin1-width-us", 160, 40, 10000, 40, RTMV20_REG_FSIN1CTRL3, RTMV20_WIDTH2_MASK }, - { "fsin2-delay-us", 23000, 0, 100000, 100, RTMV20_REG_FSIN2CTRL1, + { "richtek,fsin1-width-us", 160, 40, 10000, 40, RTMV20_REG_FSIN1CTRL3, + RTMV20_WIDTH2_MASK }, + { "richtek,fsin2-delay-us", 23000, 0, 100000, 100, RTMV20_REG_FSIN2CTRL1, RTMV20_DELAY_MASK }, - { "fsin2-width-us", 160, 40, 10000, 40, RTMV20_REG_FSIN2CTRL3, RTMV20_WIDTH2_MASK }, - { "es-pulse-width-us", 1200, 0, 10000, 1, RTMV20_REG_ESPULSEWIDTH, + { "richtek,fsin2-width-us", 160, 40, 10000, 40, RTMV20_REG_FSIN2CTRL3, + RTMV20_WIDTH2_MASK }, + { "richtek,es-pulse-width-us", 1200, 0, 10000, 1, RTMV20_REG_ESPULSEWIDTH, RTMV20_WIDTH_MASK }, - { "es-ld-current-microamp", 3000000, 0, 6000000, 30000, RTMV20_REG_ESLDCTRL1, - RTMV20_LDCURR_MASK }, - { "lbp-level-microvolt", 2700000, 2400000, 3700000, 100000, RTMV20_REG_LBP, + { "richtek,es-ld-current-microamp", 3000000, 0, 6000000, 30000, + RTMV20_REG_ESLDCTRL1, RTMV20_LDCURR_MASK }, + { "richtek,lbp-level-microvolt", 2700000, 2400000, 3700000, 100000, RTMV20_REG_LBP, RTMV20_LBPLVL_MASK }, - { "lbp-enable", 0, 0, 1, 1, RTMV20_REG_LBP, RTMV20_LBPEN_MASK }, - { "strobe-polarity-high", 1, 0, 1, 1, RTMV20_REG_LDCTRL2, RTMV20_STROBEPOL_MASK }, - { "vsync-polarity-high", 1, 0, 1, 1, RTMV20_REG_LDCTRL2, RTMV20_VSYNPOL_MASK }, - { "fsin-enable", 0, 0, 1, 1, RTMV20_REG_ENCTRL, RTMV20_FSINEN_MASK }, - { "fsin-output", 0, 0, 1, 1, RTMV20_REG_ENCTRL, RTMV20_FSINOUT_MASK }, - { "es-enable", 0, 0, 1, 1, RTMV20_REG_ENCTRL, RTMV20_ESEN_MASK }, + { "richtek,lbp-enable", 0, 0, 1, 1, RTMV20_REG_LBP, RTMV20_LBPEN_MASK }, + { "richtek,strobe-polarity-high", 1, 0, 1, 1, RTMV20_REG_LDCTRL2, + RTMV20_STROBEPOL_MASK }, + { "richtek,vsync-polarity-high", 1, 0, 1, 1, RTMV20_REG_LDCTRL2, + RTMV20_VSYNPOL_MASK }, + { "richtek,fsin-enable", 0, 0, 1, 1, RTMV20_REG_ENCTRL, RTMV20_FSINEN_MASK }, + { "richtek,fsin-output", 0, 0, 1, 1, RTMV20_REG_ENCTRL, RTMV20_FSINOUT_MASK }, + { "richtek,es-enable", 0, 0, 1, 1, RTMV20_REG_ENCTRL, RTMV20_ESEN_MASK }, }; int i, ret; -- cgit v1.2.3 From 6228cc8aed9e51afa56727b11001b37913e4dda6 Mon Sep 17 00:00:00 2001 From: ChiYuan Huang Date: Wed, 30 Sep 2020 18:18:52 +0800 Subject: regulator: rtmv20: Add missing regcache cache only before marked as dirty Add missing regcache cache only before masked as dirty. Signed-off-by: ChiYuan Huang Link: https://lore.kernel.org/r/1601461132-15251-1-git-send-email-u0084500@gmail.com Signed-off-by: Mark Brown --- drivers/regulator/rtmv20-regulator.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/regulator') diff --git a/drivers/regulator/rtmv20-regulator.c b/drivers/regulator/rtmv20-regulator.c index 05fd8e7ccea5..852fb2596ffd 100644 --- a/drivers/regulator/rtmv20-regulator.c +++ b/drivers/regulator/rtmv20-regulator.c @@ -325,6 +325,7 @@ static int rtmv20_probe(struct i2c_client *i2c) * keep in shutdown mode to minimize the current consumption * and also mark regcache as dirty */ + regcache_cache_only(priv->regmap, true); regcache_mark_dirty(priv->regmap); gpiod_set_value(priv->enable_gpio, 0); -- cgit v1.2.3 From bd8e2cad4e2857a8f3d1098236847e5b4becb3b9 Mon Sep 17 00:00:00 2001 From: Michał Mirosław Date: Sun, 27 Sep 2020 01:59:15 +0200 Subject: regulator: tps65910: use regmap accessors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use regmap accessors directly for register manipulation - removing one layer of abstraction. Signed-off-by: Michał Mirosław Link: https://lore.kernel.org/r/e82886d0f8f5131c9fccf2a17e3a15acce507d6f.1601164493.git.mirq-linux@rere.qmqm.pl Signed-off-by: Mark Brown --- drivers/regulator/tps65910-regulator.c | 125 +++++++++++++++++---------------- 1 file changed, 63 insertions(+), 62 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index faa5b3538167..1d5b0a1b86f7 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -390,8 +390,8 @@ static int tps65911_get_ctrl_register(int id) static int tps65910_set_mode(struct regulator_dev *dev, unsigned int mode) { struct tps65910_reg *pmic = rdev_get_drvdata(dev); - struct tps65910 *mfd = pmic->mfd; - int reg, value, id = rdev_get_id(dev); + struct regmap *regmap = rdev_get_regmap(dev); + int reg, id = rdev_get_id(dev); reg = pmic->get_ctrl_reg(id); if (reg < 0) @@ -399,14 +399,14 @@ static int tps65910_set_mode(struct regulator_dev *dev, unsigned int mode) switch (mode) { case REGULATOR_MODE_NORMAL: - return tps65910_reg_update_bits(pmic->mfd, reg, - LDO_ST_MODE_BIT | LDO_ST_ON_BIT, - LDO_ST_ON_BIT); + return regmap_update_bits(regmap, reg, + LDO_ST_MODE_BIT | LDO_ST_ON_BIT, + LDO_ST_ON_BIT); case REGULATOR_MODE_IDLE: - value = LDO_ST_ON_BIT | LDO_ST_MODE_BIT; - return tps65910_reg_set_bits(mfd, reg, value); + return regmap_set_bits(regmap, reg, + LDO_ST_ON_BIT | LDO_ST_MODE_BIT); case REGULATOR_MODE_STANDBY: - return tps65910_reg_clear_bits(mfd, reg, LDO_ST_ON_BIT); + return regmap_clear_bits(regmap, reg, LDO_ST_ON_BIT); } return -EINVAL; @@ -415,13 +415,14 @@ static int tps65910_set_mode(struct regulator_dev *dev, unsigned int mode) static unsigned int tps65910_get_mode(struct regulator_dev *dev) { struct tps65910_reg *pmic = rdev_get_drvdata(dev); + struct regmap *regmap = rdev_get_regmap(dev); int ret, reg, value, id = rdev_get_id(dev); reg = pmic->get_ctrl_reg(id); if (reg < 0) return reg; - ret = tps65910_reg_read(pmic->mfd, reg, &value); + ret = regmap_read(regmap, reg, &value); if (ret < 0) return ret; @@ -435,20 +436,20 @@ static unsigned int tps65910_get_mode(struct regulator_dev *dev) static int tps65910_get_voltage_dcdc_sel(struct regulator_dev *dev) { - struct tps65910_reg *pmic = rdev_get_drvdata(dev); + struct regmap *regmap = rdev_get_regmap(dev); int ret, id = rdev_get_id(dev); int opvsel = 0, srvsel = 0, vselmax = 0, mult = 0, sr = 0; switch (id) { case TPS65910_REG_VDD1: - ret = tps65910_reg_read(pmic->mfd, TPS65910_VDD1_OP, &opvsel); + ret = regmap_read(regmap, TPS65910_VDD1_OP, &opvsel); if (ret < 0) return ret; - ret = tps65910_reg_read(pmic->mfd, TPS65910_VDD1, &mult); + ret = regmap_read(regmap, TPS65910_VDD1, &mult); if (ret < 0) return ret; mult = (mult & VDD1_VGAIN_SEL_MASK) >> VDD1_VGAIN_SEL_SHIFT; - ret = tps65910_reg_read(pmic->mfd, TPS65910_VDD1_SR, &srvsel); + ret = regmap_read(regmap, TPS65910_VDD1_SR, &srvsel); if (ret < 0) return ret; sr = opvsel & VDD1_OP_CMD_MASK; @@ -457,14 +458,14 @@ static int tps65910_get_voltage_dcdc_sel(struct regulator_dev *dev) vselmax = 75; break; case TPS65910_REG_VDD2: - ret = tps65910_reg_read(pmic->mfd, TPS65910_VDD2_OP, &opvsel); + ret = regmap_read(regmap, TPS65910_VDD2_OP, &opvsel); if (ret < 0) return ret; - ret = tps65910_reg_read(pmic->mfd, TPS65910_VDD2, &mult); + ret = regmap_read(regmap, TPS65910_VDD2, &mult); if (ret < 0) return ret; mult = (mult & VDD2_VGAIN_SEL_MASK) >> VDD2_VGAIN_SEL_SHIFT; - ret = tps65910_reg_read(pmic->mfd, TPS65910_VDD2_SR, &srvsel); + ret = regmap_read(regmap, TPS65910_VDD2_SR, &srvsel); if (ret < 0) return ret; sr = opvsel & VDD2_OP_CMD_MASK; @@ -473,12 +474,10 @@ static int tps65910_get_voltage_dcdc_sel(struct regulator_dev *dev) vselmax = 75; break; case TPS65911_REG_VDDCTRL: - ret = tps65910_reg_read(pmic->mfd, TPS65911_VDDCTRL_OP, - &opvsel); + ret = regmap_read(regmap, TPS65911_VDDCTRL_OP, &opvsel); if (ret < 0) return ret; - ret = tps65910_reg_read(pmic->mfd, TPS65911_VDDCTRL_SR, - &srvsel); + ret = regmap_read(regmap, TPS65911_VDDCTRL_SR, &srvsel); if (ret < 0) return ret; sr = opvsel & VDDCTRL_OP_CMD_MASK; @@ -514,13 +513,14 @@ static int tps65910_get_voltage_dcdc_sel(struct regulator_dev *dev) static int tps65910_get_voltage_sel(struct regulator_dev *dev) { struct tps65910_reg *pmic = rdev_get_drvdata(dev); + struct regmap *regmap = rdev_get_regmap(dev); int ret, reg, value, id = rdev_get_id(dev); reg = pmic->get_ctrl_reg(id); if (reg < 0) return reg; - ret = tps65910_reg_read(pmic->mfd, reg, &value); + ret = regmap_read(regmap, reg, &value); if (ret < 0) return ret; @@ -556,12 +556,13 @@ static int tps65910_get_voltage_vdd3(struct regulator_dev *dev) static int tps65911_get_voltage_sel(struct regulator_dev *dev) { struct tps65910_reg *pmic = rdev_get_drvdata(dev); + struct regmap *regmap = rdev_get_regmap(dev); int ret, id = rdev_get_id(dev); unsigned int value, reg; reg = pmic->get_ctrl_reg(id); - ret = tps65910_reg_read(pmic->mfd, reg, &value); + ret = regmap_read(regmap, reg, &value); if (ret < 0) return ret; @@ -594,7 +595,7 @@ static int tps65911_get_voltage_sel(struct regulator_dev *dev) static int tps65910_set_voltage_dcdc_sel(struct regulator_dev *dev, unsigned selector) { - struct tps65910_reg *pmic = rdev_get_drvdata(dev); + struct regmap *regmap = rdev_get_regmap(dev); int id = rdev_get_id(dev), vsel; int dcdc_mult = 0; @@ -605,10 +606,9 @@ static int tps65910_set_voltage_dcdc_sel(struct regulator_dev *dev, dcdc_mult--; vsel = (selector % VDD1_2_NUM_VOLT_FINE) + 3; - tps65910_reg_update_bits(pmic->mfd, TPS65910_VDD1, - VDD1_VGAIN_SEL_MASK, - dcdc_mult << VDD1_VGAIN_SEL_SHIFT); - tps65910_reg_write(pmic->mfd, TPS65910_VDD1_OP, vsel); + regmap_update_bits(regmap, TPS65910_VDD1, VDD1_VGAIN_SEL_MASK, + dcdc_mult << VDD1_VGAIN_SEL_SHIFT); + regmap_write(regmap, TPS65910_VDD1_OP, vsel); break; case TPS65910_REG_VDD2: dcdc_mult = (selector / VDD1_2_NUM_VOLT_FINE) + 1; @@ -616,14 +616,14 @@ static int tps65910_set_voltage_dcdc_sel(struct regulator_dev *dev, dcdc_mult--; vsel = (selector % VDD1_2_NUM_VOLT_FINE) + 3; - tps65910_reg_update_bits(pmic->mfd, TPS65910_VDD2, - VDD1_VGAIN_SEL_MASK, - dcdc_mult << VDD2_VGAIN_SEL_SHIFT); - tps65910_reg_write(pmic->mfd, TPS65910_VDD2_OP, vsel); + regmap_update_bits(regmap, TPS65910_VDD2, VDD1_VGAIN_SEL_MASK, + dcdc_mult << VDD2_VGAIN_SEL_SHIFT); + regmap_write(regmap, TPS65910_VDD2_OP, vsel); break; case TPS65911_REG_VDDCTRL: vsel = selector + 3; - tps65910_reg_write(pmic->mfd, TPS65911_VDDCTRL_OP, vsel); + regmap_write(regmap, TPS65911_VDDCTRL_OP, vsel); + break; } return 0; @@ -633,6 +633,7 @@ static int tps65910_set_voltage_sel(struct regulator_dev *dev, unsigned selector) { struct tps65910_reg *pmic = rdev_get_drvdata(dev); + struct regmap *regmap = rdev_get_regmap(dev); int reg, id = rdev_get_id(dev); reg = pmic->get_ctrl_reg(id); @@ -649,11 +650,11 @@ static int tps65910_set_voltage_sel(struct regulator_dev *dev, case TPS65910_REG_VAUX2: case TPS65910_REG_VAUX33: case TPS65910_REG_VMMC: - return tps65910_reg_update_bits(pmic->mfd, reg, LDO_SEL_MASK, - selector << LDO_SEL_SHIFT); + return regmap_update_bits(regmap, reg, LDO_SEL_MASK, + selector << LDO_SEL_SHIFT); case TPS65910_REG_VBB: - return tps65910_reg_update_bits(pmic->mfd, reg, BBCH_BBSEL_MASK, - selector << BBCH_BBSEL_SHIFT); + return regmap_update_bits(regmap, reg, BBCH_BBSEL_MASK, + selector << BBCH_BBSEL_SHIFT); } return -EINVAL; @@ -663,6 +664,7 @@ static int tps65911_set_voltage_sel(struct regulator_dev *dev, unsigned selector) { struct tps65910_reg *pmic = rdev_get_drvdata(dev); + struct regmap *regmap = rdev_get_regmap(dev); int reg, id = rdev_get_id(dev); reg = pmic->get_ctrl_reg(id); @@ -673,21 +675,21 @@ static int tps65911_set_voltage_sel(struct regulator_dev *dev, case TPS65911_REG_LDO1: case TPS65911_REG_LDO2: case TPS65911_REG_LDO4: - return tps65910_reg_update_bits(pmic->mfd, reg, LDO1_SEL_MASK, - selector << LDO_SEL_SHIFT); + return regmap_update_bits(regmap, reg, LDO1_SEL_MASK, + selector << LDO_SEL_SHIFT); case TPS65911_REG_LDO3: case TPS65911_REG_LDO5: case TPS65911_REG_LDO6: case TPS65911_REG_LDO7: case TPS65911_REG_LDO8: - return tps65910_reg_update_bits(pmic->mfd, reg, LDO3_SEL_MASK, - selector << LDO_SEL_SHIFT); + return regmap_update_bits(regmap, reg, LDO3_SEL_MASK, + selector << LDO_SEL_SHIFT); case TPS65910_REG_VIO: - return tps65910_reg_update_bits(pmic->mfd, reg, LDO_SEL_MASK, - selector << LDO_SEL_SHIFT); + return regmap_update_bits(regmap, reg, LDO_SEL_MASK, + selector << LDO_SEL_SHIFT); case TPS65910_REG_VBB: - return tps65910_reg_update_bits(pmic->mfd, reg, BBCH_BBSEL_MASK, - selector << BBCH_BBSEL_SHIFT); + return regmap_update_bits(regmap, reg, BBCH_BBSEL_MASK, + selector << BBCH_BBSEL_SHIFT); } return -EINVAL; @@ -850,10 +852,10 @@ static int tps65910_set_ext_sleep_config(struct tps65910_reg *pmic, /* External EN1 control */ if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1) - ret = tps65910_reg_set_bits(mfd, + ret = regmap_set_bits(mfd->regmap, TPS65910_EN1_LDO_ASS + regoffs, bit_pos); else - ret = tps65910_reg_clear_bits(mfd, + ret = regmap_clear_bits(mfd->regmap, TPS65910_EN1_LDO_ASS + regoffs, bit_pos); if (ret < 0) { dev_err(mfd->dev, @@ -863,10 +865,10 @@ static int tps65910_set_ext_sleep_config(struct tps65910_reg *pmic, /* External EN2 control */ if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2) - ret = tps65910_reg_set_bits(mfd, + ret = regmap_set_bits(mfd->regmap, TPS65910_EN2_LDO_ASS + regoffs, bit_pos); else - ret = tps65910_reg_clear_bits(mfd, + ret = regmap_clear_bits(mfd->regmap, TPS65910_EN2_LDO_ASS + regoffs, bit_pos); if (ret < 0) { dev_err(mfd->dev, @@ -878,10 +880,10 @@ static int tps65910_set_ext_sleep_config(struct tps65910_reg *pmic, if ((tps65910_chip_id(mfd) == TPS65910) && (id >= TPS65910_REG_VDIG1)) { if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3) - ret = tps65910_reg_set_bits(mfd, + ret = regmap_set_bits(mfd->regmap, TPS65910_EN3_LDO_ASS + regoffs, bit_pos); else - ret = tps65910_reg_clear_bits(mfd, + ret = regmap_clear_bits(mfd->regmap, TPS65910_EN3_LDO_ASS + regoffs, bit_pos); if (ret < 0) { dev_err(mfd->dev, @@ -893,10 +895,10 @@ static int tps65910_set_ext_sleep_config(struct tps65910_reg *pmic, /* Return if no external control is selected */ if (!(ext_sleep_config & EXT_SLEEP_CONTROL)) { /* Clear all sleep controls */ - ret = tps65910_reg_clear_bits(mfd, + ret = regmap_clear_bits(mfd->regmap, TPS65910_SLEEP_KEEP_LDO_ON + regoffs, bit_pos); if (!ret) - ret = tps65910_reg_clear_bits(mfd, + ret = regmap_clear_bits(mfd->regmap, TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos); if (ret < 0) dev_err(mfd->dev, @@ -917,39 +919,38 @@ static int tps65910_set_ext_sleep_config(struct tps65910_reg *pmic, int sr_reg_add = pmic->get_ctrl_reg(id) + 2; int opvsel, srvsel; - ret = tps65910_reg_read(pmic->mfd, op_reg_add, &opvsel); + ret = regmap_read(mfd->regmap, op_reg_add, &opvsel); if (ret < 0) return ret; - ret = tps65910_reg_read(pmic->mfd, sr_reg_add, &srvsel); + ret = regmap_read(mfd->regmap, sr_reg_add, &srvsel); if (ret < 0) return ret; if (opvsel & VDD1_OP_CMD_MASK) { u8 reg_val = srvsel & VDD1_OP_SEL_MASK; - ret = tps65910_reg_write(pmic->mfd, op_reg_add, - reg_val); + ret = regmap_write(mfd->regmap, op_reg_add, reg_val); if (ret < 0) { dev_err(mfd->dev, "Error in configuring op register\n"); return ret; } } - ret = tps65910_reg_write(pmic->mfd, sr_reg_add, 0); + ret = regmap_write(mfd->regmap, sr_reg_add, 0); if (ret < 0) { dev_err(mfd->dev, "Error in setting sr register\n"); return ret; } } - ret = tps65910_reg_clear_bits(mfd, + ret = regmap_clear_bits(mfd->regmap, TPS65910_SLEEP_KEEP_LDO_ON + regoffs, bit_pos); if (!ret) { if (ext_sleep_config & TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP) - ret = tps65910_reg_set_bits(mfd, + ret = regmap_set_bits(mfd->regmap, TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos); else - ret = tps65910_reg_clear_bits(mfd, + ret = regmap_clear_bits(mfd->regmap, TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos); } if (ret < 0) @@ -1097,7 +1098,7 @@ static int tps65910_probe(struct platform_device *pdev) platform_set_drvdata(pdev, pmic); /* Give control of all register to control port */ - err = tps65910_reg_set_bits(pmic->mfd, TPS65910_DEVCTRL, + err = regmap_set_bits(pmic->mfd->regmap, TPS65910_DEVCTRL, DEVCTRL_SR_CTL_I2C_SEL_MASK); if (err < 0) return err; @@ -1113,7 +1114,7 @@ static int tps65910_probe(struct platform_device *pdev) * voltage level can go higher than expected or crash * Workaround: use no synchronization of DCDC clocks */ - tps65910_reg_clear_bits(pmic->mfd, TPS65910_DCDCCTRL, + regmap_clear_bits(pmic->mfd->regmap, TPS65910_DCDCCTRL, DCDCCTRL_DCDCCKSYNC_MASK); break; case TPS65911: -- cgit v1.2.3 From e9bb4a068b206f61ef01057cfeafdb852fb244c5 Mon Sep 17 00:00:00 2001 From: AngeloGioacchino Del Regno Date: Sat, 26 Sep 2020 14:55:43 +0200 Subject: regulator: core: Enlarge max OF property name length to 64 chars Some regulator drivers may be defining very long names: this is the case with the qcom_smd and qcom_spmi regulators, where we need to parse the regulator parents from DT. For clarity, this is an example: { "l13a", QCOM_SMD_RPM_LDOA, 13, &pm660_ht_lvpldo, "vdd_l8_l9_l10_l11_l12_l13_l14" }, pm660-regulators { ... vdd_l8_l9_l10_l11_l12_l13_l14-supply = <&vreg_s4a_2p04> ... }; Now, with a 32 characters limit, the function is trying to parse, exactly, "vdd_l8_l9_l10_l11_l12_l13_l14-s" (32 chars) instead of the right one, which is 37 chars long in this specific case. ... And this is not only the case with PM660/PM660L, but also with PMA8084, PM8916, PM8950 and others that are not implemented yet. The length of 64 chars was chosen based on the longest parsed property name that I could find, which is in PM8916, and would be 53 characters long. At that point, rounding that to 64 looked like being the best idea. Signed-off-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20200926125549.13191-2-kholk11@gmail.com Signed-off-by: Mark Brown --- drivers/regulator/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 9f704a6c4802..16497192e99b 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -404,11 +404,11 @@ err_node_put: static struct device_node *of_get_regulator(struct device *dev, const char *supply) { struct device_node *regnode = NULL; - char prop_name[32]; /* 32 is max size of property name */ + char prop_name[64]; /* 64 is max size of property name */ dev_dbg(dev, "Looking up %s-supply from device tree\n", supply); - snprintf(prop_name, 32, "%s-supply", supply); + snprintf(prop_name, 64, "%s-supply", supply); regnode = of_parse_phandle(dev->of_node, prop_name, 0); if (!regnode) { -- cgit v1.2.3 From 328816c2033160a6929fb0c6f0018b7c8d75cefe Mon Sep 17 00:00:00 2001 From: AngeloGioacchino Del Regno Date: Sat, 26 Sep 2020 14:55:44 +0200 Subject: regulator: qcom_spmi: Add support for new regulator types This commit adds the support for some regulator types that are missing in this driver, such as the ht nmos-ldo, ht-lv nmos-ldo and new gen n/pmos-ldo, all belonging to the FTSMPS426 register layout. This is done in preparation for adding support for the PM660 and PM660L PMICs. Signed-off-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20200926125549.13191-3-kholk11@gmail.com Signed-off-by: Mark Brown --- drivers/regulator/qcom_spmi-regulator.c | 56 +++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'drivers/regulator') diff --git a/drivers/regulator/qcom_spmi-regulator.c b/drivers/regulator/qcom_spmi-regulator.c index 05080483fe1b..0a507c7f4ae1 100644 --- a/drivers/regulator/qcom_spmi-regulator.c +++ b/drivers/regulator/qcom_spmi-regulator.c @@ -135,6 +135,18 @@ enum spmi_regulator_subtype { SPMI_REGULATOR_SUBTYPE_LV_P600 = 0x2b, SPMI_REGULATOR_SUBTYPE_LV_P1200 = 0x2c, SPMI_REGULATOR_SUBTYPE_LV_P450 = 0x2d, + SPMI_REGULATOR_SUBTYPE_HT_N300_ST = 0x30, + SPMI_REGULATOR_SUBTYPE_HT_N600_ST = 0x31, + SPMI_REGULATOR_SUBTYPE_HT_N1200_ST = 0x32, + SPMI_REGULATOR_SUBTYPE_HT_LVP150 = 0x3b, + SPMI_REGULATOR_SUBTYPE_HT_LVP300 = 0x3c, + SPMI_REGULATOR_SUBTYPE_L660_N300_ST = 0x42, + SPMI_REGULATOR_SUBTYPE_L660_N600_ST = 0x43, + SPMI_REGULATOR_SUBTYPE_L660_P50 = 0x46, + SPMI_REGULATOR_SUBTYPE_L660_P150 = 0x47, + SPMI_REGULATOR_SUBTYPE_L660_P600 = 0x49, + SPMI_REGULATOR_SUBTYPE_L660_LVP150 = 0x4d, + SPMI_REGULATOR_SUBTYPE_L660_LVP600 = 0x4f, SPMI_REGULATOR_SUBTYPE_LV100 = 0x01, SPMI_REGULATOR_SUBTYPE_LV300 = 0x02, SPMI_REGULATOR_SUBTYPE_MV300 = 0x08, @@ -511,6 +523,22 @@ static struct spmi_voltage_range ult_pldo_ranges[] = { SPMI_VOLTAGE_RANGE(0, 1750000, 1750000, 3337500, 3337500, 12500), }; +static struct spmi_voltage_range pldo660_ranges[] = { + SPMI_VOLTAGE_RANGE(0, 1504000, 1504000, 3544000, 3544000, 8000), +}; + +static struct spmi_voltage_range nldo660_ranges[] = { + SPMI_VOLTAGE_RANGE(0, 320000, 320000, 1304000, 1304000, 8000), +}; + +static struct spmi_voltage_range ht_lvpldo_ranges[] = { + SPMI_VOLTAGE_RANGE(0, 1504000, 1504000, 2000000, 2000000, 8000), +}; + +static struct spmi_voltage_range ht_nldo_ranges[] = { + SPMI_VOLTAGE_RANGE(0, 312000, 312000, 1304000, 1304000, 8000), +}; + static struct spmi_voltage_range hfs430_ranges[] = { SPMI_VOLTAGE_RANGE(0, 320000, 320000, 2040000, 2040000, 8000), }; @@ -530,6 +558,10 @@ static DEFINE_SPMI_SET_POINTS(ult_lo_smps); static DEFINE_SPMI_SET_POINTS(ult_ho_smps); static DEFINE_SPMI_SET_POINTS(ult_nldo); static DEFINE_SPMI_SET_POINTS(ult_pldo); +static DEFINE_SPMI_SET_POINTS(pldo660); +static DEFINE_SPMI_SET_POINTS(nldo660); +static DEFINE_SPMI_SET_POINTS(ht_lvpldo); +static DEFINE_SPMI_SET_POINTS(ht_nldo); static DEFINE_SPMI_SET_POINTS(hfs430); static inline int spmi_vreg_read(struct spmi_regulator *vreg, u16 addr, u8 *buf, @@ -1443,6 +1475,30 @@ static const struct spmi_regulator_mapping supported_regulators[] = { SPMI_VREG(LDO, LV_P300, 0, INF, LDO, ldo, pldo, 10000), SPMI_VREG(LDO, LV_P600, 0, INF, LDO, ldo, pldo, 10000), SPMI_VREG(LDO, LV_P1200, 0, INF, LDO, ldo, pldo, 10000), + SPMI_VREG(LDO, HT_N300_ST, 0, INF, FTSMPS426, ftsmps426, + ht_nldo, 30000), + SPMI_VREG(LDO, HT_N600_ST, 0, INF, FTSMPS426, ftsmps426, + ht_nldo, 30000), + SPMI_VREG(LDO, HT_N1200_ST, 0, INF, FTSMPS426, ftsmps426, + ht_nldo, 30000), + SPMI_VREG(LDO, HT_LVP150, 0, INF, FTSMPS426, ftsmps426, + ht_lvpldo, 10000), + SPMI_VREG(LDO, HT_LVP300, 0, INF, FTSMPS426, ftsmps426, + ht_lvpldo, 10000), + SPMI_VREG(LDO, L660_N300_ST, 0, INF, FTSMPS426, ftsmps426, + nldo660, 10000), + SPMI_VREG(LDO, L660_N600_ST, 0, INF, FTSMPS426, ftsmps426, + nldo660, 10000), + SPMI_VREG(LDO, L660_P50, 0, INF, FTSMPS426, ftsmps426, + pldo660, 10000), + SPMI_VREG(LDO, L660_P150, 0, INF, FTSMPS426, ftsmps426, + pldo660, 10000), + SPMI_VREG(LDO, L660_P600, 0, INF, FTSMPS426, ftsmps426, + pldo660, 10000), + SPMI_VREG(LDO, L660_LVP150, 0, INF, FTSMPS426, ftsmps426, + ht_lvpldo, 10000), + SPMI_VREG(LDO, L660_LVP600, 0, INF, FTSMPS426, ftsmps426, + ht_lvpldo, 10000), SPMI_VREG_VS(LV100, 0, INF), SPMI_VREG_VS(LV300, 0, INF), SPMI_VREG_VS(MV300, 0, INF), -- cgit v1.2.3 From 0074c4472dcb20e989d9870c0b3aba42d0aa44b8 Mon Sep 17 00:00:00 2001 From: AngeloGioacchino Del Regno Date: Sat, 26 Sep 2020 14:55:45 +0200 Subject: regulator: qcom_spmi: Add PM660/PM660L regulators The PM660 PMIC is very often paired with the PM660L option on SDM630/663/660 (and SDA variants) boards. The PM660 has 11 "660" LDOs (2 NMOS, 9 PMOS) and 7 HT LDOs (4 NMOS, 3 PMOS) and a quirk: the L4 regulator is unaccessible or does not exist on the PMIC. The PM660L has 8 "660" LDOs (1 NMOS, 7 PMOS) and 2 HT NMOS LDOs. Signed-off-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20200926125549.13191-4-kholk11@gmail.com Signed-off-by: Mark Brown --- drivers/regulator/qcom_spmi-regulator.c | 51 +++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'drivers/regulator') diff --git a/drivers/regulator/qcom_spmi-regulator.c b/drivers/regulator/qcom_spmi-regulator.c index 0a507c7f4ae1..e62e1d72d943 100644 --- a/drivers/regulator/qcom_spmi-regulator.c +++ b/drivers/regulator/qcom_spmi-regulator.c @@ -2014,6 +2014,55 @@ static const struct spmi_regulator_data pmi8994_regulators[] = { { } }; +static const struct spmi_regulator_data pm660_regulators[] = { + { "s1", 0x1400, "vdd_s1", }, + { "s2", 0x1700, "vdd_s2", }, + { "s3", 0x1a00, "vdd_s3", }, + { "s4", 0x1d00, "vdd_s3", }, + { "s5", 0x2000, "vdd_s5", }, + { "s6", 0x2300, "vdd_s6", }, + { "l1", 0x4000, "vdd_l1_l6_l7", }, + { "l2", 0x4100, "vdd_l2_l3", }, + { "l3", 0x4200, "vdd_l2_l3", }, + /* l4 is unaccessible on PM660 */ + { "l5", 0x4400, "vdd_l5", }, + { "l6", 0x4500, "vdd_l1_l6_l7", }, + { "l7", 0x4600, "vdd_l1_l6_l7", }, + { "l8", 0x4700, "vdd_l8_l9_l10_l11_l12_l13_l14", }, + { "l9", 0x4800, "vdd_l8_l9_l10_l11_l12_l13_l14", }, + { "l10", 0x4900, "vdd_l8_l9_l10_l11_l12_l13_l14", }, + { "l11", 0x4a00, "vdd_l8_l9_l10_l11_l12_l13_l14", }, + { "l12", 0x4b00, "vdd_l8_l9_l10_l11_l12_l13_l14", }, + { "l13", 0x4c00, "vdd_l8_l9_l10_l11_l12_l13_l14", }, + { "l14", 0x4d00, "vdd_l8_l9_l10_l11_l12_l13_l14", }, + { "l15", 0x4e00, "vdd_l15_l16_l17_l18_l19", }, + { "l16", 0x4f00, "vdd_l15_l16_l17_l18_l19", }, + { "l17", 0x5000, "vdd_l15_l16_l17_l18_l19", }, + { "l18", 0x5100, "vdd_l15_l16_l17_l18_l19", }, + { "l19", 0x5200, "vdd_l15_l16_l17_l18_l19", }, + { } +}; + +static const struct spmi_regulator_data pm660l_regulators[] = { + { "s1", 0x1400, "vdd_s1", }, + { "s2", 0x1700, "vdd_s2", }, + { "s3", 0x1a00, "vdd_s3", }, + { "s4", 0x1d00, "vdd_s4", }, + { "s5", 0x2000, "vdd_s5", }, + { "l1", 0x4000, "vdd_l1_l9_l10", }, + { "l2", 0x4100, "vdd_l2", }, + { "l3", 0x4200, "vdd_l3_l5_l7_l8", }, + { "l4", 0x4300, "vdd_l4_l6", }, + { "l5", 0x4400, "vdd_l3_l5_l7_l8", }, + { "l6", 0x4500, "vdd_l4_l6", }, + { "l7", 0x4600, "vdd_l3_l5_l7_l8", }, + { "l8", 0x4700, "vdd_l3_l5_l7_l8", }, + { "l9", 0x4800, "vdd_l1_l9_l10", }, + { "l10", 0x4900, "vdd_l1_l9_l10", }, + { } +}; + + static const struct spmi_regulator_data pm8004_regulators[] = { { "s2", 0x1700, "vdd_s2", }, { "s5", 0x2000, "vdd_s5", }, @@ -2042,6 +2091,8 @@ static const struct of_device_id qcom_spmi_regulator_match[] = { { .compatible = "qcom,pm8950-regulators", .data = &pm8950_regulators }, { .compatible = "qcom,pm8994-regulators", .data = &pm8994_regulators }, { .compatible = "qcom,pmi8994-regulators", .data = &pmi8994_regulators }, + { .compatible = "qcom,pm660-regulators", .data = &pm660_regulators }, + { .compatible = "qcom,pm660l-regulators", .data = &pm660l_regulators }, { .compatible = "qcom,pms405-regulators", .data = &pms405_regulators }, { } }; -- cgit v1.2.3 From 6d849653b00f2336efcd371fe85a7eb31bb094e9 Mon Sep 17 00:00:00 2001 From: AngeloGioacchino Del Regno Date: Sat, 26 Sep 2020 14:55:47 +0200 Subject: regulator: qcom_smd: Add PM660/PM660L regulator support The PM660 and PM660L are a very very common PMIC combo, found on boards using the SDM630, SDM636, SDM660 (and SDA variants) SoC. PM660 provides 6 SMPS and 19 LDOs (of which one is unaccesible), while PM660L provides 5 SMPS (of which S3 and S4 are combined), 10 LDOs and a Buck-or-Boost (BoB) regulator. The PM660L IC also provides other regulators that are very specialized (for example, for the display) and will be managed in the other appropriate drivers (for example, labibb). Signed-off-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20200926125549.13191-6-kholk11@gmail.com Signed-off-by: Mark Brown --- drivers/regulator/qcom_smd-regulator.c | 113 +++++++++++++++++++++++++++++++++ include/linux/soc/qcom/smd-rpm.h | 4 ++ 2 files changed, 117 insertions(+) (limited to 'drivers/regulator') diff --git a/drivers/regulator/qcom_smd-regulator.c b/drivers/regulator/qcom_smd-regulator.c index a87b56bc29fa..faa99690b7b3 100644 --- a/drivers/regulator/qcom_smd-regulator.c +++ b/drivers/regulator/qcom_smd-regulator.c @@ -541,6 +541,69 @@ static const struct regulator_desc pmi8998_bob = { .ops = &rpm_bob_ops, }; +static const struct regulator_desc pm660_ftsmps = { + .linear_ranges = (struct linear_range[]) { + REGULATOR_LINEAR_RANGE(355000, 0, 199, 5000), + }, + .n_linear_ranges = 1, + .n_voltages = 200, + .ops = &rpm_smps_ldo_ops, +}; + +static const struct regulator_desc pm660_hfsmps = { + .linear_ranges = (struct linear_range[]) { + REGULATOR_LINEAR_RANGE(320000, 0, 216, 8000), + }, + .n_linear_ranges = 1, + .n_voltages = 217, + .ops = &rpm_smps_ldo_ops, +}; + +static const struct regulator_desc pm660_ht_nldo = { + .linear_ranges = (struct linear_range[]) { + REGULATOR_LINEAR_RANGE(312000, 0, 124, 8000), + }, + .n_linear_ranges = 1, + .n_voltages = 125, + .ops = &rpm_smps_ldo_ops, +}; + +static const struct regulator_desc pm660_ht_lvpldo = { + .linear_ranges = (struct linear_range[]) { + REGULATOR_LINEAR_RANGE(1504000, 0, 62, 8000), + }, + .n_linear_ranges = 1, + .n_voltages = 63, + .ops = &rpm_smps_ldo_ops, +}; + +static const struct regulator_desc pm660_nldo660 = { + .linear_ranges = (struct linear_range[]) { + REGULATOR_LINEAR_RANGE(320000, 0, 123, 8000), + }, + .n_linear_ranges = 1, + .n_voltages = 124, + .ops = &rpm_smps_ldo_ops, +}; + +static const struct regulator_desc pm660_pldo660 = { + .linear_ranges = (struct linear_range[]) { + REGULATOR_LINEAR_RANGE(1504000, 0, 255, 8000), + }, + .n_linear_ranges = 1, + .n_voltages = 256, + .ops = &rpm_smps_ldo_ops, +}; + +static const struct regulator_desc pm660l_bob = { + .linear_ranges = (struct linear_range[]) { + REGULATOR_LINEAR_RANGE(1800000, 0, 84, 32000), + }, + .n_linear_ranges = 1, + .n_voltages = 85, + .ops = &rpm_bob_ops, +}; + static const struct regulator_desc pms405_hfsmps3 = { .linear_ranges = (struct linear_range[]) { REGULATOR_LINEAR_RANGE(320000, 0, 215, 8000), @@ -902,6 +965,54 @@ static const struct rpm_regulator_data rpm_pmi8998_regulators[] = { {} }; +static const struct rpm_regulator_data rpm_pm660_regulators[] = { + { "s1", QCOM_SMD_RPM_SMPA, 1, &pm660_ftsmps, "vdd_s1" }, + { "s2", QCOM_SMD_RPM_SMPA, 2, &pm660_ftsmps, "vdd_s2" }, + { "s3", QCOM_SMD_RPM_SMPA, 3, &pm660_ftsmps, "vdd_s3" }, + { "s4", QCOM_SMD_RPM_SMPA, 4, &pm660_hfsmps, "vdd_s4" }, + { "s5", QCOM_SMD_RPM_SMPA, 5, &pm660_hfsmps, "vdd_s5" }, + { "s6", QCOM_SMD_RPM_SMPA, 6, &pm660_hfsmps, "vdd_s6" }, + { "l1", QCOM_SMD_RPM_LDOA, 1, &pm660_nldo660, "vdd_l1_l6_l7" }, + { "l2", QCOM_SMD_RPM_LDOA, 2, &pm660_ht_nldo, "vdd_l2_l3" }, + { "l3", QCOM_SMD_RPM_LDOA, 3, &pm660_nldo660, "vdd_l2_l3" }, + /* l4 is unaccessible on PM660 */ + { "l5", QCOM_SMD_RPM_LDOA, 5, &pm660_ht_nldo, "vdd_l5" }, + { "l6", QCOM_SMD_RPM_LDOA, 6, &pm660_ht_nldo, "vdd_l1_l6_l7" }, + { "l7", QCOM_SMD_RPM_LDOA, 7, &pm660_ht_nldo, "vdd_l1_l6_l7" }, + { "l8", QCOM_SMD_RPM_LDOA, 8, &pm660_ht_lvpldo, "vdd_l8_l9_l10_l11_l12_l13_l14" }, + { "l9", QCOM_SMD_RPM_LDOA, 9, &pm660_ht_lvpldo, "vdd_l8_l9_l10_l11_l12_l13_l14" }, + { "l10", QCOM_SMD_RPM_LDOA, 10, &pm660_ht_lvpldo, "vdd_l8_l9_l10_l11_l12_l13_l14" }, + { "l11", QCOM_SMD_RPM_LDOA, 11, &pm660_ht_lvpldo, "vdd_l8_l9_l10_l11_l12_l13_l14" }, + { "l12", QCOM_SMD_RPM_LDOA, 12, &pm660_ht_lvpldo, "vdd_l8_l9_l10_l11_l12_l13_l14" }, + { "l13", QCOM_SMD_RPM_LDOA, 13, &pm660_ht_lvpldo, "vdd_l8_l9_l10_l11_l12_l13_l14" }, + { "l14", QCOM_SMD_RPM_LDOA, 14, &pm660_ht_lvpldo, "vdd_l8_l9_l10_l11_l12_l13_l14" }, + { "l15", QCOM_SMD_RPM_LDOA, 15, &pm660_pldo660, "vdd_l15_l16_l17_l18_l19" }, + { "l16", QCOM_SMD_RPM_LDOA, 16, &pm660_pldo660, "vdd_l15_l16_l17_l18_l19" }, + { "l17", QCOM_SMD_RPM_LDOA, 17, &pm660_pldo660, "vdd_l15_l16_l17_l18_l19" }, + { "l18", QCOM_SMD_RPM_LDOA, 18, &pm660_pldo660, "vdd_l15_l16_l17_l18_l19" }, + { "l19", QCOM_SMD_RPM_LDOA, 19, &pm660_pldo660, "vdd_l15_l16_l17_l18_l19" }, + { } +}; + +static const struct rpm_regulator_data rpm_pm660l_regulators[] = { + { "s1", QCOM_SMD_RPM_SMPB, 1, &pm660_ftsmps, "vdd_s1" }, + { "s2", QCOM_SMD_RPM_SMPB, 2, &pm660_ftsmps, "vdd_s2" }, + { "s3", QCOM_SMD_RPM_RWCX, 0, &pm660_ftsmps, "vdd_s3_s4" }, + { "s5", QCOM_SMD_RPM_RWMX, 0, &pm660_ftsmps, "vdd_s5" }, + { "l1", QCOM_SMD_RPM_LDOB, 1, &pm660_nldo660, "vdd_l1_l9_l10" }, + { "l2", QCOM_SMD_RPM_LDOB, 2, &pm660_pldo660, "vdd_l2" }, + { "l3", QCOM_SMD_RPM_LDOB, 3, &pm660_pldo660, "vdd_l3_l5_l7_l8" }, + { "l4", QCOM_SMD_RPM_LDOB, 4, &pm660_pldo660, "vdd_l4_l6" }, + { "l5", QCOM_SMD_RPM_LDOB, 5, &pm660_pldo660, "vdd_l3_l5_l7_l8" }, + { "l6", QCOM_SMD_RPM_LDOB, 6, &pm660_pldo660, "vdd_l4_l6" }, + { "l7", QCOM_SMD_RPM_LDOB, 7, &pm660_pldo660, "vdd_l3_l5_l7_l8" }, + { "l8", QCOM_SMD_RPM_LDOB, 8, &pm660_pldo660, "vdd_l3_l5_l7_l8" }, + { "l9", QCOM_SMD_RPM_RWLC, 0, &pm660_ht_nldo, "vdd_l1_l9_l10" }, + { "l10", QCOM_SMD_RPM_RWLM, 0, &pm660_ht_nldo, "vdd_l1_l9_l10" }, + { "bob", QCOM_SMD_RPM_BOBB, 1, &pm660l_bob, "vdd_bob", }, + { } +}; + static const struct rpm_regulator_data rpm_pms405_regulators[] = { { "s1", QCOM_SMD_RPM_SMPA, 1, &pms405_hfsmps3, "vdd_s1" }, { "s2", QCOM_SMD_RPM_SMPA, 2, &pms405_hfsmps3, "vdd_s2" }, @@ -932,6 +1043,8 @@ static const struct of_device_id rpm_of_match[] = { { .compatible = "qcom,rpm-pm8950-regulators", .data = &rpm_pm8950_regulators }, { .compatible = "qcom,rpm-pm8994-regulators", .data = &rpm_pm8994_regulators }, { .compatible = "qcom,rpm-pm8998-regulators", .data = &rpm_pm8998_regulators }, + { .compatible = "qcom,rpm-pm660-regulators", .data = &rpm_pm660_regulators }, + { .compatible = "qcom,rpm-pm660l-regulators", .data = &rpm_pm660l_regulators }, { .compatible = "qcom,rpm-pma8084-regulators", .data = &rpm_pma8084_regulators }, { .compatible = "qcom,rpm-pmi8994-regulators", .data = &rpm_pmi8994_regulators }, { .compatible = "qcom,rpm-pmi8998-regulators", .data = &rpm_pmi8998_regulators }, diff --git a/include/linux/soc/qcom/smd-rpm.h b/include/linux/soc/qcom/smd-rpm.h index da304ce8c8f7..f2645ec52520 100644 --- a/include/linux/soc/qcom/smd-rpm.h +++ b/include/linux/soc/qcom/smd-rpm.h @@ -19,6 +19,10 @@ struct qcom_smd_rpm; #define QCOM_SMD_RPM_CLK_BUF_A 0x616B6C63 #define QCOM_SMD_RPM_LDOA 0x616f646c #define QCOM_SMD_RPM_LDOB 0x626F646C +#define QCOM_SMD_RPM_RWCX 0x78637772 +#define QCOM_SMD_RPM_RWMX 0x786d7772 +#define QCOM_SMD_RPM_RWLC 0x636c7772 +#define QCOM_SMD_RPM_RWLM 0x6d6c7772 #define QCOM_SMD_RPM_MEM_CLK 0x326b6c63 #define QCOM_SMD_RPM_MISC_CLK 0x306b6c63 #define QCOM_SMD_RPM_NCPA 0x6170636E -- cgit v1.2.3 From e6f5ff17ca96456deceef94cf2577012a9df737f Mon Sep 17 00:00:00 2001 From: Rikard Falkeborn Date: Wed, 30 Sep 2020 18:26:02 +0200 Subject: regulator: qcom: labibb: Constify static structs The only usage of qcom_labibb_ops is to assign it to the ops field in the regulator_desc struct, which is a const pointer. The only usage of pmi8998_lab_desc and pmi8998_ibb_desc is to assign their address to the desc field in the labibb_regulator_data struct which can be made const, since it is only copied into the desc field in the labbibb_regulator_data struct. This struct is modified, but that's a copy of the static one. Make them const to allow the compiler to put them in read-only memory. Signed-off-by: Rikard Falkeborn Link: https://lore.kernel.org/r/20200930162602.18583-1-rikard.falkeborn@gmail.com Signed-off-by: Mark Brown --- drivers/regulator/qcom-labibb-regulator.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/qcom-labibb-regulator.c b/drivers/regulator/qcom-labibb-regulator.c index 8c7dd1928380..8ccf572394a2 100644 --- a/drivers/regulator/qcom-labibb-regulator.c +++ b/drivers/regulator/qcom-labibb-regulator.c @@ -44,16 +44,16 @@ struct labibb_regulator_data { const char *name; u8 type; u16 base; - struct regulator_desc *desc; + const struct regulator_desc *desc; }; -static struct regulator_ops qcom_labibb_ops = { +static const struct regulator_ops qcom_labibb_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, }; -static struct regulator_desc pmi8998_lab_desc = { +static const struct regulator_desc pmi8998_lab_desc = { .enable_mask = LAB_ENABLE_CTL_MASK, .enable_reg = (PMI8998_LAB_REG_BASE + REG_LABIBB_ENABLE_CTL), .enable_val = LABIBB_CONTROL_ENABLE, @@ -65,7 +65,7 @@ static struct regulator_desc pmi8998_lab_desc = { .ops = &qcom_labibb_ops, }; -static struct regulator_desc pmi8998_ibb_desc = { +static const struct regulator_desc pmi8998_ibb_desc = { .enable_mask = IBB_ENABLE_CTL_MASK, .enable_reg = (PMI8998_IBB_REG_BASE + REG_LABIBB_ENABLE_CTL), .enable_val = LABIBB_CONTROL_ENABLE, -- cgit v1.2.3 From c845f21ad86528f888db27849f2d315e08126816 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 5 Oct 2020 15:15:46 +0200 Subject: regulator: Make constraint debug processing conditional on DEBUG If debugging is disabled, print_constraints() does not print the actual constraints, but still performs some processing and string formatting, only to throw away the result later. Fix this by moving all constraint debug processing to a separate function, and replacing it by a dummy when debugging is disabled. This reduces kernel size by almost 800 bytes (on arm/arm64). Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20201005131546.22448-1-geert+renesas@glider.be Signed-off-by: Mark Brown --- drivers/regulator/core.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 16497192e99b..bba25935e79e 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1056,7 +1056,8 @@ static int suspend_set_initial_state(struct regulator_dev *rdev) return __suspend_set_state(rdev, rstate); } -static void print_constraints(struct regulator_dev *rdev) +#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG) +static void print_constraints_debug(struct regulator_dev *rdev) { struct regulation_constraints *constraints = rdev->constraints; char buf[160] = ""; @@ -1124,6 +1125,16 @@ static void print_constraints(struct regulator_dev *rdev) _regulator_is_enabled(rdev) ? "enabled" : "disabled"); rdev_dbg(rdev, "%s\n", buf); +} +#else /* !DEBUG && !CONFIG_DYNAMIC_DEBUG */ +static inline void print_constraints_debug(struct regulator_dev *rdev) {} +#endif /* !DEBUG && !CONFIG_DYNAMIC_DEBUG */ + +static void print_constraints(struct regulator_dev *rdev) +{ + struct regulation_constraints *constraints = rdev->constraints; + + print_constraints_debug(rdev); if ((constraints->min_uV != constraints->max_uV) && !regulator_ops_is_valid(rdev, REGULATOR_CHANGE_VOLTAGE)) -- cgit v1.2.3 From b1a2fb10b8ef07a32061c53426303f73533d867b Mon Sep 17 00:00:00 2001 From: Vladimir Lypak Date: Sun, 4 Oct 2020 11:34:12 +0300 Subject: regulator: qcom_smd: add pm8953 regulators The PM8953 is commonly used on board with MSM8953 SoCs or its variants: APQ8053, SDM(SDA)450 and SDM(SDA)632. It provides 7 SMPS and 23 LDO regulators. Signed-off-by: Vladimir Lypak Link: https://lore.kernel.org/r/20201004083413.324351-1-junak.pub@gmail.com Signed-off-by: Mark Brown --- drivers/regulator/qcom_smd-regulator.c | 54 ++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'drivers/regulator') diff --git a/drivers/regulator/qcom_smd-regulator.c b/drivers/regulator/qcom_smd-regulator.c index faa99690b7b3..bb944ee5fe3b 100644 --- a/drivers/regulator/qcom_smd-regulator.c +++ b/drivers/regulator/qcom_smd-regulator.c @@ -403,6 +403,24 @@ static const struct regulator_desc pm8950_pldo = { .ops = &rpm_smps_ldo_ops, }; +static const struct regulator_desc pm8953_lnldo = { + .linear_ranges = (struct linear_range[]) { + REGULATOR_LINEAR_RANGE(1380000, 8, 15, 120000), + REGULATOR_LINEAR_RANGE(690000, 0, 7, 60000), + }, + .n_linear_ranges = 2, + .n_voltages = 16, + .ops = &rpm_smps_ldo_ops, +}; + +static const struct regulator_desc pm8953_ult_nldo = { + .linear_ranges = (struct linear_range[]) { + REGULATOR_LINEAR_RANGE(375000, 0, 93, 12500), + }, + .n_linear_ranges = 1, + .n_voltages = 94, + .ops = &rpm_smps_ldo_ops, +}; static const struct regulator_desc pm8994_hfsmps = { .linear_ranges = (struct linear_range[]) { @@ -854,6 +872,41 @@ static const struct rpm_regulator_data rpm_pm8950_regulators[] = { {} }; +static const struct rpm_regulator_data rpm_pm8953_regulators[] = { + { "s1", QCOM_SMD_RPM_SMPA, 1, &pm8998_hfsmps, "vdd_s1" }, + { "s2", QCOM_SMD_RPM_SMPA, 2, &pm8998_hfsmps, "vdd_s2" }, + { "s3", QCOM_SMD_RPM_SMPA, 3, &pm8998_hfsmps, "vdd_s3" }, + { "s4", QCOM_SMD_RPM_SMPA, 4, &pm8998_hfsmps, "vdd_s4" }, + { "s5", QCOM_SMD_RPM_SMPA, 5, &pm8950_ftsmps2p5, "vdd_s5" }, + { "s6", QCOM_SMD_RPM_SMPA, 6, &pm8950_ftsmps2p5, "vdd_s6" }, + { "s7", QCOM_SMD_RPM_SMPA, 7, &pm8998_hfsmps, "vdd_s7" }, + + { "l1", QCOM_SMD_RPM_LDOA, 1, &pm8953_ult_nldo, "vdd_l1" }, + { "l2", QCOM_SMD_RPM_LDOA, 2, &pm8953_ult_nldo, "vdd_l2_l3" }, + { "l3", QCOM_SMD_RPM_LDOA, 3, &pm8953_ult_nldo, "vdd_l2_l3" }, + { "l4", QCOM_SMD_RPM_LDOA, 4, &pm8950_ult_pldo, "vdd_l4_l5_l6_l7_l16_l19" }, + { "l5", QCOM_SMD_RPM_LDOA, 5, &pm8950_ult_pldo, "vdd_l4_l5_l6_l7_l16_l19" }, + { "l6", QCOM_SMD_RPM_LDOA, 6, &pm8950_ult_pldo, "vdd_l4_l5_l6_l7_l16_l19" }, + { "l7", QCOM_SMD_RPM_LDOA, 7, &pm8950_ult_pldo, "vdd_l4_l5_l6_l7_l16_l19" }, + { "l8", QCOM_SMD_RPM_LDOA, 8, &pm8950_ult_pldo, "vdd_l8_l11_l12_l13_l14_l15" }, + { "l9", QCOM_SMD_RPM_LDOA, 9, &pm8950_ult_pldo, "vdd_l9_l10_l17_l18_l22" }, + { "l10", QCOM_SMD_RPM_LDOA, 10, &pm8950_ult_pldo, "vdd_l9_l10_l17_l18_l22" }, + { "l11", QCOM_SMD_RPM_LDOA, 11, &pm8950_ult_pldo, "vdd_l8_l11_l12_l13_l14_l15" }, + { "l12", QCOM_SMD_RPM_LDOA, 12, &pm8950_ult_pldo, "vdd_l8_l11_l12_l13_l14_l15" }, + { "l13", QCOM_SMD_RPM_LDOA, 13, &pm8950_ult_pldo, "vdd_l8_l11_l12_l13_l14_l15" }, + { "l14", QCOM_SMD_RPM_LDOA, 14, &pm8950_ult_pldo, "vdd_l8_l11_l12_l13_l14_l15" }, + { "l15", QCOM_SMD_RPM_LDOA, 15, &pm8950_ult_pldo, "vdd_l8_l11_l12_l13_l14_l15" }, + { "l16", QCOM_SMD_RPM_LDOA, 16, &pm8950_ult_pldo, "vdd_l4_l5_l6_l7_l16_l19" }, + { "l17", QCOM_SMD_RPM_LDOA, 17, &pm8950_ult_pldo, "vdd_l9_l10_l17_l18_l22" }, + { "l18", QCOM_SMD_RPM_LDOA, 18, &pm8950_ult_pldo, "vdd_l9_l10_l17_l18_l22" }, + { "l19", QCOM_SMD_RPM_LDOA, 19, &pm8953_ult_nldo, "vdd_l4_l5_l6_l7_l16_l19" }, + { "l20", QCOM_SMD_RPM_LDOA, 20, &pm8953_lnldo, "vdd_l20" }, + { "l21", QCOM_SMD_RPM_LDOA, 21, &pm8953_lnldo, "vdd_l21" }, + { "l22", QCOM_SMD_RPM_LDOA, 22, &pm8950_ult_pldo, "vdd_l9_l10_l17_l18_l22" }, + { "l23", QCOM_SMD_RPM_LDOA, 23, &pm8953_ult_nldo, "vdd_l23" }, + {} +}; + static const struct rpm_regulator_data rpm_pm8994_regulators[] = { { "s1", QCOM_SMD_RPM_SMPA, 1, &pm8994_ftsmps, "vdd_s1" }, { "s2", QCOM_SMD_RPM_SMPA, 2, &pm8994_ftsmps, "vdd_s2" }, @@ -1041,6 +1094,7 @@ static const struct of_device_id rpm_of_match[] = { { .compatible = "qcom,rpm-pm8916-regulators", .data = &rpm_pm8916_regulators }, { .compatible = "qcom,rpm-pm8941-regulators", .data = &rpm_pm8941_regulators }, { .compatible = "qcom,rpm-pm8950-regulators", .data = &rpm_pm8950_regulators }, + { .compatible = "qcom,rpm-pm8953-regulators", .data = &rpm_pm8953_regulators }, { .compatible = "qcom,rpm-pm8994-regulators", .data = &rpm_pm8994_regulators }, { .compatible = "qcom,rpm-pm8998-regulators", .data = &rpm_pm8998_regulators }, { .compatible = "qcom,rpm-pm660-regulators", .data = &rpm_pm660_regulators }, -- cgit v1.2.3 From 184cdb8f6d391b379bb768b0c203600f5657176b Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Mon, 5 Oct 2020 11:19:24 +0300 Subject: regulator: bd9576: Fix print The print in probe is done using pr_info. Correct print call would be dev_dbg because: - Severity should really be dbg - The dev pointer is given as first argument Signed-off-by: Matti Vaittinen Link: https://lore.kernel.org/r/c4f55add237455555df0597c72052022f7a669f6.1601885841.git.matti.vaittinen@fi.rohmeurope.com Signed-off-by: Mark Brown --- drivers/regulator/bd9576-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/bd9576-regulator.c b/drivers/regulator/bd9576-regulator.c index 4137fa9a73bb..a8b5832a5a1b 100644 --- a/drivers/regulator/bd9576-regulator.c +++ b/drivers/regulator/bd9576-regulator.c @@ -275,7 +275,7 @@ static int bd957x_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "Found BD9576MUF\n"); break; case ROHM_CHIP_TYPE_BD9573: - pr_info(&pdev->dev, "Found BD9573MUF\n"); + dev_dbg(&pdev->dev, "Found BD9573MUF\n"); break; default: dev_err(&pdev->dev, "Unsupported chip type\n"); -- cgit v1.2.3