Debugging gpio-hogs which don't get probed

I'm building u-boot for a mt7981a board, very similar to the in-tree mt7981-emmc-rfb. For reference, my device tree and output of make savedefconfig are here:
https://gist.github.com/arachsys/98048980728c652bea641b42cfd41a40
Everything boots fine, but I have a handful of gpios which need to be set to fixed values before booting the kernel to enable a 5g modem. I can do this with
gpio clear 10; gpio set 5; gpio set 9; gpio 11
which works fine, but I think the 'official' solution for this might be using u-boot's gpio-hog support?
With that in mind, I added
&gpio { hub_power { gpio-hog; gpios = <5 GPIO_ACTIVE_HIGH>; output-high; };
modem_control { gpio-hog; gpios = <9 GPIO_ACTIVE_HIGH>; output-high; };
modem_reset { gpio-hog; gpios = <10 GPIO_ACTIVE_HIGH>; output-low; };
modem_power { gpio-hog; gpios = <11 GPIO_ACTIVE_HIGH>; output-high; }; };
with CONFIG_GPIO_HOG=y, but this doesn't seem to work on either u-boot.git HEAD or 2024.07-rc.
To try to see what was going on better, I added some debug printfs:
--- a/u-boot/drivers/gpio/gpio-uclass.c +++ b/u-boot/drivers/gpio/gpio-uclass.c @@ -328,6 +330,8 @@ static int gpio_hog_of_to_plat(struct udevice *dev)
static int gpio_hog_probe(struct udevice *dev) { + printf("gpio_hog_probe called\n"); + struct gpio_hog_data *plat = dev_get_plat(dev); struct gpio_hog_priv *priv = dev_get_priv(dev); int ret; @@ -1518,6 +1523,8 @@ void devm_gpiod_put(struct udevice *dev, struct gpio_desc *desc)
static int gpio_post_bind(struct udevice *dev) { + printf("gpio_post_bind called\n"); + if (CONFIG_IS_ENABLED(GPIO_HOG) && dev_has_ofnode(dev)) { struct udevice *child; ofnode node; @@ -1539,6 +1546,7 @@ static int gpio_post_bind(struct udevice *dev) * since hogs can be essential to the hardware * system. */ + printf("found a gpio-hog\n"); dev_or_flags(child, DM_FLAG_PROBE_AFTER_BIND); } }
This shows gpio_post_bind being called, then the four gpio-hogs found and set to probe after bind, but the gpio_hog_probe function is never actually called. Presumably this is the problem - if they're not probed then they'll never take effect?
I enabled CONFIG_DM_WARN and CONFIG_DM_DEBUG, which confirm that nothing ever seems to be probing the gpio-hog children, but there aren't obviously any errors or warnings related to them either. Nothing relevant happens after gpio_post_bind is called.
Is this a bug or is there some basic config/dts mistake on my part here? Is there some other debug info I can get that might shed light on what's going on, or some config prerequisite for DM_FLAG_PROBE_AFTER_BIND to work that I'm likely to be missing?
Best wishes,
Chris.

Chris Webb chris@arachsys.com wrote:
This shows gpio_post_bind being called, then the four gpio-hogs found and set to probe after bind, but the gpio_hog_probe function is never actually called. Presumably this is the problem - if they're not probed then they'll never take effect?
I enabled CONFIG_DM_WARN and CONFIG_DM_DEBUG, which confirm that nothing ever seems to be probing the gpio-hog children, but there aren't obviously any errors or warnings related to them either. Nothing relevant happens after gpio_post_bind is called.
Following up to myself here, I enabled CONFIG_CMD_DM which seems to confirm they aren't getting probed:
boot> dm tree Class Index Probed Driver Name ----------------------------------------------------------- root 0 [ + ] root_driver root_driver clk 0 [ ] fixed_clock |-- gpt_dummy20m syscon 0 [ ] syscon |-- hwver clk 1 [ + ] mt7981-clock-fixed-p |-- apmixedsys@1001e000 clk 2 [ + ] mt7981-clock-topckge |-- topckgen@1001b000 clk 3 [ + ] mt7981-clock-infracf |-- infracfg_ao@10001000 clk 4 [ + ] mt7981-clock-infracf |-- infracfg@10001000 pinctrl 0 [ + ] mt7981_pinctrl |-- pinctrl@11d00000 pinconfig 0 [ + ] pinconfig | |-- mmc0-pins-default pinconfig 1 [ ] pinconfig | | |-- mux pinconfig 2 [ ] pinconfig | | |-- conf-cmd-dat pinconfig 3 [ ] pinconfig | | |-- conf-clk pinconfig 4 [ ] pinconfig | | `-- conf-rst gpio 0 [ ] mediatek_gpio | `-- mediatek_gpio nop 1 [ ] gpio_hog | |-- hub_power nop 2 [ ] gpio_hog | |-- modem_control nop 3 [ ] gpio_hog | |-- modem_reset nop 4 [ ] gpio_hog | `-- modem_power serial 0 [ + ] serial_mtk |-- serial@11002000 clk 5 [ + ] mt7981-clock-ethsys |-- syscon@15000000 reset 0 [ + ] mediatek_reset | |-- reset syscon 4 [ + ] syscon | `-- syscon@15000000 ethernet 0 [ + ] mtk-eth |-- ethernet@15100000 syscon 1 [ ] syscon |-- syscon@10060000 syscon 2 [ ] syscon |-- syscon@10070000 syscon 3 [ + ] syscon |-- topmisc@11d10000 mmc 0 [ + ] mtk_sd |-- mmc@11230000 blk 0 [ ] mmc_blk | `-- mmc@11230000.blk regulator 0 [ ] regulator_fixed |-- regulator-3p3v button 0 [ ] button_gpio |-- keys button 1 [ ] button_gpio | `-- reset nop 0 [ ] gpio_led_wrap `-- leds led 0 [ ] gpio_led |-- power led 1 [ ] gpio_led |-- internet led 2 [ ] gpio_led |-- wifi_2g led 3 [ ] gpio_led |-- wifi_5g led 4 [ ] gpio_led |-- signal_1 led 5 [ ] gpio_led |-- signal_2 led 6 [ ] gpio_led |-- signal_3 led 7 [ ] gpio_led `-- signal_4
on power up.
I noted that the parent gpio-controller wasn't getting probed either, so tried this:
--- a/u-boot/drivers/pinctrl/mediatek/pinctrl-mt7981.c +++ b/u-boot/drivers/pinctrl/mediatek/pinctrl-mt7981.c @@ -1038,6 +1038,12 @@ static int mtk_pinctrl_mt7981_probe(struct udevice *dev) return mtk_pinctrl_common_probe(dev, &mt7981_data); }
+static int mtk_pinctrl_mt7981_bind(struct udevice *dev) +{ + dev_or_flags(dev, DM_FLAG_PROBE_AFTER_BIND); + return 0; +} + static const struct udevice_id mt7981_pctrl_match[] = { {.compatible = "mediatek,mt7981-pinctrl"}, { /* sentinel */ } @@ -1048,6 +1054,7 @@ U_BOOT_DRIVER(mt7981_pinctrl) = { .id = UCLASS_PINCTRL, .of_match = mt7981_pctrl_match, .ops = &mtk_pinctrl_ops, + .bind = mtk_pinctrl_mt7981_bind, .probe = mtk_pinctrl_mt7981_probe, .priv_auto = sizeof(struct mtk_pinctrl_priv), };
This does indeed fix the problem: the hogs get probed and the gpios show as active outputs on gpio status -a on boot.
But presumably this is all supposed to work without patching that?
Best wishes,
Chris.
participants (1)
-
Chris Webb