From cfbe9dfd664c7717ef297e01b7eecccc2b5fde6f Mon Sep 17 00:00:00 2001 From: Wadim Egorov Date: Wed, 14 Dec 2022 16:34:09 +0100 Subject: regulator: tps65219: Report regulator name if devm_regulator_register fails Make the error message more useful by reporting the actual regulator name if devm_regulator_register() fails. Signed-off-by: Wadim Egorov Link: https://lore.kernel.org/r/20221214153409.1270213-1-w.egorov@phytec.de Signed-off-by: Mark Brown --- drivers/regulator/tps65219-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/tps65219-regulator.c b/drivers/regulator/tps65219-regulator.c index c484c943e467..f294d3bc5e73 100644 --- a/drivers/regulator/tps65219-regulator.c +++ b/drivers/regulator/tps65219-regulator.c @@ -342,7 +342,7 @@ static int tps65219_regulator_probe(struct platform_device *pdev) &config); if (IS_ERR(rdev)) { dev_err(tps->dev, "failed to register %s regulator\n", - pdev->name); + regulators[i].name); return PTR_ERR(rdev); } rdevtbl[i] = rdev; -- cgit v1.2.3 From 80332ec8c0994dc457026b20619dee0f9990706f Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 12 Jan 2023 22:44:12 -0800 Subject: regulator: act8945a: fix non-kernel-doc comments Don't use kernel-doc "/**" markers for comments that are not in kernel-doc format. This prevents these warnings: drivers/regulator/act8945a-regulator.c:19: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * ACT8945A Global Register Map. drivers/regulator/act8945a-regulator.c:50: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Field Definitions. drivers/regulator/act8945a-regulator.c:56: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * ACT8945A Voltage Number Signed-off-by: Randy Dunlap Cc: Liam Girdwood Cc: Mark Brown Link: https://lore.kernel.org/r/20230113064412.11038-1-rdunlap@infradead.org Signed-off-by: Mark Brown --- drivers/regulator/act8945a-regulator.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/act8945a-regulator.c b/drivers/regulator/act8945a-regulator.c index 6a62f946ccae..1db1c6423779 100644 --- a/drivers/regulator/act8945a-regulator.c +++ b/drivers/regulator/act8945a-regulator.c @@ -15,7 +15,7 @@ #include #include -/** +/* * ACT8945A Global Register Map. */ #define ACT8945A_SYS_MODE 0x00 @@ -46,13 +46,13 @@ #define ACT8945A_LDO4_CTRL 0x65 #define ACT8945A_LDO4_SUS 0x66 -/** +/* * Field Definitions. */ #define ACT8945A_ENA 0x80 /* ON - [7] */ #define ACT8945A_VSEL_MASK 0x3F /* VSET - [5:0] */ -/** +/* * ACT8945A Voltage Number */ #define ACT8945A_VOLTAGE_NUM 64 -- cgit v1.2.3 From a508a267dda6e67d2eccbc12088a7fecc127ba90 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 12 Jan 2023 22:44:21 -0800 Subject: regulator: fixed-helper: use the correct function name in comment Use the correct function name and modify the function short description. This prevents a kernel-doc warning: drivers/regulator/fixed-helper.c:32: warning: expecting prototype for regulator_register_fixed_name(). Prototype was for regulator_register_always_on() instead Signed-off-by: Randy Dunlap Cc: Liam Girdwood Cc: Mark Brown Link: https://lore.kernel.org/r/20230113064421.11986-1-rdunlap@infradead.org Signed-off-by: Mark Brown --- drivers/regulator/fixed-helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/fixed-helper.c b/drivers/regulator/fixed-helper.c index 2c6098e6f4bc..0eb2442456f0 100644 --- a/drivers/regulator/fixed-helper.c +++ b/drivers/regulator/fixed-helper.c @@ -20,7 +20,7 @@ static void regulator_fixed_release(struct device *dev) } /** - * regulator_register_fixed_name - register a no-op fixed regulator + * regulator_register_always_on - register an always-on regulator with a fixed name * @id: platform device id * @name: name to be used for the regulator * @supplies: consumers for this regulator -- cgit v1.2.3 From 84c13763f2a22acc31472dccde8b6130b8f2e9c2 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 16 Jan 2023 23:01:39 -0800 Subject: regulator: mcp16502: add enum MCP16502_REG_HPM description Add description for MCP16502_REG_HPM to prevent a kernel-doc warning: drivers/regulator/mcp16502.c:90: warning: Enum value 'MCP16502_REG_HPM' not described in enum 'mcp16502_reg' Signed-off-by: Randy Dunlap Reviewed-by: Claudiu Beznea Link: https://lore.kernel.org/r/20230117070139.28905-1-rdunlap@infradead.org Signed-off-by: Mark Brown --- drivers/regulator/mcp16502.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/regulator') diff --git a/drivers/regulator/mcp16502.c b/drivers/regulator/mcp16502.c index 042668385678..abee1b09008d 100644 --- a/drivers/regulator/mcp16502.c +++ b/drivers/regulator/mcp16502.c @@ -77,6 +77,7 @@ * @MCP16502_REG_A: active state register * @MCP16502_REG_LPM: low power mode state register * @MCP16502_REG_HIB: hibernate state register + * @MCP16502_REG_HPM: high-performance mode register * @MCP16502_REG_SEQ: startup sequence register * @MCP16502_REG_CFG: configuration register */ -- cgit v1.2.3 From 2bbba115c3c9a647bcb3201b014fcc3728fe75c8 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 14 Jan 2023 10:57:36 -0800 Subject: regulator: tps65219: use IS_ERR() to detect an error pointer Fix pointer comparison to integer warning from gcc & sparse: GCC: ../drivers/regulator/tps65219-regulator.c:370:26: warning: ordered comparison of pointer with integer zero [-Wextra] 370 | if (rdev < 0) { | ^ sparse warning: drivers/regulator/tps65219-regulator.c:370:26: sparse: error: incompatible types for operation (<): drivers/regulator/tps65219-regulator.c:370:26: sparse: struct regulator_dev *[assigned] rdev drivers/regulator/tps65219-regulator.c:370:26: sparse: int Fixes: c12ac5fc3e0a ("regulator: drivers: Add TI TPS65219 PMIC regulators support") Signed-off-by: Randy Dunlap Cc: Jerome Neanne Cc: Tony Lindgren Cc: linux-omap@vger.kernel.org Cc: Liam Girdwood Cc: Mark Brown Link: https://lore.kernel.org/r/20230114185736.2076-1-rdunlap@infradead.org Signed-off-by: Mark Brown --- drivers/regulator/tps65219-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/tps65219-regulator.c b/drivers/regulator/tps65219-regulator.c index f294d3bc5e73..bb4757a2042c 100644 --- a/drivers/regulator/tps65219-regulator.c +++ b/drivers/regulator/tps65219-regulator.c @@ -367,7 +367,7 @@ static int tps65219_regulator_probe(struct platform_device *pdev) irq_data[i].type = irq_type; tps65219_get_rdev_by_name(irq_type->regulator_name, rdevtbl, rdev); - if (rdev < 0) { + if (IS_ERR(rdev)) { dev_err(tps->dev, "Failed to get rdev for %s\n", irq_type->regulator_name); return -EINVAL; -- cgit v1.2.3 From 047ebaffd8171a47eb5462aec0f6006416fbe62e Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Tue, 24 Jan 2023 10:44:39 -0800 Subject: regulator: Introduce Maxim MAX20411 Step-Down converter Introduce a driver to control the Maxim MAX20411 family of high-efficiency, syncrhonous step-down converters. Signed-off-by: Bjorn Andersson Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20230124184440.1421074-3-quic_bjorande@quicinc.com Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 8 ++ drivers/regulator/Makefile | 1 + drivers/regulator/max20411-regulator.c | 163 +++++++++++++++++++++++++++++++++ 3 files changed, 172 insertions(+) create mode 100644 drivers/regulator/max20411-regulator.c (limited to 'drivers/regulator') diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 820c9a0788e5..aae28d0a489c 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -655,6 +655,14 @@ config REGULATOR_MAX20086 protectorvia I2C bus. The regulator has 2 or 4 outputs depending on the device model. This driver is only capable to turn on/off them. +config REGULATOR_MAX20411 + tristate "Maxim MAX20411 High-Efficiency Single Step-Down Converter" + depends on I2C + select REGMAP_I2C + help + This driver controls the Maxim MAX20411 family of high-efficiency, + syncrhonous step-down converters. + config REGULATOR_MAX77686 tristate "Maxim 77686 regulator" depends on MFD_MAX77686 || COMPILE_TEST diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index b9f5eb35bf5f..ee383d8fc835 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -80,6 +80,7 @@ obj-$(CONFIG_REGULATOR_MAX8973) += max8973-regulator.o obj-$(CONFIG_REGULATOR_MAX8997) += max8997-regulator.o obj-$(CONFIG_REGULATOR_MAX8998) += max8998.o obj-$(CONFIG_REGULATOR_MAX20086) += max20086-regulator.o +obj-$(CONFIG_REGULATOR_MAX20411) += max20411-regulator.o obj-$(CONFIG_REGULATOR_MAX77686) += max77686-regulator.o obj-$(CONFIG_REGULATOR_MAX77693) += max77693-regulator.o obj-$(CONFIG_REGULATOR_MAX77802) += max77802-regulator.o diff --git a/drivers/regulator/max20411-regulator.c b/drivers/regulator/max20411-regulator.c new file mode 100644 index 000000000000..69f04cbe69f1 --- /dev/null +++ b/drivers/regulator/max20411-regulator.c @@ -0,0 +1,163 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022, Linaro Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX20411_UV_STEP 6250 +#define MAX20411_BASE_UV 243750 +#define MAX20411_MIN_SEL 41 /* 0.5V */ +#define MAX20411_MAX_SEL 165 /* 1.275V */ +#define MAX20411_VID_OFFSET 0x7 +#define MAX20411_VID_MASK 0xff +#define MAX20411_SLEW_OFFSET 0x6 +#define MAX20411_SLEW_DVS_MASK 0xc +#define MAX20411_SLEW_SR_MASK 0x3 + +struct max20411 { + struct device *dev; + struct device_node *of_node; + struct regulator_desc desc; + struct regulator_dev *rdev; + struct regmap *regmap; +}; + +static const unsigned int max20411_slew_rates[] = { 13100, 6600, 3300, 1600 }; + +static int max20411_enable_time(struct regulator_dev *rdev) +{ + int voltage, rate, ret; + unsigned int val; + + /* get voltage */ + ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val); + if (ret) + return ret; + + val &= rdev->desc->vsel_mask; + voltage = regulator_list_voltage_linear(rdev, val); + + /* get rate */ + ret = regmap_read(rdev->regmap, MAX20411_SLEW_OFFSET, &val); + if (ret) + return ret; + + val = FIELD_GET(MAX20411_SLEW_SR_MASK, val); + rate = max20411_slew_rates[val]; + + return DIV_ROUND_UP(voltage, rate); +} + +static const struct regmap_config max20411_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = 0xe, +}; + +static const struct regulator_ops max20411_ops = { + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .list_voltage = regulator_list_voltage_linear, + .enable_time = max20411_enable_time, +}; + +static const struct regulator_desc max20411_desc = { + .ops = &max20411_ops, + .owner = THIS_MODULE, + .type = REGULATOR_VOLTAGE, + .supply_name = "vin", + .name = "max20411", + + /* + * voltage = 0.24375V + selector * 6.25mV + * with valid selector between 41 to 165 (0.5V to 1.275V) + */ + .min_uV = MAX20411_BASE_UV, + .uV_step = MAX20411_UV_STEP, + .linear_min_sel = MAX20411_MIN_SEL, + .n_voltages = MAX20411_MAX_SEL, + + .vsel_reg = MAX20411_VID_OFFSET, + .vsel_mask = MAX20411_VID_MASK, + + .ramp_reg = MAX20411_SLEW_OFFSET, + .ramp_mask = MAX20411_SLEW_DVS_MASK, + .ramp_delay_table = max20411_slew_rates, + .n_ramp_values = ARRAY_SIZE(max20411_slew_rates), +}; + +static int max20411_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct regulator_init_data *init_data; + struct device *dev = &client->dev; + struct regulator_config cfg = {}; + struct max20411 *max20411; + + max20411 = devm_kzalloc(dev, sizeof(*max20411), GFP_KERNEL); + if (!max20411) + return -ENOMEM; + + max20411->regmap = devm_regmap_init_i2c(client, &max20411_regmap_config); + if (IS_ERR(max20411->regmap)) { + dev_err(dev, "Failed to allocate regmap!\n"); + return PTR_ERR(max20411->regmap); + } + + max20411->dev = dev; + max20411->of_node = dev->of_node; + + max20411->desc = max20411_desc; + init_data = of_get_regulator_init_data(max20411->dev, max20411->of_node, &max20411->desc); + if (!init_data) + return -ENODATA; + + cfg.dev = max20411->dev; + cfg.init_data = init_data; + cfg.of_node = max20411->of_node; + cfg.driver_data = max20411; + + cfg.ena_gpiod = gpiod_get(max20411->dev, "enable", GPIOD_ASIS); + if (IS_ERR(cfg.ena_gpiod)) + return dev_err_probe(dev, PTR_ERR(cfg.ena_gpiod), + "unable to acquire enable gpio\n"); + + max20411->rdev = devm_regulator_register(max20411->dev, &max20411->desc, &cfg); + if (IS_ERR(max20411->rdev)) + dev_err(max20411->dev, "Failed to register regulator\n"); + + return PTR_ERR_OR_ZERO(max20411->rdev); +} + +static const struct of_device_id of_max20411_match_tbl[] = { + { .compatible = "maxim,max20411", }, + { }, +}; +MODULE_DEVICE_TABLE(of, of_max20411_match_tbl); + +static const struct i2c_device_id max20411_id[] = { + { "max20411", 0 }, + { }, +}; +MODULE_DEVICE_TABLE(i2c, max20411_id); + +static struct i2c_driver max20411_i2c_driver = { + .driver = { + .name = "max20411", + .of_match_table = of_max20411_match_tbl, + }, + .probe = max20411_probe, + .id_table = max20411_id, +}; +module_i2c_driver(max20411_i2c_driver); + +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From d5b4c8b909f5670e292fa655b22e3d35bf699c46 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 26 Jan 2023 22:51:39 +0000 Subject: regulator: max20411: Directly include bitfield.h The max20411 driver uses bitfield.h but does not directly include it, add an inclusion to avoid build errors in configurations which do not result in an implicit inclusion. Signed-off-by: Mark Brown --- drivers/regulator/max20411-regulator.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/regulator') diff --git a/drivers/regulator/max20411-regulator.c b/drivers/regulator/max20411-regulator.c index 69f04cbe69f1..b4faad54c458 100644 --- a/drivers/regulator/max20411-regulator.c +++ b/drivers/regulator/max20411-regulator.c @@ -4,6 +4,7 @@ * Copyright (c) 2022, Linaro Ltd. */ +#include #include #include #include -- cgit v1.2.3 From 668f777d02f61faa834f1e24f3b99576dbe5ff6b Mon Sep 17 00:00:00 2001 From: Cristian Marussi Date: Thu, 26 Jan 2023 18:05:11 +0000 Subject: regulator: scmi: Allow for zero voltage domains SCMI Voltage protocol allows the platform to report no voltage domains on discovery, while warning the user about such an odd configuration. As a consequence this condition should not be treated as error by the SCMI regulator driver either. Allow SCMI regulator driver to probe successfully even when no voltage domains are discovered. Signed-off-by: Cristian Marussi Link: https://lore.kernel.org/r/20230126180511.766373-1-cristian.marussi@arm.com Signed-off-by: Mark Brown --- drivers/regulator/scmi-regulator.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/scmi-regulator.c b/drivers/regulator/scmi-regulator.c index b9918f4fd241..29ab217297d6 100644 --- a/drivers/regulator/scmi-regulator.c +++ b/drivers/regulator/scmi-regulator.c @@ -311,16 +311,12 @@ static int scmi_regulator_probe(struct scmi_device *sdev) return PTR_ERR(voltage_ops); num_doms = voltage_ops->num_domains_get(ph); - if (num_doms <= 0) { - if (!num_doms) { - dev_err(&sdev->dev, - "number of voltage domains invalid\n"); - num_doms = -EINVAL; - } else { - dev_err(&sdev->dev, - "failed to get voltage domains - err:%d\n", - num_doms); - } + if (!num_doms) + return 0; + + if (num_doms < 0) { + dev_err(&sdev->dev, "failed to get voltage domains - err:%d\n", + num_doms); return num_doms; } -- cgit v1.2.3 From fad8ddda1c40c00bff4ac45eb9b85e1f717f17f4 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 27 Jan 2023 11:17:26 +0100 Subject: regulator: max20411: Convert to i2c's .probe_new() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe function doesn't make use of the i2c_device_id * parameter so it can be trivially converted. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20230127101726.1313927-1-u.kleine-koenig@pengutronix.de Signed-off-by: Mark Brown --- drivers/regulator/max20411-regulator.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/max20411-regulator.c b/drivers/regulator/max20411-regulator.c index b4faad54c458..e75d16048e2f 100644 --- a/drivers/regulator/max20411-regulator.c +++ b/drivers/regulator/max20411-regulator.c @@ -96,8 +96,7 @@ static const struct regulator_desc max20411_desc = { .n_ramp_values = ARRAY_SIZE(max20411_slew_rates), }; -static int max20411_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int max20411_probe(struct i2c_client *client) { struct regulator_init_data *init_data; struct device *dev = &client->dev; @@ -156,7 +155,7 @@ static struct i2c_driver max20411_i2c_driver = { .name = "max20411", .of_match_table = of_max20411_match_tbl, }, - .probe = max20411_probe, + .probe_new = max20411_probe, .id_table = max20411_id, }; module_i2c_driver(max20411_i2c_driver); -- cgit v1.2.3 From 4fd8bcec5fd7c0d586206fa2f42bd67b06cdaa7e Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 27 Jan 2023 14:52:07 -0800 Subject: regulator: max77802: Bounds check regulator id against opmode Explicitly bounds-check the id before accessing the opmode array. Seen with GCC 13: ../drivers/regulator/max77802-regulator.c: In function 'max77802_enable': ../drivers/regulator/max77802-regulator.c:217:29: warning: array subscript [0, 41] is outside array bounds of 'unsigned int[42]' [-Warray-bounds=] 217 | if (max77802->opmode[id] == MAX77802_OFF_PWRREQ) | ~~~~~~~~~~~~~~~~^~~~ ../drivers/regulator/max77802-regulator.c:62:22: note: while referencing 'opmode' 62 | unsigned int opmode[MAX77802_REG_MAX]; | ^~~~~~ Cc: Javier Martinez Canillas Cc: Liam Girdwood Cc: Mark Brown Signed-off-by: Kees Cook Acked-by: Javier Martinez Canillas Link: https://lore.kernel.org/r/20230127225203.never.864-kees@kernel.org Signed-off-by: Mark Brown --- drivers/regulator/max77802-regulator.c | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/max77802-regulator.c b/drivers/regulator/max77802-regulator.c index 21e0eb0f43f9..befe5f319819 100644 --- a/drivers/regulator/max77802-regulator.c +++ b/drivers/regulator/max77802-regulator.c @@ -94,9 +94,11 @@ static int max77802_set_suspend_disable(struct regulator_dev *rdev) { unsigned int val = MAX77802_OFF_PWRREQ; struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev); - int id = rdev_get_id(rdev); + unsigned int id = rdev_get_id(rdev); int shift = max77802_get_opmode_shift(id); + if (WARN_ON_ONCE(id >= ARRAY_SIZE(max77802->opmode))) + return -EINVAL; max77802->opmode[id] = val; return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, rdev->desc->enable_mask, val << shift); @@ -110,7 +112,7 @@ static int max77802_set_suspend_disable(struct regulator_dev *rdev) static int max77802_set_mode(struct regulator_dev *rdev, unsigned int mode) { struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev); - int id = rdev_get_id(rdev); + unsigned int id = rdev_get_id(rdev); unsigned int val; int shift = max77802_get_opmode_shift(id); @@ -127,6 +129,9 @@ static int max77802_set_mode(struct regulator_dev *rdev, unsigned int mode) return -EINVAL; } + if (WARN_ON_ONCE(id >= ARRAY_SIZE(max77802->opmode))) + return -EINVAL; + max77802->opmode[id] = val; return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, rdev->desc->enable_mask, val << shift); @@ -135,8 +140,10 @@ static int max77802_set_mode(struct regulator_dev *rdev, unsigned int mode) static unsigned max77802_get_mode(struct regulator_dev *rdev) { struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev); - int id = rdev_get_id(rdev); + unsigned int id = rdev_get_id(rdev); + if (WARN_ON_ONCE(id >= ARRAY_SIZE(max77802->opmode))) + return -EINVAL; return max77802_map_mode(max77802->opmode[id]); } @@ -160,10 +167,13 @@ static int max77802_set_suspend_mode(struct regulator_dev *rdev, unsigned int mode) { struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev); - int id = rdev_get_id(rdev); + unsigned int id = rdev_get_id(rdev); unsigned int val; int shift = max77802_get_opmode_shift(id); + if (WARN_ON_ONCE(id >= ARRAY_SIZE(max77802->opmode))) + return -EINVAL; + /* * If the regulator has been disabled for suspend * then is invalid to try setting a suspend mode. @@ -209,9 +219,11 @@ static int max77802_set_suspend_mode(struct regulator_dev *rdev, static int max77802_enable(struct regulator_dev *rdev) { struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev); - int id = rdev_get_id(rdev); + unsigned int id = rdev_get_id(rdev); int shift = max77802_get_opmode_shift(id); + if (WARN_ON_ONCE(id >= ARRAY_SIZE(max77802->opmode))) + return -EINVAL; if (max77802->opmode[id] == MAX77802_OFF_PWRREQ) max77802->opmode[id] = MAX77802_OPMODE_NORMAL; @@ -495,7 +507,7 @@ static int max77802_pmic_probe(struct platform_device *pdev) for (i = 0; i < MAX77802_REG_MAX; i++) { struct regulator_dev *rdev; - int id = regulators[i].id; + unsigned int id = regulators[i].id; int shift = max77802_get_opmode_shift(id); int ret; @@ -513,10 +525,12 @@ static int max77802_pmic_probe(struct platform_device *pdev) * the hardware reports OFF as the regulator operating mode. * Default to operating mode NORMAL in that case. */ - if (val == MAX77802_STATUS_OFF) - max77802->opmode[id] = MAX77802_OPMODE_NORMAL; - else - max77802->opmode[id] = val; + if (id < ARRAY_SIZE(max77802->opmode)) { + if (val == MAX77802_STATUS_OFF) + max77802->opmode[id] = MAX77802_OPMODE_NORMAL; + else + max77802->opmode[id] = val; + } rdev = devm_regulator_register(&pdev->dev, ®ulators[i], &config); -- cgit v1.2.3 From e314e15a0b58f9d051c00b25951073bcdae61953 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 27 Jan 2023 16:53:58 -0800 Subject: regulator: s5m8767: Bounds check id indexing into arrays The compiler has no way to know if "id" is within the array bounds of the regulators array. Add a check for this and a build-time check that the regulators and reg_voltage_map arrays are sized the same. Seen with GCC 13: ../drivers/regulator/s5m8767.c: In function 's5m8767_pmic_probe': ../drivers/regulator/s5m8767.c:936:35: warning: array subscript [0, 36] is outside array bounds of 'struct regulator_desc[37]' [-Warray-bounds=] 936 | regulators[id].vsel_reg = | ~~~~~~~~~~^~~~ Cc: Krzysztof Kozlowski Cc: Liam Girdwood Cc: Mark Brown Cc: linux-samsung-soc@vger.kernel.org Signed-off-by: Kees Cook Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20230128005358.never.313-kees@kernel.org Signed-off-by: Mark Brown --- drivers/regulator/s5m8767.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index 35269f998210..754c6fcc6e64 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c @@ -923,10 +923,14 @@ static int s5m8767_pmic_probe(struct platform_device *pdev) for (i = 0; i < pdata->num_regulators; i++) { const struct sec_voltage_desc *desc; - int id = pdata->regulators[i].id; + unsigned int id = pdata->regulators[i].id; int enable_reg, enable_val; struct regulator_dev *rdev; + BUILD_BUG_ON(ARRAY_SIZE(regulators) != ARRAY_SIZE(reg_voltage_map)); + if (WARN_ON_ONCE(id >= ARRAY_SIZE(regulators))) + continue; + desc = reg_voltage_map[id]; if (desc) { regulators[id].n_voltages = -- cgit v1.2.3 From 0365df81145a4cfaae5f4da896160de512256e6d Mon Sep 17 00:00:00 2001 From: Jerome Neanne Date: Fri, 3 Feb 2023 15:01:19 +0100 Subject: regulator: tps65219: use generic set_bypass() Due to wrong interpretation of the specification, custom implementation was used instead of standard regmap helper. LINK: https://lore.kernel.org/all/c2014039-f1e8-6976-33d6-52e2dd4e7b66@baylibre.com/ Fixes: c12ac5fc3e0a ("regulator: drivers: Add TI TPS65219 PMIC regulators support") Regulator does NOT require to be off to be switched to bypass mode. Signed-off-by: Jerome Neanne Link: https://lore.kernel.org/r/20230203140119.13029-1-jneanne@baylibre.com Signed-off-by: Mark Brown --- drivers/regulator/tps65219-regulator.c | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/tps65219-regulator.c b/drivers/regulator/tps65219-regulator.c index bb4757a2042c..4b5acaa45049 100644 --- a/drivers/regulator/tps65219-regulator.c +++ b/drivers/regulator/tps65219-regulator.c @@ -173,24 +173,6 @@ static unsigned int tps65219_get_mode(struct regulator_dev *dev) return REGULATOR_MODE_NORMAL; } -/* - * generic regulator_set_bypass_regmap does not fully match requirements - * TPS65219 Requires explicitly that regulator is disabled before switch - */ -static int tps65219_set_bypass(struct regulator_dev *dev, bool enable) -{ - struct tps65219 *tps = rdev_get_drvdata(dev); - unsigned int rid = rdev_get_id(dev); - - if (dev->desc->ops->is_enabled(dev)) { - dev_err(tps->dev, - "%s LDO%d enabled, must be shut down to set bypass ", - __func__, rid); - return -EBUSY; - } - return regulator_set_bypass_regmap(dev, enable); -} - /* Operations permitted on BUCK1/2/3 */ static const struct regulator_ops tps65219_bucks_ops = { .is_enabled = regulator_is_enabled_regmap, @@ -217,7 +199,7 @@ static const struct regulator_ops tps65219_ldos_1_2_ops = { .set_voltage_sel = regulator_set_voltage_sel_regmap, .list_voltage = regulator_list_voltage_linear_range, .map_voltage = regulator_map_voltage_linear_range, - .set_bypass = tps65219_set_bypass, + .set_bypass = regulator_set_bypass_regmap, .get_bypass = regulator_get_bypass_regmap, }; -- cgit v1.2.3 From 6caacd82f09c183a91951776cd8d326e46ef84b4 Mon Sep 17 00:00:00 2001 From: Naresh Solanki Date: Fri, 10 Feb 2023 17:32:25 +0100 Subject: regulator: max597x: Remove unused variable max597x_regmap_config isn't used & hence remove the same. Signed-off-by: Naresh Solanki Link: https://lore.kernel.org/r/20230210163225.1208035-1-Naresh.Solanki@9elements.com Signed-off-by: Mark Brown --- drivers/regulator/max597x-regulator.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/max597x-regulator.c b/drivers/regulator/max597x-regulator.c index 39f803ff0a90..ab9dc18f98e3 100644 --- a/drivers/regulator/max597x-regulator.c +++ b/drivers/regulator/max597x-regulator.c @@ -357,12 +357,6 @@ static int max597x_irq_handler(int irq, struct regulator_irq_data *rid, return 0; } -static const struct regmap_config max597x_regmap_config = { - .reg_bits = 8, - .val_bits = 8, - .max_register = MAX_REGISTERS, -}; - static int max597x_adc_range(struct regmap *regmap, const int ch, u32 *irng, u32 *mon_rng) { -- cgit v1.2.3 From 9d1c73191f94c79076b5f46a31b8a1e12b18bc79 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 11 Feb 2023 23:00:19 +0800 Subject: regulator: max20411: Fix off-by-one for n_voltages setting Otherwise regulator_list_voltage returns -EINVAL for MAX20411_MAX_SEL. Signed-off-by: Axel Lin Link: https://lore.kernel.org/r/20230211150019.1545542-1-axel.lin@ingics.com Signed-off-by: Mark Brown --- drivers/regulator/max20411-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/max20411-regulator.c b/drivers/regulator/max20411-regulator.c index e75d16048e2f..83dacb4ff173 100644 --- a/drivers/regulator/max20411-regulator.c +++ b/drivers/regulator/max20411-regulator.c @@ -85,7 +85,7 @@ static const struct regulator_desc max20411_desc = { .min_uV = MAX20411_BASE_UV, .uV_step = MAX20411_UV_STEP, .linear_min_sel = MAX20411_MIN_SEL, - .n_voltages = MAX20411_MAX_SEL, + .n_voltages = MAX20411_MAX_SEL + 1, .vsel_reg = MAX20411_VID_OFFSET, .vsel_mask = MAX20411_VID_MASK, -- cgit v1.2.3 From 7f62cb8861190e7cc1018ff37597fc49b2eaafa8 Mon Sep 17 00:00:00 2001 From: Naresh Solanki Date: Thu, 16 Feb 2023 08:53:01 +0100 Subject: regulator: max597x: Align for simple_mfd_i2c driver Use regmap provided by simple_mfd_i2c driver and remove unused variable. Identify device variant by checking compatible property in DT. Signed-off-by: Naresh Solanki Link: https://lore.kernel.org/r/20230216075302.68935-1-Naresh.Solanki@9elements.com Signed-off-by: Mark Brown --- drivers/regulator/max597x-regulator.c | 46 ++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 14 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/max597x-regulator.c b/drivers/regulator/max597x-regulator.c index ab9dc18f98e3..f0fb0f56e420 100644 --- a/drivers/regulator/max597x-regulator.c +++ b/drivers/regulator/max597x-regulator.c @@ -425,41 +425,59 @@ static int max597x_setup_irq(struct device *dev, static int max597x_regulator_probe(struct platform_device *pdev) { - - - struct max597x_data *max597x = dev_get_drvdata(pdev->dev.parent); + struct max597x_data *max597x; + struct regmap *regmap = dev_get_regmap(pdev->dev.parent, NULL); struct max597x_regulator *data; - + struct i2c_client *i2c = to_i2c_client(pdev->dev.parent); struct regulator_config config = { }; struct regulator_dev *rdev; struct regulator_dev *rdevs[MAX5970_NUM_SWITCHES]; - int num_switches = max597x->num_switches; + int num_switches; int ret, i; + if (!regmap) + return -EPROBE_DEFER; + + max597x = devm_kzalloc(&i2c->dev, sizeof(struct max597x_data), GFP_KERNEL); + if (!max597x) + return -ENOMEM; + + i2c_set_clientdata(i2c, max597x); + + if (of_device_is_compatible(i2c->dev.of_node, "maxim,max5978")) + max597x->num_switches = MAX597x_TYPE_MAX5978; + else if (of_device_is_compatible(i2c->dev.of_node, "maxim,max5970")) + max597x->num_switches = MAX597x_TYPE_MAX5970; + else + return -ENODEV; + + i2c_set_clientdata(i2c, max597x); + num_switches = max597x->num_switches; + for (i = 0; i < num_switches; i++) { data = - devm_kzalloc(max597x->dev, sizeof(struct max597x_regulator), + devm_kzalloc(&i2c->dev, sizeof(struct max597x_regulator), GFP_KERNEL); if (!data) return -ENOMEM; data->num_switches = num_switches; - data->regmap = max597x->regmap; + data->regmap = regmap; - ret = max597x_adc_range(data->regmap, i, &max597x->irng[i], &max597x->mon_rng[i]); + ret = max597x_adc_range(regmap, i, &max597x->irng[i], &max597x->mon_rng[i]); if (ret < 0) return ret; data->irng = max597x->irng[i]; data->mon_rng = max597x->mon_rng[i]; - config.dev = max597x->dev; + config.dev = &i2c->dev; config.driver_data = (void *)data; config.regmap = data->regmap; - rdev = devm_regulator_register(max597x->dev, + rdev = devm_regulator_register(&i2c->dev, ®ulators[i], &config); if (IS_ERR(rdev)) { - dev_err(max597x->dev, "failed to register regulator %s\n", + dev_err(&i2c->dev, "failed to register regulator %s\n", regulators[i].name); return PTR_ERR(rdev); } @@ -467,12 +485,12 @@ static int max597x_regulator_probe(struct platform_device *pdev) max597x->shunt_micro_ohms[i] = data->shunt_micro_ohms; } - if (max597x->irq) { + if (i2c->irq) { ret = - max597x_setup_irq(max597x->dev, max597x->irq, rdevs, num_switches, + max597x_setup_irq(&i2c->dev, i2c->irq, rdevs, num_switches, data); if (ret) { - dev_err(max597x->dev, "IRQ setup failed"); + dev_err(&i2c->dev, "IRQ setup failed"); return ret; } } -- cgit v1.2.3