Commit 9f946099 authored by Richard Fitzgerald's avatar Richard Fitzgerald Committed by Mark Brown

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: default avatarRichard Fitzgerald <rf@opensource.wolfsonmicro.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 679c038f
...@@ -162,34 +162,41 @@ of_get_gpio_regulator_config(struct device *dev, struct device_node *np) ...@@ -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); config->enable_gpio = of_get_named_gpio(np, "enable-gpio", 0);
/* Fetch GPIOs. */ /* Fetch GPIOs. - optional property*/
config->nr_gpios = of_gpio_count(np); ret = of_gpio_count(np);
if ((ret < 0) && (ret != -ENOENT))
config->gpios = devm_kzalloc(dev, return ERR_PTR(ret);
sizeof(struct gpio) * config->nr_gpios,
GFP_KERNEL); if (ret > 0) {
if (!config->gpios) config->nr_gpios = ret;
return ERR_PTR(-ENOMEM); config->gpios = devm_kzalloc(dev,
sizeof(struct gpio) * config->nr_gpios,
proplen = of_property_count_u32_elems(np, "gpios-states"); GFP_KERNEL);
/* optional property */ if (!config->gpios)
if (proplen < 0) return ERR_PTR(-ENOMEM);
proplen = 0;
proplen = of_property_count_u32_elems(np, "gpios-states");
if (proplen > 0 && proplen != config->nr_gpios) { /* optional property */
dev_warn(dev, "gpios <-> gpios-states mismatch\n"); if (proplen < 0)
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++) { for (i = 0; i < config->nr_gpios; i++) {
gpio = of_get_named_gpio(np, "gpios", i); gpio = of_get_named_gpio(np, "gpios", i);
if (gpio < 0) if (gpio < 0)
break; break;
config->gpios[i].gpio = gpio; config->gpios[i].gpio = gpio;
if (proplen > 0) { if (proplen > 0) {
of_property_read_u32_index(np, "gpios-states", i, &ret); of_property_read_u32_index(np, "gpios-states",
if (ret) i, &ret);
config->gpios[i].flags = GPIOF_OUT_INIT_HIGH; if (ret)
config->gpios[i].flags =
GPIOF_OUT_INIT_HIGH;
}
} }
} }
...@@ -261,13 +268,23 @@ static int gpio_regulator_probe(struct platform_device *pdev) ...@@ -261,13 +268,23 @@ static int gpio_regulator_probe(struct platform_device *pdev)
goto err; goto err;
} }
drvdata->gpios = kmemdup(config->gpios, if (config->nr_gpios != 0) {
config->nr_gpios * sizeof(struct gpio), drvdata->gpios = kmemdup(config->gpios,
GFP_KERNEL); config->nr_gpios * sizeof(struct gpio),
if (drvdata->gpios == NULL) { GFP_KERNEL);
dev_err(&pdev->dev, "Failed to allocate gpio data\n"); if (drvdata->gpios == NULL) {
ret = -ENOMEM; dev_err(&pdev->dev, "Failed to allocate gpio data\n");
goto err_name; 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, drvdata->states = kmemdup(config->states,
...@@ -301,14 +318,6 @@ static int gpio_regulator_probe(struct platform_device *pdev) ...@@ -301,14 +318,6 @@ static int gpio_regulator_probe(struct platform_device *pdev)
goto err_memgpio; 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. */ /* build initial state from gpio init data. */
state = 0; state = 0;
for (ptr = 0; ptr < drvdata->nr_gpios; ptr++) { for (ptr = 0; ptr < drvdata->nr_gpios; ptr++) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment