regulator: Fixes for v4.2

As well as some driver specific fixes there's several fixes here for the
 core support for regulators supplying other regulators fixing both an
 issue with ACPI support (which had never been tested before) and some
 error handling and device removal issues that Javier noticed.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQEcBAABAgAGBQJVsm+oAAoJECTWi3JdVIfQsZoH/11WTUvq1YY6nv/3CM14owjH
 LXUQmPR2lSj0PTQJUpbQm4Rk9007NPoArehlv+5UFBwmrW1uxt1F7/YrLqc7hcUO
 ZPnL6IBUjuilU2yWBfJ+eK9QZyhBBfG+KbkSQy+ot6K+hdMH8RvYNF9ls7O5gCVP
 iFADtO/hCahFAk9Y/iShGM4aY+cvNILPS88Ahqg3luTSc+JMQ6khhUYJiIV86xUQ
 5T6Wu0JUZtKd4+SAPU0OtPnFOksTGB5RBKfnGi9/cDdv04JN6tETT54e8aEyQFfQ
 uSHTsvZIvZgA0TmCqgmRWwSIujt2wZAm/SBNs0SLawyWLQsrnEvHlpBXwRZD3Us=
 =uoMw
 -----END PGP SIGNATURE-----

Merge tag 'regulator-fix-v4.2-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator

Pull regulator fixes from Mark Brown:
 "As well as some driver specific fixes there's several fixes here for
  the core support for regulators supplying other regulators fixing both
  an issue with ACPI support (which had never been tested before) and
  some error handling and device removal issues that Javier noticed"

* tag 'regulator-fix-v4.2-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator:
  regulator: core: Fix memory leak in regulator_resolve_supply()
  regulator: core: Increase refcount for regulator supply's module
  regulator: core: Handle full constraints systems when resolving supplies
  regulator: 88pm800: fix LDO vsel_mask value
  regulator: max8973: Fix up control flag option for bias control
  regulator: s2mps11: Fix GPIO suspend enable shift wrapping bug
This commit is contained in:
Linus Torvalds 2015-07-24 13:14:06 -07:00
commit afdf0b91bd
4 changed files with 27 additions and 10 deletions

View File

