Devicetree
 help / color / mirror / Atom feed
* [PATCH v3 0/5] PCI/pwrctrl: tc9563: introduce support for embedded GPIO controller
@ 2026-09-04 17:15 Lorenzo Bianconi
  2026-09-04 17:15 ` [PATCH v3 1/5] dt-bindings: PCI: toshiba,tc9563: Document " Lorenzo Bianconi
                   ` (4 more replies)
  0 siblings, 5 replies; 13+ messages in thread
From: Lorenzo Bianconi @ 2026-09-04 17:15 UTC (permalink / raw)
  To: Bjorn Helgaas, Lorenzo Pieralisi, Krzysztof Wilczyński,
	Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Chaitanya Chundru, Linus Walleij,
	Bartosz Golaszewski, Bjorn Andersson, Konrad Dybcio,
	Michael Walle
  Cc: Alex Elder, Daniel Thompson, Sushrut Shree Trivedi, linux-pci,
	devicetree, linux-gpio, linux-arm-msm, Lorenzo Bianconi,
	Bartosz Golaszewski, Manivannan Sadhasivam, Konrad Dybcio,
	Abel Vesa

This series is based on pwrctrl upstream branch.

---
Changes in v3:
- Describe gpio-controller support in TC9563 binding instead of defining
  a gpio child node.
- Link to v2: https://lore.kernel.org/r/20260903-pci-tc9563-aux-v2-0-34c625b542c1@oss.qualcomm.com

Changes in v2:
- Fix PCI_PWRCTRL_TC9563 Kconfig dependency
- Move of_node refcounting management in tc9563_pwrctrl_adev_add().
- Link to v1: https://lore.kernel.org/r/20260901-pci-tc9563-aux-v1-0-dd9b80738e70@oss.qualcomm.com

---
Alex Elder (1):
      gpio: tc9563: Add support for the embedded GPIO controller

Lorenzo Bianconi (4):
      dt-bindings: PCI: toshiba,tc9563: Document embedded GPIO controller
      PCI/pwrctrl: tc9563: Add GPIO auxiliary device support
      PCI/pwrctrl: tc9563: Switch per-port reset to GPIO descriptor API
      arm64: dts: qcom: qcs6490-rb3gen2: Enable TC9563 embedded GPIO controller

 .../devicetree/bindings/pci/toshiba,tc9563.yaml    |  19 ++-
 arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts       |   7 +-
 drivers/gpio/Kconfig                               |  11 ++
 drivers/gpio/Makefile                              |   1 +
 drivers/gpio/gpio-tc9563.c                         |  99 +++++++++++++
 drivers/pci/pwrctrl/Kconfig                        |   1 +
 drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c           | 154 +++++++++++++++++++--
 include/linux/soc/qcom/tc9563.h                    |  19 +++
 8 files changed, 294 insertions(+), 17 deletions(-)
---
base-commit: 028f86457e822ab9de5b0d6d23efddc1b8b54ae1
change-id: 20260731-pci-tc9563-aux-66a29d438f60

Best regards,
-- 
Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH v3 1/5] dt-bindings: PCI: toshiba,tc9563: Document embedded GPIO controller
  2026-09-04 17:15 [PATCH v3 0/5] PCI/pwrctrl: tc9563: introduce support for embedded GPIO controller Lorenzo Bianconi
@ 2026-09-04 17:15 ` Lorenzo Bianconi
  2026-09-04 17:21   ` sashiko-bot
  2026-09-04 17:15 ` [PATCH v3 2/5] gpio: tc9563: Add support for the " Lorenzo Bianconi
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 13+ messages in thread
From: Lorenzo Bianconi @ 2026-09-04 17:15 UTC (permalink / raw)
  To: Bjorn Helgaas, Lorenzo Pieralisi, Krzysztof Wilczyński,
	Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Chaitanya Chundru, Linus Walleij,
	Bartosz Golaszewski, Bjorn Andersson, Konrad Dybcio,
	Michael Walle
  Cc: Alex Elder, Daniel Thompson, Sushrut Shree Trivedi, linux-pci,
	devicetree, linux-gpio, linux-arm-msm, Lorenzo Bianconi

The TC9563 PCIe switch embeds a GPIO controller providing 37 GPIO
lines. The controller is registered as an auxiliary device by the TC9563
power controller and accessed through the same register map.

Describe the switch node itself as the embedded GPIO controller and
document the per-port reset-gpios property.

Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
---
 .../devicetree/bindings/pci/toshiba,tc9563.yaml       | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/pci/toshiba,tc9563.yaml b/Documentation/devicetree/bindings/pci/toshiba,tc9563.yaml
index f084830c6d0c..c4cd162cb084 100644
--- a/Documentation/devicetree/bindings/pci/toshiba,tc9563.yaml
+++ b/Documentation/devicetree/bindings/pci/toshiba,tc9563.yaml
@@ -31,6 +31,11 @@ properties:
     description:
       GPIO controlling the RESX# pin.
 
+  gpio-controller: true
+
+  '#gpio-cells':
+    const: 2
+
   vdd18-supply: true
 
   vdd09-supply: true
@@ -84,6 +89,11 @@ $defs:
     type: object
 
     properties:
+      reset-gpios:
+        maxItems: 1
+        description:
+          GPIO controlling the reset line connected to the downstream port.
+
       toshiba,tx-amplitude-microvolt:
         description:
           Change Tx Margin setting for low power consumption.
@@ -128,7 +138,7 @@ examples:
             ranges;
             bus-range = <0x01 0xff>;
 
-            pcie@0,0 {
+            tc9563: pcie@0,0 {
                 compatible = "pci1179,0623";
 
                 reg = <0x10000 0x0 0x0 0x0 0x0>;
@@ -149,6 +159,9 @@ examples:
 
                 resx-gpios = <&gpio 1 GPIO_ACTIVE_LOW>;
 
+                gpio-controller;
+                #gpio-cells = <2>;
+
                 pcie@1,0 {
                     compatible = "pciclass,0604";
                     reg = <0x20800 0x0 0x0 0x0 0x0>;
@@ -158,6 +171,8 @@ examples:
                     ranges;
                     bus-range = <0x03 0xff>;
 
+                    reset-gpios = <&tc9563 2 GPIO_ACTIVE_LOW>;
+
                     toshiba,no-dfe-support;
                 };
 
@@ -170,6 +185,8 @@ examples:
                     ranges;
                     bus-range = <0x04 0xff>;
 
+                    reset-gpios = <&tc9563 3 GPIO_ACTIVE_LOW>;
+
                     toshiba,tx-amplitude-microvolt = <10>;
                 };
 

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v3 2/5] gpio: tc9563: Add support for the embedded GPIO controller
  2026-09-04 17:15 [PATCH v3 0/5] PCI/pwrctrl: tc9563: introduce support for embedded GPIO controller Lorenzo Bianconi
  2026-09-04 17:15 ` [PATCH v3 1/5] dt-bindings: PCI: toshiba,tc9563: Document " Lorenzo Bianconi
