Hi!
I found a dependency issue with gpiochip and pinctrl while using the gpio-hog
feature that was implemented by Benoit
Parrot in f625d4601759f. Relevant device-tree overlay shown below [3].
I ran into a deadlock situation, because adding a gpiochip requires a
registered pinctrl with registered ranges, because
the function to add the gpiochip will check for hogged pins and request gpio
pin functionality for them.
This works in situations when gpiochip and pinctrl functionality don't depend
on each other. However, consider the
following code, which is from the bcm2835 driver for Raspberry Pi found here
[1]:
pinctrl-bcm2835.c:
err = gpiochip_add_data(&pc->gpio_chip, pc);
if (err) {
dev_err(dev, "could not add GPIO chip n");
return err;
}
...
pc->pctl_dev = devm_pinctrl_register(dev, &bcm2835_pinctrl_desc, pc);
if (IS_ERR(pc->pctl_dev)) {
gpiochip_remove(&pc->gpio_chip);
return PTR_ERR(pc->pctl_dev);
}
...
pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range);
It's not very obvious, that calling gpiochip_add_data should only be done after
adding the required ranges to pinctrl,
because the following happens:
gpiochip_add_data(_with_key):
of_gpiochip_add:
of_gpiochip_scan_gpios:
for_each_available_child_of_node(chip->of_node, np) with "gpio-hog":
gpiod_hog
gpiochip_request_own_desc:
gpiod_request_commit:
status = chip->request(chip, gpio_chip_hwgpio(desc)):
gpiochip_generic_request(...):
pinctrl_gpio_request:
pinctrl_get_device_gpio_range:
/* GPIO range not found, because it wasn't registered yet
*/
return -EPROBE_DEFER;
This of course deadlocks my system, because everything ends up waiting on the
gpiochip, which cannot ever be
instantiated. I couldn't find any documentation explicitly mentioning this
dependency between gpiochip and pinctrl.
My workaround for the moment is to re-order the gpiochip_add_data call after
the devm_pinctrl_register and
pinctrl_add_gpio_range calls. I haven't observed any ill effect, but I'm not
sure what other components may already act
on pinctrl while gpiochip is dangling or if any of the other functions that are
called by add require it as well.
Obviously, this approach won't work for SoCs where setting certain pinctrl
settings need to touch gpio settings to e.g.
activate pull-ups.
In general, I sought the same functionality that Markus Pargmann was trying to
implement in 2015 [2].
That is, to name and possibly export gpios through device tree.
It seems disadvantageous that one cannot currently specify pinctrl settings
while hogging or export by name.
Dynamic device tree overlays also don't work. Perhaps an actual driver instead
of the hogging mechanism would solve all
dependency issues better?
Regards,
Robert
Please CC, as I'm off-list.
[1]:
https://github.com/raspberrypi/linux/blob/83ea2e93/drivers/pinctrl/bcm/pinctrl-bcm2835.c#L1027
[2]:
http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/357418.html
[3]: gpio-hog.dtso
/dts-v1/;
/plugin/;
#include <dt-bindings/gpio/gpio.h>
/ {
compatible = "brcm,bcm2708";
fragment@0 {
target = <&gpio>;
__overlay__ {
myLed {
gpios = <18 GPIO_ACTIVE_HIGH>;
gpio-hog;
output-low;
};
};
};
};