From 51579137c500362018b5341f5dca47807ed558aa Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 24 Mar 2012 09:37:30 +0800 Subject: [PATCH 01/17] regulator: tps6586x: Fix list minimal voltage setting for LDO0 According to the datasheet, LDO0 has minimal voltage 1.2V rather than 1.25V. Table 3-39. VLDO0[2:0] Settings VLDOx[2:0] VOUT (V) VLDOx[2:0] VOUT (V) 000 1.20 100 2.70 001 1.50 101 2.85 010 1.80 110 3.10 011 2.50 111 3.30 Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/tps6586x-regulator.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c index 29b615ce3aff..cfc1f16f7771 100644 --- a/drivers/regulator/tps6586x-regulator.c +++ b/drivers/regulator/tps6586x-regulator.c @@ -79,6 +79,11 @@ static int tps6586x_ldo_list_voltage(struct regulator_dev *rdev, unsigned selector) { struct tps6586x_regulator *info = rdev_get_drvdata(rdev); + int rid = rdev_get_id(rdev); + + /* LDO0 has minimal voltage 1.2V rather than 1.25V */ + if ((rid == TPS6586X_ID_LDO_0) && (selector == 0)) + return (info->voltages[0] - 50) * 1000; return info->voltages[selector] * 1000; } From 09bf14b901f2c1908b6a72fe934457acdd1fa430 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 15 Mar 2012 15:53:05 +0800 Subject: [PATCH 02/17] regulator: Fix set and get current limit for wm831x_buckv WM831X_DC1_HC_THR_MASK is 0x0070. We need to do proper shift for setting and getting current limit. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/wm831x-dcdc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c index 4904a40b0d46..3044001f3cf6 100644 --- a/drivers/regulator/wm831x-dcdc.c +++ b/drivers/regulator/wm831x-dcdc.c @@ -386,7 +386,8 @@ static int wm831x_buckv_set_current_limit(struct regulator_dev *rdev, if (i == ARRAY_SIZE(wm831x_dcdc_ilim)) return -EINVAL; - return wm831x_set_bits(wm831x, reg, WM831X_DC1_HC_THR_MASK, i); + return wm831x_set_bits(wm831x, reg, WM831X_DC1_HC_THR_MASK, + i << WM831X_DC1_HC_THR_SHIFT); } static int wm831x_buckv_get_current_limit(struct regulator_dev *rdev) @@ -400,7 +401,8 @@ static int wm831x_buckv_get_current_limit(struct regulator_dev *rdev) if (val < 0) return val; - return wm831x_dcdc_ilim[val & WM831X_DC1_HC_THR_MASK]; + val = (val & WM831X_DC1_HC_THR_MASK) >> WM831X_DC1_HC_THR_SHIFT; + return wm831x_dcdc_ilim[val]; } static struct regulator_ops wm831x_buckv_ops = { From 5777d9b34aec841429ddade56403b3f53a821a1d Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 15 Mar 2012 12:49:09 +0800 Subject: [PATCH 03/17] regulator: Fix unbalanced lock/unlock in mc13892_regulator_probe error path We do not hold a lock while registering regulator, thus should not call unlock if regulator_register fails. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/mc13892-regulator.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/regulator/mc13892-regulator.c b/drivers/regulator/mc13892-regulator.c index e8cfc99dd8f0..845aa2263b8a 100644 --- a/drivers/regulator/mc13892-regulator.c +++ b/drivers/regulator/mc13892-regulator.c @@ -552,7 +552,7 @@ static int __devinit mc13892_regulator_probe(struct platform_device *pdev) mc13xxx_lock(mc13892); ret = mc13xxx_reg_read(mc13892, MC13892_REVISION, &val); if (ret) - goto err_free; + goto err_unlock; /* enable switch auto mode */ if ((val & 0x0000FFFF) == 0x45d0) { @@ -562,7 +562,7 @@ static int __devinit mc13892_regulator_probe(struct platform_device *pdev) MC13892_SWITCHERS4_SW1MODE_AUTO | MC13892_SWITCHERS4_SW2MODE_AUTO); if (ret) - goto err_free; + goto err_unlock; ret = mc13xxx_reg_rmw(mc13892, MC13892_SWITCHERS5, MC13892_SWITCHERS5_SW3MODE_M | @@ -570,7 +570,7 @@ static int __devinit mc13892_regulator_probe(struct platform_device *pdev) MC13892_SWITCHERS5_SW3MODE_AUTO | MC13892_SWITCHERS5_SW4MODE_AUTO); if (ret) - goto err_free; + goto err_unlock; } mc13xxx_unlock(mc13892); @@ -612,10 +612,10 @@ static int __devinit mc13892_regulator_probe(struct platform_device *pdev) err: while (--i >= 0) regulator_unregister(priv->regulators[i]); + return ret; -err_free: +err_unlock: mc13xxx_unlock(mc13892); - return ret; } From eb4168158f79237498e4d3ddcef6e9436db15a4a Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 23 Mar 2012 06:25:05 +0800 Subject: [PATCH 04/17] regulator: Fix restoring pmic.dcdcx_hib_mode settings in wm8350_dcdc_set_suspend_enable What we want is to restore wm8350->pmic.dcdcx_hib_mode settings to WM8350_DCDCx_LOW_POWER registers. Current code also clears all other bits of WM8350_DCDCx_LOW_POWER registers which is wrong. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/wm8350-regulator.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c index ab1e183a74b5..1c548218e12a 100644 --- a/drivers/regulator/wm8350-regulator.c +++ b/drivers/regulator/wm8350-regulator.c @@ -495,25 +495,25 @@ static int wm8350_dcdc_set_suspend_enable(struct regulator_dev *rdev) val = wm8350_reg_read(wm8350, WM8350_DCDC1_LOW_POWER) & ~WM8350_DCDC_HIB_MODE_MASK; wm8350_reg_write(wm8350, WM8350_DCDC1_LOW_POWER, - wm8350->pmic.dcdc1_hib_mode); + val | wm8350->pmic.dcdc1_hib_mode); break; case WM8350_DCDC_3: val = wm8350_reg_read(wm8350, WM8350_DCDC3_LOW_POWER) & ~WM8350_DCDC_HIB_MODE_MASK; wm8350_reg_write(wm8350, WM8350_DCDC3_LOW_POWER, - wm8350->pmic.dcdc3_hib_mode); + val | wm8350->pmic.dcdc3_hib_mode); break; case WM8350_DCDC_4: val = wm8350_reg_read(wm8350, WM8350_DCDC4_LOW_POWER) & ~WM8350_DCDC_HIB_MODE_MASK; wm8350_reg_write(wm8350, WM8350_DCDC4_LOW_POWER, - wm8350->pmic.dcdc4_hib_mode); + val | wm8350->pmic.dcdc4_hib_mode); break; case WM8350_DCDC_6: val = wm8350_reg_read(wm8350, WM8350_DCDC6_LOW_POWER) & ~WM8350_DCDC_HIB_MODE_MASK; wm8350_reg_write(wm8350, WM8350_DCDC6_LOW_POWER, - wm8350->pmic.dcdc6_hib_mode); + val | wm8350->pmic.dcdc6_hib_mode); break; case WM8350_DCDC_2: case WM8350_DCDC_5: From 9300928692f835f76f5604b3b51c3085977edf68 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 23 Mar 2012 06:27:10 +0800 Subject: [PATCH 05/17] regulator: Do proper shift to set correct bit for DC[2|5]_HIB_MODE setting DC[2|5]_HIB_MODE is BIT 12 of DCDC[2|5] Control register. WM8350_DC2_HIB_MODE_ACTIVE/WM8350_DC2_HIB_MODE_DISABLE are defined as 1/0. Thus we need to left shift WM8350_DC2_HIB_MODE_SHIFT bits. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/wm8350-regulator.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c index 1c548218e12a..ff3465423be1 100644 --- a/drivers/regulator/wm8350-regulator.c +++ b/drivers/regulator/wm8350-regulator.c @@ -575,13 +575,13 @@ static int wm8350_dcdc25_set_suspend_enable(struct regulator_dev *rdev) val = wm8350_reg_read(wm8350, WM8350_DCDC2_CONTROL) & ~WM8350_DC2_HIB_MODE_MASK; wm8350_reg_write(wm8350, WM8350_DCDC2_CONTROL, val | - WM8350_DC2_HIB_MODE_ACTIVE); + (WM8350_DC2_HIB_MODE_ACTIVE << WM8350_DC2_HIB_MODE_SHIFT)); break; case WM8350_DCDC_5: val = wm8350_reg_read(wm8350, WM8350_DCDC5_CONTROL) - & ~WM8350_DC2_HIB_MODE_MASK; + & ~WM8350_DC5_HIB_MODE_MASK; wm8350_reg_write(wm8350, WM8350_DCDC5_CONTROL, val | - WM8350_DC5_HIB_MODE_ACTIVE); + (WM8350_DC5_HIB_MODE_ACTIVE << WM8350_DC5_HIB_MODE_SHIFT)); break; default: return -EINVAL; @@ -600,13 +600,13 @@ static int wm8350_dcdc25_set_suspend_disable(struct regulator_dev *rdev) val = wm8350_reg_read(wm8350, WM8350_DCDC2_CONTROL) & ~WM8350_DC2_HIB_MODE_MASK; wm8350_reg_write(wm8350, WM8350_DCDC2_CONTROL, val | - WM8350_DC2_HIB_MODE_DISABLE); + (WM8350_DC2_HIB_MODE_DISABLE << WM8350_DC2_HIB_MODE_SHIFT)); break; case WM8350_DCDC_5: val = wm8350_reg_read(wm8350, WM8350_DCDC5_CONTROL) - & ~WM8350_DC2_HIB_MODE_MASK; + & ~WM8350_DC5_HIB_MODE_MASK; wm8350_reg_write(wm8350, WM8350_DCDC5_CONTROL, val | - WM8350_DC2_HIB_MODE_DISABLE); + (WM8350_DC5_HIB_MODE_DISABLE << WM8350_DC5_HIB_MODE_SHIFT)); break; default: return -EINVAL; From 2f2cc27f50e3d232602d3b7c972071b4a30e5e38 Mon Sep 17 00:00:00 2001 From: "Ying-Chun Liu (PaulLiu)" Date: Tue, 27 Mar 2012 15:54:01 +0800 Subject: [PATCH 06/17] regulator: anatop: patching to device-tree property "reg". Change "reg" to "anatop-reg-offset" due to there is a warning of handling no size field in reg. This patch also adds the missing device-tree binding documentation. Signed-off-by: Ying-Chun Liu (PaulLiu) Acked-by: Shawn Guo Signed-off-by: Mark Brown --- .../bindings/regulator/anatop-regulator.txt | 29 +++++++++++++++++++ drivers/regulator/anatop-regulator.c | 5 ++-- 2 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 Documentation/devicetree/bindings/regulator/anatop-regulator.txt diff --git a/Documentation/devicetree/bindings/regulator/anatop-regulator.txt b/Documentation/devicetree/bindings/regulator/anatop-regulator.txt new file mode 100644 index 000000000000..357758cb6e92 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/anatop-regulator.txt @@ -0,0 +1,29 @@ +Anatop Voltage regulators + +Required properties: +- compatible: Must be "fsl,anatop-regulator" +- anatop-reg-offset: Anatop MFD register offset +- anatop-vol-bit-shift: Bit shift for the register +- anatop-vol-bit-width: Number of bits used in the register +- anatop-min-bit-val: Minimum value of this register +- anatop-min-voltage: Minimum voltage of this regulator +- anatop-max-voltage: Maximum voltage of this regulator + +Any property defined as part of the core regulator +binding, defined in regulator.txt, can also be used. + +Example: + + regulator-vddpu { + compatible = "fsl,anatop-regulator"; + regulator-name = "vddpu"; + regulator-min-microvolt = <725000>; + regulator-max-microvolt = <1300000>; + regulator-always-on; + anatop-reg-offset = <0x140>; + anatop-vol-bit-shift = <9>; + anatop-vol-bit-width = <5>; + anatop-min-bit-val = <1>; + anatop-min-voltage = <725000>; + anatop-max-voltage = <1300000>; + }; diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c index 17499a55113d..53969af17558 100644 --- a/drivers/regulator/anatop-regulator.c +++ b/drivers/regulator/anatop-regulator.c @@ -138,9 +138,10 @@ static int __devinit anatop_regulator_probe(struct platform_device *pdev) rdesc->type = REGULATOR_VOLTAGE; rdesc->owner = THIS_MODULE; sreg->mfd = anatopmfd; - ret = of_property_read_u32(np, "reg", &sreg->control_reg); + ret = of_property_read_u32(np, "anatop-reg-offset", + &sreg->control_reg); if (ret) { - dev_err(dev, "no reg property set\n"); + dev_err(dev, "no anatop-reg-offset property set\n"); goto anatop_probe_end; } ret = of_property_read_u32(np, "anatop-vol-bit-width", From a171e782a97d4ba55d7fa02f9a46904288b2c229 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 27 Mar 2012 15:17:26 +0800 Subject: [PATCH 07/17] regulator: wm831x-dcdc: Fix the logic to choose best current limit setting Current code in wm831x_buckv_set_current_limit actually set the current limit setting greater than specified range. Fix the logic in wm831x_buckv_set_current_limit to choose the smallest current limit setting falls within the specified range. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/wm831x-dcdc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c index 3044001f3cf6..ff810e787eac 100644 --- a/drivers/regulator/wm831x-dcdc.c +++ b/drivers/regulator/wm831x-dcdc.c @@ -380,7 +380,8 @@ static int wm831x_buckv_set_current_limit(struct regulator_dev *rdev, int i; for (i = 0; i < ARRAY_SIZE(wm831x_dcdc_ilim); i++) { - if (max_uA <= wm831x_dcdc_ilim[i]) + if ((min_uA <= wm831x_dcdc_ilim[i]) && + (wm831x_dcdc_ilim[i] <= max_uA)) break; } if (i == ARRAY_SIZE(wm831x_dcdc_ilim)) From ed3be9a0e3c1050fe07d69a8c600d86cac76cdc4 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 27 Mar 2012 15:18:53 +0800 Subject: [PATCH 08/17] regulator: wm831x-isink: Fix the logic to choose best current limit setting Current code in wm831x_isink_set_current actually set the current limit setting smaller than specified range. Fix the logic in wm831x_isink_set_current to choose the smallest current limit setting falls within the specified range. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/wm831x-isink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/wm831x-isink.c b/drivers/regulator/wm831x-isink.c index 634aac3f2d5f..b414e09c5620 100644 --- a/drivers/regulator/wm831x-isink.c +++ b/drivers/regulator/wm831x-isink.c @@ -101,7 +101,7 @@ static int wm831x_isink_set_current(struct regulator_dev *rdev, for (i = 0; i < ARRAY_SIZE(wm831x_isinkv_values); i++) { int val = wm831x_isinkv_values[i]; - if (min_uA >= val && val <= max_uA) { + if (min_uA <= val && val <= max_uA) { ret = wm831x_set_bits(wm831x, isink->reg, WM831X_CS1_ISEL_MASK, i); return ret; From 3a744038b3709cd467b693f3e146c6d5b8120a18 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 27 Mar 2012 15:20:08 +0800 Subject: [PATCH 09/17] regulator: wm8350: Fix the logic to choose best current limit setting Current implementation in get_isink_val actually choose the biggest current limit setting falls within the specified range. What we want is to choose the smallest current limit setting falls within the specified range. Fix it. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/wm8350-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c index ff3465423be1..f29803cfd0cb 100644 --- a/drivers/regulator/wm8350-regulator.c +++ b/drivers/regulator/wm8350-regulator.c @@ -99,7 +99,7 @@ static int get_isink_val(int min_uA, int max_uA, u16 *setting) { int i; - for (i = ARRAY_SIZE(isink_cur) - 1; i >= 0; i--) { + for (i = 0; i < ARRAY_SIZE(isink_cur); i++) { if (min_uA <= isink_cur[i] && max_uA >= isink_cur[i]) { *setting = i; return 0; From fa5a97bb0c65cb8d0382b72a55e2b87e15268289 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 27 Mar 2012 15:21:45 +0800 Subject: [PATCH 10/17] regulator: Return microamps in wm8350_isink_get_current The values in isink_cur array are microamps. The regulator core expects get_current_limit callback to return microamps. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/wm8350-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c index f29803cfd0cb..c5f3b4090d87 100644 --- a/drivers/regulator/wm8350-regulator.c +++ b/drivers/regulator/wm8350-regulator.c @@ -186,7 +186,7 @@ static int wm8350_isink_get_current(struct regulator_dev *rdev) return 0; } - return DIV_ROUND_CLOSEST(isink_cur[val], 100); + return isink_cur[val]; } /* turn on ISINK followed by DCDC */ From e841a36abb0f95ea356d52e4386b8e8f762e9c40 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 29 Mar 2012 15:02:55 +0800 Subject: [PATCH 11/17] regulator: Fix setting low power mode for wm831x aldo Set BIT[8] of LDO7 ON Control mode for low power mode. R16507 (407Bh) LDO7 ON Control BIT[8] LDO7_ON_MODE: LDO7 ON Operating Mode 0 = Normal mode 1 = Low Power mode Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/wm831x-ldo.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c index f1e4ab0f9fda..641e9f6499d1 100644 --- a/drivers/regulator/wm831x-ldo.c +++ b/drivers/regulator/wm831x-ldo.c @@ -506,22 +506,19 @@ static int wm831x_aldo_set_mode(struct regulator_dev *rdev, { struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); struct wm831x *wm831x = ldo->wm831x; - int ctrl_reg = ldo->base + WM831X_LDO_CONTROL; int on_reg = ldo->base + WM831X_LDO_ON_CONTROL; int ret; switch (mode) { case REGULATOR_MODE_NORMAL: - ret = wm831x_set_bits(wm831x, on_reg, - WM831X_LDO7_ON_MODE, 0); + ret = wm831x_set_bits(wm831x, on_reg, WM831X_LDO7_ON_MODE, 0); if (ret < 0) return ret; break; case REGULATOR_MODE_IDLE: - ret = wm831x_set_bits(wm831x, ctrl_reg, - WM831X_LDO7_ON_MODE, + ret = wm831x_set_bits(wm831x, on_reg, WM831X_LDO7_ON_MODE, WM831X_LDO7_ON_MODE); if (ret < 0) return ret; From cee1a799eb044657922c4d63003d7bf71f8c8b8d Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 29 Mar 2012 10:47:36 +0800 Subject: [PATCH 12/17] regulator: Only update [LDOx|DCx]_HIB_MODE bits in wm8350_[ldo|dcdc]_set_suspend_disable What we want is to disable output by setting [LDOx|DCx]_HIB_MODE bits. Current code also clears other bits in LDOx/DCDCx Low Power register. R202 (CAh) LDO1 Low Power BIT[13:12] LDO1 Hibernate behaviour: 00 = Select voltage image settings 01 = disable output 10 = reserved 11 = reserved R182 (B6h) DCDC1 Low Power BIT[14:12] DC-DC1 Hibernate behaviour: 000 = Use current settings (no change) 001 = Select voltage image settings 010 = Force standby mode 011 = Force standby mode and voltage image settings. 100 = Force LDO mode 101 = Force LDO mode and voltage image settings. 110 = Reserved. 111 = Disable output Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/wm8350-regulator.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c index c5f3b4090d87..05ecfb872319 100644 --- a/drivers/regulator/wm8350-regulator.c +++ b/drivers/regulator/wm8350-regulator.c @@ -535,25 +535,25 @@ static int wm8350_dcdc_set_suspend_disable(struct regulator_dev *rdev) val = wm8350_reg_read(wm8350, WM8350_DCDC1_LOW_POWER); wm8350->pmic.dcdc1_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK; wm8350_reg_write(wm8350, WM8350_DCDC1_LOW_POWER, - WM8350_DCDC_HIB_MODE_DIS); + val | WM8350_DCDC_HIB_MODE_DIS); break; case WM8350_DCDC_3: val = wm8350_reg_read(wm8350, WM8350_DCDC3_LOW_POWER); wm8350->pmic.dcdc3_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK; wm8350_reg_write(wm8350, WM8350_DCDC3_LOW_POWER, - WM8350_DCDC_HIB_MODE_DIS); + val | WM8350_DCDC_HIB_MODE_DIS); break; case WM8350_DCDC_4: val = wm8350_reg_read(wm8350, WM8350_DCDC4_LOW_POWER); wm8350->pmic.dcdc4_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK; wm8350_reg_write(wm8350, WM8350_DCDC4_LOW_POWER, - WM8350_DCDC_HIB_MODE_DIS); + val | WM8350_DCDC_HIB_MODE_DIS); break; case WM8350_DCDC_6: val = wm8350_reg_read(wm8350, WM8350_DCDC6_LOW_POWER); wm8350->pmic.dcdc6_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK; wm8350_reg_write(wm8350, WM8350_DCDC6_LOW_POWER, - WM8350_DCDC_HIB_MODE_DIS); + val | WM8350_DCDC_HIB_MODE_DIS); break; case WM8350_DCDC_2: case WM8350_DCDC_5: @@ -749,7 +749,7 @@ static int wm8350_ldo_set_suspend_disable(struct regulator_dev *rdev) /* all LDOs have same mV bits */ val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_LDO1_HIB_MODE_MASK; - wm8350_reg_write(wm8350, volt_reg, WM8350_LDO1_HIB_MODE_DIS); + wm8350_reg_write(wm8350, volt_reg, val | WM8350_LDO1_HIB_MODE_DIS); return 0; } From 15c08f664d8ca4f4d0e202cbd4034422a706ef80 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 29 Mar 2012 12:21:17 +0800 Subject: [PATCH 13/17] regulator: Fix comments in include/linux/regulator/machine.h Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- include/linux/regulator/machine.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h index 7abb16093312..b02108446be7 100644 --- a/include/linux/regulator/machine.h +++ b/include/linux/regulator/machine.h @@ -71,7 +71,7 @@ struct regulator_state { * @uV_offset: Offset applied to voltages from consumer to compensate for * voltage drops. * - * @min_uA: Smallest consumers consumers may set. + * @min_uA: Smallest current consumers may set. * @max_uA: Largest current consumers may set. * * @valid_modes_mask: Mask of modes which may be configured by consumers. @@ -134,10 +134,8 @@ struct regulation_constraints { /** * struct regulator_consumer_supply - supply -> device mapping * - * This maps a supply name to a device. Only one of dev or dev_name - * can be specified. Use of dev_name allows support for buses which - * make struct device available late such as I2C and is the preferred - * form. + * This maps a supply name to a device. Use of dev_name allows support for + * buses which make struct device available late such as I2C. * * @dev_name: Result of dev_name() for the consumer. * @supply: Name for the supply. From e032b376551a61662b20a2c8544fbbc568ab2e7f Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 28 Mar 2012 21:17:55 +0100 Subject: [PATCH 14/17] regulator: Fix deadlock on removal of regulators with supplies If a regulator with a supply is being unregistered we will call regulator_put() to release the supply with the regulator_list_mutex held but this deadlocks as regulator_put() takes the same lock. Fix this by releasing the supply before we take the mutex in regulator_unregister(). Signed-off-by: Mark Brown --- drivers/regulator/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index e2f3afa71efb..4a5054ef9421 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2992,14 +2992,14 @@ void regulator_unregister(struct regulator_dev *rdev) if (rdev == NULL) return; + if (rdev->supply) + regulator_put(rdev->supply); mutex_lock(®ulator_list_mutex); debugfs_remove_recursive(rdev->debugfs); flush_work_sync(&rdev->disable_work.work); WARN_ON(rdev->open_count); unset_regulator_supplies(rdev); list_del(&rdev->list); - if (rdev->supply) - regulator_put(rdev->supply); kfree(rdev->constraints); device_unregister(&rdev->dev); mutex_unlock(®ulator_list_mutex); From 5f12760d289fd2da685cb54eebb08c107b146872 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Sat, 31 Mar 2012 16:33:31 +0800 Subject: [PATCH 15/17] regulator: fix sysfs name collision between dummy and fixed dummy regulator When regulator_register_fixed() is being used to register fixed dummy regulator, the following line will be seen in the boot log. And the sysfs entry for fixed dummy regulator is not shown. dummy: Failed to create debugfs directory The patch renames the fixed dummy supply to "fixed-dummy" to avoid the name collision with dummy regulator. Signed-off-by: Shawn Guo Signed-off-by: Mark Brown --- drivers/regulator/fixed-helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/fixed-helper.c b/drivers/regulator/fixed-helper.c index 30d0a15b8949..efb52dcefd35 100644 --- a/drivers/regulator/fixed-helper.c +++ b/drivers/regulator/fixed-helper.c @@ -32,7 +32,7 @@ struct platform_device *regulator_register_fixed(int id, if (!data) return NULL; - data->cfg.supply_name = "dummy"; + data->cfg.supply_name = "fixed-dummy"; data->cfg.microvolts = 0; data->cfg.gpio = -EINVAL; data->cfg.enabled_at_boot = 1; From 546e78452a3f81eb45ae5c671c71db05389d42c8 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 19 Mar 2012 12:22:10 +0800 Subject: [PATCH 16/17] regulator: Fix setting new voltage in s5m8767_set_voltage Current code does not really update the register with new value, fix it. I rename the variable i to sel for better readability. Signed-off-by: Axel Lin Acked-by: Sangbeom Kim Signed-off-by: Mark Brown --- drivers/regulator/s5m8767.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index 58447db15de1..4ca2db059004 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c @@ -311,8 +311,7 @@ static int s5m8767_set_voltage(struct regulator_dev *rdev, struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); const struct s5m_voltage_desc *desc; int reg_id = rdev_get_id(rdev); - int reg, mask, ret; - int i; + int sel, reg, mask, ret; u8 val; switch (reg_id) { @@ -333,19 +332,20 @@ static int s5m8767_set_voltage(struct regulator_dev *rdev, desc = reg_voltage_map[reg_id]; - i = s5m8767_convert_voltage_to_sel(desc, min_uV, max_uV); - if (i < 0) - return i; + sel = s5m8767_convert_voltage_to_sel(desc, min_uV, max_uV); + if (sel < 0) + return sel; ret = s5m8767_get_voltage_register(rdev, ®); if (ret) return ret; s5m_reg_read(s5m8767->iodev, reg, &val); - val = val & mask; + val &= ~mask; + val |= sel; ret = s5m_reg_write(s5m8767->iodev, reg, val); - *selector = i; + *selector = sel; return ret; } From d49fe3c4cd22965de7422dd81d46110fc3d4deef Mon Sep 17 00:00:00 2001 From: Russ Dill Date: Wed, 21 Mar 2012 22:19:45 -0700 Subject: [PATCH 17/17] regulator: Remove non-existent parameter from fixed-helper.c kernel doc Signed-off-by: Russ Dill Signed-off-by: Mark Brown --- drivers/regulator/fixed-helper.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/regulator/fixed-helper.c b/drivers/regulator/fixed-helper.c index efb52dcefd35..cacd33c9d042 100644 --- a/drivers/regulator/fixed-helper.c +++ b/drivers/regulator/fixed-helper.c @@ -18,7 +18,6 @@ static void regulator_fixed_release(struct device *dev) /** * regulator_register_fixed - register a no-op fixed regulator - * @name: supply name * @id: platform device id * @supplies: consumers for this regulator * @num_supplies: number of consumers