> On Thu, 3 Sep 2026 09:52:59 +0200, Lorenzo Bianconi > said: > > The TC9563 embeds a GPIO controller used for per-port reset signals. > > Create an auxiliary device for it so the gpio-tc9563 driver can > > register the GPIO chip and enable DT-based GPIO lookups. Pass the > > tc9563 regmap to the auxiliary device as its platform data. > > > > The downstream port DT parsing loop gains an of_node_is_type() filter > > to skip non-PCI child nodes such as the GPIO controller node. > > > > The pwrctrl driver does not wait for the GPIO chip to be probed. The > > per-port reset GPIO lookup, returning -EPROBE_DEFER until the chip is > > registered, is added in the next patch. > > > > Select AUXILIARY_BUS and GPIO_TC9563 in Kconfig. > > It's no longer true and also, it's clear from the patch so we don't have to > have it in the commit message. ack, it is just a leftover of v1. I will fix it. Regards, Lorenzo > > > > > Signed-off-by: Lorenzo Bianconi > > --- > > drivers/pci/pwrctrl/Kconfig | 1 + > > drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c | 80 ++++++++++++++++++++++++++++++-- > > 2 files changed, 78 insertions(+), 3 deletions(-) > > > > diff --git a/drivers/pci/pwrctrl/Kconfig b/drivers/pci/pwrctrl/Kconfig > > index 1952ab4f29b6..38aab596aa04 100644 > > --- a/drivers/pci/pwrctrl/Kconfig > > +++ b/drivers/pci/pwrctrl/Kconfig > > @@ -29,6 +29,7 @@ config PCI_PWRCTRL_TC9563 > > select PCI_PWRCTRL > > default m if ARCH_QCOM > > depends on I2C > > + depends on GPIO_TC9563 > > select REGMAP_I2C > > help > > Say Y here to enable the PCI Power Control driver of TC9563 PCIe > > diff --git a/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c b/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c > > index b0d8912690a2..6df512d78b54 100644 > > --- a/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c > > +++ b/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c > > @@ -4,11 +4,13 @@ > > */ > > > > #include > > +#include > > #include > > #include > > #include > > #include > > #include > > +#include > > #include > > #include > > #include > > @@ -20,12 +22,10 @@ > > #include > > #include > > #include > > +#include > > > > #include "../pci.h" > > > > -#define TC9563_GPIO_CONFIG 0x801208 > > -#define TC9563_RESET_GPIO 0x801210 > > - > > #define TC9563_PORT_L0S_DELAY 0x82496c > > #define TC9563_PORT_L1_DELAY 0x824970 > > > > @@ -393,6 +393,73 @@ static int tc9563_pwrctrl_parse_device_dt(struct device_node *node, > > return 0; > > } > > > > +static void tc9563_pwrctrl_adev_release(struct device *dev) > > +{ > > + struct auxiliary_device *adev = to_auxiliary_dev(dev); > > + > > + of_node_put(adev->dev.of_node); > > + kfree(adev); > > +} > > + > > +static void tc9563_pwrctrl_adev_remove(void *data) > > +{ > > + struct auxiliary_device *adev = data; > > + > > + auxiliary_device_delete(adev); > > + auxiliary_device_uninit(adev); > > +} > > + > > +static int tc9563_pwrctrl_adev_add(struct device *dev, const char *name, > > + u32 id, struct device_node *of_node, > > + void *priv_data) > > +{ > > + struct auxiliary_device *adev; > > + int ret; > > + > > + adev = kzalloc_obj(*adev); > > + if (!adev) > > + return -ENOMEM; > > + > > + adev->id = id; > > + adev->name = name; > > + adev->dev.parent = dev; > > + adev->dev.platform_data = priv_data; > > + adev->dev.release = tc9563_pwrctrl_adev_release; > > + adev->dev.of_node = of_node_get(of_node); > > Ah you're doing it because .release() will be called if auxiliary_device_add() > fails. It's fine I guess. > > > + > > + ret = auxiliary_device_init(adev); > > + if (ret) { > > + of_node_put(adev->dev.of_node); > > + kfree(adev); > > + return ret; > > + } > > + > > + ret = auxiliary_device_add(adev); > > + if (ret) { > > + auxiliary_device_uninit(adev); > > + return ret; > > + } > > + > > + return devm_add_action_or_reset(dev, tc9563_pwrctrl_adev_remove, adev); > > +} > > + > > +static int tc9563_pwrctrl_add_gpio_adev(struct tc9563_pwrctrl *tc9563) > > +{ > > + struct device *dev = tc9563->pwrctrl.dev; > > + struct fwnode_handle *fwnode; > > + int ret; > > + > > + fwnode = gpiochip_node_get_first(dev); > > + if (!fwnode) > > + return 0; > > + > > + ret = tc9563_pwrctrl_adev_add(dev, TC9563_GPIO_DEV_NAME, 0, > > + to_of_node(fwnode), tc9563->regmap); > > + fwnode_handle_put(fwnode); > > + > > + return ret; > > +} > > + > > static int tc9563_pwrctrl_power_off(struct pci_pwrctrl *pwrctrl) > > { > > struct tc9563_pwrctrl *tc9563 = container_of(pwrctrl, > > @@ -565,6 +632,9 @@ static int tc9563_pwrctrl_probe(struct platform_device *pdev) > > */ > > port = TC9563_USP; > > for_each_child_of_node_scoped(node, child) { > > + if (!of_node_is_type(child, "pci")) > > + continue; > > + > > if (++port >= TC9563_MAX) > > break; > > > > @@ -596,6 +666,10 @@ static int tc9563_pwrctrl_probe(struct platform_device *pdev) > > tc9563->pwrctrl.power_on = tc9563_pwrctrl_power_on; > > tc9563->pwrctrl.power_off = tc9563_pwrctrl_power_off; > > > > + ret = tc9563_pwrctrl_add_gpio_adev(tc9563); > > + if (ret) > > + goto remove_i2c; > > + > > ret = devm_pci_pwrctrl_device_set_ready(dev, &tc9563->pwrctrl); > > if (ret) > > goto power_off; > > > > -- > > 2.55.0 > > > > > > Reviewed-by: Bartosz Golaszewski