> On Tue, 1 Sep 2026 12:27:55 +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. > > > > Signed-off-by: Lorenzo Bianconi > > --- > > drivers/pci/pwrctrl/Kconfig | 2 + > > drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c | 78 ++++++++++++++++++++++++++++++-- > > 2 files changed, 77 insertions(+), 3 deletions(-) > > > > diff --git a/drivers/pci/pwrctrl/Kconfig b/drivers/pci/pwrctrl/Kconfig > > index 1952ab4f29b6..a07694fae0c9 100644 > > --- a/drivers/pci/pwrctrl/Kconfig > > +++ b/drivers/pci/pwrctrl/Kconfig > > @@ -30,6 +30,8 @@ config PCI_PWRCTRL_TC9563 > > default m if ARCH_QCOM > > depends on I2C > > select REGMAP_I2C > > + select AUXILIARY_BUS > > + select GPIO_TC9563 > > I think this should depend on it, not select it? ack, I will fix it in v2. > > > help > > Say Y here to enable the PCI Power Control driver of TC9563 PCIe > > switch. > > diff --git a/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c b/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c > > index b0d8912690a2..ee9c26b8f5cb 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,71 @@ 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) { > > + of_node_put(of_node); > > This is a bit confusing. You get the node in tc9563_pwrctrl_add_gpio_adev() but > you put it here. Please either do both here or there. ack, I will fix it in v2. Regards, Lorenzo > > > + 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; > > + > > + ret = auxiliary_device_init(adev); > > + if (ret) { > > + of_node_put(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 device_node *node; > > + > > + node = to_of_node(gpiochip_node_get_first(dev)); > > + if (!node) > > + return 0; > > + > > + return tc9563_pwrctrl_adev_add(dev, TC9563_GPIO_DEV_NAME, 0, node, > > + tc9563->regmap); > > +} > > + > > static int tc9563_pwrctrl_power_off(struct pci_pwrctrl *pwrctrl) > > { > > struct tc9563_pwrctrl *tc9563 = container_of(pwrctrl, > > @@ -565,6 +630,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 +664,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 > > > > > > Bart