2013-04-16 15:29:20

by Axel Lin

[permalink] [raw]
Subject: [PATCH v2 1/2] regulator: ab8500-ext: Don't update info->update_val if set_mode() fails

This ensures info->update_val status is still correct if set_mode() call fails.
Otherwise, get_mode() may return wrong status if a set_mode() call fails.

Signed-off-by: Axel Lin <[email protected]>
---
drivers/regulator/ab8500-ext.c | 26 ++++++++++++++++++--------
1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/drivers/regulator/ab8500-ext.c b/drivers/regulator/ab8500-ext.c
index 20680f3..03faf9c 100644
--- a/drivers/regulator/ab8500-ext.c
+++ b/drivers/regulator/ab8500-ext.c
@@ -181,6 +181,7 @@ static int ab8500_ext_regulator_set_mode(struct regulator_dev *rdev,
{
int ret = 0;
struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev);
+ u8 regval;

if (info == NULL) {
dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
@@ -189,23 +190,30 @@ static int ab8500_ext_regulator_set_mode(struct regulator_dev *rdev,

switch (mode) {
case REGULATOR_MODE_NORMAL:
- info->update_val = info->update_val_hp;
+ regval = info->update_val_hp;
break;
case REGULATOR_MODE_IDLE:
- info->update_val = info->update_val_lp;
+ regval = info->update_val_lp;
break;

default:
return -EINVAL;
}

- if (ab8500_ext_regulator_is_enabled(rdev)) {
- u8 regval;
-
- ret = enable(info, &regval);
- if (ret < 0)
+ /* If regulator is enabled and info->cfg->hwreq is set, the regulator
+ must be on in high power, so we don't need to write the register with
+ the same value.
+ */
+ if (ab8500_ext_regulator_is_enabled(rdev) &&
+ !(info->cfg && info->cfg->hwreq)) {
+ ret = abx500_mask_and_set_register_interruptible(info->dev,
+ info->update_bank, info->update_reg,
+ info->update_mask, regval);
+ if (ret < 0) {
dev_err(rdev_get_dev(rdev),
"Could not set regulator mode.\n");
+ return ret;
+ }

dev_dbg(rdev_get_dev(rdev),
"%s-set_mode (bank, reg, mask, value): "
@@ -214,7 +222,9 @@ static int ab8500_ext_regulator_set_mode(struct regulator_dev *rdev,
info->update_mask, regval);
}

- return ret;
+ info->update_val = regval;
+
+ return 0;
}

static unsigned int ab8500_ext_regulator_get_mode(struct regulator_dev *rdev)
--
1.7.10.4



2013-04-16 15:33:10

by Axel Lin

[permalink] [raw]
Subject: [PATCH v2 2/2] regulator: ab8500-ext: Remove enable() and disable() functions

Both enable() and disable() functions have only one caller, thus remove them.

Signed-off-by: Axel Lin <[email protected]>
---
drivers/regulator/ab8500-ext.c | 64 +++++++++++++++-------------------------
1 file changed, 23 insertions(+), 41 deletions(-)

diff --git a/drivers/regulator/ab8500-ext.c b/drivers/regulator/ab8500-ext.c
index 03faf9c..b4d4547 100644
--- a/drivers/regulator/ab8500-ext.c
+++ b/drivers/regulator/ab8500-ext.c
@@ -54,32 +54,44 @@ struct ab8500_ext_regulator_info {
u8 update_val_hw;
};

-static int enable(struct ab8500_ext_regulator_info *info, u8 *regval)
+static int ab8500_ext_regulator_enable(struct regulator_dev *rdev)
{
int ret;
+ struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev);
+ u8 regval;

- *regval = info->update_val;
+ if (info == NULL) {
+ dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
+ return -EINVAL;
+ }

/*
* To satisfy both HW high power request and SW request, the regulator
* must be on in high power.
*/
if (info->cfg && info->cfg->hwreq)
- *regval = info->update_val_hp;
+ regval = info->update_val_hp;
+ else
+ regval = info->update_val;

ret = abx500_mask_and_set_register_interruptible(info->dev,
info->update_bank, info->update_reg,
- info->update_mask, *regval);
+ info->update_mask, regval);
if (ret < 0) {
dev_err(rdev_get_dev(info->rdev),
"couldn't set enable bits for regulator\n");
return ret;
}

- return ret;
+ dev_dbg(rdev_get_dev(rdev),
+ "%s-enable (bank, reg, mask, value): 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
+ info->desc.name, info->update_bank, info->update_reg,
+ info->update_mask, regval);
+
+ return 0;
}

-static int ab8500_ext_regulator_enable(struct regulator_dev *rdev)
+static int ab8500_ext_regulator_disable(struct regulator_dev *rdev)
{
int ret;
struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev);
@@ -90,59 +102,29 @@ static int ab8500_ext_regulator_enable(struct regulator_dev *rdev)
return -EINVAL;
}

- ret = enable(info, &regval);
-
- dev_dbg(rdev_get_dev(rdev), "%s-enable (bank, reg, mask, value):"
- " 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
- info->desc.name, info->update_bank, info->update_reg,
- info->update_mask, regval);
-
- return ret;
-}
-
-static int disable(struct ab8500_ext_regulator_info *info, u8 *regval)
-{
- int ret;
-
- *regval = 0x0;
-
/*
* Set the regulator in HW request mode if configured
*/
if (info->cfg && info->cfg->hwreq)
- *regval = info->update_val_hw;
+ regval = info->update_val_hw;
+ else
+ regval = 0;

ret = abx500_mask_and_set_register_interruptible(info->dev,
info->update_bank, info->update_reg,
- info->update_mask, *regval);
+ info->update_mask, regval);
if (ret < 0) {
dev_err(rdev_get_dev(info->rdev),
"couldn't set disable bits for regulator\n");
return ret;
}