@ -130,7 +130,7 @@ struct pm800_regulators {
.owner = THIS_MODULE, \
.n_voltages = ARRAY_SIZE(ldo_volt_table), \
.vsel_reg = PM800_##vreg##_VOUT, \
.vsel_mask = 0x1f, \
.vsel_mask = 0xf, \
.enable_reg = PM800_##ereg, \
.enable_mask = 1 << (ebit), \
.volt_table = ldo_volt_table, \

View File

@ -109,6 +109,7 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
static struct regulator *create_regulator(struct regulator_dev *rdev,
struct device *dev,
const char *supply_name);
static void _regulator_put(struct regulator *regulator);
static const char *rdev_get_name(struct regulator_dev *rdev)
{
@ -1105,6 +1106,9 @@ static int set_supply(struct regulator_dev *rdev,
rdev_info(rdev, "supplied by %s\n", rdev_get_name(supply_rdev));
if (!try_module_get(supply_rdev->owner))
return -ENODEV;
rdev->supply = create_regulator(supply_rdev, &rdev->dev, "SUPPLY");
if (rdev->supply == NULL) {
err = -ENOMEM;
@ -1381,9 +1385,13 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
}
if (!r) {
dev_err(dev, "Failed to resolve %s-supply for %s\n",
rdev->supply_name, rdev->desc->name);
return -EPROBE_DEFER;
if (have_full_constraints()) {
r = dummy_regulator_rdev;
} else {
dev_err(dev, "Failed to resolve %s-supply for %s\n",
rdev->supply_name, rdev->desc->name);
return -EPROBE_DEFER;
}
}
/* Recursively resolve the supply of the supply */
@ -1398,8 +1406,11 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
/* Cascade always-on state to supply */
if (_regulator_is_enabled(rdev)) {
ret = regulator_enable(rdev->supply);
if (ret < 0)
if (ret < 0) {
if (rdev->supply)
_regulator_put(rdev->supply);
return ret;
}
}
return 0;

View File

@ -450,7 +450,7 @@ static struct max8973_regulator_platform_data *max8973_parse_dt(
pdata->control_flags |= MAX8973_CONTROL_FREQ_SHIFT_9PER_ENABLE;
if (of_property_read_bool(np, "maxim,enable-bias-control"))
pdata->control_flags |= MAX8973_BIAS_ENABLE;
pdata->control_flags |= MAX8973_CONTROL_BIAS_ENABLE;
return pdata;
}

View File

@ -34,6 +34,8 @@
#include <linux/mfd/samsung/s2mps14.h>
#include <linux/mfd/samsung/s2mpu02.h>
/* The highest number of possible regulators for supported devices. */
#define S2MPS_REGULATOR_MAX S2MPS13_REGULATOR_MAX
struct s2mps11_info {
unsigned int rdev_num;
int ramp_delay2;
@ -49,7 +51,7 @@ struct s2mps11_info {
* One bit for each S2MPS13/S2MPS14/S2MPU02 regulator whether
* the suspend mode was enabled.
*/
unsigned long long s2mps14_suspend_state:50;
DECLARE_BITMAP(suspend_state, S2MPS_REGULATOR_MAX);
/* Array of size rdev_num with GPIO-s for external sleep control */
int *ext_control_gpio;
@ -500,7 +502,7 @@ static int s2mps14_regulator_enable(struct regulator_dev *rdev)
switch (s2mps11->dev_type) {
case S2MPS13X:
case S2MPS14X:
if (s2mps11->s2mps14_suspend_state & (1 << rdev_get_id(rdev)))
if (test_bit(rdev_get_id(rdev), s2mps11->suspend_state))
val = S2MPS14_ENABLE_SUSPEND;
else if (gpio_is_valid(s2mps11->ext_control_gpio[rdev_get_id(rdev)]))
val = S2MPS14_ENABLE_EXT_CONTROL;
@ -508,7 +510,7 @@ static int s2mps14_regulator_enable(struct regulator_dev *rdev)
val = rdev->desc->enable_mask;
break;
case S2MPU02:
if (s2mps11->s2mps14_suspend_state & (1 << rdev_get_id(rdev)))
if (test_bit(rdev_get_id(rdev), s2mps11->suspend_state))
val = S2MPU02_ENABLE_SUSPEND;
else
val = rdev->desc->enable_mask;
@ -562,7 +564,7 @@ static int s2mps14_regulator_set_suspend_disable(struct regulator_dev *rdev)
if (ret < 0)
return ret;
s2mps11->s2mps14_suspend_state |= (1 << rdev_get_id(rdev));
set_bit(rdev_get_id(rdev), s2mps11->suspend_state);
/*
* Don't enable suspend mode if regulator is already disabled because
* this would effectively for a short time turn on the regulator after
@ -960,18 +962,22 @@ static int s2mps11_pmic_probe(struct platform_device *pdev)
case S2MPS11X:
s2mps11->rdev_num = ARRAY_SIZE(s2mps11_regulators);
regulators = s2mps11_regulators;
BUILD_BUG_ON(S2MPS_REGULATOR_MAX < s2mps11->rdev_num);
break;
case S2MPS13X:
s2mps11->rdev_num = ARRAY_SIZE(s2mps13_regulators);
regulators = s2mps13_regulators;
BUILD_BUG_ON(S2MPS_REGULATOR_MAX < s2mps11->rdev_num);
break;
case S2MPS14X:
s2mps11->rdev_num = ARRAY_SIZE(s2mps14_regulators);
regulators = s2mps14_regulators;
BUILD_BUG_ON(S2MPS_REGULATOR_MAX < s2mps11->rdev_num);
break;
case S2MPU02:
s2mps11->rdev_num = ARRAY_SIZE(s2mpu02_regulators);
regulators = s2mpu02_regulators;
BUILD_BUG_ON(S2MPS_REGULATOR_MAX < s2mps11->rdev_num);
break;
default:
dev_err(&pdev->dev, "Invalid device type: %u\n",