@ 2026-09-04 17:15 ` Lorenzo Bianconi
  2026-09-04 17:23   ` sashiko-bot
  2026-09-04 17:15 ` [PATCH v3 3/5] PCI/pwrctrl: tc9563: Add GPIO auxiliary device support Lorenzo Bianconi
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 13+ messages in thread
From: Lorenzo Bianconi @ 2026-09-04 17:15 UTC (permalink / raw)
  To: Bjorn Helgaas, Lorenzo Pieralisi, Krzysztof Wilczyński,
	Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Chaitanya Chundru, Linus Walleij,
	Bartosz Golaszewski, Bjorn Andersson, Konrad Dybcio,
	Michael Walle
  Cc: Alex Elder, Daniel Thompson, Sushrut Shree Trivedi, linux-pci,
	devicetree, linux-gpio, linux-arm-msm, Bartosz Golaszewski,
	Manivannan Sadhasivam, Lorenzo Bianconi

From: Alex Elder <elder@riscstar.com>

Add a driver for the GPIO controller embedded in the Toshiba TC9563
PCIe switch (and the Qualcomm QPS615). The device implements 35
GPIOs using two register banks: three registers control the first 32
GPIOs (20 and 21 are reserved) and three more control GPIOs 32-36.
GPIOs 22-24, 27-28, 31, and 34 are input-only.

The driver is registered as an auxiliary device driver. The TC9563
power controller creates the auxiliary device and provides a regmap
that gives access to the GPIO registers, so the gpio-regmap helpers
are used to implement the GPIO chip.

Acked-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Signed-off-by: Alex Elder <elder@riscstar.com>
Co-developed-by: Daniel Thompson <daniel@riscstar.com>
Signed-off-by: Daniel Thompson <daniel@riscstar.com>
Co-developed-by: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
---
 drivers/gpio/Kconfig            | 11 +++++
 drivers/gpio/Makefile           |  1 +
 drivers/gpio/gpio-tc9563.c      | 99 +++++++++++++++++++++++++++++++++++++++++
 include/linux/soc/qcom/tc9563.h | 16 +++++++
 4 files changed, 127 insertions(+)

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index a48586bb8edb..2179eaffcc48 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -1830,6 +1830,17 @@ config GPIO_LTC4283
 
 endmenu
 
+config GPIO_TC9563
+	tristate "Toshiba TC9563 GPIO support"
+	default m if ARCH_QCOM
+	select AUXILIARY_BUS
+	select GPIO_REGMAP
+	help
+	  This enables support for the GPIO controller embedded in the Toshiba
+	  TC9563 (and Qualcomm QPS615).  This device connects to the host
+	  via PCIe port, which is the upstream port on an internal PCIe
+	  switch.
+
 menu "PCI GPIO expanders"
 	depends on PCI
 
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index dc9e6d643b5b..792faa2668c9 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -182,6 +182,7 @@ obj-$(CONFIG_GPIO_SYSCON)		+= gpio-syscon.o
 obj-$(CONFIG_GPIO_TANGIER)		+= gpio-tangier.o
 obj-$(CONFIG_GPIO_TB10X)		+= gpio-tb10x.o
 obj-$(CONFIG_GPIO_TC3589X)		+= gpio-tc3589x.o
+obj-$(CONFIG_GPIO_TC9563)		+= gpio-tc9563.o
 obj-$(CONFIG_GPIO_TEGRA186)		+= gpio-tegra186.o
 obj-$(CONFIG_GPIO_TEGRA)		+= gpio-tegra.o
 obj-$(CONFIG_GPIO_THUNDERX)		+= gpio-thunderx.o
diff --git a/drivers/gpio/gpio-tc9563.c b/drivers/gpio/gpio-tc9563.c
new file mode 100644
index 000000000000..70c3d61905a8
--- /dev/null
+++ b/drivers/gpio/gpio-tc9563.c
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2026 by RISCstar Solutions Corporation.  All rights reserved.
+ */
+
+/*
+ * The Toshiba TC9563 implements a PCIe Gen 3 switch that connects an
+ * upstream x4 port to two downstream PCIe x2 ports. It incorporates
+ * an internal endpoint on a internal PCIe port that implements two
+ * Synopsys XGMAC Ethernet interfaces.
+ *
+ * 35 GPIOs are also implemented by an embedded GPIO controller.  Three
+ * registers control the first 32 GPIOs (other than 20 and 21, which are
+ * reserved). Three other registers control GPIOs 32 through 36. GPIOs
+ * 22-24, 27-28, 31, and 34 are treated as "input only".
+ *
+ */
+
+#include <linux/auxiliary_bus.h>
+#include <linux/gpio/driver.h>
+#include <linux/gpio/regmap.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/soc/qcom/tc9563.h>
+
+/*
+ * There are two sets of registers, each representing (up to) 32 GPIOs with a
+ * stride of 4 bytes (IN1 is 4 bytes past IN0, EN1 is 4 bytes past EN0, etc.).
+ */
+#define TC9563_GPIO_COUNT		37
+#define TC9563_GPIO_PER_REG		32
+#define TC9563_GPIO_REG_STRIDE		4
+
+static int tc9563_gpio_init_valid_mask(struct gpio_chip *gc,
+				       unsigned long *valid_mask,
+				       unsigned int ngpios)
+{
+	/* GPIOs 20 and 21 are reserved */
+	bitmap_fill(valid_mask, ngpios);
+	bitmap_clear(valid_mask, 20, 2);
+
+	return 0;
+}
+
+static int tc9563_gpio_probe(struct auxiliary_device *adev,
+			     const struct auxiliary_device_id *id)
+{
+	struct gpio_regmap_config config = {
+		.parent = &adev->dev,
+		.ngpio = TC9563_GPIO_COUNT,
+		.reg_stride = TC9563_GPIO_REG_STRIDE,
+		.ngpio_per_reg = TC9563_GPIO_PER_REG,
+		.reg_dat_base = GPIO_REGMAP_ADDR(TC9563_GPIO_IN0_OFFSET),
+		.reg_set_base = GPIO_REGMAP_ADDR(TC9563_GPIO_OUT0_OFFSET),
+		.reg_dir_in_base = GPIO_REGMAP_ADDR(TC9563_GPIO_EN0_OFFSET),
+		.init_valid_mask = tc9563_gpio_init_valid_mask,
+	};
+	DECLARE_BITMAP(fixed_dir_mask, TC9563_GPIO_COUNT);
+	DECLARE_BITMAP(fixed_dir_out, TC9563_GPIO_COUNT);
+
+	config.regmap = dev_get_platdata(&adev->dev);
+	if (!config.regmap)
+		return -EINVAL;
+
+	/*
+	 * Only some of our GPIOs are fixed direction:
+	 * 22, 23, 24, 27, 28, 31, and 34 are input-only.
+	 */
+	bitmap_zero(fixed_dir_mask, TC9563_GPIO_COUNT);
+	bitmap_set(fixed_dir_mask, 22, 3);
+	bitmap_set(fixed_dir_mask, 27, 2);
+	set_bit(31, fixed_dir_mask);
+	set_bit(34, fixed_dir_mask);
+	config.fixed_direction_mask = fixed_dir_mask;
+
+	bitmap_zero(fixed_dir_out, TC9563_GPIO_COUNT);
+	config.fixed_direction_output = fixed_dir_out;
+
+	return PTR_ERR_OR_ZERO(devm_gpio_regmap_register(&adev->dev, &config));
+};
+
+static const struct auxiliary_device_id tc9563_gpio_ids[] = {
+	{ "pci_pwrctrl_tc9563." TC9563_GPIO_DEV_NAME },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(auxiliary, tc9563_gpio_ids);
+
+static struct auxiliary_driver tc9563_gpio_driver = {
+	.name		= TC9563_GPIO_DEV_NAME,
+	.probe		= tc9563_gpio_probe,
+	.id_table	= tc9563_gpio_ids,
+};
+module_auxiliary_driver(tc9563_gpio_driver);
+
+MODULE_AUTHOR("Alex Elder <elder@riscstar.com>");
+MODULE_AUTHOR("Daniel Thompson <daniel@riscstar.com>");
+MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>");
+MODULE_DESCRIPTION("Toshiba TC9563 GPIO Driver");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/soc/qcom/tc9563.h b/include/linux/soc/qcom/tc9563.h
new file mode 100644
index 000000000000..0dfd25747b9a
--- /dev/null
+++ b/include/linux/soc/qcom/tc9563.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2026 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Author: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
+ */
+
+#ifndef __QCOM_TC9563_H
+#define __QCOM_TC9563_H
+
+#define TC9563_GPIO_DEV_NAME	"tc9563-gpio"
+
+#define TC9563_GPIO_IN0_OFFSET		0x801200
+#define TC9563_GPIO_EN0_OFFSET		0x801208
+#define TC9563_GPIO_OUT0_OFFSET		0x801210
+
+#endif /* __QCOM_TC9563_H */

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v3 3/5] PCI/pwrctrl: tc9563: Add GPIO auxiliary device support
  2026-09-04 17:15 [PATCH v3 0/5] PCI/pwrctrl: tc9563: introduce support for embedded GPIO controller Lorenzo Bianconi
  2026-09-04 17:15 ` [PATCH v3 1/5] dt-bindings: PCI: toshiba,tc9563: Document " Lorenzo Bianconi
  2026-09-04 17:15 ` [PATCH v3 2/5] gpio: tc9563: Add support for the " Lorenzo Bianconi
@ 2026-09-04 17:15 ` Lorenzo Bianconi
  2026-09-04 17:34   ` sashiko-bot
  2026-09-04 17:15 ` [PATCH v3 4/5] PCI/pwrctrl: tc9563: Switch per-port reset to GPIO descriptor API Lorenzo Bianconi
  2026-09-04 17:15 ` [PATCH v3 5/5] arm64: dts: qcom: qcs6490-rb3gen2: Enable TC9563 embedded GPIO controller Lorenzo Bianconi
  4 siblings, 1 reply; 13+ messages in thread
From: Lorenzo Bianconi @ 2026-09-04 17:15 UTC (permalink / raw)
  To: Bjorn Helgaas, Lorenzo Pieralisi, Krzysztof Wilczyński,
	Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Chaitanya Chundru, Linus Walleij,
	Bartosz Golaszewski, Bjorn Andersson, Konrad Dybcio,
	Michael Walle
  Cc: Alex Elder, Daniel Thompson, Sushrut Shree Trivedi, linux-pci,
	devicetree, linux-gpio, linux-arm-msm, Bartosz Golaszewski,
	Manivannan Sadhasivam, Lorenzo Bianconi

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 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.

Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
---
 drivers/pci/pwrctrl/Kconfig              |  1 +
 drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c | 69 ++++++++++++++++++++++++++++++++
 2 files changed, 70 insertions(+)

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 59ad219c26c0..2230765950b8 100644
--- a/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c
+++ b/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c
@@ -4,6 +4,7 @@
  */
 
 #include <linux/array_size.h>
+#include <linux/auxiliary_bus.h>
 #include <linux/bitfield.h>
 #include <linux/bits.h>
 #include <linux/delay.h>
@@ -18,6 +19,7 @@
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
+#include <linux/soc/qcom/tc9563.h>
 #include <linux/string.h>
 #include <linux/types.h>
 
@@ -393,6 +395,69 @@ 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);
+	dev_set_of_node_reused(&adev->dev);
+
+	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;
+
+	if (!of_property_read_bool(dev->of_node, "gpio-controller") ||
+	    !of_property_present(dev->of_node, "#gpio-cells"))
+		return 0;
+
+	return tc9563_pwrctrl_adev_add(dev, TC9563_GPIO_DEV_NAME, 0,
+				       dev->of_node, tc9563->regmap);
+}
+
 static int tc9563_pwrctrl_power_off(struct pci_pwrctrl *pwrctrl)
 {
 	struct tc9563_pwrctrl *tc9563 = container_of(pwrctrl,
@@ -596,6 +661,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


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v3 4/5] PCI/pwrctrl: tc9563: Switch per-port reset to GPIO descriptor API
  2026-09-04 17:15 [PATCH v3 0/5] PCI/pwrctrl: tc9563: introduce support for embedded GPIO controller Lorenzo Bianconi
                   ` (2 preceding siblings ...)
  2026-09-04 17:15 ` [PATCH v3 3/5] PCI/pwrctrl: tc9563: Add GPIO auxiliary device support Lorenzo Bianconi
@ 2026-09-04 17:15 ` Lorenzo Bianconi
  2026-09-04 17:32   ` sashiko-bot
  2026-09-04 17:15 ` [PATCH v3 5/5] arm64: dts: qcom: qcs6490-rb3gen2: Enable TC9563 embedded GPIO controller Lorenzo Bianconi
  4 siblings, 1 reply; 13+ messages in thread
