regulator: Updates for v3.13

Lots of driver updates here plus some nice new core features, the main
 one being the first:
 
  - Enable support for providing a dummy regulator when we know that one
    must exist for the device to be functional.  This makes it much
    easier to add regulator support to drivers since we don't require
    that the machine integration for all systems using the device be
    updated to provide regulators.
  - Substantial reduction in the amount of busy waiting done while
    waiting for enables to complete.
  - Allow MFDs to distribute regulator supplies to child devices so we
    don't have to expose the internal structure of MFDs outside of the
    driver.
  - Managed registeration for regulators.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.15 (GNU/Linux)
 
 iQIcBAABAgAGBQJSd9iAAAoJELSic+t+oim9UxsP/1rm2RSd7eoCjAekSBpYjaah
 bsSOTeUsDF5mT6lkM83crIG0cAvmhdx0g0A8JW2etSCwu7MlIyItUg7SgahVpoCk
 b1L6Uv2LO05spkYZlGxngZ+en3IHsl8UDOhOUjz7EiXLGBRytdfqvjU1JCrylX+j
 cISAGK0IBbyajIkspuqjEwefLsk3U3I+GQw5h4IHTZUQGSWUJ0H1rEw01Vafuieh
 PzzSt9GVaFQj3Swqo+IbcgKgxeBbtiJEI1BXSS0JJ6PgpV/sSYa6UYHJjr93nmmR
 RwThUCoOASZWE5QSOjXUpHetCcgFpcmJ26+jqAGeKAexipbfXMh4EM/6eIy6sSla
 Y4LZMK7bipRPsMTdnLL95NDvuBji2sya9q8x/k7bx+78TJDc/d6/ma2Khso2nnKA
 L+9bj+nXnGZYR8zZ7eRlzU+do0AK6o/aw6sJuCJis64Cvsxlhwix1b6S+dgptjKV
 jMXpEhL3e1w8JqeeOQUJ4AK911RvFimj1Ynfxxn+FOuFtwXrXdXB6SihB1j8Zb7w
 UjAv02tuyOcl07pnm1liS/X5yQnkjE+4x6UPDi1s1TjgYkoINyuOKrMBcteUClMu
 wN2HKZP/ZZezZjzGqbccP3hvgHtUxIpcqmu+0QIFGB9yWRZk9pOyh7xDLEHF6/Jw
 wCIRqBYd+XidEJMzv1+i
 =0xEu
 -----END PGP SIGNATURE-----

Merge tag 'regulator-v3.13' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator

Pull regulator updates from Mark Brown:
 "Lots of driver updates here plus some nice new core features, the main
  one being the first:

   - Enable support for providing a dummy regulator when we know that
     one must exist for the device to be functional.  This makes it much
     easier to add regulator support to drivers since we don't require
     that the machine integration for all systems using the device be
     updated to provide regulators.
   - Substantial reduction in the amount of busy waiting done while
     waiting for enables to complete.
   - Allow MFDs to distribute regulator supplies to child devices so we
     don't have to expose the internal structure of MFDs outside of the
     driver.
   - Managed registeration for regulators"

* tag 'regulator-v3.13' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (113 commits)
  regulator: s5m8767: Modify parsing method of the voltage table of buck2/3/4
  regulator: s5m8767: Modify parse_dt function to parse data related to ramp
  regulator: da9052: Revert se apply_[reg|bit] with regmap based voltage_sel operations
  mfd: arizona: Specify supply mappings for Arizona CODECs
  mfd: Allow mapping regulator supplies to MFD device from children
  regulator: core: Add ability to create a lookup alias for supply
  regulator: tps65910: Fix checkpatch issue
  regulator: tps65023: Fix checkpatch issue
  regulator: tps6105x: Fix checkpatch issue
  regulator: mc13783: Fix checkpatch issue
  regulator: max8997: Fix checkpatch issue
  regulator: lp3971: Fix checkpatch issue
  regulator: fixed: Fix checkpatch issue
  regulator: anatop: Fix checkpatch issue
  regulator: Add REGULATOR_LINEAR_RANGE macro
  regulator: Remove max_uV from struct regulator_linear_range
  regulator: ti-abb: Fix operator precedence typo
  regulator: tps65910: get regulators node from parent node only
  regulator: tps6586x: get regulators node from parent node only
  regulator: tps65090: get regulators node from parent node only
  ...
This commit is contained in:
Linus Torvalds 2013-11-12 14:55:17 +09:00
commit c6d65bf246
83 changed files with 2584 additions and 1521 deletions

View File

@ -0,0 +1,91 @@
Regulator of AMS AS3722 PMIC.
Name of the regulator subnode must be "regulators".
Optional properties:
--------------------
The input supply of regulators are the optional properties on the
regulator node. The AS3722 is having 7 DCDC step-down regulators as
sd[0-6], 10 LDOs as ldo[0-7], ldo[9-11]. The input supply of these
regulators are provided through following properties:
vsup-sd2-supply: Input supply for SD2.
vsup-sd3-supply: Input supply for SD3.
vsup-sd4-supply: Input supply for SD4.
vsup-sd5-supply: Input supply for SD5.
vin-ldo0-supply: Input supply for LDO0.
vin-ldo1-6-supply: Input supply for LDO1 and LDO6.
vin-ldo2-5-7-supply: Input supply for LDO2, LDO5 and LDO7.
vin-ldo3-4-supply: Input supply for LDO3 and LDO4.
vin-ldo9-10-supply: Input supply for LDO9 and LDO10.
vin-ldo11-supply: Input supply for LDO11.
Optional nodes:
--------------
- regulators : Must contain a sub-node per regulator from the list below.
Each sub-node should contain the constraints and initialization
information for that regulator. See regulator.txt for a
description of standard properties for these sub-nodes.
Additional custom properties are listed below.
sd[0-6], ldo[0-7], ldo[9-11].
Optional sub-node properties:
----------------------------
ams,ext-control: External control of the rail. The option of
this properties will tell which external input is
controlling this rail. Valid values are 0, 1, 2 ad 3.
0: There is no external control of this rail.
1: Rail is controlled by ENABLE1 input pin.
2: Rail is controlled by ENABLE2 input pin.
3: Rail is controlled by ENABLE3 input pin.
ams,enable-tracking: Enable tracking with SD1, only supported
by LDO3.
Example:
-------
ams3722: ams3722 {
compatible = "ams,as3722";
reg = <0x40>;
...
regulators {
vsup-sd2-supply = <...>;
...
sd0 {
regulator-name = "vdd_cpu";
regulator-min-microvolt = <700000>;
regulator-max-microvolt = <1400000>;
regulator-always-on;
ams,ext-control = <2>;
};
sd1 {
regulator-name = "vdd_core";
regulator-min-microvolt = <700000>;
regulator-max-microvolt = <1400000>;
regulator-always-on;
ams,ext-control = <1>;
};
sd2 {
regulator-name = "vddio_ddr";
regulator-min-microvolt = <1350000>;
regulator-max-microvolt = <1350000>;
regulator-always-on;
};
sd4 {
regulator-name = "avdd-hdmi-pex";
regulator-min-microvolt = <1050000>;
regulator-max-microvolt = <1050000>;
regulator-always-on;
};
sd5 {
regulator-name = "vdd-1v8";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
};
....
};
};

View File

@ -0,0 +1,21 @@
* Dialog Semiconductor DA9210 Voltage Regulator
Required properties:
- compatible: must be "diasemi,da9210"
- reg: the i2c slave address of the regulator. It should be 0x68.
Any standard regulator properties can be used to configure the single da9210
DCDC.
Example:
da9210@68 {
compatible = "diasemi,da9210";
reg = <0x68>;
regulator-min-microvolt = <900000>;
regulator-max-microvolt = <1000000>;
regulator-boot-on;
regulator-always-on;
};

View File

@ -26,11 +26,17 @@ Optional nodes:
For ti,palmas-pmic - smps12, smps123, smps3 depending on OTP,
smps45, smps457, smps7 depending on variant, smps6, smps[8-9],
smps10_out2, smps10_out1, do[1-9], ldoln, ldousb.
smps10_out2, smps10_out1, ldo[1-9], ldoln, ldousb.
Optional sub-node properties:
ti,warm-reset - maintain voltage during warm reset(boolean)
ti,roof-floor - control voltage selection by pin(boolean)
ti,roof-floor - This takes as optional argument on platform supporting
the rail from desired external control. If there is no argument then
it will be assume that it is controlled by NSLEEP pin.
The valid value for external pins are:
ENABLE1 then 1,
ENABLE2 then 2 or
NSLEEP then 3.
ti,mode-sleep - mode to adopt in pmic sleep 0 - off, 1 - auto,
2 - eco, 3 - forced pwm
ti,smps-range - OTP has the wrong range set for the hardware so override
@ -61,7 +67,7 @@ pmic {
regulator-always-on;
regulator-boot-on;
ti,warm-reset;
ti,roof-floor;
ti,roof-floor = <1>; /* ENABLE1 control */
ti,mode-sleep = <0>;
ti,smps-range = <1>;
};

View File

@ -14,6 +14,11 @@ Optional properties:
- regulator-ramp-delay: ramp delay for regulator(in uV/uS)
For hardwares which support disabling ramp rate, it should be explicitly
intialised to zero (regulator-ramp-delay = <0>) for disabling ramp delay.
- regulator-enable-ramp-delay: The time taken, in microseconds, for the supply
rail to reach the target voltage, plus/minus whatever tolerance the board
design requires. This property describes the total system ramp time
required due to the combination of internal ramping of the regulator itself,
and board design issues such as trace capacitance and load on the supply.
Deprecated properties:
- regulator-compatible: If a regulator chip contains multiple

View File

@ -283,6 +283,7 @@ REGULATOR
devm_regulator_get()
devm_regulator_put()
devm_regulator_bulk_get()
devm_regulator_register()
CLOCK
devm_clk_get()

View File

