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:
commit
afdf0b91bd
@ -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, \
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user