From: Lorenzo Bianconi @ 2026-09-04 17:15 UTC (permalink / raw)
  To: Bjorn Helgaas, Lorenzo Pieralisi, Krzysztof Wilczyński,
	Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Chaitanya Chundru, Linus Walleij,
	Bartosz Golaszewski, Bjorn Andersson, Konrad Dybcio,
	Michael Walle
  Cc: Alex Elder, Daniel Thompson, Sushrut Shree Trivedi, linux-pci,
	devicetree, linux-gpio, linux-arm-msm, Bartosz Golaszewski,
	Manivannan Sadhasivam, Lorenzo Bianconi

Remove the local TC9563_GPIO_MASK and TC9563_GPIO_DEASSERT_BITS
definitions, which are no longer used after switching to the GPIO
descriptor API. Move TC9563_GPIO_CONFIG and TC9563_RESET_GPIO
definitions in tc9563.h header file.

Replace the direct regmap-based per-port reset logic in
assert_deassert_reset() with gpiod_direction_output() calls, falling
back to the legacy regmap approach only when no reset-gpios DT
property is present for a given port.

Add the reset GPIO pointer to struct tc9563_pwrctrl_cfg and introduce
tc9563_pwrctrl_parse_reset_line() to look up reset-gpios from each
PCI downstream port child node. The lookup is done lazily at the
beginning of power_on(), returning -EPROBE_DEFER until the GPIO chip
is registered.

Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
---
 drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c | 85 ++++++++++++++++++++++++++------
 include/linux/soc/qcom/tc9563.h          |  3 ++
 2 files changed, 73 insertions(+), 15 deletions(-)