@ -310,10 +310,6 @@ static struct regulator_consumer_supply wallvdd_consumers[] = {
REGULATOR_SUPPLY("SPKVDDL", "spi0.1"),
REGULATOR_SUPPLY("SPKVDDR", "spi0.1"),
REGULATOR_SUPPLY("SPKVDDL", "wm5102-codec"),
REGULATOR_SUPPLY("SPKVDDR", "wm5102-codec"),
REGULATOR_SUPPLY("SPKVDDL", "wm5110-codec"),
REGULATOR_SUPPLY("SPKVDDR", "wm5110-codec"),
REGULATOR_SUPPLY("DC1VDD", "0-0034"),
REGULATOR_SUPPLY("DC2VDD", "0-0034"),
@ -653,14 +649,6 @@ static struct regulator_consumer_supply pvdd_1v8_consumers[] = {
REGULATOR_SUPPLY("DBVDD3", "spi0.1"),
REGULATOR_SUPPLY("LDOVDD", "spi0.1"),
REGULATOR_SUPPLY("CPVDD", "spi0.1"),
REGULATOR_SUPPLY("DBVDD2", "wm5102-codec"),
REGULATOR_SUPPLY("DBVDD3", "wm5102-codec"),
REGULATOR_SUPPLY("CPVDD", "wm5102-codec"),
REGULATOR_SUPPLY("DBVDD2", "wm5110-codec"),
REGULATOR_SUPPLY("DBVDD3", "wm5110-codec"),
REGULATOR_SUPPLY("CPVDD", "wm5110-codec"),
};
static struct regulator_init_data pvdd_1v8 = {

View File

@ -569,13 +569,25 @@ static struct mfd_cell early_devs[] = {
{ .name = "arizona-ldo1" },
};
static const char *wm5102_supplies[] = {
"DBVDD2",
"DBVDD3",
"CPVDD",
"SPKVDDL",
"SPKVDDR",
};
static struct mfd_cell wm5102_devs[] = {
{ .name = "arizona-micsupp" },
{ .name = "arizona-extcon" },
{ .name = "arizona-gpio" },
{ .name = "arizona-haptics" },
{ .name = "arizona-pwm" },
{ .name = "wm5102-codec" },
{
.name = "wm5102-codec",
.parent_supplies = wm5102_supplies,
.num_parent_supplies = ARRAY_SIZE(wm5102_supplies),
},
};
static struct mfd_cell wm5110_devs[] = {
@ -584,7 +596,17 @@ static struct mfd_cell wm5110_devs[] = {
{ .name = "arizona-gpio" },
{ .name = "arizona-haptics" },
{ .name = "arizona-pwm" },
{ .name = "wm5110-codec" },
{
.name = "wm5110-codec",
.parent_supplies = wm5102_supplies,
.num_parent_supplies = ARRAY_SIZE(wm5102_supplies),
},
};
static const char *wm8997_supplies[] = {
"DBVDD2",
"CPVDD",
"SPKVDD",
};
static struct mfd_cell wm8997_devs[] = {
@ -593,7 +615,11 @@ static struct mfd_cell wm8997_devs[] = {
{ .name = "arizona-gpio" },
{ .name = "arizona-haptics" },
{ .name = "arizona-pwm" },
{ .name = "wm8997-codec" },
{
.name = "wm8997-codec",
.parent_supplies = wm8997_supplies,
.num_parent_supplies = ARRAY_SIZE(wm8997_supplies),
},
};
int arizona_dev_init(struct arizona *arizona)

View File

@ -20,6 +20,7 @@
#include <linux/module.h>
#include <linux/irqdomain.h>
#include <linux/of.h>
#include <linux/regulator/consumer.h>
static struct device_type mfd_dev_type = {
.name = "mfd_device",
@ -99,6 +100,13 @@ static int mfd_add_device(struct device *parent, int id,
pdev->dev.dma_mask = parent->dma_mask;
pdev->dev.dma_parms = parent->dma_parms;
ret = devm_regulator_bulk_register_supply_alias(
&pdev->dev, cell->parent_supplies,
parent, cell->parent_supplies,
cell->num_parent_supplies);
if (ret < 0)
goto fail_res;
if (parent->of_node && cell->of_compatible) {
for_each_child_of_node(parent->of_node, np) {
if (of_device_is_compatible(np, cell->of_compatible)) {
@ -112,12 +120,12 @@ static int mfd_add_device(struct device *parent, int id,
ret = platform_device_add_data(pdev,
cell->platform_data, cell->pdata_size);
if (ret)
goto fail_res;
goto fail_alias;
}
ret = mfd_platform_add_cell(pdev, cell);
if (ret)
goto fail_res;
goto fail_alias;
for (r = 0; r < cell->num_resources; r++) {
res[r].name = cell->resources[r].name;
@ -152,17 +160,17 @@ static int mfd_add_device(struct device *parent, int id,
if (!cell->ignore_resource_conflicts) {
ret = acpi_check_resource_conflict(&res[r]);
if (ret)
goto fail_res;
goto fail_alias;
}
}
ret = platform_device_add_resources(pdev, res, cell->num_resources);
if (ret)
goto fail_res;
goto fail_alias;
ret = platform_device_add(pdev);
if (ret)
goto fail_res;
goto fail_alias;
if (cell->pm_runtime_no_callbacks)
pm_runtime_no_callbacks(&pdev->dev);
@ -171,6 +179,10 @@ static int mfd_add_device(struct device *parent, int id,
return 0;
fail_alias:
devm_regulator_bulk_unregister_supply_alias(&pdev->dev,
cell->parent_supplies,
cell->num_parent_supplies);
fail_res:
kfree(res);
fail_device:

View File

@ -141,18 +141,14 @@ struct pm800_regulators {
/* Ranges are sorted in ascending order. */
static const struct regulator_linear_range buck1_volt_range[] = {
{ .min_uV = 600000, .max_uV = 1587500, .min_sel = 0, .max_sel = 0x4f,
.uV_step = 12500 },
{ .min_uV = 1600000, .max_uV = 1800000, .min_sel = 0x50,
.max_sel = 0x54, .uV_step = 50000 },
REGULATOR_LINEAR_RANGE(600000, 0, 0x4f, 12500),
REGULATOR_LINEAR_RANGE(1600000, 0x50, 0x54, 50000),
};
/* BUCK 2~5 have same ranges. */
static const struct regulator_linear_range buck2_5_volt_range[] = {
{ .min_uV = 600000, .max_uV = 1587500, .min_sel = 0, .max_sel = 0x4f,
.uV_step = 12500 },
{ .min_uV = 1600000, .max_uV = 3300000, .min_sel = 0x50,
.max_sel = 0x72, .uV_step = 50000 },
REGULATOR_LINEAR_RANGE(600000, 0, 0x4f, 12500),
REGULATOR_LINEAR_RANGE(1600000, 0x50, 0x72, 50000),
};
static const unsigned int ldo1_volt_table[] = {

View File

@ -391,7 +391,8 @@ static int pm8607_regulator_probe(struct platform_device *pdev)
else
config.regmap = chip->regmap_companion;
info->regulator = regulator_register(&info->desc, &config);
info->regulator = devm_regulator_register(&pdev->dev, &info->desc,
&config);
if (IS_ERR(info->regulator)) {
dev_err(&pdev->dev, "failed to register regulator %s\n",
info->desc.name);
@ -402,14 +403,6 @@ static int pm8607_regulator_probe(struct platform_device *pdev)
return 0;
}
static int pm8607_regulator_remove(struct platform_device *pdev)
{
struct pm8607_regulator_info *info = platform_get_drvdata(pdev);
regulator_unregister(info->regulator);
return 0;
}
static struct platform_device_id pm8607_regulator_driver_ids[] = {
{
.name = "88pm860x-regulator",
@ -428,7 +421,6 @@ static struct platform_driver pm8607_regulator_driver = {
.owner = THIS_MODULE,
},
.probe = pm8607_regulator_probe,
.remove = pm8607_regulator_remove,
.id_table = pm8607_regulator_driver_ids,
};

View File

@ -28,16 +28,6 @@ config REGULATOR_DEBUG
help
Say yes here to enable debugging support.
config REGULATOR_DUMMY
bool "Provide a dummy regulator if regulator lookups fail"
help
If this option is enabled then when a regulator lookup fails
and the board has not specified that it has provided full
constraints the regulator core will provide an always
enabled dummy regulator, allowing consumer drivers to continue.
A warning will be generated when this substitution is done.
config REGULATOR_FIXED_VOLTAGE
tristate "Fixed voltage regulator support"
help
@ -133,6 +123,14 @@ config REGULATOR_AS3711
This driver provides support for the voltage regulators on the
AS3711 PMIC
config REGULATOR_AS3722
tristate "AMS AS3722 PMIC Regulators"
depends on MFD_AS3722
help
This driver provides support for the voltage regulators on the
AS3722 PMIC. This will enable support for all the software
controllable DCDC/LDO regulators.
config REGULATOR_DA903X
tristate "Dialog Semiconductor DA9030/DA9034 regulators"
depends on PMIC_DA903X
@ -429,6 +427,14 @@ config REGULATOR_TI_ABB
on TI SoCs may be unstable without enabling this as it provides
device specific optimized bias to allow/optimize functionality.
config REGULATOR_STW481X_VMMC
bool "ST Microelectronics STW481X VMMC regulator"
depends on MFD_STW481X
default y if MFD_STW481X
help
This driver supports the internal VMMC regulator in the STw481x
PMIC chips.
config REGULATOR_TPS51632
tristate "TI TPS51632 Power Regulator"
depends on I2C

View File

@ -3,7 +3,7 @@
#
obj-$(CONFIG_REGULATOR) += core.o dummy.o fixed-helper.o helpers.o
obj-$(CONFIG_REGULATOR) += core.o dummy.o fixed-helper.o helpers.o devres.o
obj-$(CONFIG_OF) += of_regulator.o
obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o
obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o
@ -18,6 +18,7 @@ obj-$(CONFIG_REGULATOR_AD5398) += ad5398.o
obj-$(CONFIG_REGULATOR_ANATOP) += anatop-regulator.o
obj-$(CONFIG_REGULATOR_ARIZONA) += arizona-micsupp.o arizona-ldo1.o
obj-$(CONFIG_REGULATOR_AS3711) += as3711-regulator.o
obj-$(CONFIG_REGULATOR_AS3722) += as3722-regulator.o
obj-$(CONFIG_REGULATOR_DA903X) += da903x.o
obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o
obj-$(CONFIG_REGULATOR_DA9055) += da9055-regulator.o
@ -56,6 +57,7 @@ obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o
obj-$(CONFIG_REGULATOR_RC5T583) += rc5t583-regulator.o
obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o
obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
obj-$(CONFIG_REGULATOR_STW481X_VMMC) += stw481x-vmmc.o
obj-$(CONFIG_REGULATOR_TI_ABB) += ti-abb-regulator.o
obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o
obj-$(CONFIG_REGULATOR_TPS62360) += tps62360-regulator.o

View File

@ -176,7 +176,7 @@ static int aat2870_regulator_probe(struct platform_device *pdev)
config.driver_data = ri;
config.init_data = dev_get_platdata(&pdev->dev);
rdev = regulator_register(&ri->desc, &config);
rdev = devm_regulator_register(&pdev->dev, &ri->desc, &config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "Failed to register regulator %s\n",
ri->desc.name);
@ -187,21 +187,12 @@ static int aat2870_regulator_probe(struct platform_device *pdev)
return 0;
}
static int aat2870_regulator_remove(struct platform_device *pdev)
{
struct regulator_dev *rdev = platform_get_drvdata(pdev);
regulator_unregister(rdev);
return 0;
}
static struct platform_driver aat2870_regulator_driver = {
.driver = {
.name = "aat2870-regulator",
.owner = THIS_MODULE,
},
.probe = aat2870_regulator_probe,
.remove = aat2870_regulator_remove,
};
static int __init aat2870_regulator_init(void)

View File

@ -535,7 +535,7 @@ static int ab3100_regulator_register(struct platform_device *pdev,
config.dev = &pdev->dev;
config.driver_data = reg;
rdev = regulator_register(desc, &config);
rdev = devm_regulator_register(&pdev->dev, desc, &config);
if (IS_ERR(rdev)) {
err = PTR_ERR(rdev);
dev_err(&pdev->dev,
@ -616,7 +616,6 @@ static int ab3100_regulators_remove(struct platform_device *pdev)
for (i = 0; i < AB3100_NUM_REGULATORS; i++) {
struct ab3100_regulator *reg = &ab3100_regulators[i];
regulator_unregister(reg->rdev);
reg->rdev = NULL;
}
return 0;

View File

@ -413,16 +413,12 @@ static int ab8500_ext_regulator_probe(struct platform_device *pdev)
&pdata->ext_regulator[i];
/* register regulator with framework */
info->rdev = regulator_register(&info->desc, &config);
info->rdev = devm_regulator_register(&pdev->dev, &info->desc,
&config);
if (IS_ERR(info->rdev)) {
err = PTR_ERR(info->rdev);
dev_err(&pdev->dev, "failed to register regulator %s\n",
info->desc.name);
/* when we fail, un-register all earlier regulators */
while (--i >= 0) {
info = &ab8500_ext_regulator_info[i];
regulator_unregister(info->rdev);
}
return err;
}
@ -433,26 +429,8 @@ static int ab8500_ext_regulator_probe(struct platform_device *pdev)
return 0;
}
static int ab8500_ext_regulator_remove(struct platform_device *pdev)
{
int i;
for (i = 0; i < ARRAY_SIZE(ab8500_ext_regulator_info); i++) {
struct ab8500_ext_regulator_info *info = NULL;
info = &ab8500_ext_regulator_info[i];
dev_vdbg(rdev_get_dev(info->rdev),
"%s-remove\n", info->desc.name);
regulator_unregister(info->rdev);
}
return 0;
}
static struct platform_driver ab8500_ext_regulator_driver = {
.probe = ab8500_ext_regulator_probe,
.remove = ab8500_ext_regulator_remove,
.driver = {
.name = "ab8500-ext-regulator",
.owner = THIS_MODULE,

View File

@ -219,7 +219,6 @@ static int ad5398_probe(struct i2c_client *client,
struct ad5398_chip_info *chip;
const struct ad5398_current_data_format *df =
(struct ad5398_current_data_format *)id->driver_data;
int ret;
if (!init_data)
return -EINVAL;
@ -240,33 +239,21 @@ static int ad5398_probe(struct i2c_client *client,
chip->current_offset = df->current_offset;
chip->current_mask = (chip->current_level - 1) << chip->current_offset;
chip->rdev = regulator_register(&ad5398_reg, &config);
chip->rdev = devm_regulator_register(&client->dev, &ad5398_reg,
&config);
if (IS_ERR(chip->rdev)) {
ret = PTR_ERR(chip->rdev);
dev_err(&client->dev, "failed to register %s %s\n",
id->name, ad5398_reg.name);
goto err;
return PTR_ERR(chip->rdev);
}
i2c_set_clientdata(client, chip);
dev_dbg(&client->dev, "%s regulator driver is registered.\n", id->name);
return 0;
err:
return ret;
}
static int ad5398_remove(struct i2c_client *client)
{
struct ad5398_chip_info *chip = i2c_get_clientdata(client);
regulator_unregister(chip->rdev);
return 0;
}
static struct i2c_driver ad5398_driver = {
.probe = ad5398_probe,
.remove = ad5398_remove,
.driver = {
.name = "ad5398",
},

View File

@ -200,7 +200,7 @@ static int anatop_regulator_probe(struct platform_device *pdev)
config.regmap = sreg->anatop;
/* register regulator */
rdev = regulator_register(rdesc, &config);
rdev = devm_regulator_register(dev, rdesc, &config);
if (IS_ERR(rdev)) {
dev_err(dev, "failed to register %s\n",
rdesc->name);
@ -223,7 +223,6 @@ static int anatop_regulator_remove(struct platform_device *pdev)
struct anatop_regulator *sreg = rdev_get_drvdata(rdev);
const char *name = sreg->name;
regulator_unregister(rdev);
kfree(name);
return 0;
@ -256,7 +255,7 @@ static void __exit anatop_regulator_exit(void)
}
module_exit(anatop_regulator_exit);
MODULE_AUTHOR("Nancy Chen <Nancy.Chen@freescale.com>, "
"Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>");
MODULE_AUTHOR("Nancy Chen <Nancy.Chen@freescale.com>");
MODULE_AUTHOR("Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>");
MODULE_DESCRIPTION("ANATOP Regulator driver");
MODULE_LICENSE("GPL v2");

View File

@ -226,7 +226,7 @@ static int arizona_ldo1_probe(struct platform_device *pdev)
else
config.init_data = &ldo1->init_data;
ldo1->regulator = regulator_register(desc, &config);
ldo1->regulator = devm_regulator_register(&pdev->dev, desc, &config);
if (IS_ERR(ldo1->regulator)) {
ret = PTR_ERR(ldo1->regulator);
dev_err(arizona->dev, "Failed to register LDO1 supply: %d\n",
@ -239,18 +239,8 @@ static int arizona_ldo1_probe(struct platform_device *pdev)
return 0;
}
static int arizona_ldo1_remove(struct platform_device *pdev)
{
struct arizona_ldo1 *ldo1 = platform_get_drvdata(pdev);
regulator_unregister(ldo1->regulator);
return 0;
}
static struct platform_driver arizona_ldo1_driver = {
.probe = arizona_ldo1_probe,
.remove = arizona_ldo1_remove,
.driver = {
.name = "arizona-ldo1",
.owner = THIS_MODULE,

View File

@ -225,7 +225,9 @@ static int arizona_micsupp_probe(struct platform_device *pdev)
regmap_update_bits(arizona->regmap, ARIZONA_MIC_CHARGE_PUMP_1,
ARIZONA_CPMIC_BYPASS, 0);
micsupp->regulator = regulator_register(&arizona_micsupp, &config);
micsupp->regulator = devm_regulator_register(&pdev->dev,
&arizona_micsupp,
&config);
if (IS_ERR(micsupp->regulator)) {
ret = PTR_ERR(micsupp->regulator);
dev_err(arizona->dev, "Failed to register mic supply: %d\n",
@ -238,18 +240,8 @@ static int arizona_micsupp_probe(struct platform_device *pdev)
return 0;
}
static int arizona_micsupp_remove(struct platform_device *pdev)
{
struct arizona_micsupp *micsupp = platform_get_drvdata(pdev);
regulator_unregister(micsupp->regulator);
return 0;
}
static struct platform_driver arizona_micsupp_driver = {
.probe = arizona_micsupp_probe,
.remove = arizona_micsupp_remove,
.driver = {
.name = "arizona-micsupp",
.owner = THIS_MODULE,

View File

@ -117,26 +117,19 @@ static struct regulator_ops as3711_dldo_ops = {
};
static const struct regulator_linear_range as3711_sd_ranges[] = {
{ .min_uV = 612500, .max_uV = 1400000,
.min_sel = 0x1, .max_sel = 0x40, .uV_step = 12500 },
{ .min_uV = 1425000, .max_uV = 2600000,
.min_sel = 0x41, .max_sel = 0x70, .uV_step = 25000 },
{ .min_uV = 2650000, .max_uV = 3350000,
.min_sel = 0x71, .max_sel = 0x7f, .uV_step = 50000 },
REGULATOR_LINEAR_RANGE(612500, 0x1, 0x40, 12500),
REGULATOR_LINEAR_RANGE(1425000, 0x41, 0x70, 25000),
REGULATOR_LINEAR_RANGE(2650000, 0x71, 0x7f, 50000),
};
static const struct regulator_linear_range as3711_aldo_ranges[] = {
{ .min_uV = 1200000, .max_uV = 1950000,
.min_sel = 0, .max_sel = 0xf, .uV_step = 50000 },
{ .min_uV = 1800000, .max_uV = 3300000,
.min_sel = 0x10, .max_sel = 0x1f, .uV_step = 100000 },
REGULATOR_LINEAR_RANGE(1200000, 0, 0xf, 50000),
REGULATOR_LINEAR_RANGE(1800000, 0x10, 0x1f, 100000),
};
static const struct regulator_linear_range as3711_dldo_ranges[] = {
{ .min_uV = 900000, .max_uV = 1700000,
.min_sel = 0, .max_sel = 0x10, .uV_step = 50000 },
{ .min_uV = 1750000, .max_uV = 3300000,
.min_sel = 0x20, .max_sel = 0x3f, .uV_step = 50000 },
REGULATOR_LINEAR_RANGE(900000, 0, 0x10, 50000),
REGULATOR_LINEAR_RANGE(1750000, 0x20, 0x3f, 50000),
};
#define AS3711_REG(_id, _en_reg, _en_bit, _vmask, _vshift, _min_uV, _max_uV, _sfx) \
@ -273,33 +266,16 @@ static int as3711_regulator_probe(struct platform_device *pdev)
config.regmap = as3711->regmap;
config.of_node = of_node[id];
rdev = regulator_register(&ri->desc, &config);
rdev = devm_regulator_register(&pdev->dev, &ri->desc, &config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "Failed to register regulator %s\n",
ri->desc.name);
ret = PTR_ERR(rdev);
goto eregreg;
return PTR_ERR(rdev);
}
reg->rdev = rdev;
}
platform_set_drvdata(pdev, regs);
return 0;
eregreg:
while (--id >= 0)
regulator_unregister(regs[id].rdev);
return ret;
}
static int as3711_regulator_remove(struct platform_device *pdev)
{
struct as3711_regulator *regs = platform_get_drvdata(pdev);
int id;
for (id = 0; id < AS3711_REGULATOR_NUM; ++id)
regulator_unregister(regs[id].rdev);
return 0;
}
static struct platform_driver as3711_regulator_driver = {
@ -308,7 +284,6 @@ static struct platform_driver as3711_regulator_driver = {
.owner = THIS_MODULE,
},
.probe = as3711_regulator_probe,
.remove = as3711_regulator_remove,
};
static int __init as3711_regulator_init(void)

View File

@ -0,0 +1,908 @@
/*
* Voltage regulator support for AMS AS3722 PMIC
*
* Copyright (C) 2013 ams
*
* Author: Florian Lobmaier <florian.lobmaier@ams.com>
* Author: Laxman Dewangan <ldewangan@nvidia.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mfd/as3722.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>
#include <linux/slab.h>
/* Regulator IDs */
enum as3722_regulators_id {
AS3722_REGULATOR_ID_SD0,
AS3722_REGULATOR_ID_SD1,
AS3722_REGULATOR_ID_SD2,
AS3722_REGULATOR_ID_SD3,
AS3722_REGULATOR_ID_SD4,
AS3722_REGULATOR_ID_SD5,
AS3722_REGULATOR_ID_SD6,
AS3722_REGULATOR_ID_LDO0,
AS3722_REGULATOR_ID_LDO1,
AS3722_REGULATOR_ID_LDO2,
AS3722_REGULATOR_ID_LDO3,
AS3722_REGULATOR_ID_LDO4,
AS3722_REGULATOR_ID_LDO5,
AS3722_REGULATOR_ID_LDO6,
AS3722_REGULATOR_ID_LDO7,
AS3722_REGULATOR_ID_LDO9,
AS3722_REGULATOR_ID_LDO10,
AS3722_REGULATOR_ID_LDO11,
AS3722_REGULATOR_ID_MAX,
};
struct as3722_register_mapping {
u8 regulator_id;
const char *name;
const char *sname;
u8 vsel_reg;
u8 vsel_mask;
int n_voltages;
u32 enable_reg;
u8 enable_mask;
u32 control_reg;
u8 mode_mask;
u32 sleep_ctrl_reg;
u8 sleep_ctrl_mask;
};
struct as3722_regulator_config_data {
struct regulator_init_data *reg_init;
bool enable_tracking;
int ext_control;
};
struct as3722_regulators {
struct device *dev;
struct as3722 *as3722;
struct regulator_dev *rdevs[AS3722_REGULATOR_ID_MAX];
struct regulator_desc desc[AS3722_REGULATOR_ID_MAX];
struct as3722_regulator_config_data
reg_config_data[AS3722_REGULATOR_ID_MAX];
};
static const struct as3722_register_mapping as3722_reg_lookup[] = {
{
.regulator_id = AS3722_REGULATOR_ID_SD0,
.name = "as3722-sd0",
.vsel_reg = AS3722_SD0_VOLTAGE_REG,
.vsel_mask = AS3722_SD_VSEL_MASK,
.enable_reg = AS3722_SD_CONTROL_REG,
.enable_mask = AS3722_SDn_CTRL(0),
.sleep_ctrl_reg = AS3722_ENABLE_CTRL1_REG,
.sleep_ctrl_mask = AS3722_SD0_EXT_ENABLE_MASK,
.control_reg = AS3722_SD0_CONTROL_REG,
.mode_mask = AS3722_SD0_MODE_FAST,
.n_voltages = AS3722_SD0_VSEL_MAX + 1,
},
{
.regulator_id = AS3722_REGULATOR_ID_SD1,
.name = "as3722-sd1",
.vsel_reg = AS3722_SD1_VOLTAGE_REG,
.vsel_mask = AS3722_SD_VSEL_MASK,
.enable_reg = AS3722_SD_CONTROL_REG,
.enable_mask = AS3722_SDn_CTRL(1),
.sleep_ctrl_reg = AS3722_ENABLE_CTRL1_REG,
.sleep_ctrl_mask = AS3722_SD1_EXT_ENABLE_MASK,
.control_reg = AS3722_SD1_CONTROL_REG,
.mode_mask = AS3722_SD1_MODE_FAST,
.n_voltages = AS3722_SD0_VSEL_MAX + 1,
},
{
.regulator_id = AS3722_REGULATOR_ID_SD2,
.name = "as3722-sd2",
.sname = "vsup-sd2",
.vsel_reg = AS3722_SD2_VOLTAGE_REG,
.vsel_mask = AS3722_SD_VSEL_MASK,
.enable_reg = AS3722_SD_CONTROL_REG,
.enable_mask = AS3722_SDn_CTRL(2),
.sleep_ctrl_reg = AS3722_ENABLE_CTRL1_REG,
.sleep_ctrl_mask = AS3722_SD2_EXT_ENABLE_MASK,
.control_reg = AS3722_SD23_CONTROL_REG,
.mode_mask = AS3722_SD2_MODE_FAST,
.n_voltages = AS3722_SD2_VSEL_MAX + 1,
},
{
.regulator_id = AS3722_REGULATOR_ID_SD3,
.name = "as3722-sd3",
.sname = "vsup-sd3",
.vsel_reg = AS3722_SD3_VOLTAGE_REG,
.vsel_mask = AS3722_SD_VSEL_MASK,
.enable_reg = AS3722_SD_CONTROL_REG,
.enable_mask = AS3722_SDn_CTRL(3),
.sleep_ctrl_reg = AS3722_ENABLE_CTRL1_REG,
.sleep_ctrl_mask = AS3722_SD3_EXT_ENABLE_MASK,
.control_reg = AS3722_SD23_CONTROL_REG,
.mode_mask = AS3722_SD3_MODE_FAST,
.n_voltages = AS3722_SD2_VSEL_MAX + 1,
},
{
.regulator_id = AS3722_REGULATOR_ID_SD4,
.name = "as3722-sd4",
.sname = "vsup-sd4",
.vsel_reg = AS3722_SD4_VOLTAGE_REG,
.vsel_mask = AS3722_SD_VSEL_MASK,
.enable_reg = AS3722_SD_CONTROL_REG,
.enable_mask = AS3722_SDn_CTRL(4),
.sleep_ctrl_reg = AS3722_ENABLE_CTRL2_REG,
.sleep_ctrl_mask = AS3722_SD4_EXT_ENABLE_MASK,
.control_reg = AS3722_SD4_CONTROL_REG,
.mode_mask = AS3722_SD4_MODE_FAST,
.n_voltages = AS3722_SD2_VSEL_MAX + 1,
},
{
.regulator_id = AS3722_REGULATOR_ID_SD5,
.name = "as3722-sd5",
.sname = "vsup-sd5",
.vsel_reg = AS3722_SD5_VOLTAGE_REG,
.vsel_mask = AS3722_SD_VSEL_MASK,
.enable_reg = AS3722_SD_CONTROL_REG,
.enable_mask = AS3722_SDn_CTRL(5),
.sleep_ctrl_reg = AS3722_ENABLE_CTRL2_REG,
.sleep_ctrl_mask = AS3722_SD5_EXT_ENABLE_MASK,
.control_reg = AS3722_SD5_CONTROL_REG,
.mode_mask = AS3722_SD5_MODE_FAST,
.n_voltages = AS3722_SD2_VSEL_MAX + 1,
},
{
.regulator_id = AS3722_REGULATOR_ID_SD6,
.name = "as3722-sd6",
.vsel_reg = AS3722_SD6_VOLTAGE_REG,
.vsel_mask = AS3722_SD_VSEL_MASK,
.enable_reg = AS3722_SD_CONTROL_REG,
.enable_mask = AS3722_SDn_CTRL(6),
.sleep_ctrl_reg = AS3722_ENABLE_CTRL2_REG,
.sleep_ctrl_mask = AS3722_SD6_EXT_ENABLE_MASK,
.control_reg = AS3722_SD6_CONTROL_REG,
.mode_mask = AS3722_SD6_MODE_FAST,
.n_voltages = AS3722_SD0_VSEL_MAX + 1,
},
{
.regulator_id = AS3722_REGULATOR_ID_LDO0,
.name = "as3722-ldo0",
.sname = "vin-ldo0",
.vsel_reg = AS3722_LDO0_VOLTAGE_REG,
.vsel_mask = AS3722_LDO0_VSEL_MASK,
.enable_reg = AS3722_LDOCONTROL0_REG,
.enable_mask = AS3722_LDO0_CTRL,
.sleep_ctrl_reg = AS3722_ENABLE_CTRL3_REG,
.sleep_ctrl_mask = AS3722_LDO0_EXT_ENABLE_MASK,
.n_voltages = AS3722_LDO0_NUM_VOLT,
},
{
.regulator_id = AS3722_REGULATOR_ID_LDO1,
.name = "as3722-ldo1",
.sname = "vin-ldo1-6",
.vsel_reg = AS3722_LDO1_VOLTAGE_REG,
.vsel_mask = AS3722_LDO_VSEL_MASK,
.enable_reg = AS3722_LDOCONTROL0_REG,
.enable_mask = AS3722_LDO1_CTRL,
.sleep_ctrl_reg = AS3722_ENABLE_CTRL3_REG,
.sleep_ctrl_mask = AS3722_LDO1_EXT_ENABLE_MASK,
.n_voltages = AS3722_LDO_NUM_VOLT,
},
{
.regulator_id = AS3722_REGULATOR_ID_LDO2,
.name = "as3722-ldo2",
.sname = "vin-ldo2-5-7",
.vsel_reg = AS3722_LDO2_VOLTAGE_REG,
.vsel_mask = AS3722_LDO_VSEL_MASK,
.enable_reg = AS3722_LDOCONTROL0_REG,
.enable_mask = AS3722_LDO2_CTRL,
.sleep_ctrl_reg = AS3722_ENABLE_CTRL3_REG,
.sleep_ctrl_mask = AS3722_LDO2_EXT_ENABLE_MASK,
.n_voltages = AS3722_LDO_NUM_VOLT,
},
{
.regulator_id = AS3722_REGULATOR_ID_LDO3,
.name = "as3722-ldo3",
.name = "vin-ldo3-4",
.vsel_reg = AS3722_LDO3_VOLTAGE_REG,
.vsel_mask = AS3722_LDO3_VSEL_MASK,
.enable_reg = AS3722_LDOCONTROL0_REG,
.enable_mask = AS3722_LDO3_CTRL,
.sleep_ctrl_reg = AS3722_ENABLE_CTRL3_REG,
.sleep_ctrl_mask = AS3722_LDO3_EXT_ENABLE_MASK,
.n_voltages = AS3722_LDO3_NUM_VOLT,
},
{
.regulator_id = AS3722_REGULATOR_ID_LDO4,
.name = "as3722-ldo4",
.name = "vin-ldo3-4",
.vsel_reg = AS3722_LDO4_VOLTAGE_REG,
.vsel_mask = AS3722_LDO_VSEL_MASK,
.enable_reg = AS3722_LDOCONTROL0_REG,
.enable_mask = AS3722_LDO4_CTRL,
.sleep_ctrl_reg = AS3722_ENABLE_CTRL4_REG,
.sleep_ctrl_mask = AS3722_LDO4_EXT_ENABLE_MASK,
.n_voltages = AS3722_LDO_NUM_VOLT,
},
{
.regulator_id = AS3722_REGULATOR_ID_LDO5,
.name = "as3722-ldo5",
.sname = "vin-ldo2-5-7",
.vsel_reg = AS3722_LDO5_VOLTAGE_REG,
.vsel_mask = AS3722_LDO_VSEL_MASK,
.enable_reg = AS3722_LDOCONTROL0_REG,
.enable_mask = AS3722_LDO5_CTRL,
.sleep_ctrl_reg = AS3722_ENABLE_CTRL4_REG,
.sleep_ctrl_mask = AS3722_LDO5_EXT_ENABLE_MASK,
.n_voltages = AS3722_LDO_NUM_VOLT,
},
{
.regulator_id = AS3722_REGULATOR_ID_LDO6,
.name = "as3722-ldo6",
.sname = "vin-ldo1-6",
.vsel_reg = AS3722_LDO6_VOLTAGE_REG,
.vsel_mask = AS3722_LDO_VSEL_MASK,
.enable_reg = AS3722_LDOCONTROL0_REG,
.enable_mask = AS3722_LDO6_CTRL,
.sleep_ctrl_reg = AS3722_ENABLE_CTRL4_REG,
.sleep_ctrl_mask = AS3722_LDO6_EXT_ENABLE_MASK,
.n_voltages = AS3722_LDO_NUM_VOLT,
},
{
.regulator_id = AS3722_REGULATOR_ID_LDO7,
.name = "as3722-ldo7",
.sname = "vin-ldo2-5-7",
.vsel_reg = AS3722_LDO7_VOLTAGE_REG,
.vsel_mask = AS3722_LDO_VSEL_MASK,
.enable_reg = AS3722_LDOCONTROL0_REG,
.enable_mask = AS3722_LDO7_CTRL,
.sleep_ctrl_reg = AS3722_ENABLE_CTRL4_REG,
.sleep_ctrl_mask = AS3722_LDO7_EXT_ENABLE_MASK,
.n_voltages = AS3722_LDO_NUM_VOLT,
},
{
.regulator_id = AS3722_REGULATOR_ID_LDO9,
.name = "as3722-ldo9",
.sname = "vin-ldo9-10",
.vsel_reg = AS3722_LDO9_VOLTAGE_REG,
.vsel_mask = AS3722_LDO_VSEL_MASK,
.enable_reg = AS3722_LDOCONTROL1_REG,
.enable_mask = AS3722_LDO9_CTRL,
.sleep_ctrl_reg = AS3722_ENABLE_CTRL5_REG,
.sleep_ctrl_mask = AS3722_LDO9_EXT_ENABLE_MASK,
.n_voltages = AS3722_LDO_NUM_VOLT,
},
{
.regulator_id = AS3722_REGULATOR_ID_LDO10,
.name = "as3722-ldo10",
.sname = "vin-ldo9-10",
.vsel_reg = AS3722_LDO10_VOLTAGE_REG,
.vsel_mask = AS3722_LDO_VSEL_MASK,
.enable_reg = AS3722_LDOCONTROL1_REG,
.enable_mask = AS3722_LDO10_CTRL,
.sleep_ctrl_reg = AS3722_ENABLE_CTRL5_REG,
.sleep_ctrl_mask = AS3722_LDO10_EXT_ENABLE_MASK,
.n_voltages = AS3722_LDO_NUM_VOLT,
},
{
.regulator_id = AS3722_REGULATOR_ID_LDO11,
.name = "as3722-ldo11",
.sname = "vin-ldo11",
.vsel_reg = AS3722_LDO11_VOLTAGE_REG,
.vsel_mask = AS3722_LDO_VSEL_MASK,
.enable_reg = AS3722_LDOCONTROL1_REG,
.enable_mask = AS3722_LDO11_CTRL,
.sleep_ctrl_reg = AS3722_ENABLE_CTRL5_REG,
.sleep_ctrl_mask = AS3722_LDO11_EXT_ENABLE_MASK,
.n_voltages = AS3722_LDO_NUM_VOLT,
},
};
static const int as3722_ldo_current[] = { 150000, 300000 };
static const int as3722_sd016_current[] = { 2500000, 3000000, 3500000 };
static int as3722_current_to_index(int min_uA, int max_uA,
const int *curr_table, int n_currents)
{
int i;
for (i = n_currents - 1; i >= 0; i--) {
if ((min_uA <= curr_table[i]) && (curr_table[i] <= max_uA))
return i;
}
return -EINVAL;
}
static int as3722_ldo_get_current_limit(struct regulator_dev *rdev)
{
struct as3722_regulators *as3722_regs = rdev_get_drvdata(rdev);
struct as3722 *as3722 = as3722_regs->as3722;
int id = rdev_get_id(rdev);
u32 val;
int ret;
ret = as3722_read(as3722, as3722_reg_lookup[id].vsel_reg, &val);
if (ret < 0) {
dev_err(as3722_regs->dev, "Reg 0x%02x read failed: %d\n",
as3722_reg_lookup[id].vsel_reg, ret);
return ret;
}
if (val & AS3722_LDO_ILIMIT_MASK)
return 300000;
return 150000;
}
static int as3722_ldo_set_current_limit(struct regulator_dev *rdev,
int min_uA, int max_uA)
{
struct as3722_regulators *as3722_regs = rdev_get_drvdata(rdev);
struct as3722 *as3722 = as3722_regs->as3722;
int id = rdev_get_id(rdev);
int ret;
u32 reg = 0;
ret = as3722_current_to_index(min_uA, max_uA, as3722_ldo_current,
ARRAY_SIZE(as3722_ldo_current));
if (ret < 0) {
dev_err(as3722_regs->dev,
"Current range min:max = %d:%d does not support\n",
min_uA, max_uA);
return ret;
}
if (ret)
reg = AS3722_LDO_ILIMIT_BIT;
return as3722_update_bits(as3722, as3722_reg_lookup[id].vsel_reg,
AS3722_LDO_ILIMIT_MASK, reg);
}
static struct regulator_ops as3722_ldo0_ops = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.list_voltage = regulator_list_voltage_linear,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_current_limit = as3722_ldo_get_current_limit,
.set_current_limit = as3722_ldo_set_current_limit,
};
static struct regulator_ops as3722_ldo0_extcntrl_ops = {
.list_voltage = regulator_list_voltage_linear,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_current_limit = as3722_ldo_get_current_limit,
.set_current_limit = as3722_ldo_set_current_limit,
};
static int as3722_ldo3_set_tracking_mode(struct as3722_regulators *as3722_reg,
int id, u8 mode)
{
struct as3722 *as3722 = as3722_reg->as3722;
switch (mode) {
case AS3722_LDO3_MODE_PMOS:
case AS3722_LDO3_MODE_PMOS_TRACKING:
case AS3722_LDO3_MODE_NMOS:
case AS3722_LDO3_MODE_SWITCH:
return as3722_update_bits(as3722,
as3722_reg_lookup[id].vsel_reg,
AS3722_LDO3_MODE_MASK, mode);
default:
return -EINVAL;
}
}
static int as3722_ldo3_get_current_limit(struct regulator_dev *rdev)
{
return 150000;
}
static struct regulator_ops as3722_ldo3_ops = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.list_voltage = regulator_list_voltage_linear,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_current_limit = as3722_ldo3_get_current_limit,
};
static struct regulator_ops as3722_ldo3_extcntrl_ops = {
.list_voltage = regulator_list_voltage_linear,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_current_limit = as3722_ldo3_get_current_limit,
};
static const struct regulator_linear_range as3722_ldo_ranges[] = {
REGULATOR_LINEAR_RANGE(825000, 0x01, 0x24, 25000),
REGULATOR_LINEAR_RANGE(1725000, 0x40, 0x7F, 25000),
};
static struct regulator_ops as3722_ldo_ops = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.map_voltage = regulator_map_voltage_linear_range,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.list_voltage = regulator_list_voltage_linear_range,
.get_current_limit = as3722_ldo_get_current_limit,
.set_current_limit = as3722_ldo_set_current_limit,
};
static struct regulator_ops as3722_ldo_extcntrl_ops = {
.map_voltage = regulator_map_voltage_linear_range,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.list_voltage = regulator_list_voltage_linear_range,
.get_current_limit = as3722_ldo_get_current_limit,
.set_current_limit = as3722_ldo_set_current_limit,
};
static unsigned int as3722_sd_get_mode(struct regulator_dev *rdev)
{
struct as3722_regulators *as3722_regs = rdev_get_drvdata(rdev);
struct as3722 *as3722 = as3722_regs->as3722;
int id = rdev_get_id(rdev);
u32 val;
int ret;
if (!as3722_reg_lookup[id].control_reg)
return -ENOTSUPP;
ret = as3722_read(as3722, as3722_reg_lookup[id].control_reg, &val);
if (ret < 0) {
dev_err(as3722_regs->dev, "Reg 0x%02x read failed: %d\n",
as3722_reg_lookup[id].control_reg, ret);
return ret;
}
if (val & as3722_reg_lookup[id].mode_mask)
return REGULATOR_MODE_FAST;
else
return REGULATOR_MODE_NORMAL;
}
static int as3722_sd_set_mode(struct regulator_dev *rdev,
unsigned int mode)
{
struct as3722_regulators *as3722_regs = rdev_get_drvdata(rdev);
struct as3722 *as3722 = as3722_regs->as3722;
u8 id = rdev_get_id(rdev);
u8 val = 0;
int ret;
if (!as3722_reg_lookup[id].control_reg)
return -ERANGE;
switch (mode) {
case REGULATOR_MODE_FAST:
val = as3722_reg_lookup[id].mode_mask;
case REGULATOR_MODE_NORMAL: /* fall down */
break;
default:
return -EINVAL;
}
ret = as3722_update_bits(as3722, as3722_reg_lookup[id].control_reg,
as3722_reg_lookup[id].mode_mask, val);
if (ret < 0) {
dev_err(as3722_regs->dev, "Reg 0x%02x update failed: %d\n",
as3722_reg_lookup[id].control_reg, ret);
return ret;
}
return ret;
}
static int as3722_sd016_get_current_limit(struct regulator_dev *rdev)
{
struct as3722_regulators *as3722_regs = rdev_get_drvdata(rdev);
struct as3722 *as3722 = as3722_regs->as3722;
int id = rdev_get_id(rdev);
u32 val, reg;
int mask;
int ret;
switch (id) {
case AS3722_REGULATOR_ID_SD0:
reg = AS3722_OVCURRENT_REG;
mask = AS3722_OVCURRENT_SD0_TRIP_MASK;
break;
case AS3722_REGULATOR_ID_SD1:
reg = AS3722_OVCURRENT_REG;
mask = AS3722_OVCURRENT_SD1_TRIP_MASK;
break;
case AS3722_REGULATOR_ID_SD6:
reg = AS3722_OVCURRENT_DEB_REG;
mask = AS3722_OVCURRENT_SD6_TRIP_MASK;
break;
default:
return -EINVAL;
}
ret = as3722_read(as3722, reg, &val);
if (ret < 0) {
dev_err(as3722_regs->dev, "Reg 0x%02x read failed: %d\n",
reg, ret);
return ret;
}
val &= mask;
val >>= ffs(mask) - 1;
if (val == 3)
return -EINVAL;
return as3722_sd016_current[val];
}
static int as3722_sd016_set_current_limit(struct regulator_dev *rdev,
int min_uA, int max_uA)
{
struct as3722_regulators *as3722_regs = rdev_get_drvdata(rdev);
struct as3722 *as3722 = as3722_regs->as3722;
int id = rdev_get_id(rdev);
int ret;
int val;
int mask;
u32 reg;
ret = as3722_current_to_index(min_uA, max_uA, as3722_sd016_current,
ARRAY_SIZE(as3722_sd016_current));
if (ret < 0) {
dev_err(as3722_regs->dev,
"Current range min:max = %d:%d does not support\n",
min_uA, max_uA);
return ret;
}
switch (id) {
case AS3722_REGULATOR_ID_SD0:
reg = AS3722_OVCURRENT_REG;
mask = AS3722_OVCURRENT_SD0_TRIP_MASK;
break;
case AS3722_REGULATOR_ID_SD1:
reg = AS3722_OVCURRENT_REG;
mask = AS3722_OVCURRENT_SD1_TRIP_MASK;
break;
case AS3722_REGULATOR_ID_SD6:
reg = AS3722_OVCURRENT_DEB_REG;
mask = AS3722_OVCURRENT_SD6_TRIP_MASK;
break;
default:
return -EINVAL;
}
val = ret & mask;
val <<= ffs(mask) - 1;
return as3722_update_bits(as3722, reg, mask, val);
}
static const struct regulator_linear_range as3722_sd2345_ranges[] = {
REGULATOR_LINEAR_RANGE(612500, 0x01, 0x40, 12500),
REGULATOR_LINEAR_RANGE(1425000, 0x41, 0x70, 25000),
REGULATOR_LINEAR_RANGE(2650000, 0x71, 0x7F, 50000),
};
static struct regulator_ops as3722_sd016_ops = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_current_limit = as3722_sd016_get_current_limit,
.set_current_limit = as3722_sd016_set_current_limit,
.get_mode = as3722_sd_get_mode,
.set_mode = as3722_sd_set_mode,
};
static struct regulator_ops as3722_sd016_extcntrl_ops = {
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_current_limit = as3722_sd016_get_current_limit,
.set_current_limit = as3722_sd016_set_current_limit,
.get_mode = as3722_sd_get_mode,
.set_mode = as3722_sd_set_mode,
};
static struct regulator_ops as3722_sd2345_ops = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.list_voltage = regulator_list_voltage_linear_range,
.map_voltage = regulator_map_voltage_linear_range,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.get_mode = as3722_sd_get_mode,
.set_mode = as3722_sd_set_mode,
};
static struct regulator_ops as3722_sd2345_extcntrl_ops = {
.list_voltage = regulator_list_voltage_linear_range,
.map_voltage = regulator_map_voltage_linear_range,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.get_mode = as3722_sd_get_mode,
.set_mode = as3722_sd_set_mode,
};
static int as3722_extreg_init(struct as3722_regulators *as3722_regs, int id,
int ext_pwr_ctrl)
{
int ret;
unsigned int val;
if ((ext_pwr_ctrl < AS3722_EXT_CONTROL_ENABLE1) ||
(ext_pwr_ctrl > AS3722_EXT_CONTROL_ENABLE3))
return -EINVAL;
val = ext_pwr_ctrl << (ffs(as3722_reg_lookup[id].sleep_ctrl_mask) - 1);
ret = as3722_update_bits(as3722_regs->as3722,
as3722_reg_lookup[id].sleep_ctrl_reg,
as3722_reg_lookup[id].sleep_ctrl_mask, val);
if (ret < 0)
dev_err(as3722_regs->dev, "Reg 0x%02x update failed: %d\n",
as3722_reg_lookup[id].sleep_ctrl_reg, ret);
return ret;
}
static struct of_regulator_match as3722_regulator_matches[] = {
{ .name = "sd0", },
{ .name = "sd1", },
{ .name = "sd2", },
{ .name = "sd3", },
{ .name = "sd4", },
{ .name = "sd5", },
{ .name = "sd6", },
{ .name = "ldo0", },
{ .name = "ldo1", },
{ .name = "ldo2", },
{ .name = "ldo3", },
{ .name = "ldo4", },
{ .name = "ldo5", },
{ .name = "ldo6", },
{ .name = "ldo7", },
{ .name = "ldo9", },
{ .name = "ldo10", },
{ .name = "ldo11", },
};
static int as3722_get_regulator_dt_data(struct platform_device *pdev,
struct as3722_regulators *as3722_regs)
{
struct device_node *np;
struct as3722_regulator_config_data *reg_config;
u32 prop;
int id;
int ret;
np = of_get_child_by_name(pdev->dev.parent->of_node, "regulators");
if (!np) {
dev_err(&pdev->dev, "Device is not having regulators node\n");
return -ENODEV;
}
pdev->dev.of_node = np;
ret = of_regulator_match(&pdev->dev, np, as3722_regulator_matches,
ARRAY_SIZE(as3722_regulator_matches));
if (ret < 0) {
dev_err(&pdev->dev, "Parsing of regulator node failed: %d\n",
ret);
return ret;
}
for (id = 0; id < ARRAY_SIZE(as3722_regulator_matches); ++id) {
struct device_node *reg_node;
reg_config = &as3722_regs->reg_config_data[id];
reg_config->reg_init = as3722_regulator_matches[id].init_data;
reg_node = as3722_regulator_matches[id].of_node;
if (!reg_config->reg_init || !reg_node)
continue;
ret = of_property_read_u32(reg_node, "ams,ext-control", &prop);
if (!ret) {
if (prop < 3)
reg_config->ext_control = prop;
else
dev_warn(&pdev->dev,
"ext-control have invalid option: %u\n",
prop);
}
reg_config->enable_tracking =
of_property_read_bool(reg_node, "ams,enable-tracking");
}
return 0;
}
static int as3722_regulator_probe(struct platform_device *pdev)
{
struct as3722 *as3722 = dev_get_drvdata(pdev->dev.parent);
struct as3722_regulators *as3722_regs;
struct as3722_regulator_config_data *reg_config;
struct regulator_dev *rdev;
struct regulator_config config = { };
struct regulator_ops *ops;
int id;
int ret;
as3722_regs = devm_kzalloc(&pdev->dev, sizeof(*as3722_regs),
GFP_KERNEL);
if (!as3722_regs)
return -ENOMEM;
as3722_regs->dev = &pdev->dev;
as3722_regs->as3722 = as3722;
platform_set_drvdata(pdev, as3722_regs);
ret = as3722_get_regulator_dt_data(pdev, as3722_regs);
if (ret < 0)
return ret;
config.dev = &pdev->dev;
config.driver_data = as3722_regs;
config.regmap = as3722->regmap;
for (id = 0; id < AS3722_REGULATOR_ID_MAX; id++) {
reg_config = &as3722_regs->reg_config_data[id];
as3722_regs->desc[id].name = as3722_reg_lookup[id].name;
as3722_regs->desc[id].supply_name = as3722_reg_lookup[id].sname;
as3722_regs->desc[id].id = as3722_reg_lookup[id].regulator_id;
as3722_regs->desc[id].n_voltages =
as3722_reg_lookup[id].n_voltages;
as3722_regs->desc[id].type = REGULATOR_VOLTAGE;
as3722_regs->desc[id].owner = THIS_MODULE;
as3722_regs->desc[id].enable_reg =
as3722_reg_lookup[id].enable_reg;
as3722_regs->desc[id].enable_mask =
as3722_reg_lookup[id].enable_mask;
as3722_regs->desc[id].vsel_reg = as3722_reg_lookup[id].vsel_reg;
as3722_regs->desc[id].vsel_mask =
as3722_reg_lookup[id].vsel_mask;
switch (id) {
case AS3722_REGULATOR_ID_LDO0:
if (reg_config->ext_control)
ops = &as3722_ldo0_extcntrl_ops;
else
ops = &as3722_ldo0_ops;
as3722_regs->desc[id].min_uV = 825000;
as3722_regs->desc[id].uV_step = 25000;
as3722_regs->desc[id].linear_min_sel = 1;
as3722_regs->desc[id].enable_time = 500;
break;
case AS3722_REGULATOR_ID_LDO3:
if (reg_config->ext_control)
ops = &as3722_ldo3_extcntrl_ops;
else
ops = &as3722_ldo3_ops;
as3722_regs->desc[id].min_uV = 620000;
as3722_regs->desc[id].uV_step = 20000;
as3722_regs->desc[id].linear_min_sel = 1;
as3722_regs->desc[id].enable_time = 500;
if (reg_config->enable_tracking) {
ret = as3722_ldo3_set_tracking_mode(as3722_regs,
id, AS3722_LDO3_MODE_PMOS_TRACKING);
if (ret < 0) {
dev_err(&pdev->dev,
"LDO3 tracking failed: %d\n",
ret);
return ret;
}
}
break;
case AS3722_REGULATOR_ID_SD0:
case AS3722_REGULATOR_ID_SD1:
case AS3722_REGULATOR_ID_SD6:
if (reg_config->ext_control)
ops = &as3722_sd016_extcntrl_ops;
else
ops = &as3722_sd016_ops;
as3722_regs->desc[id].min_uV = 610000;
as3722_regs->desc[id].uV_step = 10000;
as3722_regs->desc[id].linear_min_sel = 1;
break;
case AS3722_REGULATOR_ID_SD2:
case AS3722_REGULATOR_ID_SD3:
case AS3722_REGULATOR_ID_SD4:
case AS3722_REGULATOR_ID_SD5:
if (reg_config->ext_control)
ops = &as3722_sd2345_extcntrl_ops;
else
ops = &as3722_sd2345_ops;
as3722_regs->desc[id].linear_ranges =
as3722_sd2345_ranges;
as3722_regs->desc[id].n_linear_ranges =
ARRAY_SIZE(as3722_sd2345_ranges);
break;
default:
if (reg_config->ext_control)
ops = &as3722_ldo_extcntrl_ops;
else
ops = &as3722_ldo_ops;
as3722_regs->desc[id].min_uV = 825000;
as3722_regs->desc[id].uV_step = 25000;
as3722_regs->desc[id].linear_min_sel = 1;
as3722_regs->desc[id].enable_time = 500;
as3722_regs->desc[id].linear_ranges = as3722_ldo_ranges;
as3722_regs->desc[id].n_linear_ranges =
ARRAY_SIZE(as3722_ldo_ranges);
break;
}
as3722_regs->desc[id].ops = ops;
config.init_data = reg_config->reg_init;
config.of_node = as3722_regulator_matches[id].of_node;
rdev = devm_regulator_register(&pdev->dev,
&as3722_regs->desc[id], &config);
if (IS_ERR(rdev)) {
ret = PTR_ERR(rdev);
dev_err(&pdev->dev, "regulator %d register failed %d\n",
id, ret);
return ret;
}
as3722_regs->rdevs[id] = rdev;
if (reg_config->ext_control) {
ret = regulator_enable_regmap(rdev);
if (ret < 0) {
dev_err(&pdev->dev,
"Regulator %d enable failed: %d\n",
id, ret);
return ret;
}
ret = as3722_extreg_init(as3722_regs, id,
reg_config->ext_control);
if (ret < 0) {
dev_err(&pdev->dev,
"AS3722 ext control failed: %d", ret);
return ret;
}
}
}
return 0;
}
static const struct of_device_id of_as3722_regulator_match[] = {
{ .compatible = "ams,as3722-regulator", },
{},
};
MODULE_DEVICE_TABLE(of, of_as3722_regulator_match);
static struct platform_driver as3722_regulator_driver = {
.driver = {
.name = "as3722-regulator",
.owner = THIS_MODULE,
.of_match_table = of_as3722_regulator_match,
},
.probe = as3722_regulator_probe,
};
module_platform_driver(as3722_regulator_driver);
MODULE_ALIAS("platform:as3722-regulator");
MODULE_DESCRIPTION("AS3722 regulator driver");
MODULE_AUTHOR("Florian Lobmaier <florian.lobmaier@ams.com>");
MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
MODULE_LICENSE("GPL");

View File

@ -36,6 +36,7 @@
#include <trace/events/regulator.h>
#include "dummy.h"
#include "internal.h"
#define rdev_crit(rdev, fmt, ...) \
pr_crit("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
@ -52,8 +53,8 @@ static DEFINE_MUTEX(regulator_list_mutex);
static LIST_HEAD(regulator_list);
static LIST_HEAD(regulator_map_list);
static LIST_HEAD(regulator_ena_gpio_list);
static LIST_HEAD(regulator_supply_alias_list);
static bool has_full_constraints;
static bool board_wants_dummy_regulator;
static struct dentry *debugfs_root;
@ -83,22 +84,16 @@ struct regulator_enable_gpio {
};
/*
* struct regulator
* struct regulator_supply_alias
*
* One for each consumer device.
* Used to map lookups for a supply onto an alternative device.
*/
struct regulator {
struct device *dev;
struct regulator_supply_alias {
struct list_head list;
unsigned int always_on:1;
unsigned int bypass:1;
int uA_load;
int min_uV;
int max_uV;
char *supply_name;
struct device_attribute dev_attr;
struct regulator_dev *rdev;
struct dentry *debugfs;
struct device *src_dev;
const char *src_supply;
struct device *alias_dev;
const char *alias_supply;
};
static int _regulator_is_enabled(struct regulator_dev *rdev);
@ -923,6 +918,36 @@ static int machine_constraints_voltage(struct regulator_dev *rdev,
return 0;
}
static int machine_constraints_current(struct regulator_dev *rdev,
struct regulation_constraints *constraints)
{
struct regulator_ops *ops = rdev->desc->ops;
int ret;
if (!constraints->min_uA && !constraints->max_uA)
return 0;
if (constraints->min_uA > constraints->max_uA) {
rdev_err(rdev, "Invalid current constraints\n");
return -EINVAL;
}
if (!ops->set_current_limit || !ops->get_current_limit) {
rdev_warn(rdev, "Operation of current configuration missing\n");
return 0;
}
/* Set regulator current in constraints range */
ret = ops->set_current_limit(rdev, constraints->min_uA,
constraints->max_uA);
if (ret < 0) {
rdev_err(rdev, "Failed to set current constraint, %d\n", ret);
return ret;
}
return 0;
}
/**
* set_machine_constraints - sets regulator constraints
* @rdev: regulator source
@ -953,6 +978,10 @@ static int set_machine_constraints(struct regulator_dev *rdev,
if (ret != 0)
goto out;
ret = machine_constraints_current(rdev, rdev->constraints);
if (ret != 0)
goto out;
/* do we need to setup our suspend state */
if (rdev->constraints->initial_state) {
ret = suspend_prepare(rdev, rdev->constraints->initial_state);
@ -1186,11 +1215,39 @@ overflow_err:
static int _regulator_get_enable_time(struct regulator_dev *rdev)
{
if (rdev->constraints && rdev->constraints->enable_time)
return rdev->constraints->enable_time;
if (!rdev->desc->ops->enable_time)
return rdev->desc->enable_time;
return rdev->desc->ops->enable_time(rdev);
}
static struct regulator_supply_alias *regulator_find_supply_alias(
struct device *dev, const char *supply)
{
struct regulator_supply_alias *map;
list_for_each_entry(map, &regulator_supply_alias_list, list)
if (map->src_dev == dev && strcmp(map->src_supply, supply) == 0)
return map;
return NULL;
}
static void regulator_supply_alias(struct device **dev, const char **supply)
{
struct regulator_supply_alias *map;
map = regulator_find_supply_alias(*dev, *supply);
if (map) {
dev_dbg(*dev, "Mapping supply %s to %s,%s\n",
*supply, map->alias_supply,
dev_name(map->alias_dev));
*dev = map->alias_dev;
*supply = map->alias_supply;
}
}
static struct regulator_dev *regulator_dev_lookup(struct device *dev,
const char *supply,
int *ret)
@ -1200,6 +1257,8 @@ static struct regulator_dev *regulator_dev_lookup(struct device *dev,
struct regulator_map *map;
const char *devname = NULL;
regulator_supply_alias(&dev, &supply);
/* first do a dt based lookup */
if (dev && dev->of_node) {
node = of_get_regulator(dev, supply);
@ -1243,16 +1302,16 @@ static struct regulator_dev *regulator_dev_lookup(struct device *dev,
/* Internal regulator request function */
static struct regulator *_regulator_get(struct device *dev, const char *id,
bool exclusive)
bool exclusive, bool allow_dummy)
{
struct regulator_dev *rdev;
struct regulator *regulator = ERR_PTR(-EPROBE_DEFER);
const char *devname = NULL;
int ret = 0;
int ret = -EPROBE_DEFER;
if (id == NULL) {
pr_err("get() with no identifier\n");
return regulator;
return ERR_PTR(-EINVAL);
}
if (dev)
@ -1264,34 +1323,32 @@ static struct regulator *_regulator_get(struct device *dev, const char *id,
if (rdev)
goto found;
regulator = ERR_PTR(ret);
/*
* If we have return value from dev_lookup fail, we do not expect to
* succeed, so, quit with appropriate error value
*/
if (ret) {
regulator = ERR_PTR(ret);
if (ret && ret != -ENODEV) {
goto out;
}
if (board_wants_dummy_regulator) {
rdev = dummy_regulator_rdev;
goto found;
}
#ifdef CONFIG_REGULATOR_DUMMY
if (!devname)
devname = "deviceless";
/* If the board didn't flag that it was fully constrained then
* substitute in a dummy regulator so consumers can continue.
/*
* Assume that a regulator is physically present and enabled
* even if it isn't hooked up and just provide a dummy.
*/
if (!has_full_constraints) {
if (has_full_constraints && allow_dummy) {
pr_warn("%s supply %s not found, using dummy regulator\n",
devname, id);
rdev = dummy_regulator_rdev;
goto found;
} else {
dev_err(dev, "dummy supplies not allowed\n");
}
#endif
mutex_unlock(&regulator_list_mutex);
return regulator;
@ -1349,44 +1406,10 @@ out:
*/
struct regulator *regulator_get(struct device *dev, const char *id)
{
return _regulator_get(dev, id, false);
return _regulator_get(dev, id, false, true);
}
EXPORT_SYMBOL_GPL(regulator_get);
static void devm_regulator_release(struct device *dev, void *res)
{
regulator_put(*(struct regulator **)res);
}
/**
* devm_regulator_get - Resource managed regulator_get()
* @dev: device for regulator "consumer"
* @id: Supply name or regulator ID.
*
* Managed regulator_get(). Regulators returned from this function are
* automatically regulator_put() on driver detach. See regulator_get() for more
* information.
*/
struct regulator *devm_regulator_get(struct device *dev, const char *id)
{
struct regulator **ptr, *regulator;
ptr = devres_alloc(devm_regulator_release, sizeof(*ptr), GFP_KERNEL);
if (!ptr)
return ERR_PTR(-ENOMEM);
regulator = regulator_get(dev, id);
if (!IS_ERR(regulator)) {
*ptr = regulator;
devres_add(dev, ptr);
} else {
devres_free(ptr);
}
return regulator;
}
EXPORT_SYMBOL_GPL(devm_regulator_get);
/**
* regulator_get_exclusive - obtain exclusive access to a regulator.
* @dev: device for regulator "consumer"
@ -1410,7 +1433,7 @@ EXPORT_SYMBOL_GPL(devm_regulator_get);
*/
struct regulator *regulator_get_exclusive(struct device *dev, const char *id)
{
return _regulator_get(dev, id, true);
return _regulator_get(dev, id, true, false);
}
EXPORT_SYMBOL_GPL(regulator_get_exclusive);
@ -1439,40 +1462,10 @@ EXPORT_SYMBOL_GPL(regulator_get_exclusive);
*/
struct regulator *regulator_get_optional(struct device *dev, const char *id)
{
return _regulator_get(dev, id, 0);
return _regulator_get(dev, id, false, false);
}
EXPORT_SYMBOL_GPL(regulator_get_optional);
/**
* devm_regulator_get_optional - Resource managed regulator_get_optional()
* @dev: device for regulator "consumer"
* @id: Supply name or regulator ID.
*
* Managed regulator_get_optional(). Regulators returned from this
* function are automatically regulator_put() on driver detach. See
* regulator_get_optional() for more information.
*/
struct regulator *devm_regulator_get_optional(struct device *dev,
const char *id)
{
struct regulator **ptr, *regulator;
ptr = devres_alloc(devm_regulator_release, sizeof(*ptr), GFP_KERNEL);
if (!ptr)
return ERR_PTR(-ENOMEM);
regulator = regulator_get_optional(dev, id);
if (!IS_ERR(regulator)) {
*ptr = regulator;
devres_add(dev, ptr);
} else {
devres_free(ptr);
}
return regulator;
}
EXPORT_SYMBOL_GPL(devm_regulator_get_optional);
/* Locks held by regulator_put() */
static void _regulator_put(struct regulator *regulator)
{
@ -1498,36 +1491,6 @@ static void _regulator_put(struct regulator *regulator)
module_put(rdev->owner);
}
/**
* devm_regulator_get_exclusive - Resource managed regulator_get_exclusive()
* @dev: device for regulator "consumer"
* @id: Supply name or regulator ID.
*
* Managed regulator_get_exclusive(). Regulators returned from this function
* are automatically regulator_put() on driver detach. See regulator_get() for
* more information.
*/
struct regulator *devm_regulator_get_exclusive(struct device *dev,
const char *id)
{
struct regulator **ptr, *regulator;
ptr = devres_alloc(devm_regulator_release, sizeof(*ptr), GFP_KERNEL);
if (!ptr)
return ERR_PTR(-ENOMEM);
regulator = _regulator_get(dev, id, 1);
if (!IS_ERR(regulator)) {
*ptr = regulator;
devres_add(dev, ptr);
} else {
devres_free(ptr);
}
return regulator;
}
EXPORT_SYMBOL_GPL(devm_regulator_get_exclusive);
/**
* regulator_put - "free" the regulator source
* @regulator: regulator source
@ -1544,34 +1507,133 @@ void regulator_put(struct regulator *regulator)
}
EXPORT_SYMBOL_GPL(regulator_put);
static int devm_regulator_match(struct device *dev, void *res, void *data)
/**
* regulator_register_supply_alias - Provide device alias for supply lookup
*
* @dev: device that will be given as the regulator "consumer"
* @id: Supply name or regulator ID
* @alias_dev: device that should be used to lookup the supply
* @alias_id: Supply name or regulator ID that should be used to lookup the
* supply
*
* All lookups for id on dev will instead be conducted for alias_id on
* alias_dev.
*/
int regulator_register_supply_alias(struct device *dev, const char *id,
struct device *alias_dev,
const char *alias_id)
{
struct regulator **r = res;
if (!r || !*r) {
WARN_ON(!r || !*r);
return 0;
}
return *r == data;
struct regulator_supply_alias *map;
map = regulator_find_supply_alias(dev, id);
if (map)
return -EEXIST;
map = kzalloc(sizeof(struct regulator_supply_alias), GFP_KERNEL);
if (!map)
return -ENOMEM;
map->src_dev = dev;
map->src_supply = id;
map->alias_dev = alias_dev;
map->alias_supply = alias_id;
list_add(&map->list, &regulator_supply_alias_list);
pr_info("Adding alias for supply %s,%s -> %s,%s\n",
id, dev_name(dev), alias_id, dev_name(alias_dev));
return 0;
}
EXPORT_SYMBOL_GPL(regulator_register_supply_alias);
/**
* devm_regulator_put - Resource managed regulator_put()
* @regulator: regulator to free
* regulator_unregister_supply_alias - Remove device alias
*
* Deallocate a regulator allocated with devm_regulator_get(). Normally
* this function will not need to be called and the resource management
* code will ensure that the resource is freed.
* @dev: device that will be given as the regulator "consumer"
* @id: Supply name or regulator ID
*
* Remove a lookup alias if one exists for id on dev.
*/
void devm_regulator_put(struct regulator *regulator)
void regulator_unregister_supply_alias(struct device *dev, const char *id)
{
int rc;
struct regulator_supply_alias *map;
rc = devres_release(regulator->dev, devm_regulator_release,
devm_regulator_match, regulator);
if (rc != 0)
WARN_ON(rc);
map = regulator_find_supply_alias(dev, id);
if (map) {
list_del(&map->list);
kfree(map);
}
}
EXPORT_SYMBOL_GPL(devm_regulator_put);
EXPORT_SYMBOL_GPL(regulator_unregister_supply_alias);
/**
* regulator_bulk_register_supply_alias - register multiple aliases
*
* @dev: device that will be given as the regulator "consumer"
* @id: List of supply names or regulator IDs
* @alias_dev: device that should be used to lookup the supply
* @alias_id: List of supply names or regulator IDs that should be used to
* lookup the supply
* @num_id: Number of aliases to register
*
* @return 0 on success, an errno on failure.
*
* This helper function allows drivers to register several supply
* aliases in one operation. If any of the aliases cannot be
* registered any aliases that were registered will be removed
* before returning to the caller.
*/
int regulator_bulk_register_supply_alias(struct device *dev, const char **id,
struct device *alias_dev,
const char **alias_id,
int num_id)
{
int i;
int ret;
for (i = 0; i < num_id; ++i) {
ret = regulator_register_supply_alias(dev, id[i], alias_dev,
alias_id[i]);
if (ret < 0)
goto err;
}
return 0;
err:
dev_err(dev,
"Failed to create supply alias %s,%s -> %s,%s\n",
id[i], dev_name(dev), alias_id[i], dev_name(alias_dev));
while (--i >= 0)
regulator_unregister_supply_alias(dev, id[i]);
return ret;
}
EXPORT_SYMBOL_GPL(regulator_bulk_register_supply_alias);
/**
* regulator_bulk_unregister_supply_alias - unregister multiple aliases
*
* @dev: device that will be given as the regulator "consumer"
* @id: List of supply names or regulator IDs
* @num_id: Number of aliases to unregister
*
* This helper function allows drivers to unregister several supply
* aliases in one operation.
*/
void regulator_bulk_unregister_supply_alias(struct device *dev,
const char **id,
int num_id)
{
int i;
for (i = 0; i < num_id; ++i)
regulator_unregister_supply_alias(dev, id[i]);
}
EXPORT_SYMBOL_GPL(regulator_bulk_unregister_supply_alias);
/* Manage enable GPIO list. Same GPIO pin can be shared among regulators */
static int regulator_ena_gpio_request(struct regulator_dev *rdev,
@ -1704,11 +1766,39 @@ static int _regulator_do_enable(struct regulator_dev *rdev)
* together. */
trace_regulator_enable_delay(rdev_get_name(rdev));
if (delay >= 1000) {
mdelay(delay / 1000);
udelay(delay % 1000);
} else if (delay) {
udelay(delay);
/*
* Delay for the requested amount of time as per the guidelines in:
*
* Documentation/timers/timers-howto.txt
*
* The assumption here is that regulators will never be enabled in
* atomic context and therefore sleeping functions can be used.
*/
if (delay) {
unsigned int ms = delay / 1000;
unsigned int us = delay % 1000;
if (ms > 0) {
/*
* For small enough values, handle super-millisecond
* delays in the usleep_range() call below.
*/
if (ms < 20)
us += ms * 1000;
else
msleep(ms);
}
/*
* Give the scheduler some room to coalesce with any other
* wakeup sources. For delays shorter than 10 us, don't even
* bother setting up high-resolution timers and just busy-
* loop.
*/
if (us >= 10)
usleep_range(us, us + 100);
else
udelay(us);
}
trace_regulator_enable_complete(rdev_get_name(rdev));
@ -2489,6 +2579,8 @@ static int _regulator_get_voltage(struct regulator_dev *rdev)
ret = rdev->desc->ops->get_voltage(rdev);
} else if (rdev->desc->ops->list_voltage) {
ret = rdev->desc->ops->list_voltage(rdev, 0);
} else if (rdev->desc->fixed_uV && (rdev->desc->n_voltages == 1)) {
ret = rdev->desc->fixed_uV;
} else {
return -EINVAL;
}
@ -2912,52 +3004,6 @@ err:
}
EXPORT_SYMBOL_GPL(regulator_bulk_get);
/**
* devm_regulator_bulk_get - managed get multiple regulator consumers
*
* @dev: Device to supply
* @num_consumers: Number of consumers to register
* @consumers: Configuration of consumers; clients are stored here.
*
* @return 0 on success, an errno on failure.
*
* This helper function allows drivers to get several regulator
* consumers in one operation with management, the regulators will
* automatically be freed when the device is unbound. If any of the
* regulators cannot be acquired then any regulators that were
* allocated will be freed before returning to the caller.
*/
int devm_regulator_bulk_get(struct device *dev, int num_consumers,
struct regulator_bulk_data *consumers)
{
int i;
int ret;
for (i = 0; i < num_consumers; i++)
consumers[i].consumer = NULL;
for (i = 0; i < num_consumers; i++) {
consumers[i].consumer = devm_regulator_get(dev,
consumers[i].supply);
if (IS_ERR(consumers[i].consumer)) {
ret = PTR_ERR(consumers[i].consumer);
dev_err(dev, "Failed to get supply '%s': %d\n",
consumers[i].supply, ret);
consumers[i].consumer = NULL;
goto err;
}
}
return 0;
err:
for (i = 0; i < num_consumers && consumers[i].consumer; i++)
devm_regulator_put(consumers[i].consumer);
return ret;
}
EXPORT_SYMBOL_GPL(devm_regulator_bulk_get);
static void regulator_bulk_enable_async(void *data, async_cookie_t cookie)
{
struct regulator_bulk_data *bulk = data;
@ -3170,7 +3216,8 @@ static int add_regulator_attributes(struct regulator_dev *rdev)
/* some attributes need specific methods to be displayed */
if ((ops->get_voltage && ops->get_voltage(rdev) >= 0) ||
(ops->get_voltage_sel && ops->get_voltage_sel(rdev) >= 0) ||
(ops->list_voltage && ops->list_voltage(rdev, 0) >= 0)) {
(ops->list_voltage && ops->list_voltage(rdev, 0) >= 0) ||
(rdev->desc->fixed_uV && (rdev->desc->n_voltages == 1))) {
status = device_create_file(dev, &dev_attr_microvolts);
if (status < 0)
return status;
@ -3613,22 +3660,6 @@ void regulator_has_full_constraints(void)
}
EXPORT_SYMBOL_GPL(regulator_has_full_constraints);
/**
* regulator_use_dummy_regulator - Provide a dummy regulator when none is found
*
* Calling this function will cause the regulator API to provide a
* dummy regulator to consumers if no physical regulator is found,
* allowing most consumers to proceed as though a regulator were
* configured. This allows systems such as those with software
* controllable regulators for the CPU core only to be brought up more
* readily.
*/
void regulator_use_dummy_regulator(void)
{
board_wants_dummy_regulator = true;
}
EXPORT_SYMBOL_GPL(regulator_use_dummy_regulator);
/**
* rdev_get_drvdata - get rdev regulator driver data
* @rdev: regulator

View File

@ -253,10 +253,8 @@ static int da9034_set_dvc_voltage_sel(struct regulator_dev *rdev,
}
static const struct regulator_linear_range da9034_ldo12_ranges[] = {
{ .min_uV = 1700000, .max_uV = 2050000, .min_sel = 0, .max_sel = 7,
.uV_step = 50000 },
{ .min_uV = 2700000, .max_uV = 3050000, .min_sel = 8, .max_sel = 15,
.uV_step = 50000 },
REGULATOR_LINEAR_RANGE(1700000, 0, 7, 50000),
REGULATOR_LINEAR_RANGE(2700000, 8, 15, 50000),
};
static struct regulator_ops da903x_regulator_ldo_ops = {
@ -463,7 +461,7 @@ static int da903x_regulator_probe(struct platform_device *pdev)
config.init_data = dev_get_platdata(&pdev->dev);
config.driver_data = ri;
rdev = regulator_register(&ri->desc, &config);
rdev = devm_regulator_register(&pdev->dev, &ri->desc, &config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "failed to register regulator %s\n",
ri->desc.name);
@ -474,21 +472,12 @@ static int da903x_regulator_probe(struct platform_device *pdev)
return 0;
}
static int da903x_regulator_remove(struct platform_device *pdev)
{
struct regulator_dev *rdev = platform_get_drvdata(pdev);
regulator_unregister(rdev);
return 0;
}
static struct platform_driver da903x_regulator_driver = {
.driver = {
.name = "da903x-regulator",
.owner = THIS_MODULE,
},
.probe = da903x_regulator_probe,
.remove = da903x_regulator_remove,
};
static int __init da903x_regulator_init(void)

View File

@ -70,6 +70,7 @@ struct da9052_regulator_info {
int step_uV;
int min_uV;
int max_uV;
unsigned char activate_bit;
};
struct da9052_regulator {
@ -209,6 +210,36 @@ static int da9052_map_voltage(struct regulator_dev *rdev,
return sel;
}
static int da9052_regulator_set_voltage_sel(struct regulator_dev *rdev,
unsigned int selector)
{
struct da9052_regulator *regulator = rdev_get_drvdata(rdev);
struct da9052_regulator_info *info = regulator->info;
int id = rdev_get_id(rdev);
int ret;
ret = da9052_reg_update(regulator->da9052, rdev->desc->vsel_reg,
rdev->desc->vsel_mask, selector);
if (ret < 0)
return ret;
/* Some LDOs and DCDCs are DVC controlled which requires enabling of
* the activate bit to implment the changes on the output.
*/
switch (id) {
case DA9052_ID_BUCK1:
case DA9052_ID_BUCK2:
case DA9052_ID_BUCK3:
case DA9052_ID_LDO2:
case DA9052_ID_LDO3:
ret = da9052_reg_update(regulator->da9052, DA9052_SUPPLY_REG,
info->activate_bit, info->activate_bit);
break;
}
return ret;
}
static struct regulator_ops da9052_dcdc_ops = {
.get_current_limit = da9052_dcdc_get_current_limit,
.set_current_limit = da9052_dcdc_set_current_limit,
@ -216,7 +247,7 @@ static struct regulator_ops da9052_dcdc_ops = {
.list_voltage = da9052_list_voltage,
.map_voltage = da9052_map_voltage,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.set_voltage_sel = da9052_regulator_set_voltage_sel,
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
@ -226,7 +257,7 @@ static struct regulator_ops da9052_ldo_ops = {
.list_voltage = da9052_list_voltage,
.map_voltage = da9052_map_voltage,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.set_voltage_sel = da9052_regulator_set_voltage_sel,
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
@ -243,14 +274,13 @@ static struct regulator_ops da9052_ldo_ops = {
.owner = THIS_MODULE,\
.vsel_reg = DA9052_BUCKCORE_REG + DA9052_ID_##_id, \
.vsel_mask = (1 << (sbits)) - 1,\
.apply_reg = DA9052_SUPPLY_REG, \
.apply_bit = (abits), \
.enable_reg = DA9052_BUCKCORE_REG + DA9052_ID_##_id, \
.enable_mask = 1 << (ebits),\
},\
.min_uV = (min) * 1000,\
.max_uV = (max) * 1000,\
.step_uV = (step) * 1000,\
.activate_bit = (abits),\
}
#define DA9052_DCDC(_id, step, min, max, sbits, ebits, abits) \
@ -264,14 +294,13 @@ static struct regulator_ops da9052_ldo_ops = {
.owner = THIS_MODULE,\
.vsel_reg = DA9052_BUCKCORE_REG + DA9052_ID_##_id, \
.vsel_mask = (1 << (sbits)) - 1,\
.apply_reg = DA9052_SUPPLY_REG, \
.apply_bit = (abits), \
.enable_reg = DA9052_BUCKCORE_REG + DA9052_ID_##_id, \
.enable_mask = 1 << (ebits),\
},\
.min_uV = (min) * 1000,\
.max_uV = (max) * 1000,\
.step_uV = (step) * 1000,\
.activate_bit = (abits),\
}
static struct da9052_regulator_info da9052_regulator_info[] = {
@ -389,8 +418,9 @@ static int da9052_regulator_probe(struct platform_device *pdev)
#endif
}
regulator->rdev = regulator_register(&regulator->info->reg_desc,
&config);
regulator->rdev = devm_regulator_register(&pdev->dev,
&regulator->info->reg_desc,
&config);
if (IS_ERR(regulator->rdev)) {
dev_err(&pdev->dev, "failed to register regulator %s\n",
regulator->info->reg_desc.name);
@ -402,17 +432,8 @@ static int da9052_regulator_probe(struct platform_device *pdev)
return 0;
}
static int da9052_regulator_remove(struct platform_device *pdev)
{
struct da9052_regulator *regulator = platform_get_drvdata(pdev);
regulator_unregister(regulator->rdev);
return 0;
}
static struct platform_driver da9052_regulator_driver = {
.probe = da9052_regulator_probe,
.remove = da9052_regulator_remove,
.driver = {
.name = "da9052-regulator",
.owner = THIS_MODULE,

View File

@ -564,13 +564,13 @@ static int da9055_regulator_probe(struct platform_device *pdev)
if (ret < 0)
return ret;
regulator->rdev = regulator_register(&regulator->info->reg_desc,
&config);
regulator->rdev = devm_regulator_register(&pdev->dev,
&regulator->info->reg_desc,
&config);
if (IS_ERR(regulator->rdev)) {
dev_err(&pdev->dev, "Failed to register regulator %s\n",
regulator->info->reg_desc.name);
ret = PTR_ERR(regulator->rdev);
return ret;
return PTR_ERR(regulator->rdev);
}
/* Only LDO 5 and 6 has got the over current interrupt */
@ -588,32 +588,18 @@ static int da9055_regulator_probe(struct platform_device *pdev)
dev_err(&pdev->dev,
"Failed to request Regulator IRQ %d: %d\n",
irq, ret);
goto err_regulator;
return ret;
}
}
}
platform_set_drvdata(pdev, regulator);
return 0;
err_regulator:
regulator_unregister(regulator->rdev);
return ret;
}
static int da9055_regulator_remove(struct platform_device *pdev)
{
struct da9055_regulator *regulator = platform_get_drvdata(pdev);
regulator_unregister(regulator->rdev);
return 0;
}
static struct platform_driver da9055_regulator_driver = {
.probe = da9055_regulator_probe,
.remove = da9055_regulator_remove,
.driver = {
.name = "da9055-regulator",
.owner = THIS_MODULE,

View File

@ -717,7 +717,7 @@ static int da9063_regulator_probe(struct platform_device *pdev)
{
struct da9063 *da9063 = dev_get_drvdata(pdev->dev.parent);
struct da9063_pdata *da9063_pdata = dev_get_platdata(da9063->dev);
struct of_regulator_match *da9063_reg_matches;
struct of_regulator_match *da9063_reg_matches = NULL;
struct da9063_regulators_pdata *regl_pdata;
const struct da9063_dev_model *model;
struct da9063_regulators *regulators;
@ -847,13 +847,13 @@ static int da9063_regulator_probe(struct platform_device *pdev)
if (da9063_reg_matches)
config.of_node = da9063_reg_matches[id].of_node;
config.regmap = da9063->regmap;
regl->rdev = regulator_register(&regl->desc, &config);
regl->rdev = devm_regulator_register(&pdev->dev, &regl->desc,
&config);
if (IS_ERR(regl->rdev)) {
dev_err(&pdev->dev,
"Failed to register %s regulator\n",
regl->desc.name);
ret = PTR_ERR(regl->rdev);
goto err;
return PTR_ERR(regl->rdev);
}
id++;
n++;
@ -862,9 +862,8 @@ static int da9063_regulator_probe(struct platform_device *pdev)
/* LDOs overcurrent event support */
irq = platform_get_irq_byname(pdev, "LDO_LIM");
if (irq < 0) {
ret = irq;
dev_err(&pdev->dev, "Failed to get IRQ.\n");
goto err;
return irq;
}
regulators->irq_ldo_lim = regmap_irq_get_virq(da9063->regmap_irq, irq);
@ -881,27 +880,15 @@ static int da9063_regulator_probe(struct platform_device *pdev)
}
return 0;
err:
/* Wind back regulators registeration */
while (--n >= 0)
regulator_unregister(regulators->regulator[n].rdev);
return ret;
}
static int da9063_regulator_remove(struct platform_device *pdev)
{
struct da9063_regulators *regulators = platform_get_drvdata(pdev);
struct da9063_regulator *regl;
free_irq(regulators->irq_ldo_lim, regulators);
free_irq(regulators->irq_uvov, regulators);
for (regl = &regulators->regulator[regulators->n_regulators - 1];
regl >= &regulators->regulator[0]; regl--)
regulator_unregister(regl->rdev);
return 0;
}

View File

@ -25,6 +25,7 @@
#include <linux/slab.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>
#include <linux/regmap.h>
#include "da9210-regulator.h"
@ -126,7 +127,8 @@ static int da9210_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct da9210 *chip;
struct da9210_pdata *pdata = i2c->dev.platform_data;
struct device *dev = &i2c->dev;
struct da9210_pdata *pdata = dev_get_platdata(dev);
struct regulator_dev *rdev = NULL;
struct regulator_config config = { };
int error;
@ -147,12 +149,13 @@ static int da9210_i2c_probe(struct i2c_client *i2c,
}
config.dev = &i2c->dev;
if (pdata)
config.init_data = &pdata->da9210_constraints;
config.init_data = pdata ? &pdata->da9210_constraints :
of_get_regulator_init_data(dev, dev->of_node);
config.driver_data = chip;
config.regmap = chip->regmap;
config.of_node = dev->of_node;
rdev = regulator_register(&da9210_reg, &config);
rdev = devm_regulator_register(&i2c->dev, &da9210_reg, &config);
if (IS_ERR(rdev)) {
dev_err(&i2c->dev, "Failed to register DA9210 regulator\n");
return PTR_ERR(rdev);
@ -165,13 +168,6 @@ static int da9210_i2c_probe(struct i2c_client *i2c,
return 0;
}
static int da9210_i2c_remove(struct i2c_client *i2c)
{
struct da9210 *chip = i2c_get_clientdata(i2c);
regulator_unregister(chip->rdev);
return 0;
}
static const struct i2c_device_id da9210_i2c_id[] = {
{"da9210", 0},
{},
@ -185,7 +181,6 @@ static struct i2c_driver da9210_regulator_driver = {
.owner = THIS_MODULE,
},
.probe = da9210_i2c_probe,
.remove = da9210_i2c_remove,
.id_table = da9210_i2c_id,
};

415
drivers/regulator/devres.c Normal file
View File

@ -0,0 +1,415 @@
/*
* devres.c -- Voltage/Current Regulator framework devres implementation.
*
* Copyright 2013 Linaro Ltd
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
*/
#include <linux/kernel.h>
#include <linux/err.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/regulator/driver.h>
#include <linux/module.h>
#include "internal.h"
enum {
NORMAL_GET,
EXCLUSIVE_GET,
OPTIONAL_GET,
};
static void devm_regulator_release(struct device *dev, void *res)
{
regulator_put(*(struct regulator **)res);
}
static struct regulator *_devm_regulator_get(struct device *dev, const char *id,
int get_type)
{
struct regulator **ptr, *regulator;
ptr = devres_alloc(devm_regulator_release, sizeof(*ptr), GFP_KERNEL);
if (!ptr)
return ERR_PTR(-ENOMEM);
switch (get_type) {
case NORMAL_GET:
regulator = regulator_get(dev, id);
break;
case EXCLUSIVE_GET:
regulator = regulator_get_exclusive(dev, id);
break;
case OPTIONAL_GET:
regulator = regulator_get_optional(dev, id);
break;
default:
regulator = ERR_PTR(-EINVAL);
}
if (!IS_ERR(regulator)) {
*ptr = regulator;
devres_add(dev, ptr);
} else {
devres_free(ptr);
}
return regulator;
}
/**
* devm_regulator_get - Resource managed regulator_get()
* @dev: device for regulator "consumer"
* @id: Supply name or regulator ID.
*
* Managed regulator_get(). Regulators returned from this function are
* automatically regulator_put() on driver detach. See regulator_get() for more
* information.
*/
struct regulator *devm_regulator_get(struct device *dev, const char *id)
{
return _devm_regulator_get(dev, id, NORMAL_GET);
}
EXPORT_SYMBOL_GPL(devm_regulator_get);
/**
* devm_regulator_get_exclusive - Resource managed regulator_get_exclusive()
* @dev: device for regulator "consumer"
* @id: Supply name or regulator ID.
*
* Managed regulator_get_exclusive(). Regulators returned from this function
* are automatically regulator_put() on driver detach. See regulator_get() for
* more information.
*/
struct regulator *devm_regulator_get_exclusive(struct device *dev,
const char *id)
{
return _devm_regulator_get(dev, id, EXCLUSIVE_GET);
}
EXPORT_SYMBOL_GPL(devm_regulator_get_exclusive);
/**
* devm_regulator_get_optional - Resource managed regulator_get_optional()
* @dev: device for regulator "consumer"
* @id: Supply name or regulator ID.
*
* Managed regulator_get_optional(). Regulators returned from this
* function are automatically regulator_put() on driver detach. See
* regulator_get_optional() for more information.
*/
struct regulator *devm_regulator_get_optional(struct device *dev,
const char *id)
{
return _devm_regulator_get(dev, id, OPTIONAL_GET);
}
EXPORT_SYMBOL_GPL(devm_regulator_get_optional);
static int devm_regulator_match(struct device *dev, void *res, void *data)
{
struct regulator **r = res;
if (!r || !*r) {
WARN_ON(!r || !*r);
return 0;
}
return *r == data;
}
/**
* devm_regulator_put - Resource managed regulator_put()
* @regulator: regulator to free
*
* Deallocate a regulator allocated with devm_regulator_get(). Normally
* this function will not need to be called and the resource management
* code will ensure that the resource is freed.
*/
void devm_regulator_put(struct regulator *regulator)
{
int rc;
rc = devres_release(regulator->dev, devm_regulator_release,
devm_regulator_match, regulator);
if (rc != 0)
WARN_ON(rc);
}
EXPORT_SYMBOL_GPL(devm_regulator_put);
/**
* devm_regulator_bulk_get - managed get multiple regulator consumers
*
* @dev: Device to supply
* @num_consumers: Number of consumers to register
* @consumers: Configuration of consumers; clients are stored here.
*
* @return 0 on success, an errno on failure.
*
* This helper function allows drivers to get several regulator
* consumers in one operation with management, the regulators will
* automatically be freed when the device is unbound. If any of the
* regulators cannot be acquired then any regulators that were
* allocated will be freed before returning to the caller.
*/
int devm_regulator_bulk_get(struct device *dev, int num_consumers,
struct regulator_bulk_data *consumers)
{
int i;
int ret;
for (i = 0; i < num_consumers; i++)
consumers[i].consumer = NULL;
for (i = 0; i < num_consumers; i++) {
consumers[i].consumer = devm_regulator_get(dev,
consumers[i].supply);
if (IS_ERR(consumers[i].consumer)) {
ret = PTR_ERR(consumers[i].consumer);
dev_err(dev, "Failed to get supply '%s': %d\n",
consumers[i].supply, ret);
consumers[i].consumer = NULL;
goto err;
}
}
return 0;
err:
for (i = 0; i < num_consumers && consumers[i].consumer; i++)
devm_regulator_put(consumers[i].consumer);
return ret;
}
EXPORT_SYMBOL_GPL(devm_regulator_bulk_get);
static void devm_rdev_release(struct device *dev, void *res)
{
regulator_unregister(*(struct regulator_dev **)res);
}
/**
* devm_regulator_register - Resource managed regulator_register()
* @regulator_desc: regulator to register
* @config: runtime configuration for regulator
*
* Called by regulator drivers to register a regulator. Returns a
* valid pointer to struct regulator_dev on success or an ERR_PTR() on
* error. The regulator will automatically be released when the device
* is unbound.
*/
struct regulator_dev *devm_regulator_register(struct device *dev,
const struct regulator_desc *regulator_desc,
const struct regulator_config *config)
{
struct regulator_dev **ptr, *rdev;
ptr = devres_alloc(devm_rdev_release, sizeof(*ptr),
GFP_KERNEL);
if (!ptr)
return ERR_PTR(-ENOMEM);
rdev = regulator_register(regulator_desc, config);
if (!IS_ERR(rdev)) {
*ptr = rdev;
devres_add(dev, ptr);
} else {
devres_free(ptr);
}
return rdev;
}
EXPORT_SYMBOL_GPL(devm_regulator_register);
static int devm_rdev_match(struct device *dev, void *res, void *data)
{
struct regulator_dev **r = res;
if (!r || !*r) {
WARN_ON(!r || !*r);
return 0;
}
return *r == data;
}
/**
* devm_regulator_unregister - Resource managed regulator_unregister()
* @regulator: regulator to free
*
* Unregister a regulator registered with devm_regulator_register().
* Normally this function will not need to be called and the resource
* management code will ensure that the resource is freed.
*/
void devm_regulator_unregister(struct device *dev, struct regulator_dev *rdev)
{
int rc;
rc = devres_release(dev, devm_rdev_release, devm_rdev_match, rdev);
if (rc != 0)
WARN_ON(rc);
}
EXPORT_SYMBOL_GPL(devm_regulator_unregister);
struct regulator_supply_alias_match {
struct device *dev;
const char *id;
};
static int devm_regulator_match_supply_alias(struct device *dev, void *res,
void *data)
{
struct regulator_supply_alias_match *match = res;
struct regulator_supply_alias_match *target = data;
return match->dev == target->dev && strcmp(match->id, target->id) == 0;
}
static void devm_regulator_destroy_supply_alias(struct device *dev, void *res)
{
struct regulator_supply_alias_match *match = res;
regulator_unregister_supply_alias(match->dev, match->id);
}
/**
* devm_regulator_register_supply_alias - Resource managed
* regulator_register_supply_alias()
*
* @dev: device that will be given as the regulator "consumer"
* @id: Supply name or regulator ID
* @alias_dev: device that should be used to lookup the supply
* @alias_id: Supply name or regulator ID that should be used to lookup the
* supply
*
* The supply alias will automatically be unregistered when the source
* device is unbound.
*/
int devm_regulator_register_supply_alias(struct device *dev, const char *id,
struct device *alias_dev,
const char *alias_id)
{
struct regulator_supply_alias_match *match;
int ret;
match = devres_alloc(devm_regulator_destroy_supply_alias,
sizeof(struct regulator_supply_alias_match),
GFP_KERNEL);
if (!match)
return -ENOMEM;
match->dev = dev;
match->id = id;
ret = regulator_register_supply_alias(dev, id, alias_dev, alias_id);
if (ret < 0) {
devres_free(match);
return ret;
}
devres_add(dev, match);
return 0;
}
EXPORT_SYMBOL_GPL(devm_regulator_register_supply_alias);
/**
* devm_regulator_unregister_supply_alias - Resource managed
* regulator_unregister_supply_alias()
*
* @dev: device that will be given as the regulator "consumer"
* @id: Supply name or regulator ID
*
* Unregister an alias registered with
* devm_regulator_register_supply_alias(). Normally this function
* will not need to be called and the resource management code
* will ensure that the resource is freed.
*/
void devm_regulator_unregister_supply_alias(struct device *dev, const char *id)
{
struct regulator_supply_alias_match match;
int rc;
match.dev = dev;
match.id = id;
rc = devres_release(dev, devm_regulator_destroy_supply_alias,
devm_regulator_match_supply_alias, &match);
if (rc != 0)
WARN_ON(rc);
}
EXPORT_SYMBOL_GPL(devm_regulator_unregister_supply_alias);
/**
* devm_regulator_bulk_register_supply_alias - Managed register
* multiple aliases
*
* @dev: device that will be given as the regulator "consumer"
* @id: List of supply names or regulator IDs
* @alias_dev: device that should be used to lookup the supply
* @alias_id: List of supply names or regulator IDs that should be used to
* lookup the supply
* @num_id: Number of aliases to register
*
* @return 0 on success, an errno on failure.
*
* This helper function allows drivers to register several supply
* aliases in one operation, the aliases will be automatically
* unregisters when the source device is unbound. If any of the
* aliases cannot be registered any aliases that were registered
* will be removed before returning to the caller.
*/
int devm_regulator_bulk_register_supply_alias(struct device *dev,
const char **id,
struct device *alias_dev,
const char **alias_id,
int num_id)
{
int i;
int ret;
for (i = 0; i < num_id; ++i) {
ret = devm_regulator_register_supply_alias(dev, id[i],
alias_dev,
alias_id[i]);
if (ret < 0)
goto err;
}
return 0;
err:
dev_err(dev,
"Failed to create supply alias %s,%s -> %s,%s\n",
id[i], dev_name(dev), alias_id[i], dev_name(alias_dev));
while (--i >= 0)
devm_regulator_unregister_supply_alias(dev, id[i]);
return ret;
}
EXPORT_SYMBOL_GPL(devm_regulator_bulk_register_supply_alias);
/**
* devm_regulator_bulk_unregister_supply_alias - Managed unregister
* multiple aliases
*
* @dev: device that will be given as the regulator "consumer"
* @id: List of supply names or regulator IDs
* @num_id: Number of aliases to unregister
*
* Unregister aliases registered with
* devm_regulator_bulk_register_supply_alias(). Normally this function
* will not need to be called and the resource management code
* will ensure that the resource is freed.
*/
void devm_regulator_bulk_unregister_supply_alias(struct device *dev,
const char **id,
int num_id)
{
int i;
for (i = 0; i < num_id; ++i)
devm_regulator_unregister_supply_alias(dev, id[i]);
}
EXPORT_SYMBOL_GPL(devm_regulator_bulk_unregister_supply_alias);

View File

@ -218,9 +218,8 @@ static int fan53555_regulator_register(struct fan53555_device_info *di,
rdesc->vsel_mask = VSEL_NSEL_MASK;
rdesc->owner = THIS_MODULE;
di->rdev = regulator_register(&di->desc, config);
di->rdev = devm_regulator_register(di->dev, &di->desc, config);
return PTR_ERR_OR_ZERO(di->rdev);
}
static struct regmap_config fan53555_regmap_config = {
@ -291,14 +290,6 @@ static int fan53555_regulator_probe(struct i2c_client *client,
}
static int fan53555_regulator_remove(struct i2c_client *client)
{
struct fan53555_device_info *di = i2c_get_clientdata(client);
regulator_unregister(di->rdev);
return 0;
}
static const struct i2c_device_id fan53555_id[] = {
{"fan53555", -1},
{ },
@ -309,7 +300,6 @@ static struct i2c_driver fan53555_regulator_driver = {
.name = "fan53555-regulator",
},
.probe = fan53555_regulator_probe,
.remove = fan53555_regulator_remove,
.id_table = fan53555_id,
};

View File

@ -34,7 +34,6 @@
struct fixed_voltage_data {
struct regulator_desc desc;
struct regulator_dev *dev;
int microvolts;
};
@ -108,30 +107,7 @@ of_get_fixed_voltage_config(struct device *dev)
return config;
}
static int fixed_voltage_get_voltage(struct regulator_dev *dev)
{
struct fixed_voltage_data *data = rdev_get_drvdata(dev);
if (data->microvolts)
return data->microvolts;
else
return -EINVAL;
}
static int fixed_voltage_list_voltage(struct regulator_dev *dev,
unsigned selector)
{
struct fixed_voltage_data *data = rdev_get_drvdata(dev);
if (selector != 0)
return -EINVAL;
return data->microvolts;
}
static struct regulator_ops fixed_voltage_ops = {
.get_voltage = fixed_voltage_get_voltage,
.list_voltage = fixed_voltage_list_voltage,
};
static int reg_fixed_voltage_probe(struct platform_device *pdev)
@ -186,23 +162,21 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev)
if (config->microvolts)
drvdata->desc.n_voltages = 1;
drvdata->microvolts = config->microvolts;
drvdata->desc.fixed_uV = config->microvolts;
if (config->gpio >= 0)
cfg.ena_gpio = config->gpio;
cfg.ena_gpio_invert = !config->enable_high;
if (config->enabled_at_boot) {
if (config->enable_high) {
if (config->enable_high)
cfg.ena_gpio_flags |= GPIOF_OUT_INIT_HIGH;
} else {
else
cfg.ena_gpio_flags |= GPIOF_OUT_INIT_LOW;
}
} else {
if (config->enable_high) {
if (config->enable_high)
cfg.ena_gpio_flags |= GPIOF_OUT_INIT_LOW;
} else {
else
cfg.ena_gpio_flags |= GPIOF_OUT_INIT_HIGH;
}
}
if (config->gpio_is_open_drain)
cfg.ena_gpio_flags |= GPIOF_OPEN_DRAIN;
@ -222,7 +196,7 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, drvdata);
dev_dbg(&pdev->dev, "%s supplying %duV\n", drvdata->desc.name,
drvdata->microvolts);
drvdata->desc.fixed_uV);
return 0;

View File

@ -283,7 +283,6 @@ static int gpio_regulator_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "No regulator type set\n");
ret = -EINVAL;
goto err_memgpio;
break;
}
drvdata->nr_gpios = config->nr_gpios;

View File

@ -284,9 +284,13 @@ int regulator_map_voltage_linear_range(struct regulator_dev *rdev,
}
for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
range = &rdev->desc->linear_ranges[i];
int linear_max_uV;
if (!(min_uV <= range->max_uV && max_uV >= range->min_uV))
range = &rdev->desc->linear_ranges[i];
linear_max_uV = range->min_uV +
(range->max_sel - range->min_sel) * range->uV_step;
if (!(min_uV <= linear_max_uV && max_uV >= range->min_uV))
continue;
if (min_uV <= range->min_uV)

View File

@ -0,0 +1,38 @@
/*
* internal.h -- Voltage/Current Regulator framework internal code
*
* Copyright 2007, 2008 Wolfson Microelectronics PLC.
* Copyright 2008 SlimLogic Ltd.
*
* Author: Liam Girdwood <lrg@slimlogic.co.uk>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
*/
#ifndef __REGULATOR_INTERNAL_H
#define __REGULATOR_INTERNAL_H
/*
* struct regulator
*
* One for each consumer device.
*/
struct regulator {
struct device *dev;
struct list_head list;
unsigned int always_on:1;
unsigned int bypass:1;
int uA_load;
int min_uV;
int max_uV;
char *supply_name;
struct device_attribute dev_attr;
struct regulator_dev *rdev;
struct dentry *debugfs;
};
#endif

View File

@ -112,7 +112,7 @@ static int isl6271a_probe(struct i2c_client *i2c,
struct regulator_config config = { };
struct regulator_init_data *init_data = dev_get_platdata(&i2c->dev);
struct isl_pmic *pmic;
int err, i;
int i;
if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
return -EIO;
@ -133,32 +133,17 @@ static int isl6271a_probe(struct i2c_client *i2c,
config.init_data = NULL;
config.driver_data = pmic;
pmic->rdev[i] = regulator_register(&isl_rd[i], &config);
pmic->rdev[i] = devm_regulator_register(&i2c->dev, &isl_rd[i],
&config);
if (IS_ERR(pmic->rdev[i])) {
dev_err(&i2c->dev, "failed to register %s\n", id->name);
err = PTR_ERR(pmic->rdev[i]);
goto error;
return PTR_ERR(pmic->rdev[i]);
}
}
i2c_set_clientdata(i2c, pmic);
return 0;
error:
while (--i >= 0)
regulator_unregister(pmic->rdev[i]);
return err;
}
static int isl6271a_remove(struct i2c_client *i2c)
{
struct isl_pmic *pmic = i2c_get_clientdata(i2c);
int i;
for (i = 0; i < 3; i++)
regulator_unregister(pmic->rdev[i]);
return 0;
}
static const struct i2c_device_id isl6271a_id[] = {
@ -174,7 +159,6 @@ static struct i2c_driver isl6271a_i2c_driver = {
.owner = THIS_MODULE,
},
.probe = isl6271a_probe,
.remove = isl6271a_remove,
.id_table = isl6271a_id,
};

View File

@ -474,8 +474,8 @@ static int lp3971_i2c_remove(struct i2c_client *i2c)
}
static const struct i2c_device_id lp3971_i2c_id[] = {
{ "lp3971", 0 },
{ }
{ "lp3971", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, lp3971_i2c_id);

View File

@ -785,7 +785,7 @@ static int lp872x_regulator_register(struct lp872x *lp)
struct regulator_desc *desc;
struct regulator_config cfg = { };
struct regulator_dev *rdev;
int i, ret;
int i;
for (i = 0; i < lp->num_regulators; i++) {
desc = (lp->chipid == LP8720) ? &lp8720_regulator_desc[i] :
@ -796,34 +796,16 @@ static int lp872x_regulator_register(struct lp872x *lp)
cfg.driver_data = lp;
cfg.regmap = lp->regmap;
rdev = regulator_register(desc, &cfg);
rdev = devm_regulator_register(lp->dev, desc, &cfg);
if (IS_ERR(rdev)) {
dev_err(lp->dev, "regulator register err");
ret = PTR_ERR(rdev);
goto err;
return PTR_ERR(rdev);
}
*(lp->regulators + i) = rdev;
}
return 0;
err:
while (--i >= 0) {
rdev = *(lp->regulators + i);
regulator_unregister(rdev);
}
return ret;
}
static void lp872x_regulator_unregister(struct lp872x *lp)
{
struct regulator_dev *rdev;
int i;
for (i = 0; i < lp->num_regulators; i++) {
rdev = *(lp->regulators + i);
regulator_unregister(rdev);
}
}
static const struct regmap_config lp872x_regmap_config = {
@ -979,14 +961,6 @@ err_dev:
return ret;
}
static int lp872x_remove(struct i2c_client *cl)
{
struct lp872x *lp = i2c_get_clientdata(cl);
lp872x_regulator_unregister(lp);
return 0;
}
static const struct of_device_id lp872x_dt_ids[] = {
{ .compatible = "ti,lp8720", },
{ .compatible = "ti,lp8725", },
@ -1008,7 +982,6 @@ static struct i2c_driver lp872x_driver = {
.of_match_table = of_match_ptr(lp872x_dt_ids),
},
.probe = lp872x_probe,
.remove = lp872x_remove,
.id_table = lp872x_ids,
};

View File

@ -515,7 +515,7 @@ static int lp8788_buck_probe(struct platform_device *pdev)
cfg.driver_data = buck;
cfg.regmap = lp->regmap;
rdev = regulator_register(&lp8788_buck_desc[id], &cfg);
rdev = devm_regulator_register(&pdev->dev, &lp8788_buck_desc[id], &cfg);
if (IS_ERR(rdev)) {
ret = PTR_ERR(rdev);
dev_err(&pdev->dev, "BUCK%d regulator register err = %d\n",
@ -529,18 +529,8 @@ static int lp8788_buck_probe(struct platform_device *pdev)
return 0;
}
static int lp8788_buck_remove(struct platform_device *pdev)
{
struct lp8788_buck *buck = platform_get_drvdata(pdev);
regulator_unregister(buck->regulator);
return 0;
}
static struct platform_driver lp8788_buck_driver = {
.probe = lp8788_buck_probe,
.remove = lp8788_buck_remove,
.driver = {
.name = LP8788_DEV_BUCK,
.owner = THIS_MODULE,

View File

@ -543,7 +543,7 @@ static int lp8788_dldo_probe(struct platform_device *pdev)
cfg.driver_data = ldo;
cfg.regmap = lp->regmap;
rdev = regulator_register(&lp8788_dldo_desc[id], &cfg);
rdev = devm_regulator_register(&pdev->dev, &lp8788_dldo_desc[id], &cfg);
if (IS_ERR(rdev)) {
ret = PTR_ERR(rdev);
dev_err(&pdev->dev, "DLDO%d regulator register err = %d\n",
@ -557,18 +557,8 @@ static int lp8788_dldo_probe(struct platform_device *pdev)
return 0;
}
static int lp8788_dldo_remove(struct platform_device *pdev)
{
struct lp8788_ldo *ldo = platform_get_drvdata(pdev);
regulator_unregister(ldo->regulator);
return 0;
}
static struct platform_driver lp8788_dldo_driver = {
.probe = lp8788_dldo_probe,
.remove = lp8788_dldo_remove,
.driver = {
.name = LP8788_DEV_DLDO,
.owner = THIS_MODULE,
@ -603,7 +593,7 @@ static int lp8788_aldo_probe(struct platform_device *pdev)
cfg.driver_data = ldo;
cfg.regmap = lp->regmap;
rdev = regulator_register(&lp8788_aldo_desc[id], &cfg);
rdev = devm_regulator_register(&pdev->dev, &lp8788_aldo_desc[id], &cfg);
if (IS_ERR(rdev)) {
ret = PTR_ERR(rdev);
dev_err(&pdev->dev, "ALDO%d regulator register err = %d\n",
@ -617,18 +607,8 @@ static int lp8788_aldo_probe(struct platform_device *pdev)
return 0;
}
static int lp8788_aldo_remove(struct platform_device *pdev)
{
struct lp8788_ldo *ldo = platform_get_drvdata(pdev);
regulator_unregister(ldo->regulator);
return 0;
}
static struct platform_driver lp8788_aldo_driver = {
.probe = lp8788_aldo_probe,
.remove = lp8788_aldo_remove,
.driver = {
.name = LP8788_DEV_ALDO,
.owner = THIS_MODULE,

View File

@ -166,7 +166,7 @@ static int max1586_pmic_probe(struct i2c_client *client,
struct max1586_platform_data *pdata = dev_get_platdata(&client->dev);
struct regulator_config config = { };
struct max1586_data *max1586;
int i, id, ret = -ENOMEM;
int i, id;
max1586 = devm_kzalloc(&client->dev, sizeof(struct max1586_data) +
sizeof(struct regulator_dev *) * (MAX1586_V6 + 1),
@ -193,7 +193,7 @@ static int max1586_pmic_probe(struct i2c_client *client,
continue;
if (id < MAX1586_V3 || id > MAX1586_V6) {
dev_err(&client->dev, "invalid regulator id %d\n", id);
goto err;
return -EINVAL;
}
if (id == MAX1586_V3) {
@ -207,33 +207,18 @@ static int max1586_pmic_probe(struct i2c_client *client,
config.init_data = pdata->subdevs[i].platform_data;
config.driver_data = max1586;
rdev[i] = regulator_register(&max1586_reg[id], &config);
rdev[i] = devm_regulator_register(&client->dev,
&max1586_reg[id], &config);
if (IS_ERR(rdev[i])) {
ret = PTR_ERR(rdev[i]);
dev_err(&client->dev, "failed to register %s\n",
max1586_reg[id].name);
goto err;
return PTR_ERR(rdev[i]);
}
}
i2c_set_clientdata(client, max1586);
dev_info(&client->dev, "Maxim 1586 regulator driver loaded\n");
return 0;
err:
while (--i >= 0)
regulator_unregister(rdev[i]);
return ret;
}
static int max1586_pmic_remove(struct i2c_client *client)
{
struct max1586_data *max1586 = i2c_get_clientdata(client);
int i;
for (i = 0; i <= MAX1586_V6; i++)
regulator_unregister(max1586->rdev[i]);
return 0;
}
static const struct i2c_device_id max1586_id[] = {
@ -244,7 +229,6 @@ MODULE_DEVICE_TABLE(i2c, max1586_id);
static struct i2c_driver max1586_pmic_driver = {
.probe = max1586_pmic_probe,
.remove = max1586_pmic_remove,
.driver = {
.name = "max1586",
.owner = THIS_MODULE,

View File

@ -478,31 +478,15 @@ static int max77686_pmic_probe(struct platform_device *pdev)
config.of_node = pdata->regulators[i].of_node;
max77686->opmode[i] = regulators[i].enable_mask;
max77686->rdev[i] = regulator_register(&regulators[i], &config);
max77686->rdev[i] = devm_regulator_register(&pdev->dev,
&regulators[i], &config);
if (IS_ERR(max77686->rdev[i])) {
ret = PTR_ERR(max77686->rdev[i]);
dev_err(&pdev->dev,
"regulator init failed for %d\n", i);
max77686->rdev[i] = NULL;
goto err;
return PTR_ERR(max77686->rdev[i]);
}
}
return 0;
err:
while (--i >= 0)
regulator_unregister(max77686->rdev[i]);
return ret;
}
static int max77686_pmic_remove(struct platform_device *pdev)
{
struct max77686_data *max77686 = platform_get_drvdata(pdev);
int i;
for (i = 0; i < MAX77686_REGULATORS; i++)
regulator_unregister(max77686->rdev[i]);
return 0;
}
@ -518,7 +502,6 @@ static struct platform_driver max77686_pmic_driver = {
.owner = THIS_MODULE,
},
.probe = max77686_pmic_probe,
.remove = max77686_pmic_remove,
.id_table = max77686_pmic_id,
};

View File

@ -230,7 +230,7 @@ static int max77693_pmic_probe(struct platform_device *pdev)
struct max77693_dev *iodev = dev_get_drvdata(pdev->dev.parent);
struct max77693_pmic_dev *max77693_pmic;
struct max77693_regulator_data *rdata = NULL;
int num_rdata, i, ret;
int num_rdata, i;
struct regulator_config config;
num_rdata = max77693_pmic_init_rdata(&pdev->dev, &rdata);
@ -266,35 +266,15 @@ static int max77693_pmic_probe(struct platform_device *pdev)
config.init_data = rdata[i].initdata;
config.of_node = rdata[i].of_node;
max77693_pmic->rdev[i] = regulator_register(&regulators[id],
&config);
max77693_pmic->rdev[i] = devm_regulator_register(&pdev->dev,
&regulators[id], &config);
if (IS_ERR(max77693_pmic->rdev[i])) {
ret = PTR_ERR(max77693_pmic->rdev[i]);
dev_err(max77693_pmic->dev,
"Failed to initialize regulator-%d\n", id);
max77693_pmic->rdev[i] = NULL;
goto err;
return PTR_ERR(max77693_pmic->rdev[i]);
}
}
return 0;
err:
while (--i >= 0)
regulator_unregister(max77693_pmic->rdev[i]);
return ret;
}
static int max77693_pmic_remove(struct platform_device *pdev)
{
struct max77693_pmic_dev *max77693_pmic = platform_get_drvdata(pdev);
struct regulator_dev **rdev = max77693_pmic->rdev;
int i;
for (i = 0; i < max77693_pmic->num_regulators; i++)
if (rdev[i])
regulator_unregister(rdev[i]);
return 0;
}
@ -311,7 +291,6 @@ static struct platform_driver max77693_pmic_driver = {
.owner = THIS_MODULE,
},
.probe = max77693_pmic_probe,
.remove = max77693_pmic_remove,
.id_table = max77693_pmic_id,
};

View File

@ -234,7 +234,8 @@ static int max8649_regulator_probe(struct i2c_client *client,
config.driver_data = info;
config.regmap = info->regmap;
info->regulator = regulator_register(&dcdc_desc, &config);
info->regulator = devm_regulator_register(&client->dev, &dcdc_desc,
&config);
if (IS_ERR(info->regulator)) {
dev_err(info->dev, "failed to register regulator %s\n",
dcdc_desc.name);
@ -244,16 +245,6 @@ static int max8649_regulator_probe(struct i2c_client *client,
return 0;
}
static int max8649_regulator_remove(struct i2c_client *client)
{
struct max8649_regulator_info *info = i2c_get_clientdata(client);
if (info)
regulator_unregister(info->regulator);
return 0;
}
static const struct i2c_device_id max8649_id[] = {
{ "max8649", 0 },
{ }
@ -262,7 +253,6 @@ MODULE_DEVICE_TABLE(i2c, max8649_id);
static struct i2c_driver max8649_driver = {
.probe = max8649_regulator_probe,
.remove = max8649_regulator_remove,
.driver = {
.name = "max8649",
},

View File

@ -439,7 +439,7 @@ static int max8660_probe(struct i2c_client *client,
for (i = 0; i < pdata->num_subdevs; i++) {
if (!pdata->subdevs[i].platform_data)
goto err_out;
return ret;
boot_on = pdata->subdevs[i].platform_data->constraints.boot_on;
@ -465,7 +465,7 @@ static int max8660_probe(struct i2c_client *client,
case MAX8660_V7:
if (type == MAX8661) {
dev_err(dev, "Regulator not on this chip!\n");
goto err_out;
return -EINVAL;
}
if (boot_on)
@ -475,7 +475,7 @@ static int max8660_probe(struct i2c_client *client,
default:
dev_err(dev, "invalid regulator %s\n",
pdata->subdevs[i].name);
goto err_out;
return ret;
}
}
@ -489,33 +489,18 @@ static int max8660_probe(struct i2c_client *client,
config.of_node = of_node[i];
config.driver_data = max8660;
rdev[i] = regulator_register(&max8660_reg[id], &config);
rdev[i] = devm_regulator_register(&client->dev,
&max8660_reg[id], &config);
if (IS_ERR(rdev[i])) {
ret = PTR_ERR(rdev[i]);
dev_err(dev, "failed to register %s\n",
dev_err(&client->dev, "failed to register %s\n",
max8660_reg[id].name);
goto err_unregister;
return PTR_ERR(rdev[i]);
}
}
i2c_set_clientdata(client, max8660);
return 0;
err_unregister:
while (--i >= 0)
regulator_unregister(rdev[i]);
err_out:
return ret;
}
static int max8660_remove(struct i2c_client *client)
{
struct max8660 *max8660 = i2c_get_clientdata(client);
int i;
for (i = 0; i < MAX8660_V_END; i++)
regulator_unregister(max8660->rdev[i]);
return 0;
}
static const struct i2c_device_id max8660_id[] = {
@ -527,7 +512,6 @@ MODULE_DEVICE_TABLE(i2c, max8660_id);
static struct i2c_driver max8660_driver = {
.probe = max8660_probe,
.remove = max8660_remove,
.driver = {
.name = "max8660",
.owner = THIS_MODULE,

View File

@ -350,33 +350,17 @@ static int max8907_regulator_probe(struct platform_device *pdev)
pmic->desc[i].ops = &max8907_out5v_hwctl_ops;
}
pmic->rdev[i] = regulator_register(&pmic->desc[i], &config);
pmic->rdev[i] = devm_regulator_register(&pdev->dev,
&pmic->desc[i], &config);
if (IS_ERR(pmic->rdev[i])) {
dev_err(&pdev->dev,
"failed to register %s regulator\n",
pmic->desc[i].name);
ret = PTR_ERR(pmic->rdev[i]);
goto err_unregister_regulator;
return PTR_ERR(pmic->rdev[i]);
}
}
return 0;
err_unregister_regulator:
while (--i >= 0)
regulator_unregister(pmic->rdev[i]);
return ret;
}
static int max8907_regulator_remove(struct platform_device *pdev)
{
struct max8907_regulator *pmic = platform_get_drvdata(pdev);
int i;
for (i = 0; i < MAX8907_NUM_REGULATORS; i++)
regulator_unregister(pmic->rdev[i]);
return 0;
}
static struct platform_driver max8907_regulator_driver = {
@ -385,7 +369,6 @@ static struct platform_driver max8907_regulator_driver = {
.owner = THIS_MODULE,
},
.probe = max8907_regulator_probe,
.remove = max8907_regulator_remove,
};
static int __init max8907_regulator_init(void)

View File

@ -312,7 +312,7 @@ static int max8925_regulator_probe(struct platform_device *pdev)
if (pdata)
config.init_data = pdata;
rdev = regulator_register(&ri->desc, &config);
rdev = devm_regulator_register(&pdev->dev, &ri->desc, &config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "failed to register regulator %s\n",
ri->desc.name);
@ -323,22 +323,12 @@ static int max8925_regulator_probe(struct platform_device *pdev)
return 0;
}
static int max8925_regulator_remove(struct platform_device *pdev)
{
struct regulator_dev *rdev = platform_get_drvdata(pdev);
regulator_unregister(rdev);
return 0;
}
static struct platform_driver max8925_regulator_driver = {
.driver = {
.name = "max8925-regulator",
.owner = THIS_MODULE,
},
.probe = max8925_regulator_probe,
.remove = max8925_regulator_remove,
};
static int __init max8925_regulator_init(void)

View File

@ -467,7 +467,7 @@ static int max8973_probe(struct i2c_client *client,
config.regmap = max->regmap;
/* Register the regulators */
rdev = regulator_register(&max->desc, &config);
rdev = devm_regulator_register(&client->dev, &max->desc, &config);
if (IS_ERR(rdev)) {
ret = PTR_ERR(rdev);
dev_err(max->dev, "regulator register failed, err %d\n", ret);
@ -478,14 +478,6 @@ static int max8973_probe(struct i2c_client *client,
return 0;
}
static int max8973_remove(struct i2c_client *client)
{
struct max8973_chip *max = i2c_get_clientdata(client);
regulator_unregister(max->rdev);
return 0;
}
static const struct i2c_device_id max8973_id[] = {
{.name = "max8973",},
{},
@ -499,7 +491,6 @@ static struct i2c_driver max8973_i2c_driver = {
.owner = THIS_MODULE,
},
.probe = max8973_probe,
.remove = max8973_remove,
.id_table = max8973_id,
};

View File

@ -690,8 +690,9 @@ static int max8997_set_voltage_buck(struct regulator_dev *rdev,
if (max8997->ignore_gpiodvs_side_effect == false)
return -EINVAL;
dev_warn(&rdev->dev, "MAX8997 GPIO-DVS Side Effect Warning: GPIO SET:"
" %d -> %d\n", max8997->buck125_gpioindex, tmp_idx);
dev_warn(&rdev->dev,
"MAX8997 GPIO-DVS Side Effect Warning: GPIO SET: %d -> %d\n",
max8997->buck125_gpioindex, tmp_idx);
out:
if (new_idx < 0 || new_val < 0)
@ -1081,7 +1082,7 @@ static int max8997_pmic_probe(struct platform_device *pdev)
pdata->buck1_voltage[i] +
buck1245_voltage_map_desc.step);
if (ret < 0)
goto err_out;
return ret;
max8997->buck2_vol[i] = ret =
max8997_get_voltage_proper_val(
@ -1090,7 +1091,7 @@ static int max8997_pmic_probe(struct platform_device *pdev)
pdata->buck2_voltage[i] +
buck1245_voltage_map_desc.step);
if (ret < 0)
goto err_out;
return ret;
max8997->buck5_vol[i] = ret =
max8997_get_voltage_proper_val(
@ -1099,7 +1100,7 @@ static int max8997_pmic_probe(struct platform_device *pdev)
pdata->buck5_voltage[i] +
buck1245_voltage_map_desc.step);
if (ret < 0)
goto err_out;
return ret;
if (max_buck1 < max8997->buck1_vol[i])
max_buck1 = max8997->buck1_vol[i];
@ -1143,24 +1144,23 @@ static int max8997_pmic_probe(struct platform_device *pdev)
!gpio_is_valid(pdata->buck125_gpios[1]) ||
!gpio_is_valid(pdata->buck125_gpios[2])) {
dev_err(&pdev->dev, "GPIO NOT VALID\n");
ret = -EINVAL;
goto err_out;
return -EINVAL;
}
ret = devm_gpio_request(&pdev->dev, pdata->buck125_gpios[0],
"MAX8997 SET1");
if (ret)
goto err_out;
return ret;
ret = devm_gpio_request(&pdev->dev, pdata->buck125_gpios[1],
"MAX8997 SET2");
if (ret)
goto err_out;
return ret;
ret = devm_gpio_request(&pdev->dev, pdata->buck125_gpios[2],
"MAX8997 SET3");
if (ret)
goto err_out;
return ret;
gpio_direction_output(pdata->buck125_gpios[0],
(max8997->buck125_gpioindex >> 2)
@ -1205,33 +1205,16 @@ static int max8997_pmic_probe(struct platform_device *pdev)
config.driver_data = max8997;
config.of_node = pdata->regulators[i].reg_node;
rdev[i] = regulator_register(&regulators[id], &config);
rdev[i] = devm_regulator_register(&pdev->dev, &regulators[id],
&config);
if (IS_ERR(rdev[i])) {
ret = PTR_ERR(rdev[i]);
dev_err(max8997->dev, "regulator init failed for %d\n",
id);
rdev[i] = NULL;
goto err;
return PTR_ERR(rdev[i]);
}
}
return 0;
err:
while (--i >= 0)
regulator_unregister(rdev[i]);
err_out:
return ret;
}
static int max8997_pmic_remove(struct platform_device *pdev)
{
struct max8997_data *max8997 = platform_get_drvdata(pdev);
struct regulator_dev **rdev = max8997->rdev;
int i;
for (i = 0; i < max8997->num_regulators; i++)
regulator_unregister(rdev[i]);
return 0;
}
static const struct platform_device_id max8997_pmic_id[] = {
@ -1246,7 +1229,6 @@ static struct platform_driver max8997_pmic_driver = {
.owner = THIS_MODULE,
},
.probe = max8997_pmic_probe,
.remove = max8997_pmic_remove,
.id_table = max8997_pmic_id,
};

View File

@ -790,16 +790,14 @@ static int max8998_pmic_probe(struct platform_device *pdev)
dev_err(&pdev->dev,
"MAX8998 SET1 GPIO defined as 0 !\n");
WARN_ON(!pdata->buck1_set1);
ret = -EIO;
goto err_out;
return -EIO;
}
/* Check if SET2 is not equal to 0 */
if (!pdata->buck1_set2) {
dev_err(&pdev->dev,
"MAX8998 SET2 GPIO defined as 0 !\n");
WARN_ON(!pdata->buck1_set2);
ret = -EIO;
goto err_out;
return -EIO;
}
gpio_request(pdata->buck1_set1, "MAX8998 BUCK1_SET1");
@ -823,7 +821,7 @@ static int max8998_pmic_probe(struct platform_device *pdev)
ret = max8998_write_reg(i2c,
MAX8998_REG_BUCK1_VOLTAGE1 + v, i);
if (ret)
goto err_out;
return ret;
}
}
@ -833,8 +831,7 @@ static int max8998_pmic_probe(struct platform_device *pdev)
dev_err(&pdev->dev,
"MAX8998 SET3 GPIO defined as 0 !\n");
WARN_ON(!pdata->buck2_set3);
ret = -EIO;
goto err_out;
return -EIO;
}
gpio_request(pdata->buck2_set3, "MAX8998 BUCK2_SET3");
gpio_direction_output(pdata->buck2_set3,
@ -852,7 +849,7 @@ static int max8998_pmic_probe(struct platform_device *pdev)
ret = max8998_write_reg(i2c,
MAX8998_REG_BUCK2_VOLTAGE1 + v, i);
if (ret)
goto err_out;
return ret;
}
}
@ -875,33 +872,18 @@ static int max8998_pmic_probe(struct platform_device *pdev)
config.init_data = pdata->regulators[i].initdata;
config.driver_data = max8998;
rdev[i] = regulator_register(&regulators[index], &config);
rdev[i] = devm_regulator_register(&pdev->dev,
&regulators[index], &config);
if (IS_ERR(rdev[i])) {
ret = PTR_ERR(rdev[i]);
dev_err(max8998->dev, "regulator %s init failed (%d)\n",
regulators[index].name, ret);
rdev[i] = NULL;
goto err;
return ret;
}
}
return 0;
err:
while (--i >= 0)
regulator_unregister(rdev[i]);
err_out:
return ret;
}
static int max8998_pmic_remove(struct platform_device *pdev)
{
struct max8998_data *max8998 = platform_get_drvdata(pdev);
struct regulator_dev **rdev = max8998->rdev;
int i;
for (i = 0; i < max8998->num_regulators; i++)
regulator_unregister(rdev[i]);
return 0;
}
@ -918,7 +900,6 @@ static struct platform_driver max8998_pmic_driver = {
.owner = THIS_MODULE,
},
.probe = max8998_pmic_probe,
.remove = max8998_pmic_remove,
.id_table = max8998_pmic_id,
};

View File

@ -258,34 +258,34 @@ static struct mc13xxx_regulator mc13783_regulators[] = {
MC13783_FIXED_DEFINE(REG, VAUDIO, REGULATORMODE0, mc13783_vaudio_val),
MC13783_FIXED_DEFINE(REG, VIOHI, REGULATORMODE0, mc13783_viohi_val),
MC13783_DEFINE_REGU(VIOLO, REGULATORMODE0, REGULATORSETTING0, \
MC13783_DEFINE_REGU(VIOLO, REGULATORMODE0, REGULATORSETTING0,
mc13783_violo_val),
MC13783_DEFINE_REGU(VDIG, REGULATORMODE0, REGULATORSETTING0, \
MC13783_DEFINE_REGU(VDIG, REGULATORMODE0, REGULATORSETTING0,
mc13783_vdig_val),
MC13783_DEFINE_REGU(VGEN, REGULATORMODE0, REGULATORSETTING0, \
MC13783_DEFINE_REGU(VGEN, REGULATORMODE0, REGULATORSETTING0,
mc13783_vgen_val),
MC13783_DEFINE_REGU(VRFDIG, REGULATORMODE0, REGULATORSETTING0, \
MC13783_DEFINE_REGU(VRFDIG, REGULATORMODE0, REGULATORSETTING0,
mc13783_vrfdig_val),
MC13783_DEFINE_REGU(VRFREF, REGULATORMODE0, REGULATORSETTING0, \
MC13783_DEFINE_REGU(VRFREF, REGULATORMODE0, REGULATORSETTING0,
mc13783_vrfref_val),
MC13783_DEFINE_REGU(VRFCP, REGULATORMODE0, REGULATORSETTING0, \
MC13783_DEFINE_REGU(VRFCP, REGULATORMODE0, REGULATORSETTING0,
mc13783_vrfcp_val),
MC13783_DEFINE_REGU(VSIM, REGULATORMODE1, REGULATORSETTING0, \
MC13783_DEFINE_REGU(VSIM, REGULATORMODE1, REGULATORSETTING0,
mc13783_vsim_val),
MC13783_DEFINE_REGU(VESIM, REGULATORMODE1, REGULATORSETTING0, \
MC13783_DEFINE_REGU(VESIM, REGULATORMODE1, REGULATORSETTING0,
mc13783_vesim_val),
MC13783_DEFINE_REGU(VCAM, REGULATORMODE1, REGULATORSETTING0, \
MC13783_DEFINE_REGU(VCAM, REGULATORMODE1, REGULATORSETTING0,
mc13783_vcam_val),
MC13783_FIXED_DEFINE(REG, VRFBG, REGULATORMODE1, mc13783_vrfbg_val),
MC13783_DEFINE_REGU(VVIB, REGULATORMODE1, REGULATORSETTING1, \
MC13783_DEFINE_REGU(VVIB, REGULATORMODE1, REGULATORSETTING1,
mc13783_vvib_val),
MC13783_DEFINE_REGU(VRF1, REGULATORMODE1, REGULATORSETTING1, \
MC13783_DEFINE_REGU(VRF1, REGULATORMODE1, REGULATORSETTING1,
mc13783_vrf_val),
MC13783_DEFINE_REGU(VRF2, REGULATORMODE1, REGULATORSETTING1, \
MC13783_DEFINE_REGU(VRF2, REGULATORMODE1, REGULATORSETTING1,
mc13783_vrf_val),
MC13783_DEFINE_REGU(VMMC1, REGULATORMODE1, REGULATORSETTING1, \
MC13783_DEFINE_REGU(VMMC1, REGULATORMODE1, REGULATORSETTING1,
mc13783_vmmc_val),
MC13783_DEFINE_REGU(VMMC2, REGULATORMODE1, REGULATORSETTING1, \
MC13783_DEFINE_REGU(VMMC2, REGULATORMODE1, REGULATORSETTING1,
mc13783_vmmc_val),
MC13783_GPO_DEFINE(REG, GPO1, POWERMISC, mc13783_gpo_val),
MC13783_GPO_DEFINE(REG, GPO2, POWERMISC, mc13783_gpo_val),
@ -400,7 +400,7 @@ static int mc13783_regulator_probe(struct platform_device *pdev)
dev_get_platdata(&pdev->dev);
struct mc13xxx_regulator_init_data *mc13xxx_data;
struct regulator_config config = { };
int i, ret, num_regulators;
int i, num_regulators;
num_regulators = mc13xxx_get_num_regulators_dt(pdev);
@ -444,31 +444,15 @@ static int mc13783_regulator_probe(struct platform_device *pdev)
config.driver_data = priv;
config.of_node = node;
priv->regulators[i] = regulator_register(desc, &config);
priv->regulators[i] = devm_regulator_register(&pdev->dev, desc,
&config);
if (IS_ERR(priv->regulators[i])) {
dev_err(&pdev->dev, "failed to register regulator %s\n",
mc13783_regulators[i].desc.name);
ret = PTR_ERR(priv->regulators[i]);
goto err;
return PTR_ERR(priv->regulators[i]);
}
}
return 0;
err:
while (--i >= 0)
regulator_unregister(priv->regulators[i]);
return ret;
}
static int mc13783_regulator_remove(struct platform_device *pdev)
{
struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev);
int i;
for (i = 0; i < priv->num_regulators; i++)
regulator_unregister(priv->regulators[i]);
return 0;
}
@ -477,7 +461,6 @@ static struct platform_driver mc13783_regulator_driver = {
.name = "mc13783-regulator",
.owner = THIS_MODULE,
},
.remove = mc13783_regulator_remove,
.probe = mc13783_regulator_probe,
};

View File

@ -611,43 +611,27 @@ static int mc13892_regulator_probe(struct platform_device *pdev)
config.driver_data = priv;
config.of_node = node;
priv->regulators[i] = regulator_register(desc, &config);
priv->regulators[i] = devm_regulator_register(&pdev->dev, desc,
&config);
if (IS_ERR(priv->regulators[i])) {
dev_err(&pdev->dev, "failed to register regulator %s\n",
mc13892_regulators[i].desc.name);
ret = PTR_ERR(priv->regulators[i]);
goto err;
return PTR_ERR(priv->regulators[i]);
}
}
return 0;
err:
while (--i >= 0)
regulator_unregister(priv->regulators[i]);
return ret;
err_unlock:
mc13xxx_unlock(mc13892);
return ret;
}
static int mc13892_regulator_remove(struct platform_device *pdev)
{
struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev);
int i;
for (i = 0; i < priv->num_regulators; i++)
regulator_unregister(priv->regulators[i]);
return 0;
}
static struct platform_driver mc13892_regulator_driver = {
.driver = {
.name = "mc13892-regulator",
.owner = THIS_MODULE,
},
.remove = mc13892_regulator_remove,
.probe = mc13892_regulator_probe,
};

View File

@ -23,6 +23,8 @@ static void of_get_regulation_constraints(struct device_node *np,
const __be32 *min_uA, *max_uA, *ramp_delay;
struct property *prop;
struct regulation_constraints *constraints = &(*init_data)->constraints;
int ret;
u32 pval;
constraints->name = of_get_property(np, "regulator-name", NULL);
@ -73,6 +75,10 @@ static void of_get_regulation_constraints(struct device_node *np,
else
constraints->ramp_disable = true;
}
ret = of_property_read_u32(np, "regulator-enable-ramp-delay", &pval);
if (!ret)
constraints->enable_time = pval;
}
/**

View File

@ -33,6 +33,7 @@ struct regs_info {
u8 vsel_addr;
u8 ctrl_addr;
u8 tstep_addr;
int sleep_id;
};
static const struct regs_info palmas_regs_info[] = {
@ -42,6 +43,7 @@ static const struct regs_info palmas_regs_info[] = {
.vsel_addr = PALMAS_SMPS12_VOLTAGE,
.ctrl_addr = PALMAS_SMPS12_CTRL,
.tstep_addr = PALMAS_SMPS12_TSTEP,
.sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS12,
},
{
.name = "SMPS123",
@ -49,12 +51,14 @@ static const struct regs_info palmas_regs_info[] = {
.vsel_addr = PALMAS_SMPS12_VOLTAGE,
.ctrl_addr = PALMAS_SMPS12_CTRL,
.tstep_addr = PALMAS_SMPS12_TSTEP,
.sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS12,
},
{
.name = "SMPS3",
.sname = "smps3-in",
.vsel_addr = PALMAS_SMPS3_VOLTAGE,
.ctrl_addr = PALMAS_SMPS3_CTRL,
.sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS3,
},
{
.name = "SMPS45",
@ -62,6 +66,7 @@ static const struct regs_info palmas_regs_info[] = {
.vsel_addr = PALMAS_SMPS45_VOLTAGE,
.ctrl_addr = PALMAS_SMPS45_CTRL,
.tstep_addr = PALMAS_SMPS45_TSTEP,
.sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS45,
},
{
.name = "SMPS457",
@ -69,6 +74,7 @@ static const struct regs_info palmas_regs_info[] = {
.vsel_addr = PALMAS_SMPS45_VOLTAGE,
.ctrl_addr = PALMAS_SMPS45_CTRL,
.tstep_addr = PALMAS_SMPS45_TSTEP,
.sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS45,
},
{
.name = "SMPS6",
@ -76,12 +82,14 @@ static const struct regs_info palmas_regs_info[] = {
.vsel_addr = PALMAS_SMPS6_VOLTAGE,
.ctrl_addr = PALMAS_SMPS6_CTRL,
.tstep_addr = PALMAS_SMPS6_TSTEP,
.sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS6,
},
{
.name = "SMPS7",
.sname = "smps7-in",
.vsel_addr = PALMAS_SMPS7_VOLTAGE,
.ctrl_addr = PALMAS_SMPS7_CTRL,
.sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS7,
},
{
.name = "SMPS8",
@ -89,108 +97,128 @@ static const struct regs_info palmas_regs_info[] = {
.vsel_addr = PALMAS_SMPS8_VOLTAGE,
.ctrl_addr = PALMAS_SMPS8_CTRL,
.tstep_addr = PALMAS_SMPS8_TSTEP,
.sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS8,
},
{
.name = "SMPS9",
.sname = "smps9-in",
.vsel_addr = PALMAS_SMPS9_VOLTAGE,
.ctrl_addr = PALMAS_SMPS9_CTRL,
.sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS9,
},
{
.name = "SMPS10_OUT2",
.sname = "smps10-in",
.ctrl_addr = PALMAS_SMPS10_CTRL,
.sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS10,
},
{
.name = "SMPS10_OUT1",
.sname = "smps10-out2",
.ctrl_addr = PALMAS_SMPS10_CTRL,
.sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SMPS10,
},
{
.name = "LDO1",
.sname = "ldo1-in",
.vsel_addr = PALMAS_LDO1_VOLTAGE,
.ctrl_addr = PALMAS_LDO1_CTRL,
.sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDO1,
},
{
.name = "LDO2",
.sname = "ldo2-in",
.vsel_addr = PALMAS_LDO2_VOLTAGE,
.ctrl_addr = PALMAS_LDO2_CTRL,
.sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDO2,
},
{
.name = "LDO3",
.sname = "ldo3-in",
.vsel_addr = PALMAS_LDO3_VOLTAGE,
.ctrl_addr = PALMAS_LDO3_CTRL,
.sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDO3,
},
{
.name = "LDO4",
.sname = "ldo4-in",
.vsel_addr = PALMAS_LDO4_VOLTAGE,
.ctrl_addr = PALMAS_LDO4_CTRL,
.sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDO4,
},
{
.name = "LDO5",
.sname = "ldo5-in",
.vsel_addr = PALMAS_LDO5_VOLTAGE,
.ctrl_addr = PALMAS_LDO5_CTRL,
.sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDO5,
},
{
.name = "LDO6",
.sname = "ldo6-in",
.vsel_addr = PALMAS_LDO6_VOLTAGE,
.ctrl_addr = PALMAS_LDO6_CTRL,
.sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDO6,
},
{
.name = "LDO7",
.sname = "ldo7-in",
.vsel_addr = PALMAS_LDO7_VOLTAGE,
.ctrl_addr = PALMAS_LDO7_CTRL,
.sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDO7,
},
{
.name = "LDO8",
.sname = "ldo8-in",
.vsel_addr = PALMAS_LDO8_VOLTAGE,
.ctrl_addr = PALMAS_LDO8_CTRL,
.sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDO8,
},
{
.name = "LDO9",
.sname = "ldo9-in",
.vsel_addr = PALMAS_LDO9_VOLTAGE,
.ctrl_addr = PALMAS_LDO9_CTRL,
.sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDO9,
},
{
.name = "LDOLN",
.sname = "ldoln-in",
.vsel_addr = PALMAS_LDOLN_VOLTAGE,
.ctrl_addr = PALMAS_LDOLN_CTRL,
.sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDOLN,
},
{
.name = "LDOUSB",
.sname = "ldousb-in",
.vsel_addr = PALMAS_LDOUSB_VOLTAGE,
.ctrl_addr = PALMAS_LDOUSB_CTRL,
.sleep_id = PALMAS_EXTERNAL_REQSTR_ID_LDOUSB,
},
{
.name = "REGEN1",
.ctrl_addr = PALMAS_REGEN1_CTRL,
.sleep_id = PALMAS_EXTERNAL_REQSTR_ID_REGEN1,
},
{
.name = "REGEN2",
.ctrl_addr = PALMAS_REGEN2_CTRL,
.sleep_id = PALMAS_EXTERNAL_REQSTR_ID_REGEN2,
},
{
.name = "REGEN3",
.ctrl_addr = PALMAS_REGEN3_CTRL,
.sleep_id = PALMAS_EXTERNAL_REQSTR_ID_REGEN3,
},
{
.name = "SYSEN1",
.ctrl_addr = PALMAS_SYSEN1_CTRL,
.sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SYSEN1,
},
{
.name = "SYSEN2",
.ctrl_addr = PALMAS_SYSEN2_CTRL,
.sleep_id = PALMAS_EXTERNAL_REQSTR_ID_SYSEN2,
},
};
@ -478,6 +506,17 @@ static struct regulator_ops palmas_ops_smps = {
.set_ramp_delay = palmas_smps_set_ramp_delay,
};
static struct regulator_ops palmas_ops_ext_control_smps = {
.set_mode = palmas_set_mode_smps,
.get_mode = palmas_get_mode_smps,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.list_voltage = palmas_list_voltage_smps,
.map_voltage = palmas_map_voltage_smps,
.set_voltage_time_sel = palma_smps_set_voltage_smps_time_sel,
.set_ramp_delay = palmas_smps_set_ramp_delay,
};
static struct regulator_ops palmas_ops_smps10 = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
@ -513,12 +552,37 @@ static struct regulator_ops palmas_ops_ldo = {
.map_voltage = regulator_map_voltage_linear,
};
static struct regulator_ops palmas_ops_ext_control_ldo = {
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
};
static struct regulator_ops palmas_ops_extreg = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
};
static struct regulator_ops palmas_ops_ext_control_extreg = {
};
static int palmas_regulator_config_external(struct palmas *palmas, int id,
struct palmas_reg_init *reg_init)
{
int sleep_id = palmas_regs_info[id].sleep_id;
int ret;
ret = palmas_ext_control_req_config(palmas, sleep_id,
reg_init->roof_floor, true);
if (ret < 0)
dev_err(palmas->dev,
"Ext control config for regulator %d failed %d\n",
id, ret);
return ret;
}
/*
* setup the hardware based sleep configuration of the SMPS/LDO regulators
* from the platform data. This is different to the software based control
@ -577,7 +641,22 @@ static int palmas_smps_init(struct palmas *palmas, int id,
return ret;
}
if (reg_init->roof_floor && (id != PALMAS_REG_SMPS10_OUT1) &&
(id != PALMAS_REG_SMPS10_OUT2)) {
/* Enable externally controlled regulator */
addr = palmas_regs_info[id].ctrl_addr;
ret = palmas_smps_read(palmas, addr, &reg);
if (ret < 0)
return ret;
if (!(reg & PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK)) {
reg |= SMPS_CTRL_MODE_ON;
ret = palmas_smps_write(palmas, addr, reg);
if (ret < 0)
return ret;
}
return palmas_regulator_config_external(palmas, id, reg_init);
}
return 0;
}
@ -608,6 +687,20 @@ static int palmas_ldo_init(struct palmas *palmas, int id,
if (ret)
return ret;
if (reg_init->roof_floor) {
/* Enable externally controlled regulator */
addr = palmas_regs_info[id].ctrl_addr;
ret = palmas_update_bits(palmas, PALMAS_LDO_BASE,
addr, PALMAS_LDO1_CTRL_MODE_ACTIVE,
PALMAS_LDO1_CTRL_MODE_ACTIVE);
if (ret < 0) {
dev_err(palmas->dev,
"LDO Register 0x%02x update failed %d\n",
addr, ret);
return ret;
}
return palmas_regulator_config_external(palmas, id, reg_init);
}
return 0;
}
@ -630,6 +723,21 @@ static int palmas_extreg_init(struct palmas *palmas, int id,
addr, ret);
return ret;
}
if (reg_init->roof_floor) {
/* Enable externally controlled regulator */
addr = palmas_regs_info[id].ctrl_addr;
ret = palmas_update_bits(palmas, PALMAS_RESOURCE_BASE,
addr, PALMAS_REGEN1_CTRL_MODE_ACTIVE,
PALMAS_REGEN1_CTRL_MODE_ACTIVE);
if (ret < 0) {
dev_err(palmas->dev,
"Resource Register 0x%02x update failed %d\n",
addr, ret);
return ret;
}
return palmas_regulator_config_external(palmas, id, reg_init);
}
return 0;
}
@ -712,7 +820,7 @@ static void palmas_dt_to_pdata(struct device *dev,
int idx, ret;
node = of_node_get(node);
regulators = of_find_node_by_name(node, "regulators");
regulators = of_get_child_by_name(node, "regulators");
if (!regulators) {
dev_info(dev, "regulator node not found\n");
return;
@ -740,9 +848,35 @@ static void palmas_dt_to_pdata(struct device *dev,
of_property_read_bool(palmas_matches[idx].of_node,
"ti,warm-reset");
pdata->reg_init[idx]->roof_floor =
of_property_read_bool(palmas_matches[idx].of_node,
"ti,roof-floor");
ret = of_property_read_u32(palmas_matches[idx].of_node,
"ti,roof-floor", &prop);
/* EINVAL: Property not found */
if (ret != -EINVAL) {
int econtrol;
/* use default value, when no value is specified */
econtrol = PALMAS_EXT_CONTROL_NSLEEP;
if (!ret) {
switch (prop) {
case 1:
econtrol = PALMAS_EXT_CONTROL_ENABLE1;
break;
case 2:
econtrol = PALMAS_EXT_CONTROL_ENABLE2;
break;
case 3:
econtrol = PALMAS_EXT_CONTROL_NSLEEP;
break;
default:
WARN_ON(1);
dev_warn(dev,
"%s: Invalid roof-floor option: %u\n",
palmas_matches[idx].name, prop);
break;
}
}
pdata->reg_init[idx]->roof_floor = econtrol;
}
ret = of_property_read_u32(palmas_matches[idx].of_node,
"ti,mode-sleep", &prop);
@ -856,7 +990,7 @@ static int palmas_regulators_probe(struct platform_device *pdev)
if (ret < 0) {
dev_err(&pdev->dev,
"reading TSTEP reg failed: %d\n", ret);
goto err_unregister_regulator;
return ret;
}
pmic->desc[id].ramp_delay =
palmas_smps_ramp_delay[reg & 0x3];
@ -868,7 +1002,9 @@ static int palmas_regulators_probe(struct platform_device *pdev)
reg_init = pdata->reg_init[id];
ret = palmas_smps_init(palmas, id, reg_init);
if (ret)
goto err_unregister_regulator;
return ret;
} else {
reg_init = NULL;
}
/* Register the regulators */
@ -909,11 +1045,15 @@ static int palmas_regulators_probe(struct platform_device *pdev)
ret = palmas_smps_read(pmic->palmas, addr, &reg);
if (ret)
goto err_unregister_regulator;
return ret;
if (reg & PALMAS_SMPS12_VOLTAGE_RANGE)
pmic->range[id] = 1;
pmic->desc[id].ops = &palmas_ops_smps;
if (reg_init && reg_init->roof_floor)
pmic->desc[id].ops =
&palmas_ops_ext_control_smps;
else
pmic->desc[id].ops = &palmas_ops_smps;
pmic->desc[id].n_voltages = PALMAS_SMPS_NUM_VOLTAGES;
pmic->desc[id].vsel_reg =
PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE,
@ -925,7 +1065,7 @@ static int palmas_regulators_probe(struct platform_device *pdev)
addr = palmas_regs_info[id].ctrl_addr;
ret = palmas_smps_read(pmic->palmas, addr, &reg);
if (ret)
goto err_unregister_regulator;
return ret;
pmic->current_reg_mode[id] = reg &
PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK;
}
@ -941,13 +1081,13 @@ static int palmas_regulators_probe(struct platform_device *pdev)
pmic->desc[id].supply_name = palmas_regs_info[id].sname;
config.of_node = palmas_matches[id].of_node;
rdev = regulator_register(&pmic->desc[id], &config);
rdev = devm_regulator_register(&pdev->dev, &pmic->desc[id],
&config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev,
"failed to register %s regulator\n",
pdev->name);
ret = PTR_ERR(rdev);
goto err_unregister_regulator;
return PTR_ERR(rdev);
}
/* Save regulator for cleanup */
@ -956,6 +1096,10 @@ static int palmas_regulators_probe(struct platform_device *pdev)
/* Start this loop from the id left from previous loop */
for (; id < PALMAS_NUM_REGS; id++) {
if (pdata && pdata->reg_init[id])
reg_init = pdata->reg_init[id];
else
reg_init = NULL;
/* Miss out regulators which are not available due
* to alternate functions.
@ -969,7 +1113,11 @@ static int palmas_regulators_probe(struct platform_device *pdev)
if (id < PALMAS_REG_REGEN1) {
pmic->desc[id].n_voltages = PALMAS_LDO_NUM_VOLTAGES;
pmic->desc[id].ops = &palmas_ops_ldo;
if (reg_init && reg_init->roof_floor)
pmic->desc[id].ops =
&palmas_ops_ext_control_ldo;
else
pmic->desc[id].ops = &palmas_ops_ldo;
pmic->desc[id].min_uV = 900000;
pmic->desc[id].uV_step = 50000;
pmic->desc[id].linear_min_sel = 1;
@ -999,7 +1147,11 @@ static int palmas_regulators_probe(struct platform_device *pdev)
pmic->desc[id].enable_time = 2000;
} else {
pmic->desc[id].n_voltages = 1;
pmic->desc[id].ops = &palmas_ops_extreg;
if (reg_init && reg_init->roof_floor)
pmic->desc[id].ops =
&palmas_ops_ext_control_extreg;
else
pmic->desc[id].ops = &palmas_ops_extreg;
pmic->desc[id].enable_reg =
PALMAS_BASE_TO_REG(PALMAS_RESOURCE_BASE,
palmas_regs_info[id].ctrl_addr);
@ -1015,13 +1167,13 @@ static int palmas_regulators_probe(struct platform_device *pdev)
pmic->desc[id].supply_name = palmas_regs_info[id].sname;
config.of_node = palmas_matches[id].of_node;
rdev = regulator_register(&pmic->desc[id], &config);
rdev = devm_regulator_register(&pdev->dev, &pmic->desc[id],
&config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev,
"failed to register %s regulator\n",
pdev->name);
ret = PTR_ERR(rdev);
goto err_unregister_regulator;
return PTR_ERR(rdev);
}
/* Save regulator for cleanup */
@ -1037,31 +1189,14 @@ static int palmas_regulators_probe(struct platform_device *pdev)
else
ret = palmas_extreg_init(palmas,
id, reg_init);
if (ret) {
regulator_unregister(pmic->rdev[id]);
goto err_unregister_regulator;
}
if (ret)
return ret;
}
}
}
return 0;
err_unregister_regulator:
while (--id >= 0)
regulator_unregister(pmic->rdev[id]);
return ret;
}
static int palmas_regulators_remove(struct platform_device *pdev)
{
struct palmas_pmic *pmic = platform_get_drvdata(pdev);
int id;
for (id = 0; id < PALMAS_NUM_REGS; id++)
regulator_unregister(pmic->rdev[id]);
return 0;
}
static struct of_device_id of_palmas_match_tbl[] = {
@ -1083,7 +1218,6 @@ static struct platform_driver palmas_driver = {
.owner = THIS_MODULE,
},
.probe = palmas_regulators_probe,
.remove = palmas_regulators_remove,
};
static int __init palmas_init(void)

View File

@ -246,7 +246,8 @@ static int pcap_regulator_probe(struct platform_device *pdev)
config.init_data = dev_get_platdata(&pdev->dev);
config.driver_data = pcap;
rdev = regulator_register(&pcap_regulators[pdev->id], &config);
rdev = devm_regulator_register(&pdev->dev, &pcap_regulators[pdev->id],
&config);
if (IS_ERR(rdev))
return PTR_ERR(rdev);
@ -255,22 +256,12 @@ static int pcap_regulator_probe(struct platform_device *pdev)
return 0;
}
static int pcap_regulator_remove(struct platform_device *pdev)
{
struct regulator_dev *rdev = platform_get_drvdata(pdev);
regulator_unregister(rdev);
return 0;
}
static struct platform_driver pcap_regulator_driver = {
.driver = {
.name = "pcap-regulator",
.owner = THIS_MODULE,
},
.probe = pcap_regulator_probe,
.remove = pcap_regulator_remove,
};
static int __init pcap_regulator_init(void)

View File

@ -90,7 +90,8 @@ static int pcf50633_regulator_probe(struct platform_device *pdev)
config.driver_data = pcf;
config.regmap = pcf->regmap;
rdev = regulator_register(&regulators[pdev->id], &config);
rdev = devm_regulator_register(&pdev->dev, &regulators[pdev->id],
&config);
if (IS_ERR(rdev))
return PTR_ERR(rdev);
@ -102,21 +103,11 @@ static int pcf50633_regulator_probe(struct platform_device *pdev)
return 0;
}
static int pcf50633_regulator_remove(struct platform_device *pdev)
{
struct regulator_dev *rdev = platform_get_drvdata(pdev);
regulator_unregister(rdev);
return 0;
}
static struct platform_driver pcf50633_regulator_driver = {
.driver = {
.name = "pcf50633-regltr",
},
.probe = pcf50633_regulator_probe,
.remove = pcf50633_regulator_remove,
};
static int __init pcf50633_regulator_init(void)

View File

@ -173,33 +173,16 @@ skip_ext_pwr_config:
config.driver_data = reg;
config.regmap = rc5t583->regmap;
rdev = regulator_register(&ri->desc, &config);
rdev = devm_regulator_register(&pdev->dev, &ri->desc, &config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "Failed to register regulator %s\n",
ri->desc.name);
ret = PTR_ERR(rdev);
goto clean_exit;
return PTR_ERR(rdev);
}
reg->rdev = rdev;
}
platform_set_drvdata(pdev, regs);
return 0;
clean_exit:
while (--id >= 0)
regulator_unregister(regs[id].rdev);
return ret;
}
static int rc5t583_regulator_remove(struct platform_device *pdev)
{
struct rc5t583_regulator *regs = platform_get_drvdata(pdev);
int id;
for (id = 0; id < RC5T583_REGULATOR_MAX; ++id)
regulator_unregister(regs[id].rdev);
return 0;
}
static struct platform_driver rc5t583_regulator_driver = {
@ -208,7 +191,6 @@ static struct platform_driver rc5t583_regulator_driver = {
.owner = THIS_MODULE,
},
.probe = rc5t583_regulator_probe,
.remove = rc5t583_regulator_remove,
};
static int __init rc5t583_regulator_init(void)

View File

@ -448,32 +448,16 @@ common_reg:
config.of_node = rdata[i].of_node;
}
s2mps11->rdev[i] = regulator_register(&regulators[i], &config);
s2mps11->rdev[i] = devm_regulator_register(&pdev->dev,
&regulators[i], &config);
if (IS_ERR(s2mps11->rdev[i])) {
ret = PTR_ERR(s2mps11->rdev[i]);
dev_err(&pdev->dev, "regulator init failed for %d\n",
i);
s2mps11->rdev[i] = NULL;
goto err;
return ret;
}
}
return 0;
err:
for (i = 0; i < S2MPS11_REGULATOR_MAX; i++)
regulator_unregister(s2mps11->rdev[i]);
return ret;
}
static int s2mps11_pmic_remove(struct platform_device *pdev)
{
struct s2mps11_info *s2mps11 = platform_get_drvdata(pdev);
int i;
for (i = 0; i < S2MPS11_REGULATOR_MAX; i++)
regulator_unregister(s2mps11->rdev[i]);
return 0;
}
@ -489,7 +473,6 @@ static struct platform_driver s2mps11_pmic_driver = {
.owner = THIS_MODULE,
},
.probe = s2mps11_pmic_probe,
.remove = s2mps11_pmic_remove,
.id_table = s2mps11_pmic_id,
};

View File

@ -522,7 +522,7 @@ static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev,
struct device_node *pmic_np, *regulators_np, *reg_np;
struct sec_regulator_data *rdata;
struct sec_opmode_data *rmode;
unsigned int i, dvs_voltage_nr = 1, ret;
unsigned int i, dvs_voltage_nr = 8, ret;
pmic_np = iodev->dev->of_node;
if (!pmic_np) {
@ -586,15 +586,39 @@ static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev,
rmode++;
}
if (of_get_property(pmic_np, "s5m8767,pmic-buck2-uses-gpio-dvs", NULL))
if (of_get_property(pmic_np, "s5m8767,pmic-buck2-uses-gpio-dvs", NULL)) {
pdata->buck2_gpiodvs = true;
if (of_get_property(pmic_np, "s5m8767,pmic-buck3-uses-gpio-dvs", NULL))
if (of_property_read_u32_array(pmic_np,
"s5m8767,pmic-buck2-dvs-voltage",
pdata->buck2_voltage, dvs_voltage_nr)) {
dev_err(iodev->dev, "buck2 voltages not specified\n");
return -EINVAL;
}
}
if (of_get_property(pmic_np, "s5m8767,pmic-buck3-uses-gpio-dvs", NULL)) {
pdata->buck3_gpiodvs = true;
if (of_get_property(pmic_np, "s5m8767,pmic-buck4-uses-gpio-dvs", NULL))
if (of_property_read_u32_array(pmic_np,
"s5m8767,pmic-buck3-dvs-voltage",
pdata->buck3_voltage, dvs_voltage_nr)) {
dev_err(iodev->dev, "buck3 voltages not specified\n");
return -EINVAL;
}
}
if (of_get_property(pmic_np, "s5m8767,pmic-buck4-uses-gpio-dvs", NULL)) {
pdata->buck4_gpiodvs = true;
if (of_property_read_u32_array(pmic_np,
"s5m8767,pmic-buck4-dvs-voltage",
pdata->buck4_voltage, dvs_voltage_nr)) {
dev_err(iodev->dev, "buck4 voltages not specified\n");
return -EINVAL;
}
}
if (pdata->buck2_gpiodvs || pdata->buck3_gpiodvs ||
pdata->buck4_gpiodvs) {
ret = s5m8767_pmic_dt_parse_dvs_gpio(iodev, pdata, pmic_np);
@ -612,32 +636,26 @@ static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev,
"invalid value for default dvs index, use 0\n");
}
}
dvs_voltage_nr = 8;
}
ret = s5m8767_pmic_dt_parse_ds_gpio(iodev, pdata, pmic_np);
if (ret)
return -EINVAL;
if (of_property_read_u32_array(pmic_np,
"s5m8767,pmic-buck2-dvs-voltage",
pdata->buck2_voltage, dvs_voltage_nr)) {
dev_err(iodev->dev, "buck2 voltages not specified\n");
return -EINVAL;
}
if (of_get_property(pmic_np, "s5m8767,pmic-buck2-ramp-enable", NULL))
pdata->buck2_ramp_enable = true;
if (of_property_read_u32_array(pmic_np,
"s5m8767,pmic-buck3-dvs-voltage",
pdata->buck3_voltage, dvs_voltage_nr)) {
dev_err(iodev->dev, "buck3 voltages not specified\n");
return -EINVAL;
}
if (of_get_property(pmic_np, "s5m8767,pmic-buck3-ramp-enable", NULL))
pdata->buck3_ramp_enable = true;
if (of_property_read_u32_array(pmic_np,
"s5m8767,pmic-buck4-dvs-voltage",
pdata->buck4_voltage, dvs_voltage_nr)) {
dev_err(iodev->dev, "buck4 voltages not specified\n");
return -EINVAL;
if (of_get_property(pmic_np, "s5m8767,pmic-buck4-ramp-enable", NULL))
pdata->buck4_ramp_enable = true;
if (pdata->buck2_ramp_enable || pdata->buck3_ramp_enable
|| pdata->buck4_ramp_enable) {
if (of_property_read_u32(pmic_np, "s5m8767,pmic-buck-ramp-delay",
&pdata->buck_ramp_delay))
pdata->buck_ramp_delay = 0;
}
return 0;
@ -910,33 +928,16 @@ static int s5m8767_pmic_probe(struct platform_device *pdev)
config.regmap = iodev->regmap;
config.of_node = pdata->regulators[i].reg_node;
rdev[i] = regulator_register(&regulators[id], &config);
rdev[i] = devm_regulator_register(&pdev->dev, &regulators[id],
&config);
if (IS_ERR(rdev[i])) {
ret = PTR_ERR(rdev[i]);
dev_err(s5m8767->dev, "regulator init failed for %d\n",
id);
rdev[i] = NULL;
goto err;
return ret;
}
}
return 0;
err:
for (i = 0; i < s5m8767->num_regulators; i++)
regulator_unregister(rdev[i]);
return ret;
}
static int s5m8767_pmic_remove(struct platform_device *pdev)
{
struct s5m8767_info *s5m8767 = platform_get_drvdata(pdev);
struct regulator_dev **rdev = s5m8767->rdev;
int i;
for (i = 0; i < s5m8767->num_regulators; i++)
regulator_unregister(rdev[i]);
return 0;
}
@ -952,7 +953,6 @@ static struct platform_driver s5m8767_pmic_driver = {
.owner = THIS_MODULE,
},
.probe = s5m8767_pmic_probe,
.remove = s5m8767_pmic_remove,
.id_table = s5m8767_pmic_id,
};

View File

@ -0,0 +1,111 @@
/*
* Regulator driver for STw4810/STw4811 VMMC regulator.
*
* Copyright (C) 2013 ST-Ericsson SA
* Written on behalf of Linaro for ST-Ericsson
*
* Author: Linus Walleij <linus.walleij@linaro.org>
*
* License terms: GNU General Public License (GPL) version 2
*/
#include <linux/err.h>
#include <linux/init.h>
#include <linux/mfd/stw481x.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>
static const unsigned int stw481x_vmmc_voltages[] = {
1800000,
1800000,
2850000,
3000000,
1850000,
2600000,
2700000,
3300000,
};
static struct regulator_ops stw481x_vmmc_ops = {
.list_voltage = regulator_list_voltage_table,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
};
static struct regulator_desc vmmc_regulator = {
.name = "VMMC",
.id = 0,
.ops = &stw481x_vmmc_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.n_voltages = ARRAY_SIZE(stw481x_vmmc_voltages),
.volt_table = stw481x_vmmc_voltages,
.enable_time = 200, /* FIXME: look this up */
.enable_reg = STW_CONF1,
.enable_mask = STW_CONF1_PDN_VMMC,
.vsel_reg = STW_CONF1,
.vsel_mask = STW_CONF1_VMMC_MASK,
};
static int stw481x_vmmc_regulator_probe(struct platform_device *pdev)
{
struct stw481x *stw481x = dev_get_platdata(&pdev->dev);
struct regulator_config config = { };
int ret;
/* First disable the external VMMC if it's active */
ret = regmap_update_bits(stw481x->map, STW_CONF2,
STW_CONF2_VMMC_EXT, 0);
if (ret) {
dev_err(&pdev->dev, "could not disable external VMMC\n");
return ret;
}
/* Register VMMC regulator */
config.dev = &pdev->dev;
config.driver_data = stw481x;
config.regmap = stw481x->map;
config.of_node = pdev->dev.of_node;
config.init_data = of_get_regulator_init_data(&pdev->dev,
pdev->dev.of_node);
stw481x->vmmc_regulator = regulator_register(&vmmc_regulator, &config);
if (IS_ERR(stw481x->vmmc_regulator)) {
dev_err(&pdev->dev,
"error initializing STw481x VMMC regulator\n");
return PTR_ERR(stw481x->vmmc_regulator);
}
dev_info(&pdev->dev, "initialized STw481x VMMC regulator\n");
return 0;
}
static int stw481x_vmmc_regulator_remove(struct platform_device *pdev)
{
struct stw481x *stw481x = dev_get_platdata(&pdev->dev);
regulator_unregister(stw481x->vmmc_regulator);
return 0;
}
static const struct of_device_id stw481x_vmmc_match[] = {
{ .compatible = "st,stw481x-vmmc", },
{},
};
static struct platform_driver stw481x_vmmc_regulator_driver = {
.driver = {
.name = "stw481x-vmmc-regulator",
.owner = THIS_MODULE,
.of_match_table = stw481x_vmmc_match,
},
.probe = stw481x_vmmc_regulator_probe,
.remove = stw481x_vmmc_regulator_remove,
};
module_platform_driver(stw481x_vmmc_regulator_driver);

View File

@ -615,7 +615,7 @@ static int ti_abb_init_table(struct device *dev, struct ti_abb *abb,
pname, *volt_table, vset_mask);
continue;
}
info->vset = efuse_val & vset_mask >> __ffs(vset_mask);
info->vset = (efuse_val & vset_mask) >> __ffs(vset_mask);
dev_dbg(dev, "[%d]v=%d vset=%x\n", i, *volt_table, info->vset);
check_abb:
switch (info->opp_sel) {
@ -708,39 +708,31 @@ static int ti_abb_probe(struct platform_device *pdev)
match = of_match_device(ti_abb_of_match, dev);
if (!match) {
/* We do not expect this to happen */
ret = -ENODEV;
dev_err(dev, "%s: Unable to match device\n", __func__);
goto err;
return -ENODEV;
}
if (!match->data) {
ret = -EINVAL;
dev_err(dev, "%s: Bad data in match\n", __func__);
goto err;
return -EINVAL;
}
abb = devm_kzalloc(dev, sizeof(struct ti_abb), GFP_KERNEL);
if (!abb) {
dev_err(dev, "%s: Unable to allocate ABB struct\n", __func__);
ret = -ENOMEM;
goto err;
}
if (!abb)
return -ENOMEM;
abb->regs = match->data;
/* Map ABB resources */
pname = "base-address";
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname);
abb->base = devm_ioremap_resource(dev, res);
if (IS_ERR(abb->base)) {
ret = PTR_ERR(abb->base);
goto err;
}
if (IS_ERR(abb->base))
return PTR_ERR(abb->base);
pname = "int-address";
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname);
if (!res) {
dev_err(dev, "Missing '%s' IO resource\n", pname);
ret = -ENODEV;
goto err;
return -ENODEV;
}
/*
* We may have shared interrupt register offsets which are
@ -750,8 +742,7 @@ static int ti_abb_probe(struct platform_device *pdev)
resource_size(res));
if (!abb->int_base) {
dev_err(dev, "Unable to map '%s'\n", pname);
ret = -ENOMEM;
goto err;
return -ENOMEM;
}
/* Map Optional resources */
@ -771,17 +762,19 @@ static int ti_abb_probe(struct platform_device *pdev)
resource_size(res));
if (!abb->efuse_base) {
dev_err(dev, "Unable to map '%s'\n", pname);
ret = -ENOMEM;
goto err;
return -ENOMEM;
}
pname = "ldo-address";
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname);
abb->ldo_base = devm_ioremap_resource(dev, res);
if (IS_ERR(abb->ldo_base)) {
ret = PTR_ERR(abb->ldo_base);
goto err;
if (!res) {
dev_dbg(dev, "Missing '%s' IO resource\n", pname);
ret = -ENODEV;
goto skip_opt;
}
abb->ldo_base = devm_ioremap_resource(dev, res);
if (IS_ERR(abb->ldo_base))
return PTR_ERR(abb->ldo_base);
/* IF ldo_base is set, the following are mandatory */
pname = "ti,ldovbb-override-mask";
@ -790,12 +783,11 @@ static int ti_abb_probe(struct platform_device *pdev)
&abb->ldovbb_override_mask);
if (ret) {
dev_err(dev, "Missing '%s' (%d)\n", pname, ret);
goto err;
return ret;
}
if (!abb->ldovbb_override_mask) {
dev_err(dev, "Invalid property:'%s' set as 0!\n", pname);
ret = -EINVAL;
goto err;
return -EINVAL;
}
pname = "ti,ldovbb-vset-mask";
@ -804,12 +796,11 @@ static int ti_abb_probe(struct platform_device *pdev)
&abb->ldovbb_vset_mask);
if (ret) {
dev_err(dev, "Missing '%s' (%d)\n", pname, ret);
goto err;
return ret;
}
if (!abb->ldovbb_vset_mask) {
dev_err(dev, "Invalid property:'%s' set as 0!\n", pname);
ret = -EINVAL;
goto err;
return -EINVAL;
}
skip_opt:
@ -819,31 +810,29 @@ skip_opt:
&abb->txdone_mask);
if (ret) {
dev_err(dev, "Missing '%s' (%d)\n", pname, ret);
goto err;
return ret;
}
if (!abb->txdone_mask) {
dev_err(dev, "Invalid property:'%s' set as 0!\n", pname);
ret = -EINVAL;
goto err;
return -EINVAL;
}
initdata = of_get_regulator_init_data(dev, pdev->dev.of_node);
if (!initdata) {
ret = -ENOMEM;
dev_err(dev, "%s: Unable to alloc regulator init data\n",
__func__);
goto err;
return -ENOMEM;
}
/* init ABB opp_sel table */
ret = ti_abb_init_table(dev, abb, initdata);
if (ret)
goto err;
return ret;
/* init ABB timing */
ret = ti_abb_init_timings(dev, abb);
if (ret)
goto err;
return ret;
desc = &abb->rdesc;
desc->name = dev_name(dev);
@ -861,12 +850,12 @@ skip_opt:
config.driver_data = abb;
config.of_node = pdev->dev.of_node;
rdev = regulator_register(desc, &config);
rdev = devm_regulator_register(dev, desc, &config);
if (IS_ERR(rdev)) {
ret = PTR_ERR(rdev);
dev_err(dev, "%s: failed to register regulator(%d)\n",
__func__, ret);
goto err;
return ret;
}
platform_set_drvdata(pdev, rdev);
@ -874,31 +863,12 @@ skip_opt:
ti_abb_rmw(abb->regs->sr2_en_mask, 1, abb->regs->setup_reg, abb->base);
return 0;
err:
dev_err(dev, "%s: Failed to initialize(%d)\n", __func__, ret);
return ret;
}
/**
* ti_abb_remove() - cleanups
* @pdev: ABB platform device
*
* Return: 0
*/
static int ti_abb_remove(struct platform_device *pdev)
{
struct regulator_dev *rdev = platform_get_drvdata(pdev);
regulator_unregister(rdev);
return 0;
}
MODULE_ALIAS("platform:ti_abb");
static struct platform_driver ti_abb_driver = {
.probe = ti_abb_probe,
.remove = ti_abb_remove,
.driver = {
.name = "ti_abb",
.owner = THIS_MODULE,

View File

@ -343,7 +343,7 @@ static int tps51632_probe(struct i2c_client *client,
config.regmap = tps->regmap;
config.of_node = client->dev.of_node;
rdev = regulator_register(&tps->desc, &config);
rdev = devm_regulator_register(&client->dev, &tps->desc, &config);
if (IS_ERR(rdev)) {
dev_err(tps->dev, "regulator register failed\n");
return PTR_ERR(rdev);
@ -353,14 +353,6 @@ static int tps51632_probe(struct i2c_client *client,
return 0;
}
static int tps51632_remove(struct i2c_client *client)
{
struct tps51632_chip *tps = i2c_get_clientdata(client);
regulator_unregister(tps->rdev);
return 0;
}
static const struct i2c_device_id tps51632_id[] = {
{.name = "tps51632",},
{},
@ -375,7 +367,6 @@ static struct i2c_driver tps51632_i2c_driver = {
.of_match_table = of_match_ptr(tps51632_of_match),
},
.probe = tps51632_probe,
.remove = tps51632_remove,
.id_table = tps51632_id,
};

View File

@ -137,7 +137,7 @@ static int tps6105x_regulator_probe(struct platform_device *pdev)
/* This instance is not set for regulator mode so bail out */
if (pdata->mode != TPS6105X_MODE_VOLTAGE) {
dev_info(&pdev->dev,
"chip not in voltage mode mode, exit probe \n");
"chip not in voltage mode mode, exit probe\n");
return 0;
}
@ -146,8 +146,9 @@ static int tps6105x_regulator_probe(struct platform_device *pdev)
config.driver_data = tps6105x;
/* Register regulator with framework */
tps6105x->regulator = regulator_register(&tps6105x_regulator_desc,
&config);
tps6105x->regulator = devm_regulator_register(&pdev->dev,
&tps6105x_regulator_desc,
&config);
if (IS_ERR(tps6105x->regulator)) {
ret = PTR_ERR(tps6105x->regulator);
dev_err(&tps6105x->client->dev,
@ -159,20 +160,12 @@ static int tps6105x_regulator_probe(struct platform_device *pdev)
return 0;
}
static int tps6105x_regulator_remove(struct platform_device *pdev)
{
struct tps6105x *tps6105x = dev_get_platdata(&pdev->dev);
regulator_unregister(tps6105x->regulator);
return 0;
}
static struct platform_driver tps6105x_regulator_driver = {
.driver = {
.name = "tps6105x-regulator",
.owner = THIS_MODULE,
},
.probe = tps6105x_regulator_probe,
.remove = tps6105x_regulator_remove,
};
static __init int tps6105x_regulator_init(void)

View File

@ -476,7 +476,7 @@ static int tps62360_probe(struct i2c_client *client,
config.of_node = client->dev.of_node;
/* Register the regulators */
rdev = regulator_register(&tps->desc, &config);
rdev = devm_regulator_register(&client->dev, &tps->desc, &config);
if (IS_ERR(rdev)) {
dev_err(tps->dev,
"%s(): regulator register failed with err %s\n",
@ -488,20 +488,6 @@ static int tps62360_probe(struct i2c_client *client,
return 0;
}
/**
* tps62360_remove - tps62360 driver i2c remove handler
* @client: i2c driver client device structure
*
* Unregister TPS driver as an i2c client device driver
*/
static int tps62360_remove(struct i2c_client *client)
{
struct tps62360_chip *tps = i2c_get_clientdata(client);
regulator_unregister(tps->rdev);
return 0;
}
static void tps62360_shutdown(struct i2c_client *client)
{
struct tps62360_chip *tps = i2c_get_clientdata(client);
@ -535,7 +521,6 @@ static struct i2c_driver tps62360_i2c_driver = {
.of_match_table = of_match_ptr(tps62360_of_match),
},
.probe = tps62360_probe,
.remove = tps62360_remove,
.shutdown = tps62360_shutdown,
.id_table = tps62360_id,
};

View File

@ -277,12 +277,12 @@ static int tps_65023_probe(struct i2c_client *client,
config.regmap = tps->regmap;
/* Register the regulators */
rdev = regulator_register(&tps->desc[i], &config);
rdev = devm_regulator_register(&client->dev, &tps->desc[i],
&config);
if (IS_ERR(rdev)) {
dev_err(&client->dev, "failed to register %s\n",
id->name);
error = PTR_ERR(rdev);
goto fail;
return PTR_ERR(rdev);
}
/* Save regulator for cleanup */
@ -293,24 +293,10 @@ static int tps_65023_probe(struct i2c_client *client,
/* Enable setting output voltage by I2C */
regmap_update_bits(tps->regmap, TPS65023_REG_CON_CTRL2,
TPS65023_REG_CTRL2_CORE_ADJ, TPS65023_REG_CTRL2_CORE_ADJ);
TPS65023_REG_CTRL2_CORE_ADJ,
TPS65023_REG_CTRL2_CORE_ADJ);
return 0;
fail:
while (--i >= 0)
regulator_unregister(tps->rdev[i]);
return error;
}
static int tps_65023_remove(struct i2c_client *client)
{
struct tps_pmic *tps = i2c_get_clientdata(client);
int i;
for (i = 0; i < TPS65023_NUM_REGULATOR; i++)
regulator_unregister(tps->rdev[i]);
return 0;
}
static const struct tps_info tps65020_regs[] = {
@ -430,7 +416,6 @@ static struct i2c_driver tps_65023_i2c_driver = {
.owner = THIS_MODULE,
},
.probe = tps_65023_probe,
.remove = tps_65023_remove,
.id_table = tps_65023_id,
};

View File

@ -508,13 +508,13 @@ static int tps6507x_pmic_probe(struct platform_device *pdev)
config.of_node = tps6507x_reg_matches[i].of_node;
}
rdev = regulator_register(&tps->desc[i], &config);
rdev = devm_regulator_register(&pdev->dev, &tps->desc[i],
&config);
if (IS_ERR(rdev)) {
dev_err(tps6507x_dev->dev,
"failed to register %s regulator\n",
pdev->name);
error = PTR_ERR(rdev);
goto fail;
return PTR_ERR(rdev);
}
/* Save regulator for cleanup */
@ -525,22 +525,6 @@ static int tps6507x_pmic_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, tps6507x_dev);
return 0;
fail:
while (--i >= 0)
regulator_unregister(tps->rdev[i]);
return error;
}
static int tps6507x_pmic_remove(struct platform_device *pdev)
{
struct tps6507x_dev *tps6507x_dev = platform_get_drvdata(pdev);
struct tps6507x_pmic *tps = tps6507x_dev->pmic;
int i;
for (i = 0; i < TPS6507X_NUM_REGULATOR; i++)
regulator_unregister(tps->rdev[i]);
return 0;
}
static struct platform_driver tps6507x_pmic_driver = {
@ -549,7 +533,6 @@ static struct platform_driver tps6507x_pmic_driver = {
.owner = THIS_MODULE,
},
.probe = tps6507x_pmic_probe,
.remove = tps6507x_pmic_remove,
};
static int __init tps6507x_pmic_init(void)

View File

@ -180,7 +180,7 @@ static struct tps65090_platform_data *tps65090_parse_dt_reg_data(
return ERR_PTR(-ENOMEM);
}
regulators = of_find_node_by_name(np, "regulators");
regulators = of_get_child_by_name(np, "regulators");
if (!regulators) {
dev_err(&pdev->dev, "regulator node not found\n");
return ERR_PTR(-ENODEV);
@ -279,7 +279,7 @@ static int tps65090_regulator_probe(struct platform_device *pdev)
if (ret < 0) {
dev_err(&pdev->dev,
"failed disable ext control\n");
goto scrub;
return ret;
}
}
}
@ -296,12 +296,11 @@ static int tps65090_regulator_probe(struct platform_device *pdev)
else
config.of_node = NULL;
rdev = regulator_register(ri->desc, &config);
rdev = devm_regulator_register(&pdev->dev, ri->desc, &config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "failed to register regulator %s\n",
ri->desc->name);
ret = PTR_ERR(rdev);
goto scrub;
return PTR_ERR(rdev);
}
ri->rdev = rdev;
@ -309,36 +308,13 @@ static int tps65090_regulator_probe(struct platform_device *pdev)
if (tps_pdata && is_dcdc(num) && tps_pdata->reg_init_data &&
tps_pdata->enable_ext_control) {
ret = tps65090_config_ext_control(ri, true);
if (ret < 0) {
/* Increment num to get unregister rdev */
num++;
goto scrub;
}
if (ret < 0)
return ret;
}
}
platform_set_drvdata(pdev, pmic);
return 0;
scrub:
while (--num >= 0) {
ri = &pmic[num];
regulator_unregister(ri->rdev);
}
return ret;
}
static int tps65090_regulator_remove(struct platform_device *pdev)
{
struct tps65090_regulator *pmic = platform_get_drvdata(pdev);
struct tps65090_regulator *ri;
int num;
for (num = 0; num < TPS65090_REGULATOR_MAX; ++num) {
ri = &pmic[num];
regulator_unregister(ri->rdev);
}
return 0;
}
static struct platform_driver tps65090_regulator_driver = {
@ -347,7 +323,6 @@ static struct platform_driver tps65090_regulator_driver = {
.owner = THIS_MODULE,
},
.probe = tps65090_regulator_probe,
.remove = tps65090_regulator_remove,
};
static int __init tps65090_regulator_init(void)

View File

@ -52,25 +52,17 @@ static const unsigned int LDO1_VSEL_table[] = {
};
static const struct regulator_linear_range tps65217_uv1_ranges[] = {
{ .min_uV = 900000, .max_uV = 1500000, .min_sel = 0, .max_sel = 24,
.uV_step = 25000 },
{ .min_uV = 1550000, .max_uV = 1800000, .min_sel = 25, .max_sel = 30,
.uV_step = 50000 },
{ .min_uV = 1850000, .max_uV = 2900000, .min_sel = 31, .max_sel = 52,
.uV_step = 50000 },
{ .min_uV = 3000000, .max_uV = 3200000, .min_sel = 53, .max_sel = 55,
.uV_step = 100000 },
{ .min_uV = 3300000, .max_uV = 3300000, .min_sel = 56, .max_sel = 62,
.uV_step = 0 },
REGULATOR_LINEAR_RANGE(900000, 0, 24, 25000),
REGULATOR_LINEAR_RANGE(1550000, 25, 30, 50000),
REGULATOR_LINEAR_RANGE(1850000, 31, 52, 50000),
REGULATOR_LINEAR_RANGE(3000000, 53, 55, 100000),
REGULATOR_LINEAR_RANGE(3300000, 56, 62, 0),
};
static const struct regulator_linear_range tps65217_uv2_ranges[] = {
{ .min_uV = 1500000, .max_uV = 1900000, .min_sel = 0, .max_sel = 8,
.uV_step = 50000 },
{ .min_uV = 2000000, .max_uV = 2400000, .min_sel = 9, .max_sel = 13,
.uV_step = 100000 },
{ .min_uV = 2450000, .max_uV = 3300000, .min_sel = 14, .max_sel = 31,
.uV_step = 50000 },
REGULATOR_LINEAR_RANGE(1500000, 0, 8, 50000),
REGULATOR_LINEAR_RANGE(2000000, 9, 13, 100000),
REGULATOR_LINEAR_RANGE(2450000, 14, 31, 50000),
};
static int tps65217_pmic_enable(struct regulator_dev *dev)
@ -233,7 +225,7 @@ static int tps65217_regulator_probe(struct platform_device *pdev)
struct regulator_init_data *reg_data;
struct regulator_dev *rdev;
struct regulator_config config = { };
int i, ret;
int i;
if (tps->dev->of_node)
pdata = tps65217_parse_dt(pdev);
@ -269,35 +261,18 @@ static int tps65217_regulator_probe(struct platform_device *pdev)
if (tps->dev->of_node)
config.of_node = pdata->of_node[i];
rdev = regulator_register(&regulators[i], &config);
rdev = devm_regulator_register(&pdev->dev, &regulators[i],
&config);
if (IS_ERR(rdev)) {
dev_err(tps->dev, "failed to register %s regulator\n",
pdev->name);
ret = PTR_ERR(rdev);
goto err_unregister_regulator;
return PTR_ERR(rdev);
}
/* Save regulator for cleanup */
tps->rdev[i] = rdev;
}
return 0;
err_unregister_regulator:
while (--i >= 0)
regulator_unregister(tps->rdev[i]);
return ret;
}
static int tps65217_regulator_remove(struct platform_device *pdev)
{
struct tps65217 *tps = platform_get_drvdata(pdev);
unsigned int i;
for (i = 0; i < TPS65217_NUM_REGULATOR; i++)
regulator_unregister(tps->rdev[i]);
return 0;
}
static struct platform_driver tps65217_regulator_driver = {
@ -305,7 +280,6 @@ static struct platform_driver tps65217_regulator_driver = {
.name = "tps65217-pmic",
},
.probe = tps65217_regulator_probe,
.remove = tps65217_regulator_remove,
};
static int __init tps65217_regulator_init(void)

View File

@ -577,21 +577,6 @@ static struct regulator_ops regulator_ops = {
.get_current_limit = get_current_limit,
};
static int pmic_remove(struct spi_device *spi)
{
struct tps6524x *hw = spi_get_drvdata(spi);
int i;
if (!hw)
return 0;
for (i = 0; i < N_REGULATORS; i++) {
regulator_unregister(hw->rdev[i]);
hw->rdev[i] = NULL;
}
spi_set_drvdata(spi, NULL);
return 0;
}
static int pmic_probe(struct spi_device *spi)
{
struct tps6524x *hw;
@ -599,7 +584,7 @@ static int pmic_probe(struct spi_device *spi)
const struct supply_info *info = supply_info;
struct regulator_init_data *init_data;
struct regulator_config config = { };
int ret = 0, i;
int i;
init_data = dev_get_platdata(dev);
if (!init_data) {
@ -632,24 +617,17 @@ static int pmic_probe(struct spi_device *spi)
config.init_data = init_data;
config.driver_data = hw;
hw->rdev[i] = regulator_register(&hw->desc[i], &config);
if (IS_ERR(hw->rdev[i])) {
ret = PTR_ERR(hw->rdev[i]);
hw->rdev[i] = NULL;
goto fail;
}
hw->rdev[i] = devm_regulator_register(dev, &hw->desc[i],
&config);
if (IS_ERR(hw->rdev[i]))
return PTR_ERR(hw->rdev[i]);
}
return 0;
fail:
pmic_remove(spi);
return ret;
}
static struct spi_driver pmic_driver = {
.probe = pmic_probe,
.remove = pmic_remove,
.driver = {
.name = "tps6524x",
.owner = THIS_MODULE,

View File

@ -298,7 +298,7 @@ static struct tps6586x_platform_data *tps6586x_parse_regulator_dt(
struct tps6586x_platform_data *pdata;
int err;
regs = of_find_node_by_name(np, "regulators");
regs = of_get_child_by_name(np, "regulators");
if (!regs) {
dev_err(&pdev->dev, "regulator node not found\n");
return NULL;
@ -379,15 +379,14 @@ static int tps6586x_regulator_probe(struct platform_device *pdev)
ri = find_regulator_info(id);
if (!ri) {
dev_err(&pdev->dev, "invalid regulator ID specified\n");
err = -EINVAL;
goto fail;
return -EINVAL;
}
err = tps6586x_regulator_preinit(pdev->dev.parent, ri);
if (err) {
dev_err(&pdev->dev,
"regulator %d preinit failed, e %d\n", id, err);
goto fail;
return err;
}
config.dev = pdev->dev.parent;
@ -397,12 +396,12 @@ static int tps6586x_regulator_probe(struct platform_device *pdev)
if (tps6586x_reg_matches)
config.of_node = tps6586x_reg_matches[id].of_node;
rdev[id] = regulator_register(&ri->desc, &config);
rdev[id] = devm_regulator_register(&pdev->dev, &ri->desc,
&config);
if (IS_ERR(rdev[id])) {
dev_err(&pdev->dev, "failed to register regulator %s\n",
ri->desc.name);
err = PTR_ERR(rdev[id]);
goto fail;
return PTR_ERR(rdev[id]);
}
if (reg_data) {
@ -411,30 +410,13 @@ static int tps6586x_regulator_probe(struct platform_device *pdev)
if (err < 0) {
dev_err(&pdev->dev,
"Slew rate config failed, e %d\n", err);
regulator_unregister(rdev[id]);
goto fail;
return err;
}
}
}
platform_set_drvdata(pdev, rdev);
return 0;
fail:
while (--id >= 0)
regulator_unregister(rdev[id]);
return err;
}
static int tps6586x_regulator_remove(struct platform_device *pdev)
{
struct regulator_dev **rdev = platform_get_drvdata(pdev);
int id = TPS6586X_ID_MAX_REGULATOR;
while (--id >= 0)
regulator_unregister(rdev[id]);
return 0;
}
static struct platform_driver tps6586x_regulator_driver = {
@ -443,7 +425,6 @@ static struct platform_driver tps6586x_regulator_driver = {
.owner = THIS_MODULE,
},
.probe = tps6586x_regulator_probe,
.remove = tps6586x_regulator_remove,
};
static int __init tps6586x_regulator_init(void)

View File

@ -481,7 +481,7 @@ static int tps65910_get_voltage_dcdc_sel(struct regulator_dev *dev)
/* multiplier 0 == 1 but 2,3 normal */
if (!mult)
mult=1;
mult = 1;
if (sr) {
/* normalise to valid range */
@ -685,7 +685,7 @@ static int tps65910_list_voltage_dcdc(struct regulator_dev *dev,
case TPS65910_REG_VDD2:
mult = (selector / VDD1_2_NUM_VOLT_FINE) + 1;
volt = VDD1_2_MIN_VOLT +
(selector % VDD1_2_NUM_VOLT_FINE) * VDD1_2_OFFSET;
(selector % VDD1_2_NUM_VOLT_FINE) * VDD1_2_OFFSET;
break;
case TPS65911_REG_VDDCTRL:
volt = VDDCTRL_MIN_VOLT + (selector * VDDCTRL_OFFSET);
@ -703,7 +703,7 @@ static int tps65911_list_voltage(struct regulator_dev *dev, unsigned selector)
struct tps65910_reg *pmic = rdev_get_drvdata(dev);
int step_mv = 0, id = rdev_get_id(dev);
switch(id) {
switch (id) {
case TPS65911_REG_LDO1:
case TPS65911_REG_LDO2:
case TPS65911_REG_LDO4:
@ -982,7 +982,7 @@ static struct tps65910_board *tps65910_parse_dt_reg_data(
}
np = of_node_get(pdev->dev.parent->of_node);
regulators = of_find_node_by_name(np, "regulators");
regulators = of_get_child_by_name(np, "regulators");
if (!regulators) {
dev_err(&pdev->dev, "regulator node not found\n");
return NULL;
@ -1074,7 +1074,7 @@ static int tps65910_probe(struct platform_device *pdev)
tps65910_reg_set_bits(pmic->mfd, TPS65910_DEVCTRL,
DEVCTRL_SR_CTL_I2C_SEL_MASK);
switch(tps65910_chip_id(tps65910)) {
switch (tps65910_chip_id(tps65910)) {
case TPS65910:
pmic->get_ctrl_reg = &tps65910_get_ctrl_register;
pmic->num_regulators = ARRAY_SIZE(tps65910_regs);
@ -1177,35 +1177,19 @@ static int tps65910_probe(struct platform_device *pdev)
if (tps65910_reg_matches)
config.of_node = tps65910_reg_matches[i].of_node;
rdev = regulator_register(&pmic->desc[i], &config);
rdev = devm_regulator_register(&pdev->dev, &pmic->desc[i],
&config);
if (IS_ERR(rdev)) {
dev_err(tps65910->dev,
"failed to register %s regulator\n",
pdev->name);
err = PTR_ERR(rdev);
goto err_unregister_regulator;
return PTR_ERR(rdev);
}
/* Save regulator for cleanup */
pmic->rdev[i] = rdev;
}
return 0;
err_unregister_regulator:
while (--i >= 0)
regulator_unregister(pmic->rdev[i]);
return err;
}
static int tps65910_remove(struct platform_device *pdev)
{
struct tps65910_reg *pmic = platform_get_drvdata(pdev);
int i;
for (i = 0; i < pmic->num_regulators; i++)
regulator_unregister(pmic->rdev[i]);
return 0;
}
static void tps65910_shutdown(struct platform_device *pdev)
@ -1244,7 +1228,6 @@ static struct platform_driver tps65910_driver = {
.owner = THIS_MODULE,
},
.probe = tps65910_probe,
.remove = tps65910_remove,
.shutdown = tps65910_shutdown,
};

View File

@ -119,12 +119,9 @@ struct tps65912_reg {
};
static const struct regulator_linear_range tps65912_ldo_ranges[] = {
{ .min_uV = 800000, .max_uV = 1600000, .min_sel = 0, .max_sel = 32,
.uV_step = 25000 },
{ .min_uV = 1650000, .max_uV = 3000000, .min_sel = 33, .max_sel = 60,
.uV_step = 50000 },
{ .min_uV = 3100000, .max_uV = 3300000, .min_sel = 61, .max_sel = 63,
.uV_step = 100000 },
REGULATOR_LINEAR_RANGE(800000, 0, 32, 25000),
REGULATOR_LINEAR_RANGE(1650000, 33, 60, 50000),
REGULATOR_LINEAR_RANGE(3100000, 61, 63, 100000),
};
static int tps65912_get_range(struct tps65912_reg *pmic, int id)
@ -461,7 +458,7 @@ static int tps65912_probe(struct platform_device *pdev)
struct regulator_dev *rdev;
struct tps65912_reg *pmic;
struct tps65912_board *pmic_plat_data;
int i, err;
int i;
pmic_plat_data = dev_get_platdata(tps65912->dev);
if (!pmic_plat_data)
@ -504,34 +501,19 @@ static int tps65912_probe(struct platform_device *pdev)
config.init_data = reg_data;
config.driver_data = pmic;
rdev = regulator_register(&pmic->desc[i], &config);
rdev = devm_regulator_register(&pdev->dev, &pmic->desc[i],
&config);
if (IS_ERR(rdev)) {
dev_err(tps65912->dev,
"failed to register %s regulator\n",
pdev->name);
err = PTR_ERR(rdev);
goto err;
return PTR_ERR(rdev);
}
/* Save regulator for cleanup */
pmic->rdev[i] = rdev;
}
return 0;
err:
while (--i >= 0)
regulator_unregister(pmic->rdev[i]);
return err;
}
static int tps65912_remove(struct platform_device *pdev)
{
struct tps65912_reg *tps65912_reg = platform_get_drvdata(pdev);
int i;
for (i = 0; i < TPS65912_NUM_REGULATOR; i++)
regulator_unregister(tps65912_reg->rdev[i]);
return 0;
}
static struct platform_driver tps65912_driver = {
@ -540,7 +522,6 @@ static struct platform_driver tps65912_driver = {
.owner = THIS_MODULE,
},
.probe = tps65912_probe,
.remove = tps65912_remove,
};
static int __init tps65912_init(void)

View File

@ -719,7 +719,7 @@ static int tps80031_regulator_probe(struct platform_device *pdev)
if (ret < 0) {
dev_err(&pdev->dev,
"regulator config failed, e %d\n", ret);
goto fail;
return ret;
}
ret = tps80031_power_req_config(pdev->dev.parent,
@ -727,41 +727,22 @@ static int tps80031_regulator_probe(struct platform_device *pdev)
if (ret < 0) {
dev_err(&pdev->dev,
"pwr_req config failed, err %d\n", ret);
goto fail;
return ret;
}
}
rdev = regulator_register(&ri->rinfo->desc, &config);
rdev = devm_regulator_register(&pdev->dev, &ri->rinfo->desc,
&config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev,
"register regulator failed %s\n",
ri->rinfo->desc.name);
ret = PTR_ERR(rdev);
goto fail;
return PTR_ERR(rdev);
}
ri->rdev = rdev;
}
platform_set_drvdata(pdev, pmic);
return 0;
fail:
while (--num >= 0) {
ri = &pmic[num];
regulator_unregister(ri->rdev);
}
return ret;
}
static int tps80031_regulator_remove(struct platform_device *pdev)
{
struct tps80031_regulator *pmic = platform_get_drvdata(pdev);
struct tps80031_regulator *ri = NULL;
int num;
for (num = 0; num < TPS80031_REGULATOR_MAX; ++num) {
ri = &pmic[num];
regulator_unregister(ri->rdev);
}
return 0;
}
static struct platform_driver tps80031_regulator_driver = {
@ -770,7 +751,6 @@ static struct platform_driver tps80031_regulator_driver = {
.owner = THIS_MODULE,
},
.probe = tps80031_regulator_probe,
.remove = tps80031_regulator_remove,
};
static int __init tps80031_regulator_init(void)

View File

@ -1188,7 +1188,7 @@ static int twlreg_probe(struct platform_device *pdev)
config.driver_data = info;
config.of_node = pdev->dev.of_node;
rdev = regulator_register(&info->desc, &config);
rdev = devm_regulator_register(&pdev->dev, &info->desc, &config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "can't register %s, %ld\n",
info->desc.name, PTR_ERR(rdev));
@ -1217,7 +1217,6 @@ static int twlreg_remove(struct platform_device *pdev)
struct regulator_dev *rdev = platform_get_drvdata(pdev);
struct twlreg_info *info = rdev->reg_data;
regulator_unregister(rdev);
kfree(info);
return 0;
}

View File

@ -96,7 +96,7 @@ static int vexpress_regulator_probe(struct platform_device *pdev)
config.driver_data = reg;
config.of_node = pdev->dev.of_node;
reg->regdev = regulator_register(&reg->desc, &config);
reg->regdev = devm_regulator_register(&pdev->dev, &reg->desc, &config);
if (IS_ERR(reg->regdev)) {
err = PTR_ERR(reg->regdev);
goto error_regulator_register;
@ -119,7 +119,6 @@ static int vexpress_regulator_remove(struct platform_device *pdev)
struct vexpress_regulator *reg = platform_get_drvdata(pdev);
vexpress_config_func_put(reg->func);
regulator_unregister(reg->regdev);
return 0;
}

View File

@ -387,8 +387,9 @@ static struct regulator_ops wm831x_buckv_ops = {
* Set up DVS control. We just log errors since we can still run
* (with reduced performance) if we fail.
*/
static void wm831x_buckv_dvs_init(struct wm831x_dcdc *dcdc,
struct wm831x_buckv_pdata *pdata)
static void wm831x_buckv_dvs_init(struct platform_device *pdev,
struct wm831x_dcdc *dcdc,
struct wm831x_buckv_pdata *pdata)
{
struct wm831x *wm831x = dcdc->wm831x;
int ret;
@ -402,9 +403,9 @@ static void wm831x_buckv_dvs_init(struct wm831x_dcdc *dcdc,
*/
dcdc->dvs_gpio_state = pdata->dvs_init_state;
ret = gpio_request_one(pdata->dvs_gpio,
dcdc->dvs_gpio_state ? GPIOF_INIT_HIGH : 0,
"DCDC DVS");
ret = devm_gpio_request_one(&pdev->dev, pdata->dvs_gpio,
dcdc->dvs_gpio_state ? GPIOF_INIT_HIGH : 0,
"DCDC DVS");
if (ret < 0) {
dev_err(wm831x->dev, "Failed to get %s DVS GPIO: %d\n",
dcdc->name, ret);
@ -513,7 +514,8 @@ static int wm831x_buckv_probe(struct platform_device *pdev)
dcdc->dvs_vsel = ret & WM831X_DC1_DVS_VSEL_MASK;
if (pdata && pdata->dcdc[id])
wm831x_buckv_dvs_init(dcdc, pdata->dcdc[id]->driver_data);
wm831x_buckv_dvs_init(pdev, dcdc,
pdata->dcdc[id]->driver_data);
config.dev = pdev->dev.parent;
if (pdata)
@ -521,7 +523,8 @@ static int wm831x_buckv_probe(struct platform_device *pdev)
config.driver_data = dcdc;
config.regmap = wm831x->regmap;
dcdc->regulator = regulator_register(&dcdc->desc, &config);
dcdc->regulator = devm_regulator_register(&pdev->dev, &dcdc->desc,
&config);
if (IS_ERR(dcdc->regulator)) {
ret = PTR_ERR(dcdc->regulator);
dev_err(wm831x->dev, "Failed to register DCDC%d: %d\n",
@ -530,57 +533,35 @@ static int wm831x_buckv_probe(struct platform_device *pdev)
}
irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "UV"));
ret = request_threaded_irq(irq, NULL, wm831x_dcdc_uv_irq,
IRQF_TRIGGER_RISING, dcdc->name, dcdc);
ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
wm831x_dcdc_uv_irq,
IRQF_TRIGGER_RISING, dcdc->name, dcdc);
if (ret != 0) {
dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n",
irq, ret);
goto err_regulator;
goto err;
}
irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "HC"));
ret = request_threaded_irq(irq, NULL, wm831x_dcdc_oc_irq,
IRQF_TRIGGER_RISING, dcdc->name, dcdc);
ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
wm831x_dcdc_oc_irq,
IRQF_TRIGGER_RISING, dcdc->name, dcdc);
if (ret != 0) {
dev_err(&pdev->dev, "Failed to request HC IRQ %d: %d\n",
irq, ret);
goto err_uv;
goto err;
}
platform_set_drvdata(pdev, dcdc);
return 0;
err_uv:
free_irq(wm831x_irq(wm831x, platform_get_irq_byname(pdev, "UV")),
dcdc);
err_regulator:
regulator_unregister(dcdc->regulator);
err:
if (dcdc->dvs_gpio)
gpio_free(dcdc->dvs_gpio);
return ret;
}
static int wm831x_buckv_remove(struct platform_device *pdev)
{
struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
struct wm831x *wm831x = dcdc->wm831x;
free_irq(wm831x_irq(wm831x, platform_get_irq_byname(pdev, "HC")),
dcdc);
free_irq(wm831x_irq(wm831x, platform_get_irq_byname(pdev, "UV")),
dcdc);
regulator_unregister(dcdc->regulator);
if (dcdc->dvs_gpio)
gpio_free(dcdc->dvs_gpio);
return 0;
}
static struct platform_driver wm831x_buckv_driver = {
.probe = wm831x_buckv_probe,
.remove = wm831x_buckv_remove,
.driver = {
.name = "wm831x-buckv",
.owner = THIS_MODULE,
@ -681,7 +662,8 @@ static int wm831x_buckp_probe(struct platform_device *pdev)
config.driver_data = dcdc;
config.regmap = wm831x->regmap;
dcdc->regulator = regulator_register(&dcdc->desc, &config);
dcdc->regulator = devm_regulator_register(&pdev->dev, &dcdc->desc,
&config);
if (IS_ERR(dcdc->regulator)) {
ret = PTR_ERR(dcdc->regulator);
dev_err(wm831x->dev, "Failed to register DCDC%d: %d\n",
@ -690,38 +672,25 @@ static int wm831x_buckp_probe(struct platform_device *pdev)
}
irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "UV"));
ret = request_threaded_irq(irq, NULL, wm831x_dcdc_uv_irq,
IRQF_TRIGGER_RISING, dcdc->name, dcdc);
ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
wm831x_dcdc_uv_irq,
IRQF_TRIGGER_RISING, dcdc->name, dcdc);
if (ret != 0) {
dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n",
irq, ret);
goto err_regulator;
goto err;
}
platform_set_drvdata(pdev, dcdc);
return 0;
err_regulator:
regulator_unregister(dcdc->regulator);
err:
return ret;
}
static int wm831x_buckp_remove(struct platform_device *pdev)
{
struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
free_irq(wm831x_irq(dcdc->wm831x, platform_get_irq_byname(pdev, "UV")),
dcdc);
regulator_unregister(dcdc->regulator);
return 0;
}
static struct platform_driver wm831x_buckp_driver = {
.probe = wm831x_buckp_probe,
.remove = wm831x_buckp_remove,
.driver = {
.name = "wm831x-buckp",
.owner = THIS_MODULE,
@ -813,7 +782,8 @@ static int wm831x_boostp_probe(struct platform_device *pdev)
config.driver_data = dcdc;
config.regmap = wm831x->regmap;
dcdc->regulator = regulator_register(&dcdc->desc, &config);
dcdc->regulator = devm_regulator_register(&pdev->dev, &dcdc->desc,
&config);
if (IS_ERR(dcdc->regulator)) {
ret = PTR_ERR(dcdc->regulator);
dev_err(wm831x->dev, "Failed to register DCDC%d: %d\n",
@ -822,39 +792,26 @@ static int wm831x_boostp_probe(struct platform_device *pdev)
}
irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "UV"));
ret = request_threaded_irq(irq, NULL, wm831x_dcdc_uv_irq,
IRQF_TRIGGER_RISING, dcdc->name,
dcdc);
ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
wm831x_dcdc_uv_irq,
IRQF_TRIGGER_RISING, dcdc->name,
dcdc);
if (ret != 0) {
dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n",
irq, ret);
goto err_regulator;
goto err;
}
platform_set_drvdata(pdev, dcdc);
return 0;
err_regulator:
regulator_unregister(dcdc->regulator);
err:
return ret;
}
static int wm831x_boostp_remove(struct platform_device *pdev)
{
struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
free_irq(wm831x_irq(dcdc->wm831x, platform_get_irq_byname(pdev, "UV")),
dcdc);
regulator_unregister(dcdc->regulator);
return 0;
}
static struct platform_driver wm831x_boostp_driver = {
.probe = wm831x_boostp_probe,
.remove = wm831x_boostp_remove,
.driver = {
.name = "wm831x-boostp",
.owner = THIS_MODULE,
@ -914,7 +871,8 @@ static int wm831x_epe_probe(struct platform_device *pdev)
config.driver_data = dcdc;
config.regmap = wm831x->regmap;
dcdc->regulator = regulator_register(&dcdc->desc, &config);
dcdc->regulator = devm_regulator_register(&pdev->dev, &dcdc->desc,
&config);
if (IS_ERR(dcdc->regulator)) {
ret = PTR_ERR(dcdc->regulator);
dev_err(wm831x->dev, "Failed to register EPE%d: %d\n",
@ -930,18 +888,8 @@ err:
return ret;
}
static int wm831x_epe_remove(struct platform_device *pdev)
{
struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
regulator_unregister(dcdc->regulator);
return 0;
}
static struct platform_driver wm831x_epe_driver = {
.probe = wm831x_epe_probe,
.remove = wm831x_epe_remove,
.driver = {
.name = "wm831x-epe",
.owner = THIS_MODULE,

View File

@ -194,7 +194,8 @@ static int wm831x_isink_probe(struct platform_device *pdev)
config.init_data = pdata->isink[id];
config.driver_data = isink;
isink->regulator = regulator_register(&isink->desc, &config);
isink->regulator = devm_regulator_register(&pdev->dev, &isink->desc,
&config);
if (IS_ERR(isink->regulator)) {
ret = PTR_ERR(isink->regulator);
dev_err(wm831x->dev, "Failed to register ISINK%d: %d\n",
@ -203,38 +204,26 @@ static int wm831x_isink_probe(struct platform_device *pdev)
}
irq = wm831x_irq(wm831x, platform_get_irq(pdev, 0));
ret = request_threaded_irq(irq, NULL, wm831x_isink_irq,
IRQF_TRIGGER_RISING, isink->name, isink);
ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
wm831x_isink_irq,
IRQF_TRIGGER_RISING, isink->name,
isink);
if (ret != 0) {
dev_err(&pdev->dev, "Failed to request ISINK IRQ %d: %d\n",
irq, ret);
goto err_regulator;
goto err;
}
platform_set_drvdata(pdev, isink);
return 0;
err_regulator:
regulator_unregister(isink->regulator);
err:
return ret;
}
static int wm831x_isink_remove(struct platform_device *pdev)
{
struct wm831x_isink *isink = platform_get_drvdata(pdev);
free_irq(wm831x_irq(isink->wm831x, platform_get_irq(pdev, 0)), isink);
regulator_unregister(isink->regulator);
return 0;
}
static struct platform_driver wm831x_isink_driver = {
.probe = wm831x_isink_probe,
.remove = wm831x_isink_remove,
.driver = {
.name = "wm831x-isink",
.owner = THIS_MODULE,

View File

@ -63,10 +63,8 @@ static irqreturn_t wm831x_ldo_uv_irq(int irq, void *data)
*/
static const struct regulator_linear_range wm831x_gp_ldo_ranges[] = {
{ .min_uV = 900000, .max_uV = 1600000, .min_sel = 0, .max_sel = 14,
.uV_step = 50000 },
{ .min_uV = 1700000, .max_uV = 3300000, .min_sel = 15, .max_sel = 31,
.uV_step = 100000 },
REGULATOR_LINEAR_RANGE(900000, 0, 14, 50000),
REGULATOR_LINEAR_RANGE(1700000, 15, 31, 100000),
};
static int wm831x_gp_ldo_set_suspend_voltage(struct regulator_dev *rdev,
@ -279,7 +277,8 @@ static int wm831x_gp_ldo_probe(struct platform_device *pdev)
config.driver_data = ldo;
config.regmap = wm831x->regmap;
ldo->regulator = regulator_register(&ldo->desc, &config);
ldo->regulator = devm_regulator_register(&pdev->dev, &ldo->desc,
&config);
if (IS_ERR(ldo->regulator)) {
ret = PTR_ERR(ldo->regulator);
dev_err(wm831x->dev, "Failed to register LDO%d: %d\n",
@ -288,39 +287,26 @@ static int wm831x_gp_ldo_probe(struct platform_device *pdev)
}
irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "UV"));
ret = request_threaded_irq(irq, NULL, wm831x_ldo_uv_irq,
IRQF_TRIGGER_RISING, ldo->name,
ldo);
ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
wm831x_ldo_uv_irq,
IRQF_TRIGGER_RISING, ldo->name,
ldo);
if (ret != 0) {
dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n",
irq, ret);
goto err_regulator;
goto err;
}
platform_set_drvdata(pdev, ldo);
return 0;
err_regulator:
regulator_unregister(ldo->regulator);
err:
return ret;
}
static int wm831x_gp_ldo_remove(struct platform_device *pdev)
{
struct wm831x_ldo *ldo = platform_get_drvdata(pdev);
free_irq(wm831x_irq(ldo->wm831x,
platform_get_irq_byname(pdev, "UV")), ldo);
regulator_unregister(ldo->regulator);
return 0;
}
static struct platform_driver wm831x_gp_ldo_driver = {
.probe = wm831x_gp_ldo_probe,
.remove = wm831x_gp_ldo_remove,
.driver = {
.name = "wm831x-ldo",
.owner = THIS_MODULE,
@ -332,10 +318,8 @@ static struct platform_driver wm831x_gp_ldo_driver = {
*/
static const struct regulator_linear_range wm831x_aldo_ranges[] = {
{ .min_uV = 1000000, .max_uV = 1600000, .min_sel = 0, .max_sel = 12,
.uV_step = 50000 },
{ .min_uV = 1700000, .max_uV = 3500000, .min_sel = 13, .max_sel = 31,
.uV_step = 100000 },
REGULATOR_LINEAR_RANGE(1000000, 0, 12, 50000),
REGULATOR_LINEAR_RANGE(1700000, 13, 31, 100000),
};
static int wm831x_aldo_set_suspend_voltage(struct regulator_dev *rdev,
@ -505,7 +489,8 @@ static int wm831x_aldo_probe(struct platform_device *pdev)
config.driver_data = ldo;
config.regmap = wm831x->regmap;
ldo->regulator = regulator_register(&ldo->desc, &config);
ldo->regulator = devm_regulator_register(&pdev->dev, &ldo->desc,
&config);
if (IS_ERR(ldo->regulator)) {
ret = PTR_ERR(ldo->regulator);
dev_err(wm831x->dev, "Failed to register LDO%d: %d\n",
@ -514,38 +499,25 @@ static int wm831x_aldo_probe(struct platform_device *pdev)
}
irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "UV"));
ret = request_threaded_irq(irq, NULL, wm831x_ldo_uv_irq,
IRQF_TRIGGER_RISING, ldo->name, ldo);
ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
wm831x_ldo_uv_irq,
IRQF_TRIGGER_RISING, ldo->name, ldo);
if (ret != 0) {
dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n",
irq, ret);
goto err_regulator;
goto err;
}
platform_set_drvdata(pdev, ldo);
return 0;
err_regulator:
regulator_unregister(ldo->regulator);
err:
return ret;
}
static int wm831x_aldo_remove(struct platform_device *pdev)
{
struct wm831x_ldo *ldo = platform_get_drvdata(pdev);
free_irq(wm831x_irq(ldo->wm831x, platform_get_irq_byname(pdev, "UV")),
ldo);
regulator_unregister(ldo->regulator);
return 0;
}
static struct platform_driver wm831x_aldo_driver = {
.probe = wm831x_aldo_probe,
.remove = wm831x_aldo_remove,
.driver = {
.name = "wm831x-aldo",
.owner = THIS_MODULE,
@ -663,7 +635,8 @@ static int wm831x_alive_ldo_probe(struct platform_device *pdev)
config.driver_data = ldo;
config.regmap = wm831x->regmap;
ldo->regulator = regulator_register(&ldo->desc, &config);
ldo->regulator = devm_regulator_register(&pdev->dev, &ldo->desc,
&config);
if (IS_ERR(ldo->regulator)) {
ret = PTR_ERR(ldo->regulator);
dev_err(wm831x->dev, "Failed to register LDO%d: %d\n",
@ -679,18 +652,8 @@ err:
return ret;
}
static int wm831x_alive_ldo_remove(struct platform_device *pdev)
{
struct wm831x_ldo *ldo = platform_get_drvdata(pdev);
regulator_unregister(ldo->regulator);
return 0;
}
static struct platform_driver wm831x_alive_ldo_driver = {
.probe = wm831x_alive_ldo_probe,
.remove = wm831x_alive_ldo_remove,
.driver = {
.name = "wm831x-alive-ldo",
.owner = THIS_MODULE,

View File

@ -543,10 +543,8 @@ static int wm8350_dcdc_set_suspend_mode(struct regulator_dev *rdev,
}
static const struct regulator_linear_range wm8350_ldo_ranges[] = {
{ .min_uV = 900000, .max_uV = 1650000, .min_sel = 0, .max_sel = 15,
.uV_step = 50000 },
{ .min_uV = 1800000, .max_uV = 3300000, .min_sel = 16, .max_sel = 31,
.uV_step = 100000 },
REGULATOR_LINEAR_RANGE(900000, 0, 15, 50000),
REGULATOR_LINEAR_RANGE(1800000, 16, 31, 100000),
};
static int wm8350_ldo_set_suspend_voltage(struct regulator_dev *rdev, int uV)
@ -1206,7 +1204,8 @@ static int wm8350_regulator_probe(struct platform_device *pdev)
config.regmap = wm8350->regmap;
/* register regulator */
rdev = regulator_register(&wm8350_reg[pdev->id], &config);
rdev = devm_regulator_register(&pdev->dev, &wm8350_reg[pdev->id],
&config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "failed to register %s\n",
wm8350_reg[pdev->id].name);
@ -1217,7 +1216,6 @@ static int wm8350_regulator_probe(struct platform_device *pdev)
ret = wm8350_register_irq(wm8350, wm8350_reg[pdev->id].irq,
pmic_uv_handler, 0, "UV", rdev);
if (ret < 0) {
regulator_unregister(rdev);
dev_err(&pdev->dev, "failed to register regulator %s IRQ\n",
wm8350_reg[pdev->id].name);
return ret;
@ -1233,8 +1231,6 @@ static int wm8350_regulator_remove(struct platform_device *pdev)
wm8350_free_irq(wm8350, wm8350_reg[pdev->id].irq, rdev);
regulator_unregister(rdev);
return 0;
}

View File

@ -20,10 +20,8 @@
#include <linux/mfd/wm8400-private.h>
static const struct regulator_linear_range wm8400_ldo_ranges[] = {
{ .min_uV = 900000, .max_uV = 1600000, .min_sel = 0, .max_sel = 14,
.uV_step = 50000 },
{ .min_uV = 1700000, .max_uV = 3300000, .min_sel = 15, .max_sel = 31,
.uV_step = 100000 },
REGULATOR_LINEAR_RANGE(900000, 0, 14, 50000),
REGULATOR_LINEAR_RANGE(1700000, 15, 31, 100000),
};
static struct regulator_ops wm8400_ldo_ops = {
@ -219,7 +217,8 @@ static int wm8400_regulator_probe(struct platform_device *pdev)
config.driver_data = wm8400;
config.regmap = wm8400->regmap;
rdev = regulator_register(&regulators[pdev->id], &config);
rdev = devm_regulator_register(&pdev->dev, &regulators[pdev->id],
&config);
if (IS_ERR(rdev))
return PTR_ERR(rdev);
@ -228,21 +227,11 @@ static int wm8400_regulator_probe(struct platform_device *pdev)
return 0;
}
static int wm8400_regulator_remove(struct platform_device *pdev)
{
struct regulator_dev *rdev = platform_get_drvdata(pdev);
regulator_unregister(rdev);
return 0;
}
static struct platform_driver wm8400_regulator_driver = {
.driver = {
.name = "wm8400-regulator",
},
.probe = wm8400_regulator_probe,
.remove = wm8400_regulator_remove,
};
/**

View File

@ -165,7 +165,9 @@ static int wm8994_ldo_probe(struct platform_device *pdev)
ldo->init_data = *pdata->ldo[id].init_data;
}
ldo->regulator = regulator_register(&wm8994_ldo_desc[id], &config);
ldo->regulator = devm_regulator_register(&pdev->dev,
&wm8994_ldo_desc[id],
&config);
if (IS_ERR(ldo->regulator)) {
ret = PTR_ERR(ldo->regulator);
dev_err(wm8994->dev, "Failed to register LDO%d: %d\n",
@ -181,18 +183,8 @@ err:
return ret;
}
static int wm8994_ldo_remove(struct platform_device *pdev)
{
struct wm8994_ldo *ldo = platform_get_drvdata(pdev);
regulator_unregister(ldo->regulator);
return 0;
}
static struct platform_driver wm8994_ldo_driver = {
.probe = wm8994_ldo_probe,
.remove = wm8994_ldo_remove,
.driver = {
.name = "wm8994-ldo",
.owner = THIS_MODULE,

View File

@ -59,6 +59,12 @@ struct mfd_cell {
* pm_runtime_no_callbacks().
*/
bool pm_runtime_no_callbacks;
/* A list of regulator supplies that should be mapped to the MFD
* device rather than the child device when requested
*/
const char **parent_supplies;
int num_parent_supplies;
};
/*

View File

@ -146,6 +146,32 @@ struct regulator *__must_check devm_regulator_get_optional(struct device *dev,
void regulator_put(struct regulator *regulator);
void devm_regulator_put(struct regulator *regulator);
int regulator_register_supply_alias(struct device *dev, const char *id,
struct device *alias_dev,
const char *alias_id);
void regulator_unregister_supply_alias(struct device *dev, const char *id);
int regulator_bulk_register_supply_alias(struct device *dev, const char **id,
struct device *alias_dev,
const char **alias_id, int num_id);
void regulator_bulk_unregister_supply_alias(struct device *dev,
const char **id, int num_id);
int devm_regulator_register_supply_alias(struct device *dev, const char *id,
struct device *alias_dev,
const char *alias_id);
void devm_regulator_unregister_supply_alias(struct device *dev,
const char *id);
int devm_regulator_bulk_register_supply_alias(struct device *dev,
const char **id,
struct device *alias_dev,
const char **alias_id,
int num_id);
void devm_regulator_bulk_unregister_supply_alias(struct device *dev,
const char **id,
int num_id);
/* regulator output control and status */
int __must_check regulator_enable(struct regulator *regulator);
int regulator_disable(struct regulator *regulator);
@ -250,6 +276,59 @@ static inline void devm_regulator_put(struct regulator *regulator)
{
}
static inline int regulator_register_supply_alias(struct device *dev,
const char *id,
struct device *alias_dev,
const char *alias_id)
{
return 0;
}
static inline void regulator_unregister_supply_alias(struct device *dev,
const char *id)
{
}
static inline int regulator_bulk_register_supply_alias(struct device *dev,
const char **id,
struct device *alias_dev,
const char **alias_id,
int num_id)
{
return 0;
}
static inline void regulator_bulk_unregister_supply_alias(struct device *dev,
const char **id,
int num_id)
{
}
static inline int devm_regulator_register_supply_alias(struct device *dev,
const char *id,
struct device *alias_dev,
const char *alias_id)
{
return 0;
}
static inline void devm_regulator_unregister_supply_alias(struct device *dev,
const char *id)
{
}
static inline int devm_regulator_bulk_register_supply_alias(
struct device *dev, const char **id, struct device *alias_dev,
const char **alias_id, int num_id)
{
return 0;
}
static inline void devm_regulator_bulk_unregister_supply_alias(
struct device *dev, const char **id, int num_id)
{
}
static inline int regulator_enable(struct regulator *regulator)
{
return 0;

View File

@ -46,19 +46,26 @@ enum regulator_status {
* regulator_list_linear_range().
*
* @min_uV: Lowest voltage in range
* @max_uV: Highest voltage in range
* @min_sel: Lowest selector for range
* @max_sel: Highest selector for range
* @uV_step: Step size
*/
struct regulator_linear_range {
unsigned int min_uV;
unsigned int max_uV;
unsigned int min_sel;
unsigned int max_sel;
unsigned int uV_step;
};
/* Initialize struct regulator_linear_range */
#define REGULATOR_LINEAR_RANGE(_min_uV, _min_sel, _max_sel, _step_uV) \
{ \
.min_uV = _min_uV, \
.min_sel = _min_sel, \
.max_sel = _max_sel, \
.uV_step = _step_uV, \
}
/**
* struct regulator_ops - regulator operations.
*
@ -209,6 +216,7 @@ enum regulator_type {
* @min_uV: Voltage given by the lowest selector (if linear mapping)
* @uV_step: Voltage increase with each selector (if linear mapping)
* @linear_min_sel: Minimal selector for starting linear mapping
* @fixed_uV: Fixed voltage of rails.
* @ramp_delay: Time to settle down after voltage change (unit: uV/us)
* @volt_table: Voltage mapping table (if table based mapping)
*
@ -241,6 +249,7 @@ struct regulator_desc {
unsigned int min_uV;
unsigned int uV_step;
unsigned int linear_min_sel;
int fixed_uV;
unsigned int ramp_delay;
const struct regulator_linear_range *linear_ranges;
@ -336,7 +345,12 @@ struct regulator_dev {
struct regulator_dev *
regulator_register(const struct regulator_desc *regulator_desc,
const struct regulator_config *config);
struct regulator_dev *
devm_regulator_register(struct device *dev,
const struct regulator_desc *regulator_desc,
const struct regulator_config *config);
void regulator_unregister(struct regulator_dev *rdev);
void devm_regulator_unregister(struct device *dev, struct regulator_dev *rdev);
int regulator_notifier_call_chain(struct regulator_dev *rdev,
unsigned long event, void *data);

View File

@ -95,6 +95,7 @@ struct regulator_state {
* @initial_state: Suspend state to set by default.
* @initial_mode: Mode to set at startup.
* @ramp_delay: Time to settle down after voltage change (unit: uV/us)
* @enable_time: Turn-on time of the rails (unit: microseconds)
*/
struct regulation_constraints {
@ -129,6 +130,7 @@ struct regulation_constraints {
unsigned int initial_mode;
unsigned int ramp_delay;
unsigned int enable_time;
/* constraint flags */
unsigned always_on:1; /* regulator never off when system is on */
@ -193,15 +195,10 @@ int regulator_suspend_finish(void);
#ifdef CONFIG_REGULATOR
void regulator_has_full_constraints(void);
void regulator_use_dummy_regulator(void);
#else
static inline void regulator_has_full_constraints(void)
{
}
static inline void regulator_use_dummy_regulator(void)
{
}
#endif
#endif