diff options
53 files changed, 911 insertions, 467 deletions
diff --git a/Documentation/devicetree/bindings/power/power-controller.txt b/Documentation/devicetree/bindings/power/power-controller.txt new file mode 100644 index 000000000000..4f7a3bc9c407 --- /dev/null +++ b/Documentation/devicetree/bindings/power/power-controller.txt | |||
@@ -0,0 +1,18 @@ | |||
1 | * Generic system power control capability | ||
2 | |||
3 | Power-management integrated circuits or miscellaneous hardware components are | ||
4 | sometimes able to control the system power. The device driver associated with these | ||
5 | components might need to define this capability, which tells the kernel that | ||
6 | it can be used to switch off the system. The corresponding device must have the | ||
7 | standard property "system-power-controller" in its device node. This property | ||
8 | marks the device as able to control the system power. In order to test if this | ||
9 | property is found programmatically, use the helper function | ||
10 | "of_device_is_system_power_controller" from of.h . | ||
11 | |||
12 | Example: | ||
13 | |||
14 | act8846: act8846@5 { | ||
15 | compatible = "active-semi,act8846"; | ||
16 | status = "okay"; | ||
17 | system-power-controller; | ||
18 | } | ||
diff --git a/Documentation/devicetree/bindings/regulator/act8865-regulator.txt b/Documentation/devicetree/bindings/regulator/act8865-regulator.txt index 865614b34d6f..dad6358074ac 100644 --- a/Documentation/devicetree/bindings/regulator/act8865-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/act8865-regulator.txt | |||
@@ -5,6 +5,10 @@ Required properties: | |||
5 | - compatible: "active-semi,act8846" or "active-semi,act8865" | 5 | - compatible: "active-semi,act8846" or "active-semi,act8865" |
6 | - reg: I2C slave address | 6 | - reg: I2C slave address |
7 | 7 | ||
8 | Optional properties: | ||
9 | - system-power-controller: Telling whether or not this pmic is controlling | ||
10 | the system power. See Documentation/devicetree/bindings/power/power-controller.txt . | ||
11 | |||
8 | Any standard regulator properties can be used to configure the single regulator. | 12 | Any standard regulator properties can be used to configure the single regulator. |
9 | 13 | ||
10 | The valid names for regulators are: | 14 | The valid names for regulators are: |
diff --git a/Documentation/devicetree/bindings/regulator/max77802.txt b/Documentation/devicetree/bindings/regulator/max77802.txt index 5aeaffc0f1f0..79e5476444f7 100644 --- a/Documentation/devicetree/bindings/regulator/max77802.txt +++ b/Documentation/devicetree/bindings/regulator/max77802.txt | |||
@@ -25,6 +25,29 @@ with their hardware counterparts as follow. The valid names are: | |||
25 | example: LDO1, LDO2, LDO35. | 25 | example: LDO1, LDO2, LDO35. |
26 | -BUCKn : for BUCKs, where n can lie in range 1 to 10. | 26 | -BUCKn : for BUCKs, where n can lie in range 1 to 10. |
27 | example: BUCK1, BUCK5, BUCK10. | 27 | example: BUCK1, BUCK5, BUCK10. |
28 | |||
29 | The max77802 regulator supports two different operating modes: Normal and Low | ||
30 | Power Mode. Some regulators support the modes to be changed at startup or by | ||
31 | the consumers during normal operation while others only support to change the | ||
32 | mode during system suspend. The standard regulator suspend states binding can | ||
33 | be used to configure the regulator operating mode. | ||
34 | |||
35 | The regulators that support the standard "regulator-initial-mode" property, | ||
36 | changing their mode during normal operation are: LDOs 1, 3, 20 and 21. | ||
37 | |||
38 | The possible values for "regulator-initial-mode" and "regulator-mode" are: | ||
39 | 1: Normal regulator voltage output mode. | ||
40 | 3: Low Power which reduces the quiescent current down to only 1uA | ||
41 | |||
42 | The list of valid modes are defined in the dt-bindings/clock/maxim,max77802.h | ||
43 | header and can be included by device tree source files. | ||
44 | |||
45 | The standard "regulator-mode" property can only be used for regulators that | ||
46 | support changing their mode to Low Power Mode during suspend. These regulators | ||
47 | are: BUCKs 2-4 and LDOs 1-35. Also, it only takes effect if the regulator has | ||
48 | been enabled for the given suspend state using "regulator-on-in-suspend" and | ||
49 | has not been disabled for that state using "regulator-off-in-suspend". | ||
50 | |||
28 | Example: | 51 | Example: |
29 | 52 | ||
30 | max77802@09 { | 53 | max77802@09 { |
@@ -36,11 +59,23 @@ Example: | |||
36 | #size-cells = <0>; | 59 | #size-cells = <0>; |
37 | 60 | ||
38 | regulators { | 61 | regulators { |
62 | ldo1_reg: LDO1 { | ||
63 | regulator-name = "vdd_1v0"; | ||
64 | regulator-min-microvolt = <1000000>; | ||
65 | regulator-max-microvolt = <1000000>; | ||
66 | regulator-always-on; | ||
67 | regulator-initial-mode = <MAX77802_OPMODE_LP>; | ||
68 | }; | ||
69 | |||
39 | ldo11_reg: LDO11 { | 70 | ldo11_reg: LDO11 { |
40 | regulator-name = "vdd_ldo11"; | 71 | regulator-name = "vdd_ldo11"; |
41 | regulator-min-microvolt = <1900000>; | 72 | regulator-min-microvolt = <1900000>; |
42 | regulator-max-microvolt = <1900000>; | 73 | regulator-max-microvolt = <1900000>; |
43 | regulator-always-on; | 74 | regulator-always-on; |
75 | regulator-state-mem { | ||
76 | regulator-on-in-suspend; | ||
77 | regulator-mode = <MAX77802_OPMODE_LP>; | ||
78 | }; | ||
44 | }; | 79 | }; |
45 | 80 | ||
46 | buck1_reg: BUCK1 { | 81 | buck1_reg: BUCK1 { |
diff --git a/Documentation/devicetree/bindings/regulator/regulator.txt b/Documentation/devicetree/bindings/regulator/regulator.txt index 86074334e342..abb26b58c83e 100644 --- a/Documentation/devicetree/bindings/regulator/regulator.txt +++ b/Documentation/devicetree/bindings/regulator/regulator.txt | |||
@@ -19,6 +19,24 @@ Optional properties: | |||
19 | design requires. This property describes the total system ramp time | 19 | design requires. This property describes the total system ramp time |
20 | required due to the combination of internal ramping of the regulator itself, | 20 | required due to the combination of internal ramping of the regulator itself, |
21 | and board design issues such as trace capacitance and load on the supply. | 21 | and board design issues such as trace capacitance and load on the supply. |
22 | - regulator-state-mem sub-root node for Suspend-to-RAM mode | ||
23 | : suspend to memory, the device goes to sleep, but all data stored in memory, | ||
24 | only some external interrupt can wake the device. | ||
25 | - regulator-state-disk sub-root node for Suspend-to-DISK mode | ||
26 | : suspend to disk, this state operates similarly to Suspend-to-RAM, | ||
27 | but includes a final step of writing memory contents to disk. | ||
28 | - regulator-state-[mem/disk] node has following common properties: | ||
29 | - regulator-on-in-suspend: regulator should be on in suspend state. | ||
30 | - regulator-off-in-suspend: regulator should be off in suspend state. | ||
31 | - regulator-suspend-microvolt: regulator should be set to this voltage | ||
32 | in suspend. | ||
33 | - regulator-mode: operating mode in the given suspend state. | ||
34 | The set of possible operating modes depends on the capabilities of | ||
35 | every hardware so the valid modes are documented on each regulator | ||
36 | device tree binding document. | ||
37 | - regulator-initial-mode: initial operating mode. The set of possible operating | ||
38 | modes depends on the capabilities of every hardware so each device binding | ||
39 | documentation explains which values the regulator supports. | ||
22 | 40 | ||
23 | Deprecated properties: | 41 | Deprecated properties: |
24 | - regulator-compatible: If a regulator chip contains multiple | 42 | - regulator-compatible: If a regulator chip contains multiple |
@@ -34,6 +52,10 @@ Example: | |||
34 | regulator-max-microvolt = <2500000>; | 52 | regulator-max-microvolt = <2500000>; |
35 | regulator-always-on; | 53 | regulator-always-on; |
36 | vin-supply = <&vin>; | 54 | vin-supply = <&vin>; |
55 | |||
56 | regulator-state-mem { | ||
57 | regulator-on-in-suspend; | ||
58 | }; | ||
37 | }; | 59 | }; |
38 | 60 | ||
39 | Regulator Consumers: | 61 | Regulator Consumers: |
diff --git a/Documentation/devicetree/bindings/regulator/sky81452-regulator.txt b/Documentation/devicetree/bindings/regulator/sky81452-regulator.txt index 882455e9b36d..f9acbc1f3c6b 100644 --- a/Documentation/devicetree/bindings/regulator/sky81452-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/sky81452-regulator.txt | |||
@@ -1,6 +1,7 @@ | |||
1 | SKY81452 voltage regulator | 1 | SKY81452 voltage regulator |
2 | 2 | ||
3 | Required properties: | 3 | Required properties: |
4 | - regulator node named lout. | ||
4 | - any required generic properties defined in regulator.txt | 5 | - any required generic properties defined in regulator.txt |
5 | 6 | ||
6 | Optional properties: | 7 | Optional properties: |
@@ -9,8 +10,9 @@ Optional properties: | |||
9 | Example: | 10 | Example: |
10 | 11 | ||
11 | regulator { | 12 | regulator { |
12 | /* generic regulator properties */ | 13 | lout { |
13 | regulator-name = "touch_en"; | 14 | regulator-name = "sky81452-lout"; |
14 | regulator-min-microvolt = <4500000>; | 15 | regulator-min-microvolt = <4500000>; |
15 | regulator-max-microvolt = <8000000>; | 16 | regulator-max-microvolt = <8000000>; |
17 | }; | ||
16 | }; | 18 | }; |
diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c index 6d77dcd7dcf6..3fe47bd66153 100644 --- a/drivers/regulator/88pm8607.c +++ b/drivers/regulator/88pm8607.c | |||
@@ -330,7 +330,8 @@ static int pm8607_regulator_dt_init(struct platform_device *pdev, | |||
330 | for_each_child_of_node(nproot, np) { | 330 | for_each_child_of_node(nproot, np) { |
331 | if (!of_node_cmp(np->name, info->desc.name)) { | 331 | if (!of_node_cmp(np->name, info->desc.name)) { |
332 | config->init_data = | 332 | config->init_data = |
333 | of_get_regulator_init_data(&pdev->dev, np); | 333 | of_get_regulator_init_data(&pdev->dev, np, |
334 | &info->desc); | ||
334 | config->of_node = np; | 335 | config->of_node = np; |
335 | break; | 336 | break; |
336 | } | 337 | } |
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 5e061347be93..c3a60b57a865 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig | |||
@@ -521,6 +521,14 @@ config REGULATOR_RN5T618 | |||
521 | help | 521 | help |
522 | Say y here to support the regulators found on Ricoh RN5T618 PMIC. | 522 | Say y here to support the regulators found on Ricoh RN5T618 PMIC. |
523 | 523 | ||
524 | config REGULATOR_RT5033 | ||
525 | tristate "Richtek RT5033 Regulators" | ||
526 | depends on MFD_RT5033 | ||
527 | help | ||
528 | This adds support for voltage and current regulators in Richtek | ||
529 | RT5033 PMIC. The device supports multiple regulators like | ||
530 | current source, LDO and Buck. | ||
531 | |||
524 | config REGULATOR_S2MPA01 | 532 | config REGULATOR_S2MPA01 |
525 | tristate "Samsung S2MPA01 voltage regulator" | 533 | tristate "Samsung S2MPA01 voltage regulator" |
526 | depends on MFD_SEC_CORE | 534 | depends on MFD_SEC_CORE |
@@ -547,7 +555,7 @@ config REGULATOR_S5M8767 | |||
547 | 555 | ||
548 | config REGULATOR_SKY81452 | 556 | config REGULATOR_SKY81452 |
549 | tristate "Skyworks Solutions SKY81452 voltage regulator" | 557 | tristate "Skyworks Solutions SKY81452 voltage regulator" |
550 | depends on SKY81452 | 558 | depends on MFD_SKY81452 |
551 | help | 559 | help |
552 | This driver supports Skyworks SKY81452 voltage output regulator | 560 | This driver supports Skyworks SKY81452 voltage output regulator |
553 | via I2C bus. SKY81452 has one voltage linear regulator can be | 561 | via I2C bus. SKY81452 has one voltage linear regulator can be |
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 1029ed39c512..1f28ebfc6f3a 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile | |||
@@ -69,6 +69,7 @@ obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o | |||
69 | obj-$(CONFIG_REGULATOR_RC5T583) += rc5t583-regulator.o | 69 | obj-$(CONFIG_REGULATOR_RC5T583) += rc5t583-regulator.o |
70 | obj-$(CONFIG_REGULATOR_RK808) += rk808-regulator.o | 70 | obj-$(CONFIG_REGULATOR_RK808) += rk808-regulator.o |
71 | obj-$(CONFIG_REGULATOR_RN5T618) += rn5t618-regulator.o | 71 | obj-$(CONFIG_REGULATOR_RN5T618) += rn5t618-regulator.o |
72 | obj-$(CONFIG_REGULATOR_RT5033) += rt5033-regulator.o | ||
72 | obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o | 73 | obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o |
73 | obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o | 74 | obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o |
74 | obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o | 75 | obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o |
diff --git a/drivers/regulator/act8865-regulator.c b/drivers/regulator/act8865-regulator.c index afd06f92dfdf..9eec453b745d 100644 --- a/drivers/regulator/act8865-regulator.c +++ b/drivers/regulator/act8865-regulator.c | |||
@@ -61,6 +61,8 @@ | |||
61 | #define ACT8846_REG12_VSET 0xa0 | 61 | #define ACT8846_REG12_VSET 0xa0 |
62 | #define ACT8846_REG12_CTRL 0xa1 | 62 | #define ACT8846_REG12_CTRL 0xa1 |
63 | #define ACT8846_REG13_CTRL 0xb1 | 63 | #define ACT8846_REG13_CTRL 0xb1 |
64 | #define ACT8846_GLB_OFF_CTRL 0xc3 | ||
65 | #define ACT8846_OFF_SYSMASK 0x18 | ||
64 | 66 | ||
65 | /* | 67 | /* |
66 | * ACT8865 Global Register Map. | 68 | * ACT8865 Global Register Map. |
@@ -84,6 +86,7 @@ | |||
84 | #define ACT8865_LDO3_CTRL 0x61 | 86 | #define ACT8865_LDO3_CTRL 0x61 |
85 | #define ACT8865_LDO4_VSET 0x64 | 87 | #define ACT8865_LDO4_VSET 0x64 |
86 | #define ACT8865_LDO4_CTRL 0x65 | 88 | #define ACT8865_LDO4_CTRL 0x65 |
89 | #define ACT8865_MSTROFF 0x20 | ||
87 | 90 | ||
88 | /* | 91 | /* |
89 | * Field Definitions. | 92 | * Field Definitions. |
@@ -98,6 +101,8 @@ | |||
98 | 101 | ||
99 | struct act8865 { | 102 | struct act8865 { |
100 | struct regmap *regmap; | 103 | struct regmap *regmap; |
104 | int off_reg; | ||
105 | int off_mask; | ||
101 | }; | 106 | }; |
102 | 107 | ||
103 | static const struct regmap_config act8865_regmap_config = { | 108 | static const struct regmap_config act8865_regmap_config = { |
@@ -275,6 +280,16 @@ static struct regulator_init_data | |||
275 | return NULL; | 280 | return NULL; |
276 | } | 281 | } |
277 | 282 | ||
283 | static struct i2c_client *act8865_i2c_client; | ||
284 | static void act8865_power_off(void) | ||
285 | { | ||
286 | struct act8865 *act8865; | ||
287 | |||
288 | act8865 = i2c_get_clientdata(act8865_i2c_client); | ||
289 | regmap_write(act8865->regmap, act8865->off_reg, act8865->off_mask); | ||
290 | while (1); | ||
291 | } | ||
292 | |||
278 | static int act8865_pmic_probe(struct i2c_client *client, | 293 | static int act8865_pmic_probe(struct i2c_client *client, |
279 | const struct i2c_device_id *i2c_id) | 294 | const struct i2c_device_id *i2c_id) |
280 | { | 295 | { |
@@ -285,6 +300,7 @@ static int act8865_pmic_probe(struct i2c_client *client, | |||
285 | int i, ret, num_regulators; | 300 | int i, ret, num_regulators; |
286 | struct act8865 *act8865; | 301 | struct act8865 *act8865; |
287 | unsigned long type; | 302 | unsigned long type; |
303 | int off_reg, off_mask; | ||
288 | 304 | ||
289 | pdata = dev_get_platdata(dev); | 305 | pdata = dev_get_platdata(dev); |
290 | 306 | ||
@@ -304,10 +320,14 @@ static int act8865_pmic_probe(struct i2c_client *client, | |||
304 | case ACT8846: | 320 | case ACT8846: |
305 | regulators = act8846_regulators; | 321 | regulators = act8846_regulators; |
306 | num_regulators = ARRAY_SIZE(act8846_regulators); | 322 | num_regulators = ARRAY_SIZE(act8846_regulators); |
323 | off_reg = ACT8846_GLB_OFF_CTRL; | ||
324 | off_mask = ACT8846_OFF_SYSMASK; | ||
307 | break; | 325 | break; |
308 | case ACT8865: | 326 | case ACT8865: |
309 | regulators = act8865_regulators; | 327 | regulators = act8865_regulators; |
310 | num_regulators = ARRAY_SIZE(act8865_regulators); | 328 | num_regulators = ARRAY_SIZE(act8865_regulators); |
329 | off_reg = ACT8865_SYS_CTRL; | ||
330 | off_mask = ACT8865_MSTROFF; | ||
311 | break; | 331 | break; |
312 | default: | 332 | default: |
313 | dev_err(dev, "invalid device id %lu\n", type); | 333 | dev_err(dev, "invalid device id %lu\n", type); |
@@ -345,6 +365,17 @@ static int act8865_pmic_probe(struct i2c_client *client, | |||
345 | return ret; | 365 | return ret; |
346 | } | 366 | } |
347 | 367 | ||
368 | if (of_device_is_system_power_controller(dev->of_node)) { | ||
369 | if (!pm_power_off) { | ||
370 | act8865_i2c_client = client; | ||
371 | act8865->off_reg = off_reg; | ||
372 | act8865->off_mask = off_mask; | ||
373 | pm_power_off = act8865_power_off; | ||
374 | } else { | ||
375 | dev_err(dev, "Failed to set poweroff capability, already defined\n"); | ||
376 | } | ||
377 | } | ||
378 | |||
348 | /* Finally register devices */ | 379 | /* Finally register devices */ |
349 | for (i = 0; i < num_regulators; i++) { | 380 | for (i = 0; i < num_regulators; i++) { |
350 | const struct regulator_desc *desc = ®ulators[i]; | 381 | const struct regulator_desc *desc = ®ulators[i]; |
diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c index 4f730af70e7c..3586571814b2 100644 --- a/drivers/regulator/anatop-regulator.c +++ b/drivers/regulator/anatop-regulator.c | |||
@@ -189,17 +189,18 @@ static int anatop_regulator_probe(struct platform_device *pdev) | |||
189 | int ret = 0; | 189 | int ret = 0; |
190 | u32 val; | 190 | u32 val; |
191 | 191 | ||
192 | initdata = of_get_regulator_init_data(dev, np); | ||
193 | sreg = devm_kzalloc(dev, sizeof(*sreg), GFP_KERNEL); | 192 | sreg = devm_kzalloc(dev, sizeof(*sreg), GFP_KERNEL); |
194 | if (!sreg) | 193 | if (!sreg) |
195 | return -ENOMEM; | 194 | return -ENOMEM; |
196 | sreg->initdata = initdata; | ||
197 | sreg->name = of_get_property(np, "regulator-name", NULL); | 195 | sreg->name = of_get_property(np, "regulator-name", NULL); |
198 | rdesc = &sreg->rdesc; | 196 | rdesc = &sreg->rdesc; |
199 | rdesc->name = sreg->name; | 197 | rdesc->name = sreg->name; |
200 | rdesc->type = REGULATOR_VOLTAGE; | 198 | rdesc->type = REGULATOR_VOLTAGE; |
201 | rdesc->owner = THIS_MODULE; | 199 | rdesc->owner = THIS_MODULE; |
202 | 200 | ||
201 | initdata = of_get_regulator_init_data(dev, np, rdesc); | ||
202 | sreg->initdata = initdata; | ||
203 | |||
203 | anatop_np = of_get_parent(np); | 204 | anatop_np = of_get_parent(np); |
204 | if (!anatop_np) | 205 | if (!anatop_np) |
205 | return -ENODEV; | 206 | return -ENODEV; |
@@ -283,6 +284,19 @@ static int anatop_regulator_probe(struct platform_device *pdev) | |||
283 | sreg->sel = 0; | 284 | sreg->sel = 0; |
284 | sreg->bypass = true; | 285 | sreg->bypass = true; |
285 | } | 286 | } |
287 | |||
288 | /* | ||
289 | * In case vddpu was disabled by the bootloader, we need to set | ||
290 | * a sane default until imx6-cpufreq was probed and changes the | ||
291 | * voltage to the correct value. In this case we set 1.25V. | ||
292 | */ | ||
293 | if (!sreg->sel && !strcmp(sreg->name, "vddpu")) | ||
294 | sreg->sel = 22; | ||
295 | |||
296 | if (!sreg->sel) { | ||
297 | dev_err(&pdev->dev, "Failed to read a valid default voltage selector.\n"); | ||
298 | return -EINVAL; | ||
299 | } | ||
286 | } else { | 300 | } else { |
287 | rdesc->ops = &anatop_rops; | 301 | rdesc->ops = &anatop_rops; |
288 | } | 302 | } |
diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c index 4c9db589f6c1..d071b2119a60 100644 --- a/drivers/regulator/arizona-ldo1.c +++ b/drivers/regulator/arizona-ldo1.c | |||
@@ -179,7 +179,8 @@ static const struct regulator_init_data arizona_ldo1_default = { | |||
179 | }; | 179 | }; |
180 | 180 | ||
181 | static int arizona_ldo1_of_get_pdata(struct arizona *arizona, | 181 | static int arizona_ldo1_of_get_pdata(struct arizona *arizona, |
182 | struct regulator_config *config) | 182 | struct regulator_config *config, |
183 | const struct regulator_desc *desc) | ||
183 | { | 184 | { |
184 | struct arizona_pdata *pdata = &arizona->pdata; | 185 | struct arizona_pdata *pdata = &arizona->pdata; |
185 | struct arizona_ldo1 *ldo1 = config->driver_data; | 186 | struct arizona_ldo1 *ldo1 = config->driver_data; |
@@ -194,7 +195,8 @@ static int arizona_ldo1_of_get_pdata(struct arizona *arizona, | |||
194 | if (init_node) { | 195 | if (init_node) { |
195 | config->of_node = init_node; | 196 | config->of_node = init_node; |
196 | 197 | ||
197 | init_data = of_get_regulator_init_data(arizona->dev, init_node); | 198 | init_data = of_get_regulator_init_data(arizona->dev, init_node, |
199 | desc); | ||
198 | 200 | ||
199 | if (init_data) { | 201 | if (init_data) { |
200 | init_data->consumer_supplies = &ldo1->supply; | 202 | init_data->consumer_supplies = &ldo1->supply; |
@@ -257,9 +259,11 @@ static int arizona_ldo1_probe(struct platform_device *pdev) | |||
257 | 259 | ||
258 | if (IS_ENABLED(CONFIG_OF)) { | 260 | if (IS_ENABLED(CONFIG_OF)) { |
259 | if (!dev_get_platdata(arizona->dev)) { | 261 | if (!dev_get_platdata(arizona->dev)) { |
260 | ret = arizona_ldo1_of_get_pdata(arizona, &config); | 262 | ret = arizona_ldo1_of_get_pdata(arizona, &config, desc); |
261 | if (ret < 0) | 263 | if (ret < 0) |
262 | return ret; | 264 | return ret; |
265 | |||
266 | config.ena_gpio_initialized = true; | ||
263 | } | 267 | } |
264 | } | 268 | } |
265 | 269 | ||
diff --git a/drivers/regulator/arizona-micsupp.c b/drivers/regulator/arizona-micsupp.c index ce9aca5f8ee7..c313ef4c3a2f 100644 --- a/drivers/regulator/arizona-micsupp.c +++ b/drivers/regulator/arizona-micsupp.c | |||
@@ -198,7 +198,8 @@ static const struct regulator_init_data arizona_micsupp_ext_default = { | |||
198 | }; | 198 | }; |
199 | 199 | ||
200 | static int arizona_micsupp_of_get_pdata(struct arizona *arizona, | 200 | static int arizona_micsupp_of_get_pdata(struct arizona *arizona, |
201 | struct regulator_config *config) | 201 | struct regulator_config *config, |
202 | const struct regulator_desc *desc) | ||
202 | { | 203 | { |
203 | struct arizona_pdata *pdata = &arizona->pdata; | 204 | struct arizona_pdata *pdata = &arizona->pdata; |
204 | struct arizona_micsupp *micsupp = config->driver_data; | 205 | struct arizona_micsupp *micsupp = config->driver_data; |
@@ -210,7 +211,7 @@ static int arizona_micsupp_of_get_pdata(struct arizona *arizona, | |||
210 | if (np) { | 211 | if (np) { |
211 | config->of_node = np; | 212 | config->of_node = np; |
212 | 213 | ||
213 | init_data = of_get_regulator_init_data(arizona->dev, np); | 214 | init_data = of_get_regulator_init_data(arizona->dev, np, desc); |
214 | 215 | ||
215 | if (init_data) { | 216 | if (init_data) { |
216 | init_data->consumer_supplies = &micsupp->supply; | 217 | init_data->consumer_supplies = &micsupp->supply; |
@@ -264,7 +265,8 @@ static int arizona_micsupp_probe(struct platform_device *pdev) | |||
264 | 265 | ||
265 | if (IS_ENABLED(CONFIG_OF)) { | 266 | if (IS_ENABLED(CONFIG_OF)) { |
266 | if (!dev_get_platdata(arizona->dev)) { | 267 | if (!dev_get_platdata(arizona->dev)) { |
267 | ret = arizona_micsupp_of_get_pdata(arizona, &config); | 268 | ret = arizona_micsupp_of_get_pdata(arizona, &config, |
269 | desc); | ||
268 | if (ret < 0) | 270 | if (ret < 0) |
269 | return ret; | 271 | return ret; |
270 | } | 272 | } |
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index cd87c0c37034..e225711bb8bc 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
@@ -828,7 +828,7 @@ static void print_constraints(struct regulator_dev *rdev) | |||
828 | if (!count) | 828 | if (!count) |
829 | sprintf(buf, "no parameters"); | 829 | sprintf(buf, "no parameters"); |
830 | 830 | ||
831 | rdev_info(rdev, "%s\n", buf); | 831 | rdev_dbg(rdev, "%s\n", buf); |
832 | 832 | ||
833 | if ((constraints->min_uV != constraints->max_uV) && | 833 | if ((constraints->min_uV != constraints->max_uV) && |
834 | !(constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) | 834 | !(constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) |
@@ -1713,6 +1713,8 @@ static void regulator_ena_gpio_free(struct regulator_dev *rdev) | |||
1713 | gpiod_put(pin->gpiod); | 1713 | gpiod_put(pin->gpiod); |
1714 | list_del(&pin->list); | 1714 | list_del(&pin->list); |
1715 | kfree(pin); | 1715 | kfree(pin); |
1716 | rdev->ena_pin = NULL; | ||
1717 | return; | ||
1716 | } else { | 1718 | } else { |
1717 | pin->request_count--; | 1719 | pin->request_count--; |
1718 | } | 1720 | } |
@@ -1976,9 +1978,18 @@ static int _regulator_disable(struct regulator_dev *rdev) | |||
1976 | 1978 | ||
1977 | /* we are last user */ | 1979 | /* we are last user */ |
1978 | if (_regulator_can_change_status(rdev)) { | 1980 | if (_regulator_can_change_status(rdev)) { |
1981 | ret = _notifier_call_chain(rdev, | ||
1982 | REGULATOR_EVENT_PRE_DISABLE, | ||
1983 | NULL); | ||
1984 | if (ret & NOTIFY_STOP_MASK) | ||
1985 | return -EINVAL; | ||
1986 | |||
1979 | ret = _regulator_do_disable(rdev); | 1987 | ret = _regulator_do_disable(rdev); |
1980 | if (ret < 0) { | 1988 | if (ret < 0) { |
1981 | rdev_err(rdev, "failed to disable\n"); | 1989 | rdev_err(rdev, "failed to disable\n"); |
1990 | _notifier_call_chain(rdev, | ||
1991 | REGULATOR_EVENT_ABORT_DISABLE, | ||
1992 | NULL); | ||
1982 | return ret; | 1993 | return ret; |
1983 | } | 1994 | } |
1984 | _notifier_call_chain(rdev, REGULATOR_EVENT_DISABLE, | 1995 | _notifier_call_chain(rdev, REGULATOR_EVENT_DISABLE, |
@@ -2035,9 +2046,16 @@ static int _regulator_force_disable(struct regulator_dev *rdev) | |||
2035 | { | 2046 | { |
2036 | int ret = 0; | 2047 | int ret = 0; |
2037 | 2048 | ||
2049 | ret = _notifier_call_chain(rdev, REGULATOR_EVENT_FORCE_DISABLE | | ||
2050 | REGULATOR_EVENT_PRE_DISABLE, NULL); | ||
2051 | if (ret & NOTIFY_STOP_MASK) | ||
2052 | return -EINVAL; | ||
2053 | |||
2038 | ret = _regulator_do_disable(rdev); | 2054 | ret = _regulator_do_disable(rdev); |
2039 | if (ret < 0) { | 2055 | if (ret < 0) { |
2040 | rdev_err(rdev, "failed to force disable\n"); | 2056 | rdev_err(rdev, "failed to force disable\n"); |
2057 | _notifier_call_chain(rdev, REGULATOR_EVENT_FORCE_DISABLE | | ||
2058 | REGULATOR_EVENT_ABORT_DISABLE, NULL); | ||
2041 | return ret; | 2059 | return ret; |
2042 | } | 2060 | } |
2043 | 2061 | ||
@@ -3650,7 +3668,8 @@ regulator_register(const struct regulator_desc *regulator_desc, | |||
3650 | 3668 | ||
3651 | dev_set_drvdata(&rdev->dev, rdev); | 3669 | dev_set_drvdata(&rdev->dev, rdev); |
3652 | 3670 | ||
3653 | if (config->ena_gpio && gpio_is_valid(config->ena_gpio)) { | 3671 | if ((config->ena_gpio || config->ena_gpio_initialized) && |
3672 | gpio_is_valid(config->ena_gpio)) { | ||
3654 | ret = regulator_ena_gpio_request(rdev, config); | 3673 | ret = regulator_ena_gpio_request(rdev, config); |
3655 | if (ret != 0) { | 3674 | if (ret != 0) { |
3656 | rdev_err(rdev, "Failed to request enable GPIO%d: %d\n", | 3675 | rdev_err(rdev, "Failed to request enable GPIO%d: %d\n", |
diff --git a/drivers/regulator/da9052-regulator.c b/drivers/regulator/da9052-regulator.c index 00033625a09c..3945f1006d23 100644 --- a/drivers/regulator/da9052-regulator.c +++ b/drivers/regulator/da9052-regulator.c | |||
@@ -436,7 +436,8 @@ static int da9052_regulator_probe(struct platform_device *pdev) | |||
436 | if (!of_node_cmp(np->name, | 436 | if (!of_node_cmp(np->name, |
437 | regulator->info->reg_desc.name)) { | 437 | regulator->info->reg_desc.name)) { |
438 | config.init_data = of_get_regulator_init_data( | 438 | config.init_data = of_get_regulator_init_data( |
439 | &pdev->dev, np); | 439 | &pdev->dev, np, |
440 | ®ulator->info->reg_desc); | ||
440 | config.of_node = np; | 441 | config.of_node = np; |
441 | break; | 442 | break; |
442 | } | 443 | } |
diff --git a/drivers/regulator/da9063-regulator.c b/drivers/regulator/da9063-regulator.c index 7c9461d13313..37dd42759ca9 100644 --- a/drivers/regulator/da9063-regulator.c +++ b/drivers/regulator/da9063-regulator.c | |||
@@ -867,17 +867,14 @@ static int da9063_regulator_probe(struct platform_device *pdev) | |||
867 | return irq; | 867 | return irq; |
868 | } | 868 | } |
869 | 869 | ||
870 | regulators->irq_ldo_lim = regmap_irq_get_virq(da9063->regmap_irq, irq); | 870 | ret = request_threaded_irq(irq, |
871 | if (regulators->irq_ldo_lim >= 0) { | 871 | NULL, da9063_ldo_lim_event, |
872 | ret = request_threaded_irq(regulators->irq_ldo_lim, | 872 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, |
873 | NULL, da9063_ldo_lim_event, | 873 | "LDO_LIM", regulators); |
874 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, | 874 | if (ret) { |
875 | "LDO_LIM", regulators); | 875 | dev_err(&pdev->dev, |
876 | if (ret) { | 876 | "Failed to request LDO_LIM IRQ.\n"); |
877 | dev_err(&pdev->dev, | 877 | regulators->irq_ldo_lim = -ENXIO; |
878 | "Failed to request LDO_LIM IRQ.\n"); | ||
879 | regulators->irq_ldo_lim = -ENXIO; | ||
880 | } | ||
881 | } | 878 | } |
882 | 879 | ||
883 | return 0; | 880 | return 0; |
diff --git a/drivers/regulator/da9210-regulator.c b/drivers/regulator/da9210-regulator.c index 7a320dd11c46..bc6100103f7f 100644 --- a/drivers/regulator/da9210-regulator.c +++ b/drivers/regulator/da9210-regulator.c | |||
@@ -147,7 +147,7 @@ static int da9210_i2c_probe(struct i2c_client *i2c, | |||
147 | 147 | ||
148 | config.dev = &i2c->dev; | 148 | config.dev = &i2c->dev; |
149 | config.init_data = pdata ? &pdata->da9210_constraints : | 149 | config.init_data = pdata ? &pdata->da9210_constraints : |
150 | of_get_regulator_init_data(dev, dev->of_node); | 150 | of_get_regulator_init_data(dev, dev->of_node, &da9210_reg); |
151 | config.driver_data = chip; | 151 | config.driver_data = chip; |
152 | config.regmap = chip->regmap; | 152 | config.regmap = chip->regmap; |
153 | config.of_node = dev->of_node; | 153 | config.of_node = dev->of_node; |
diff --git a/drivers/regulator/dummy.c b/drivers/regulator/dummy.c index 2436db9e2ca3..7aef9e4c6fbf 100644 --- a/drivers/regulator/dummy.c +++ b/drivers/regulator/dummy.c | |||
@@ -33,7 +33,7 @@ static struct regulator_init_data dummy_initdata = { | |||
33 | 33 | ||
34 | static struct regulator_ops dummy_ops; | 34 | static struct regulator_ops dummy_ops; |
35 | 35 | ||
36 | static struct regulator_desc dummy_desc = { | 36 | static const struct regulator_desc dummy_desc = { |
37 | .name = "regulator-dummy", | 37 | .name = "regulator-dummy", |
38 | .id = -1, | 38 | .id = -1, |
39 | .type = REGULATOR_VOLTAGE, | 39 | .type = REGULATOR_VOLTAGE, |
diff --git a/drivers/regulator/fan53555.c b/drivers/regulator/fan53555.c index f8e4257aef92..6c43ab2d5121 100644 --- a/drivers/regulator/fan53555.c +++ b/drivers/regulator/fan53555.c | |||
@@ -302,7 +302,8 @@ static struct regmap_config fan53555_regmap_config = { | |||
302 | }; | 302 | }; |
303 | 303 | ||
304 | static struct fan53555_platform_data *fan53555_parse_dt(struct device *dev, | 304 | static struct fan53555_platform_data *fan53555_parse_dt(struct device *dev, |
305 | struct device_node *np) | 305 | struct device_node *np, |
306 | const struct regulator_desc *desc) | ||
306 | { | 307 | { |
307 | struct fan53555_platform_data *pdata; | 308 | struct fan53555_platform_data *pdata; |
308 | int ret; | 309 | int ret; |
@@ -312,7 +313,7 @@ static struct fan53555_platform_data *fan53555_parse_dt(struct device *dev, | |||
312 | if (!pdata) | 313 | if (!pdata) |
313 | return NULL; | 314 | return NULL; |
314 | 315 | ||
315 | pdata->regulator = of_get_regulator_init_data(dev, np); | 316 | pdata->regulator = of_get_regulator_init_data(dev, np, desc); |
316 | 317 | ||
317 | ret = of_property_read_u32(np, "fcs,suspend-voltage-selector", | 318 | ret = of_property_read_u32(np, "fcs,suspend-voltage-selector", |
318 | &tmp); | 319 | &tmp); |
@@ -347,20 +348,20 @@ static int fan53555_regulator_probe(struct i2c_client *client, | |||
347 | unsigned int val; | 348 | unsigned int val; |
348 | int ret; | 349 | int ret; |
349 | 350 | ||
351 | di = devm_kzalloc(&client->dev, sizeof(struct fan53555_device_info), | ||
352 | GFP_KERNEL); | ||
353 | if (!di) | ||
354 | return -ENOMEM; | ||
355 | |||
350 | pdata = dev_get_platdata(&client->dev); | 356 | pdata = dev_get_platdata(&client->dev); |
351 | if (!pdata) | 357 | if (!pdata) |
352 | pdata = fan53555_parse_dt(&client->dev, np); | 358 | pdata = fan53555_parse_dt(&client->dev, np, &di->desc); |
353 | 359 | ||
354 | if (!pdata || !pdata->regulator) { | 360 | if (!pdata || !pdata->regulator) { |
355 | dev_err(&client->dev, "Platform data not found!\n"); | 361 | dev_err(&client->dev, "Platform data not found!\n"); |
356 | return -ENODEV; | 362 | return -ENODEV; |
357 | } | 363 | } |
358 | 364 | ||
359 | di = devm_kzalloc(&client->dev, sizeof(struct fan53555_device_info), | ||
360 | GFP_KERNEL); | ||
361 | if (!di) | ||
362 | return -ENOMEM; | ||
363 | |||
364 | di->regulator = pdata->regulator; | 365 | di->regulator = pdata->regulator; |
365 | if (client->dev.of_node) { | 366 | if (client->dev.of_node) { |
366 | const struct of_device_id *match; | 367 | const struct of_device_id *match; |
diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c index 354105eff1f8..d21da27c0eb6 100644 --- a/drivers/regulator/fixed.c +++ b/drivers/regulator/fixed.c | |||
@@ -40,13 +40,15 @@ struct fixed_voltage_data { | |||
40 | /** | 40 | /** |
41 | * of_get_fixed_voltage_config - extract fixed_voltage_config structure info | 41 | * of_get_fixed_voltage_config - extract fixed_voltage_config structure info |
42 | * @dev: device requesting for fixed_voltage_config | 42 | * @dev: device requesting for fixed_voltage_config |
43 | * @desc: regulator description | ||
43 | * | 44 | * |
44 | * Populates fixed_voltage_config structure by extracting data from device | 45 | * Populates fixed_voltage_config structure by extracting data from device |
45 | * tree node, returns a pointer to the populated structure of NULL if memory | 46 | * tree node, returns a pointer to the populated structure of NULL if memory |
46 | * alloc fails. | 47 | * alloc fails. |
47 | */ | 48 | */ |
48 | static struct fixed_voltage_config * | 49 | static struct fixed_voltage_config * |
49 | of_get_fixed_voltage_config(struct device *dev) | 50 | of_get_fixed_voltage_config(struct device *dev, |
51 | const struct regulator_desc *desc) | ||
50 | { | 52 | { |
51 | struct fixed_voltage_config *config; | 53 | struct fixed_voltage_config *config; |
52 | struct device_node *np = dev->of_node; | 54 | struct device_node *np = dev->of_node; |
@@ -57,7 +59,7 @@ of_get_fixed_voltage_config(struct device *dev) | |||
57 | if (!config) | 59 | if (!config) |
58 | return ERR_PTR(-ENOMEM); | 60 | return ERR_PTR(-ENOMEM); |
59 | 61 | ||
60 | config->init_data = of_get_regulator_init_data(dev, dev->of_node); | 62 | config->init_data = of_get_regulator_init_data(dev, dev->of_node, desc); |
61 | if (!config->init_data) | 63 | if (!config->init_data) |
62 | return ERR_PTR(-EINVAL); | 64 | return ERR_PTR(-EINVAL); |
63 | 65 | ||
@@ -112,8 +114,14 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev) | |||
112 | struct regulator_config cfg = { }; | 114 | struct regulator_config cfg = { }; |
113 | int ret; | 115 | int ret; |
114 | 116 | ||
117 | drvdata = devm_kzalloc(&pdev->dev, sizeof(struct fixed_voltage_data), | ||
118 | GFP_KERNEL); | ||
119 | if (!drvdata) | ||
120 | return -ENOMEM; | ||
121 | |||
115 | if (pdev->dev.of_node) { | 122 | if (pdev->dev.of_node) { |
116 | config = of_get_fixed_voltage_config(&pdev->dev); | 123 | config = of_get_fixed_voltage_config(&pdev->dev, |
124 | &drvdata->desc); | ||
117 | if (IS_ERR(config)) | 125 | if (IS_ERR(config)) |
118 | return PTR_ERR(config); | 126 | return PTR_ERR(config); |
119 | } else { | 127 | } else { |
@@ -123,11 +131,6 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev) | |||
123 | if (!config) | 131 | if (!config) |
124 | return -ENOMEM; | 132 | return -ENOMEM; |
125 | 133 | ||
126 | drvdata = devm_kzalloc(&pdev->dev, sizeof(struct fixed_voltage_data), | ||
127 | GFP_KERNEL); | ||
128 | if (!drvdata) | ||
129 | return -ENOMEM; | ||
130 | |||
131 | drvdata->desc.name = devm_kstrdup(&pdev->dev, | 134 | drvdata->desc.name = devm_kstrdup(&pdev->dev, |
132 | config->supply_name, | 135 | config->supply_name, |
133 | GFP_KERNEL); | 136 | GFP_KERNEL); |
@@ -157,8 +160,11 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev) | |||
157 | 160 | ||
158 | drvdata->desc.fixed_uV = config->microvolts; | 161 | drvdata->desc.fixed_uV = config->microvolts; |
159 | 162 | ||
160 | if (config->gpio >= 0) | 163 | if (gpio_is_valid(config->gpio)) { |
161 | cfg.ena_gpio = config->gpio; | 164 | cfg.ena_gpio = config->gpio; |
165 | if (pdev->dev.of_node) | ||
166 | cfg.ena_gpio_initialized = true; | ||
167 | } | ||
162 | cfg.ena_gpio_invert = !config->enable_high; | 168 | cfg.ena_gpio_invert = !config->enable_high; |
163 | if (config->enabled_at_boot) { | 169 | if (config->enabled_at_boot) { |
164 | if (config->enable_high) | 170 | if (config->enable_high) |
diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c index 989b23b377c0..c888a9a9482c 100644 --- a/drivers/regulator/gpio-regulator.c +++ b/drivers/regulator/gpio-regulator.c | |||
@@ -133,7 +133,8 @@ static struct regulator_ops gpio_regulator_voltage_ops = { | |||
133 | }; | 133 | }; |
134 | 134 | ||
135 | static struct gpio_regulator_config * | 135 | static struct gpio_regulator_config * |
136 | of_get_gpio_regulator_config(struct device *dev, struct device_node *np) | 136 | of_get_gpio_regulator_config(struct device *dev, struct device_node *np, |
137 | const struct regulator_desc *desc) | ||
137 | { | 138 | { |
138 | struct gpio_regulator_config *config; | 139 | struct gpio_regulator_config *config; |
139 | const char *regtype; | 140 | const char *regtype; |
@@ -146,7 +147,7 @@ of_get_gpio_regulator_config(struct device *dev, struct device_node *np) | |||
146 | if (!config) | 147 | if (!config) |
147 | return ERR_PTR(-ENOMEM); | 148 | return ERR_PTR(-ENOMEM); |
148 | 149 | ||
149 | config->init_data = of_get_regulator_init_data(dev, np); | 150 | config->init_data = of_get_regulator_init_data(dev, np, desc); |
150 | if (!config->init_data) | 151 | if (!config->init_data) |
151 | return ERR_PTR(-EINVAL); | 152 | return ERR_PTR(-EINVAL); |
152 | 153 | ||
@@ -162,34 +163,41 @@ of_get_gpio_regulator_config(struct device *dev, struct device_node *np) | |||
162 | 163 | ||
163 | config->enable_gpio = of_get_named_gpio(np, "enable-gpio", 0); | 164 | config->enable_gpio = of_get_named_gpio(np, "enable-gpio", 0); |
164 | 165 | ||
165 | /* Fetch GPIOs. */ | 166 | /* Fetch GPIOs. - optional property*/ |
166 | config->nr_gpios = of_gpio_count(np); | 167 | ret = of_gpio_count(np); |
167 | 168 | if ((ret < 0) && (ret != -ENOENT)) | |
168 | config->gpios = devm_kzalloc(dev, | 169 | return ERR_PTR(ret); |
169 | sizeof(struct gpio) * config->nr_gpios, | 170 | |
170 | GFP_KERNEL); | 171 | if (ret > 0) { |
171 | if (!config->gpios) | 172 | config->nr_gpios = ret; |
172 | return ERR_PTR(-ENOMEM); | 173 | config->gpios = devm_kzalloc(dev, |
173 | 174 | sizeof(struct gpio) * config->nr_gpios, | |
174 | proplen = of_property_count_u32_elems(np, "gpios-states"); | 175 | GFP_KERNEL); |
175 | /* optional property */ | 176 | if (!config->gpios) |
176 | if (proplen < 0) | 177 | return ERR_PTR(-ENOMEM); |
177 | proplen = 0; | 178 | |
178 | 179 | proplen = of_property_count_u32_elems(np, "gpios-states"); | |
179 | if (proplen > 0 && proplen != config->nr_gpios) { | 180 | /* optional property */ |
180 | dev_warn(dev, "gpios <-> gpios-states mismatch\n"); | 181 | if (proplen < 0) |
181 | proplen = 0; | 182 | proplen = 0; |
182 | } | 183 | |
184 | if (proplen > 0 && proplen != config->nr_gpios) { | ||
185 | dev_warn(dev, "gpios <-> gpios-states mismatch\n"); | ||
186 | proplen = 0; | ||
187 | } | ||
183 | 188 | ||
184 | for (i = 0; i < config->nr_gpios; i++) { | 189 | for (i = 0; i < config->nr_gpios; i++) { |
185 | gpio = of_get_named_gpio(np, "gpios", i); | 190 | gpio = of_get_named_gpio(np, "gpios", i); |
186 | if (gpio < 0) | 191 | if (gpio < 0) |
187 | break; | 192 | break; |
188 | config->gpios[i].gpio = gpio; | 193 | config->gpios[i].gpio = gpio; |
189 | if (proplen > 0) { | 194 | if (proplen > 0) { |
190 | of_property_read_u32_index(np, "gpios-states", i, &ret); | 195 | of_property_read_u32_index(np, "gpios-states", |
191 | if (ret) | 196 | i, &ret); |
192 | config->gpios[i].flags = GPIOF_OUT_INIT_HIGH; | 197 | if (ret) |
198 | config->gpios[i].flags = | ||
199 | GPIOF_OUT_INIT_HIGH; | ||
200 | } | ||
193 | } | 201 | } |
194 | } | 202 | } |
195 | 203 | ||
@@ -243,17 +251,18 @@ static int gpio_regulator_probe(struct platform_device *pdev) | |||
243 | struct regulator_config cfg = { }; | 251 | struct regulator_config cfg = { }; |
244 | int ptr, ret, state; | 252 | int ptr, ret, state; |
245 | 253 | ||
246 | if (np) { | ||
247 | config = of_get_gpio_regulator_config(&pdev->dev, np); | ||
248 | if (IS_ERR(config)) | ||
249 | return PTR_ERR(config); | ||
250 | } | ||
251 | |||
252 | drvdata = devm_kzalloc(&pdev->dev, sizeof(struct gpio_regulator_data), | 254 | drvdata = devm_kzalloc(&pdev->dev, sizeof(struct gpio_regulator_data), |
253 | GFP_KERNEL); | 255 | GFP_KERNEL); |
254 | if (drvdata == NULL) | 256 | if (drvdata == NULL) |
255 | return -ENOMEM; | 257 | return -ENOMEM; |
256 | 258 | ||
259 | if (np) { | ||
260 | config = of_get_gpio_regulator_config(&pdev->dev, np, | ||
261 | &drvdata->desc); | ||
262 | if (IS_ERR(config)) | ||
263 | return PTR_ERR(config); | ||
264 | } | ||
265 | |||
257 | drvdata->desc.name = kstrdup(config->supply_name, GFP_KERNEL); | 266 | drvdata->desc.name = kstrdup(config->supply_name, GFP_KERNEL); |
258 | if (drvdata->desc.name == NULL) { | 267 | if (drvdata->desc.name == NULL) { |
259 | dev_err(&pdev->dev, "Failed to allocate supply name\n"); | 268 | dev_err(&pdev->dev, "Failed to allocate supply name\n"); |
@@ -261,13 +270,23 @@ static int gpio_regulator_probe(struct platform_device *pdev) | |||
261 | goto err; | 270 | goto err; |
262 | } | 271 | } |
263 | 272 | ||
264 | drvdata->gpios = kmemdup(config->gpios, | 273 | if (config->nr_gpios != 0) { |
265 | config->nr_gpios * sizeof(struct gpio), | 274 | drvdata->gpios = kmemdup(config->gpios, |
266 | GFP_KERNEL); | 275 | config->nr_gpios * sizeof(struct gpio), |
267 | if (drvdata->gpios == NULL) { | 276 | GFP_KERNEL); |
268 | dev_err(&pdev->dev, "Failed to allocate gpio data\n"); | 277 | if (drvdata->gpios == NULL) { |
269 | ret = -ENOMEM; | 278 | dev_err(&pdev->dev, "Failed to allocate gpio data\n"); |
270 | goto err_name; | 279 | ret = -ENOMEM; |
280 | goto err_name; | ||
281 | } | ||
282 | |||
283 | drvdata->nr_gpios = config->nr_gpios; | ||
284 | ret = gpio_request_array(drvdata->gpios, drvdata->nr_gpios); | ||
285 | if (ret) { | ||
286 | dev_err(&pdev->dev, | ||
287 | "Could not obtain regulator setting GPIOs: %d\n", ret); | ||
288 | goto err_memstate; | ||
289 | } | ||
271 | } | 290 | } |
272 | 291 | ||
273 | drvdata->states = kmemdup(config->states, | 292 | drvdata->states = kmemdup(config->states, |
@@ -301,14 +320,6 @@ static int gpio_regulator_probe(struct platform_device *pdev) | |||
301 | goto err_memgpio; | 320 | goto err_memgpio; |
302 | } | 321 | } |
303 | 322 | ||
304 | drvdata->nr_gpios = config->nr_gpios; | ||
305 | ret = gpio_request_array(drvdata->gpios, drvdata->nr_gpios); | ||
306 | if (ret) { | ||
307 | dev_err(&pdev->dev, | ||
308 | "Could not obtain regulator setting GPIOs: %d\n", ret); | ||
309 | goto err_memstate; | ||
310 | } | ||
311 | |||
312 | /* build initial state from gpio init data. */ | 323 | /* build initial state from gpio init data. */ |
313 | state = 0; | 324 | state = 0; |
314 | for (ptr = 0; ptr < drvdata->nr_gpios; ptr++) { | 325 | for (ptr = 0; ptr < drvdata->nr_gpios; ptr++) { |
@@ -322,8 +333,10 @@ static int gpio_regulator_probe(struct platform_device *pdev) | |||
322 | cfg.driver_data = drvdata; | 333 | cfg.driver_data = drvdata; |
323 | cfg.of_node = np; | 334 | cfg.of_node = np; |
324 | 335 | ||
325 | if (config->enable_gpio >= 0) | 336 | if (gpio_is_valid(config->enable_gpio)) { |
326 | cfg.ena_gpio = config->enable_gpio; | 337 | cfg.ena_gpio = config->enable_gpio; |
338 | cfg.ena_gpio_initialized = true; | ||
339 | } | ||
327 | cfg.ena_gpio_invert = !config->enable_high; | 340 | cfg.ena_gpio_invert = !config->enable_high; |
328 | if (config->enabled_at_boot) { | 341 | if (config->enabled_at_boot) { |
329 | if (config->enable_high) | 342 | if (config->enable_high) |
diff --git a/drivers/regulator/max77686.c b/drivers/regulator/max77686.c index f69320e1738f..871b96bcd2d0 100644 --- a/drivers/regulator/max77686.c +++ b/drivers/regulator/max77686.c | |||
@@ -45,6 +45,23 @@ | |||
45 | #define MAX77686_DVS_MINUV 600000 | 45 | #define MAX77686_DVS_MINUV 600000 |
46 | #define MAX77686_DVS_UVSTEP 12500 | 46 | #define MAX77686_DVS_UVSTEP 12500 |
47 | 47 | ||
48 | /* | ||
49 | * Values used for configuring LDOs and bucks. | ||
50 | * Forcing low power mode: LDO1, 3-5, 9, 13, 17-26 | ||
51 | */ | ||
52 | #define MAX77686_LDO_LOWPOWER 0x1 | ||
53 | /* | ||
54 | * On/off controlled by PWRREQ: | ||
55 | * - LDO2, 6-8, 10-12, 14-16 | ||
56 | * - buck[1234] | ||
57 | */ | ||
58 | #define MAX77686_OFF_PWRREQ 0x1 | ||
59 | /* Low power mode controlled by PWRREQ: All LDOs */ | ||
60 | #define MAX77686_LDO_LOWPOWER_PWRREQ 0x2 | ||
61 | /* Forcing low power mode: buck[234] */ | ||
62 | #define MAX77686_BUCK_LOWPOWER 0x2 | ||
63 | #define MAX77686_NORMAL 0x3 | ||
64 | |||
48 | #define MAX77686_OPMODE_SHIFT 6 | 65 | #define MAX77686_OPMODE_SHIFT 6 |
49 | #define MAX77686_OPMODE_BUCK234_SHIFT 4 | 66 | #define MAX77686_OPMODE_BUCK234_SHIFT 4 |
50 | #define MAX77686_OPMODE_MASK 0x3 | 67 | #define MAX77686_OPMODE_MASK 0x3 |
@@ -65,23 +82,36 @@ enum max77686_ramp_rate { | |||
65 | }; | 82 | }; |
66 | 83 | ||
67 | struct max77686_data { | 84 | struct max77686_data { |
85 | /* Array indexed by regulator id */ | ||
68 | unsigned int opmode[MAX77686_REGULATORS]; | 86 | unsigned int opmode[MAX77686_REGULATORS]; |
69 | }; | 87 | }; |
70 | 88 | ||
71 | /* Some BUCKS supports Normal[ON/OFF] mode during suspend */ | 89 | static unsigned int max77686_get_opmode_shift(int id) |
72 | static int max77686_buck_set_suspend_disable(struct regulator_dev *rdev) | ||
73 | { | 90 | { |
74 | unsigned int val; | 91 | switch (id) { |
92 | case MAX77686_BUCK1: | ||
93 | case MAX77686_BUCK5 ... MAX77686_BUCK9: | ||
94 | return 0; | ||
95 | case MAX77686_BUCK2 ... MAX77686_BUCK4: | ||
96 | return MAX77686_OPMODE_BUCK234_SHIFT; | ||
97 | default: | ||
98 | /* all LDOs */ | ||
99 | return MAX77686_OPMODE_SHIFT; | ||
100 | } | ||
101 | } | ||
102 | |||
103 | /* Some BUCKs and LDOs supports Normal[ON/OFF] mode during suspend */ | ||
104 | static int max77686_set_suspend_disable(struct regulator_dev *rdev) | ||
105 | { | ||
106 | unsigned int val, shift; | ||
75 | struct max77686_data *max77686 = rdev_get_drvdata(rdev); | 107 | struct max77686_data *max77686 = rdev_get_drvdata(rdev); |
76 | int ret, id = rdev_get_id(rdev); | 108 | int ret, id = rdev_get_id(rdev); |
77 | 109 | ||
78 | if (id == MAX77686_BUCK1) | 110 | shift = max77686_get_opmode_shift(id); |
79 | val = 0x1; | 111 | val = MAX77686_OFF_PWRREQ; |
80 | else | ||
81 | val = 0x1 << MAX77686_OPMODE_BUCK234_SHIFT; | ||
82 | 112 | ||
83 | ret = regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | 113 | ret = regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, |
84 | rdev->desc->enable_mask, val); | 114 | rdev->desc->enable_mask, val << shift); |
85 | if (ret) | 115 | if (ret) |
86 | return ret; | 116 | return ret; |
87 | 117 | ||
@@ -103,10 +133,10 @@ static int max77686_set_suspend_mode(struct regulator_dev *rdev, | |||
103 | 133 | ||
104 | switch (mode) { | 134 | switch (mode) { |
105 | case REGULATOR_MODE_IDLE: /* ON in LP Mode */ | 135 | case REGULATOR_MODE_IDLE: /* ON in LP Mode */ |
106 | val = 0x2 << MAX77686_OPMODE_SHIFT; | 136 | val = MAX77686_LDO_LOWPOWER_PWRREQ; |
107 | break; | 137 | break; |
108 | case REGULATOR_MODE_NORMAL: /* ON in Normal Mode */ | 138 | case REGULATOR_MODE_NORMAL: /* ON in Normal Mode */ |
109 | val = 0x3 << MAX77686_OPMODE_SHIFT; | 139 | val = MAX77686_NORMAL; |
110 | break; | 140 | break; |
111 | default: | 141 | default: |
112 | pr_warn("%s: regulator_suspend_mode : 0x%x not supported\n", | 142 | pr_warn("%s: regulator_suspend_mode : 0x%x not supported\n", |
@@ -115,7 +145,8 @@ static int max77686_set_suspend_mode(struct regulator_dev *rdev, | |||
115 | } | 145 | } |
116 | 146 | ||
117 | ret = regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | 147 | ret = regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, |
118 | rdev->desc->enable_mask, val); | 148 | rdev->desc->enable_mask, |
149 | val << MAX77686_OPMODE_SHIFT); | ||
119 | if (ret) | 150 | if (ret) |
120 | return ret; | 151 | return ret; |
121 | 152 | ||
@@ -133,13 +164,13 @@ static int max77686_ldo_set_suspend_mode(struct regulator_dev *rdev, | |||
133 | 164 | ||
134 | switch (mode) { | 165 | switch (mode) { |
135 | case REGULATOR_MODE_STANDBY: /* switch off */ | 166 | case REGULATOR_MODE_STANDBY: /* switch off */ |
136 | val = 0x1 << MAX77686_OPMODE_SHIFT; | 167 | val = MAX77686_OFF_PWRREQ; |
137 | break; | 168 | break; |
138 | case REGULATOR_MODE_IDLE: /* ON in LP Mode */ | 169 | case REGULATOR_MODE_IDLE: /* ON in LP Mode */ |
139 | val = 0x2 << MAX77686_OPMODE_SHIFT; | 170 | val = MAX77686_LDO_LOWPOWER_PWRREQ; |
140 | break; | 171 | break; |
141 | case REGULATOR_MODE_NORMAL: /* ON in Normal Mode */ | 172 | case REGULATOR_MODE_NORMAL: /* ON in Normal Mode */ |
142 | val = 0x3 << MAX77686_OPMODE_SHIFT; | 173 | val = MAX77686_NORMAL; |
143 | break; | 174 | break; |
144 | default: | 175 | default: |
145 | pr_warn("%s: regulator_suspend_mode : 0x%x not supported\n", | 176 | pr_warn("%s: regulator_suspend_mode : 0x%x not supported\n", |
@@ -148,7 +179,8 @@ static int max77686_ldo_set_suspend_mode(struct regulator_dev *rdev, | |||
148 | } | 179 | } |
149 | 180 | ||
150 | ret = regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | 181 | ret = regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, |
151 | rdev->desc->enable_mask, val); | 182 | rdev->desc->enable_mask, |
183 | val << MAX77686_OPMODE_SHIFT); | ||
152 | if (ret) | 184 | if (ret) |
153 | return ret; | 185 | return ret; |
154 | 186 | ||
@@ -159,10 +191,17 @@ static int max77686_ldo_set_suspend_mode(struct regulator_dev *rdev, | |||
159 | static int max77686_enable(struct regulator_dev *rdev) | 191 | static int max77686_enable(struct regulator_dev *rdev) |
160 | { | 192 | { |
161 | struct max77686_data *max77686 = rdev_get_drvdata(rdev); | 193 | struct max77686_data *max77686 = rdev_get_drvdata(rdev); |
194 | unsigned int shift; | ||
195 | int id = rdev_get_id(rdev); | ||
196 | |||
197 | shift = max77686_get_opmode_shift(id); | ||
198 | |||
199 | if (max77686->opmode[id] == MAX77686_OFF_PWRREQ) | ||
200 | max77686->opmode[id] = MAX77686_NORMAL; | ||
162 | 201 | ||
163 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | 202 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, |
164 | rdev->desc->enable_mask, | 203 | rdev->desc->enable_mask, |
165 | max77686->opmode[rdev_get_id(rdev)]); | 204 | max77686->opmode[id] << shift); |
166 | } | 205 | } |
167 | 206 | ||
168 | static int max77686_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) | 207 | static int max77686_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) |
@@ -212,6 +251,7 @@ static struct regulator_ops max77686_ldo_ops = { | |||
212 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | 251 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
213 | .set_voltage_time_sel = regulator_set_voltage_time_sel, | 252 | .set_voltage_time_sel = regulator_set_voltage_time_sel, |
214 | .set_suspend_mode = max77686_ldo_set_suspend_mode, | 253 | .set_suspend_mode = max77686_ldo_set_suspend_mode, |
254 | .set_suspend_disable = max77686_set_suspend_disable, | ||
215 | }; | 255 | }; |
216 | 256 | ||
217 | static struct regulator_ops max77686_buck1_ops = { | 257 | static struct regulator_ops max77686_buck1_ops = { |
@@ -223,7 +263,7 @@ static struct regulator_ops max77686_buck1_ops = { | |||
223 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | 263 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
224 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | 264 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
225 | .set_voltage_time_sel = regulator_set_voltage_time_sel, | 265 | .set_voltage_time_sel = regulator_set_voltage_time_sel, |
226 | .set_suspend_disable = max77686_buck_set_suspend_disable, | 266 | .set_suspend_disable = max77686_set_suspend_disable, |
227 | }; | 267 | }; |
228 | 268 | ||
229 | static struct regulator_ops max77686_buck_dvs_ops = { | 269 | static struct regulator_ops max77686_buck_dvs_ops = { |
@@ -236,11 +276,13 @@ static struct regulator_ops max77686_buck_dvs_ops = { | |||
236 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | 276 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
237 | .set_voltage_time_sel = regulator_set_voltage_time_sel, | 277 | .set_voltage_time_sel = regulator_set_voltage_time_sel, |
238 | .set_ramp_delay = max77686_set_ramp_delay, | 278 | .set_ramp_delay = max77686_set_ramp_delay, |
239 | .set_suspend_disable = max77686_buck_set_suspend_disable, | 279 | .set_suspend_disable = max77686_set_suspend_disable, |
240 | }; | 280 | }; |
241 | 281 | ||
242 | #define regulator_desc_ldo(num) { \ | 282 | #define regulator_desc_ldo(num) { \ |
243 | .name = "LDO"#num, \ | 283 | .name = "LDO"#num, \ |
284 | .of_match = of_match_ptr("LDO"#num), \ | ||
285 | .regulators_node = of_match_ptr("voltage-regulators"), \ | ||
244 | .id = MAX77686_LDO##num, \ | 286 | .id = MAX77686_LDO##num, \ |
245 | .ops = &max77686_ops, \ | 287 | .ops = &max77686_ops, \ |
246 | .type = REGULATOR_VOLTAGE, \ | 288 | .type = REGULATOR_VOLTAGE, \ |
@@ -257,6 +299,8 @@ static struct regulator_ops max77686_buck_dvs_ops = { | |||
257 | } | 299 | } |
258 | #define regulator_desc_lpm_ldo(num) { \ | 300 | #define regulator_desc_lpm_ldo(num) { \ |
259 | .name = "LDO"#num, \ | 301 | .name = "LDO"#num, \ |
302 | .of_match = of_match_ptr("LDO"#num), \ | ||
303 | .regulators_node = of_match_ptr("voltage-regulators"), \ | ||
260 | .id = MAX77686_LDO##num, \ | 304 | .id = MAX77686_LDO##num, \ |
261 | .ops = &max77686_ldo_ops, \ | 305 | .ops = &max77686_ldo_ops, \ |
262 | .type = REGULATOR_VOLTAGE, \ | 306 | .type = REGULATOR_VOLTAGE, \ |
@@ -273,6 +317,8 @@ static struct regulator_ops max77686_buck_dvs_ops = { | |||
273 | } | 317 | } |
274 | #define regulator_desc_ldo_low(num) { \ | 318 | #define regulator_desc_ldo_low(num) { \ |
275 | .name = "LDO"#num, \ | 319 | .name = "LDO"#num, \ |
320 | .of_match = of_match_ptr("LDO"#num), \ | ||
321 | .regulators_node = of_match_ptr("voltage-regulators"), \ | ||
276 | .id = MAX77686_LDO##num, \ | 322 | .id = MAX77686_LDO##num, \ |
277 | .ops = &max77686_ldo_ops, \ | 323 | .ops = &max77686_ldo_ops, \ |
278 | .type = REGULATOR_VOLTAGE, \ | 324 | .type = REGULATOR_VOLTAGE, \ |
@@ -289,6 +335,8 @@ static struct regulator_ops max77686_buck_dvs_ops = { | |||
289 | } | 335 | } |
290 | #define regulator_desc_ldo1_low(num) { \ | 336 | #define regulator_desc_ldo1_low(num) { \ |
291 | .name = "LDO"#num, \ | 337 | .name = "LDO"#num, \ |
338 | .of_match = of_match_ptr("LDO"#num), \ | ||
339 | .regulators_node = of_match_ptr("voltage-regulators"), \ | ||
292 | .id = MAX77686_LDO##num, \ | 340 | .id = MAX77686_LDO##num, \ |
293 | .ops = &max77686_ops, \ | 341 | .ops = &max77686_ops, \ |
294 | .type = REGULATOR_VOLTAGE, \ | 342 | .type = REGULATOR_VOLTAGE, \ |
@@ -305,6 +353,8 @@ static struct regulator_ops max77686_buck_dvs_ops = { | |||
305 | } | 353 | } |
306 | #define regulator_desc_buck(num) { \ | 354 | #define regulator_desc_buck(num) { \ |
307 | .name = "BUCK"#num, \ | 355 | .name = "BUCK"#num, \ |
356 | .of_match = of_match_ptr("BUCK"#num), \ | ||
357 | .regulators_node = of_match_ptr("voltage-regulators"), \ | ||
308 | .id = MAX77686_BUCK##num, \ | 358 | .id = MAX77686_BUCK##num, \ |
309 | .ops = &max77686_ops, \ | 359 | .ops = &max77686_ops, \ |
310 | .type = REGULATOR_VOLTAGE, \ | 360 | .type = REGULATOR_VOLTAGE, \ |
@@ -320,6 +370,8 @@ static struct regulator_ops max77686_buck_dvs_ops = { | |||
320 | } | 370 | } |
321 | #define regulator_desc_buck1(num) { \ | 371 | #define regulator_desc_buck1(num) { \ |
322 | .name = "BUCK"#num, \ | 372 | .name = "BUCK"#num, \ |
373 | .of_match = of_match_ptr("BUCK"#num), \ | ||
374 | .regulators_node = of_match_ptr("voltage-regulators"), \ | ||
323 | .id = MAX77686_BUCK##num, \ | 375 | .id = MAX77686_BUCK##num, \ |
324 | .ops = &max77686_buck1_ops, \ | 376 | .ops = &max77686_buck1_ops, \ |
325 | .type = REGULATOR_VOLTAGE, \ | 377 | .type = REGULATOR_VOLTAGE, \ |
@@ -335,6 +387,8 @@ static struct regulator_ops max77686_buck_dvs_ops = { | |||
335 | } | 387 | } |
336 | #define regulator_desc_buck_dvs(num) { \ | 388 | #define regulator_desc_buck_dvs(num) { \ |
337 | .name = "BUCK"#num, \ | 389 | .name = "BUCK"#num, \ |
390 | .of_match = of_match_ptr("BUCK"#num), \ | ||
391 | .regulators_node = of_match_ptr("voltage-regulators"), \ | ||
338 | .id = MAX77686_BUCK##num, \ | 392 | .id = MAX77686_BUCK##num, \ |
339 | .ops = &max77686_buck_dvs_ops, \ | 393 | .ops = &max77686_buck_dvs_ops, \ |
340 | .type = REGULATOR_VOLTAGE, \ | 394 | .type = REGULATOR_VOLTAGE, \ |
@@ -350,7 +404,7 @@ static struct regulator_ops max77686_buck_dvs_ops = { | |||
350 | << MAX77686_OPMODE_BUCK234_SHIFT, \ | 404 | << MAX77686_OPMODE_BUCK234_SHIFT, \ |
351 | } | 405 | } |
352 | 406 | ||
353 | static struct regulator_desc regulators[] = { | 407 | static const struct regulator_desc regulators[] = { |
354 | regulator_desc_ldo1_low(1), | 408 | regulator_desc_ldo1_low(1), |
355 | regulator_desc_ldo_low(2), | 409 | regulator_desc_ldo_low(2), |
356 | regulator_desc_ldo(3), | 410 | regulator_desc_ldo(3), |
@@ -388,103 +442,37 @@ static struct regulator_desc regulators[] = { | |||
388 | regulator_desc_buck(9), | 442 | regulator_desc_buck(9), |
389 | }; | 443 | }; |
390 | 444 | ||
391 | #ifdef CONFIG_OF | ||
392 | static int max77686_pmic_dt_parse_pdata(struct platform_device *pdev, | ||
393 | struct max77686_platform_data *pdata) | ||
394 | { | ||
395 | struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent); | ||
396 | struct device_node *pmic_np, *regulators_np; | ||
397 | struct max77686_regulator_data *rdata; | ||
398 | struct of_regulator_match rmatch = { }; | ||
399 | unsigned int i; | ||
400 | |||
401 | pmic_np = iodev->dev->of_node; | ||
402 | regulators_np = of_get_child_by_name(pmic_np, "voltage-regulators"); | ||
403 | if (!regulators_np) { | ||
404 | dev_err(&pdev->dev, "could not find regulators sub-node\n"); | ||
405 | return -EINVAL; | ||
406 | } | ||
407 | |||
408 | pdata->num_regulators = ARRAY_SIZE(regulators); | ||
409 | rdata = devm_kzalloc(&pdev->dev, sizeof(*rdata) * | ||
410 | pdata->num_regulators, GFP_KERNEL); | ||
411 | if (!rdata) { | ||
412 | of_node_put(regulators_np); | ||
413 | return -ENOMEM; | ||
414 | } | ||
415 | |||
416 | for (i = 0; i < pdata->num_regulators; i++) { | ||
417 | rmatch.name = regulators[i].name; | ||
418 | rmatch.init_data = NULL; | ||
419 | rmatch.of_node = NULL; | ||
420 | of_regulator_match(&pdev->dev, regulators_np, &rmatch, 1); | ||
421 | rdata[i].initdata = rmatch.init_data; | ||
422 | rdata[i].of_node = rmatch.of_node; | ||
423 | } | ||
424 | |||
425 | pdata->regulators = rdata; | ||
426 | of_node_put(regulators_np); | ||
427 | |||
428 | return 0; | ||
429 | } | ||
430 | #else | ||
431 | static int max77686_pmic_dt_parse_pdata(struct platform_device *pdev, | ||
432 | struct max77686_platform_data *pdata) | ||
433 | { | ||
434 | return 0; | ||
435 | } | ||
436 | #endif /* CONFIG_OF */ | ||
437 | |||
438 | static int max77686_pmic_probe(struct platform_device *pdev) | 445 | static int max77686_pmic_probe(struct platform_device *pdev) |
439 | { | 446 | { |
440 | struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent); | 447 | struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent); |
441 | struct max77686_platform_data *pdata = dev_get_platdata(iodev->dev); | ||
442 | struct max77686_data *max77686; | 448 | struct max77686_data *max77686; |
443 | int i, ret = 0; | 449 | int i; |
444 | struct regulator_config config = { }; | 450 | struct regulator_config config = { }; |
445 | 451 | ||
446 | dev_dbg(&pdev->dev, "%s\n", __func__); | 452 | dev_dbg(&pdev->dev, "%s\n", __func__); |
447 | 453 | ||
448 | if (!pdata) { | ||
449 | dev_err(&pdev->dev, "no platform data found for regulator\n"); | ||
450 | return -ENODEV; | ||
451 | } | ||
452 | |||
453 | if (iodev->dev->of_node) { | ||
454 | ret = max77686_pmic_dt_parse_pdata(pdev, pdata); | ||
455 | if (ret) | ||
456 | return ret; | ||
457 | } | ||
458 | |||
459 | if (pdata->num_regulators != MAX77686_REGULATORS) { | ||
460 | dev_err(&pdev->dev, | ||
461 | "Invalid initial data for regulator's initialiation\n"); | ||
462 | return -EINVAL; | ||
463 | } | ||
464 | |||
465 | max77686 = devm_kzalloc(&pdev->dev, sizeof(struct max77686_data), | 454 | max77686 = devm_kzalloc(&pdev->dev, sizeof(struct max77686_data), |
466 | GFP_KERNEL); | 455 | GFP_KERNEL); |
467 | if (!max77686) | 456 | if (!max77686) |
468 | return -ENOMEM; | 457 | return -ENOMEM; |
469 | 458 | ||
470 | config.dev = &pdev->dev; | 459 | config.dev = iodev->dev; |
471 | config.regmap = iodev->regmap; | 460 | config.regmap = iodev->regmap; |
472 | config.driver_data = max77686; | 461 | config.driver_data = max77686; |
473 | platform_set_drvdata(pdev, max77686); | 462 | platform_set_drvdata(pdev, max77686); |
474 | 463 | ||
475 | for (i = 0; i < MAX77686_REGULATORS; i++) { | 464 | for (i = 0; i < MAX77686_REGULATORS; i++) { |
476 | struct regulator_dev *rdev; | 465 | struct regulator_dev *rdev; |
466 | int id = regulators[i].id; | ||
477 | 467 | ||
478 | config.init_data = pdata->regulators[i].initdata; | 468 | max77686->opmode[id] = MAX77686_NORMAL; |
479 | config.of_node = pdata->regulators[i].of_node; | ||
480 | |||
481 | max77686->opmode[i] = regulators[i].enable_mask; | ||
482 | rdev = devm_regulator_register(&pdev->dev, | 469 | rdev = devm_regulator_register(&pdev->dev, |
483 | ®ulators[i], &config); | 470 | ®ulators[i], &config); |
484 | if (IS_ERR(rdev)) { | 471 | if (IS_ERR(rdev)) { |
472 | int ret = PTR_ERR(rdev); | ||
485 | dev_err(&pdev->dev, | 473 | dev_err(&pdev->dev, |
486 | "regulator init failed for %d\n", i); | 474 | "regulator init failed for %d: %d\n", i, ret); |
487 | return PTR_ERR(rdev); | 475 | return ret; |
488 | } | 476 | } |
489 | } | 477 | } |
490 | 478 | ||
diff --git a/drivers/regulator/max77693.c b/drivers/regulator/max77693.c index d158f71fa128..7b9755a6c3b5 100644 --- a/drivers/regulator/max77693.c +++ b/drivers/regulator/max77693.c | |||
@@ -139,7 +139,7 @@ static struct regulator_ops max77693_charger_ops = { | |||
139 | .enable_mask = SAFEOUT_CTRL_ENSAFEOUT##_num##_MASK , \ | 139 | .enable_mask = SAFEOUT_CTRL_ENSAFEOUT##_num##_MASK , \ |
140 | } | 140 | } |
141 | 141 | ||
142 | static struct regulator_desc regulators[] = { | 142 | static const struct regulator_desc regulators[] = { |
143 | regulator_desc_esafeout(1), | 143 | regulator_desc_esafeout(1), |
144 | regulator_desc_esafeout(2), | 144 | regulator_desc_esafeout(2), |
145 | { | 145 | { |
diff --git a/drivers/regulator/max77802.c b/drivers/regulator/max77802.c index 45fa240fe243..0766615c60bc 100644 --- a/drivers/regulator/max77802.c +++ b/drivers/regulator/max77802.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/regulator/of_regulator.h> | 33 | #include <linux/regulator/of_regulator.h> |
34 | #include <linux/mfd/max77686.h> | 34 | #include <linux/mfd/max77686.h> |
35 | #include <linux/mfd/max77686-private.h> | 35 | #include <linux/mfd/max77686-private.h> |
36 | #include <dt-bindings/regulator/maxim,max77802.h> | ||
36 | 37 | ||
37 | /* Default ramp delay in case it is not manually set */ | 38 | /* Default ramp delay in case it is not manually set */ |
38 | #define MAX77802_RAMP_DELAY 100000 /* uV/us */ | 39 | #define MAX77802_RAMP_DELAY 100000 /* uV/us */ |
@@ -49,6 +50,10 @@ | |||
49 | #define MAX77802_RAMP_RATE_MASK_4BIT 0xF0 | 50 | #define MAX77802_RAMP_RATE_MASK_4BIT 0xF0 |
50 | #define MAX77802_RAMP_RATE_SHIFT_4BIT 4 | 51 | #define MAX77802_RAMP_RATE_SHIFT_4BIT 4 |
51 | 52 | ||
53 | #define MAX77802_STATUS_OFF 0x0 | ||
54 | #define MAX77802_OFF_PWRREQ 0x1 | ||
55 | #define MAX77802_LP_PWRREQ 0x2 | ||
56 | |||
52 | /* MAX77802 has two register formats: 2-bit and 4-bit */ | 57 | /* MAX77802 has two register formats: 2-bit and 4-bit */ |
53 | static const unsigned int ramp_table_77802_2bit[] = { | 58 | static const unsigned int ramp_table_77802_2bit[] = { |
54 | 12500, | 59 | 12500, |
@@ -65,9 +70,16 @@ static unsigned int ramp_table_77802_4bit[] = { | |||
65 | }; | 70 | }; |
66 | 71 | ||
67 | struct max77802_regulator_prv { | 72 | struct max77802_regulator_prv { |
73 | /* Array indexed by regulator id */ | ||
68 | unsigned int opmode[MAX77802_REG_MAX]; | 74 | unsigned int opmode[MAX77802_REG_MAX]; |
69 | }; | 75 | }; |
70 | 76 | ||
77 | static inline unsigned int max77802_map_mode(unsigned int mode) | ||
78 | { | ||
79 | return mode == MAX77802_OPMODE_NORMAL ? | ||
80 | REGULATOR_MODE_NORMAL : REGULATOR_MODE_STANDBY; | ||
81 | } | ||
82 | |||
71 | static int max77802_get_opmode_shift(int id) | 83 | static int max77802_get_opmode_shift(int id) |
72 | { | 84 | { |
73 | if (id == MAX77802_BUCK1 || (id >= MAX77802_BUCK5 && | 85 | if (id == MAX77802_BUCK1 || (id >= MAX77802_BUCK5 && |
@@ -83,17 +95,16 @@ static int max77802_get_opmode_shift(int id) | |||
83 | return -EINVAL; | 95 | return -EINVAL; |
84 | } | 96 | } |
85 | 97 | ||
86 | /* | 98 | /** |
87 | * Some BUCKS supports Normal[ON/OFF] mode during suspend | 99 | * max77802_set_suspend_disable - Disable the regulator during system suspend |
100 | * @rdev: regulator to mark as disabled | ||
88 | * | 101 | * |
89 | * BUCK 1, 6, 2-4, 5, 7-10 (all) | 102 | * All regulators expect LDO 1, 3, 20 and 21 support OFF by PWRREQ. |
90 | * | 103 | * Configure the regulator so the PMIC will turn it OFF during system suspend. |
91 | * The other mode (0x02) will make PWRREQ switch between normal | ||
92 | * and low power. | ||
93 | */ | 104 | */ |
94 | static int max77802_buck_set_suspend_disable(struct regulator_dev *rdev) | 105 | static int max77802_set_suspend_disable(struct regulator_dev *rdev) |
95 | { | 106 | { |
96 | unsigned int val = MAX77802_OPMODE_STANDBY; | 107 | unsigned int val = MAX77802_OFF_PWRREQ; |
97 | struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev); | 108 | struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev); |
98 | int id = rdev_get_id(rdev); | 109 | int id = rdev_get_id(rdev); |
99 | int shift = max77802_get_opmode_shift(id); | 110 | int shift = max77802_get_opmode_shift(id); |
@@ -104,14 +115,11 @@ static int max77802_buck_set_suspend_disable(struct regulator_dev *rdev) | |||
104 | } | 115 | } |
105 | 116 | ||
106 | /* | 117 | /* |
107 | * Some LDOs supports LPM-ON/OFF/Normal-ON mode during suspend state | 118 | * Some LDOs support Low Power Mode while the system is running. |
108 | * (Enable Control Logic1 by PWRREQ) | ||
109 | * | ||
110 | * LDOs 2, 4-19, 22-35. | ||
111 | * | 119 | * |
120 | * LDOs 1, 3, 20, 21. | ||
112 | */ | 121 | */ |
113 | static int max77802_ldo_set_suspend_mode_logic1(struct regulator_dev *rdev, | 122 | static int max77802_set_mode(struct regulator_dev *rdev, unsigned int mode) |
114 | unsigned int mode) | ||
115 | { | 123 | { |
116 | struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev); | 124 | struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev); |
117 | int id = rdev_get_id(rdev); | 125 | int id = rdev_get_id(rdev); |
@@ -119,14 +127,11 @@ static int max77802_ldo_set_suspend_mode_logic1(struct regulator_dev *rdev, | |||
119 | int shift = max77802_get_opmode_shift(id); | 127 | int shift = max77802_get_opmode_shift(id); |
120 | 128 | ||
121 | switch (mode) { | 129 | switch (mode) { |
122 | case REGULATOR_MODE_IDLE: /* ON in LP Mode */ | 130 | case REGULATOR_MODE_STANDBY: |
123 | val = MAX77802_OPMODE_LP; | 131 | val = MAX77802_OPMODE_LP; /* ON in Low Power Mode */ |
124 | break; | 132 | break; |
125 | case REGULATOR_MODE_NORMAL: /* ON in Normal Mode */ | 133 | case REGULATOR_MODE_NORMAL: |
126 | val = MAX77802_OPMODE_NORMAL; | 134 | val = MAX77802_OPMODE_NORMAL; /* ON in Normal Mode */ |
127 | break; | ||
128 | case REGULATOR_MODE_STANDBY: /* ON/OFF by PWRREQ */ | ||
129 | val = MAX77802_OPMODE_STANDBY; | ||
130 | break; | 135 | break; |
131 | default: | 136 | default: |
132 | dev_warn(&rdev->dev, "%s: regulator mode: 0x%x not supported\n", | 137 | dev_warn(&rdev->dev, "%s: regulator mode: 0x%x not supported\n", |
@@ -139,35 +144,76 @@ static int max77802_ldo_set_suspend_mode_logic1(struct regulator_dev *rdev, | |||
139 | rdev->desc->enable_mask, val << shift); | 144 | rdev->desc->enable_mask, val << shift); |
140 | } | 145 | } |
141 | 146 | ||
142 | /* | 147 | static unsigned max77802_get_mode(struct regulator_dev *rdev) |
143 | * Mode 1 (Output[ON/OFF] by PWRREQ) is not supported on some LDOs | 148 | { |
144 | * (Enable Control Logic2 by PWRREQ) | 149 | struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev); |
150 | int id = rdev_get_id(rdev); | ||
151 | |||
152 | return max77802_map_mode(max77802->opmode[id]); | ||
153 | } | ||
154 | |||
155 | /** | ||
156 | * max77802_set_suspend_mode - set regulator opmode when the system is suspended | ||
157 | * @rdev: regulator to change mode | ||
158 | * @mode: operating mode to be set | ||
145 | * | 159 | * |
146 | * LDOs 1, 20, 21, and 3, | 160 | * Will set the operating mode for the regulators during system suspend. |
161 | * This function is valid for the three different enable control logics: | ||
147 | * | 162 | * |
163 | * Enable Control Logic1 by PWRREQ (BUCK 2-4 and LDOs 2, 4-19, 22-35) | ||
164 | * Enable Control Logic2 by PWRREQ (LDOs 1, 20, 21) | ||
165 | * Enable Control Logic3 by PWRREQ (LDO 3) | ||
166 | * | ||
167 | * If setting the regulator mode fails, the function only warns but does | ||
168 | * not return an error code to avoid the regulator core to stop setting | ||
169 | * the operating mode for the remaining regulators. | ||
148 | */ | 170 | */ |
149 | static int max77802_ldo_set_suspend_mode_logic2(struct regulator_dev *rdev, | 171 | static int max77802_set_suspend_mode(struct regulator_dev *rdev, |
150 | unsigned int mode) | 172 | unsigned int mode) |
151 | { | 173 | { |
152 | struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev); | 174 | struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev); |
153 | int id = rdev_get_id(rdev); | 175 | int id = rdev_get_id(rdev); |
154 | unsigned int val; | 176 | unsigned int val; |
155 | int shift = max77802_get_opmode_shift(id); | 177 | int shift = max77802_get_opmode_shift(id); |
156 | 178 | ||
179 | /* | ||
180 | * If the regulator has been disabled for suspend | ||
181 | * then is invalid to try setting a suspend mode. | ||
182 | */ | ||
183 | if (max77802->opmode[id] == MAX77802_OFF_PWRREQ) { | ||
184 | dev_warn(&rdev->dev, "%s: is disabled, mode: 0x%x not set\n", | ||
185 | rdev->desc->name, mode); | ||
186 | return 0; | ||
187 | } | ||
188 | |||
157 | switch (mode) { | 189 | switch (mode) { |
158 | case REGULATOR_MODE_IDLE: /* ON in LP Mode */ | 190 | case REGULATOR_MODE_STANDBY: |
159 | val = MAX77802_OPMODE_LP; | 191 | /* |
160 | break; | 192 | * If the regulator opmode is normal then enable |
161 | case REGULATOR_MODE_NORMAL: /* ON in Normal Mode */ | 193 | * ON in Low Power Mode by PWRREQ. If the mode is |
162 | val = MAX77802_OPMODE_NORMAL; | 194 | * already Low Power then no action is required. |
195 | */ | ||
196 | if (max77802->opmode[id] == MAX77802_OPMODE_NORMAL) | ||
197 | val = MAX77802_LP_PWRREQ; | ||
198 | else | ||
199 | return 0; | ||
163 | break; | 200 | break; |
201 | case REGULATOR_MODE_NORMAL: | ||
202 | /* | ||
203 | * If the regulator operating mode is Low Power then | ||
204 | * normal is not a valid opmode in suspend. If the | ||
205 | * mode is already normal then no action is required. | ||
206 | */ | ||
207 | if (max77802->opmode[id] == MAX77802_OPMODE_LP) | ||
208 | dev_warn(&rdev->dev, "%s: in Low Power: 0x%x invalid\n", | ||
209 | rdev->desc->name, mode); | ||
210 | return 0; | ||
164 | default: | 211 | default: |
165 | dev_warn(&rdev->dev, "%s: regulator mode: 0x%x not supported\n", | 212 | dev_warn(&rdev->dev, "%s: regulator mode: 0x%x not supported\n", |
166 | rdev->desc->name, mode); | 213 | rdev->desc->name, mode); |
167 | return -EINVAL; | 214 | return -EINVAL; |
168 | } | 215 | } |
169 | 216 | ||
170 | max77802->opmode[id] = val; | ||
171 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | 217 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, |
172 | rdev->desc->enable_mask, val << shift); | 218 | rdev->desc->enable_mask, val << shift); |
173 | } | 219 | } |
@@ -178,6 +224,9 @@ static int max77802_enable(struct regulator_dev *rdev) | |||
178 | int id = rdev_get_id(rdev); | 224 | int id = rdev_get_id(rdev); |
179 | int shift = max77802_get_opmode_shift(id); | 225 | int shift = max77802_get_opmode_shift(id); |
180 | 226 | ||
227 | if (max77802->opmode[id] == MAX77802_OFF_PWRREQ) | ||
228 | max77802->opmode[id] = MAX77802_OPMODE_NORMAL; | ||
229 | |||
181 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | 230 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, |
182 | rdev->desc->enable_mask, | 231 | rdev->desc->enable_mask, |
183 | max77802->opmode[id] << shift); | 232 | max77802->opmode[id] << shift); |
@@ -247,7 +296,8 @@ static struct regulator_ops max77802_ldo_ops_logic1 = { | |||
247 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | 296 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
248 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | 297 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
249 | .set_voltage_time_sel = regulator_set_voltage_time_sel, | 298 | .set_voltage_time_sel = regulator_set_voltage_time_sel, |
250 | .set_suspend_mode = max77802_ldo_set_suspend_mode_logic1, | 299 | .set_suspend_disable = max77802_set_suspend_disable, |
300 | .set_suspend_mode = max77802_set_suspend_mode, | ||
251 | }; | 301 | }; |
252 | 302 | ||
253 | /* | 303 | /* |
@@ -262,7 +312,9 @@ static struct regulator_ops max77802_ldo_ops_logic2 = { | |||
262 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | 312 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
263 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | 313 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
264 | .set_voltage_time_sel = regulator_set_voltage_time_sel, | 314 | .set_voltage_time_sel = regulator_set_voltage_time_sel, |
265 | .set_suspend_mode = max77802_ldo_set_suspend_mode_logic2, | 315 | .set_mode = max77802_set_mode, |
316 | .get_mode = max77802_get_mode, | ||
317 | .set_suspend_mode = max77802_set_suspend_mode, | ||
266 | }; | 318 | }; |
267 | 319 | ||
268 | /* BUCKS 1, 6 */ | 320 | /* BUCKS 1, 6 */ |
@@ -276,10 +328,25 @@ static struct regulator_ops max77802_buck_16_dvs_ops = { | |||
276 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | 328 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
277 | .set_voltage_time_sel = regulator_set_voltage_time_sel, | 329 | .set_voltage_time_sel = regulator_set_voltage_time_sel, |
278 | .set_ramp_delay = max77802_set_ramp_delay_4bit, | 330 | .set_ramp_delay = max77802_set_ramp_delay_4bit, |
279 | .set_suspend_disable = max77802_buck_set_suspend_disable, | 331 | .set_suspend_disable = max77802_set_suspend_disable, |
280 | }; | 332 | }; |
281 | 333 | ||
282 | /* BUCKs 2-4, 5, 7-10 */ | 334 | /* BUCKs 2-4 */ |
335 | static struct regulator_ops max77802_buck_234_ops = { | ||
336 | .list_voltage = regulator_list_voltage_linear, | ||
337 | .map_voltage = regulator_map_voltage_linear, | ||
338 | .is_enabled = regulator_is_enabled_regmap, | ||
339 | .enable = max77802_enable, | ||
340 | .disable = regulator_disable_regmap, | ||
341 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
342 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
343 | .set_voltage_time_sel = regulator_set_voltage_time_sel, | ||
344 | .set_ramp_delay = max77802_set_ramp_delay_2bit, | ||
345 | .set_suspend_disable = max77802_set_suspend_disable, | ||
346 | .set_suspend_mode = max77802_set_suspend_mode, | ||
347 | }; | ||
348 | |||
349 | /* BUCKs 5, 7-10 */ | ||
283 | static struct regulator_ops max77802_buck_dvs_ops = { | 350 | static struct regulator_ops max77802_buck_dvs_ops = { |
284 | .list_voltage = regulator_list_voltage_linear, | 351 | .list_voltage = regulator_list_voltage_linear, |
285 | .map_voltage = regulator_map_voltage_linear, | 352 | .map_voltage = regulator_map_voltage_linear, |
@@ -290,12 +357,14 @@ static struct regulator_ops max77802_buck_dvs_ops = { | |||
290 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | 357 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
291 | .set_voltage_time_sel = regulator_set_voltage_time_sel, | 358 | .set_voltage_time_sel = regulator_set_voltage_time_sel, |
292 | .set_ramp_delay = max77802_set_ramp_delay_2bit, | 359 | .set_ramp_delay = max77802_set_ramp_delay_2bit, |
293 | .set_suspend_disable = max77802_buck_set_suspend_disable, | 360 | .set_suspend_disable = max77802_set_suspend_disable, |
294 | }; | 361 | }; |
295 | 362 | ||
296 | /* LDOs 3-7, 9-14, 18-26, 28, 29, 32-34 */ | 363 | /* LDOs 3-7, 9-14, 18-26, 28, 29, 32-34 */ |
297 | #define regulator_77802_desc_p_ldo(num, supply, log) { \ | 364 | #define regulator_77802_desc_p_ldo(num, supply, log) { \ |
298 | .name = "LDO"#num, \ | 365 | .name = "LDO"#num, \ |
366 | .of_match = of_match_ptr("LDO"#num), \ | ||
367 | .regulators_node = of_match_ptr("regulators"), \ | ||
299 | .id = MAX77802_LDO##num, \ | 368 | .id = MAX77802_LDO##num, \ |
300 | .supply_name = "inl"#supply, \ | 369 | .supply_name = "inl"#supply, \ |
301 | .ops = &max77802_ldo_ops_logic##log, \ | 370 | .ops = &max77802_ldo_ops_logic##log, \ |
@@ -309,11 +378,14 @@ static struct regulator_ops max77802_buck_dvs_ops = { | |||
309 | .vsel_mask = MAX77802_VSEL_MASK, \ | 378 | .vsel_mask = MAX77802_VSEL_MASK, \ |
310 | .enable_reg = MAX77802_REG_LDO1CTRL1 + num - 1, \ | 379 | .enable_reg = MAX77802_REG_LDO1CTRL1 + num - 1, \ |
311 | .enable_mask = MAX77802_OPMODE_MASK << MAX77802_OPMODE_SHIFT_LDO, \ | 380 | .enable_mask = MAX77802_OPMODE_MASK << MAX77802_OPMODE_SHIFT_LDO, \ |
381 | .of_map_mode = max77802_map_mode, \ | ||
312 | } | 382 | } |
313 | 383 | ||
314 | /* LDOs 1, 2, 8, 15, 17, 27, 30, 35 */ | 384 | /* LDOs 1, 2, 8, 15, 17, 27, 30, 35 */ |
315 | #define regulator_77802_desc_n_ldo(num, supply, log) { \ | 385 | #define regulator_77802_desc_n_ldo(num, supply, log) { \ |
316 | .name = "LDO"#num, \ | 386 | .name = "LDO"#num, \ |
387 | .of_match = of_match_ptr("LDO"#num), \ | ||
388 | .regulators_node = of_match_ptr("regulators"), \ | ||
317 | .id = MAX77802_LDO##num, \ | 389 | .id = MAX77802_LDO##num, \ |
318 | .supply_name = "inl"#supply, \ | 390 | .supply_name = "inl"#supply, \ |
319 | .ops = &max77802_ldo_ops_logic##log, \ | 391 | .ops = &max77802_ldo_ops_logic##log, \ |
@@ -327,11 +399,14 @@ static struct regulator_ops max77802_buck_dvs_ops = { | |||
327 | .vsel_mask = MAX77802_VSEL_MASK, \ | 399 | .vsel_mask = MAX77802_VSEL_MASK, \ |
328 | .enable_reg = MAX77802_REG_LDO1CTRL1 + num - 1, \ | 400 | .enable_reg = MAX77802_REG_LDO1CTRL1 + num - 1, \ |
329 | .enable_mask = MAX77802_OPMODE_MASK << MAX77802_OPMODE_SHIFT_LDO, \ | 401 | .enable_mask = MAX77802_OPMODE_MASK << MAX77802_OPMODE_SHIFT_LDO, \ |
402 | .of_map_mode = max77802_map_mode, \ | ||
330 | } | 403 | } |
331 | 404 | ||
332 | /* BUCKs 1, 6 */ | 405 | /* BUCKs 1, 6 */ |
333 | #define regulator_77802_desc_16_buck(num) { \ | 406 | #define regulator_77802_desc_16_buck(num) { \ |
334 | .name = "BUCK"#num, \ | 407 | .name = "BUCK"#num, \ |
408 | .of_match = of_match_ptr("BUCK"#num), \ | ||
409 | .regulators_node = of_match_ptr("regulators"), \ | ||
335 | .id = MAX77802_BUCK##num, \ | 410 | .id = MAX77802_BUCK##num, \ |
336 | .supply_name = "inb"#num, \ | 411 | .supply_name = "inb"#num, \ |
337 | .ops = &max77802_buck_16_dvs_ops, \ | 412 | .ops = &max77802_buck_16_dvs_ops, \ |
@@ -345,14 +420,17 @@ static struct regulator_ops max77802_buck_dvs_ops = { | |||
345 | .vsel_mask = MAX77802_DVS_VSEL_MASK, \ | 420 | .vsel_mask = MAX77802_DVS_VSEL_MASK, \ |
346 | .enable_reg = MAX77802_REG_BUCK ## num ## CTRL, \ | 421 | .enable_reg = MAX77802_REG_BUCK ## num ## CTRL, \ |
347 | .enable_mask = MAX77802_OPMODE_MASK, \ | 422 | .enable_mask = MAX77802_OPMODE_MASK, \ |
423 | .of_map_mode = max77802_map_mode, \ | ||
348 | } | 424 | } |
349 | 425 | ||
350 | /* BUCKS 2-4 */ | 426 | /* BUCKS 2-4 */ |
351 | #define regulator_77802_desc_234_buck(num) { \ | 427 | #define regulator_77802_desc_234_buck(num) { \ |
352 | .name = "BUCK"#num, \ | 428 | .name = "BUCK"#num, \ |
429 | .of_match = of_match_ptr("BUCK"#num), \ | ||
430 | .regulators_node = of_match_ptr("regulators"), \ | ||
353 | .id = MAX77802_BUCK##num, \ | 431 | .id = MAX77802_BUCK##num, \ |
354 | .supply_name = "inb"#num, \ | 432 | .supply_name = "inb"#num, \ |
355 | .ops = &max77802_buck_dvs_ops, \ | 433 | .ops = &max77802_buck_234_ops, \ |
356 | .type = REGULATOR_VOLTAGE, \ | 434 | .type = REGULATOR_VOLTAGE, \ |
357 | .owner = THIS_MODULE, \ | 435 | .owner = THIS_MODULE, \ |
358 | .min_uV = 600000, \ | 436 | .min_uV = 600000, \ |
@@ -364,11 +442,14 @@ static struct regulator_ops max77802_buck_dvs_ops = { | |||
364 | .enable_reg = MAX77802_REG_BUCK ## num ## CTRL1, \ | 442 | .enable_reg = MAX77802_REG_BUCK ## num ## CTRL1, \ |
365 | .enable_mask = MAX77802_OPMODE_MASK << \ | 443 | .enable_mask = MAX77802_OPMODE_MASK << \ |
366 | MAX77802_OPMODE_BUCK234_SHIFT, \ | 444 | MAX77802_OPMODE_BUCK234_SHIFT, \ |
445 | .of_map_mode = max77802_map_mode, \ | ||
367 | } | 446 | } |
368 | 447 | ||
369 | /* BUCK 5 */ | 448 | /* BUCK 5 */ |
370 | #define regulator_77802_desc_buck5(num) { \ | 449 | #define regulator_77802_desc_buck5(num) { \ |
371 | .name = "BUCK"#num, \ | 450 | .name = "BUCK"#num, \ |
451 | .of_match = of_match_ptr("BUCK"#num), \ | ||
452 | .regulators_node = of_match_ptr("regulators"), \ | ||
372 | .id = MAX77802_BUCK##num, \ | 453 | .id = MAX77802_BUCK##num, \ |
373 | .supply_name = "inb"#num, \ | 454 | .supply_name = "inb"#num, \ |
374 | .ops = &max77802_buck_dvs_ops, \ | 455 | .ops = &max77802_buck_dvs_ops, \ |
@@ -382,11 +463,14 @@ static struct regulator_ops max77802_buck_dvs_ops = { | |||
382 | .vsel_mask = MAX77802_VSEL_MASK, \ | 463 | .vsel_mask = MAX77802_VSEL_MASK, \ |
383 | .enable_reg = MAX77802_REG_BUCK5CTRL, \ | 464 | .enable_reg = MAX77802_REG_BUCK5CTRL, \ |
384 | .enable_mask = MAX77802_OPMODE_MASK, \ | 465 | .enable_mask = MAX77802_OPMODE_MASK, \ |
466 | .of_map_mode = max77802_map_mode, \ | ||
385 | } | 467 | } |
386 | 468 | ||
387 | /* BUCKs 7-10 */ | 469 | /* BUCKs 7-10 */ |
388 | #define regulator_77802_desc_buck7_10(num) { \ | 470 | #define regulator_77802_desc_buck7_10(num) { \ |
389 | .name = "BUCK"#num, \ | 471 | .name = "BUCK"#num, \ |
472 | .of_match = of_match_ptr("BUCK"#num), \ | ||
473 | .regulators_node = of_match_ptr("regulators"), \ | ||
390 | .id = MAX77802_BUCK##num, \ | 474 | .id = MAX77802_BUCK##num, \ |
391 | .supply_name = "inb"#num, \ | 475 | .supply_name = "inb"#num, \ |
392 | .ops = &max77802_buck_dvs_ops, \ | 476 | .ops = &max77802_buck_dvs_ops, \ |
@@ -400,9 +484,10 @@ static struct regulator_ops max77802_buck_dvs_ops = { | |||
400 | .vsel_mask = MAX77802_VSEL_MASK, \ | 484 | .vsel_mask = MAX77802_VSEL_MASK, \ |
401 | .enable_reg = MAX77802_REG_BUCK7CTRL + (num - 7) * 3, \ | 485 | .enable_reg = MAX77802_REG_BUCK7CTRL + (num - 7) * 3, \ |
402 | .enable_mask = MAX77802_OPMODE_MASK, \ | 486 | .enable_mask = MAX77802_OPMODE_MASK, \ |
487 | .of_map_mode = max77802_map_mode, \ | ||
403 | } | 488 | } |
404 | 489 | ||
405 | static struct regulator_desc regulators[] = { | 490 | static const struct regulator_desc regulators[] = { |
406 | regulator_77802_desc_16_buck(1), | 491 | regulator_77802_desc_16_buck(1), |
407 | regulator_77802_desc_234_buck(2), | 492 | regulator_77802_desc_234_buck(2), |
408 | regulator_77802_desc_234_buck(3), | 493 | regulator_77802_desc_234_buck(3), |
@@ -447,85 +532,19 @@ static struct regulator_desc regulators[] = { | |||
447 | regulator_77802_desc_n_ldo(35, 2, 1), | 532 | regulator_77802_desc_n_ldo(35, 2, 1), |
448 | }; | 533 | }; |
449 | 534 | ||
450 | #ifdef CONFIG_OF | ||
451 | static int max77802_pmic_dt_parse_pdata(struct platform_device *pdev, | ||
452 | struct max77686_platform_data *pdata) | ||
453 | { | ||
454 | struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent); | ||
455 | struct device_node *pmic_np, *regulators_np; | ||
456 | struct max77686_regulator_data *rdata; | ||
457 | struct of_regulator_match rmatch = { }; | ||
458 | unsigned int i; | ||
459 | |||
460 | pmic_np = iodev->dev->of_node; | ||
461 | regulators_np = of_get_child_by_name(pmic_np, "regulators"); | ||
462 | if (!regulators_np) { | ||
463 | dev_err(&pdev->dev, "could not find regulators sub-node\n"); | ||
464 | return -EINVAL; | ||
465 | } | ||
466 | |||
467 | pdata->num_regulators = ARRAY_SIZE(regulators); | ||
468 | rdata = devm_kzalloc(&pdev->dev, sizeof(*rdata) * | ||
469 | pdata->num_regulators, GFP_KERNEL); | ||
470 | if (!rdata) { | ||
471 | of_node_put(regulators_np); | ||
472 | return -ENOMEM; | ||
473 | } | ||
474 | |||
475 | for (i = 0; i < pdata->num_regulators; i++) { | ||
476 | rmatch.name = regulators[i].name; | ||
477 | rmatch.init_data = NULL; | ||
478 | rmatch.of_node = NULL; | ||
479 | if (of_regulator_match(&pdev->dev, regulators_np, &rmatch, | ||
480 | 1) != 1) { | ||
481 | dev_warn(&pdev->dev, "No matching regulator for '%s'\n", | ||
482 | rmatch.name); | ||
483 | continue; | ||
484 | } | ||
485 | rdata[i].initdata = rmatch.init_data; | ||
486 | rdata[i].of_node = rmatch.of_node; | ||
487 | rdata[i].id = regulators[i].id; | ||
488 | } | ||
489 | |||
490 | pdata->regulators = rdata; | ||
491 | of_node_put(regulators_np); | ||
492 | |||
493 | return 0; | ||
494 | } | ||
495 | #else | ||
496 | static int max77802_pmic_dt_parse_pdata(struct platform_device *pdev, | ||
497 | struct max77686_platform_data *pdata) | ||
498 | { | ||
499 | return 0; | ||
500 | } | ||
501 | #endif /* CONFIG_OF */ | ||
502 | |||
503 | static int max77802_pmic_probe(struct platform_device *pdev) | 535 | static int max77802_pmic_probe(struct platform_device *pdev) |
504 | { | 536 | { |
505 | struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent); | 537 | struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent); |
506 | struct max77686_platform_data *pdata = dev_get_platdata(iodev->dev); | ||
507 | struct max77802_regulator_prv *max77802; | 538 | struct max77802_regulator_prv *max77802; |
508 | int i, ret = 0, val; | 539 | int i, val; |
509 | struct regulator_config config = { }; | 540 | struct regulator_config config = { }; |
510 | 541 | ||
511 | /* This is allocated by the MFD driver */ | ||
512 | if (!pdata) { | ||
513 | dev_err(&pdev->dev, "no platform data found for regulator\n"); | ||
514 | return -ENODEV; | ||
515 | } | ||
516 | |||
517 | max77802 = devm_kzalloc(&pdev->dev, | 542 | max77802 = devm_kzalloc(&pdev->dev, |
518 | sizeof(struct max77802_regulator_prv), | 543 | sizeof(struct max77802_regulator_prv), |
519 | GFP_KERNEL); | 544 | GFP_KERNEL); |
520 | if (!max77802) | 545 | if (!max77802) |
521 | return -ENOMEM; | 546 | return -ENOMEM; |
522 | 547 | ||
523 | if (iodev->dev->of_node) { | ||
524 | ret = max77802_pmic_dt_parse_pdata(pdev, pdata); | ||
525 | if (ret) | ||
526 | return ret; | ||
527 | } | ||
528 | |||
529 | config.dev = iodev->dev; | 548 | config.dev = iodev->dev; |
530 | config.regmap = iodev->regmap; | 549 | config.regmap = iodev->regmap; |
531 | config.driver_data = max77802; | 550 | config.driver_data = max77802; |
@@ -533,21 +552,25 @@ static int max77802_pmic_probe(struct platform_device *pdev) | |||
533 | 552 | ||
534 | for (i = 0; i < MAX77802_REG_MAX; i++) { | 553 | for (i = 0; i < MAX77802_REG_MAX; i++) { |
535 | struct regulator_dev *rdev; | 554 | struct regulator_dev *rdev; |
536 | int id = pdata->regulators[i].id; | 555 | int id = regulators[i].id; |
537 | int shift = max77802_get_opmode_shift(id); | 556 | int shift = max77802_get_opmode_shift(id); |
538 | 557 | int ret; | |
539 | config.init_data = pdata->regulators[i].initdata; | ||
540 | config.of_node = pdata->regulators[i].of_node; | ||
541 | 558 | ||
542 | ret = regmap_read(iodev->regmap, regulators[i].enable_reg, &val); | 559 | ret = regmap_read(iodev->regmap, regulators[i].enable_reg, &val); |
543 | val = val >> shift & MAX77802_OPMODE_MASK; | 560 | if (ret < 0) { |
561 | dev_warn(&pdev->dev, | ||
562 | "cannot read current mode for %d\n", i); | ||
563 | val = MAX77802_OPMODE_NORMAL; | ||
564 | } else { | ||
565 | val = val >> shift & MAX77802_OPMODE_MASK; | ||
566 | } | ||
544 | 567 | ||
545 | /* | 568 | /* |
546 | * If the regulator is disabled and the system warm rebooted, | 569 | * If the regulator is disabled and the system warm rebooted, |
547 | * the hardware reports OFF as the regulator operating mode. | 570 | * the hardware reports OFF as the regulator operating mode. |
548 | * Default to operating mode NORMAL in that case. | 571 | * Default to operating mode NORMAL in that case. |
549 | */ | 572 | */ |
550 | if (val == MAX77802_OPMODE_OFF) | 573 | if (val == MAX77802_STATUS_OFF) |
551 | max77802->opmode[id] = MAX77802_OPMODE_NORMAL; | 574 | max77802->opmode[id] = MAX77802_OPMODE_NORMAL; |
552 | else | 575 | else |
553 | max77802->opmode[id] = val; | 576 | max77802->opmode[id] = val; |
@@ -555,9 +578,10 @@ static int max77802_pmic_probe(struct platform_device *pdev) | |||
555 | rdev = devm_regulator_register(&pdev->dev, | 578 | rdev = devm_regulator_register(&pdev->dev, |
556 | ®ulators[i], &config); | 579 | ®ulators[i], &config); |
557 | if (IS_ERR(rdev)) { | 580 | if (IS_ERR(rdev)) { |
581 | ret = PTR_ERR(rdev); | ||
558 | dev_err(&pdev->dev, | 582 | dev_err(&pdev->dev, |
559 | "regulator init failed for %d\n", i); | 583 | "regulator init failed for %d: %d\n", i, ret); |
560 | return PTR_ERR(rdev); | 584 | return ret; |
561 | } | 585 | } |
562 | } | 586 | } |
563 | 587 | ||
diff --git a/drivers/regulator/max8952.c b/drivers/regulator/max8952.c index f7f9efcfedb7..1af8f4a2ab86 100644 --- a/drivers/regulator/max8952.c +++ b/drivers/regulator/max8952.c | |||
@@ -174,7 +174,7 @@ static struct max8952_platform_data *max8952_parse_dt(struct device *dev) | |||
174 | if (of_property_read_u32(np, "max8952,ramp-speed", &pd->ramp_speed)) | 174 | if (of_property_read_u32(np, "max8952,ramp-speed", &pd->ramp_speed)) |
175 | dev_warn(dev, "max8952,ramp-speed property not specified, defaulting to 32mV/us\n"); | 175 | dev_warn(dev, "max8952,ramp-speed property not specified, defaulting to 32mV/us\n"); |
176 | 176 | ||
177 | pd->reg_data = of_get_regulator_init_data(dev, np); | 177 | pd->reg_data = of_get_regulator_init_data(dev, np, ®ulator); |
178 | if (!pd->reg_data) { | 178 | if (!pd->reg_data) { |
179 | dev_err(dev, "Failed to parse regulator init data\n"); | 179 | dev_err(dev, "Failed to parse regulator init data\n"); |
180 | return NULL; | 180 | return NULL; |
@@ -225,6 +225,8 @@ static int max8952_pmic_probe(struct i2c_client *client, | |||
225 | config.of_node = client->dev.of_node; | 225 | config.of_node = client->dev.of_node; |
226 | 226 | ||
227 | config.ena_gpio = pdata->gpio_en; | 227 | config.ena_gpio = pdata->gpio_en; |
228 | if (client->dev.of_node) | ||
229 | config.ena_gpio_initialized = true; | ||
228 | if (pdata->reg_data->constraints.boot_on) | 230 | if (pdata->reg_data->constraints.boot_on) |
229 | config.ena_gpio_flags |= GPIOF_OUT_INIT_HIGH; | 231 | config.ena_gpio_flags |= GPIOF_OUT_INIT_HIGH; |
230 | 232 | ||
diff --git a/drivers/regulator/max8973-regulator.c b/drivers/regulator/max8973-regulator.c index dbedf1768db0..c3d55c2db593 100644 --- a/drivers/regulator/max8973-regulator.c +++ b/drivers/regulator/max8973-regulator.c | |||
@@ -458,7 +458,8 @@ static int max8973_probe(struct i2c_client *client, | |||
458 | 458 | ||
459 | config.dev = &client->dev; | 459 | config.dev = &client->dev; |
460 | config.init_data = pdata ? pdata->reg_init_data : | 460 | config.init_data = pdata ? pdata->reg_init_data : |
461 | of_get_regulator_init_data(&client->dev, client->dev.of_node); | 461 | of_get_regulator_init_data(&client->dev, client->dev.of_node, |
462 | &max->desc); | ||
462 | config.driver_data = max; | 463 | config.driver_data = max; |
463 | config.of_node = client->dev.of_node; | 464 | config.of_node = client->dev.of_node; |
464 | config.regmap = max->regmap; | 465 | config.regmap = max->regmap; |
diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c index 9c31e215a521..726fde1d883e 100644 --- a/drivers/regulator/max8997.c +++ b/drivers/regulator/max8997.c | |||
@@ -953,7 +953,8 @@ static int max8997_pmic_dt_parse_pdata(struct platform_device *pdev, | |||
953 | 953 | ||
954 | rdata->id = i; | 954 | rdata->id = i; |
955 | rdata->initdata = of_get_regulator_init_data(&pdev->dev, | 955 | rdata->initdata = of_get_regulator_init_data(&pdev->dev, |
956 | reg_np); | 956 | reg_np, |
957 | ®ulators[i]); | ||
957 | rdata->reg_node = reg_np; | 958 | rdata->reg_node = reg_np; |
958 | rdata++; | 959 | rdata++; |
959 | } | 960 | } |
diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c index 961091b46557..59e34a05a4a2 100644 --- a/drivers/regulator/max8998.c +++ b/drivers/regulator/max8998.c | |||
@@ -686,8 +686,9 @@ static int max8998_pmic_dt_parse_pdata(struct max8998_dev *iodev, | |||
686 | continue; | 686 | continue; |
687 | 687 | ||
688 | rdata->id = regulators[i].id; | 688 | rdata->id = regulators[i].id; |
689 | rdata->initdata = of_get_regulator_init_data( | 689 | rdata->initdata = of_get_regulator_init_data(iodev->dev, |
690 | iodev->dev, reg_np); | 690 | reg_np, |
691 | ®ulators[i]); | ||
691 | rdata->reg_node = reg_np; | 692 | rdata->reg_node = reg_np; |
692 | ++rdata; | 693 | ++rdata; |
693 | } | 694 | } |
diff --git a/drivers/regulator/mc13xxx-regulator-core.c b/drivers/regulator/mc13xxx-regulator-core.c index afba024953e1..0281c31ae2ed 100644 --- a/drivers/regulator/mc13xxx-regulator-core.c +++ b/drivers/regulator/mc13xxx-regulator-core.c | |||
@@ -194,7 +194,8 @@ struct mc13xxx_regulator_init_data *mc13xxx_parse_regulators_dt( | |||
194 | regulators[i].desc.name)) { | 194 | regulators[i].desc.name)) { |
195 | p->id = i; | 195 | p->id = i; |
196 | p->init_data = of_get_regulator_init_data( | 196 | p->init_data = of_get_regulator_init_data( |
197 | &pdev->dev, child); | 197 | &pdev->dev, child, |
198 | ®ulators[i].desc); | ||
198 | p->node = child; | 199 | p->node = child; |
199 | p++; | 200 | p++; |
200 | 201 | ||
diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index 5a1d4afa4776..91eaaf010524 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c | |||
@@ -19,12 +19,20 @@ | |||
19 | 19 | ||
20 | #include "internal.h" | 20 | #include "internal.h" |
21 | 21 | ||
22 | static const char *const regulator_states[PM_SUSPEND_MAX + 1] = { | ||
23 | [PM_SUSPEND_MEM] = "regulator-state-mem", | ||
24 | [PM_SUSPEND_MAX] = "regulator-state-disk", | ||
25 | }; | ||
26 | |||
22 | static void of_get_regulation_constraints(struct device_node *np, | 27 | static void of_get_regulation_constraints(struct device_node *np, |
23 | struct regulator_init_data **init_data) | 28 | struct regulator_init_data **init_data, |
29 | const struct regulator_desc *desc) | ||
24 | { | 30 | { |
25 | const __be32 *min_uV, *max_uV; | 31 | const __be32 *min_uV, *max_uV; |
26 | struct regulation_constraints *constraints = &(*init_data)->constraints; | 32 | struct regulation_constraints *constraints = &(*init_data)->constraints; |
27 | int ret; | 33 | struct regulator_state *suspend_state; |
34 | struct device_node *suspend_np; | ||
35 | int ret, i; | ||
28 | u32 pval; | 36 | u32 pval; |
29 | 37 | ||
30 | constraints->name = of_get_property(np, "regulator-name", NULL); | 38 | constraints->name = of_get_property(np, "regulator-name", NULL); |
@@ -73,18 +81,84 @@ static void of_get_regulation_constraints(struct device_node *np, | |||
73 | ret = of_property_read_u32(np, "regulator-enable-ramp-delay", &pval); | 81 | ret = of_property_read_u32(np, "regulator-enable-ramp-delay", &pval); |
74 | if (!ret) | 82 | if (!ret) |
75 | constraints->enable_time = pval; | 83 | constraints->enable_time = pval; |
84 | |||
85 | if (!of_property_read_u32(np, "regulator-initial-mode", &pval)) { | ||
86 | if (desc && desc->of_map_mode) { | ||
87 | ret = desc->of_map_mode(pval); | ||
88 | if (ret == -EINVAL) | ||
89 | pr_err("%s: invalid mode %u\n", np->name, pval); | ||
90 | else | ||
91 | constraints->initial_mode = ret; | ||
92 | } else { | ||
93 | pr_warn("%s: mapping for mode %d not defined\n", | ||
94 | np->name, pval); | ||
95 | } | ||
96 | } | ||
97 | |||
98 | for (i = 0; i < ARRAY_SIZE(regulator_states); i++) { | ||
99 | switch (i) { | ||
100 | case PM_SUSPEND_MEM: | ||
101 | suspend_state = &constraints->state_mem; | ||
102 | break; | ||
103 | case PM_SUSPEND_MAX: | ||
104 | suspend_state = &constraints->state_disk; | ||
105 | break; | ||
106 | case PM_SUSPEND_ON: | ||
107 | case PM_SUSPEND_FREEZE: | ||
108 | case PM_SUSPEND_STANDBY: | ||
109 | default: | ||
110 | continue; | ||
111 | }; | ||
112 | |||
113 | suspend_np = of_get_child_by_name(np, regulator_states[i]); | ||
114 | if (!suspend_np || !suspend_state) | ||
115 | continue; | ||
116 | |||
117 | if (!of_property_read_u32(suspend_np, "regulator-mode", | ||
118 | &pval)) { | ||
119 | if (desc && desc->of_map_mode) { | ||
120 | ret = desc->of_map_mode(pval); | ||
121 | if (ret == -EINVAL) | ||
122 | pr_err("%s: invalid mode %u\n", | ||
123 | np->name, pval); | ||
124 | else | ||
125 | suspend_state->mode = ret; | ||
126 | } else { | ||
127 | pr_warn("%s: mapping for mode %d not defined\n", | ||
128 | np->name, pval); | ||
129 | } | ||
130 | } | ||
131 | |||
132 | if (of_property_read_bool(suspend_np, | ||
133 | "regulator-on-in-suspend")) | ||
134 | suspend_state->enabled = true; | ||
135 | else if (of_property_read_bool(suspend_np, | ||
136 | "regulator-off-in-suspend")) | ||
137 | suspend_state->disabled = true; | ||
138 | |||
139 | if (!of_property_read_u32(suspend_np, | ||
140 | "regulator-suspend-microvolt", &pval)) | ||
141 | suspend_state->uV = pval; | ||
142 | |||
143 | of_node_put(suspend_np); | ||
144 | suspend_state = NULL; | ||
145 | suspend_np = NULL; | ||
146 | } | ||
76 | } | 147 | } |
77 | 148 | ||
78 | /** | 149 | /** |
79 | * of_get_regulator_init_data - extract regulator_init_data structure info | 150 | * of_get_regulator_init_data - extract regulator_init_data structure info |
80 | * @dev: device requesting for regulator_init_data | 151 | * @dev: device requesting for regulator_init_data |
152 | * @node: regulator device node | ||
153 | * @desc: regulator description | ||
81 | * | 154 | * |
82 | * Populates regulator_init_data structure by extracting data from device | 155 | * Populates regulator_init_data structure by extracting data from device |
83 | * tree node, returns a pointer to the populated struture or NULL if memory | 156 | * tree node, returns a pointer to the populated struture or NULL if memory |
84 | * alloc fails. | 157 | * alloc fails. |
85 | */ | 158 | */ |
86 | struct regulator_init_data *of_get_regulator_init_data(struct device *dev, | 159 | struct regulator_init_data *of_get_regulator_init_data(struct device *dev, |
87 | struct device_node *node) | 160 | struct device_node *node, |
161 | const struct regulator_desc *desc) | ||
88 | { | 162 | { |
89 | struct regulator_init_data *init_data; | 163 | struct regulator_init_data *init_data; |
90 | 164 | ||
@@ -95,7 +169,7 @@ struct regulator_init_data *of_get_regulator_init_data(struct device *dev, | |||
95 | if (!init_data) | 169 | if (!init_data) |
96 | return NULL; /* Out of memory? */ | 170 | return NULL; /* Out of memory? */ |
97 | 171 | ||
98 | of_get_regulation_constraints(node, &init_data); | 172 | of_get_regulation_constraints(node, &init_data, desc); |
99 | return init_data; | 173 | return init_data; |
100 | } | 174 | } |
101 | EXPORT_SYMBOL_GPL(of_get_regulator_init_data); | 175 | EXPORT_SYMBOL_GPL(of_get_regulator_init_data); |
@@ -176,7 +250,8 @@ int of_regulator_match(struct device *dev, struct device_node *node, | |||
176 | continue; | 250 | continue; |
177 | 251 | ||
178 | match->init_data = | 252 | match->init_data = |
179 | of_get_regulator_init_data(dev, child); | 253 | of_get_regulator_init_data(dev, child, |
254 | match->desc); | ||
180 | if (!match->init_data) { | 255 | if (!match->init_data) { |
181 | dev_err(dev, | 256 | dev_err(dev, |
182 | "failed to parse DT for regulator %s\n", | 257 | "failed to parse DT for regulator %s\n", |
@@ -224,7 +299,7 @@ struct regulator_init_data *regulator_of_get_init_data(struct device *dev, | |||
224 | if (strcmp(desc->of_match, name)) | 299 | if (strcmp(desc->of_match, name)) |
225 | continue; | 300 | continue; |
226 | 301 | ||
227 | init_data = of_get_regulator_init_data(dev, child); | 302 | init_data = of_get_regulator_init_data(dev, child, desc); |
228 | if (!init_data) { | 303 | if (!init_data) { |
229 | dev_err(dev, | 304 | dev_err(dev, |
230 | "failed to parse DT for regulator %s\n", | 305 | "failed to parse DT for regulator %s\n", |
diff --git a/drivers/regulator/pwm-regulator.c b/drivers/regulator/pwm-regulator.c index d3f55eaea058..91f34ca3a9ac 100644 --- a/drivers/regulator/pwm-regulator.c +++ b/drivers/regulator/pwm-regulator.c | |||
@@ -149,7 +149,8 @@ static int pwm_regulator_probe(struct platform_device *pdev) | |||
149 | return ret; | 149 | return ret; |
150 | } | 150 | } |
151 | 151 | ||
152 | config.init_data = of_get_regulator_init_data(&pdev->dev, np); | 152 | config.init_data = of_get_regulator_init_data(&pdev->dev, np, |
153 | &drvdata->desc); | ||
153 | if (!config.init_data) | 154 | if (!config.init_data) |
154 | return -ENOMEM; | 155 | return -ENOMEM; |
155 | 156 | ||
diff --git a/drivers/regulator/qcom_rpm-regulator.c b/drivers/regulator/qcom_rpm-regulator.c index b55cd5b50ebe..183598b111f9 100644 --- a/drivers/regulator/qcom_rpm-regulator.c +++ b/drivers/regulator/qcom_rpm-regulator.c | |||
@@ -183,6 +183,13 @@ static const struct regulator_linear_range ftsmps_ranges[] = { | |||
183 | REGULATOR_LINEAR_RANGE(1500000, 64, 100, 50000), | 183 | REGULATOR_LINEAR_RANGE(1500000, 64, 100, 50000), |
184 | }; | 184 | }; |
185 | 185 | ||
186 | static const struct regulator_linear_range smb208_ranges[] = { | ||
187 | REGULATOR_LINEAR_RANGE( 375000, 0, 29, 12500), | ||
188 | REGULATOR_LINEAR_RANGE( 750000, 30, 89, 12500), | ||
189 | REGULATOR_LINEAR_RANGE(1500000, 90, 153, 25000), | ||
190 | REGULATOR_LINEAR_RANGE(3100000, 154, 234, 25000), | ||
191 | }; | ||
192 | |||
186 | static const struct regulator_linear_range ncp_ranges[] = { | 193 | static const struct regulator_linear_range ncp_ranges[] = { |
187 | REGULATOR_LINEAR_RANGE(1500000, 0, 31, 50000), | 194 | REGULATOR_LINEAR_RANGE(1500000, 0, 31, 50000), |
188 | }; | 195 | }; |
@@ -559,6 +566,16 @@ static const struct qcom_rpm_reg pm8921_switch = { | |||
559 | .parts = &rpm8960_switch_parts, | 566 | .parts = &rpm8960_switch_parts, |
560 | }; | 567 | }; |
561 | 568 | ||
569 | static const struct qcom_rpm_reg smb208_smps = { | ||
570 | .desc.linear_ranges = smb208_ranges, | ||
571 | .desc.n_linear_ranges = ARRAY_SIZE(smb208_ranges), | ||
572 | .desc.n_voltages = 235, | ||
573 | .desc.ops = &uV_ops, | ||
574 | .parts = &rpm8960_smps_parts, | ||
575 | .supports_force_mode_auto = false, | ||
576 | .supports_force_mode_bypass = false, | ||
577 | }; | ||
578 | |||
562 | static const struct of_device_id rpm_of_match[] = { | 579 | static const struct of_device_id rpm_of_match[] = { |
563 | { .compatible = "qcom,rpm-pm8058-pldo", .data = &pm8058_pldo }, | 580 | { .compatible = "qcom,rpm-pm8058-pldo", .data = &pm8058_pldo }, |
564 | { .compatible = "qcom,rpm-pm8058-nldo", .data = &pm8058_nldo }, | 581 | { .compatible = "qcom,rpm-pm8058-nldo", .data = &pm8058_nldo }, |
@@ -578,6 +595,8 @@ static const struct of_device_id rpm_of_match[] = { | |||
578 | { .compatible = "qcom,rpm-pm8921-ftsmps", .data = &pm8921_ftsmps }, | 595 | { .compatible = "qcom,rpm-pm8921-ftsmps", .data = &pm8921_ftsmps }, |
579 | { .compatible = "qcom,rpm-pm8921-ncp", .data = &pm8921_ncp }, | 596 | { .compatible = "qcom,rpm-pm8921-ncp", .data = &pm8921_ncp }, |
580 | { .compatible = "qcom,rpm-pm8921-switch", .data = &pm8921_switch }, | 597 | { .compatible = "qcom,rpm-pm8921-switch", .data = &pm8921_switch }, |
598 | |||
599 | { .compatible = "qcom,rpm-smb208", .data = &smb208_smps }, | ||
581 | { } | 600 | { } |
582 | }; | 601 | }; |
583 | MODULE_DEVICE_TABLE(of, rpm_of_match); | 602 | MODULE_DEVICE_TABLE(of, rpm_of_match); |
@@ -643,10 +662,6 @@ static int rpm_reg_probe(struct platform_device *pdev) | |||
643 | match = of_match_device(rpm_of_match, &pdev->dev); | 662 | match = of_match_device(rpm_of_match, &pdev->dev); |
644 | template = match->data; | 663 | template = match->data; |
645 | 664 | ||
646 | initdata = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node); | ||
647 | if (!initdata) | ||
648 | return -EINVAL; | ||
649 | |||
650 | vreg = devm_kmalloc(&pdev->dev, sizeof(*vreg), GFP_KERNEL); | 665 | vreg = devm_kmalloc(&pdev->dev, sizeof(*vreg), GFP_KERNEL); |
651 | if (!vreg) { | 666 | if (!vreg) { |
652 | dev_err(&pdev->dev, "failed to allocate vreg\n"); | 667 | dev_err(&pdev->dev, "failed to allocate vreg\n"); |
@@ -666,6 +681,11 @@ static int rpm_reg_probe(struct platform_device *pdev) | |||
666 | return -ENODEV; | 681 | return -ENODEV; |
667 | } | 682 | } |
668 | 683 | ||
684 | initdata = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node, | ||
685 | &vreg->desc); | ||
686 | if (!initdata) | ||
687 | return -EINVAL; | ||
688 | |||
669 | key = "reg"; | 689 | key = "reg"; |
670 | ret = of_property_read_u32(pdev->dev.of_node, key, &val); | 690 | ret = of_property_read_u32(pdev->dev.of_node, key, &val); |
671 | if (ret) { | 691 | if (ret) { |
diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c index 196a5c8838c4..ea9d05eabd0a 100644 --- a/drivers/regulator/rk808-regulator.c +++ b/drivers/regulator/rk808-regulator.c | |||
@@ -36,6 +36,12 @@ | |||
36 | #define RK808_RAMP_RATE_6MV_PER_US (2 << RK808_RAMP_RATE_OFFSET) | 36 | #define RK808_RAMP_RATE_6MV_PER_US (2 << RK808_RAMP_RATE_OFFSET) |
37 | #define RK808_RAMP_RATE_10MV_PER_US (3 << RK808_RAMP_RATE_OFFSET) | 37 | #define RK808_RAMP_RATE_10MV_PER_US (3 << RK808_RAMP_RATE_OFFSET) |
38 | 38 | ||
39 | /* Offset from XXX_ON_VSEL to XXX_SLP_VSEL */ | ||
40 | #define RK808_SLP_REG_OFFSET 1 | ||
41 | |||
42 | /* Offset from XXX_EN_REG to SLEEP_SET_OFF_XXX */ | ||
43 | #define RK808_SLP_SET_OFF_REG_OFFSET 2 | ||
44 | |||
39 | static const int rk808_buck_config_regs[] = { | 45 | static const int rk808_buck_config_regs[] = { |
40 | RK808_BUCK1_CONFIG_REG, | 46 | RK808_BUCK1_CONFIG_REG, |
41 | RK808_BUCK2_CONFIG_REG, | 47 | RK808_BUCK2_CONFIG_REG, |
@@ -91,6 +97,43 @@ static int rk808_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) | |||
91 | RK808_RAMP_RATE_MASK, ramp_value); | 97 | RK808_RAMP_RATE_MASK, ramp_value); |
92 | } | 98 | } |
93 | 99 | ||
100 | int rk808_set_suspend_voltage(struct regulator_dev *rdev, int uv) | ||
101 | { | ||
102 | unsigned int reg; | ||
103 | int sel = regulator_map_voltage_linear_range(rdev, uv, uv); | ||
104 | |||
105 | if (sel < 0) | ||
106 | return -EINVAL; | ||
107 | |||
108 | reg = rdev->desc->vsel_reg + RK808_SLP_REG_OFFSET; | ||
109 | |||
110 | return regmap_update_bits(rdev->regmap, reg, | ||
111 | rdev->desc->vsel_mask, | ||
112 | sel); | ||
113 | } | ||
114 | |||
115 | int rk808_set_suspend_enable(struct regulator_dev *rdev) | ||
116 | { | ||
117 | unsigned int reg; | ||
118 | |||
119 | reg = rdev->desc->enable_reg + RK808_SLP_SET_OFF_REG_OFFSET; | ||
120 | |||
121 | return regmap_update_bits(rdev->regmap, reg, | ||
122 | rdev->desc->enable_mask, | ||
123 | 0); | ||
124 | } | ||
125 | |||
126 | int rk808_set_suspend_disable(struct regulator_dev *rdev) | ||
127 | { | ||
128 | unsigned int reg; | ||
129 | |||
130 | reg = rdev->desc->enable_reg + RK808_SLP_SET_OFF_REG_OFFSET; | ||
131 | |||
132 | return regmap_update_bits(rdev->regmap, reg, | ||
133 | rdev->desc->enable_mask, | ||
134 | rdev->desc->enable_mask); | ||
135 | } | ||
136 | |||
94 | static struct regulator_ops rk808_buck1_2_ops = { | 137 | static struct regulator_ops rk808_buck1_2_ops = { |
95 | .list_voltage = regulator_list_voltage_linear_range, | 138 | .list_voltage = regulator_list_voltage_linear_range, |
96 | .map_voltage = regulator_map_voltage_linear_range, | 139 | .map_voltage = regulator_map_voltage_linear_range, |
@@ -100,6 +143,9 @@ static struct regulator_ops rk808_buck1_2_ops = { | |||
100 | .disable = regulator_disable_regmap, | 143 | .disable = regulator_disable_regmap, |
101 | .is_enabled = regulator_is_enabled_regmap, | 144 | .is_enabled = regulator_is_enabled_regmap, |
102 | .set_ramp_delay = rk808_set_ramp_delay, | 145 | .set_ramp_delay = rk808_set_ramp_delay, |
146 | .set_suspend_voltage = rk808_set_suspend_voltage, | ||
147 | .set_suspend_enable = rk808_set_suspend_enable, | ||
148 | .set_suspend_disable = rk808_set_suspend_disable, | ||
103 | }; | 149 | }; |
104 | 150 | ||
105 | static struct regulator_ops rk808_reg_ops = { | 151 | static struct regulator_ops rk808_reg_ops = { |
@@ -110,12 +156,17 @@ static struct regulator_ops rk808_reg_ops = { | |||
110 | .enable = regulator_enable_regmap, | 156 | .enable = regulator_enable_regmap, |
111 | .disable = regulator_disable_regmap, | 157 | .disable = regulator_disable_regmap, |
112 | .is_enabled = regulator_is_enabled_regmap, | 158 | .is_enabled = regulator_is_enabled_regmap, |
159 | .set_suspend_voltage = rk808_set_suspend_voltage, | ||
160 | .set_suspend_enable = rk808_set_suspend_enable, | ||
161 | .set_suspend_disable = rk808_set_suspend_disable, | ||
113 | }; | 162 | }; |
114 | 163 | ||
115 | static struct regulator_ops rk808_switch_ops = { | 164 | static struct regulator_ops rk808_switch_ops = { |
116 | .enable = regulator_enable_regmap, | 165 | .enable = regulator_enable_regmap, |
117 | .disable = regulator_disable_regmap, | 166 | .disable = regulator_disable_regmap, |
118 | .is_enabled = regulator_is_enabled_regmap, | 167 | .is_enabled = regulator_is_enabled_regmap, |
168 | .set_suspend_enable = rk808_set_suspend_enable, | ||
169 | .set_suspend_disable = rk808_set_suspend_disable, | ||
119 | }; | 170 | }; |
120 | 171 | ||
121 | static const struct regulator_desc rk808_reg[] = { | 172 | static const struct regulator_desc rk808_reg[] = { |
diff --git a/drivers/regulator/rn5t618-regulator.c b/drivers/regulator/rn5t618-regulator.c index e58d79aeb393..b85ceb8ff911 100644 --- a/drivers/regulator/rn5t618-regulator.c +++ b/drivers/regulator/rn5t618-regulator.c | |||
@@ -31,6 +31,8 @@ static struct regulator_ops rn5t618_reg_ops = { | |||
31 | #define REG(rid, ereg, emask, vreg, vmask, min, max, step) \ | 31 | #define REG(rid, ereg, emask, vreg, vmask, min, max, step) \ |
32 | [RN5T618_##rid] = { \ | 32 | [RN5T618_##rid] = { \ |
33 | .name = #rid, \ | 33 | .name = #rid, \ |
34 | .of_match = of_match_ptr(#rid), \ | ||
35 | .regulators_node = of_match_ptr("regulators"), \ | ||
34 | .id = RN5T618_##rid, \ | 36 | .id = RN5T618_##rid, \ |
35 | .type = REGULATOR_VOLTAGE, \ | 37 | .type = REGULATOR_VOLTAGE, \ |
36 | .owner = THIS_MODULE, \ | 38 | .owner = THIS_MODULE, \ |
@@ -60,60 +62,15 @@ static struct regulator_desc rn5t618_regulators[] = { | |||
60 | REG(LDORTC2, LDOEN2, BIT(5), LDORTC2DAC, 0x7f, 900000, 3500000, 25000), | 62 | REG(LDORTC2, LDOEN2, BIT(5), LDORTC2DAC, 0x7f, 900000, 3500000, 25000), |
61 | }; | 63 | }; |
62 | 64 | ||
63 | static struct of_regulator_match rn5t618_matches[] = { | ||
64 | [RN5T618_DCDC1] = { .name = "DCDC1" }, | ||
65 | [RN5T618_DCDC2] = { .name = "DCDC2" }, | ||
66 | [RN5T618_DCDC3] = { .name = "DCDC3" }, | ||
67 | [RN5T618_LDO1] = { .name = "LDO1" }, | ||
68 | [RN5T618_LDO2] = { .name = "LDO2" }, | ||
69 | [RN5T618_LDO3] = { .name = "LDO3" }, | ||
70 | [RN5T618_LDO4] = { .name = "LDO4" }, | ||
71 | [RN5T618_LDO5] = { .name = "LDO5" }, | ||
72 | [RN5T618_LDORTC1] = { .name = "LDORTC1" }, | ||
73 | [RN5T618_LDORTC2] = { .name = "LDORTC2" }, | ||
74 | }; | ||
75 | |||
76 | static int rn5t618_regulator_parse_dt(struct platform_device *pdev) | ||
77 | { | ||
78 | struct device_node *np, *regulators; | ||
79 | int ret; | ||
80 | |||
81 | np = of_node_get(pdev->dev.parent->of_node); | ||
82 | if (!np) | ||
83 | return 0; | ||
84 | |||
85 | regulators = of_get_child_by_name(np, "regulators"); | ||
86 | if (!regulators) { | ||
87 | dev_err(&pdev->dev, "regulators node not found\n"); | ||
88 | return -EINVAL; | ||
89 | } | ||
90 | |||
91 | ret = of_regulator_match(&pdev->dev, regulators, rn5t618_matches, | ||
92 | ARRAY_SIZE(rn5t618_matches)); | ||
93 | of_node_put(regulators); | ||
94 | if (ret < 0) { | ||
95 | dev_err(&pdev->dev, "error parsing regulator init data: %d\n", | ||
96 | ret); | ||
97 | } | ||
98 | |||
99 | return 0; | ||
100 | } | ||
101 | |||
102 | static int rn5t618_regulator_probe(struct platform_device *pdev) | 65 | static int rn5t618_regulator_probe(struct platform_device *pdev) |
103 | { | 66 | { |
104 | struct rn5t618 *rn5t618 = dev_get_drvdata(pdev->dev.parent); | 67 | struct rn5t618 *rn5t618 = dev_get_drvdata(pdev->dev.parent); |
105 | struct regulator_config config = { }; | 68 | struct regulator_config config = { }; |
106 | struct regulator_dev *rdev; | 69 | struct regulator_dev *rdev; |
107 | int ret, i; | 70 | int i; |
108 | |||
109 | ret = rn5t618_regulator_parse_dt(pdev); | ||
110 | if (ret) | ||
111 | return ret; | ||
112 | 71 | ||
113 | for (i = 0; i < RN5T618_REG_NUM; i++) { | 72 | for (i = 0; i < RN5T618_REG_NUM; i++) { |
114 | config.dev = &pdev->dev; | 73 | config.dev = pdev->dev.parent; |
115 | config.init_data = rn5t618_matches[i].init_data; | ||
116 | config.of_node = rn5t618_matches[i].of_node; | ||
117 | config.regmap = rn5t618->regmap; | 74 | config.regmap = rn5t618->regmap; |
118 | 75 | ||
119 | rdev = devm_regulator_register(&pdev->dev, | 76 | rdev = devm_regulator_register(&pdev->dev, |
diff --git a/drivers/regulator/rt5033-regulator.c b/drivers/regulator/rt5033-regulator.c new file mode 100644 index 000000000000..870cc49438db --- /dev/null +++ b/drivers/regulator/rt5033-regulator.c | |||
@@ -0,0 +1,123 @@ | |||
1 | /* | ||
2 | * Regulator driver for the Richtek RT5033 | ||
3 | * | ||
4 | * Copyright (C) 2014 Samsung Electronics, Co., Ltd. | ||
5 | * Author: Beomho Seo <beomho.seo@samsung.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published bythe Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/platform_device.h> | ||
14 | #include <linux/regulator/driver.h> | ||
15 | #include <linux/mfd/rt5033.h> | ||
16 | #include <linux/mfd/rt5033-private.h> | ||
17 | #include <linux/regulator/of_regulator.h> | ||
18 | |||
19 | static struct regulator_ops rt5033_safe_ldo_ops = { | ||
20 | .is_enabled = regulator_is_enabled_regmap, | ||
21 | .enable = regulator_enable_regmap, | ||
22 | .disable = regulator_disable_regmap, | ||
23 | .list_voltage = regulator_list_voltage_linear, | ||
24 | }; | ||
25 | |||
26 | static struct regulator_ops rt5033_buck_ops = { | ||
27 | .is_enabled = regulator_is_enabled_regmap, | ||
28 | .enable = regulator_enable_regmap, | ||
29 | .disable = regulator_disable_regmap, | ||
30 | .list_voltage = regulator_list_voltage_linear, | ||
31 | .map_voltage = regulator_map_voltage_linear, | ||
32 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
33 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
34 | }; | ||
35 | |||
36 | static const struct regulator_desc rt5033_supported_regulators[] = { | ||
37 | [RT5033_BUCK] = { | ||
38 | .name = "BUCK", | ||
39 | .id = RT5033_BUCK, | ||
40 | .ops = &rt5033_buck_ops, | ||
41 | .type = REGULATOR_VOLTAGE, | ||
42 | .owner = THIS_MODULE, | ||
43 | .n_voltages = RT5033_REGULATOR_BUCK_VOLTAGE_STEP_NUM, | ||
44 | .min_uV = RT5033_REGULATOR_BUCK_VOLTAGE_MIN, | ||
45 | .uV_step = RT5033_REGULATOR_BUCK_VOLTAGE_STEP, | ||
46 | .enable_reg = RT5033_REG_CTRL, | ||
47 | .enable_mask = RT5033_CTRL_EN_BUCK_MASK, | ||
48 | .vsel_reg = RT5033_REG_BUCK_CTRL, | ||
49 | .vsel_mask = RT5033_BUCK_CTRL_MASK, | ||
50 | }, | ||
51 | [RT5033_LDO] = { | ||
52 | .name = "LDO", | ||
53 | .id = RT5033_LDO, | ||
54 | .ops = &rt5033_buck_ops, | ||
55 | .type = REGULATOR_VOLTAGE, | ||
56 | .owner = THIS_MODULE, | ||
57 | .n_voltages = RT5033_REGULATOR_LDO_VOLTAGE_STEP_NUM, | ||
58 | .min_uV = RT5033_REGULATOR_LDO_VOLTAGE_MIN, | ||
59 | .uV_step = RT5033_REGULATOR_LDO_VOLTAGE_STEP, | ||
60 | .enable_reg = RT5033_REG_CTRL, | ||
61 | .enable_mask = RT5033_CTRL_EN_LDO_MASK, | ||
62 | .vsel_reg = RT5033_REG_LDO_CTRL, | ||
63 | .vsel_mask = RT5033_LDO_CTRL_MASK, | ||
64 | }, | ||
65 | [RT5033_SAFE_LDO] = { | ||
66 | .name = "SAFE_LDO", | ||
67 | .id = RT5033_SAFE_LDO, | ||
68 | .ops = &rt5033_safe_ldo_ops, | ||
69 | .type = REGULATOR_VOLTAGE, | ||
70 | .owner = THIS_MODULE, | ||
71 | .n_voltages = 1, | ||
72 | .min_uV = RT5033_REGULATOR_SAFE_LDO_VOLTAGE, | ||
73 | .enable_reg = RT5033_REG_CTRL, | ||
74 | .enable_mask = RT5033_CTRL_EN_SAFE_LDO_MASK, | ||
75 | }, | ||
76 | }; | ||
77 | |||
78 | static int rt5033_regulator_probe(struct platform_device *pdev) | ||
79 | { | ||
80 | struct rt5033_dev *rt5033 = dev_get_drvdata(pdev->dev.parent); | ||
81 | int ret, i; | ||
82 | struct regulator_config config = {}; | ||
83 | |||
84 | config.dev = &pdev->dev; | ||
85 | config.driver_data = rt5033; | ||
86 | |||
87 | for (i = 0; i < ARRAY_SIZE(rt5033_supported_regulators); i++) { | ||
88 | struct regulator_dev *regulator; | ||
89 | |||
90 | config.regmap = rt5033->regmap; | ||
91 | |||
92 | regulator = devm_regulator_register(&pdev->dev, | ||
93 | &rt5033_supported_regulators[i], &config); | ||
94 | if (IS_ERR(regulator)) { | ||
95 | ret = PTR_ERR(regulator); | ||
96 | dev_err(&pdev->dev, | ||
97 | "Regulator init failed %d: with error: %d\n", | ||
98 | i, ret); | ||
99 | return ret; | ||
100 | } | ||
101 | } | ||
102 | |||
103 | return 0; | ||
104 | } | ||
105 | |||
106 | static const struct platform_device_id rt5033_regulator_id[] = { | ||
107 | { "rt5033-regulator", }, | ||
108 | { } | ||
109 | }; | ||
110 | MODULE_DEVICE_TABLE(platform, rt5033_regulator_id); | ||
111 | |||
112 | static struct platform_driver rt5033_regulator_driver = { | ||
113 | .driver = { | ||
114 | .name = "rt5033-regulator", | ||
115 | }, | ||
116 | .probe = rt5033_regulator_probe, | ||
117 | .id_table = rt5033_regulator_id, | ||
118 | }; | ||
119 | module_platform_driver(rt5033_regulator_driver); | ||
120 | |||
121 | MODULE_DESCRIPTION("Richtek RT5033 Regulator driver"); | ||
122 | MODULE_AUTHOR("Beomho Seo <beomho.seo@samsung.com>"); | ||
123 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/regulator/s2mpa01.c b/drivers/regulator/s2mpa01.c index 7633b9bfbe6e..5db4e12a7e04 100644 --- a/drivers/regulator/s2mpa01.c +++ b/drivers/regulator/s2mpa01.c | |||
@@ -298,7 +298,7 @@ static struct regulator_ops s2mpa01_buck_ops = { | |||
298 | .enable_mask = S2MPA01_ENABLE_MASK \ | 298 | .enable_mask = S2MPA01_ENABLE_MASK \ |
299 | } | 299 | } |
300 | 300 | ||
301 | static struct regulator_desc regulators[] = { | 301 | static const struct regulator_desc regulators[] = { |
302 | regulator_desc_ldo(1, STEP_25_MV), | 302 | regulator_desc_ldo(1, STEP_25_MV), |
303 | regulator_desc_ldo(2, STEP_50_MV), | 303 | regulator_desc_ldo(2, STEP_50_MV), |
304 | regulator_desc_ldo(3, STEP_50_MV), | 304 | regulator_desc_ldo(3, STEP_50_MV), |
diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c index 738dc7763d47..b345cf51225a 100644 --- a/drivers/regulator/s2mps11.c +++ b/drivers/regulator/s2mps11.c | |||
@@ -940,7 +940,7 @@ static int s2mps11_pmic_probe(struct platform_device *pdev) | |||
940 | return -EINVAL; | 940 | return -EINVAL; |
941 | }; | 941 | }; |
942 | 942 | ||
943 | s2mps11->ext_control_gpio = devm_kzalloc(&pdev->dev, | 943 | s2mps11->ext_control_gpio = devm_kmalloc(&pdev->dev, |
944 | sizeof(*s2mps11->ext_control_gpio) * s2mps11->rdev_num, | 944 | sizeof(*s2mps11->ext_control_gpio) * s2mps11->rdev_num, |
945 | GFP_KERNEL); | 945 | GFP_KERNEL); |
946 | if (!s2mps11->ext_control_gpio) | 946 | if (!s2mps11->ext_control_gpio) |
@@ -981,6 +981,7 @@ common_reg: | |||
981 | config.regmap = iodev->regmap_pmic; | 981 | config.regmap = iodev->regmap_pmic; |
982 | config.driver_data = s2mps11; | 982 | config.driver_data = s2mps11; |
983 | config.ena_gpio_flags = GPIOF_OUT_INIT_HIGH; | 983 | config.ena_gpio_flags = GPIOF_OUT_INIT_HIGH; |
984 | config.ena_gpio_initialized = true; | ||
984 | for (i = 0; i < s2mps11->rdev_num; i++) { | 985 | for (i = 0; i < s2mps11->rdev_num; i++) { |
985 | struct regulator_dev *regulator; | 986 | struct regulator_dev *regulator; |
986 | 987 | ||
diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index 0ab5cbeeb797..dc1328c0c71c 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c | |||
@@ -581,7 +581,8 @@ static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev, | |||
581 | 581 | ||
582 | rdata->id = i; | 582 | rdata->id = i; |
583 | rdata->initdata = of_get_regulator_init_data( | 583 | rdata->initdata = of_get_regulator_init_data( |
584 | &pdev->dev, reg_np); | 584 | &pdev->dev, reg_np, |
585 | ®ulators[i]); | ||
585 | rdata->reg_node = reg_np; | 586 | rdata->reg_node = reg_np; |
586 | rdata++; | 587 | rdata++; |
587 | rmode->id = i; | 588 | rmode->id = i; |
@@ -950,6 +951,7 @@ static int s5m8767_pmic_probe(struct platform_device *pdev) | |||
950 | config.of_node = pdata->regulators[i].reg_node; | 951 | config.of_node = pdata->regulators[i].reg_node; |
951 | config.ena_gpio = -EINVAL; | 952 | config.ena_gpio = -EINVAL; |
952 | config.ena_gpio_flags = 0; | 953 | config.ena_gpio_flags = 0; |
954 | config.ena_gpio_initialized = true; | ||
953 | if (gpio_is_valid(pdata->regulators[i].ext_control_gpio)) | 955 | if (gpio_is_valid(pdata->regulators[i].ext_control_gpio)) |
954 | s5m8767_regulator_config_ext_control(s5m8767, | 956 | s5m8767_regulator_config_ext_control(s5m8767, |
955 | &pdata->regulators[i], &config); | 957 | &pdata->regulators[i], &config); |
diff --git a/drivers/regulator/sky81452-regulator.c b/drivers/regulator/sky81452-regulator.c index 97aff0ccd65f..647860611916 100644 --- a/drivers/regulator/sky81452-regulator.c +++ b/drivers/regulator/sky81452-regulator.c | |||
@@ -5,9 +5,8 @@ | |||
5 | * Author : Gyungoh Yoo <jack.yoo@skyworksinc.com> | 5 | * Author : Gyungoh Yoo <jack.yoo@skyworksinc.com> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
8 | * under the terms of the GNU General Public License as published by the | 8 | * under the terms of the GNU General Public License version 2 |
9 | * Free Software Foundation; either version 2, or (at your option) any | 9 | * as published by the Free Software Foundation. |
10 | * later version. | ||
11 | * | 10 | * |
12 | * This program is distributed in the hope that it will be useful, but | 11 | * This program is distributed in the hope that it will be useful, but |
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
@@ -52,6 +51,8 @@ static const struct regulator_linear_range sky81452_reg_ranges[] = { | |||
52 | 51 | ||
53 | static const struct regulator_desc sky81452_reg = { | 52 | static const struct regulator_desc sky81452_reg = { |
54 | .name = "LOUT", | 53 | .name = "LOUT", |
54 | .of_match = of_match_ptr("lout"), | ||
55 | .regulators_node = of_match_ptr("regulator"), | ||
55 | .ops = &sky81452_reg_ops, | 56 | .ops = &sky81452_reg_ops, |
56 | .type = REGULATOR_VOLTAGE, | 57 | .type = REGULATOR_VOLTAGE, |
57 | .owner = THIS_MODULE, | 58 | .owner = THIS_MODULE, |
@@ -64,30 +65,6 @@ static const struct regulator_desc sky81452_reg = { | |||
64 | .enable_mask = SKY81452_LEN, | 65 | .enable_mask = SKY81452_LEN, |
65 | }; | 66 | }; |
66 | 67 | ||
67 | #ifdef CONFIG_OF | ||
68 | static struct regulator_init_data *sky81452_reg_parse_dt(struct device *dev) | ||
69 | { | ||
70 | struct regulator_init_data *init_data; | ||
71 | struct device_node *np; | ||
72 | |||
73 | np = of_get_child_by_name(dev->parent->of_node, "regulator"); | ||
74 | if (unlikely(!np)) { | ||
75 | dev_err(dev, "regulator node not found"); | ||
76 | return NULL; | ||
77 | } | ||
78 | |||
79 | init_data = of_get_regulator_init_data(dev, np); | ||
80 | |||
81 | of_node_put(np); | ||
82 | return init_data; | ||
83 | } | ||
84 | #else | ||
85 | static struct regulator_init_data *sky81452_reg_parse_dt(struct device *dev) | ||
86 | { | ||
87 | return ERR_PTR(-EINVAL); | ||
88 | } | ||
89 | #endif | ||
90 | |||
91 | static int sky81452_reg_probe(struct platform_device *pdev) | 68 | static int sky81452_reg_probe(struct platform_device *pdev) |
92 | { | 69 | { |
93 | struct device *dev = &pdev->dev; | 70 | struct device *dev = &pdev->dev; |
@@ -95,20 +72,16 @@ static int sky81452_reg_probe(struct platform_device *pdev) | |||
95 | struct regulator_config config = { }; | 72 | struct regulator_config config = { }; |
96 | struct regulator_dev *rdev; | 73 | struct regulator_dev *rdev; |
97 | 74 | ||
98 | if (!init_data) { | 75 | config.dev = dev->parent; |
99 | init_data = sky81452_reg_parse_dt(dev); | ||
100 | if (IS_ERR(init_data)) | ||
101 | return PTR_ERR(init_data); | ||
102 | } | ||
103 | |||
104 | config.dev = dev; | ||
105 | config.init_data = init_data; | 76 | config.init_data = init_data; |
106 | config.of_node = dev->of_node; | 77 | config.of_node = dev->of_node; |
107 | config.regmap = dev_get_drvdata(dev->parent); | 78 | config.regmap = dev_get_drvdata(dev->parent); |
108 | 79 | ||
109 | rdev = devm_regulator_register(dev, &sky81452_reg, &config); | 80 | rdev = devm_regulator_register(dev, &sky81452_reg, &config); |
110 | if (IS_ERR(rdev)) | 81 | if (IS_ERR(rdev)) { |
82 | dev_err(dev, "failed to register. err=%ld\n", PTR_ERR(rdev)); | ||
111 | return PTR_ERR(rdev); | 83 | return PTR_ERR(rdev); |
84 | } | ||
112 | 85 | ||
113 | platform_set_drvdata(pdev, rdev); | 86 | platform_set_drvdata(pdev, rdev); |
114 | 87 | ||
@@ -126,5 +99,4 @@ module_platform_driver(sky81452_reg_driver); | |||
126 | 99 | ||
127 | MODULE_DESCRIPTION("Skyworks SKY81452 Regulator driver"); | 100 | MODULE_DESCRIPTION("Skyworks SKY81452 Regulator driver"); |
128 | MODULE_AUTHOR("Gyungoh Yoo <jack.yoo@skyworksinc.com>"); | 101 | MODULE_AUTHOR("Gyungoh Yoo <jack.yoo@skyworksinc.com>"); |
129 | MODULE_LICENSE("GPL"); | 102 | MODULE_LICENSE("GPL v2"); |
130 | MODULE_VERSION("1.0"); | ||
diff --git a/drivers/regulator/stw481x-vmmc.c b/drivers/regulator/stw481x-vmmc.c index a7e152696a02..b4f1696456a7 100644 --- a/drivers/regulator/stw481x-vmmc.c +++ b/drivers/regulator/stw481x-vmmc.c | |||
@@ -72,7 +72,8 @@ static int stw481x_vmmc_regulator_probe(struct platform_device *pdev) | |||
72 | config.regmap = stw481x->map; | 72 | config.regmap = stw481x->map; |
73 | config.of_node = pdev->dev.of_node; | 73 | config.of_node = pdev->dev.of_node; |
74 | config.init_data = of_get_regulator_init_data(&pdev->dev, | 74 | config.init_data = of_get_regulator_init_data(&pdev->dev, |
75 | pdev->dev.of_node); | 75 | pdev->dev.of_node, |
76 | &vmmc_regulator); | ||
76 | 77 | ||
77 | stw481x->vmmc_regulator = devm_regulator_register(&pdev->dev, | 78 | stw481x->vmmc_regulator = devm_regulator_register(&pdev->dev, |
78 | &vmmc_regulator, &config); | 79 | &vmmc_regulator, &config); |
diff --git a/drivers/regulator/ti-abb-regulator.c b/drivers/regulator/ti-abb-regulator.c index a2dabb575b97..1ef5aba96f17 100644 --- a/drivers/regulator/ti-abb-regulator.c +++ b/drivers/regulator/ti-abb-regulator.c | |||
@@ -837,7 +837,8 @@ skip_opt: | |||
837 | return -EINVAL; | 837 | return -EINVAL; |
838 | } | 838 | } |
839 | 839 | ||
840 | initdata = of_get_regulator_init_data(dev, pdev->dev.of_node); | 840 | initdata = of_get_regulator_init_data(dev, pdev->dev.of_node, |
841 | &abb->rdesc); | ||
841 | if (!initdata) { | 842 | if (!initdata) { |
842 | dev_err(dev, "%s: Unable to alloc regulator init data\n", | 843 | dev_err(dev, "%s: Unable to alloc regulator init data\n", |
843 | __func__); | 844 | __func__); |
diff --git a/drivers/regulator/tps51632-regulator.c b/drivers/regulator/tps51632-regulator.c index f31f22e3e1bd..c213e37eb69e 100644 --- a/drivers/regulator/tps51632-regulator.c +++ b/drivers/regulator/tps51632-regulator.c | |||
@@ -221,7 +221,8 @@ static const struct of_device_id tps51632_of_match[] = { | |||
221 | MODULE_DEVICE_TABLE(of, tps51632_of_match); | 221 | MODULE_DEVICE_TABLE(of, tps51632_of_match); |
222 | 222 | ||
223 | static struct tps51632_regulator_platform_data * | 223 | static struct tps51632_regulator_platform_data * |
224 | of_get_tps51632_platform_data(struct device *dev) | 224 | of_get_tps51632_platform_data(struct device *dev, |
225 | const struct regulator_desc *desc) | ||
225 | { | 226 | { |
226 | struct tps51632_regulator_platform_data *pdata; | 227 | struct tps51632_regulator_platform_data *pdata; |
227 | struct device_node *np = dev->of_node; | 228 | struct device_node *np = dev->of_node; |
@@ -230,7 +231,8 @@ static struct tps51632_regulator_platform_data * | |||
230 | if (!pdata) | 231 | if (!pdata) |
231 | return NULL; | 232 | return NULL; |
232 | 233 | ||
233 | pdata->reg_init_data = of_get_regulator_init_data(dev, dev->of_node); | 234 | pdata->reg_init_data = of_get_regulator_init_data(dev, dev->of_node, |
235 | desc); | ||
234 | if (!pdata->reg_init_data) { | 236 | if (!pdata->reg_init_data) { |
235 | dev_err(dev, "Not able to get OF regulator init data\n"); | 237 | dev_err(dev, "Not able to get OF regulator init data\n"); |
236 | return NULL; | 238 | return NULL; |
@@ -248,7 +250,8 @@ static struct tps51632_regulator_platform_data * | |||
248 | } | 250 | } |
249 | #else | 251 | #else |
250 | static struct tps51632_regulator_platform_data * | 252 | static struct tps51632_regulator_platform_data * |
251 | of_get_tps51632_platform_data(struct device *dev) | 253 | of_get_tps51632_platform_data(struct device *dev, |
254 | const struct regulator_desc *desc) | ||
252 | { | 255 | { |
253 | return NULL; | 256 | return NULL; |
254 | } | 257 | } |
@@ -273,9 +276,25 @@ static int tps51632_probe(struct i2c_client *client, | |||
273 | } | 276 | } |
274 | } | 277 | } |
275 | 278 | ||
279 | tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); | ||
280 | if (!tps) | ||
281 | return -ENOMEM; | ||
282 | |||
283 | tps->dev = &client->dev; | ||
284 | tps->desc.name = client->name; | ||
285 | tps->desc.id = 0; | ||
286 | tps->desc.ramp_delay = TPS51632_DEFAULT_RAMP_DELAY; | ||
287 | tps->desc.min_uV = TPS51632_MIN_VOLTAGE; | ||
288 | tps->desc.uV_step = TPS51632_VOLTAGE_STEP_10mV; | ||
289 | tps->desc.linear_min_sel = TPS51632_MIN_VSEL; | ||
290 | tps->desc.n_voltages = TPS51632_MAX_VSEL + 1; | ||
291 | tps->desc.ops = &tps51632_dcdc_ops; | ||
292 | tps->desc.type = REGULATOR_VOLTAGE; | ||
293 | tps->desc.owner = THIS_MODULE; | ||
294 | |||
276 | pdata = dev_get_platdata(&client->dev); | 295 | pdata = dev_get_platdata(&client->dev); |
277 | if (!pdata && client->dev.of_node) | 296 | if (!pdata && client->dev.of_node) |
278 | pdata = of_get_tps51632_platform_data(&client->dev); | 297 | pdata = of_get_tps51632_platform_data(&client->dev, &tps->desc); |
279 | if (!pdata) { | 298 | if (!pdata) { |
280 | dev_err(&client->dev, "No Platform data\n"); | 299 | dev_err(&client->dev, "No Platform data\n"); |
281 | return -EINVAL; | 300 | return -EINVAL; |
@@ -296,22 +315,6 @@ static int tps51632_probe(struct i2c_client *client, | |||
296 | } | 315 | } |
297 | } | 316 | } |
298 | 317 | ||
299 | tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); | ||
300 | if (!tps) | ||
301 | return -ENOMEM; | ||
302 | |||
303 | tps->dev = &client->dev; | ||
304 | tps->desc.name = client->name; | ||
305 | tps->desc.id = 0; | ||
306 | tps->desc.ramp_delay = TPS51632_DEFAULT_RAMP_DELAY; | ||
307 | tps->desc.min_uV = TPS51632_MIN_VOLTAGE; | ||
308 | tps->desc.uV_step = TPS51632_VOLTAGE_STEP_10mV; | ||
309 | tps->desc.linear_min_sel = TPS51632_MIN_VSEL; | ||
310 | tps->desc.n_voltages = TPS51632_MAX_VSEL + 1; | ||
311 | tps->desc.ops = &tps51632_dcdc_ops; | ||
312 | tps->desc.type = REGULATOR_VOLTAGE; | ||
313 | tps->desc.owner = THIS_MODULE; | ||
314 | |||
315 | if (pdata->enable_pwm_dvfs) | 318 | if (pdata->enable_pwm_dvfs) |
316 | tps->desc.vsel_reg = TPS51632_VOLTAGE_BASE_REG; | 319 | tps->desc.vsel_reg = TPS51632_VOLTAGE_BASE_REG; |
317 | else | 320 | else |
diff --git a/drivers/regulator/tps62360-regulator.c b/drivers/regulator/tps62360-regulator.c index a1672044e519..a1fd626c6c96 100644 --- a/drivers/regulator/tps62360-regulator.c +++ b/drivers/regulator/tps62360-regulator.c | |||
@@ -293,7 +293,8 @@ static const struct regmap_config tps62360_regmap_config = { | |||
293 | }; | 293 | }; |
294 | 294 | ||
295 | static struct tps62360_regulator_platform_data * | 295 | static struct tps62360_regulator_platform_data * |
296 | of_get_tps62360_platform_data(struct device *dev) | 296 | of_get_tps62360_platform_data(struct device *dev, |
297 | const struct regulator_desc *desc) | ||
297 | { | 298 | { |
298 | struct tps62360_regulator_platform_data *pdata; | 299 | struct tps62360_regulator_platform_data *pdata; |
299 | struct device_node *np = dev->of_node; | 300 | struct device_node *np = dev->of_node; |
@@ -302,7 +303,8 @@ static struct tps62360_regulator_platform_data * | |||
302 | if (!pdata) | 303 | if (!pdata) |
303 | return NULL; | 304 | return NULL; |
304 | 305 | ||
305 | pdata->reg_init_data = of_get_regulator_init_data(dev, dev->of_node); | 306 | pdata->reg_init_data = of_get_regulator_init_data(dev, dev->of_node, |
307 | desc); | ||
306 | if (!pdata->reg_init_data) { | 308 | if (!pdata->reg_init_data) { |
307 | dev_err(dev, "Not able to get OF regulator init data\n"); | 309 | dev_err(dev, "Not able to get OF regulator init data\n"); |
308 | return NULL; | 310 | return NULL; |
@@ -350,6 +352,17 @@ static int tps62360_probe(struct i2c_client *client, | |||
350 | 352 | ||
351 | pdata = dev_get_platdata(&client->dev); | 353 | pdata = dev_get_platdata(&client->dev); |
352 | 354 | ||
355 | tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); | ||
356 | if (!tps) | ||
357 | return -ENOMEM; | ||
358 | |||
359 | tps->desc.name = client->name; | ||
360 | tps->desc.id = 0; | ||
361 | tps->desc.ops = &tps62360_dcdc_ops; | ||
362 | tps->desc.type = REGULATOR_VOLTAGE; | ||
363 | tps->desc.owner = THIS_MODULE; | ||
364 | tps->desc.uV_step = 10000; | ||
365 | |||
353 | if (client->dev.of_node) { | 366 | if (client->dev.of_node) { |
354 | const struct of_device_id *match; | 367 | const struct of_device_id *match; |
355 | match = of_match_device(of_match_ptr(tps62360_of_match), | 368 | match = of_match_device(of_match_ptr(tps62360_of_match), |
@@ -360,7 +373,8 @@ static int tps62360_probe(struct i2c_client *client, | |||
360 | } | 373 | } |
361 | chip_id = (int)(long)match->data; | 374 | chip_id = (int)(long)match->data; |
362 | if (!pdata) | 375 | if (!pdata) |
363 | pdata = of_get_tps62360_platform_data(&client->dev); | 376 | pdata = of_get_tps62360_platform_data(&client->dev, |
377 | &tps->desc); | ||
364 | } else if (id) { | 378 | } else if (id) { |
365 | chip_id = id->driver_data; | 379 | chip_id = id->driver_data; |
366 | } else { | 380 | } else { |
@@ -374,10 +388,6 @@ static int tps62360_probe(struct i2c_client *client, | |||
374 | return -EIO; | 388 | return -EIO; |
375 | } | 389 | } |
376 | 390 | ||
377 | tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); | ||
378 | if (!tps) | ||
379 | return -ENOMEM; | ||
380 | |||
381 | tps->en_discharge = pdata->en_discharge; | 391 | tps->en_discharge = pdata->en_discharge; |
382 | tps->en_internal_pulldn = pdata->en_internal_pulldn; | 392 | tps->en_internal_pulldn = pdata->en_internal_pulldn; |
383 | tps->vsel0_gpio = pdata->vsel0_gpio; | 393 | tps->vsel0_gpio = pdata->vsel0_gpio; |
@@ -401,13 +411,6 @@ static int tps62360_probe(struct i2c_client *client, | |||
401 | return -ENODEV; | 411 | return -ENODEV; |
402 | } | 412 | } |
403 | 413 | ||
404 | tps->desc.name = client->name; | ||
405 | tps->desc.id = 0; | ||
406 | tps->desc.ops = &tps62360_dcdc_ops; | ||
407 | tps->desc.type = REGULATOR_VOLTAGE; | ||
408 | tps->desc.owner = THIS_MODULE; | ||
409 | tps->desc.uV_step = 10000; | ||
410 | |||
411 | tps->regmap = devm_regmap_init_i2c(client, &tps62360_regmap_config); | 414 | tps->regmap = devm_regmap_init_i2c(client, &tps62360_regmap_config); |
412 | if (IS_ERR(tps->regmap)) { | 415 | if (IS_ERR(tps->regmap)) { |
413 | ret = PTR_ERR(tps->regmap); | 416 | ret = PTR_ERR(tps->regmap); |
diff --git a/drivers/regulator/tps65090-regulator.c b/drivers/regulator/tps65090-regulator.c index d5df1e9ad1da..f1df4423d361 100644 --- a/drivers/regulator/tps65090-regulator.c +++ b/drivers/regulator/tps65090-regulator.c | |||
@@ -312,7 +312,11 @@ static void tps65090_configure_regulator_config( | |||
312 | gpio_flag = GPIOF_OUT_INIT_HIGH; | 312 | gpio_flag = GPIOF_OUT_INIT_HIGH; |
313 | 313 | ||
314 | config->ena_gpio = tps_pdata->gpio; | 314 | config->ena_gpio = tps_pdata->gpio; |
315 | config->ena_gpio_initialized = true; | ||
315 | config->ena_gpio_flags = gpio_flag; | 316 | config->ena_gpio_flags = gpio_flag; |
317 | } else { | ||
318 | config->ena_gpio = -EINVAL; | ||
319 | config->ena_gpio_initialized = false; | ||
316 | } | 320 | } |
317 | } | 321 | } |
318 | 322 | ||
diff --git a/drivers/regulator/tps65218-regulator.c b/drivers/regulator/tps65218-regulator.c index f0a40281b9c1..263cc85d6202 100644 --- a/drivers/regulator/tps65218-regulator.c +++ b/drivers/regulator/tps65218-regulator.c | |||
@@ -231,7 +231,8 @@ static int tps65218_regulator_probe(struct platform_device *pdev) | |||
231 | 231 | ||
232 | template = match->data; | 232 | template = match->data; |
233 | id = template->id; | 233 | id = template->id; |
234 | init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node); | 234 | init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node, |
235 | ®ulators[id]); | ||
235 | 236 | ||
236 | platform_set_drvdata(pdev, tps); | 237 | platform_set_drvdata(pdev, tps); |
237 | 238 | ||
diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index 0b4f8660fdb4..dd727bca1983 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c | |||
@@ -1104,7 +1104,8 @@ static int twlreg_probe(struct platform_device *pdev) | |||
1104 | template = match->data; | 1104 | template = match->data; |
1105 | id = template->desc.id; | 1105 | id = template->desc.id; |
1106 | initdata = of_get_regulator_init_data(&pdev->dev, | 1106 | initdata = of_get_regulator_init_data(&pdev->dev, |
1107 | pdev->dev.of_node); | 1107 | pdev->dev.of_node, |
1108 | &template->desc); | ||
1108 | drvdata = NULL; | 1109 | drvdata = NULL; |
1109 | } else { | 1110 | } else { |
1110 | id = pdev->id; | 1111 | id = pdev->id; |
diff --git a/drivers/regulator/vexpress.c b/drivers/regulator/vexpress.c index 02e7267ccf92..5e7c789023a9 100644 --- a/drivers/regulator/vexpress.c +++ b/drivers/regulator/vexpress.c | |||
@@ -74,7 +74,8 @@ static int vexpress_regulator_probe(struct platform_device *pdev) | |||
74 | reg->desc.owner = THIS_MODULE; | 74 | reg->desc.owner = THIS_MODULE; |
75 | reg->desc.continuous_voltage_range = true; | 75 | reg->desc.continuous_voltage_range = true; |
76 | 76 | ||
77 | init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node); | 77 | init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node, |
78 | ®->desc); | ||
78 | if (!init_data) | 79 | if (!init_data) |
79 | return -EINVAL; | 80 | return -EINVAL; |
80 | 81 | ||
diff --git a/drivers/regulator/wm8994-regulator.c b/drivers/regulator/wm8994-regulator.c index c24346db8a71..88f5064e412b 100644 --- a/drivers/regulator/wm8994-regulator.c +++ b/drivers/regulator/wm8994-regulator.c | |||
@@ -145,10 +145,12 @@ static int wm8994_ldo_probe(struct platform_device *pdev) | |||
145 | config.driver_data = ldo; | 145 | config.driver_data = ldo; |
146 | config.regmap = wm8994->regmap; | 146 | config.regmap = wm8994->regmap; |
147 | config.init_data = &ldo->init_data; | 147 | config.init_data = &ldo->init_data; |
148 | if (pdata) | 148 | if (pdata) { |
149 | config.ena_gpio = pdata->ldo[id].enable; | 149 | config.ena_gpio = pdata->ldo[id].enable; |
150 | else if (wm8994->dev->of_node) | 150 | } else if (wm8994->dev->of_node) { |
151 | config.ena_gpio = wm8994->pdata.ldo[id].enable; | 151 | config.ena_gpio = wm8994->pdata.ldo[id].enable; |
152 | config.ena_gpio_initialized = true; | ||
153 | } | ||
152 | 154 | ||
153 | /* Use default constraints if none set up */ | 155 | /* Use default constraints if none set up */ |
154 | if (!pdata || !pdata->ldo[id].init_data || wm8994->dev->of_node) { | 156 | if (!pdata || !pdata->ldo[id].init_data || wm8994->dev->of_node) { |
diff --git a/include/dt-bindings/regulator/maxim,max77802.h b/include/dt-bindings/regulator/maxim,max77802.h new file mode 100644 index 000000000000..cf28631d7109 --- /dev/null +++ b/include/dt-bindings/regulator/maxim,max77802.h | |||
@@ -0,0 +1,18 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014 Google, Inc | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | * Device Tree binding constants for the Maxim 77802 PMIC regulators | ||
9 | */ | ||
10 | |||
11 | #ifndef _DT_BINDINGS_REGULATOR_MAXIM_MAX77802_H | ||
12 | #define _DT_BINDINGS_REGULATOR_MAXIM_MAX77802_H | ||
13 | |||
14 | /* Regulator operating modes */ | ||
15 | #define MAX77802_OPMODE_LP 1 | ||
16 | #define MAX77802_OPMODE_NORMAL 3 | ||
17 | |||
18 | #endif /* _DT_BINDINGS_REGULATOR_MAXIM_MAX77802_H */ | ||
diff --git a/include/linux/mfd/max77686.h b/include/linux/mfd/max77686.h index 7e6dc4b2b795..553f7d09258a 100644 --- a/include/linux/mfd/max77686.h +++ b/include/linux/mfd/max77686.h | |||
@@ -131,13 +131,6 @@ enum max77686_opmode { | |||
131 | MAX77686_OPMODE_STANDBY, | 131 | MAX77686_OPMODE_STANDBY, |
132 | }; | 132 | }; |
133 | 133 | ||
134 | enum max77802_opmode { | ||
135 | MAX77802_OPMODE_OFF, | ||
136 | MAX77802_OPMODE_STANDBY, | ||
137 | MAX77802_OPMODE_LP, | ||
138 | MAX77802_OPMODE_NORMAL, | ||
139 | }; | ||
140 | |||
141 | struct max77686_opmode_data { | 134 | struct max77686_opmode_data { |
142 | int id; | 135 | int id; |
143 | int mode; | 136 | int mode; |
diff --git a/include/linux/of.h b/include/linux/of.h index 364a15858746..c55b50018ac4 100644 --- a/include/linux/of.h +++ b/include/linux/of.h | |||
@@ -923,14 +923,14 @@ static inline int of_changeset_update_property(struct of_changeset *ocs, | |||
923 | extern int of_resolve_phandles(struct device_node *tree); | 923 | extern int of_resolve_phandles(struct device_node *tree); |
924 | 924 | ||
925 | /** | 925 | /** |
926 | * of_system_has_poweroff_source - Tells if poweroff-source is found for device_node | 926 | * of_device_is_system_power_controller - Tells if system-power-controller is found for device_node |
927 | * @np: Pointer to the given device_node | 927 | * @np: Pointer to the given device_node |
928 | * | 928 | * |
929 | * return true if present false otherwise | 929 | * return true if present false otherwise |
930 | */ | 930 | */ |
931 | static inline bool of_system_has_poweroff_source(const struct device_node *np) | 931 | static inline bool of_device_is_system_power_controller(const struct device_node *np) |
932 | { | 932 | { |
933 | return of_property_read_bool(np, "poweroff-source"); | 933 | return of_property_read_bool(np, "system-power-controller"); |
934 | } | 934 | } |
935 | 935 | ||
936 | #endif /* _LINUX_OF_H */ | 936 | #endif /* _LINUX_OF_H */ |
diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index f540b1496e2f..d17e1ff7ad01 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h | |||
@@ -101,6 +101,8 @@ struct regmap; | |||
101 | * Data passed is "struct pre_voltage_change_data" | 101 | * Data passed is "struct pre_voltage_change_data" |
102 | * ABORT_VOLTAGE_CHANGE Regulator voltage change failed for some reason. | 102 | * ABORT_VOLTAGE_CHANGE Regulator voltage change failed for some reason. |
103 | * Data passed is old voltage cast to (void *). | 103 | * Data passed is old voltage cast to (void *). |
104 | * PRE_DISABLE Regulator is about to be disabled | ||
105 | * ABORT_DISABLE Regulator disable failed for some reason | ||
104 | * | 106 | * |
105 | * NOTE: These events can be OR'ed together when passed into handler. | 107 | * NOTE: These events can be OR'ed together when passed into handler. |
106 | */ | 108 | */ |
@@ -115,6 +117,8 @@ struct regmap; | |||
115 | #define REGULATOR_EVENT_DISABLE 0x80 | 117 | #define REGULATOR_EVENT_DISABLE 0x80 |
116 | #define REGULATOR_EVENT_PRE_VOLTAGE_CHANGE 0x100 | 118 | #define REGULATOR_EVENT_PRE_VOLTAGE_CHANGE 0x100 |
117 | #define REGULATOR_EVENT_ABORT_VOLTAGE_CHANGE 0x200 | 119 | #define REGULATOR_EVENT_ABORT_VOLTAGE_CHANGE 0x200 |
120 | #define REGULATOR_EVENT_PRE_DISABLE 0x400 | ||
121 | #define REGULATOR_EVENT_ABORT_DISABLE 0x800 | ||
118 | 122 | ||
119 | /** | 123 | /** |
120 | * struct pre_voltage_change_data - Data sent with PRE_VOLTAGE_CHANGE event | 124 | * struct pre_voltage_change_data - Data sent with PRE_VOLTAGE_CHANGE event |
@@ -284,7 +288,7 @@ devm_regulator_get(struct device *dev, const char *id) | |||
284 | static inline struct regulator *__must_check | 288 | static inline struct regulator *__must_check |
285 | regulator_get_exclusive(struct device *dev, const char *id) | 289 | regulator_get_exclusive(struct device *dev, const char *id) |
286 | { | 290 | { |
287 | return NULL; | 291 | return ERR_PTR(-ENODEV); |
288 | } | 292 | } |
289 | 293 | ||
290 | static inline struct regulator *__must_check | 294 | static inline struct regulator *__must_check |
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index fc0ee0ce8325..5f1e9ca47417 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h | |||
@@ -243,6 +243,8 @@ enum regulator_type { | |||
243 | * | 243 | * |
244 | * @enable_time: Time taken for initial enable of regulator (in uS). | 244 | * @enable_time: Time taken for initial enable of regulator (in uS). |
245 | * @off_on_delay: guard time (in uS), before re-enabling a regulator | 245 | * @off_on_delay: guard time (in uS), before re-enabling a regulator |
246 | * | ||
247 | * @of_map_mode: Maps a hardware mode defined in a DeviceTree to a standard mode | ||
246 | */ | 248 | */ |
247 | struct regulator_desc { | 249 | struct regulator_desc { |
248 | const char *name; | 250 | const char *name; |
@@ -285,6 +287,8 @@ struct regulator_desc { | |||
285 | unsigned int enable_time; | 287 | unsigned int enable_time; |
286 | 288 | ||
287 | unsigned int off_on_delay; | 289 | unsigned int off_on_delay; |
290 | |||
291 | unsigned int (*of_map_mode)(unsigned int mode); | ||
288 | }; | 292 | }; |
289 | 293 | ||
290 | /** | 294 | /** |
@@ -301,6 +305,9 @@ struct regulator_desc { | |||
301 | * NULL). | 305 | * NULL). |
302 | * @regmap: regmap to use for core regmap helpers if dev_get_regulator() is | 306 | * @regmap: regmap to use for core regmap helpers if dev_get_regulator() is |
303 | * insufficient. | 307 | * insufficient. |
308 | * @ena_gpio_initialized: GPIO controlling regulator enable was properly | ||
309 | * initialized, meaning that >= 0 is a valid gpio | ||
310 | * identifier and < 0 is a non existent gpio. | ||
304 | * @ena_gpio: GPIO controlling regulator enable. | 311 | * @ena_gpio: GPIO controlling regulator enable. |
305 | * @ena_gpio_invert: Sense for GPIO enable control. | 312 | * @ena_gpio_invert: Sense for GPIO enable control. |
306 | * @ena_gpio_flags: Flags to use when calling gpio_request_one() | 313 | * @ena_gpio_flags: Flags to use when calling gpio_request_one() |
@@ -312,6 +319,7 @@ struct regulator_config { | |||
312 | struct device_node *of_node; | 319 | struct device_node *of_node; |
313 | struct regmap *regmap; | 320 | struct regmap *regmap; |
314 | 321 | ||
322 | bool ena_gpio_initialized; | ||
315 | int ena_gpio; | 323 | int ena_gpio; |
316 | unsigned int ena_gpio_invert:1; | 324 | unsigned int ena_gpio_invert:1; |
317 | unsigned int ena_gpio_flags; | 325 | unsigned int ena_gpio_flags; |
diff --git a/include/linux/regulator/of_regulator.h b/include/linux/regulator/of_regulator.h index f9217965aaa3..763953f7e3b8 100644 --- a/include/linux/regulator/of_regulator.h +++ b/include/linux/regulator/of_regulator.h | |||
@@ -6,24 +6,29 @@ | |||
6 | #ifndef __LINUX_OF_REG_H | 6 | #ifndef __LINUX_OF_REG_H |
7 | #define __LINUX_OF_REG_H | 7 | #define __LINUX_OF_REG_H |
8 | 8 | ||
9 | struct regulator_desc; | ||
10 | |||
9 | struct of_regulator_match { | 11 | struct of_regulator_match { |
10 | const char *name; | 12 | const char *name; |
11 | void *driver_data; | 13 | void *driver_data; |
12 | struct regulator_init_data *init_data; | 14 | struct regulator_init_data *init_data; |
13 | struct device_node *of_node; | 15 | struct device_node *of_node; |
16 | const struct regulator_desc *desc; | ||
14 | }; | 17 | }; |
15 | 18 | ||
16 | #if defined(CONFIG_OF) | 19 | #if defined(CONFIG_OF) |
17 | extern struct regulator_init_data | 20 | extern struct regulator_init_data |
18 | *of_get_regulator_init_data(struct device *dev, | 21 | *of_get_regulator_init_data(struct device *dev, |
19 | struct device_node *node); | 22 | struct device_node *node, |
23 | const struct regulator_desc *desc); | ||
20 | extern int of_regulator_match(struct device *dev, struct device_node *node, | 24 | extern int of_regulator_match(struct device *dev, struct device_node *node, |
21 | struct of_regulator_match *matches, | 25 | struct of_regulator_match *matches, |
22 | unsigned int num_matches); | 26 | unsigned int num_matches); |
23 | #else | 27 | #else |
24 | static inline struct regulator_init_data | 28 | static inline struct regulator_init_data |
25 | *of_get_regulator_init_data(struct device *dev, | 29 | *of_get_regulator_init_data(struct device *dev, |
26 | struct device_node *node) | 30 | struct device_node *node, |
31 | const struct regulator_desc *desc) | ||
27 | { | 32 | { |
28 | return NULL; | 33 | return NULL; |
29 | } | 34 | } |