- return ret;
-}
-
-static int ab8500_ext_regulator_disable(struct regulator_dev *rdev)
-{
- int ret;
- struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev);
- u8 regval;
-
- if (info == NULL) {
- dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
- return -EINVAL;
- }
-
- ret = disable(info, &regval);
-
dev_dbg(rdev_get_dev(rdev), "%s-disable (bank, reg, mask, value):"
" 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
info->desc.name, info->update_bank, info->update_reg,
info->update_mask, regval);

- return ret;
+ return 0;
}

static int ab8500_ext_regulator_is_enabled(struct regulator_dev *rdev)
--
1.7.10.4


2013-04-17 08:51:42

by Bengt Jönsson

[permalink] [raw]
Subject: Re: [PATCH v2 1/2] regulator: ab8500-ext: Don't update info->update_val if set_mode() fails

On 04/16/2013 05:29 PM, Axel Lin wrote:
> This ensures info->update_val status is still correct if set_mode() call fails.
> Otherwise, get_mode() may return wrong status if a set_mode() call fails.
>
> Signed-off-by: Axel Lin <[email protected]>
Looks fine.

Acked-by: Bengt Jonsson <[email protected]>
> ---
> drivers/regulator/ab8500-ext.c | 26 ++++++++++++++++++--------
> 1 file changed, 18 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/regulator/ab8500-ext.c b/drivers/regulator/ab8500-ext.c
> index 20680f3..03faf9c 100644
> --- a/drivers/regulator/ab8500-ext.c
> +++ b/drivers/regulator/ab8500-ext.c
> @@ -181,6 +181,7 @@ static int ab8500_ext_regulator_set_mode(struct regulator_dev *rdev,
> {
> int ret = 0;
> struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev);
> + u8 regval;
>
> if (info == NULL) {
> dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
> @@ -189,23 +190,30 @@ static int ab8500_ext_regulator_set_mode(struct regulator_dev *rdev,
>
> switch (mode) {
> case REGULATOR_MODE_NORMAL:
> - info->update_val = info->update_val_hp;
> + regval = info->update_val_hp;
> break;
> case REGULATOR_MODE_IDLE:
> - info->update_val = info->update_val_lp;
> + regval = info->update_val_lp;
> break;
>
> default:
> return -EINVAL;
> }
>
> - if (ab8500_ext_regulator_is_enabled(rdev)) {
> - u8 regval;
> -
> - ret = enable(info, &regval);
> - if (ret < 0)
> + /* If regulator is enabled and info->cfg->hwreq is set, the regulator
> + must be on in high power, so we don't need to write the register with
> + the same value.
> + */
> + if (ab8500_ext_regulator_is_enabled(rdev) &&
> + !(info->cfg && info->cfg->hwreq)) {
> + ret = abx500_mask_and_set_register_interruptible(info->dev,
> + info->update_bank, info->update_reg,
> + info->update_mask, regval);
> + if (ret < 0) {
> dev_err(rdev_get_dev(rdev),
> "Could not set regulator mode.\n");
> + return ret;
> + }
>
> dev_dbg(rdev_get_dev(rdev),
> "%s-set_mode (bank, reg, mask, value): "
> @@ -214,7 +222,9 @@ static int ab8500_ext_regulator_set_mode(struct regulator_dev *rdev,
> info->update_mask, regval);
> }
>
> - return ret;
> + info->update_val = regval;
> +
> + return 0;
> }
>
> static unsigned int ab8500_ext_regulator_get_mode(struct regulator_dev *rdev)

2013-04-17 08:52:17

by Bengt Jönsson

[permalink] [raw]
Subject: Re: [PATCH v2 2/2] regulator: ab8500-ext: Remove enable() and disable() functions

On 04/16/2013 05:33 PM, Axel Lin wrote:
> Both enable() and disable() functions have only one caller, thus remove them.
>
> Signed-off-by: Axel Lin <[email protected]>
Looks fine.

Acked-by: Bengt Jonsson <[email protected]>
> ---
> drivers/regulator/ab8500-ext.c | 64 +++++++++++++++-------------------------
> 1 file changed, 23 insertions(+), 41 deletions(-)
>
> diff --git a/drivers/regulator/ab8500-ext.c b/drivers/regulator/ab8500-ext.c
> index 03faf9c..b4d4547 100644
> --- a/drivers/regulator/ab8500-ext.c
> +++ b/drivers/regulator/ab8500-ext.c
> @@ -54,32 +54,44 @@ struct ab8500_ext_regulator_info {
> u8 update_val_hw;
> };
>
> -static int enable(struct ab8500_ext_regulator_info *info, u8 *regval)
> +static int ab8500_ext_regulator_enable(struct regulator_dev *rdev)
> {
> int ret;
> + struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev);
> + u8 regval;
>
> - *regval = info->update_val;
> + if (info == NULL) {
> + dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
> + return -EINVAL;
> + }
>
> /*
> * To satisfy both HW high power request and SW request, the regulator
> * must be on in high power.
> */
> if (info->cfg && info->cfg->hwreq)
> - *regval = info->update_val_hp;
> + regval = info->update_val_hp;
> + else
> + regval = info->update_val;
>
> ret = abx500_mask_and_set_register_interruptible(info->dev,
> info->update_bank, info->update_reg,
> - info->update_mask, *regval);
> + info->update_mask, regval);
> if (ret < 0) {
> dev_err(rdev_get_dev(info->rdev),
> "couldn't set enable bits for regulator\n");
> return ret;
> }
>
> - return ret;
> + dev_dbg(rdev_get_dev(rdev),
> + "%s-enable (bank, reg, mask, value): 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
> + info->desc.name, info->update_bank, info->update_reg,
> + info->update_mask, regval);
> +
> + return 0;
> }
>
> -static int ab8500_ext_regulator_enable(struct regulator_dev *rdev)
> +static int ab8500_ext_regulator_disable(struct regulator_dev *rdev)
> {
> int ret;
> struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev);
> @@ -90,59 +102,29 @@ static int ab8500_ext_regulator_enable(struct regulator_dev *rdev)
> return -EINVAL;
> }
>
> - ret = enable(info, &regval);
> -
> - dev_dbg(rdev_get_dev(rdev), "%s-enable (bank, reg, mask, value):"
> - " 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
> - info->desc.name, info->update_bank, info->update_reg,
> - info->update_mask, regval);
> -
> - return ret;
> -}
> -
> -static int disable(struct ab8500_ext_regulator_info *info, u8 *regval)
> -{
> - int ret;
> -
> - *regval = 0x0;
> -
> /*
> * Set the regulator in HW request mode if configured
> */
> if (info->cfg && info->cfg->hwreq)
> - *regval = info->update_val_hw;
> + regval = info->update_val_hw;
> + else
> + regval = 0;
>
> ret = abx500_mask_and_set_register_interruptible(info->dev,
> info->update_bank, info->update_reg,
> - info->update_mask, *regval);
> + info->update_mask, regval);
> if (ret < 0) {
> dev_err(rdev_get_dev(info->rdev),
> "couldn't set disable bits for regulator\n");
> return ret;
> }
>
> - return ret;
> -}
> -
> -static int ab8500_ext_regulator_disable(struct regulator_dev *rdev)
> -{
> - int ret;
> - struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev);
> - u8 regval;
> -
> - if (info == NULL) {
> - dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
> - return -EINVAL;
> - }
> -
> - ret = disable(info, &regval);
> -
> dev_dbg(rdev_get_dev(rdev), "%s-disable (bank, reg, mask, value):"
> " 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
> info->desc.name, info->update_bank, info->update_reg,
> info->update_mask, regval);
>
> - return ret;
> + return 0;
> }
>
> static int ab8500_ext_regulator_is_enabled(struct regulator_dev *rdev)

2013-04-17 14:10:04

by Mark Brown

[permalink] [raw]
Subject: Re: [PATCH v2 1/2] regulator: ab8500-ext: Don't update info->update_val if set_mode() fails

On Tue, Apr 16, 2013 at 11:29:12PM +0800, Axel Lin wrote:
> This ensures info->update_val status is still correct if set_mode() call fails.
> Otherwise, get_mode() may return wrong status if a set_mode() call fails.

Applied both, thanks.


Attachments:
(No filename) (239.00 B)
signature.asc (836.00 B)
Digital signature
Download all attachments