regulator: Fixes for v6.8

The main set of fixes here are for the PWM regulator, fixing
 bootstrapping issues on some platforms where the hardware setup looked
 like it was out of spec for the constraints we have for the regulator
 causing us to make spurious and unhelpful changes to try to bring things
 in line with the constraints.  There's also a couple of other driver
 specific fixes.
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAmW7hcYACgkQJNaLcl1U
 h9CWhgf/WJDxnyzxd4pp8hw68oPBQKetJkO4cS/syqb3az3HcKM7dnQkmK9LMgMq
 N9VxkraaYMNvnde4LZ7yg2cQgXaCstdFXAglECCJpKCUtibQqdpP+c9u0Yo8ENDE
 Sa/3desx9R0//rG36yX2XMtZb6WiZyqtz2At4WOlvx1xo3ajTr0yyGNaPLrBsu24
 Saft05gLSAdBUCKc9mR+QpXpooiG4FkBfGJ9cM9zWd5lu61TAsRdCTUvQmyykVXC
 O7JTH3mvpakjcaDZ2h+ntH54duG5CwhbvWea6tsBBaR6GI/tBlOG1GemJNrELgYU
 9hUve07VIO1DyTxpp2lANjBAiNo6Og==
 =BI0g
 -----END PGP SIGNATURE-----

Merge tag 'regulator-fix-v6.8-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator

Pull regulator fixes from Mark Brown:
 "The main set of fixes here are for the PWM regulator, fixing
  bootstrapping issues on some platforms where the hardware setup looked
  like it was out of spec for the constraints we have for the regulator
  causing us to make spurious and unhelpful changes to try to bring
  things in line with the constraints.

  There's also a couple of other driver specific fixes"

* tag 'regulator-fix-v6.8-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator:
  regulator (max5970): Fix IRQ handler
  regulator: ti-abb: don't use devm_platform_ioremap_resource_byname for shared interrupt register
  regulator: pwm-regulator: Manage boot-on with disabled PWM channels
  regulator: pwm-regulator: Calculate the output voltage for disabled PWMs
  regulator: pwm-regulator: Add validity checks in continuous .get_voltage
This commit is contained in:
Linus Torvalds 2024-02-01 10:06:55 -08:00
commit 4b561d1001
3 changed files with 63 additions and 4 deletions

View File

@ -392,7 +392,7 @@ static int max597x_regmap_read_clear(struct regmap *map, unsigned int reg,
return ret;
if (*val)
return regmap_write(map, reg, *val);
return regmap_write(map, reg, 0);
return 0;
}

View File

@ -157,7 +157,17 @@ static int pwm_regulator_get_voltage(struct regulator_dev *rdev)
pwm_get_state(drvdata->pwm, &pstate);
if (!pstate.enabled) {
if (pstate.polarity == PWM_POLARITY_INVERSED)
pstate.duty_cycle = pstate.period;
else
pstate.duty_cycle = 0;
}
voltage = pwm_get_relative_duty_cycle(&pstate, duty_unit);
if (voltage < min(max_uV_duty, min_uV_duty) ||
voltage > max(max_uV_duty, min_uV_duty))
return -ENOTRECOVERABLE;
/*
* The dutycycle for min_uV might be greater than the one for max_uV.
@ -313,6 +323,32 @@ static int pwm_regulator_init_continuous(struct platform_device *pdev,
return 0;
}
static int pwm_regulator_init_boot_on(struct platform_device *pdev,
struct pwm_regulator_data *drvdata,
const struct regulator_init_data *init_data)
{
struct pwm_state pstate;
if (!init_data->constraints.boot_on || drvdata->enb_gpio)
return 0;
pwm_get_state(drvdata->pwm, &pstate);
if (pstate.enabled)
return 0;
/*
* Update the duty cycle so the output does not change
* when the regulator core enables the regulator (and
* thus the PWM channel).
*/
if (pstate.polarity == PWM_POLARITY_INVERSED)
pstate.duty_cycle = pstate.period;
else
pstate.duty_cycle = 0;
return pwm_apply_might_sleep(drvdata->pwm, &pstate);
}
static int pwm_regulator_probe(struct platform_device *pdev)
{
const struct regulator_init_data *init_data;
@ -372,6 +408,13 @@ static int pwm_regulator_probe(struct platform_device *pdev)
if (ret)
return ret;
ret = pwm_regulator_init_boot_on(pdev, drvdata, init_data);
if (ret) {
dev_err(&pdev->dev, "Failed to apply boot_on settings: %d\n",
ret);
return ret;
}
regulator = devm_regulator_register(&pdev->dev,
&drvdata->desc, &config);
if (IS_ERR(regulator)) {

View File

@ -726,9 +726,25 @@ static int ti_abb_probe(struct platform_device *pdev)
return PTR_ERR(abb->setup_reg);
}
abb->int_base = devm_platform_ioremap_resource_byname(pdev, "int-address");
if (IS_ERR(abb->int_base))
return PTR_ERR(abb->int_base);
pname = "int-address";
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname);
if (!res) {
dev_err(dev, "Missing '%s' IO resource\n", pname);
return -ENODEV;
}
/*
* The MPU interrupt status register (PRM_IRQSTATUS_MPU) is
* shared between regulator-abb-{ivahd,dspeve,gpu} driver
* instances. Therefore use devm_ioremap() rather than
* devm_platform_ioremap_resource_byname() to avoid busy
* resource region conflicts.
*/
abb->int_base = devm_ioremap(dev, res->start,
resource_size(res));
if (!abb->int_base) {
dev_err(dev, "Unable to map '%s'\n", pname);
return -ENOMEM;
}
/* Map Optional resources */
pname = "efuse-address";