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>
This commit is contained in:
parent
679c038f54
commit
9f946099fe
|
@ -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))
|
||||||
|
return ERR_PTR(ret);
|
||||||
|
|
||||||
config->gpios = devm_kzalloc(dev,
|
if (ret > 0) {
|
||||||
sizeof(struct gpio) * config->nr_gpios,
|
config->nr_gpios = ret;
|
||||||
GFP_KERNEL);
|
config->gpios = devm_kzalloc(dev,
|
||||||
if (!config->gpios)
|
sizeof(struct gpio) * config->nr_gpios,
|
||||||
return ERR_PTR(-ENOMEM);
|
GFP_KERNEL);
|
||||||
|
if (!config->gpios)
|
||||||
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
proplen = of_property_count_u32_elems(np, "gpios-states");
|
proplen = of_property_count_u32_elems(np, "gpios-states");
|
||||||
/* optional property */
|
/* optional property */
|
||||||
if (proplen < 0)
|
if (proplen < 0)
|
||||||
proplen = 0;
|
proplen = 0;
|
||||||
|
|
||||||
if (proplen > 0 && proplen != config->nr_gpios) {
|
if (proplen > 0 && proplen != config->nr_gpios) {
|
||||||
dev_warn(dev, "gpios <-> gpios-states mismatch\n");
|
dev_warn(dev, "gpios <-> gpios-states mismatch\n");
|
||||||
proplen = 0;
|
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)
|
||||||
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)
|
||||||
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++) {
|
||||||
|
|
Loading…
Reference in New Issue