From c71c8fd4daa342ba714090586a55fc5db7eaa275 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 21 May 2012 20:55:40 +0800 Subject: [PATCH 1/7] regulator: palmas: Fix wrong kfree calls The devm_kzalloc function eliminates the need for manual resource releasing and simplify error handling. Resources allocated by devm_* are freed automatically on driver detach. Thus adding kfree calls here will introduce double free bug. The memory of desc array and the pointers to the rdev[] are allocated by devm_kzalloc call for struct palmas_pmic. struct palmas_pmic { struct palmas *palmas; struct device *dev; struct regulator_desc desc[PALMAS_NUM_REGS]; struct regulator_dev *rdev[PALMAS_NUM_REGS]; struct mutex mutex; int smps123; int smps457; int range[PALMAS_REG_SMPS10]; }; Which means we should not call kfree for pmic->rdev and pmic->desc. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/palmas-regulator.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index c4435f608df7..9b7ca90057d5 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -775,9 +775,6 @@ static __devinit int palmas_probe(struct platform_device *pdev) err_unregister_regulator: while (--id >= 0) regulator_unregister(pmic->rdev[id]); - kfree(pmic->rdev); - kfree(pmic->desc); - kfree(pmic); return ret; } @@ -788,10 +785,6 @@ static int __devexit palmas_remove(struct platform_device *pdev) for (id = 0; id < PALMAS_NUM_REGS; id++) regulator_unregister(pmic->rdev[id]); - - kfree(pmic->rdev); - kfree(pmic->desc); - kfree(pmic); return 0; } From 0c09d3150902d8ca7e763d508ac1a93701b21321 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 23 May 2012 09:08:08 +0800 Subject: [PATCH 2/7] regulator: anatop: Use correct __devexit_p annotation __devexit functions are discarded when CONFIG_HOTPLUG is not set, so the symbol needs to be referenced carefully. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/anatop-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c index 3660bace123c..e82e7eaac0f1 100644 --- a/drivers/regulator/anatop-regulator.c +++ b/drivers/regulator/anatop-regulator.c @@ -224,7 +224,7 @@ static struct platform_driver anatop_regulator_driver = { .of_match_table = of_anatop_regulator_match_tbl, }, .probe = anatop_regulator_probe, - .remove = anatop_regulator_remove, + .remove = __devexit_p(anatop_regulator_remove), }; static int __init anatop_regulator_init(void) From 7d4be2f5ad223942577c2319153b86592f3da5b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20St=C3=BCbner?= Date: Sun, 3 Jun 2012 21:30:33 +0200 Subject: [PATCH 3/7] regulator: gpio-regulator: do not pass drvdata pointer as reference Commit c172708d38a4 (regulator: core: Use a struct to pass in regulator runtime configuration) added the drvdata pointer only per reference to the new config array in the gpio-regulator. Signed-off-by: Heiko Stuebner Acked-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/gpio-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c index 9997d7aaca84..ebe2b5c2e2df 100644 --- a/drivers/regulator/gpio-regulator.c +++ b/drivers/regulator/gpio-regulator.c @@ -286,7 +286,7 @@ static int __devinit gpio_regulator_probe(struct platform_device *pdev) cfg.dev = &pdev->dev; cfg.init_data = config->init_data; - cfg.driver_data = &drvdata; + cfg.driver_data = drvdata; drvdata->dev = regulator_register(&drvdata->desc, &cfg); if (IS_ERR(drvdata->dev)) { From 00926369b745fb0c1e5c27cec35f6adc9752f2c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20St=C3=BCbner?= Date: Sun, 3 Jun 2012 21:31:09 +0200 Subject: [PATCH 4/7] regulator: gpio-regulator: Fix finding of smallest value Commit 4dbd8f63f07a (regulator: gpio-regulator: Set the smallest voltage/current in the specified range) forgot to set the newly introduced best_val. Therefore it stayed always at INT_MAX thus breaking the setting of the voltage. Included is also an init value for target, as warnings about a possibly uninitialised target started appearing with this fix. Signed-off-by: Heiko Stuebner Acked-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/gpio-regulator.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c index ebe2b5c2e2df..2c38bea5065e 100644 --- a/drivers/regulator/gpio-regulator.c +++ b/drivers/regulator/gpio-regulator.c @@ -104,13 +104,15 @@ static int gpio_regulator_set_value(struct regulator_dev *dev, int min, int max) { struct gpio_regulator_data *data = rdev_get_drvdata(dev); - int ptr, target, state, best_val = INT_MAX; + int ptr, target = 0, state, best_val = INT_MAX; for (ptr = 0; ptr < data->nr_states; ptr++) if (data->states[ptr].value < best_val && data->states[ptr].value >= min && - data->states[ptr].value <= max) + data->states[ptr].value <= max) { target = data->states[ptr].gpios; + best_val = data->states[ptr].value; + } if (best_val == INT_MAX) return -EINVAL; From b0e4d7bf8b5704904a5d138d81a8ec8b7145767f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20St=C3=BCbner?= Date: Sun, 3 Jun 2012 21:32:05 +0200 Subject: [PATCH 5/7] regulator: gpio-regulator: populate selector from set_voltage This was missing until now and the underlying _regulator_do_set_voltage is using this value when calling list_voltage. Signed-off-by: Heiko Stuebner Acked-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/gpio-regulator.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c index 2c38bea5065e..242851a4c1a6 100644 --- a/drivers/regulator/gpio-regulator.c +++ b/drivers/regulator/gpio-regulator.c @@ -101,7 +101,7 @@ static int gpio_regulator_get_value(struct regulator_dev *dev) } static int gpio_regulator_set_value(struct regulator_dev *dev, - int min, int max) + int min, int max, unsigned *selector) { struct gpio_regulator_data *data = rdev_get_drvdata(dev); int ptr, target = 0, state, best_val = INT_MAX; @@ -112,6 +112,8 @@ static int gpio_regulator_set_value(struct regulator_dev *dev, data->states[ptr].value <= max) { target = data->states[ptr].gpios; best_val = data->states[ptr].value; + if (selector) + *selector = ptr; } if (best_val == INT_MAX) @@ -130,7 +132,7 @@ static int gpio_regulator_set_voltage(struct regulator_dev *dev, int min_uV, int max_uV, unsigned *selector) { - return gpio_regulator_set_value(dev, min_uV, max_uV); + return gpio_regulator_set_value(dev, min_uV, max_uV, selector); } static int gpio_regulator_list_voltage(struct regulator_dev *dev, @@ -147,7 +149,7 @@ static int gpio_regulator_list_voltage(struct regulator_dev *dev, static int gpio_regulator_set_current_limit(struct regulator_dev *dev, int min_uA, int max_uA) { - return gpio_regulator_set_value(dev, min_uA, max_uA); + return gpio_regulator_set_value(dev, min_uA, max_uA, NULL); } static struct regulator_ops gpio_regulator_voltage_ops = { From 61663171bea0ccb499f0818234c5be7ea6c4c791 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Tue, 5 Jun 2012 18:10:10 +0800 Subject: [PATCH 6/7] regulator: max8649: fix missing regmap in rdev In probe(), rdev->regmap must be assigned. Signed-off-by: Haojian Zhuang Signed-off-by: Mark Brown --- drivers/regulator/max8649.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/regulator/max8649.c b/drivers/regulator/max8649.c index 1f4bb80457b3..9d540cd02dab 100644 --- a/drivers/regulator/max8649.c +++ b/drivers/regulator/max8649.c @@ -259,6 +259,7 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client, config.dev = &client->dev; config.init_data = pdata->regulator; config.driver_data = info; + config.regmap = info->regmap; info->regulator = regulator_register(&dcdc_desc, &config); if (IS_ERR(info->regulator)) { From 0bdc81e4e944781a2bcc971f9e3cf24ac7030939 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 7 Jun 2012 09:52:12 +0800 Subject: [PATCH 7/7] regulator: core: Properly handle the case min_uV < rdev->desc->min_uV in map_voltage_linear Properly handle the case if the specified min_uV is less than the voltage given by the lowest selector. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 7584a74eec8a..09a737c868b5 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2050,6 +2050,9 @@ int regulator_map_voltage_linear(struct regulator_dev *rdev, return -EINVAL; } + if (min_uV < rdev->desc->min_uV) + min_uV = rdev->desc->min_uV; + ret = DIV_ROUND_UP(min_uV - rdev->desc->min_uV, rdev->desc->uV_step); if (ret < 0) return ret;