diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-11-05 16:06:22 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-11-05 16:06:22 -0500 |
commit | 52787e91bf5375e68e90f381bd157bd92e1f4a77 (patch) | |
tree | 102103aca706e14ed1df0fab36cdd827a4d86b75 | |
parent | f66477a0aeb77f97a7de5f791700dadc42f3f792 (diff) | |
parent | 62e544b983a0a8ec36a33017e1d7eb60eb7ffb5e (diff) |
Merge tag 'regulator-v4.4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator
Pull regulator updates from Mark Brown:
"This is quite a quiet release in terms of volume of patches but it
includes a couple of really nice core changes - the work Sascha has
done in particular is something I've wanted to get done for a long
time but just never got round to myself.
Highlights include:
- Support from Sascha Hauer for setting the voltage of parent
supplies based on requests from their children. This is used both
to allow set_voltage() to work through a dumb switch and to improve
the efficiency of systems where DCDCs are used to supply LDOs by
minimising the voltage drop over the LDOs.
- Removal of regulator_list by Tomeu Vizoso, meaning we're not
duplicating the device list maintained by the driver core.
- Support for Wolfson/Cirrus WM8998 and WM1818"
* tag 'regulator-v4.4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (29 commits)
regulator: Use regulator_lock_supply() for get_voltage() too
regulator: arizona: Add regulator specific device tree binding document
regulator: stw481x: compile on COMPILE_TEST
regulator: qcom-smd: Correct set_load() unit
regulator: core: Propagate voltage changes to supply regulators
regulator: core: Factor out regulator_map_voltage
regulator: i.MX anatop: Allow supply regulator
regulator: introduce min_dropout_uV
regulator: core: create unlocked version of regulator_set_voltage
regulator: arizona-ldo1: Fix handling of GPIO 0
regulator: da9053: Update regulator for DA9053 BC silicon support
regulator: max77802: Separate sections for nodes and properties
regulator: max77802: Add input supply properties to DT binding doc
regulator: axp20x: set supply names for AXP22X DC1SW/DC5LDO internally
regulator: axp20x: Drop AXP221 DC1SW and DC5LDO regulator supplies from bindings
mfd: tps6105x: Use i2c regmap to access registers
regulator: act8865: add DT binding for property "active-semi,vsel-high"
regulator: act8865: support output voltage by VSET2[] bits
regulator: arizona: add support for WM8998 and WM1814
regulator: core: create unlocked version of regulator_list_voltage
...
24 files changed, 729 insertions, 456 deletions
diff --git a/Documentation/devicetree/bindings/mfd/axp20x.txt b/Documentation/devicetree/bindings/mfd/axp20x.txt index 41811223e5be..a474359dd206 100644 --- a/Documentation/devicetree/bindings/mfd/axp20x.txt +++ b/Documentation/devicetree/bindings/mfd/axp20x.txt | |||
@@ -60,8 +60,8 @@ DCDC2 : DC-DC buck : vin2-supply | |||
60 | DCDC3 : DC-DC buck : vin3-supply | 60 | DCDC3 : DC-DC buck : vin3-supply |
61 | DCDC4 : DC-DC buck : vin4-supply | 61 | DCDC4 : DC-DC buck : vin4-supply |
62 | DCDC5 : DC-DC buck : vin5-supply | 62 | DCDC5 : DC-DC buck : vin5-supply |
63 | DC1SW : On/Off Switch : dcdc1-supply : DCDC1 secondary output | 63 | DC1SW : On/Off Switch : : DCDC1 secondary output |
64 | DC5LDO : LDO : dcdc5-supply : input from DCDC5 | 64 | DC5LDO : LDO : : input from DCDC5 |
65 | ALDO1 : LDO : aldoin-supply : shared supply | 65 | ALDO1 : LDO : aldoin-supply : shared supply |
66 | ALDO2 : LDO : aldoin-supply : shared supply | 66 | ALDO2 : LDO : aldoin-supply : shared supply |
67 | ALDO3 : LDO : aldoin-supply : shared supply | 67 | ALDO3 : LDO : aldoin-supply : shared supply |
diff --git a/Documentation/devicetree/bindings/regulator/act8865-regulator.txt b/Documentation/devicetree/bindings/regulator/act8865-regulator.txt index e91485d11241..6067d9830d07 100644 --- a/Documentation/devicetree/bindings/regulator/act8865-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/act8865-regulator.txt | |||
@@ -8,6 +8,8 @@ Required properties: | |||
8 | Optional properties: | 8 | Optional properties: |
9 | - system-power-controller: Telling whether or not this pmic is controlling | 9 | - system-power-controller: Telling whether or not this pmic is controlling |
10 | the system power. See Documentation/devicetree/bindings/power/power-controller.txt . | 10 | the system power. See Documentation/devicetree/bindings/power/power-controller.txt . |
11 | - active-semi,vsel-high: Indicates the VSEL pin is high. | ||
12 | If this property is missing, assume the VSEL pin is low(0). | ||
11 | 13 | ||
12 | Optional input supply properties: | 14 | Optional input supply properties: |
13 | - for act8600: | 15 | - for act8600: |
@@ -49,6 +51,7 @@ Example: | |||
49 | pmic: act8865@5b { | 51 | pmic: act8865@5b { |
50 | compatible = "active-semi,act8865"; | 52 | compatible = "active-semi,act8865"; |
51 | reg = <0x5b>; | 53 | reg = <0x5b>; |
54 | active-semi,vsel-high; | ||
52 | status = "disabled"; | 55 | status = "disabled"; |
53 | 56 | ||
54 | regulators { | 57 | regulators { |
diff --git a/Documentation/devicetree/bindings/regulator/anatop-regulator.txt b/Documentation/devicetree/bindings/regulator/anatop-regulator.txt index 758eae24082a..37c4ea076f88 100644 --- a/Documentation/devicetree/bindings/regulator/anatop-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/anatop-regulator.txt | |||
@@ -13,6 +13,7 @@ Optional properties: | |||
13 | - anatop-delay-reg-offset: Anatop MFD step time register offset | 13 | - anatop-delay-reg-offset: Anatop MFD step time register offset |
14 | - anatop-delay-bit-shift: Bit shift for the step time register | 14 | - anatop-delay-bit-shift: Bit shift for the step time register |
15 | - anatop-delay-bit-width: Number of bits used in the step time register | 15 | - anatop-delay-bit-width: Number of bits used in the step time register |
16 | - vin-supply: The supply for this regulator | ||
16 | 17 | ||
17 | Any property defined as part of the core regulator | 18 | Any property defined as part of the core regulator |
18 | binding, defined in regulator.txt, can also be used. | 19 | binding, defined in regulator.txt, can also be used. |
diff --git a/Documentation/devicetree/bindings/regulator/arizona-regulator.txt b/Documentation/devicetree/bindings/regulator/arizona-regulator.txt new file mode 100644 index 000000000000..443564d7784f --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/arizona-regulator.txt | |||
@@ -0,0 +1,17 @@ | |||
1 | Cirrus Logic Arizona class audio SoCs | ||
2 | |||
3 | These devices are audio SoCs with extensive digital capabilities and a range | ||
4 | of analogue I/O. | ||
5 | |||
6 | This document lists regulator specific bindings, see the primary binding | ||
7 | document: | ||
8 | ../mfd/arizona.txt | ||
9 | |||
10 | Optional properties: | ||
11 | - wlf,ldoena : GPIO specifier for the GPIO controlling LDOENA | ||
12 | |||
13 | Optional subnodes: | ||
14 | - ldo1 : Initial data for the LDO1 regulator, as covered in | ||
15 | Documentation/devicetree/bindings/regulator/regulator.txt | ||
16 | - micvdd : Initial data for the MICVDD regulator, as covered in | ||
17 | Documentation/devicetree/bindings/regulator/regulator.txt | ||
diff --git a/Documentation/devicetree/bindings/regulator/max77802.txt b/Documentation/devicetree/bindings/regulator/max77802.txt index 79e5476444f7..09d796ed48be 100644 --- a/Documentation/devicetree/bindings/regulator/max77802.txt +++ b/Documentation/devicetree/bindings/regulator/max77802.txt | |||
@@ -8,7 +8,28 @@ regulators that can be controlled over I2C. | |||
8 | 8 | ||
9 | Following properties should be present in main device node of the MFD chip. | 9 | Following properties should be present in main device node of the MFD chip. |
10 | 10 | ||
11 | Optional node: | 11 | Optional properties: |
12 | - inb1-supply: The input supply for BUCK1 | ||
13 | - inb2-supply: The input supply for BUCK2 | ||
14 | - inb3-supply: The input supply for BUCK3 | ||
15 | - inb4-supply: The input supply for BUCK4 | ||
16 | - inb5-supply: The input supply for BUCK5 | ||
17 | - inb6-supply: The input supply for BUCK6 | ||
18 | - inb7-supply: The input supply for BUCK7 | ||
19 | - inb8-supply: The input supply for BUCK8 | ||
20 | - inb9-supply: The input supply for BUCK9 | ||
21 | - inb10-supply: The input supply for BUCK10 | ||
22 | - inl1-supply: The input supply for LDO8 and LDO15 | ||
23 | - inl2-supply: The input supply for LDO17, LDO27, LDO30 and LDO35 | ||
24 | - inl3-supply: The input supply for LDO3, LDO5, LDO6 and LDO7 | ||
25 | - inl4-supply: The input supply for LDO10, LDO11, LDO13 and LDO14 | ||
26 | - inl5-supply: The input supply for LDO9 and LDO19 | ||
27 | - inl6-supply: The input supply for LDO4, LDO21, LDO24 and LDO33 | ||
28 | - inl7-supply: The input supply for LDO18, LDO20, LDO28 and LDO29 | ||
29 | - inl9-supply: The input supply for LDO12, LDO23, LDO25, LDO26, LDO32 and LDO34 | ||
30 | - inl10-supply: The input supply for LDO1 and LDO2 | ||
31 | |||
32 | Optional nodes: | ||
12 | - regulators : The regulators of max77802 have to be instantiated | 33 | - regulators : The regulators of max77802 have to be instantiated |
13 | under subnode named "regulators" using the following format. | 34 | under subnode named "regulators" using the following format. |
14 | 35 | ||
@@ -58,6 +79,8 @@ Example: | |||
58 | #address-cells = <1>; | 79 | #address-cells = <1>; |
59 | #size-cells = <0>; | 80 | #size-cells = <0>; |
60 | 81 | ||
82 | inb1-supply = <&parent_reg>; | ||
83 | |||
61 | regulators { | 84 | regulators { |
62 | ldo1_reg: LDO1 { | 85 | ldo1_reg: LDO1 { |
63 | regulator-name = "vdd_1v0"; | 86 | regulator-name = "vdd_1v0"; |
diff --git a/Documentation/devicetree/bindings/regulator/regulator.txt b/Documentation/devicetree/bindings/regulator/regulator.txt index 24bd422cecd5..1d112fc456aa 100644 --- a/Documentation/devicetree/bindings/regulator/regulator.txt +++ b/Documentation/devicetree/bindings/regulator/regulator.txt | |||
@@ -11,6 +11,7 @@ Optional properties: | |||
11 | - regulator-always-on: boolean, regulator should never be disabled | 11 | - regulator-always-on: boolean, regulator should never be disabled |
12 | - regulator-boot-on: bootloader/firmware enabled regulator | 12 | - regulator-boot-on: bootloader/firmware enabled regulator |
13 | - regulator-allow-bypass: allow the regulator to go into bypass mode | 13 | - regulator-allow-bypass: allow the regulator to go into bypass mode |
14 | - regulator-allow-set-load: allow the regulator performance level to be configured | ||
14 | - <name>-supply: phandle to the parent supply/regulator node | 15 | - <name>-supply: phandle to the parent supply/regulator node |
15 | - regulator-ramp-delay: ramp delay for regulator(in uV/uS) | 16 | - regulator-ramp-delay: ramp delay for regulator(in uV/uS) |
16 | For hardware which supports disabling ramp rate, it should be explicitly | 17 | For hardware which supports disabling ramp rate, it should be explicitly |
diff --git a/Documentation/devicetree/bindings/regulator/tps65023.txt b/Documentation/devicetree/bindings/regulator/tps65023.txt new file mode 100644 index 000000000000..a4714e4da370 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/tps65023.txt | |||
@@ -0,0 +1,60 @@ | |||
1 | TPS65023 family of regulators | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: Must be one of the following. | ||
5 | "ti,tps65020", | ||
6 | "ti,tps65021", | ||
7 | "ti,tps65023", | ||
8 | - reg: I2C slave address | ||
9 | - regulators: list of regulators provided by this controller, must be named | ||
10 | after their hardware counterparts: VDCDC[1-3] and LDO[1-2] | ||
11 | - regulators: This is the list of child nodes that specify the regulator | ||
12 | initialization data for defined regulators. The definition for each of | ||
13 | these nodes is defined using the standard binding for regulators found at | ||
14 | Documentation/devicetree/bindings/regulator/regulator.txt. | ||
15 | |||
16 | Each regulator is defined using the standard binding for regulators. | ||
17 | |||
18 | Example: | ||
19 | |||
20 | tps65023@48 { | ||
21 | compatible = "ti,tps65023"; | ||
22 | reg = <0x48>; | ||
23 | |||
24 | regulators { | ||
25 | VDCDC1 { | ||
26 | regulator-name = "vdd_mpu"; | ||
27 | regulator-always-on; | ||
28 | regulator-min-microvolt = <1200000>; | ||
29 | regulator-max-microvolt = <1200000>; | ||
30 | }; | ||
31 | |||
32 | VDCDC2 { | ||
33 | regulator-name = "vdd_core"; | ||
34 | regulator-always-on; | ||
35 | regulator-min-microvolt = <3300000>; | ||
36 | regulator-max-microvolt = <3300000>; | ||
37 | }; | ||
38 | |||
39 | VDCDC3 { | ||
40 | regulator-name = "vdd_io"; | ||
41 | regulator-always-on; | ||
42 | regulator-min-microvolt = <1800000>; | ||
43 | regulator-max-microvolt = <1800000>; | ||
44 | }; | ||
45 | |||
46 | LDO1 { | ||
47 | regulator-name = "vdd_usb18"; | ||
48 | regulator-always-on; | ||
49 | regulator-min-microvolt = <1800000>; | ||
50 | regulator-max-microvolt = <1800000>; | ||
51 | }; | ||
52 | |||
53 | LDO2 { | ||
54 | regulator-name = "vdd_usb33"; | ||
55 | regulator-always-on; | ||
56 | regulator-min-microvolt = <3300000>; | ||
57 | regulator-max-microvolt = <3300000>; | ||
58 | }; | ||
59 | }; | ||
60 | }; | ||
diff --git a/drivers/mfd/tps6105x.c b/drivers/mfd/tps6105x.c index 5de95c265c1a..4a174cdb50b6 100644 --- a/drivers/mfd/tps6105x.c +++ b/drivers/mfd/tps6105x.c | |||
@@ -16,7 +16,7 @@ | |||
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/i2c.h> | 18 | #include <linux/i2c.h> |
19 | #include <linux/mutex.h> | 19 | #include <linux/regmap.h> |
20 | #include <linux/gpio.h> | 20 | #include <linux/gpio.h> |
21 | #include <linux/spinlock.h> | 21 | #include <linux/spinlock.h> |
22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
@@ -25,73 +25,18 @@ | |||
25 | #include <linux/mfd/core.h> | 25 | #include <linux/mfd/core.h> |
26 | #include <linux/mfd/tps6105x.h> | 26 | #include <linux/mfd/tps6105x.h> |
27 | 27 | ||
28 | int tps6105x_set(struct tps6105x *tps6105x, u8 reg, u8 value) | 28 | static struct regmap_config tps6105x_regmap_config = { |
29 | { | 29 | .reg_bits = 8, |
30 | int ret; | 30 | .val_bits = 8, |
31 | 31 | .max_register = TPS6105X_REG_3, | |
32 | ret = mutex_lock_interruptible(&tps6105x->lock); | 32 | }; |
33 | if (ret) | ||
34 | return ret; | ||
35 | ret = i2c_smbus_write_byte_data(tps6105x->client, reg, value); | ||
36 | mutex_unlock(&tps6105x->lock); | ||
37 | if (ret < 0) | ||
38 | return ret; | ||
39 | |||
40 | return 0; | ||
41 | } | ||
42 | EXPORT_SYMBOL(tps6105x_set); | ||
43 | |||
44 | int tps6105x_get(struct tps6105x *tps6105x, u8 reg, u8 *buf) | ||
45 | { | ||
46 | int ret; | ||
47 | |||
48 | ret = mutex_lock_interruptible(&tps6105x->lock); | ||
49 | if (ret) | ||
50 | return ret; | ||
51 | ret = i2c_smbus_read_byte_data(tps6105x->client, reg); | ||
52 | mutex_unlock(&tps6105x->lock); | ||
53 | if (ret < 0) | ||
54 | return ret; | ||
55 | |||
56 | *buf = ret; | ||
57 | return 0; | ||
58 | } | ||
59 | EXPORT_SYMBOL(tps6105x_get); | ||
60 | |||
61 | /* | ||
62 | * Masks off the bits in the mask and sets the bits in the bitvalues | ||
63 | * parameter in one atomic operation | ||
64 | */ | ||
65 | int tps6105x_mask_and_set(struct tps6105x *tps6105x, u8 reg, | ||
66 | u8 bitmask, u8 bitvalues) | ||
67 | { | ||
68 | int ret; | ||
69 | u8 regval; | ||
70 | |||
71 | ret = mutex_lock_interruptible(&tps6105x->lock); | ||
72 | if (ret) | ||
73 | return ret; | ||
74 | ret = i2c_smbus_read_byte_data(tps6105x->client, reg); | ||
75 | if (ret < 0) | ||
76 | goto fail; | ||
77 | regval = ret; | ||
78 | regval = (~bitmask & regval) | (bitmask & bitvalues); | ||
79 | ret = i2c_smbus_write_byte_data(tps6105x->client, reg, regval); | ||
80 | fail: | ||
81 | mutex_unlock(&tps6105x->lock); | ||
82 | if (ret < 0) | ||
83 | return ret; | ||
84 | |||
85 | return 0; | ||
86 | } | ||
87 | EXPORT_SYMBOL(tps6105x_mask_and_set); | ||
88 | 33 | ||
89 | static int tps6105x_startup(struct tps6105x *tps6105x) | 34 | static int tps6105x_startup(struct tps6105x *tps6105x) |
90 | { | 35 | { |
91 | int ret; | 36 | int ret; |
92 | u8 regval; | 37 | unsigned int regval; |
93 | 38 | ||
94 | ret = tps6105x_get(tps6105x, TPS6105X_REG_0, ®val); | 39 | ret = regmap_read(tps6105x->regmap, TPS6105X_REG_0, ®val); |
95 | if (ret) | 40 | if (ret) |
96 | return ret; | 41 | return ret; |
97 | switch (regval >> TPS6105X_REG0_MODE_SHIFT) { | 42 | switch (regval >> TPS6105X_REG0_MODE_SHIFT) { |
@@ -145,11 +90,14 @@ static int tps6105x_probe(struct i2c_client *client, | |||
145 | if (!tps6105x) | 90 | if (!tps6105x) |
146 | return -ENOMEM; | 91 | return -ENOMEM; |
147 | 92 | ||
93 | tps6105x->regmap = devm_regmap_init_i2c(client, &tps6105x_regmap_config); | ||
94 | if (IS_ERR(tps6105x->regmap)) | ||
95 | return PTR_ERR(tps6105x->regmap); | ||
96 | |||
148 | i2c_set_clientdata(client, tps6105x); | 97 | i2c_set_clientdata(client, tps6105x); |
149 | tps6105x->client = client; | 98 | tps6105x->client = client; |
150 | pdata = dev_get_platdata(&client->dev); | 99 | pdata = dev_get_platdata(&client->dev); |
151 | tps6105x->pdata = pdata; | 100 | tps6105x->pdata = pdata; |
152 | mutex_init(&tps6105x->lock); | ||
153 | 101 | ||
154 | ret = tps6105x_startup(tps6105x); | 102 | ret = tps6105x_startup(tps6105x); |
155 | if (ret) { | 103 | if (ret) { |
@@ -198,7 +146,7 @@ static int tps6105x_remove(struct i2c_client *client) | |||
198 | mfd_remove_devices(&client->dev); | 146 | mfd_remove_devices(&client->dev); |
199 | 147 | ||
200 | /* Put chip in shutdown mode */ | 148 | /* Put chip in shutdown mode */ |
201 | tps6105x_mask_and_set(tps6105x, TPS6105X_REG_0, | 149 | regmap_update_bits(tps6105x->regmap, TPS6105X_REG_0, |
202 | TPS6105X_REG0_MODE_MASK, | 150 | TPS6105X_REG0_MODE_MASK, |
203 | TPS6105X_MODE_SHUTDOWN << TPS6105X_REG0_MODE_SHIFT); | 151 | TPS6105X_MODE_SHUTDOWN << TPS6105X_REG0_MODE_SHIFT); |
204 | 152 | ||
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 64bccff557be..8df0b0e62976 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig | |||
@@ -627,7 +627,7 @@ config REGULATOR_TI_ABB | |||
627 | 627 | ||
628 | config REGULATOR_STW481X_VMMC | 628 | config REGULATOR_STW481X_VMMC |
629 | bool "ST Microelectronics STW481X VMMC regulator" | 629 | bool "ST Microelectronics STW481X VMMC regulator" |
630 | depends on MFD_STW481X | 630 | depends on MFD_STW481X || COMPILE_TEST |
631 | default y if MFD_STW481X | 631 | default y if MFD_STW481X |
632 | help | 632 | help |
633 | This driver supports the internal VMMC regulator in the STw481x | 633 | This driver supports the internal VMMC regulator in the STw481x |
diff --git a/drivers/regulator/act8865-regulator.c b/drivers/regulator/act8865-regulator.c index 896db168e4bd..f8d4cd3d1397 100644 --- a/drivers/regulator/act8865-regulator.c +++ b/drivers/regulator/act8865-regulator.c | |||
@@ -261,6 +261,16 @@ static const struct regulator_desc act8865_regulators[] = { | |||
261 | ACT88xx_REG("LDO_REG4", ACT8865, LDO4, VSET, "inl67"), | 261 | ACT88xx_REG("LDO_REG4", ACT8865, LDO4, VSET, "inl67"), |
262 | }; | 262 | }; |
263 | 263 | ||
264 | static const struct regulator_desc act8865_alt_regulators[] = { | ||
265 | ACT88xx_REG("DCDC_REG1", ACT8865, DCDC1, VSET2, "vp1"), | ||
266 | ACT88xx_REG("DCDC_REG2", ACT8865, DCDC2, VSET2, "vp2"), | ||
267 | ACT88xx_REG("DCDC_REG3", ACT8865, DCDC3, VSET2, "vp3"), | ||
268 | ACT88xx_REG("LDO_REG1", ACT8865, LDO1, VSET, "inl45"), | ||
269 | ACT88xx_REG("LDO_REG2", ACT8865, LDO2, VSET, "inl45"), | ||
270 | ACT88xx_REG("LDO_REG3", ACT8865, LDO3, VSET, "inl67"), | ||
271 | ACT88xx_REG("LDO_REG4", ACT8865, LDO4, VSET, "inl67"), | ||
272 | }; | ||
273 | |||
264 | #ifdef CONFIG_OF | 274 | #ifdef CONFIG_OF |
265 | static const struct of_device_id act8865_dt_ids[] = { | 275 | static const struct of_device_id act8865_dt_ids[] = { |
266 | { .compatible = "active-semi,act8600", .data = (void *)ACT8600 }, | 276 | { .compatible = "active-semi,act8600", .data = (void *)ACT8600 }, |
@@ -413,6 +423,7 @@ static int act8865_pmic_probe(struct i2c_client *client, | |||
413 | struct act8865 *act8865; | 423 | struct act8865 *act8865; |
414 | unsigned long type; | 424 | unsigned long type; |
415 | int off_reg, off_mask; | 425 | int off_reg, off_mask; |
426 | int voltage_select = 0; | ||
416 | 427 | ||
417 | pdata = dev_get_platdata(dev); | 428 | pdata = dev_get_platdata(dev); |
418 | 429 | ||
@@ -424,6 +435,10 @@ static int act8865_pmic_probe(struct i2c_client *client, | |||
424 | return -ENODEV; | 435 | return -ENODEV; |
425 | 436 | ||
426 | type = (unsigned long) id->data; | 437 | type = (unsigned long) id->data; |
438 | |||
439 | voltage_select = !!of_get_property(dev->of_node, | ||
440 | "active-semi,vsel-high", | ||
441 | NULL); | ||
427 | } else { | 442 | } else { |
428 | type = i2c_id->driver_data; | 443 | type = i2c_id->driver_data; |
429 | } | 444 | } |
@@ -442,8 +457,13 @@ static int act8865_pmic_probe(struct i2c_client *client, | |||
442 | off_mask = ACT8846_OFF_SYSMASK; | 457 | off_mask = ACT8846_OFF_SYSMASK; |
443 | break; | 458 | break; |
444 | case ACT8865: | 459 | case ACT8865: |
445 | regulators = act8865_regulators; | 460 | if (voltage_select) { |
446 | num_regulators = ARRAY_SIZE(act8865_regulators); | 461 | regulators = act8865_alt_regulators; |
462 | num_regulators = ARRAY_SIZE(act8865_alt_regulators); | ||
463 | } else { | ||
464 | regulators = act8865_regulators; | ||
465 | num_regulators = ARRAY_SIZE(act8865_regulators); | ||
466 | } | ||
447 | off_reg = ACT8865_SYS_CTRL; | 467 | off_reg = ACT8865_SYS_CTRL; |
448 | off_mask = ACT8865_MSTROFF; | 468 | off_mask = ACT8865_MSTROFF; |
449 | break; | 469 | break; |
diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c index 52ea605f8130..63cd5e68c864 100644 --- a/drivers/regulator/anatop-regulator.c +++ b/drivers/regulator/anatop-regulator.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/regmap.h> | 30 | #include <linux/regmap.h> |
31 | #include <linux/regulator/driver.h> | 31 | #include <linux/regulator/driver.h> |
32 | #include <linux/regulator/of_regulator.h> | 32 | #include <linux/regulator/of_regulator.h> |
33 | #include <linux/regulator/machine.h> | ||
33 | 34 | ||
34 | #define LDO_RAMP_UP_UNIT_IN_CYCLES 64 /* 64 cycles per step */ | 35 | #define LDO_RAMP_UP_UNIT_IN_CYCLES 64 /* 64 cycles per step */ |
35 | #define LDO_RAMP_UP_FREQ_IN_MHZ 24 /* cycle based on 24M OSC */ | 36 | #define LDO_RAMP_UP_FREQ_IN_MHZ 24 /* cycle based on 24M OSC */ |
@@ -199,6 +200,7 @@ static int anatop_regulator_probe(struct platform_device *pdev) | |||
199 | rdesc->owner = THIS_MODULE; | 200 | rdesc->owner = THIS_MODULE; |
200 | 201 | ||
201 | initdata = of_get_regulator_init_data(dev, np, rdesc); | 202 | initdata = of_get_regulator_init_data(dev, np, rdesc); |
203 | initdata->supply_regulator = "vin"; | ||
202 | sreg->initdata = initdata; | 204 | sreg->initdata = initdata; |
203 | 205 | ||
204 | anatop_np = of_get_parent(np); | 206 | anatop_np = of_get_parent(np); |
@@ -262,6 +264,7 @@ static int anatop_regulator_probe(struct platform_device *pdev) | |||
262 | rdesc->vsel_reg = sreg->control_reg; | 264 | rdesc->vsel_reg = sreg->control_reg; |
263 | rdesc->vsel_mask = ((1 << sreg->vol_bit_width) - 1) << | 265 | rdesc->vsel_mask = ((1 << sreg->vol_bit_width) - 1) << |
264 | sreg->vol_bit_shift; | 266 | sreg->vol_bit_shift; |
267 | rdesc->min_dropout_uV = 125000; | ||
265 | 268 | ||
266 | config.dev = &pdev->dev; | 269 | config.dev = &pdev->dev; |
267 | config.init_data = initdata; | 270 | config.init_data = initdata; |
diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c index 5e947a8ddb84..f7c88ff90c43 100644 --- a/drivers/regulator/arizona-ldo1.c +++ b/drivers/regulator/arizona-ldo1.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/bitops.h> | 17 | #include <linux/bitops.h> |
18 | #include <linux/err.h> | 18 | #include <linux/err.h> |
19 | #include <linux/of.h> | 19 | #include <linux/of.h> |
20 | #include <linux/of_gpio.h> | ||
20 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
21 | #include <linux/regulator/driver.h> | 22 | #include <linux/regulator/driver.h> |
22 | #include <linux/regulator/machine.h> | 23 | #include <linux/regulator/machine.h> |
@@ -189,13 +190,22 @@ static int arizona_ldo1_of_get_pdata(struct arizona *arizona, | |||
189 | { | 190 | { |
190 | struct arizona_pdata *pdata = &arizona->pdata; | 191 | struct arizona_pdata *pdata = &arizona->pdata; |
191 | struct arizona_ldo1 *ldo1 = config->driver_data; | 192 | struct arizona_ldo1 *ldo1 = config->driver_data; |
193 | struct device_node *np = arizona->dev->of_node; | ||
192 | struct device_node *init_node, *dcvdd_node; | 194 | struct device_node *init_node, *dcvdd_node; |
193 | struct regulator_init_data *init_data; | 195 | struct regulator_init_data *init_data; |
194 | 196 | ||
195 | pdata->ldoena = arizona_of_get_named_gpio(arizona, "wlf,ldoena", true); | 197 | pdata->ldoena = of_get_named_gpio(np, "wlf,ldoena", 0); |
198 | if (pdata->ldoena < 0) { | ||
199 | dev_warn(arizona->dev, | ||
200 | "LDOENA GPIO property missing/malformed: %d\n", | ||
201 | pdata->ldoena); | ||
202 | pdata->ldoena = 0; | ||
203 | } else { | ||
204 | config->ena_gpio_initialized = true; | ||
205 | } | ||
196 | 206 | ||
197 | init_node = of_get_child_by_name(arizona->dev->of_node, "ldo1"); | 207 | init_node = of_get_child_by_name(np, "ldo1"); |
198 | dcvdd_node = of_parse_phandle(arizona->dev->of_node, "DCVDD-supply", 0); | 208 | dcvdd_node = of_parse_phandle(np, "DCVDD-supply", 0); |
199 | 209 | ||
200 | if (init_node) { | 210 | if (init_node) { |
201 | config->of_node = init_node; | 211 | config->of_node = init_node; |
@@ -245,6 +255,8 @@ static int arizona_ldo1_probe(struct platform_device *pdev) | |||
245 | switch (arizona->type) { | 255 | switch (arizona->type) { |
246 | case WM5102: | 256 | case WM5102: |
247 | case WM8997: | 257 | case WM8997: |
258 | case WM8998: | ||
259 | case WM1814: | ||
248 | desc = &arizona_ldo1_hc; | 260 | desc = &arizona_ldo1_hc; |
249 | ldo1->init_data = arizona_ldo1_dvfs; | 261 | ldo1->init_data = arizona_ldo1_dvfs; |
250 | break; | 262 | break; |
@@ -272,8 +284,6 @@ static int arizona_ldo1_probe(struct platform_device *pdev) | |||
272 | ret = arizona_ldo1_of_get_pdata(arizona, &config, desc); | 284 | ret = arizona_ldo1_of_get_pdata(arizona, &config, desc); |
273 | if (ret < 0) | 285 | if (ret < 0) |
274 | return ret; | 286 | return ret; |
275 | |||
276 | config.ena_gpio_initialized = true; | ||
277 | } | 287 | } |
278 | } | 288 | } |
279 | 289 | ||
diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c index a9567af7cec0..35de22fdb7a0 100644 --- a/drivers/regulator/axp20x-regulator.c +++ b/drivers/regulator/axp20x-regulator.c | |||
@@ -196,10 +196,10 @@ static const struct regulator_desc axp22x_regulators[] = { | |||
196 | AXP_DESC(AXP22X, DCDC5, "dcdc5", "vin5", 1000, 2550, 50, | 196 | AXP_DESC(AXP22X, DCDC5, "dcdc5", "vin5", 1000, 2550, 50, |
197 | AXP22X_DCDC5_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(5)), | 197 | AXP22X_DCDC5_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(5)), |
198 | /* secondary switchable output of DCDC1 */ | 198 | /* secondary switchable output of DCDC1 */ |
199 | AXP_DESC_SW(AXP22X, DC1SW, "dc1sw", "dcdc1", 1600, 3400, 100, | 199 | AXP_DESC_SW(AXP22X, DC1SW, "dc1sw", NULL, 1600, 3400, 100, |
200 | AXP22X_DCDC1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(7)), | 200 | AXP22X_DCDC1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(7)), |
201 | /* LDO regulator internally chained to DCDC5 */ | 201 | /* LDO regulator internally chained to DCDC5 */ |
202 | AXP_DESC(AXP22X, DC5LDO, "dc5ldo", "dcdc5", 700, 1400, 100, | 202 | AXP_DESC(AXP22X, DC5LDO, "dc5ldo", NULL, 700, 1400, 100, |
203 | AXP22X_DC5LDO_V_OUT, 0x7, AXP22X_PWR_OUT_CTRL1, BIT(0)), | 203 | AXP22X_DC5LDO_V_OUT, 0x7, AXP22X_PWR_OUT_CTRL1, BIT(0)), |
204 | AXP_DESC(AXP22X, ALDO1, "aldo1", "aldoin", 700, 3300, 100, | 204 | AXP_DESC(AXP22X, ALDO1, "aldo1", "aldoin", 700, 3300, 100, |
205 | AXP22X_ALDO1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(6)), | 205 | AXP22X_ALDO1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(6)), |
@@ -350,6 +350,8 @@ static int axp20x_regulator_probe(struct platform_device *pdev) | |||
350 | }; | 350 | }; |
351 | int ret, i, nregulators; | 351 | int ret, i, nregulators; |
352 | u32 workmode; | 352 | u32 workmode; |
353 | const char *axp22x_dc1_name = axp22x_regulators[AXP22X_DCDC1].name; | ||
354 | const char *axp22x_dc5_name = axp22x_regulators[AXP22X_DCDC5].name; | ||
353 | 355 | ||
354 | switch (axp20x->variant) { | 356 | switch (axp20x->variant) { |
355 | case AXP202_ID: | 357 | case AXP202_ID: |
@@ -371,8 +373,37 @@ static int axp20x_regulator_probe(struct platform_device *pdev) | |||
371 | axp20x_regulator_parse_dt(pdev); | 373 | axp20x_regulator_parse_dt(pdev); |
372 | 374 | ||
373 | for (i = 0; i < nregulators; i++) { | 375 | for (i = 0; i < nregulators; i++) { |
374 | rdev = devm_regulator_register(&pdev->dev, ®ulators[i], | 376 | const struct regulator_desc *desc = ®ulators[i]; |
375 | &config); | 377 | struct regulator_desc *new_desc; |
378 | |||
379 | /* | ||
380 | * Regulators DC1SW and DC5LDO are connected internally, | ||
381 | * so we have to handle their supply names separately. | ||
382 | * | ||
383 | * We always register the regulators in proper sequence, | ||
384 | * so the supply names are correctly read. See the last | ||
385 | * part of this loop to see where we save the DT defined | ||
386 | * name. | ||
387 | */ | ||
388 | if (regulators == axp22x_regulators) { | ||
389 | if (i == AXP22X_DC1SW) { | ||
390 | new_desc = devm_kzalloc(&pdev->dev, | ||
391 | sizeof(*desc), | ||
392 | GFP_KERNEL); | ||
393 | *new_desc = regulators[i]; | ||
394 | new_desc->supply_name = axp22x_dc1_name; | ||
395 | desc = new_desc; | ||
396 | } else if (i == AXP22X_DC5LDO) { | ||
397 | new_desc = devm_kzalloc(&pdev->dev, | ||
398 | sizeof(*desc), | ||
399 | GFP_KERNEL); | ||
400 | *new_desc = regulators[i]; | ||
401 | new_desc->supply_name = axp22x_dc5_name; | ||
402 | desc = new_desc; | ||
403 | } | ||
404 | } | ||
405 | |||
406 | rdev = devm_regulator_register(&pdev->dev, desc, &config); | ||
376 | if (IS_ERR(rdev)) { | 407 | if (IS_ERR(rdev)) { |
377 | dev_err(&pdev->dev, "Failed to register %s\n", | 408 | dev_err(&pdev->dev, "Failed to register %s\n", |
378 | regulators[i].name); | 409 | regulators[i].name); |
@@ -388,6 +419,21 @@ static int axp20x_regulator_probe(struct platform_device *pdev) | |||
388 | dev_err(&pdev->dev, "Failed to set workmode on %s\n", | 419 | dev_err(&pdev->dev, "Failed to set workmode on %s\n", |
389 | rdev->desc->name); | 420 | rdev->desc->name); |
390 | } | 421 | } |
422 | |||
423 | /* | ||
424 | * Save AXP22X DCDC1 / DCDC5 regulator names for later. | ||
425 | */ | ||
426 | if (regulators == axp22x_regulators) { | ||
427 | /* Can we use rdev->constraints->name instead? */ | ||
428 | if (i == AXP22X_DCDC1) | ||
429 | of_property_read_string(rdev->dev.of_node, | ||
430 | "regulator-name", | ||
431 | &axp22x_dc1_name); | ||
432 | else if (i == AXP22X_DCDC5) | ||
433 | of_property_read_string(rdev->dev.of_node, | ||
434 | "regulator-name", | ||
435 | &axp22x_dc5_name); | ||
436 | } | ||
391 | } | 437 | } |
392 | 438 | ||
393 | return 0; | 439 | return 0; |
diff --git a/drivers/regulator/bcm590xx-regulator.c b/drivers/regulator/bcm590xx-regulator.c index 628430bdc312..76b01835dcb4 100644 --- a/drivers/regulator/bcm590xx-regulator.c +++ b/drivers/regulator/bcm590xx-regulator.c | |||
@@ -244,7 +244,7 @@ static int bcm590xx_get_enable_register(int id) | |||
244 | break; | 244 | break; |
245 | case BCM590XX_REG_VBUS: | 245 | case BCM590XX_REG_VBUS: |
246 | reg = BCM590XX_OTG_CTRL; | 246 | reg = BCM590XX_OTG_CTRL; |
247 | }; | 247 | } |
248 | 248 | ||
249 | 249 | ||
250 | return reg; | 250 | return reg; |
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 8a34f6acc801..73b7683355cd 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
@@ -51,7 +51,6 @@ | |||
51 | pr_debug("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__) | 51 | pr_debug("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__) |
52 | 52 | ||
53 | static DEFINE_MUTEX(regulator_list_mutex); | 53 | static DEFINE_MUTEX(regulator_list_mutex); |
54 | static LIST_HEAD(regulator_list); | ||
55 | static LIST_HEAD(regulator_map_list); | 54 | static LIST_HEAD(regulator_map_list); |
56 | static LIST_HEAD(regulator_ena_gpio_list); | 55 | static LIST_HEAD(regulator_ena_gpio_list); |
57 | static LIST_HEAD(regulator_supply_alias_list); | 56 | static LIST_HEAD(regulator_supply_alias_list); |
@@ -59,6 +58,8 @@ static bool has_full_constraints; | |||
59 | 58 | ||
60 | static struct dentry *debugfs_root; | 59 | static struct dentry *debugfs_root; |
61 | 60 | ||
61 | static struct class regulator_class; | ||
62 | |||
62 | /* | 63 | /* |
63 | * struct regulator_map | 64 | * struct regulator_map |
64 | * | 65 | * |
@@ -132,6 +133,45 @@ static bool have_full_constraints(void) | |||
132 | } | 133 | } |
133 | 134 | ||
134 | /** | 135 | /** |
136 | * regulator_lock_supply - lock a regulator and its supplies | ||
137 | * @rdev: regulator source | ||
138 | */ | ||
139 | static void regulator_lock_supply(struct regulator_dev *rdev) | ||
140 | { | ||
141 | struct regulator *supply; | ||
142 | int i = 0; | ||
143 | |||
144 | while (1) { | ||
145 | mutex_lock_nested(&rdev->mutex, i++); | ||
146 | supply = rdev->supply; | ||
147 | |||
148 | if (!rdev->supply) | ||
149 | return; | ||
150 | |||
151 | rdev = supply->rdev; | ||
152 | } | ||
153 | } | ||
154 | |||
155 | /** | ||
156 | * regulator_unlock_supply - unlock a regulator and its supplies | ||
157 | * @rdev: regulator source | ||
158 | */ | ||
159 | static void regulator_unlock_supply(struct regulator_dev *rdev) | ||
160 | { | ||
161 | struct regulator *supply; | ||
162 | |||
163 | while (1) { | ||
164 | mutex_unlock(&rdev->mutex); | ||
165 | supply = rdev->supply; | ||
166 | |||
167 | if (!rdev->supply) | ||
168 | return; | ||
169 | |||
170 | rdev = supply->rdev; | ||
171 | } | ||
172 | } | ||
173 | |||
174 | /** | ||
135 | * of_get_regulator - get a regulator device node based on supply name | 175 | * of_get_regulator - get a regulator device node based on supply name |
136 | * @dev: Device pointer for the consumer (of regulator) device | 176 | * @dev: Device pointer for the consumer (of regulator) device |
137 | * @supply: regulator supply name | 177 | * @supply: regulator supply name |
@@ -180,7 +220,7 @@ static int regulator_check_voltage(struct regulator_dev *rdev, | |||
180 | return -ENODEV; | 220 | return -ENODEV; |
181 | } | 221 | } |
182 | if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) { | 222 | if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) { |
183 | rdev_err(rdev, "operation not allowed\n"); | 223 | rdev_err(rdev, "voltage operation not allowed\n"); |
184 | return -EPERM; | 224 | return -EPERM; |
185 | } | 225 | } |
186 | 226 | ||
@@ -240,7 +280,7 @@ static int regulator_check_current_limit(struct regulator_dev *rdev, | |||
240 | return -ENODEV; | 280 | return -ENODEV; |
241 | } | 281 | } |
242 | if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_CURRENT)) { | 282 | if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_CURRENT)) { |
243 | rdev_err(rdev, "operation not allowed\n"); | 283 | rdev_err(rdev, "current operation not allowed\n"); |
244 | return -EPERM; | 284 | return -EPERM; |
245 | } | 285 | } |
246 | 286 | ||
@@ -277,7 +317,7 @@ static int regulator_mode_constrain(struct regulator_dev *rdev, int *mode) | |||
277 | return -ENODEV; | 317 | return -ENODEV; |
278 | } | 318 | } |
279 | if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_MODE)) { | 319 | if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_MODE)) { |
280 | rdev_err(rdev, "operation not allowed\n"); | 320 | rdev_err(rdev, "mode operation not allowed\n"); |
281 | return -EPERM; | 321 | return -EPERM; |
282 | } | 322 | } |
283 | 323 | ||
@@ -301,7 +341,7 @@ static int regulator_check_drms(struct regulator_dev *rdev) | |||
301 | return -ENODEV; | 341 | return -ENODEV; |
302 | } | 342 | } |
303 | if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_DRMS)) { | 343 | if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_DRMS)) { |
304 | rdev_dbg(rdev, "operation not allowed\n"); | 344 | rdev_dbg(rdev, "drms operation not allowed\n"); |
305 | return -EPERM; | 345 | return -EPERM; |
306 | } | 346 | } |
307 | return 0; | 347 | return 0; |
@@ -1325,6 +1365,47 @@ static void regulator_supply_alias(struct device **dev, const char **supply) | |||
1325 | } | 1365 | } |
1326 | } | 1366 | } |
1327 | 1367 | ||
1368 | static int of_node_match(struct device *dev, const void *data) | ||
1369 | { | ||
1370 | return dev->of_node == data; | ||
1371 | } | ||
1372 | |||
1373 | static struct regulator_dev *of_find_regulator_by_node(struct device_node *np) | ||
1374 | { | ||
1375 | struct device *dev; | ||
1376 | |||
1377 | dev = class_find_device(®ulator_class, NULL, np, of_node_match); | ||
1378 | |||
1379 | return dev ? dev_to_rdev(dev) : NULL; | ||
1380 | } | ||
1381 | |||
1382 | static int regulator_match(struct device *dev, const void *data) | ||
1383 | { | ||
1384 | struct regulator_dev *r = dev_to_rdev(dev); | ||
1385 | |||
1386 | return strcmp(rdev_get_name(r), data) == 0; | ||
1387 | } | ||
1388 | |||
1389 | static struct regulator_dev *regulator_lookup_by_name(const char *name) | ||
1390 | { | ||
1391 | struct device *dev; | ||
1392 | |||
1393 | dev = class_find_device(®ulator_class, NULL, name, regulator_match); | ||
1394 | |||
1395 | return dev ? dev_to_rdev(dev) : NULL; | ||
1396 | } | ||
1397 | |||
1398 | /** | ||
1399 | * regulator_dev_lookup - lookup a regulator device. | ||
1400 | * @dev: device for regulator "consumer". | ||
1401 | * @supply: Supply name or regulator ID. | ||
1402 | * @ret: 0 on success, -ENODEV if lookup fails permanently, -EPROBE_DEFER if | ||
1403 | * lookup could succeed in the future. | ||
1404 | * | ||
1405 | * If successful, returns a struct regulator_dev that corresponds to the name | ||
1406 | * @supply and with the embedded struct device refcount incremented by one, | ||
1407 | * or NULL on failure. The refcount must be dropped by calling put_device(). | ||
1408 | */ | ||
1328 | static struct regulator_dev *regulator_dev_lookup(struct device *dev, | 1409 | static struct regulator_dev *regulator_dev_lookup(struct device *dev, |
1329 | const char *supply, | 1410 | const char *supply, |
1330 | int *ret) | 1411 | int *ret) |
@@ -1340,10 +1421,9 @@ static struct regulator_dev *regulator_dev_lookup(struct device *dev, | |||
1340 | if (dev && dev->of_node) { | 1421 | if (dev && dev->of_node) { |
1341 | node = of_get_regulator(dev, supply); | 1422 | node = of_get_regulator(dev, supply); |
1342 | if (node) { | 1423 | if (node) { |
1343 | list_for_each_entry(r, ®ulator_list, list) | 1424 | r = of_find_regulator_by_node(node); |
1344 | if (r->dev.parent && | 1425 | if (r) |
1345 | node == r->dev.of_node) | 1426 | return r; |
1346 | return r; | ||
1347 | *ret = -EPROBE_DEFER; | 1427 | *ret = -EPROBE_DEFER; |
1348 | return NULL; | 1428 | return NULL; |
1349 | } else { | 1429 | } else { |
@@ -1361,20 +1441,24 @@ static struct regulator_dev *regulator_dev_lookup(struct device *dev, | |||
1361 | if (dev) | 1441 | if (dev) |
1362 | devname = dev_name(dev); | 1442 | devname = dev_name(dev); |
1363 | 1443 | ||
1364 | list_for_each_entry(r, ®ulator_list, list) | 1444 | r = regulator_lookup_by_name(supply); |
1365 | if (strcmp(rdev_get_name(r), supply) == 0) | 1445 | if (r) |
1366 | return r; | 1446 | return r; |
1367 | 1447 | ||
1448 | mutex_lock(®ulator_list_mutex); | ||
1368 | list_for_each_entry(map, ®ulator_map_list, list) { | 1449 | list_for_each_entry(map, ®ulator_map_list, list) { |
1369 | /* If the mapping has a device set up it must match */ | 1450 | /* If the mapping has a device set up it must match */ |
1370 | if (map->dev_name && | 1451 | if (map->dev_name && |
1371 | (!devname || strcmp(map->dev_name, devname))) | 1452 | (!devname || strcmp(map->dev_name, devname))) |
1372 | continue; | 1453 | continue; |
1373 | 1454 | ||
1374 | if (strcmp(map->supply, supply) == 0) | 1455 | if (strcmp(map->supply, supply) == 0 && |
1456 | get_device(&map->regulator->dev)) { | ||
1457 | mutex_unlock(®ulator_list_mutex); | ||
1375 | return map->regulator; | 1458 | return map->regulator; |
1459 | } | ||
1376 | } | 1460 | } |
1377 | 1461 | mutex_unlock(®ulator_list_mutex); | |
1378 | 1462 | ||
1379 | return NULL; | 1463 | return NULL; |
1380 | } | 1464 | } |
@@ -1409,6 +1493,7 @@ static int regulator_resolve_supply(struct regulator_dev *rdev) | |||
1409 | 1493 | ||
1410 | if (have_full_constraints()) { | 1494 | if (have_full_constraints()) { |
1411 | r = dummy_regulator_rdev; | 1495 | r = dummy_regulator_rdev; |
1496 | get_device(&r->dev); | ||
1412 | } else { | 1497 | } else { |
1413 | dev_err(dev, "Failed to resolve %s-supply for %s\n", | 1498 | dev_err(dev, "Failed to resolve %s-supply for %s\n", |
1414 | rdev->supply_name, rdev->desc->name); | 1499 | rdev->supply_name, rdev->desc->name); |
@@ -1418,12 +1503,16 @@ static int regulator_resolve_supply(struct regulator_dev *rdev) | |||
1418 | 1503 | ||
1419 | /* Recursively resolve the supply of the supply */ | 1504 | /* Recursively resolve the supply of the supply */ |
1420 | ret = regulator_resolve_supply(r); | 1505 | ret = regulator_resolve_supply(r); |
1421 | if (ret < 0) | 1506 | if (ret < 0) { |
1507 | put_device(&r->dev); | ||
1422 | return ret; | 1508 | return ret; |
1509 | } | ||
1423 | 1510 | ||
1424 | ret = set_supply(rdev, r); | 1511 | ret = set_supply(rdev, r); |
1425 | if (ret < 0) | 1512 | if (ret < 0) { |
1513 | put_device(&r->dev); | ||
1426 | return ret; | 1514 | return ret; |
1515 | } | ||
1427 | 1516 | ||
1428 | /* Cascade always-on state to supply */ | 1517 | /* Cascade always-on state to supply */ |
1429 | if (_regulator_is_enabled(rdev) && rdev->supply) { | 1518 | if (_regulator_is_enabled(rdev) && rdev->supply) { |
@@ -1459,8 +1548,6 @@ static struct regulator *_regulator_get(struct device *dev, const char *id, | |||
1459 | else | 1548 | else |
1460 | ret = -EPROBE_DEFER; | 1549 | ret = -EPROBE_DEFER; |
1461 | 1550 | ||
1462 | mutex_lock(®ulator_list_mutex); | ||
1463 | |||
1464 | rdev = regulator_dev_lookup(dev, id, &ret); | 1551 | rdev = regulator_dev_lookup(dev, id, &ret); |
1465 | if (rdev) | 1552 | if (rdev) |
1466 | goto found; | 1553 | goto found; |
@@ -1472,7 +1559,7 @@ static struct regulator *_regulator_get(struct device *dev, const char *id, | |||
1472 | * succeed, so, quit with appropriate error value | 1559 | * succeed, so, quit with appropriate error value |
1473 | */ | 1560 | */ |
1474 | if (ret && ret != -ENODEV) | 1561 | if (ret && ret != -ENODEV) |
1475 | goto out; | 1562 | return regulator; |
1476 | 1563 | ||
1477 | if (!devname) | 1564 | if (!devname) |
1478 | devname = "deviceless"; | 1565 | devname = "deviceless"; |
@@ -1486,40 +1573,46 @@ static struct regulator *_regulator_get(struct device *dev, const char *id, | |||
1486 | devname, id); | 1573 | devname, id); |
1487 | 1574 | ||
1488 | rdev = dummy_regulator_rdev; | 1575 | rdev = dummy_regulator_rdev; |
1576 | get_device(&rdev->dev); | ||
1489 | goto found; | 1577 | goto found; |
1490 | /* Don't log an error when called from regulator_get_optional() */ | 1578 | /* Don't log an error when called from regulator_get_optional() */ |
1491 | } else if (!have_full_constraints() || exclusive) { | 1579 | } else if (!have_full_constraints() || exclusive) { |
1492 | dev_warn(dev, "dummy supplies not allowed\n"); | 1580 | dev_warn(dev, "dummy supplies not allowed\n"); |
1493 | } | 1581 | } |
1494 | 1582 | ||
1495 | mutex_unlock(®ulator_list_mutex); | ||
1496 | return regulator; | 1583 | return regulator; |
1497 | 1584 | ||
1498 | found: | 1585 | found: |
1499 | if (rdev->exclusive) { | 1586 | if (rdev->exclusive) { |
1500 | regulator = ERR_PTR(-EPERM); | 1587 | regulator = ERR_PTR(-EPERM); |
1501 | goto out; | 1588 | put_device(&rdev->dev); |
1589 | return regulator; | ||
1502 | } | 1590 | } |
1503 | 1591 | ||
1504 | if (exclusive && rdev->open_count) { | 1592 | if (exclusive && rdev->open_count) { |
1505 | regulator = ERR_PTR(-EBUSY); | 1593 | regulator = ERR_PTR(-EBUSY); |
1506 | goto out; | 1594 | put_device(&rdev->dev); |
1595 | return regulator; | ||
1507 | } | 1596 | } |
1508 | 1597 | ||
1509 | ret = regulator_resolve_supply(rdev); | 1598 | ret = regulator_resolve_supply(rdev); |
1510 | if (ret < 0) { | 1599 | if (ret < 0) { |
1511 | regulator = ERR_PTR(ret); | 1600 | regulator = ERR_PTR(ret); |
1512 | goto out; | 1601 | put_device(&rdev->dev); |
1602 | return regulator; | ||
1513 | } | 1603 | } |
1514 | 1604 | ||
1515 | if (!try_module_get(rdev->owner)) | 1605 | if (!try_module_get(rdev->owner)) { |
1516 | goto out; | 1606 | put_device(&rdev->dev); |
1607 | return regulator; | ||
1608 | } | ||
1517 | 1609 | ||
1518 | regulator = create_regulator(rdev, dev, id); | 1610 | regulator = create_regulator(rdev, dev, id); |
1519 | if (regulator == NULL) { | 1611 | if (regulator == NULL) { |
1520 | regulator = ERR_PTR(-ENOMEM); | 1612 | regulator = ERR_PTR(-ENOMEM); |
1613 | put_device(&rdev->dev); | ||
1521 | module_put(rdev->owner); | 1614 | module_put(rdev->owner); |
1522 | goto out; | 1615 | return regulator; |
1523 | } | 1616 | } |
1524 | 1617 | ||
1525 | rdev->open_count++; | 1618 | rdev->open_count++; |
@@ -1533,9 +1626,6 @@ found: | |||
1533 | rdev->use_count = 0; | 1626 | rdev->use_count = 0; |
1534 | } | 1627 | } |
1535 | 1628 | ||
1536 | out: | ||
1537 | mutex_unlock(®ulator_list_mutex); | ||
1538 | |||
1539 | return regulator; | 1629 | return regulator; |
1540 | } | 1630 | } |
1541 | 1631 | ||
@@ -1633,6 +1723,7 @@ static void _regulator_put(struct regulator *regulator) | |||
1633 | 1723 | ||
1634 | rdev->open_count--; | 1724 | rdev->open_count--; |
1635 | rdev->exclusive = 0; | 1725 | rdev->exclusive = 0; |
1726 | put_device(&rdev->dev); | ||
1636 | mutex_unlock(&rdev->mutex); | 1727 | mutex_unlock(&rdev->mutex); |
1637 | 1728 | ||
1638 | kfree(regulator->supply_name); | 1729 | kfree(regulator->supply_name); |
@@ -2312,6 +2403,40 @@ static int _regulator_is_enabled(struct regulator_dev *rdev) | |||
2312 | return rdev->desc->ops->is_enabled(rdev); | 2403 | return rdev->desc->ops->is_enabled(rdev); |
2313 | } | 2404 | } |
2314 | 2405 | ||
2406 | static int _regulator_list_voltage(struct regulator *regulator, | ||
2407 | unsigned selector, int lock) | ||
2408 | { | ||
2409 | struct regulator_dev *rdev = regulator->rdev; | ||
2410 | const struct regulator_ops *ops = rdev->desc->ops; | ||
2411 | int ret; | ||
2412 | |||
2413 | if (rdev->desc->fixed_uV && rdev->desc->n_voltages == 1 && !selector) | ||
2414 | return rdev->desc->fixed_uV; | ||
2415 | |||
2416 | if (ops->list_voltage) { | ||
2417 | if (selector >= rdev->desc->n_voltages) | ||
2418 | return -EINVAL; | ||
2419 | if (lock) | ||
2420 | mutex_lock(&rdev->mutex); | ||
2421 | ret = ops->list_voltage(rdev, selector); | ||
2422 | if (lock) | ||
2423 | mutex_unlock(&rdev->mutex); | ||
2424 | } else if (rdev->supply) { | ||
2425 | ret = _regulator_list_voltage(rdev->supply, selector, lock); | ||
2426 | } else { | ||
2427 | return -EINVAL; | ||
2428 | } | ||
2429 | |||
2430 | if (ret > 0) { | ||
2431 | if (ret < rdev->constraints->min_uV) | ||
2432 | ret = 0; | ||
2433 | else if (ret > rdev->constraints->max_uV) | ||
2434 | ret = 0; | ||
2435 | } | ||
2436 | |||
2437 | return ret; | ||
2438 | } | ||
2439 | |||
2315 | /** | 2440 | /** |
2316 | * regulator_is_enabled - is the regulator output enabled | 2441 | * regulator_is_enabled - is the regulator output enabled |
2317 | * @regulator: regulator source | 2442 | * @regulator: regulator source |
@@ -2401,33 +2526,7 @@ EXPORT_SYMBOL_GPL(regulator_count_voltages); | |||
2401 | */ | 2526 | */ |
2402 | int regulator_list_voltage(struct regulator *regulator, unsigned selector) | 2527 | int regulator_list_voltage(struct regulator *regulator, unsigned selector) |
2403 | { | 2528 | { |
2404 | struct regulator_dev *rdev = regulator->rdev; | 2529 | return _regulator_list_voltage(regulator, selector, 1); |
2405 | const struct regulator_ops *ops = rdev->desc->ops; | ||
2406 | int ret; | ||
2407 | |||
2408 | if (rdev->desc->fixed_uV && rdev->desc->n_voltages == 1 && !selector) | ||
2409 | return rdev->desc->fixed_uV; | ||
2410 | |||
2411 | if (ops->list_voltage) { | ||
2412 | if (selector >= rdev->desc->n_voltages) | ||
2413 | return -EINVAL; | ||
2414 | mutex_lock(&rdev->mutex); | ||
2415 | ret = ops->list_voltage(rdev, selector); | ||
2416 | mutex_unlock(&rdev->mutex); | ||
2417 | } else if (rdev->supply) { | ||
2418 | ret = regulator_list_voltage(rdev->supply, selector); | ||
2419 | } else { | ||
2420 | return -EINVAL; | ||
2421 | } | ||
2422 | |||
2423 | if (ret > 0) { | ||
2424 | if (ret < rdev->constraints->min_uV) | ||
2425 | ret = 0; | ||
2426 | else if (ret > rdev->constraints->max_uV) | ||
2427 | ret = 0; | ||
2428 | } | ||
2429 | |||
2430 | return ret; | ||
2431 | } | 2530 | } |
2432 | EXPORT_SYMBOL_GPL(regulator_list_voltage); | 2531 | EXPORT_SYMBOL_GPL(regulator_list_voltage); |
2433 | 2532 | ||
@@ -2562,6 +2661,23 @@ int regulator_is_supported_voltage(struct regulator *regulator, | |||
2562 | } | 2661 | } |
2563 | EXPORT_SYMBOL_GPL(regulator_is_supported_voltage); | 2662 | EXPORT_SYMBOL_GPL(regulator_is_supported_voltage); |
2564 | 2663 | ||
2664 | static int regulator_map_voltage(struct regulator_dev *rdev, int min_uV, | ||
2665 | int max_uV) | ||
2666 | { | ||
2667 | const struct regulator_desc *desc = rdev->desc; | ||
2668 | |||
2669 | if (desc->ops->map_voltage) | ||
2670 | return desc->ops->map_voltage(rdev, min_uV, max_uV); | ||
2671 | |||
2672 | if (desc->ops->list_voltage == regulator_list_voltage_linear) | ||
2673 | return regulator_map_voltage_linear(rdev, min_uV, max_uV); | ||
2674 | |||
2675 | if (desc->ops->list_voltage == regulator_list_voltage_linear_range) | ||
2676 | return regulator_map_voltage_linear_range(rdev, min_uV, max_uV); | ||
2677 | |||
2678 | return regulator_map_voltage_iterate(rdev, min_uV, max_uV); | ||
2679 | } | ||
2680 | |||
2565 | static int _regulator_call_set_voltage(struct regulator_dev *rdev, | 2681 | static int _regulator_call_set_voltage(struct regulator_dev *rdev, |
2566 | int min_uV, int max_uV, | 2682 | int min_uV, int max_uV, |
2567 | unsigned *selector) | 2683 | unsigned *selector) |
@@ -2650,23 +2766,7 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, | |||
2650 | } | 2766 | } |
2651 | 2767 | ||
2652 | } else if (rdev->desc->ops->set_voltage_sel) { | 2768 | } else if (rdev->desc->ops->set_voltage_sel) { |
2653 | if (rdev->desc->ops->map_voltage) { | 2769 | ret = regulator_map_voltage(rdev, min_uV, max_uV); |
2654 | ret = rdev->desc->ops->map_voltage(rdev, min_uV, | ||
2655 | max_uV); | ||
2656 | } else { | ||
2657 | if (rdev->desc->ops->list_voltage == | ||
2658 | regulator_list_voltage_linear) | ||
2659 | ret = regulator_map_voltage_linear(rdev, | ||
2660 | min_uV, max_uV); | ||
2661 | else if (rdev->desc->ops->list_voltage == | ||
2662 | regulator_list_voltage_linear_range) | ||
2663 | ret = regulator_map_voltage_linear_range(rdev, | ||
2664 | min_uV, max_uV); | ||
2665 | else | ||
2666 | ret = regulator_map_voltage_iterate(rdev, | ||
2667 | min_uV, max_uV); | ||
2668 | } | ||
2669 | |||
2670 | if (ret >= 0) { | 2770 | if (ret >= 0) { |
2671 | best_val = rdev->desc->ops->list_voltage(rdev, ret); | 2771 | best_val = rdev->desc->ops->list_voltage(rdev, ret); |
2672 | if (min_uV <= best_val && max_uV >= best_val) { | 2772 | if (min_uV <= best_val && max_uV >= best_val) { |
@@ -2717,32 +2817,15 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, | |||
2717 | return ret; | 2817 | return ret; |
2718 | } | 2818 | } |
2719 | 2819 | ||
2720 | /** | 2820 | static int regulator_set_voltage_unlocked(struct regulator *regulator, |
2721 | * regulator_set_voltage - set regulator output voltage | 2821 | int min_uV, int max_uV) |
2722 | * @regulator: regulator source | ||
2723 | * @min_uV: Minimum required voltage in uV | ||
2724 | * @max_uV: Maximum acceptable voltage in uV | ||
2725 | * | ||
2726 | * Sets a voltage regulator to the desired output voltage. This can be set | ||
2727 | * during any regulator state. IOW, regulator can be disabled or enabled. | ||
2728 | * | ||
2729 | * If the regulator is enabled then the voltage will change to the new value | ||
2730 | * immediately otherwise if the regulator is disabled the regulator will | ||
2731 | * output at the new voltage when enabled. | ||
2732 | * | ||
2733 | * NOTE: If the regulator is shared between several devices then the lowest | ||
2734 | * request voltage that meets the system constraints will be used. | ||
2735 | * Regulator system constraints must be set for this regulator before | ||
2736 | * calling this function otherwise this call will fail. | ||
2737 | */ | ||
2738 | int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV) | ||
2739 | { | 2822 | { |
2740 | struct regulator_dev *rdev = regulator->rdev; | 2823 | struct regulator_dev *rdev = regulator->rdev; |
2741 | int ret = 0; | 2824 | int ret = 0; |
2742 | int old_min_uV, old_max_uV; | 2825 | int old_min_uV, old_max_uV; |
2743 | int current_uV; | 2826 | int current_uV; |
2744 | 2827 | int best_supply_uV = 0; | |
2745 | mutex_lock(&rdev->mutex); | 2828 | int supply_change_uV = 0; |
2746 | 2829 | ||
2747 | /* If we're setting the same range as last time the change | 2830 | /* If we're setting the same range as last time the change |
2748 | * should be a noop (some cpufreq implementations use the same | 2831 | * should be a noop (some cpufreq implementations use the same |
@@ -2786,17 +2869,95 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV) | |||
2786 | if (ret < 0) | 2869 | if (ret < 0) |
2787 | goto out2; | 2870 | goto out2; |
2788 | 2871 | ||
2872 | if (rdev->supply && (rdev->desc->min_dropout_uV || | ||
2873 | !rdev->desc->ops->get_voltage)) { | ||
2874 | int current_supply_uV; | ||
2875 | int selector; | ||
2876 | |||
2877 | selector = regulator_map_voltage(rdev, min_uV, max_uV); | ||
2878 | if (selector < 0) { | ||
2879 | ret = selector; | ||
2880 | goto out2; | ||
2881 | } | ||
2882 | |||
2883 | best_supply_uV = _regulator_list_voltage(regulator, selector, 0); | ||
2884 | if (best_supply_uV < 0) { | ||
2885 | ret = best_supply_uV; | ||
2886 | goto out2; | ||
2887 | } | ||
2888 | |||
2889 | best_supply_uV += rdev->desc->min_dropout_uV; | ||
2890 | |||
2891 | current_supply_uV = _regulator_get_voltage(rdev->supply->rdev); | ||
2892 | if (current_supply_uV < 0) { | ||
2893 | ret = current_supply_uV; | ||
2894 | goto out2; | ||
2895 | } | ||
2896 | |||
2897 | supply_change_uV = best_supply_uV - current_supply_uV; | ||
2898 | } | ||
2899 | |||
2900 | if (supply_change_uV > 0) { | ||
2901 | ret = regulator_set_voltage_unlocked(rdev->supply, | ||
2902 | best_supply_uV, INT_MAX); | ||
2903 | if (ret) { | ||
2904 | dev_err(&rdev->dev, "Failed to increase supply voltage: %d\n", | ||
2905 | ret); | ||
2906 | goto out2; | ||
2907 | } | ||
2908 | } | ||
2909 | |||
2789 | ret = _regulator_do_set_voltage(rdev, min_uV, max_uV); | 2910 | ret = _regulator_do_set_voltage(rdev, min_uV, max_uV); |
2790 | if (ret < 0) | 2911 | if (ret < 0) |
2791 | goto out2; | 2912 | goto out2; |
2792 | 2913 | ||
2914 | if (supply_change_uV < 0) { | ||
2915 | ret = regulator_set_voltage_unlocked(rdev->supply, | ||
2916 | best_supply_uV, INT_MAX); | ||
2917 | if (ret) | ||
2918 | dev_warn(&rdev->dev, "Failed to decrease supply voltage: %d\n", | ||
2919 | ret); | ||
2920 | /* No need to fail here */ | ||
2921 | ret = 0; | ||
2922 | } | ||
2923 | |||
2793 | out: | 2924 | out: |
2794 | mutex_unlock(&rdev->mutex); | ||
2795 | return ret; | 2925 | return ret; |
2796 | out2: | 2926 | out2: |
2797 | regulator->min_uV = old_min_uV; | 2927 | regulator->min_uV = old_min_uV; |
2798 | regulator->max_uV = old_max_uV; | 2928 | regulator->max_uV = old_max_uV; |
2799 | mutex_unlock(&rdev->mutex); | 2929 | |
2930 | return ret; | ||
2931 | } | ||
2932 | |||
2933 | /** | ||
2934 | * regulator_set_voltage - set regulator output voltage | ||
2935 | * @regulator: regulator source | ||
2936 | * @min_uV: Minimum required voltage in uV | ||
2937 | * @max_uV: Maximum acceptable voltage in uV | ||
2938 | * | ||
2939 | * Sets a voltage regulator to the desired output voltage. This can be set | ||
2940 | * during any regulator state. IOW, regulator can be disabled or enabled. | ||
2941 | * | ||
2942 | * If the regulator is enabled then the voltage will change to the new value | ||
2943 | * immediately otherwise if the regulator is disabled the regulator will | ||
2944 | * output at the new voltage when enabled. | ||
2945 | * | ||
2946 | * NOTE: If the regulator is shared between several devices then the lowest | ||
2947 | * request voltage that meets the system constraints will be used. | ||
2948 | * Regulator system constraints must be set for this regulator before | ||
2949 | * calling this function otherwise this call will fail. | ||
2950 | */ | ||
2951 | int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV) | ||
2952 | { | ||
2953 | int ret = 0; | ||
2954 | |||
2955 | regulator_lock_supply(regulator->rdev); | ||
2956 | |||
2957 | ret = regulator_set_voltage_unlocked(regulator, min_uV, max_uV); | ||
2958 | |||
2959 | regulator_unlock_supply(regulator->rdev); | ||
2960 | |||
2800 | return ret; | 2961 | return ret; |
2801 | } | 2962 | } |
2802 | EXPORT_SYMBOL_GPL(regulator_set_voltage); | 2963 | EXPORT_SYMBOL_GPL(regulator_set_voltage); |
@@ -2949,7 +3110,7 @@ static int _regulator_get_voltage(struct regulator_dev *rdev) | |||
2949 | } else if (rdev->desc->fixed_uV && (rdev->desc->n_voltages == 1)) { | 3110 | } else if (rdev->desc->fixed_uV && (rdev->desc->n_voltages == 1)) { |
2950 | ret = rdev->desc->fixed_uV; | 3111 | ret = rdev->desc->fixed_uV; |
2951 | } else if (rdev->supply) { | 3112 | } else if (rdev->supply) { |
2952 | ret = regulator_get_voltage(rdev->supply); | 3113 | ret = _regulator_get_voltage(rdev->supply->rdev); |
2953 | } else { | 3114 | } else { |
2954 | return -EINVAL; | 3115 | return -EINVAL; |
2955 | } | 3116 | } |
@@ -2972,11 +3133,11 @@ int regulator_get_voltage(struct regulator *regulator) | |||
2972 | { | 3133 | { |
2973 | int ret; | 3134 | int ret; |
2974 | 3135 | ||
2975 | mutex_lock(®ulator->rdev->mutex); | 3136 | regulator_lock_supply(regulator->rdev); |
2976 | 3137 | ||
2977 | ret = _regulator_get_voltage(regulator->rdev); | 3138 | ret = _regulator_get_voltage(regulator->rdev); |
2978 | 3139 | ||
2979 | mutex_unlock(®ulator->rdev->mutex); | 3140 | regulator_unlock_supply(regulator->rdev); |
2980 | 3141 | ||
2981 | return ret; | 3142 | return ret; |
2982 | } | 3143 | } |
@@ -3810,8 +3971,6 @@ regulator_register(const struct regulator_desc *regulator_desc, | |||
3810 | } | 3971 | } |
3811 | } | 3972 | } |
3812 | 3973 | ||
3813 | list_add(&rdev->list, ®ulator_list); | ||
3814 | |||
3815 | rdev_init_debugfs(rdev); | 3974 | rdev_init_debugfs(rdev); |
3816 | out: | 3975 | out: |
3817 | mutex_unlock(®ulator_list_mutex); | 3976 | mutex_unlock(®ulator_list_mutex); |
@@ -3865,6 +4024,19 @@ void regulator_unregister(struct regulator_dev *rdev) | |||
3865 | } | 4024 | } |
3866 | EXPORT_SYMBOL_GPL(regulator_unregister); | 4025 | EXPORT_SYMBOL_GPL(regulator_unregister); |
3867 | 4026 | ||
4027 | static int _regulator_suspend_prepare(struct device *dev, void *data) | ||
4028 | { | ||
4029 | struct regulator_dev *rdev = dev_to_rdev(dev); | ||
4030 | const suspend_state_t *state = data; | ||
4031 | int ret; | ||
4032 | |||
4033 | mutex_lock(&rdev->mutex); | ||
4034 | ret = suspend_prepare(rdev, *state); | ||
4035 | mutex_unlock(&rdev->mutex); | ||
4036 | |||
4037 | return ret; | ||
4038 | } | ||
4039 | |||
3868 | /** | 4040 | /** |
3869 | * regulator_suspend_prepare - prepare regulators for system wide suspend | 4041 | * regulator_suspend_prepare - prepare regulators for system wide suspend |
3870 | * @state: system suspend state | 4042 | * @state: system suspend state |
@@ -3874,30 +4046,45 @@ EXPORT_SYMBOL_GPL(regulator_unregister); | |||
3874 | */ | 4046 | */ |
3875 | int regulator_suspend_prepare(suspend_state_t state) | 4047 | int regulator_suspend_prepare(suspend_state_t state) |
3876 | { | 4048 | { |
3877 | struct regulator_dev *rdev; | ||
3878 | int ret = 0; | ||
3879 | |||
3880 | /* ON is handled by regulator active state */ | 4049 | /* ON is handled by regulator active state */ |
3881 | if (state == PM_SUSPEND_ON) | 4050 | if (state == PM_SUSPEND_ON) |
3882 | return -EINVAL; | 4051 | return -EINVAL; |
3883 | 4052 | ||
3884 | mutex_lock(®ulator_list_mutex); | 4053 | return class_for_each_device(®ulator_class, NULL, &state, |
3885 | list_for_each_entry(rdev, ®ulator_list, list) { | 4054 | _regulator_suspend_prepare); |
4055 | } | ||
4056 | EXPORT_SYMBOL_GPL(regulator_suspend_prepare); | ||
3886 | 4057 | ||
3887 | mutex_lock(&rdev->mutex); | 4058 | static int _regulator_suspend_finish(struct device *dev, void *data) |
3888 | ret = suspend_prepare(rdev, state); | 4059 | { |
3889 | mutex_unlock(&rdev->mutex); | 4060 | struct regulator_dev *rdev = dev_to_rdev(dev); |
4061 | int ret; | ||
3890 | 4062 | ||
3891 | if (ret < 0) { | 4063 | mutex_lock(&rdev->mutex); |
3892 | rdev_err(rdev, "failed to prepare\n"); | 4064 | if (rdev->use_count > 0 || rdev->constraints->always_on) { |
3893 | goto out; | 4065 | if (!_regulator_is_enabled(rdev)) { |
4066 | ret = _regulator_do_enable(rdev); | ||
4067 | if (ret) | ||
4068 | dev_err(dev, | ||
4069 | "Failed to resume regulator %d\n", | ||
4070 | ret); | ||
3894 | } | 4071 | } |
4072 | } else { | ||
4073 | if (!have_full_constraints()) | ||
4074 | goto unlock; | ||
4075 | if (!_regulator_is_enabled(rdev)) | ||
4076 | goto unlock; | ||
4077 | |||
4078 | ret = _regulator_do_disable(rdev); | ||
4079 | if (ret) | ||
4080 | dev_err(dev, "Failed to suspend regulator %d\n", ret); | ||
3895 | } | 4081 | } |
3896 | out: | 4082 | unlock: |
3897 | mutex_unlock(®ulator_list_mutex); | 4083 | mutex_unlock(&rdev->mutex); |
3898 | return ret; | 4084 | |
4085 | /* Keep processing regulators in spite of any errors */ | ||
4086 | return 0; | ||
3899 | } | 4087 | } |
3900 | EXPORT_SYMBOL_GPL(regulator_suspend_prepare); | ||
3901 | 4088 | ||
3902 | /** | 4089 | /** |
3903 | * regulator_suspend_finish - resume regulators from system wide suspend | 4090 | * regulator_suspend_finish - resume regulators from system wide suspend |
@@ -3907,33 +4094,8 @@ EXPORT_SYMBOL_GPL(regulator_suspend_prepare); | |||
3907 | */ | 4094 | */ |
3908 | int regulator_suspend_finish(void) | 4095 | int regulator_suspend_finish(void) |
3909 | { | 4096 | { |
3910 | struct regulator_dev *rdev; | 4097 | return class_for_each_device(®ulator_class, NULL, NULL, |
3911 | int ret = 0, error; | 4098 | _regulator_suspend_finish); |
3912 | |||
3913 | mutex_lock(®ulator_list_mutex); | ||
3914 | list_for_each_entry(rdev, ®ulator_list, list) { | ||
3915 | mutex_lock(&rdev->mutex); | ||
3916 | if (rdev->use_count > 0 || rdev->constraints->always_on) { | ||
3917 | if (!_regulator_is_enabled(rdev)) { | ||
3918 | error = _regulator_do_enable(rdev); | ||
3919 | if (error) | ||
3920 | ret = error; | ||
3921 | } | ||
3922 | } else { | ||
3923 | if (!have_full_constraints()) | ||
3924 | goto unlock; | ||
3925 | if (!_regulator_is_enabled(rdev)) | ||
3926 | goto unlock; | ||
3927 | |||
3928 | error = _regulator_do_disable(rdev); | ||
3929 | if (error) | ||
3930 | ret = error; | ||
3931 | } | ||
3932 | unlock: | ||
3933 | mutex_unlock(&rdev->mutex); | ||
3934 | } | ||
3935 | mutex_unlock(®ulator_list_mutex); | ||
3936 | return ret; | ||
3937 | } | 4099 | } |
3938 | EXPORT_SYMBOL_GPL(regulator_suspend_finish); | 4100 | EXPORT_SYMBOL_GPL(regulator_suspend_finish); |
3939 | 4101 | ||
@@ -4053,14 +4215,35 @@ static const struct file_operations supply_map_fops = { | |||
4053 | }; | 4215 | }; |
4054 | 4216 | ||
4055 | #ifdef CONFIG_DEBUG_FS | 4217 | #ifdef CONFIG_DEBUG_FS |
4218 | struct summary_data { | ||
4219 | struct seq_file *s; | ||
4220 | struct regulator_dev *parent; | ||
4221 | int level; | ||
4222 | }; | ||
4223 | |||
4224 | static void regulator_summary_show_subtree(struct seq_file *s, | ||
4225 | struct regulator_dev *rdev, | ||
4226 | int level); | ||
4227 | |||
4228 | static int regulator_summary_show_children(struct device *dev, void *data) | ||
4229 | { | ||
4230 | struct regulator_dev *rdev = dev_to_rdev(dev); | ||
4231 | struct summary_data *summary_data = data; | ||
4232 | |||
4233 | if (rdev->supply && rdev->supply->rdev == summary_data->parent) | ||
4234 | regulator_summary_show_subtree(summary_data->s, rdev, | ||
4235 | summary_data->level + 1); | ||
4236 | |||
4237 | return 0; | ||
4238 | } | ||
4239 | |||
4056 | static void regulator_summary_show_subtree(struct seq_file *s, | 4240 | static void regulator_summary_show_subtree(struct seq_file *s, |
4057 | struct regulator_dev *rdev, | 4241 | struct regulator_dev *rdev, |
4058 | int level) | 4242 | int level) |
4059 | { | 4243 | { |
4060 | struct list_head *list = s->private; | ||
4061 | struct regulator_dev *child; | ||
4062 | struct regulation_constraints *c; | 4244 | struct regulation_constraints *c; |
4063 | struct regulator *consumer; | 4245 | struct regulator *consumer; |
4246 | struct summary_data summary_data; | ||
4064 | 4247 | ||
4065 | if (!rdev) | 4248 | if (!rdev) |
4066 | return; | 4249 | return; |
@@ -4110,33 +4293,32 @@ static void regulator_summary_show_subtree(struct seq_file *s, | |||
4110 | seq_puts(s, "\n"); | 4293 | seq_puts(s, "\n"); |
4111 | } | 4294 | } |
4112 | 4295 | ||
4113 | list_for_each_entry(child, list, list) { | 4296 | summary_data.s = s; |
4114 | /* handle only non-root regulators supplied by current rdev */ | 4297 | summary_data.level = level; |
4115 | if (!child->supply || child->supply->rdev != rdev) | 4298 | summary_data.parent = rdev; |
4116 | continue; | ||
4117 | 4299 | ||
4118 | regulator_summary_show_subtree(s, child, level + 1); | 4300 | class_for_each_device(®ulator_class, NULL, &summary_data, |
4119 | } | 4301 | regulator_summary_show_children); |
4120 | } | 4302 | } |
4121 | 4303 | ||
4122 | static int regulator_summary_show(struct seq_file *s, void *data) | 4304 | static int regulator_summary_show_roots(struct device *dev, void *data) |
4123 | { | 4305 | { |
4124 | struct list_head *list = s->private; | 4306 | struct regulator_dev *rdev = dev_to_rdev(dev); |
4125 | struct regulator_dev *rdev; | 4307 | struct seq_file *s = data; |
4126 | |||
4127 | seq_puts(s, " regulator use open bypass voltage current min max\n"); | ||
4128 | seq_puts(s, "-------------------------------------------------------------------------------\n"); | ||
4129 | 4308 | ||
4130 | mutex_lock(®ulator_list_mutex); | 4309 | if (!rdev->supply) |
4310 | regulator_summary_show_subtree(s, rdev, 0); | ||
4131 | 4311 | ||
4132 | list_for_each_entry(rdev, list, list) { | 4312 | return 0; |
4133 | if (rdev->supply) | 4313 | } |
4134 | continue; | ||
4135 | 4314 | ||
4136 | regulator_summary_show_subtree(s, rdev, 0); | 4315 | static int regulator_summary_show(struct seq_file *s, void *data) |
4137 | } | 4316 | { |
4317 | seq_puts(s, " regulator use open bypass voltage current min max\n"); | ||
4318 | seq_puts(s, "-------------------------------------------------------------------------------\n"); | ||
4138 | 4319 | ||
4139 | mutex_unlock(®ulator_list_mutex); | 4320 | class_for_each_device(®ulator_class, NULL, s, |
4321 | regulator_summary_show_roots); | ||
4140 | 4322 | ||
4141 | return 0; | 4323 | return 0; |
4142 | } | 4324 | } |
@@ -4170,7 +4352,7 @@ static int __init regulator_init(void) | |||
4170 | &supply_map_fops); | 4352 | &supply_map_fops); |
4171 | 4353 | ||
4172 | debugfs_create_file("regulator_summary", 0444, debugfs_root, | 4354 | debugfs_create_file("regulator_summary", 0444, debugfs_root, |
4173 | ®ulator_list, ®ulator_summary_fops); | 4355 | NULL, ®ulator_summary_fops); |
4174 | 4356 | ||
4175 | regulator_dummy_init(); | 4357 | regulator_dummy_init(); |
4176 | 4358 | ||
diff --git a/drivers/regulator/da9052-regulator.c b/drivers/regulator/da9052-regulator.c index e628d4c2f2ae..12a25b40e473 100644 --- a/drivers/regulator/da9052-regulator.c +++ b/drivers/regulator/da9052-regulator.c | |||
@@ -381,6 +381,7 @@ static inline struct da9052_regulator_info *find_regulator_info(u8 chip_id, | |||
381 | case DA9053_AA: | 381 | case DA9053_AA: |
382 | case DA9053_BA: | 382 | case DA9053_BA: |
383 | case DA9053_BB: | 383 | case DA9053_BB: |
384 | case DA9053_BC: | ||
384 | for (i = 0; i < ARRAY_SIZE(da9053_regulator_info); i++) { | 385 | for (i = 0; i < ARRAY_SIZE(da9053_regulator_info); i++) { |
385 | info = &da9053_regulator_info[i]; | 386 | info = &da9053_regulator_info[i]; |
386 | if (info->reg_desc.id == id) | 387 | if (info->reg_desc.id == id) |
diff --git a/drivers/regulator/da9063-regulator.c b/drivers/regulator/da9063-regulator.c index aed1ad3dc964..536e931eb921 100644 --- a/drivers/regulator/da9063-regulator.c +++ b/drivers/regulator/da9063-regulator.c | |||
@@ -698,7 +698,7 @@ static struct da9063_regulators_pdata *da9063_parse_regulators_dt( | |||
698 | rdata->initdata = da9063_matches[i].init_data; | 698 | rdata->initdata = da9063_matches[i].init_data; |
699 | 699 | ||
700 | n++; | 700 | n++; |
701 | }; | 701 | } |
702 | 702 | ||
703 | *da9063_reg_matches = da9063_matches; | 703 | *da9063_reg_matches = da9063_matches; |
704 | return pdata; | 704 | return pdata; |
diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index 250700c853bf..499e437c7e91 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c | |||
@@ -76,6 +76,9 @@ static void of_get_regulation_constraints(struct device_node *np, | |||
76 | if (of_property_read_bool(np, "regulator-allow-bypass")) | 76 | if (of_property_read_bool(np, "regulator-allow-bypass")) |
77 | constraints->valid_ops_mask |= REGULATOR_CHANGE_BYPASS; | 77 | constraints->valid_ops_mask |= REGULATOR_CHANGE_BYPASS; |
78 | 78 | ||
79 | if (of_property_read_bool(np, "regulator-allow-set-load")) | ||
80 | constraints->valid_ops_mask |= REGULATOR_CHANGE_DRMS; | ||
81 | |||
79 | ret = of_property_read_u32(np, "regulator-ramp-delay", &pval); | 82 | ret = of_property_read_u32(np, "regulator-ramp-delay", &pval); |
80 | if (!ret) { | 83 | if (!ret) { |
81 | if (pval) | 84 | if (pval) |
diff --git a/drivers/regulator/pwm-regulator.c b/drivers/regulator/pwm-regulator.c index fc3166dfcbfa..3aca067b9901 100644 --- a/drivers/regulator/pwm-regulator.c +++ b/drivers/regulator/pwm-regulator.c | |||
@@ -69,12 +69,6 @@ static int pwm_regulator_set_voltage_sel(struct regulator_dev *rdev, | |||
69 | 69 | ||
70 | drvdata->state = selector; | 70 | drvdata->state = selector; |
71 | 71 | ||
72 | ret = pwm_enable(drvdata->pwm); | ||
73 | if (ret) { | ||
74 | dev_err(&rdev->dev, "Failed to enable PWM\n"); | ||
75 | return ret; | ||
76 | } | ||
77 | |||
78 | return 0; | 72 | return 0; |
79 | } | 73 | } |
80 | 74 | ||
@@ -89,6 +83,29 @@ static int pwm_regulator_list_voltage(struct regulator_dev *rdev, | |||
89 | return drvdata->duty_cycle_table[selector].uV; | 83 | return drvdata->duty_cycle_table[selector].uV; |
90 | } | 84 | } |
91 | 85 | ||
86 | static int pwm_regulator_enable(struct regulator_dev *dev) | ||
87 | { | ||
88 | struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev); | ||
89 | |||
90 | return pwm_enable(drvdata->pwm); | ||
91 | } | ||
92 | |||
93 | static int pwm_regulator_disable(struct regulator_dev *dev) | ||
94 | { | ||
95 | struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev); | ||
96 | |||
97 | pwm_disable(drvdata->pwm); | ||
98 | |||
99 | return 0; | ||
100 | } | ||
101 | |||
102 | static int pwm_regulator_is_enabled(struct regulator_dev *dev) | ||
103 | { | ||
104 | struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev); | ||
105 | |||
106 | return pwm_is_enabled(drvdata->pwm); | ||
107 | } | ||
108 | |||
92 | /** | 109 | /** |
93 | * Continuous voltage call-backs | 110 | * Continuous voltage call-backs |
94 | */ | 111 | */ |
@@ -144,11 +161,17 @@ static struct regulator_ops pwm_regulator_voltage_table_ops = { | |||
144 | .get_voltage_sel = pwm_regulator_get_voltage_sel, | 161 | .get_voltage_sel = pwm_regulator_get_voltage_sel, |
145 | .list_voltage = pwm_regulator_list_voltage, | 162 | .list_voltage = pwm_regulator_list_voltage, |
146 | .map_voltage = regulator_map_voltage_iterate, | 163 | .map_voltage = regulator_map_voltage_iterate, |
164 | .enable = pwm_regulator_enable, | ||
165 | .disable = pwm_regulator_disable, | ||
166 | .is_enabled = pwm_regulator_is_enabled, | ||
147 | }; | 167 | }; |
148 | 168 | ||
149 | static struct regulator_ops pwm_regulator_voltage_continuous_ops = { | 169 | static struct regulator_ops pwm_regulator_voltage_continuous_ops = { |
150 | .get_voltage = pwm_regulator_get_voltage, | 170 | .get_voltage = pwm_regulator_get_voltage, |
151 | .set_voltage = pwm_regulator_set_voltage, | 171 | .set_voltage = pwm_regulator_set_voltage, |
172 | .enable = pwm_regulator_enable, | ||
173 | .disable = pwm_regulator_disable, | ||
174 | .is_enabled = pwm_regulator_is_enabled, | ||
152 | }; | 175 | }; |
153 | 176 | ||
154 | static struct regulator_desc pwm_regulator_desc = { | 177 | static struct regulator_desc pwm_regulator_desc = { |
diff --git a/drivers/regulator/qcom_smd-regulator.c b/drivers/regulator/qcom_smd-regulator.c index 9c6167dd2c8b..6fa0c7d13290 100644 --- a/drivers/regulator/qcom_smd-regulator.c +++ b/drivers/regulator/qcom_smd-regulator.c | |||
@@ -36,9 +36,9 @@ struct qcom_rpm_reg { | |||
36 | }; | 36 | }; |
37 | 37 | ||
38 | struct rpm_regulator_req { | 38 | struct rpm_regulator_req { |
39 | u32 key; | 39 | __le32 key; |
40 | u32 nbytes; | 40 | __le32 nbytes; |
41 | u32 value; | 41 | __le32 value; |
42 | }; | 42 | }; |
43 | 43 | ||
44 | #define RPM_KEY_SWEN 0x6e657773 /* "swen" */ | 44 | #define RPM_KEY_SWEN 0x6e657773 /* "swen" */ |
@@ -62,9 +62,9 @@ static int rpm_reg_enable(struct regulator_dev *rdev) | |||
62 | struct rpm_regulator_req req; | 62 | struct rpm_regulator_req req; |
63 | int ret; | 63 | int ret; |
64 | 64 | ||
65 | req.key = RPM_KEY_SWEN; | 65 | req.key = cpu_to_le32(RPM_KEY_SWEN); |
66 | req.nbytes = sizeof(u32); | 66 | req.nbytes = cpu_to_le32(sizeof(u32)); |
67 | req.value = 1; | 67 | req.value = cpu_to_le32(1); |
68 | 68 | ||
69 | ret = rpm_reg_write_active(vreg, &req, sizeof(req)); | 69 | ret = rpm_reg_write_active(vreg, &req, sizeof(req)); |
70 | if (!ret) | 70 | if (!ret) |
@@ -86,8 +86,8 @@ static int rpm_reg_disable(struct regulator_dev *rdev) | |||
86 | struct rpm_regulator_req req; | 86 | struct rpm_regulator_req req; |
87 | int ret; | 87 | int ret; |
88 | 88 | ||
89 | req.key = RPM_KEY_SWEN; | 89 | req.key = cpu_to_le32(RPM_KEY_SWEN); |
90 | req.nbytes = sizeof(u32); | 90 | req.nbytes = cpu_to_le32(sizeof(u32)); |
91 | req.value = 0; | 91 | req.value = 0; |
92 | 92 | ||
93 | ret = rpm_reg_write_active(vreg, &req, sizeof(req)); | 93 | ret = rpm_reg_write_active(vreg, &req, sizeof(req)); |
@@ -113,9 +113,9 @@ static int rpm_reg_set_voltage(struct regulator_dev *rdev, | |||
113 | struct rpm_regulator_req req; | 113 | struct rpm_regulator_req req; |
114 | int ret = 0; | 114 | int ret = 0; |
115 | 115 | ||
116 | req.key = RPM_KEY_UV; | 116 | req.key = cpu_to_le32(RPM_KEY_UV); |
117 | req.nbytes = sizeof(u32); | 117 | req.nbytes = cpu_to_le32(sizeof(u32)); |
118 | req.value = min_uV; | 118 | req.value = cpu_to_le32(min_uV); |
119 | 119 | ||
120 | ret = rpm_reg_write_active(vreg, &req, sizeof(req)); | 120 | ret = rpm_reg_write_active(vreg, &req, sizeof(req)); |
121 | if (!ret) | 121 | if (!ret) |
@@ -129,9 +129,9 @@ static int rpm_reg_set_load(struct regulator_dev *rdev, int load_uA) | |||
129 | struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev); | 129 | struct qcom_rpm_reg *vreg = rdev_get_drvdata(rdev); |
130 | struct rpm_regulator_req req; | 130 | struct rpm_regulator_req req; |
131 | 131 | ||
132 | req.key = RPM_KEY_MA; | 132 | req.key = cpu_to_le32(RPM_KEY_MA); |
133 | req.nbytes = sizeof(u32); | 133 | req.nbytes = cpu_to_le32(sizeof(u32)); |
134 | req.value = load_uA; | 134 | req.value = cpu_to_le32(load_uA / 1000); |
135 | 135 | ||
136 | return rpm_reg_write_active(vreg, &req, sizeof(req)); | 136 | return rpm_reg_write_active(vreg, &req, sizeof(req)); |
137 | } | 137 | } |
diff --git a/drivers/regulator/tps6105x-regulator.c b/drivers/regulator/tps6105x-regulator.c index 3510b3e7330a..ddc4f10e268a 100644 --- a/drivers/regulator/tps6105x-regulator.c +++ b/drivers/regulator/tps6105x-regulator.c | |||
@@ -14,7 +14,7 @@ | |||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/err.h> | 16 | #include <linux/err.h> |
17 | #include <linux/i2c.h> | 17 | #include <linux/regmap.h> |
18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
19 | #include <linux/regulator/driver.h> | 19 | #include <linux/regulator/driver.h> |
20 | #include <linux/mfd/core.h> | 20 | #include <linux/mfd/core.h> |
@@ -33,7 +33,7 @@ static int tps6105x_regulator_enable(struct regulator_dev *rdev) | |||
33 | int ret; | 33 | int ret; |
34 | 34 | ||
35 | /* Activate voltage mode */ | 35 | /* Activate voltage mode */ |
36 | ret = tps6105x_mask_and_set(tps6105x, TPS6105X_REG_0, | 36 | ret = regmap_update_bits(tps6105x->regmap, TPS6105X_REG_0, |
37 | TPS6105X_REG0_MODE_MASK, | 37 | TPS6105X_REG0_MODE_MASK, |
38 | TPS6105X_REG0_MODE_VOLTAGE << TPS6105X_REG0_MODE_SHIFT); | 38 | TPS6105X_REG0_MODE_VOLTAGE << TPS6105X_REG0_MODE_SHIFT); |
39 | if (ret) | 39 | if (ret) |
@@ -48,7 +48,7 @@ static int tps6105x_regulator_disable(struct regulator_dev *rdev) | |||
48 | int ret; | 48 | int ret; |
49 | 49 | ||
50 | /* Set into shutdown mode */ | 50 | /* Set into shutdown mode */ |
51 | ret = tps6105x_mask_and_set(tps6105x, TPS6105X_REG_0, | 51 | ret = regmap_update_bits(tps6105x->regmap, TPS6105X_REG_0, |
52 | TPS6105X_REG0_MODE_MASK, | 52 | TPS6105X_REG0_MODE_MASK, |
53 | TPS6105X_REG0_MODE_SHUTDOWN << TPS6105X_REG0_MODE_SHIFT); | 53 | TPS6105X_REG0_MODE_SHUTDOWN << TPS6105X_REG0_MODE_SHIFT); |
54 | if (ret) | 54 | if (ret) |
@@ -60,10 +60,10 @@ static int tps6105x_regulator_disable(struct regulator_dev *rdev) | |||
60 | static int tps6105x_regulator_is_enabled(struct regulator_dev *rdev) | 60 | static int tps6105x_regulator_is_enabled(struct regulator_dev *rdev) |
61 | { | 61 | { |
62 | struct tps6105x *tps6105x = rdev_get_drvdata(rdev); | 62 | struct tps6105x *tps6105x = rdev_get_drvdata(rdev); |
63 | u8 regval; | 63 | unsigned int regval; |
64 | int ret; | 64 | int ret; |
65 | 65 | ||
66 | ret = tps6105x_get(tps6105x, TPS6105X_REG_0, ®val); | 66 | ret = regmap_read(tps6105x->regmap, TPS6105X_REG_0, ®val); |
67 | if (ret) | 67 | if (ret) |
68 | return ret; | 68 | return ret; |
69 | regval &= TPS6105X_REG0_MODE_MASK; | 69 | regval &= TPS6105X_REG0_MODE_MASK; |
@@ -78,10 +78,10 @@ static int tps6105x_regulator_is_enabled(struct regulator_dev *rdev) | |||
78 | static int tps6105x_regulator_get_voltage_sel(struct regulator_dev *rdev) | 78 | static int tps6105x_regulator_get_voltage_sel(struct regulator_dev *rdev) |
79 | { | 79 | { |
80 | struct tps6105x *tps6105x = rdev_get_drvdata(rdev); | 80 | struct tps6105x *tps6105x = rdev_get_drvdata(rdev); |
81 | u8 regval; | 81 | unsigned int regval; |
82 | int ret; | 82 | int ret; |
83 | 83 | ||
84 | ret = tps6105x_get(tps6105x, TPS6105X_REG_0, ®val); | 84 | ret = regmap_read(tps6105x->regmap, TPS6105X_REG_0, ®val); |
85 | if (ret) | 85 | if (ret) |
86 | return ret; | 86 | return ret; |
87 | 87 | ||
@@ -96,7 +96,7 @@ static int tps6105x_regulator_set_voltage_sel(struct regulator_dev *rdev, | |||
96 | struct tps6105x *tps6105x = rdev_get_drvdata(rdev); | 96 | struct tps6105x *tps6105x = rdev_get_drvdata(rdev); |
97 | int ret; | 97 | int ret; |
98 | 98 | ||
99 | ret = tps6105x_mask_and_set(tps6105x, TPS6105X_REG_0, | 99 | ret = regmap_update_bits(tps6105x->regmap, TPS6105X_REG_0, |
100 | TPS6105X_REG0_VOLTAGE_MASK, | 100 | TPS6105X_REG0_VOLTAGE_MASK, |
101 | selector << TPS6105X_REG0_VOLTAGE_SHIFT); | 101 | selector << TPS6105X_REG0_VOLTAGE_SHIFT); |
102 | if (ret) | 102 | if (ret) |
diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c index 5cc19b44974a..d2c3d7cc35f5 100644 --- a/drivers/regulator/tps65023-regulator.c +++ b/drivers/regulator/tps65023-regulator.c | |||
@@ -86,6 +86,42 @@ | |||
86 | 86 | ||
87 | #define TPS65023_MAX_REG_ID TPS65023_LDO_2 | 87 | #define TPS65023_MAX_REG_ID TPS65023_LDO_2 |
88 | 88 | ||
89 | #define TPS65023_REGULATOR_DCDC(_num, _t, _em) \ | ||
90 | { \ | ||
91 | .name = "VDCDC"#_num, \ | ||
92 | .of_match = of_match_ptr("VDCDC"#_num), \ | ||
93 | .regulators_node = of_match_ptr("regulators"), \ | ||
94 | .id = TPS65023_DCDC_##_num, \ | ||
95 | .n_voltages = ARRAY_SIZE(_t), \ | ||
96 | .ops = &tps65023_dcdc_ops, \ | ||
97 | .type = REGULATOR_VOLTAGE, \ | ||
98 | .owner = THIS_MODULE, \ | ||
99 | .volt_table = _t, \ | ||
100 | .vsel_reg = TPS65023_REG_DEF_CORE, \ | ||
101 | .vsel_mask = ARRAY_SIZE(_t) - 1, \ | ||
102 | .enable_mask = _em, \ | ||
103 | .enable_reg = TPS65023_REG_REG_CTRL, \ | ||
104 | .apply_reg = TPS65023_REG_CON_CTRL2, \ | ||
105 | .apply_bit = TPS65023_REG_CTRL2_GO, \ | ||
106 | } \ | ||
107 | |||
108 | #define TPS65023_REGULATOR_LDO(_num, _t, _vm) \ | ||
109 | { \ | ||
110 | .name = "LDO"#_num, \ | ||
111 | .of_match = of_match_ptr("LDO"#_num), \ | ||
112 | .regulators_node = of_match_ptr("regulators"), \ | ||
113 | .id = TPS65023_LDO_##_num, \ | ||
114 | .n_voltages = ARRAY_SIZE(_t), \ | ||
115 | .ops = &tps65023_ldo_ops, \ | ||
116 | .type = REGULATOR_VOLTAGE, \ | ||
117 | .owner = THIS_MODULE, \ | ||
118 | .volt_table = _t, \ | ||
119 | .vsel_reg = TPS65023_REG_LDO_CTRL, \ | ||
120 | .vsel_mask = _vm, \ | ||
121 | .enable_mask = 1 << (_num), \ | ||
122 | .enable_reg = TPS65023_REG_REG_CTRL, \ | ||
123 | } \ | ||
124 | |||
89 | /* Supported voltage values for regulators */ | 125 | /* Supported voltage values for regulators */ |
90 | static const unsigned int VCORE_VSEL_table[] = { | 126 | static const unsigned int VCORE_VSEL_table[] = { |
91 | 800000, 825000, 850000, 875000, | 127 | 800000, 825000, 850000, 875000, |
@@ -124,25 +160,16 @@ static const unsigned int TPS65023_LDO2_VSEL_table[] = { | |||
124 | 2500000, 2800000, 3000000, 3300000, | 160 | 2500000, 2800000, 3000000, 3300000, |
125 | }; | 161 | }; |
126 | 162 | ||
127 | /* Regulator specific details */ | ||
128 | struct tps_info { | ||
129 | const char *name; | ||
130 | u8 table_len; | ||
131 | const unsigned int *table; | ||
132 | }; | ||
133 | |||
134 | /* PMIC details */ | 163 | /* PMIC details */ |
135 | struct tps_pmic { | 164 | struct tps_pmic { |
136 | struct regulator_desc desc[TPS65023_NUM_REGULATOR]; | ||
137 | struct regulator_dev *rdev[TPS65023_NUM_REGULATOR]; | 165 | struct regulator_dev *rdev[TPS65023_NUM_REGULATOR]; |
138 | const struct tps_info *info[TPS65023_NUM_REGULATOR]; | 166 | const struct tps_driver_data *driver_data; |
139 | struct regmap *regmap; | 167 | struct regmap *regmap; |
140 | u8 core_regulator; | ||
141 | }; | 168 | }; |
142 | 169 | ||
143 | /* Struct passed as driver data */ | 170 | /* Struct passed as driver data */ |
144 | struct tps_driver_data { | 171 | struct tps_driver_data { |
145 | const struct tps_info *info; | 172 | const struct regulator_desc *desc; |
146 | u8 core_regulator; | 173 | u8 core_regulator; |
147 | }; | 174 | }; |
148 | 175 | ||
@@ -154,7 +181,7 @@ static int tps65023_dcdc_get_voltage_sel(struct regulator_dev *dev) | |||
154 | if (dcdc < TPS65023_DCDC_1 || dcdc > TPS65023_DCDC_3) | 181 | if (dcdc < TPS65023_DCDC_1 || dcdc > TPS65023_DCDC_3) |
155 | return -EINVAL; | 182 | return -EINVAL; |
156 | 183 | ||
157 | if (dcdc != tps->core_regulator) | 184 | if (dcdc != tps->driver_data->core_regulator) |
158 | return 0; | 185 | return 0; |
159 | 186 | ||
160 | return regulator_get_voltage_sel_regmap(dev); | 187 | return regulator_get_voltage_sel_regmap(dev); |
@@ -166,7 +193,7 @@ static int tps65023_dcdc_set_voltage_sel(struct regulator_dev *dev, | |||
166 | struct tps_pmic *tps = rdev_get_drvdata(dev); | 193 | struct tps_pmic *tps = rdev_get_drvdata(dev); |
167 | int dcdc = rdev_get_id(dev); | 194 | int dcdc = rdev_get_id(dev); |
168 | 195 | ||
169 | if (dcdc != tps->core_regulator) | 196 | if (dcdc != tps->driver_data->core_regulator) |
170 | return -EINVAL; | 197 | return -EINVAL; |
171 | 198 | ||
172 | return regulator_set_voltage_sel_regmap(dev, selector); | 199 | return regulator_set_voltage_sel_regmap(dev, selector); |
@@ -199,30 +226,60 @@ static const struct regmap_config tps65023_regmap_config = { | |||
199 | .val_bits = 8, | 226 | .val_bits = 8, |
200 | }; | 227 | }; |
201 | 228 | ||
229 | static const struct regulator_desc tps65020_regulators[] = { | ||
230 | TPS65023_REGULATOR_DCDC(1, DCDC_FIXED_3300000_VSEL_table, 0x20), | ||
231 | TPS65023_REGULATOR_DCDC(2, DCDC_FIXED_1800000_VSEL_table, 0x10), | ||
232 | TPS65023_REGULATOR_DCDC(3, VCORE_VSEL_table, 0x08), | ||
233 | TPS65023_REGULATOR_LDO(1, TPS65020_LDO_VSEL_table, 0x07), | ||
234 | TPS65023_REGULATOR_LDO(2, TPS65020_LDO_VSEL_table, 0x70), | ||
235 | }; | ||
236 | |||
237 | static const struct regulator_desc tps65021_regulators[] = { | ||
238 | TPS65023_REGULATOR_DCDC(1, DCDC_FIXED_3300000_VSEL_table, 0x20), | ||
239 | TPS65023_REGULATOR_DCDC(2, DCDC_FIXED_1800000_VSEL_table, 0x10), | ||
240 | TPS65023_REGULATOR_DCDC(3, VCORE_VSEL_table, 0x08), | ||
241 | TPS65023_REGULATOR_LDO(1, TPS65023_LDO1_VSEL_table, 0x07), | ||
242 | TPS65023_REGULATOR_LDO(2, TPS65023_LDO2_VSEL_table, 0x70), | ||
243 | }; | ||
244 | |||
245 | static const struct regulator_desc tps65023_regulators[] = { | ||
246 | TPS65023_REGULATOR_DCDC(1, VCORE_VSEL_table, 0x20), | ||
247 | TPS65023_REGULATOR_DCDC(2, DCDC_FIXED_3300000_VSEL_table, 0x10), | ||
248 | TPS65023_REGULATOR_DCDC(3, DCDC_FIXED_1800000_VSEL_table, 0x08), | ||
249 | TPS65023_REGULATOR_LDO(1, TPS65023_LDO1_VSEL_table, 0x07), | ||
250 | TPS65023_REGULATOR_LDO(2, TPS65023_LDO2_VSEL_table, 0x70), | ||
251 | }; | ||
252 | |||
253 | static struct tps_driver_data tps65020_drv_data = { | ||
254 | .desc = tps65020_regulators, | ||
255 | .core_regulator = TPS65023_DCDC_3, | ||
256 | }; | ||
257 | |||
258 | static struct tps_driver_data tps65021_drv_data = { | ||
259 | .desc = tps65021_regulators, | ||
260 | .core_regulator = TPS65023_DCDC_3, | ||
261 | }; | ||
262 | |||
263 | static struct tps_driver_data tps65023_drv_data = { | ||
264 | .desc = tps65023_regulators, | ||
265 | .core_regulator = TPS65023_DCDC_1, | ||
266 | }; | ||
267 | |||
202 | static int tps_65023_probe(struct i2c_client *client, | 268 | static int tps_65023_probe(struct i2c_client *client, |
203 | const struct i2c_device_id *id) | 269 | const struct i2c_device_id *id) |
204 | { | 270 | { |
205 | const struct tps_driver_data *drv_data = (void *)id->driver_data; | 271 | struct regulator_init_data *init_data = dev_get_platdata(&client->dev); |
206 | const struct tps_info *info = drv_data->info; | ||
207 | struct regulator_config config = { }; | 272 | struct regulator_config config = { }; |
208 | struct regulator_init_data *init_data; | ||
209 | struct regulator_dev *rdev; | ||
210 | struct tps_pmic *tps; | 273 | struct tps_pmic *tps; |
211 | int i; | 274 | int i; |
212 | int error; | 275 | int error; |
213 | 276 | ||
214 | /** | ||
215 | * init_data points to array of regulator_init structures | ||
216 | * coming from the board-evm file. | ||
217 | */ | ||
218 | init_data = dev_get_platdata(&client->dev); | ||
219 | if (!init_data) | ||
220 | return -EIO; | ||
221 | |||
222 | tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); | 277 | tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); |
223 | if (!tps) | 278 | if (!tps) |
224 | return -ENOMEM; | 279 | return -ENOMEM; |
225 | 280 | ||
281 | tps->driver_data = (struct tps_driver_data *)id->driver_data; | ||
282 | |||
226 | tps->regmap = devm_regmap_init_i2c(client, &tps65023_regmap_config); | 283 | tps->regmap = devm_regmap_init_i2c(client, &tps65023_regmap_config); |
227 | if (IS_ERR(tps->regmap)) { | 284 | if (IS_ERR(tps->regmap)) { |
228 | error = PTR_ERR(tps->regmap); | 285 | error = PTR_ERR(tps->regmap); |
@@ -232,58 +289,22 @@ static int tps_65023_probe(struct i2c_client *client, | |||
232 | } | 289 | } |
233 | 290 | ||
234 | /* common for all regulators */ | 291 | /* common for all regulators */ |
235 | tps->core_regulator = drv_data->core_regulator; | 292 | config.dev = &client->dev; |
236 | 293 | config.driver_data = tps; | |
237 | for (i = 0; i < TPS65023_NUM_REGULATOR; i++, info++, init_data++) { | 294 | config.regmap = tps->regmap; |
238 | /* Store regulator specific information */ | ||
239 | tps->info[i] = info; | ||
240 | |||
241 | tps->desc[i].name = info->name; | ||
242 | tps->desc[i].id = i; | ||
243 | tps->desc[i].n_voltages = info->table_len; | ||
244 | tps->desc[i].volt_table = info->table; | ||
245 | tps->desc[i].ops = (i > TPS65023_DCDC_3 ? | ||
246 | &tps65023_ldo_ops : &tps65023_dcdc_ops); | ||
247 | tps->desc[i].type = REGULATOR_VOLTAGE; | ||
248 | tps->desc[i].owner = THIS_MODULE; | ||
249 | |||
250 | tps->desc[i].enable_reg = TPS65023_REG_REG_CTRL; | ||
251 | switch (i) { | ||
252 | case TPS65023_LDO_1: | ||
253 | tps->desc[i].vsel_reg = TPS65023_REG_LDO_CTRL; | ||
254 | tps->desc[i].vsel_mask = 0x07; | ||
255 | tps->desc[i].enable_mask = 1 << 1; | ||
256 | break; | ||
257 | case TPS65023_LDO_2: | ||
258 | tps->desc[i].vsel_reg = TPS65023_REG_LDO_CTRL; | ||
259 | tps->desc[i].vsel_mask = 0x70; | ||
260 | tps->desc[i].enable_mask = 1 << 2; | ||
261 | break; | ||
262 | default: /* DCDCx */ | ||
263 | tps->desc[i].enable_mask = | ||
264 | 1 << (TPS65023_NUM_REGULATOR - i); | ||
265 | tps->desc[i].vsel_reg = TPS65023_REG_DEF_CORE; | ||
266 | tps->desc[i].vsel_mask = info->table_len - 1; | ||
267 | tps->desc[i].apply_reg = TPS65023_REG_CON_CTRL2; | ||
268 | tps->desc[i].apply_bit = TPS65023_REG_CTRL2_GO; | ||
269 | } | ||
270 | 295 | ||
271 | config.dev = &client->dev; | 296 | for (i = 0; i < TPS65023_NUM_REGULATOR; i++) { |
272 | config.init_data = init_data; | 297 | if (init_data) |
273 | config.driver_data = tps; | 298 | config.init_data = &init_data[i]; |
274 | config.regmap = tps->regmap; | ||
275 | 299 | ||
276 | /* Register the regulators */ | 300 | /* Register the regulators */ |
277 | rdev = devm_regulator_register(&client->dev, &tps->desc[i], | 301 | tps->rdev[i] = devm_regulator_register(&client->dev, |
278 | &config); | 302 | &tps->driver_data->desc[i], &config); |
279 | if (IS_ERR(rdev)) { | 303 | if (IS_ERR(tps->rdev[i])) { |
280 | dev_err(&client->dev, "failed to register %s\n", | 304 | dev_err(&client->dev, "failed to register %s\n", |
281 | id->name); | 305 | id->name); |
282 | return PTR_ERR(rdev); | 306 | return PTR_ERR(tps->rdev[i]); |
283 | } | 307 | } |
284 | |||
285 | /* Save regulator for cleanup */ | ||
286 | tps->rdev[i] = rdev; | ||
287 | } | 308 | } |
288 | 309 | ||
289 | i2c_set_clientdata(client, tps); | 310 | i2c_set_clientdata(client, tps); |
@@ -296,120 +317,33 @@ static int tps_65023_probe(struct i2c_client *client, | |||
296 | return 0; | 317 | return 0; |
297 | } | 318 | } |
298 | 319 | ||
299 | static const struct tps_info tps65020_regs[] = { | 320 | static const struct of_device_id tps65023_of_match[] = { |
300 | { | 321 | { .compatible = "ti,tps65020", .data = &tps65020_drv_data}, |
301 | .name = "VDCDC1", | 322 | { .compatible = "ti,tps65021", .data = &tps65021_drv_data}, |
302 | .table_len = ARRAY_SIZE(DCDC_FIXED_3300000_VSEL_table), | 323 | { .compatible = "ti,tps65023", .data = &tps65023_drv_data}, |
303 | .table = DCDC_FIXED_3300000_VSEL_table, | 324 | {}, |
304 | }, | ||
305 | { | ||
306 | .name = "VDCDC2", | ||
307 | .table_len = ARRAY_SIZE(DCDC_FIXED_1800000_VSEL_table), | ||
308 | .table = DCDC_FIXED_1800000_VSEL_table, | ||
309 | }, | ||
310 | { | ||
311 | .name = "VDCDC3", | ||
312 | .table_len = ARRAY_SIZE(VCORE_VSEL_table), | ||
313 | .table = VCORE_VSEL_table, | ||
314 | }, | ||
315 | { | ||
316 | .name = "LDO1", | ||
317 | .table_len = ARRAY_SIZE(TPS65020_LDO_VSEL_table), | ||
318 | .table = TPS65020_LDO_VSEL_table, | ||
319 | }, | ||
320 | { | ||
321 | .name = "LDO2", | ||
322 | .table_len = ARRAY_SIZE(TPS65020_LDO_VSEL_table), | ||
323 | .table = TPS65020_LDO_VSEL_table, | ||
324 | }, | ||
325 | }; | ||
326 | |||
327 | static const struct tps_info tps65021_regs[] = { | ||
328 | { | ||
329 | .name = "VDCDC1", | ||
330 | .table_len = ARRAY_SIZE(DCDC_FIXED_3300000_VSEL_table), | ||
331 | .table = DCDC_FIXED_3300000_VSEL_table, | ||
332 | }, | ||
333 | { | ||
334 | .name = "VDCDC2", | ||
335 | .table_len = ARRAY_SIZE(DCDC_FIXED_1800000_VSEL_table), | ||
336 | .table = DCDC_FIXED_1800000_VSEL_table, | ||
337 | }, | ||
338 | { | ||
339 | .name = "VDCDC3", | ||
340 | .table_len = ARRAY_SIZE(VCORE_VSEL_table), | ||
341 | .table = VCORE_VSEL_table, | ||
342 | }, | ||
343 | { | ||
344 | .name = "LDO1", | ||
345 | .table_len = ARRAY_SIZE(TPS65023_LDO1_VSEL_table), | ||
346 | .table = TPS65023_LDO1_VSEL_table, | ||
347 | }, | ||
348 | { | ||
349 | .name = "LDO2", | ||
350 | .table_len = ARRAY_SIZE(TPS65023_LDO2_VSEL_table), | ||
351 | .table = TPS65023_LDO2_VSEL_table, | ||
352 | }, | ||
353 | }; | 325 | }; |
326 | MODULE_DEVICE_TABLE(of, tps65023_of_match); | ||
354 | 327 | ||
355 | static const struct tps_info tps65023_regs[] = { | 328 | static const struct i2c_device_id tps_65023_id[] = { |
356 | { | ||
357 | .name = "VDCDC1", | ||
358 | .table_len = ARRAY_SIZE(VCORE_VSEL_table), | ||
359 | .table = VCORE_VSEL_table, | ||
360 | }, | ||
361 | { | ||
362 | .name = "VDCDC2", | ||
363 | .table_len = ARRAY_SIZE(DCDC_FIXED_3300000_VSEL_table), | ||
364 | .table = DCDC_FIXED_3300000_VSEL_table, | ||
365 | }, | ||
366 | { | ||
367 | .name = "VDCDC3", | ||
368 | .table_len = ARRAY_SIZE(DCDC_FIXED_1800000_VSEL_table), | ||
369 | .table = DCDC_FIXED_1800000_VSEL_table, | ||
370 | }, | ||
371 | { | ||
372 | .name = "LDO1", | ||
373 | .table_len = ARRAY_SIZE(TPS65023_LDO1_VSEL_table), | ||
374 | .table = TPS65023_LDO1_VSEL_table, | ||
375 | }, | ||
376 | { | 329 | { |
377 | .name = "LDO2", | 330 | .name = "tps65023", |
378 | .table_len = ARRAY_SIZE(TPS65023_LDO2_VSEL_table), | 331 | .driver_data = (kernel_ulong_t)&tps65023_drv_data |
379 | .table = TPS65023_LDO2_VSEL_table, | 332 | }, { |
333 | .name = "tps65021", | ||
334 | .driver_data = (kernel_ulong_t)&tps65021_drv_data | ||
335 | }, { | ||
336 | .name = "tps65020", | ||
337 | .driver_data = (kernel_ulong_t)&tps65020_drv_data | ||
380 | }, | 338 | }, |
381 | }; | ||
382 | |||
383 | static struct tps_driver_data tps65020_drv_data = { | ||
384 | .info = tps65020_regs, | ||
385 | .core_regulator = TPS65023_DCDC_3, | ||
386 | }; | ||
387 | |||
388 | static struct tps_driver_data tps65021_drv_data = { | ||
389 | .info = tps65021_regs, | ||
390 | .core_regulator = TPS65023_DCDC_3, | ||
391 | }; | ||
392 | |||
393 | static struct tps_driver_data tps65023_drv_data = { | ||
394 | .info = tps65023_regs, | ||
395 | .core_regulator = TPS65023_DCDC_1, | ||
396 | }; | ||
397 | |||
398 | static const struct i2c_device_id tps_65023_id[] = { | ||
399 | {.name = "tps65023", | ||
400 | .driver_data = (unsigned long) &tps65023_drv_data}, | ||
401 | {.name = "tps65021", | ||
402 | .driver_data = (unsigned long) &tps65021_drv_data,}, | ||
403 | {.name = "tps65020", | ||
404 | .driver_data = (unsigned long) &tps65020_drv_data}, | ||
405 | { }, | 339 | { }, |
406 | }; | 340 | }; |
407 | |||
408 | MODULE_DEVICE_TABLE(i2c, tps_65023_id); | 341 | MODULE_DEVICE_TABLE(i2c, tps_65023_id); |
409 | 342 | ||
410 | static struct i2c_driver tps_65023_i2c_driver = { | 343 | static struct i2c_driver tps_65023_i2c_driver = { |
411 | .driver = { | 344 | .driver = { |
412 | .name = "tps65023", | 345 | .name = "tps65023", |
346 | .of_match_table = of_match_ptr(tps65023_of_match), | ||
413 | }, | 347 | }, |
414 | .probe = tps_65023_probe, | 348 | .probe = tps_65023_probe, |
415 | .id_table = tps_65023_id, | 349 | .id_table = tps_65023_id, |
diff --git a/include/linux/mfd/tps6105x.h b/include/linux/mfd/tps6105x.h index 386743dd931c..8bc51180800a 100644 --- a/include/linux/mfd/tps6105x.h +++ b/include/linux/mfd/tps6105x.h | |||
@@ -10,6 +10,7 @@ | |||
10 | #define MFD_TPS6105X_H | 10 | #define MFD_TPS6105X_H |
11 | 11 | ||
12 | #include <linux/i2c.h> | 12 | #include <linux/i2c.h> |
13 | #include <linux/regmap.h> | ||
13 | #include <linux/regulator/machine.h> | 14 | #include <linux/regulator/machine.h> |
14 | 15 | ||
15 | /* | 16 | /* |
@@ -82,20 +83,15 @@ struct tps6105x_platform_data { | |||
82 | 83 | ||
83 | /** | 84 | /** |
84 | * struct tps6105x - state holder for the TPS6105x drivers | 85 | * struct tps6105x - state holder for the TPS6105x drivers |
85 | * @mutex: mutex to serialize I2C accesses | ||
86 | * @i2c_client: corresponding I2C client | 86 | * @i2c_client: corresponding I2C client |
87 | * @regulator: regulator device if used in voltage mode | 87 | * @regulator: regulator device if used in voltage mode |
88 | * @regmap: used for i2c communcation on accessing registers | ||
88 | */ | 89 | */ |
89 | struct tps6105x { | 90 | struct tps6105x { |
90 | struct tps6105x_platform_data *pdata; | 91 | struct tps6105x_platform_data *pdata; |
91 | struct mutex lock; | ||
92 | struct i2c_client *client; | 92 | struct i2c_client *client; |
93 | struct regulator_dev *regulator; | 93 | struct regulator_dev *regulator; |
94 | struct regmap *regmap; | ||
94 | }; | 95 | }; |
95 | 96 | ||
96 | extern int tps6105x_set(struct tps6105x *tps6105x, u8 reg, u8 value); | ||
97 | extern int tps6105x_get(struct tps6105x *tps6105x, u8 reg, u8 *buf); | ||
98 | extern int tps6105x_mask_and_set(struct tps6105x *tps6105x, u8 reg, | ||
99 | u8 bitmask, u8 bitvalues); | ||
100 | |||
101 | #endif | 97 | #endif |
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index 45932228cbf5..9c2903e58adb 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h | |||
@@ -245,6 +245,7 @@ enum regulator_type { | |||
245 | * @linear_min_sel: Minimal selector for starting linear mapping | 245 | * @linear_min_sel: Minimal selector for starting linear mapping |
246 | * @fixed_uV: Fixed voltage of rails. | 246 | * @fixed_uV: Fixed voltage of rails. |
247 | * @ramp_delay: Time to settle down after voltage change (unit: uV/us) | 247 | * @ramp_delay: Time to settle down after voltage change (unit: uV/us) |
248 | * @min_dropout_uV: The minimum dropout voltage this regulator can handle | ||
248 | * @linear_ranges: A constant table of possible voltage ranges. | 249 | * @linear_ranges: A constant table of possible voltage ranges. |
249 | * @n_linear_ranges: Number of entries in the @linear_ranges table. | 250 | * @n_linear_ranges: Number of entries in the @linear_ranges table. |
250 | * @volt_table: Voltage mapping table (if table based mapping) | 251 | * @volt_table: Voltage mapping table (if table based mapping) |
@@ -292,6 +293,7 @@ struct regulator_desc { | |||
292 | unsigned int linear_min_sel; | 293 | unsigned int linear_min_sel; |
293 | int fixed_uV; | 294 | int fixed_uV; |
294 | unsigned int ramp_delay; | 295 | unsigned int ramp_delay; |
296 | int min_dropout_uV; | ||
295 | 297 | ||
296 | const struct regulator_linear_range *linear_ranges; | 298 | const struct regulator_linear_range *linear_ranges; |
297 | int n_linear_ranges; | 299 | int n_linear_ranges; |