diff --git a/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c b/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c
index 2230765950b8..d9b69c3aeb7e 100644
--- a/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c
+++ b/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c
@@ -25,9 +25,6 @@
 
 #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
 
@@ -59,9 +56,6 @@
 #define TC9563_POWER_CONTROL		0x82b09c
 #define TC9563_POWER_CONTROL_OVREN	0x82b2c8
 
-#define TC9563_GPIO_MASK		0xfffffff3
-#define TC9563_GPIO_DEASSERT_BITS	0xc  /* Clear to deassert GPIO */
-
 #define TC9563_TX_MARGIN_MIN_UA		400000
 
 /*
@@ -87,6 +81,7 @@ struct tc9563_pwrctrl_cfg {
 	u8 nfts[2]; /* GEN1 & GEN2 */
 	bool disable_dfe;
 	bool disable_port;
+	struct gpio_desc *reset;
 };
 
 #define TC9563_PWRCTL_MAX_SUPPLY	6
@@ -351,16 +346,40 @@ static int tc9563_pwrctrl_set_nfts(struct tc9563_pwrctrl *tc9563,
 static int tc9563_pwrctrl_assert_deassert_reset(struct tc9563_pwrctrl *tc9563,
 						bool deassert)
 {
-	int ret, val;
-
-	ret = regmap_write(tc9563->regmap, TC9563_GPIO_CONFIG,
-			   TC9563_GPIO_MASK);
-	if (ret)
-		return ret;
-
-	val = deassert ? TC9563_GPIO_DEASSERT_BITS : 0;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(tc9563->cfg); i++) {
+		int err;
+
+		if (tc9563->cfg[i].reset) {
+			err = gpiod_direction_output(tc9563->cfg[i].reset,
+						     !deassert);
+			if (err)
+				return err;
+		} else {
+			/* Fallback: legacy DTS without reset-gpios */
+			switch (i) {
+			case TC9563_DSP1:
+			case TC9563_DSP2:
+				err = regmap_clear_bits(tc9563->regmap,
+							TC9563_GPIO_CONFIG,
+							BIT(i + 1));
+				if (err)
+					return err;
+
+				err = regmap_assign_bits(tc9563->regmap,
+							 TC9563_RESET_GPIO,
+							 BIT(i + 1), deassert);
+				if (err)
+					return err;
+				break;
+			default:
+				break;
+			}
+		}
+	}
 
-	return regmap_write(tc9563->regmap, TC9563_RESET_GPIO, val);
+	return 0;
 }
 
 static int tc9563_pwrctrl_parse_device_dt(struct device_node *node,
@@ -395,6 +414,38 @@ static int tc9563_pwrctrl_parse_device_dt(struct device_node *node,
 	return 0;
 }
 
+static int tc9563_pwrctrl_parse_reset_line(struct tc9563_pwrctrl *tc9563)
+{
+	enum tc9563_pwrctrl_ports port = TC9563_USP;
+	struct device *dev = tc9563->pwrctrl.dev;
+	struct device_node *node = dev->of_node;
+
+	for_each_child_of_node_scoped(node, child) {
+		struct tc9563_pwrctrl_cfg *cfg;
+
+		if (++port >= TC9563_MAX)
+			break;
+
+		cfg = &tc9563->cfg[port];
+		if (cfg->reset) /* Already discovered */
+			continue;
+
+		cfg->reset = devm_fwnode_gpiod_get(dev, of_fwnode_handle(child),
+						   "reset", GPIOD_ASIS,
+						   NULL);
+		if (IS_ERR(cfg->reset)) {
+			int err = PTR_ERR(cfg->reset);
+
+			cfg->reset = NULL;
+			if (err != -ENOENT)
+				return dev_err_probe(dev, err,
+						     "failed to get reset\n");
+		}
+	}
+
+	return 0;
+}
+
 static void tc9563_pwrctrl_adev_release(struct device *dev)
 {
 	struct auxiliary_device *adev = to_auxiliary_dev(dev);
@@ -478,6 +529,10 @@ static int tc9563_pwrctrl_power_on(struct pci_pwrctrl *pwrctrl)
 	struct tc9563_pwrctrl_cfg *cfg;
 	int ret, i;
 
+	ret = tc9563_pwrctrl_parse_reset_line(tc9563);
+	if (ret)
+		return ret;
+
 	ret = regulator_bulk_enable(ARRAY_SIZE(tc9563->supplies),
 				    tc9563->supplies);
 	if (ret < 0)
diff --git a/include/linux/soc/qcom/tc9563.h b/include/linux/soc/qcom/tc9563.h
index 0dfd25747b9a..086f37a40d80 100644
--- a/include/linux/soc/qcom/tc9563.h
+++ b/include/linux/soc/qcom/tc9563.h
@@ -13,4 +13,7 @@
 #define TC9563_GPIO_EN0_OFFSET		0x801208
 #define TC9563_GPIO_OUT0_OFFSET		0x801210
 
+#define TC9563_GPIO_CONFIG		TC9563_GPIO_EN0_OFFSET
+#define TC9563_RESET_GPIO		TC9563_GPIO_OUT0_OFFSET
+
 #endif /* __QCOM_TC9563_H */

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v3 5/5] arm64: dts: qcom: qcs6490-rb3gen2: Enable TC9563 embedded GPIO controller
  2026-09-04 17:15 [PATCH v3 0/5] PCI/pwrctrl: tc9563: introduce support for embedded GPIO controller Lorenzo Bianconi
                   ` (3 preceding siblings ...)
  2026-09-04 17:15 ` [PATCH v3 4/5] PCI/pwrctrl: tc9563: Switch per-port reset to GPIO descriptor API Lorenzo Bianconi
@ 2026-09-04 17:15 ` Lorenzo Bianconi
  2026-09-04 17:23   ` sashiko-bot
  4 siblings, 1 reply; 13+ messages in thread
From: Lorenzo Bianconi @ 2026-09-04 17:15 UTC (permalink / raw)
  To: Bjorn Helgaas, Lorenzo Pieralisi, Krzysztof Wilczyński,
	Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Chaitanya Chundru, Linus Walleij,
	Bartosz Golaszewski, Bjorn Andersson, Konrad Dybcio,
	Michael Walle
  Cc: Alex Elder, Daniel Thompson, Sushrut Shree Trivedi, linux-pci,
	devicetree, linux-gpio, linux-arm-msm, Konrad Dybcio,
	Bartosz Golaszewski, Abel Vesa, Lorenzo Bianconi

The Toshiba TC9563 PCIe switch embeds a GPIO controller providing 37 GPIO
lines. The controller is registered as an auxiliary device by the TC9563
power controller and accessed through the same i2c device.

Describe the switch node itself as the embedded GPIO controller and us
it to drive the PERST# reset lines of the two external downstream port
(pcie@1,0 and pcie@2,0), as expected by the TC9563 power controller after
switching to the GPIO descriptor API for per-port resets.

Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
---
 arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
index a13315bf0fb0..4da7342ca90d 100644
--- a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
+++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
@@ -867,7 +867,7 @@ &pcie1_phy {
 &pcie1_port0 {
 	reset-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>;
 
-	pcie@0,0 {
+	tc9563: pcie@0,0 {
 		compatible = "pci1179,0623";
 		reg = <0x10000 0x0 0x0 0x0 0x0>;
 		#address-cells = <3>;
@@ -891,6 +891,9 @@ pcie@0,0 {
 		pinctrl-0 = <&tc9563_resx_n>;
 		pinctrl-names = "default";
 
+		gpio-controller;
+		#gpio-cells = <2>;
+
 		pcie1_switch0_dsp1: pcie@1,0 {
 			reg = <0x20800 0x0 0x0 0x0 0x0>;
 			#address-cells = <3>;
@@ -899,6 +902,7 @@ pcie1_switch0_dsp1: pcie@1,0 {
 			device_type = "pci";
 			ranges;
 			bus-range = <0x3 0xff>;
+			reset-gpios = <&tc9563 2 GPIO_ACTIVE_LOW>;
 		};
 
 		pcie@2,0 {
@@ -909,6 +913,7 @@ pcie@2,0 {
 			device_type = "pci";
 			ranges;
 			bus-range = <0x4 0xff>;
+			reset-gpios = <&tc9563 3 GPIO_ACTIVE_LOW>;
 
 			/* Renesas μPD720201 PCIe USB3.0 Host Controller */
 			usb-controller@0,0 {

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 1/5] dt-bindings: PCI: toshiba,tc9563: Document embedded GPIO controller
  2026-09-04 17:15 ` [PATCH v3 1/5] dt-bindings: PCI: toshiba,tc9563: Document " Lorenzo Bianconi
@ 2026-09-04 17:21   ` sashiko-bot
  2026-09-04 18:32     ` Lorenzo Bianconi
  0 siblings, 1 reply; 13+ messages in thread
From: sashiko-bot @ 2026-09-04 17:21 UTC (permalink / raw)
  To: Lorenzo Bianconi; +Cc: robh, linux-pci, conor+dt, devicetree

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The 'gpio-controller' and '#gpio-cells' properties were added to the binding to document GPIO provider capabilities, but were not added to the 'required' list.
--

commit 167159eda5a6932cbffa6730117f8dd7e23b2970
Author: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>

dt-bindings: PCI: toshiba,tc9563: Document embedded GPIO controller

This commit documents the embedded GPIO controller within the TC9563 PCIe
switch. It adds gpio-controller and #gpio-cells properties to the device
tree binding, along with the reset-gpios property for the downstream port.

> diff --git a/Documentation/devicetree/bindings/pci/toshiba,tc9563.yaml b/Documentation/devicetree/bindings/pci/toshiba,tc9563.yaml
> index f084830c6d0cb..c4cd162cb084b 100644
> --- a/Documentation/devicetree/bindings/pci/toshiba,tc9563.yaml
> +++ b/Documentation/devicetree/bindings/pci/toshiba,tc9563.yaml
> @@ -31,6 +31,11 @@ properties:
>      description:
>        GPIO controlling the RESX# pin.
>  
> +  gpio-controller: true
> +
> +  '#gpio-cells':
> +    const: 2
> +

[Severity: Medium]
Should gpio-controller and #gpio-cells be added to the required list?

Looking at the required list in
Documentation/devicetree/bindings/pci/toshiba,tc9563.yaml around line 108,
these newly added GPIO provider capabilities are missing:

required:
  - resx-gpios
  - vdd18-supply
  - vdd09-supply
  - vddc-supply

Without being added to the required list, device trees with incomplete
configurations (missing the newly added GPIO controller properties) will
silently pass schema validation when running dt_binding_check or dtbs_check.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260904-pci-tc9563-aux-v3-0-5b1449d62ba2@oss.qualcomm.com?part=1

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 5/5] arm64: dts: qcom: qcs6490-rb3gen2: Enable TC9563 embedded GPIO controller
  2026-09-04 17:15 ` [PATCH v3 5/5] arm64: dts: qcom: qcs6490-rb3gen2: Enable TC9563 embedded GPIO controller Lorenzo Bianconi
@ 2026-09-04 17:23   ` sashiko-bot
  0 siblings, 0 replies; 13+ messages in thread
From: sashiko-bot @ 2026-09-04 17:23 UTC (permalink / raw)
  To: Lorenzo Bianconi; +Cc: linux-pci, conor+dt, robh, devicetree

> The Toshiba TC9563 PCIe switch embeds a GPIO controller providing 37 GPIO
> lines. The controller is registered as an auxiliary device by the TC9563
> power controller and accessed through the same i2c device.
> 
> Describe the switch node itself as the embedded GPIO controller and us
> it to drive the PERST# reset lines of the two external downstream port
> (pcie@1,0 and pcie@2,0), as expected by the TC9563 power controller after
> switching to the GPIO descriptor API for per-port resets.
> 
> Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
> Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
> Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
> Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260904-pci-tc9563-aux-v3-0-5b1449d62ba2@oss.qualcomm.com?part=5


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 2/5] gpio: tc9563: Add support for the embedded GPIO controller
  2026-09-04 17:15 ` [PATCH v3 2/5] gpio: tc9563: Add support for the " Lorenzo Bianconi
@ 2026-09-04 17:23   ` sashiko-bot
  0 siblings, 0 replies; 13+ messages in thread
From: sashiko-bot @ 2026-09-04 17:23 UTC (permalink / raw)
  To: Lorenzo Bianconi; +Cc: robh, linux-pci, devicetree, conor+dt

> From: Alex Elder <elder@riscstar.com>
> 
> Add a driver for the GPIO controller embedded in the Toshiba TC9563
> PCIe switch (and the Qualcomm QPS615). The device implements 35
> GPIOs using two register banks: three registers control the first 32
> GPIOs (20 and 21 are reserved) and three more control GPIOs 32-36.
> GPIOs 22-24, 27-28, 31, and 34 are input-only.
> 
> The driver is registered as an auxiliary device driver. The TC9563
> power controller creates the auxiliary device and provides a regmap
> that gives access to the GPIO registers, so the gpio-regmap helpers
> are used to implement the GPIO chip.
> 
> Acked-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> Signed-off-by: Alex Elder <elder@riscstar.com>
> Co-developed-by: Daniel Thompson <daniel@riscstar.com>
> Signed-off-by: Daniel Thompson <daniel@riscstar.com>
> Co-developed-by: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
> Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260904-pci-tc9563-aux-v3-0-5b1449d62ba2@oss.qualcomm.com?part=2


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 4/5] PCI/pwrctrl: tc9563: Switch per-port reset to GPIO descriptor API
  2026-09-04 17:15 ` [PATCH v3 4/5] PCI/pwrctrl: tc9563: Switch per-port reset to GPIO descriptor API Lorenzo Bianconi
@ 2026-09-04 17:32   ` sashiko-bot
  0 siblings, 0 replies; 13+ messages in thread
From: sashiko-bot @ 2026-09-04 17:32 UTC (permalink / raw)
  To: Lorenzo Bianconi; +Cc: linux-pci, conor+dt, devicetree, robh

> Remove the local TC9563_GPIO_MASK and TC9563_GPIO_DEASSERT_BITS
> definitions, which are no longer used after switching to the GPIO
> descriptor API. Move TC9563_GPIO_CONFIG and TC9563_RESET_GPIO
> definitions in tc9563.h header file.
> 
> Replace the direct regmap-based per-port reset logic in
> assert_deassert_reset() with gpiod_direction_output() calls, falling
> back to the legacy regmap approach only when no reset-gpios DT
> property is present for a given port.
> 
> Add the reset GPIO pointer to struct tc9563_pwrctrl_cfg and introduce
> tc9563_pwrctrl_parse_reset_line() to look up reset-gpios from each
> PCI downstream port child node. The lookup is done lazily at the
> beginning of power_on(), returning -EPROBE_DEFER until the GPIO chip
> is registered.
> 
> Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260904-pci-tc9563-aux-v3-0-5b1449d62ba2@oss.qualcomm.com?part=4


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 3/5] PCI/pwrctrl: tc9563: Add GPIO auxiliary device support
  2026-09-04 17:15 ` [PATCH v3 3/5] PCI/pwrctrl: tc9563: Add GPIO auxiliary device support Lorenzo Bianconi
@ 2026-09-04 17:34   ` sashiko-bot
  2026-09-04 19:25     ` Lorenzo Bianconi
  0 siblings, 1 reply; 13+ messages in thread
From: sashiko-bot @ 2026-09-04 17:34 UTC (permalink / raw)
  To: Lorenzo Bianconi; +Cc: conor+dt, linux-pci, robh, devicetree

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

New issues:
- [High] The GPIO auxiliary device is unconditionally registered without runtime PM synchronization with the parent device, exposing unpowered hardware to I2C accesses.
- [High] Hardcoded auxiliary device ID causes a sysfs naming collision, breaking support for multiple TC9563 controllers.

Pre-existing issues:
- [High] Inversion of teardown order between the I2C adapter reference and devm-managed resources.
--

commit 4ceb9152c94ce43b58577ae6c0490e74f1fcf9de
Author: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>

PCI/pwrctrl: tc9563: Add GPIO auxiliary device support

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.

> diff --git a/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c b/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c
> index 59ad219c26c02..2230765950b88 100644
> --- a/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c
> +++ b/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c
[ ... ]
> @@ -393,6 +395,69 @@ static int tc9563_pwrctrl_parse_device_dt(struct device_node *node,
[ ... ]
> +static int tc9563_pwrctrl_add_gpio_adev(struct tc9563_pwrctrl *tc9563)
> +{
> +	struct device *dev = tc9563->pwrctrl.dev;
> +
> +	if (!of_property_read_bool(dev->of_node, "gpio-controller") ||
> +	    !of_property_present(dev->of_node, "#gpio-cells"))
> +		return 0;
> +
> +	return tc9563_pwrctrl_adev_add(dev, TC9563_GPIO_DEV_NAME, 0,
> +				       dev->of_node, tc9563->regmap);
                                                                  ^
[Severity: High]
Does this hardcoded auxiliary device ID of 0 in
tc9563_pwrctrl_add_gpio_adev() (in drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c)
cause a sysfs naming collision?

If there is more than one TC9563 controller in the system, the first
will probe and register successfully. When the second probes, won't it
attempt to register the same name and fail with -EEXIST?

[Severity: High]
Will unconditionally registering the GPIO auxiliary device here expose
it to accesses while the parent device is suspended?

The PCI subsystem manages the hardware's power state via the pwrctrl
callbacks, powering it off when the PCI endpoint suspends. However, the
GPIO auxiliary device remains registered and active without runtime PM
synchronization.

When userspace or another subsystem accesses a GPIO via sysfs or libgpiod
while the PCI link is suspended, wouldn't the resulting I2C operations
target an unpowered chip?

> +}
> +
[ ... ]
> @@ -596,6 +661,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;
> +

[Severity: High]
This is a pre-existing issue, but could dropping the I2C adapter
reference manually here and in tc9563_pwrctrl_remove() create a
use-after-free risk during devm teardown?

The driver acquires the I2C adapter via of_get_i2c_adapter_by_node() in
tc9563_pwrctrl_probe() (in drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c).
In the probe error path (and similarly in tc9563_pwrctrl_remove() during
unbind), i2c_put_adapter() is called manually before the devm teardown
runs.

With this patch adding the auxiliary device via devm, devm will
unregister the GPIO auxiliary device after the adapter reference is
dropped. If the GPIO driver performs any I2C transfers during its
teardown, it will access the I2C adapter after its reference has been
released.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260904-pci-tc9563-aux-v3-0-5b1449d62ba2@oss.qualcomm.com?part=3

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 1/5] dt-bindings: PCI: toshiba,tc9563: Document embedded GPIO controller
  2026-09-04 17:21   ` sashiko-bot
@ 2026-09-04 18:32     ` Lorenzo Bianconi
  0 siblings, 0 replies; 13+ messages in thread
From: Lorenzo Bianconi @ 2026-09-04 18:32 UTC (permalink / raw)
  To: sashiko-reviews; +Cc: robh, linux-pci, conor+dt, devicetree

[-- Attachment #1: Type: text/plain, Size: 2012 bytes --]

> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> - [Medium] The 'gpio-controller' and '#gpio-cells' properties were added to the binding to document GPIO provider capabilities, but were not added to the 'required' list.
> --
> 
> commit 167159eda5a6932cbffa6730117f8dd7e23b2970
> Author: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
> 
> dt-bindings: PCI: toshiba,tc9563: Document embedded GPIO controller
> 
> This commit documents the embedded GPIO controller within the TC9563 PCIe
> switch. It adds gpio-controller and #gpio-cells properties to the device
> tree binding, along with the reset-gpios property for the downstream port.
> 
> > diff --git a/Documentation/devicetree/bindings/pci/toshiba,tc9563.yaml b/Documentation/devicetree/bindings/pci/toshiba,tc9563.yaml
> > index f084830c6d0cb..c4cd162cb084b 100644
> > --- a/Documentation/devicetree/bindings/pci/toshiba,tc9563.yaml
> > +++ b/Documentation/devicetree/bindings/pci/toshiba,tc9563.yaml
> > @@ -31,6 +31,11 @@ properties:
> >      description:
> >        GPIO controlling the RESX# pin.
> >  
> > +  gpio-controller: true
> > +
> > +  '#gpio-cells':
> > +    const: 2
> > +
> 
> [Severity: Medium]
> Should gpio-controller and #gpio-cells be added to the required list?
> 
> Looking at the required list in
> Documentation/devicetree/bindings/pci/toshiba,tc9563.yaml around line 108,
> these newly added GPIO provider capabilities are missing:
> 
> required:
>   - resx-gpios
>   - vdd18-supply
>   - vdd09-supply
>   - vddc-supply
> 
> Without being added to the required list, device trees with incomplete
> configurations (missing the newly added GPIO controller properties) will
> silently pass schema validation when running dt_binding_check or dtbs_check.

ack, I will fix it in v4.

Regards,
Lorenzo

> 
> -- 
> Sashiko AI review · https://sashiko.dev/#/patchset/20260904-pci-tc9563-aux-v3-0-5b1449d62ba2@oss.qualcomm.com?part=1

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 3/5] PCI/pwrctrl: tc9563: Add GPIO auxiliary device support
  2026-09-04 17:34   ` sashiko-bot
@ 2026-09-04 19:25     ` Lorenzo Bianconi
  0 siblings, 0 replies; 13+ messages in thread
From: Lorenzo Bianconi @ 2026-09-04 19:25 UTC (permalink / raw)
  To: sashiko-reviews; +Cc: conor+dt, linux-pci, robh, devicetree

[-- Attachment #1: Type: text/plain, Size: 4620 bytes --]

> Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
> 
> New issues:
> - [High] The GPIO auxiliary device is unconditionally registered without runtime PM synchronization with the parent device, exposing unpowered hardware to I2C accesses.
> - [High] Hardcoded auxiliary device ID causes a sysfs naming collision, breaking support for multiple TC9563 controllers.
> 
> Pre-existing issues:
> - [High] Inversion of teardown order between the I2C adapter reference and devm-managed resources.
> --
> 
> commit 4ceb9152c94ce43b58577ae6c0490e74f1fcf9de
> Author: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
> 
> PCI/pwrctrl: tc9563: Add GPIO auxiliary device support
> 
> 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.
> 
> > diff --git a/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c b/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c
> > index 59ad219c26c02..2230765950b88 100644
> > --- a/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c
> > +++ b/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c
> [ ... ]
> > @@ -393,6 +395,69 @@ static int tc9563_pwrctrl_parse_device_dt(struct device_node *node,
> [ ... ]
> > +static int tc9563_pwrctrl_add_gpio_adev(struct tc9563_pwrctrl *tc9563)
> > +{
> > +	struct device *dev = tc9563->pwrctrl.dev;
> > +
> > +	if (!of_property_read_bool(dev->of_node, "gpio-controller") ||
> > +	    !of_property_present(dev->of_node, "#gpio-cells"))
> > +		return 0;
> > +
> > +	return tc9563_pwrctrl_adev_add(dev, TC9563_GPIO_DEV_NAME, 0,
> > +				       dev->of_node, tc9563->regmap);
>                                                                   ^
> [Severity: High]
> Does this hardcoded auxiliary device ID of 0 in
> tc9563_pwrctrl_add_gpio_adev() (in drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c)
> cause a sysfs naming collision?
> 
> If there is more than one TC9563 controller in the system, the first
> will probe and register successfully. When the second probes, won't it
> attempt to register the same name and fail with -EEXIST?

ack, I will fix it in v4.

> 
> [Severity: High]
> Will unconditionally registering the GPIO auxiliary device here expose
> it to accesses while the parent device is suspended?
> 
> The PCI subsystem manages the hardware's power state via the pwrctrl
> callbacks, powering it off when the PCI endpoint suspends. However, the
> GPIO auxiliary device remains registered and active without runtime PM
> synchronization.
> 
> When userspace or another subsystem accesses a GPIO via sysfs or libgpiod
> while the PCI link is suspended, wouldn't the resulting I2C operations
> target an unpowered chip?

I guess this is not a real issue since if pwrctrl driver runs the power_off()
callback, it will disable device regulators and so the i2c communications
triggered by gpio read/write will fail returning an error.

> 
> > +}
> > +
> [ ... ]
> > @@ -596,6 +661,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;
> > +
> 
> [Severity: High]
> This is a pre-existing issue, but could dropping the I2C adapter
> reference manually here and in tc9563_pwrctrl_remove() create a
> use-after-free risk during devm teardown?

I guess this can't really occur since i2c_adapter refcount is 2 after probe
(of_get_i2c_adapter_by_node() and devm_i2c_new_dummy_device()). During
teardown phase, the first reference is released (i2c_put_adapter()) but the
second one is released just after aux device is destroyed.

Regards,
Lorenzo

> 
> The driver acquires the I2C adapter via of_get_i2c_adapter_by_node() in
> tc9563_pwrctrl_probe() (in drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c).
> In the probe error path (and similarly in tc9563_pwrctrl_remove() during
> unbind), i2c_put_adapter() is called manually before the devm teardown
> runs.
> 
> With this patch adding the auxiliary device via devm, devm will
> unregister the GPIO auxiliary device after the adapter reference is
> dropped. If the GPIO driver performs any I2C transfers during its
> teardown, it will access the I2C adapter after its reference has been
> released.



> 
> -- 
> Sashiko AI review · https://sashiko.dev/#/patchset/20260904-pci-tc9563-aux-v3-0-5b1449d62ba2@oss.qualcomm.com?part=3

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2026-09-04 19:25 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-04 17:15 [PATCH v3 0/5] PCI/pwrctrl: tc9563: introduce support for embedded GPIO controller Lorenzo Bianconi
2026-09-04 17:15 ` [PATCH v3 1/5] dt-bindings: PCI: toshiba,tc9563: Document " Lorenzo Bianconi
2026-09-04 17:21   ` sashiko-bot
2026-09-04 18:32     ` Lorenzo Bianconi
2026-09-04 17:15 ` [PATCH v3 2/5] gpio: tc9563: Add support for the " Lorenzo Bianconi
2026-09-04 17:23   ` sashiko-bot
2026-09-04 17:15 ` [PATCH v3 3/5] PCI/pwrctrl: tc9563: Add GPIO auxiliary device support Lorenzo Bianconi
2026-09-04 17:34   ` sashiko-bot
2026-09-04 19:25     ` Lorenzo Bianconi
2026-09-04 17:15 ` [PATCH v3 4/5] PCI/pwrctrl: tc9563: Switch per-port reset to GPIO descriptor API Lorenzo Bianconi
2026-09-04 17:32   ` sashiko-bot
2026-09-04 17:15 ` [PATCH v3 5/5] arm64: dts: qcom: qcs6490-rb3gen2: Enable TC9563 embedded GPIO controller Lorenzo Bianconi
2026-09-04 17:23   ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox