From a8d77166fcfe1cd4be70c21d65ff2b27b4f54a26 Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Thu, 14 Nov 2024 09:19:59 +0200 Subject: [PATCH 01/10] regulator: bd96801: Add ERRB IRQ The ROHM BD96801 "scalable PMIC" provides two physical IRQs. The ERRB handling can in many cases be omitted because it is used to inform fatal IRQs, which usually kill the power from the SOC. There may however be use-cases where the SOC has a 'back-up' emergency power source which allows some very short time of operation to try to gracefully shut down sensitive hardware. Furthermore, it is possible the processor controlling the PMIC is not powered by the PMIC. In such cases handling the ERRB IRQs may be beneficial. Add support for ERRB IRQs. Signed-off-by: Matti Vaittinen Reviewed-by: Mark Brown Link: https://patch.msgid.link/ZzWkny4lKpY09SX5@mva-rohm Signed-off-by: Mark Brown --- drivers/regulator/bd96801-regulator.c | 130 +++++++++++++++++++++++--- 1 file changed, 115 insertions(+), 15 deletions(-) diff --git a/drivers/regulator/bd96801-regulator.c b/drivers/regulator/bd96801-regulator.c index 9876cc05867e..3a9d772491a8 100644 --- a/drivers/regulator/bd96801-regulator.c +++ b/drivers/regulator/bd96801-regulator.c @@ -5,12 +5,7 @@ /* * This version of the "BD86801 scalable PMIC"'s driver supports only very * basic set of the PMIC features. Most notably, there is no support for - * the ERRB interrupt and the configurations which should be done when the - * PMIC is in STBY mode. - * - * Supporting the ERRB interrupt would require dropping the regmap-IRQ - * usage or working around (or accepting a presense of) a naming conflict - * in debugFS IRQs. + * the configurations which should be done when the PMIC is in STBY mode. * * Being able to reliably do the configurations like changing the * regulator safety limits (like limits for the over/under -voltages, over @@ -22,16 +17,14 @@ * be the need to configure these safety limits. Hence it's not simple to * come up with a generic solution. * - * Users who require the ERRB handling and STBY state configurations can - * have a look at the original RFC: + * Users who require the STBY state configurations can have a look at the + * original RFC: * https://lore.kernel.org/all/cover.1712920132.git.mazziesaccount@gmail.com/ - * which implements a workaround to debugFS naming conflict and some of - * the safety limit configurations - but leaves the state change handling - * and synchronization to be implemented. + * which implements some of the safety limit configurations - but leaves the + * state change handling and synchronization to be implemented. * * It would be great to hear (and receive a patch!) if you implement the - * STBY configuration support or a proper fix to the debugFS naming - * conflict in your downstream driver ;) + * STBY configuration support in your downstream driver ;) */ #include @@ -728,6 +721,95 @@ static int initialize_pmic_data(struct device *dev, return 0; } +static int bd96801_map_event_all(int irq, struct regulator_irq_data *rid, + unsigned long *dev_mask) +{ + int i; + + for (i = 0; i < rid->num_states; i++) { + rid->states[i].notifs = REGULATOR_EVENT_FAIL; + rid->states[i].errors = REGULATOR_ERROR_FAIL; + *dev_mask |= BIT(i); + } + + return 0; +} + +static int bd96801_rdev_errb_irqs(struct platform_device *pdev, + struct regulator_dev *rdev) +{ + int i; + void *retp; + static const char * const single_out_errb_irqs[] = { + "bd96801-%s-pvin-err", "bd96801-%s-ovp-err", + "bd96801-%s-uvp-err", "bd96801-%s-shdn-err", + }; + + for (i = 0; i < ARRAY_SIZE(single_out_errb_irqs); i++) { + struct regulator_irq_desc id = { + .map_event = bd96801_map_event_all, + .irq_off_ms = 1000, + }; + struct regulator_dev *rdev_arr[1]; + char tmp[255]; + int irq; + + snprintf(tmp, 255, single_out_errb_irqs[i], rdev->desc->name); + tmp[254] = 0; + id.name = tmp; + + irq = platform_get_irq_byname(pdev, tmp); + if (irq < 0) + continue; + + rdev_arr[0] = rdev; + retp = devm_regulator_irq_helper(&pdev->dev, &id, irq, 0, + REGULATOR_ERROR_FAIL, NULL, + rdev_arr, 1); + if (IS_ERR(retp)) + return PTR_ERR(retp); + + } + return 0; +} + +static int bd96801_global_errb_irqs(struct platform_device *pdev, + struct regulator_dev **rdev, int num_rdev) +{ + int i, num_irqs; + void *retp; + static const char * const global_errb_irqs[] = { + "bd96801-otp-err", "bd96801-dbist-err", "bd96801-eep-err", + "bd96801-abist-err", "bd96801-prstb-err", "bd96801-drmoserr1", + "bd96801-drmoserr2", "bd96801-slave-err", "bd96801-vref-err", + "bd96801-tsd", "bd96801-uvlo-err", "bd96801-ovlo-err", + "bd96801-osc-err", "bd96801-pon-err", "bd96801-poff-err", + "bd96801-cmd-shdn-err", "bd96801-int-shdn-err" + }; + + num_irqs = ARRAY_SIZE(global_errb_irqs); + for (i = 0; i < num_irqs; i++) { + int irq; + struct regulator_irq_desc id = { + .name = global_errb_irqs[i], + .map_event = bd96801_map_event_all, + .irq_off_ms = 1000, + }; + + irq = platform_get_irq_byname(pdev, global_errb_irqs[i]); + if (irq < 0) + continue; + + retp = devm_regulator_irq_helper(&pdev->dev, &id, irq, 0, + REGULATOR_ERROR_FAIL, NULL, + rdev, num_rdev); + if (IS_ERR(retp)) + return PTR_ERR(retp); + } + + return 0; +} + static int bd96801_rdev_intb_irqs(struct platform_device *pdev, struct bd96801_pmic_data *pdata, struct bd96801_irqinfo *iinfo, @@ -783,11 +865,10 @@ static int bd96801_rdev_intb_irqs(struct platform_device *pdev, return 0; } - - static int bd96801_probe(struct platform_device *pdev) { struct regulator_dev *ldo_errs_rdev_arr[BD96801_NUM_LDOS]; + struct regulator_dev *all_rdevs[BD96801_NUM_REGULATORS]; struct bd96801_regulator_data *rdesc; struct regulator_config config = {}; int ldo_errs_arr[BD96801_NUM_LDOS]; @@ -795,6 +876,7 @@ static int bd96801_probe(struct platform_device *pdev) int temp_notif_ldos = 0; struct device *parent; int i, ret; + bool use_errb; void *retp; parent = pdev->dev.parent; @@ -819,6 +901,13 @@ static int bd96801_probe(struct platform_device *pdev) config.regmap = pdata->regmap; config.dev = parent; + ret = of_property_match_string(pdev->dev.parent->of_node, + "interrupt-names", "errb"); + if (ret < 0) + use_errb = false; + else + use_errb = true; + ret = bd96801_walk_regulator_dt(&pdev->dev, pdata->regmap, rdesc, BD96801_NUM_REGULATORS); if (ret) @@ -837,6 +926,7 @@ static int bd96801_probe(struct platform_device *pdev) rdesc[i].desc.name); return PTR_ERR(rdev); } + all_rdevs[i] = rdev; /* * LDOs don't have own temperature monitoring. If temperature * notification was requested for this LDO from DT then we will @@ -856,6 +946,12 @@ static int bd96801_probe(struct platform_device *pdev) if (ret) return ret; } + /* Register per regulator ERRB notifiers */ + if (use_errb) { + ret = bd96801_rdev_errb_irqs(pdev, rdev); + if (ret) + return ret; + } } if (temp_notif_ldos) { int irq; @@ -877,6 +973,10 @@ static int bd96801_probe(struct platform_device *pdev) return PTR_ERR(retp); } + if (use_errb) + return bd96801_global_errb_irqs(pdev, all_rdevs, + ARRAY_SIZE(all_rdevs)); + return 0; } From 229773f90b1f886e8fd542f98b495c66e43be5ba Mon Sep 17 00:00:00 2001 From: Robin Gong Date: Thu, 5 Dec 2024 11:51:09 -0500 Subject: [PATCH 02/10] regulator: pca9450: add enable_value for all bucks Set 'enable_value' in the regulator descriptor for different bucks to manage their enable modes: - 00b: OFF - 01b: ON when PMIC_ON_REQ = H - 10b: ON when PMIC_ON_REQ = H && PMIC_STBY_REQ = L - 11b: Always ON Ensure appropriate behavior based on the intended design. For example: - Buck2, designed for vddarm, should be set to '10b' (ON when PMIC_STBY_REQ = L) since it can be off when `PMIC_STBY_REQ = H` after the kernel enters suspend. - Other bucks remain '01b' (ON when PMIC_ON_REQ = H), matching the default setting. This avoids the need to re-enable them during kernel boot as they are already enabled after PMIC initialization. Signed-off-by: Robin Gong Signed-off-by: Frank Li Link: https://patch.msgid.link/20241205-pca9450-v1-1-aab448b74e78@nxp.com Signed-off-by: Mark Brown --- drivers/regulator/pca9450-regulator.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/regulator/pca9450-regulator.c b/drivers/regulator/pca9450-regulator.c index 9714afe347dc..caeeed433165 100644 --- a/drivers/regulator/pca9450-regulator.c +++ b/drivers/regulator/pca9450-regulator.c @@ -247,6 +247,7 @@ static const struct pca9450_regulator_desc pca9450a_regulators[] = { .ramp_mask = BUCK1_RAMP_MASK, .ramp_delay_table = pca9450_dvs_buck_ramp_table, .n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table), + .enable_val = BUCK_ENMODE_ONREQ, .owner = THIS_MODULE, .of_parse_cb = pca9450_set_dvs_levels, }, @@ -272,6 +273,7 @@ static const struct pca9450_regulator_desc pca9450a_regulators[] = { .vsel_mask = BUCK2OUT_DVS0_MASK, .enable_reg = PCA9450_REG_BUCK2CTRL, .enable_mask = BUCK2_ENMODE_MASK, + .enable_val = BUCK_ENMODE_ONREQ_STBYREQ, .ramp_reg = PCA9450_REG_BUCK2CTRL, .ramp_mask = BUCK2_RAMP_MASK, .ramp_delay_table = pca9450_dvs_buck_ramp_table, @@ -301,6 +303,7 @@ static const struct pca9450_regulator_desc pca9450a_regulators[] = { .vsel_mask = BUCK3OUT_DVS0_MASK, .enable_reg = PCA9450_REG_BUCK3CTRL, .enable_mask = BUCK3_ENMODE_MASK, + .enable_val = BUCK_ENMODE_ONREQ, .ramp_reg = PCA9450_REG_BUCK3CTRL, .ramp_mask = BUCK3_RAMP_MASK, .ramp_delay_table = pca9450_dvs_buck_ramp_table, @@ -330,6 +333,7 @@ static const struct pca9450_regulator_desc pca9450a_regulators[] = { .vsel_mask = BUCK4OUT_MASK, .enable_reg = PCA9450_REG_BUCK4CTRL, .enable_mask = BUCK4_ENMODE_MASK, + .enable_val = BUCK_ENMODE_ONREQ, .owner = THIS_MODULE, }, }, @@ -348,6 +352,7 @@ static const struct pca9450_regulator_desc pca9450a_regulators[] = { .vsel_mask = BUCK5OUT_MASK, .enable_reg = PCA9450_REG_BUCK5CTRL, .enable_mask = BUCK5_ENMODE_MASK, + .enable_val = BUCK_ENMODE_ONREQ, .owner = THIS_MODULE, }, }, @@ -366,6 +371,7 @@ static const struct pca9450_regulator_desc pca9450a_regulators[] = { .vsel_mask = BUCK6OUT_MASK, .enable_reg = PCA9450_REG_BUCK6CTRL, .enable_mask = BUCK6_ENMODE_MASK, + .enable_val = BUCK_ENMODE_ONREQ, .owner = THIS_MODULE, }, }, @@ -481,6 +487,7 @@ static const struct pca9450_regulator_desc pca9450bc_regulators[] = { .vsel_mask = BUCK1OUT_DVS0_MASK, .enable_reg = PCA9450_REG_BUCK1CTRL, .enable_mask = BUCK1_ENMODE_MASK, + .enable_val = BUCK_ENMODE_ONREQ, .ramp_reg = PCA9450_REG_BUCK1CTRL, .ramp_mask = BUCK1_RAMP_MASK, .ramp_delay_table = pca9450_dvs_buck_ramp_table, @@ -510,6 +517,7 @@ static const struct pca9450_regulator_desc pca9450bc_regulators[] = { .vsel_mask = BUCK2OUT_DVS0_MASK, .enable_reg = PCA9450_REG_BUCK2CTRL, .enable_mask = BUCK2_ENMODE_MASK, + .enable_val = BUCK_ENMODE_ONREQ_STBYREQ, .ramp_reg = PCA9450_REG_BUCK2CTRL, .ramp_mask = BUCK2_RAMP_MASK, .ramp_delay_table = pca9450_dvs_buck_ramp_table, @@ -539,6 +547,7 @@ static const struct pca9450_regulator_desc pca9450bc_regulators[] = { .vsel_mask = BUCK4OUT_MASK, .enable_reg = PCA9450_REG_BUCK4CTRL, .enable_mask = BUCK4_ENMODE_MASK, + .enable_val = BUCK_ENMODE_ONREQ, .owner = THIS_MODULE, }, }, @@ -557,6 +566,7 @@ static const struct pca9450_regulator_desc pca9450bc_regulators[] = { .vsel_mask = BUCK5OUT_MASK, .enable_reg = PCA9450_REG_BUCK5CTRL, .enable_mask = BUCK5_ENMODE_MASK, + .enable_val = BUCK_ENMODE_ONREQ, .owner = THIS_MODULE, }, }, @@ -575,6 +585,7 @@ static const struct pca9450_regulator_desc pca9450bc_regulators[] = { .vsel_mask = BUCK6OUT_MASK, .enable_reg = PCA9450_REG_BUCK6CTRL, .enable_mask = BUCK6_ENMODE_MASK, + .enable_val = BUCK_ENMODE_ONREQ, .owner = THIS_MODULE, }, }, From 0f5c601098bd3c9cdfea3e01aacdd9d0c4010ea7 Mon Sep 17 00:00:00 2001 From: Frank Li Date: Thu, 5 Dec 2024 11:51:10 -0500 Subject: [PATCH 03/10] regulator: pca9450: Use dev_err_probe() to simplify code Use dev_err_probe() to simplify code. Signed-off-by: Frank Li Link: https://patch.msgid.link/20241205-pca9450-v1-2-aab448b74e78@nxp.com Signed-off-by: Mark Brown --- drivers/regulator/pca9450-regulator.c | 73 ++++++++++----------------- 1 file changed, 27 insertions(+), 46 deletions(-) diff --git a/drivers/regulator/pca9450-regulator.c b/drivers/regulator/pca9450-regulator.c index caeeed433165..0b1f099fdd5e 100644 --- a/drivers/regulator/pca9450-regulator.c +++ b/drivers/regulator/pca9450-regulator.c @@ -932,25 +932,20 @@ static int pca9450_i2c_probe(struct i2c_client *i2c) pca9450->regmap = devm_regmap_init_i2c(i2c, &pca9450_regmap_config); - if (IS_ERR(pca9450->regmap)) { - dev_err(&i2c->dev, "regmap initialization failed\n"); - return PTR_ERR(pca9450->regmap); - } + if (IS_ERR(pca9450->regmap)) + return dev_err_probe(&i2c->dev, PTR_ERR(pca9450->regmap), + "regmap initialization failed\n"); ret = regmap_read(pca9450->regmap, PCA9450_REG_DEV_ID, &device_id); - if (ret) { - dev_err(&i2c->dev, "Read device id error\n"); - return ret; - } + if (ret) + return dev_err_probe(&i2c->dev, ret, "Read device id error\n"); /* Check your board and dts for match the right pmic */ if (((device_id >> 4) != 0x1 && type == PCA9450_TYPE_PCA9450A) || ((device_id >> 4) != 0x3 && type == PCA9450_TYPE_PCA9450BC) || - ((device_id >> 4) != 0x9 && type == PCA9450_TYPE_PCA9451A)) { - dev_err(&i2c->dev, "Device id(%x) mismatched\n", - device_id >> 4); - return -EINVAL; - } + ((device_id >> 4) != 0x9 && type == PCA9450_TYPE_PCA9451A)) + return dev_err_probe(&i2c->dev, -EINVAL, + "Device id(%x) mismatched\n", device_id >> 4); for (i = 0; i < pca9450->rcnt; i++) { const struct regulator_desc *desc; @@ -964,13 +959,9 @@ static int pca9450_i2c_probe(struct i2c_client *i2c) config.dev = pca9450->dev; rdev = devm_regulator_register(pca9450->dev, desc, &config); - if (IS_ERR(rdev)) { - ret = PTR_ERR(rdev); - dev_err(pca9450->dev, - "Failed to register regulator(%s): %d\n", - desc->name, ret); - return ret; - } + if (IS_ERR(rdev)) + return dev_err_probe(pca9450->dev, PTR_ERR(rdev), + "Failed to register regulator(%s)\n", desc->name); } if (pca9450->irq) { @@ -978,29 +969,24 @@ static int pca9450_i2c_probe(struct i2c_client *i2c) pca9450_irq_handler, (IRQF_TRIGGER_FALLING | IRQF_ONESHOT), "pca9450-irq", pca9450); - if (ret != 0) { - dev_err(pca9450->dev, "Failed to request IRQ: %d\n", - pca9450->irq); - return ret; - } + if (ret != 0) + return dev_err_probe(pca9450->dev, ret, "Failed to request IRQ: %d\n", + pca9450->irq); + /* Unmask all interrupt except PWRON/WDOG/RSVD */ ret = regmap_update_bits(pca9450->regmap, PCA9450_REG_INT1_MSK, IRQ_VR_FLT1 | IRQ_VR_FLT2 | IRQ_LOWVSYS | IRQ_THERM_105 | IRQ_THERM_125, IRQ_PWRON | IRQ_WDOGB | IRQ_RSVD); - if (ret) { - dev_err(&i2c->dev, "Unmask irq error\n"); - return ret; - } + if (ret) + return dev_err_probe(&i2c->dev, ret, "Unmask irq error\n"); } /* Clear PRESET_EN bit in BUCK123_DVS to use DVS registers */ ret = regmap_clear_bits(pca9450->regmap, PCA9450_REG_BUCK123_DVS, BUCK123_PRESET_EN); - if (ret) { - dev_err(&i2c->dev, "Failed to clear PRESET_EN bit: %d\n", ret); - return ret; - } + if (ret) + return dev_err_probe(&i2c->dev, ret, "Failed to clear PRESET_EN bit\n"); if (of_property_read_bool(i2c->dev.of_node, "nxp,wdog_b-warm-reset")) reset_ctrl = WDOG_B_CFG_WARM; @@ -1010,20 +996,16 @@ static int pca9450_i2c_probe(struct i2c_client *i2c) /* Set reset behavior on assertion of WDOG_B signal */ ret = regmap_update_bits(pca9450->regmap, PCA9450_REG_RESET_CTRL, WDOG_B_CFG_MASK, reset_ctrl); - if (ret) { - dev_err(&i2c->dev, "Failed to set WDOG_B reset behavior\n"); - return ret; - } + if (ret) + return dev_err_probe(&i2c->dev, ret, "Failed to set WDOG_B reset behavior\n"); if (of_property_read_bool(i2c->dev.of_node, "nxp,i2c-lt-enable")) { /* Enable I2C Level Translator */ ret = regmap_update_bits(pca9450->regmap, PCA9450_REG_CONFIG2, I2C_LT_MASK, I2C_LT_ON_STANDBY_RUN); - if (ret) { - dev_err(&i2c->dev, - "Failed to enable I2C level translator\n"); - return ret; - } + if (ret) + return dev_err_probe(&i2c->dev, ret, + "Failed to enable I2C level translator\n"); } /* @@ -1033,10 +1015,9 @@ static int pca9450_i2c_probe(struct i2c_client *i2c) */ pca9450->sd_vsel_gpio = gpiod_get_optional(pca9450->dev, "sd-vsel", GPIOD_OUT_HIGH); - if (IS_ERR(pca9450->sd_vsel_gpio)) { - dev_err(&i2c->dev, "Failed to get SD_VSEL GPIO\n"); - return PTR_ERR(pca9450->sd_vsel_gpio); - } + if (IS_ERR(pca9450->sd_vsel_gpio)) + return dev_err_probe(&i2c->dev, PTR_ERR(pca9450->sd_vsel_gpio), + "Failed to get SD_VSEL GPIO\n"); dev_info(&i2c->dev, "%s probed.\n", type == PCA9450_TYPE_PCA9450A ? "pca9450a" : From 17b531c162e5dbdce9a184ccd1c730ae3f31576b Mon Sep 17 00:00:00 2001 From: Joy Zou Date: Thu, 5 Dec 2024 11:51:11 -0500 Subject: [PATCH 04/10] regulator: dt-bindings: pca9450: Add pca9452 support Add compatible string 'nxp,pca9452'. pca9452 add 'ldo3' compared with pca9451a. Signed-off-by: Joy Zou Signed-off-by: Frank Li Link: https://patch.msgid.link/20241205-pca9450-v1-3-aab448b74e78@nxp.com Acked-by: Conor Dooley Signed-off-by: Mark Brown --- .../devicetree/bindings/regulator/nxp,pca9450-regulator.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml b/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml index f8057bba747a..68709a7dc43f 100644 --- a/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/nxp,pca9450-regulator.yaml @@ -29,6 +29,7 @@ properties: - nxp,pca9450b - nxp,pca9450c - nxp,pca9451a + - nxp,pca9452 reg: maxItems: 1 From 017b76fb8e5b6066f6791e7ad2387deb2c9c9a14 Mon Sep 17 00:00:00 2001 From: Joy Zou Date: Thu, 5 Dec 2024 11:51:12 -0500 Subject: [PATCH 05/10] regulator: pca9450: Add PMIC pca9452 support Add the PMIC pca9452 support, which add ldo3 compared with pca9451a. Signed-off-by: Joy Zou Signed-off-by: Frank Li Link: https://patch.msgid.link/20241205-pca9450-v1-4-aab448b74e78@nxp.com Signed-off-by: Mark Brown --- drivers/regulator/pca9450-regulator.c | 29 ++++++++++++++++++++++++++- include/linux/regulator/pca9450.h | 1 + 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/drivers/regulator/pca9450-regulator.c b/drivers/regulator/pca9450-regulator.c index 0b1f099fdd5e..faa6b79c27d7 100644 --- a/drivers/regulator/pca9450-regulator.c +++ b/drivers/regulator/pca9450-regulator.c @@ -815,6 +815,24 @@ static const struct pca9450_regulator_desc pca9451a_regulators[] = { .owner = THIS_MODULE, }, }, + { + .desc = { + .name = "ldo3", + .of_match = of_match_ptr("LDO3"), + .regulators_node = of_match_ptr("regulators"), + .id = PCA9450_LDO3, + .ops = &pca9450_ldo_regulator_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = PCA9450_LDO3_VOLTAGE_NUM, + .linear_ranges = pca9450_ldo34_volts, + .n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts), + .vsel_reg = PCA9450_REG_LDO3CTRL, + .vsel_mask = LDO3OUT_MASK, + .enable_reg = PCA9450_REG_LDO3CTRL, + .enable_mask = LDO3_EN_MASK, + .owner = THIS_MODULE, + }, + }, { .desc = { .name = "ldo4", @@ -916,6 +934,7 @@ static int pca9450_i2c_probe(struct i2c_client *i2c) pca9450->rcnt = ARRAY_SIZE(pca9450bc_regulators); break; case PCA9450_TYPE_PCA9451A: + case PCA9450_TYPE_PCA9452: regulator_desc = pca9451a_regulators; pca9450->rcnt = ARRAY_SIZE(pca9451a_regulators); break; @@ -943,7 +962,8 @@ static int pca9450_i2c_probe(struct i2c_client *i2c) /* Check your board and dts for match the right pmic */ if (((device_id >> 4) != 0x1 && type == PCA9450_TYPE_PCA9450A) || ((device_id >> 4) != 0x3 && type == PCA9450_TYPE_PCA9450BC) || - ((device_id >> 4) != 0x9 && type == PCA9450_TYPE_PCA9451A)) + ((device_id >> 4) != 0x9 && type == PCA9450_TYPE_PCA9451A) || + ((device_id >> 4) != 0x9 && type == PCA9450_TYPE_PCA9452)) return dev_err_probe(&i2c->dev, -EINVAL, "Device id(%x) mismatched\n", device_id >> 4); @@ -955,6 +975,9 @@ static int pca9450_i2c_probe(struct i2c_client *i2c) r = ®ulator_desc[i]; desc = &r->desc; + if (type == PCA9450_TYPE_PCA9451A && !strcmp(desc->name, "ldo3")) + continue; + config.regmap = pca9450->regmap; config.dev = pca9450->dev; @@ -1043,6 +1066,10 @@ static const struct of_device_id pca9450_of_match[] = { .compatible = "nxp,pca9451a", .data = (void *)PCA9450_TYPE_PCA9451A, }, + { + .compatible = "nxp,pca9452", + .data = (void *)PCA9450_TYPE_PCA9452, + }, { } }; MODULE_DEVICE_TABLE(of, pca9450_of_match); diff --git a/include/linux/regulator/pca9450.h b/include/linux/regulator/pca9450.h index 243633c8dceb..b427b5873de1 100644 --- a/include/linux/regulator/pca9450.h +++ b/include/linux/regulator/pca9450.h @@ -10,6 +10,7 @@ enum pca9450_chip_type { PCA9450_TYPE_PCA9450A = 0, PCA9450_TYPE_PCA9450BC, PCA9450_TYPE_PCA9451A, + PCA9450_TYPE_PCA9452, PCA9450_TYPE_AMOUNT, }; From 08242719a8af603db54a2a79234a8fe600680105 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Wed, 11 Dec 2024 13:24:19 +0800 Subject: [PATCH 06/10] regulator: dt-bindings: mt6315: Drop regulator-compatible property The "regulator-compatible" property has been deprecated since 2012 in commit 13511def87b9 ("regulator: deprecate regulator-compatible DT property"), which is so old it's not even mentioned in the converted regulator bindings YAML file. It should not have been used for new submissions such as the MT6315. Drop the property from the MT6315 regulator binding and its examples. Fixes: 977fb5b58469 ("regulator: document binding for MT6315 regulator") Fixes: 6d435a94ba5b ("regulator: mt6315: Enforce regulator-compatible, not name") Signed-off-by: Chen-Yu Tsai Reviewed-by: AngeloGioacchino Del Regno Link: https://patch.msgid.link/20241211052427.4178367-2-wenst@chromium.org Signed-off-by: Mark Brown --- .../devicetree/bindings/regulator/mt6315-regulator.yaml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Documentation/devicetree/bindings/regulator/mt6315-regulator.yaml b/Documentation/devicetree/bindings/regulator/mt6315-regulator.yaml index cd4aa27218a1..fa6743bb269d 100644 --- a/Documentation/devicetree/bindings/regulator/mt6315-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/mt6315-regulator.yaml @@ -35,10 +35,6 @@ properties: $ref: regulator.yaml# unevaluatedProperties: false - properties: - regulator-compatible: - pattern: "^vbuck[1-4]$" - additionalProperties: false required: @@ -56,7 +52,6 @@ examples: regulators { vbuck1 { - regulator-compatible = "vbuck1"; regulator-min-microvolt = <300000>; regulator-max-microvolt = <1193750>; regulator-enable-ramp-delay = <256>; @@ -64,7 +59,6 @@ examples: }; vbuck3 { - regulator-compatible = "vbuck3"; regulator-min-microvolt = <300000>; regulator-max-microvolt = <1193750>; regulator-enable-ramp-delay = <256>; From e7ce0437709552a5f5e577c29f3dfde620153913 Mon Sep 17 00:00:00 2001 From: Shree Ramamoorthy Date: Tue, 17 Dec 2024 14:45:23 -0600 Subject: [PATCH 07/10] regulator: tps65219: Use dev_err_probe() instead of dev_err() Make the error message format unified by switching from dev_err() to dev_err_probe() where there is a chance of -EPROBE_DEFER returned. This helps simplify the error code where possible. Signed-off-by: Shree Ramamoorthy Link: https://patch.msgid.link/20241217204526.1010989-2-s-ramamoorthy@ti.com Signed-off-by: Mark Brown --- drivers/regulator/tps65219-regulator.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/regulator/tps65219-regulator.c b/drivers/regulator/tps65219-regulator.c index b4065356392f..14d843a99d0f 100644 --- a/drivers/regulator/tps65219-regulator.c +++ b/drivers/regulator/tps65219-regulator.c @@ -322,11 +322,11 @@ static int tps65219_regulator_probe(struct platform_device *pdev) dev_dbg(tps->dev, "%s regul i= %d START", __func__, i); rdev = devm_regulator_register(&pdev->dev, ®ulators[i], &config); - if (IS_ERR(rdev)) { - dev_err(tps->dev, "failed to register %s regulator\n", - regulators[i].name); - return PTR_ERR(rdev); - } + if (IS_ERR(rdev)) + return dev_err_probe(tps->dev, PTR_ERR(rdev), + "Failed to register %s regulator\n", + regulators[i].name); + rdevtbl[i] = rdev; dev_dbg(tps->dev, "%s regul i= %d COMPLETED", __func__, i); } From 2ef8310c464cac41a024fc6fd2910e51f10a38e7 Mon Sep 17 00:00:00 2001 From: Shree Ramamoorthy Date: Tue, 17 Dec 2024 14:45:24 -0600 Subject: [PATCH 08/10] regulator: tps65219: Update driver name Follow the same naming convention in tps6594-regulator.c with tpsxxx-regulator instead of tpsxxx-pmic. Signed-off-by: Shree Ramamoorthy Link: https://patch.msgid.link/20241217204526.1010989-3-s-ramamoorthy@ti.com Signed-off-by: Mark Brown --- drivers/regulator/tps65219-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/tps65219-regulator.c b/drivers/regulator/tps65219-regulator.c index 14d843a99d0f..5decf69f327a 100644 --- a/drivers/regulator/tps65219-regulator.c +++ b/drivers/regulator/tps65219-regulator.c @@ -379,7 +379,7 @@ MODULE_DEVICE_TABLE(platform, tps65219_regulator_id_table); static struct platform_driver tps65219_regulator_driver = { .driver = { - .name = "tps65219-pmic", + .name = "tps65219-regulator", .probe_type = PROBE_PREFER_ASYNCHRONOUS, }, .probe = tps65219_regulator_probe, From ca321ef98b80eb282a4dcdd5231f666c610b0575 Mon Sep 17 00:00:00 2001 From: Shree Ramamoorthy Date: Tue, 17 Dec 2024 14:45:25 -0600 Subject: [PATCH 09/10] regulator: tps65219: Remove MODULE_ALIAS Remove MODULE_ALIAS because the same module alias is already generated by MODULE_DEVICE_TABLE. Signed-off-by: Shree Ramamoorthy Link: https://patch.msgid.link/20241217204526.1010989-4-s-ramamoorthy@ti.com Signed-off-by: Mark Brown --- drivers/regulator/tps65219-regulator.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/regulator/tps65219-regulator.c b/drivers/regulator/tps65219-regulator.c index 5decf69f327a..f57a046f9dea 100644 --- a/drivers/regulator/tps65219-regulator.c +++ b/drivers/regulator/tps65219-regulator.c @@ -390,5 +390,4 @@ module_platform_driver(tps65219_regulator_driver); MODULE_AUTHOR("Jerome Neanne "); MODULE_DESCRIPTION("TPS65219 voltage regulator driver"); -MODULE_ALIAS("platform:tps65219-pmic"); MODULE_LICENSE("GPL"); From 64a6b577490c1c71f1a3bbdb3844717815214621 Mon Sep 17 00:00:00 2001 From: Shree Ramamoorthy Date: Tue, 17 Dec 2024 14:45:26 -0600 Subject: [PATCH 10/10] regulator: tps65219: Remove debugging helper function This helper function is primarily used by developers for debugging & is not a standard feature included in other PMIC drivers. The purpose of debugging function is to check if rdev is determine if the regulator has been registered prior to requesting a threaded irq. This case is already handled with the ISERR(rdev) check because the error code is returned. Signed-off-by: Shree Ramamoorthy Link: https://patch.msgid.link/20241217204526.1010989-5-s-ramamoorthy@ti.com Signed-off-by: Mark Brown --- drivers/regulator/tps65219-regulator.c | 28 -------------------------- 1 file changed, 28 deletions(-) diff --git a/drivers/regulator/tps65219-regulator.c b/drivers/regulator/tps65219-regulator.c index f57a046f9dea..aa65077f9d41 100644 --- a/drivers/regulator/tps65219-regulator.c +++ b/drivers/regulator/tps65219-regulator.c @@ -287,21 +287,6 @@ static irqreturn_t tps65219_regulator_irq_handler(int irq, void *data) return IRQ_HANDLED; } -static int tps65219_get_rdev_by_name(const char *regulator_name, - struct regulator_dev *rdevtbl[7], - struct regulator_dev **dev) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(regulators); i++) { - if (strcmp(regulator_name, regulators[i].name) == 0) { - *dev = rdevtbl[i]; - return 0; - } - } - return -EINVAL; -} - static int tps65219_regulator_probe(struct platform_device *pdev) { struct tps65219 *tps = dev_get_drvdata(pdev->dev.parent); @@ -312,23 +297,18 @@ static int tps65219_regulator_probe(struct platform_device *pdev) int irq; struct tps65219_regulator_irq_data *irq_data; struct tps65219_regulator_irq_type *irq_type; - struct regulator_dev *rdevtbl[7]; config.dev = tps->dev; config.driver_data = tps; config.regmap = tps->regmap; for (i = 0; i < ARRAY_SIZE(regulators); i++) { - dev_dbg(tps->dev, "%s regul i= %d START", __func__, i); rdev = devm_regulator_register(&pdev->dev, ®ulators[i], &config); if (IS_ERR(rdev)) return dev_err_probe(tps->dev, PTR_ERR(rdev), "Failed to register %s regulator\n", regulators[i].name); - - rdevtbl[i] = rdev; - dev_dbg(tps->dev, "%s regul i= %d COMPLETED", __func__, i); } irq_data = devm_kmalloc(tps->dev, @@ -348,14 +328,6 @@ static int tps65219_regulator_probe(struct platform_device *pdev) irq_data[i].dev = tps->dev; irq_data[i].type = irq_type; - tps65219_get_rdev_by_name(irq_type->regulator_name, rdevtbl, &rdev); - if (IS_ERR(rdev)) { - dev_err(tps->dev, "Failed to get rdev for %s\n", - irq_type->regulator_name); - return -EINVAL; - } - irq_data[i].rdev = rdev; - error = devm_request_threaded_irq(tps->dev, irq, NULL, tps65219_regulator_irq_handler, IRQF_ONESHOT,