summaryrefslogtreecommitdiffstats
path: root/drivers/regulator/gpio-regulator.c
diff options
context:
space:
mode:
authorRichard Fitzgerald <rf@opensource.wolfsonmicro.com>2014-11-19 14:13:06 +0000
committerMark Brown <broonie@kernel.org>2014-11-21 19:25:35 +0000
commit9f946099fe1927aa746892232c4421e1ae175699 (patch)
tree545de7cfbd1851d475879b21359e1eacc252b949 /drivers/regulator/gpio-regulator.c
parent679c038f544e46803d4fce16636747c3e77af4f1 (diff)
regulator: gpio: fix parsing of gpio list
The list of gpios is defined as optional but the code was failing to properly handle the case of no gpios, and also failing to check for errors reading the entry from the devicetree. This patch fixes the handling of optional gpios - this is a useful feature enabling the gpio-regulator to be used as a dummy variable voltage regulator without having to assign any real GPIO lines. Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/regulator/gpio-regulator.c')
-rw-r--r--drivers/regulator/gpio-regulator.c93
1 files changed, 51 insertions, 42 deletions
diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c
index 86546c1c32c..b42c7ec0017 100644
--- a/drivers/regulator/gpio-regulator.c
+++ b/drivers/regulator/gpio-regulator.c
@@ -162,34 +162,41 @@ of_get_gpio_regulator_config(struct device *dev, struct device_node *np)
config->enable_gpio = of_get_named_gpio(np, "enable-gpio", 0);
- /* Fetch GPIOs. */
- config->nr_gpios = of_gpio_count(np);
-
- config->gpios = devm_kzalloc(dev,
- sizeof(struct gpio) * config->nr_gpios,
- GFP_KERNEL);
- if (!config->gpios)
- return ERR_PTR(-ENOMEM);
-
- proplen = of_property_count_u32_elems(np, "gpios-states");
- /* optional property */
- if (proplen < 0)
- proplen = 0;
-
- if (proplen > 0 && proplen != config->nr_gpios) {
- dev_warn(dev, "gpios <-> gpios-states mismatch\n");
- proplen = 0;
- }
+ /* Fetch GPIOs. - optional property*/
+ ret = of_gpio_count(np);
+ if ((ret < 0) && (ret != -ENOENT))
+ return ERR_PTR(ret);
+
+ if (ret > 0) {
+ config->nr_gpios = ret;
+ config->gpios = devm_kzalloc(dev,
+ sizeof(struct gpio) * config->nr_gpios,
+ GFP_KERNEL);
+ if (!config->gpios)
+ return ERR_PTR(-ENOMEM);
+
+ proplen = of_property_count_u32_elems(np, "gpios-states");
+ /* optional property */
+ if (proplen < 0)
+ proplen = 0;
+
+ if (proplen > 0 && proplen != config->nr_gpios) {
+ dev_warn(dev, "gpios <-> gpios-states mismatch\n");
+ proplen = 0;
+ }
- for (i = 0; i < config->nr_gpios; i++) {
- gpio = of_get_named_gpio(np, "gpios", i);
- if (gpio < 0)
- break;
- config->gpios[i].gpio = gpio;
- if (proplen > 0) {
- of_property_read_u32_index(np, "gpios-states", i, &ret);
- if (ret)
- config->gpios[i].flags = GPIOF_OUT_INIT_HIGH;
+ for (i = 0; i < config->nr_gpios; i++) {
+ gpio = of_get_named_gpio(np, "gpios", i);
+ if (gpio < 0)
+ break;
+ config->gpios[i].gpio = gpio;
+ if (proplen > 0) {
+ of_property_read_u32_index(np, "gpios-states",
+ i, &ret);
+ if (ret)
+ config->gpios[i].flags =
+ GPIOF_OUT_INIT_HIGH;
+ }
}
}
@@ -261,13 +268,23 @@ static int gpio_regulator_probe(struct platform_device *pdev)
goto err;
}
- drvdata->gpios = kmemdup(config->gpios,
- config->nr_gpios * sizeof(struct gpio),
- GFP_KERNEL);
- if (drvdata->gpios == NULL) {
- dev_err(&pdev->dev, "Failed to allocate gpio data\n");
- ret = -ENOMEM;
- goto err_name;
+ if (config->nr_gpios != 0) {
+ drvdata->gpios = kmemdup(config->gpios,
+ config->nr_gpios * sizeof(struct gpio),
+ GFP_KERNEL);
+ if (drvdata->gpios == NULL) {
+ dev_err(&pdev->dev, "Failed to allocate gpio data\n");
+ ret = -ENOMEM;
+ goto err_name;
+ }
+
+ drvdata->nr_gpios = config->nr_gpios;
+ ret = gpio_request_array(drvdata->gpios, drvdata->nr_gpios);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "Could not obtain regulator setting GPIOs: %d\n", ret);
+ goto err_memstate;
+ }
}
drvdata->states = kmemdup(config->states,
@@ -301,14 +318,6 @@ static int gpio_regulator_probe(struct platform_device *pdev)
goto err_memgpio;
}
- drvdata->nr_gpios = config->nr_gpios;
- ret = gpio_request_array(drvdata->gpios, drvdata->nr_gpios);
- if (ret) {
- dev_err(&pdev->dev,
- "Could not obtain regulator setting GPIOs: %d\n", ret);
- goto err_memstate;
- }
-
/* build initial state from gpio init data. */
state = 0;
for (ptr = 0; ptr < drvdata->nr_gpios; ptr++) {