Devicetree
 help / color / mirror / Atom feed
* [PATCH 0/5] PCI/pwrctrl: tc9563: introduce support for embedded GPIO controller
@ 2026-09-01 10:27 Lorenzo Bianconi
  2026-09-01 10:27 ` [PATCH 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-01 10:27 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: linux-pci, devicetree, linux-gpio, linux-arm-msm,
	Lorenzo Bianconi, Alex Elder, Daniel Thompson

This series is based on pwrctrl upstream branch.

---
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    |  31 ++++
 arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts       |   7 +
 drivers/gpio/Kconfig                               |   9 ++
 drivers/gpio/Makefile                              |   1 +
 drivers/gpio/gpio-tc9563.c                         |  99 +++++++++++++
 drivers/pci/pwrctrl/Kconfig                        |   2 +
 drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c           | 163 +++++++++++++++++++--
 include/linux/soc/qcom/tc9563.h                    |  19 +++
 8 files changed, 316 insertions(+), 15 deletions(-)
---
base-commit: 550ecdbab0f51174202e7f9f6557673090bcd5eb
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 1/5] dt-bindings: PCI: toshiba,tc9563: document embedded GPIO controller
  2026-09-01 10:27 [PATCH 0/5] PCI/pwrctrl: tc9563: introduce support for embedded GPIO controller Lorenzo Bianconi
@ 2026-09-01 10:27 ` Lorenzo Bianconi
  2026-09-03 12:51   ` Krzysztof Kozlowski
  2026-09-01 10:27 ` [PATCH 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-01 10:27 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: 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 not bound by a device tree compatible string
but is registered as an auxiliary device by the TC9563 power controller
and accessed through the same register map, so the GPIO node has no
compatible of its own.

Describe the embedded GPIO controller as a "gpio" child node of the
switch, document the per-port reset-gpios property, and update the
example to reference the controller from the downstream port reset
lines.

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

diff --git a/Documentation/devicetree/bindings/pci/toshiba,tc9563.yaml b/Documentation/devicetree/bindings/pci/toshiba,tc9563.yaml
index f084830c6d0c..47cd58c14e4a 100644
--- a/Documentation/devicetree/bindings/pci/toshiba,tc9563.yaml
+++ b/Documentation/devicetree/bindings/pci/toshiba,tc9563.yaml
@@ -54,6 +54,23 @@ properties:
           - description: I2C slave address
 
 patternProperties:
+  "^gpio(@[0-9a-f]+)?$":
+    description:
+      child node describing the embedded GPIO controller available in TC9563
+      PCIe switch. The controller is registered as an auxiliary device by the
+      TC9563 power controller and accessed through the i2c device.
+    type: object
+    additionalProperties: false
+    properties:
+      gpio-controller: true
+
+      "#gpio-cells":
+        const: 2
+
+    required:
+      - gpio-controller
+      - "#gpio-cells"
+
   "^pcie@[1-2],0$":
     description:
       child nodes describing the internal downstream ports of
@@ -62,6 +79,11 @@ patternProperties:
     allOf:
       - $ref: "#/$defs/tc9563-node"
       - $ref: /schemas/pci/pci-pci-bridge.yaml#
+    properties:
+      reset-gpios:
+        maxItems: 1
+        description:
+          GPIO controlling the PERST# reset of the downstream port.
     unevaluatedProperties: false
 
   "^pcie@[3],0$":
@@ -149,6 +171,11 @@ examples:
 
                 resx-gpios = <&gpio 1 GPIO_ACTIVE_LOW>;
 
+                tc9563_gpio: gpio {
+                    gpio-controller;
+                    #gpio-cells = <2>;
+                };
+
                 pcie@1,0 {
                     compatible = "pciclass,0604";
                     reg = <0x20800 0x0 0x0 0x0 0x0>;
@@ -158,6 +185,8 @@ examples:
                     ranges;
                     bus-range = <0x03 0xff>;
 
+                    reset-gpios = <&tc9563_gpio 2 GPIO_ACTIVE_LOW>;
+
                     toshiba,no-dfe-support;
                 };
 
@@ -170,6 +199,8 @@ examples:
                     ranges;
                     bus-range = <0x04 0xff>;
 
+                    reset-gpios = <&tc9563_gpio 3 GPIO_ACTIVE_LOW>;
+
                     toshiba,tx-amplitude-microvolt = <10>;
                 };
 

-- 
2.55.0


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

* [PATCH 2/5] gpio: tc9563: add support for the embedded GPIO controller
  2026-09-01 10:27 [PATCH 0/5] PCI/pwrctrl: tc9563: introduce support for embedded GPIO controller Lorenzo Bianconi
  2026-09-01 10:27 ` [PATCH 1/5] dt-bindings: PCI: toshiba,tc9563: document " Lorenzo Bianconi
@ 2026-09-01 10:27 ` Lorenzo Bianconi
  2026-09-01 10:27 ` [PATCH 3/5] PCI/pwrctrl: tc9563: add GPIO auxiliary device support Lorenzo Bianconi
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 13+ messages in thread
From: Lorenzo Bianconi @ 2026-09-01 10:27 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: linux-pci, devicetree, linux-gpio, linux-arm-msm, Alex Elder,
	Daniel Thompson, 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.

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            |  9 ++++
 drivers/gpio/Makefile           |  1 +
 drivers/gpio/gpio-tc9563.c      | 99 +++++++++++++++++++++++++++++++++++++++++
 include/linux/soc/qcom/tc9563.h | 19 ++++++++
 4 files changed, 128 insertions(+)

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index a48586bb8edb..c522174e630d 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -1828,6 +1828,15 @@ config GPIO_LTC4283
 	  This driver can also be built as a module. If so, the module will
 	  be called gpio-ltc4283.
 
+config GPIO_TC9563
+	tristate "Toshiba TC9563 GPIO support"
+	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.
+
 endmenu
 
 menu "PCI GPIO expanders"
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..f8ea3fc35c6d
--- /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..086f37a40d80
--- /dev/null
+++ b/include/linux/soc/qcom/tc9563.h
@@ -0,0 +1,19 @@
+/* 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
+
+#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 3/5] PCI/pwrctrl: tc9563: add GPIO auxiliary device support
  2026-09-01 10:27 [PATCH 0/5] PCI/pwrctrl: tc9563: introduce support for embedded GPIO controller Lorenzo Bianconi
  2026-09-01 10:27 ` [PATCH 1/5] dt-bindings: PCI: toshiba,tc9563: document " Lorenzo Bianconi
  2026-09-01 10:27 ` [PATCH 2/5] gpio: tc9563: add support for the " Lorenzo Bianconi
@ 2026-09-01 10:27 ` Lorenzo Bianconi
  2026-09-02 14:12   ` Bartosz Golaszewski
  2026-09-01 10:27 ` [PATCH 4/5] PCI/pwrctrl: tc9563: switch per-port reset to GPIO descriptor API Lorenzo Bianconi
  2026-09-01 10:27 ` [PATCH 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-01 10:27 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: linux-pci, devicetree, linux-gpio, linux-arm-msm,
	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 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 <lorenzo.bianconi@oss.qualcomm.com>
---
 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
 	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 <linux/array_size.h>
+#include <linux/auxiliary_bus.h>
 #include <linux/bitfield.h>
 #include <linux/bits.h>
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/gpio/consumer.h>
+#include <linux/gpio/driver.h>
 #include <linux/i2c.h>
 #include <linux/module.h>
 #include <linux/of.h>
@@ -20,12 +22,10 @@
 #include <linux/regulator/consumer.h>
 #include <linux/string.h>
 #include <linux/types.h>
+#include <linux/soc/qcom/tc9563.h>
 
 #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);
+		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


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

* [PATCH 4/5] PCI/pwrctrl: tc9563: switch per-port reset to GPIO descriptor API
  2026-09-01 10:27 [PATCH 0/5] PCI/pwrctrl: tc9563: introduce support for embedded GPIO controller Lorenzo Bianconi
                   ` (2 preceding siblings ...)
  2026-09-01 10:27 ` [PATCH 3/5] PCI/pwrctrl: tc9563: add GPIO auxiliary device support Lorenzo Bianconi
@ 2026-09-01 10:27 ` Lorenzo Bianconi
  2026-09-01 10:27 ` [PATCH 5/5] arm64: dts: qcom: qcs6490-rb3gen2: enable TC9563 embedded GPIO controller Lorenzo Bianconi
  4 siblings, 0 replies; 13+ messages in thread
From: Lorenzo Bianconi @ 2026-09-01 10:27 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: linux-pci, devicetree, linux-gpio, linux-arm-msm,
	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.

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.

Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
---
 drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c | 85 +++++++++++++++++++++++++++-----
 1 file changed, 73 insertions(+), 12 deletions(-)

diff --git a/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c b/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c
index ee9c26b8f5cb..ff84f4ef7878 100644
--- a/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c
+++ b/drivers/pci/pwrctrl/pci-pwrctrl-tc9563.c
@@ -57,9 +57,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
 
 /*
@@ -85,6 +82,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
@@ -349,16 +347,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,
@@ -393,6 +415,41 @@ 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 (!of_node_is_type(child, "pci"))
+			continue;
+
+		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 +535,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)

-- 
2.55.0


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

* [PATCH 5/5] arm64: dts: qcom: qcs6490-rb3gen2: enable TC9563 embedded GPIO controller
  2026-09-01 10:27 [PATCH 0/5] PCI/pwrctrl: tc9563: introduce support for embedded GPIO controller Lorenzo Bianconi
                   ` (3 preceding siblings ...)
  2026-09-01 10:27 ` [PATCH 4/5] PCI/pwrctrl: tc9563: switch per-port reset to GPIO descriptor API Lorenzo Bianconi
@ 2026-09-01 10:27 ` Lorenzo Bianconi
  2026-09-01 12:20   ` Konrad Dybcio
  2026-09-03 11:05   ` Abel Vesa
  4 siblings, 2 replies; 13+ messages in thread
From: Lorenzo Bianconi @ 2026-09-01 10:27 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: linux-pci, devicetree, linux-gpio, linux-arm-msm,
	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 controller as a "gpio" child node of the switch and use it
to control the PERST# reset lines of the two external downstream ports
(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.

Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
---
 arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
index a13315bf0fb0..8670c4243b10 100644
--- a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
+++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
@@ -891,6 +891,11 @@ pcie@0,0 {
 		pinctrl-0 = <&tc9563_resx_n>;
 		pinctrl-names = "default";
 
+		tc9563_gpio0: gpio {
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
 		pcie1_switch0_dsp1: pcie@1,0 {
 			reg = <0x20800 0x0 0x0 0x0 0x0>;
 			#address-cells = <3>;
@@ -899,6 +904,7 @@ pcie1_switch0_dsp1: pcie@1,0 {
 			device_type = "pci";
 			ranges;
 			bus-range = <0x3 0xff>;
+			reset-gpios = <&tc9563_gpio0 2 GPIO_ACTIVE_LOW>;
 		};
 
 		pcie@2,0 {
@@ -909,6 +915,7 @@ pcie@2,0 {
 			device_type = "pci";
 			ranges;
 			bus-range = <0x4 0xff>;
+			reset-gpios = <&tc9563_gpio0 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 5/5] arm64: dts: qcom: qcs6490-rb3gen2: enable TC9563 embedded GPIO controller
  2026-09-01 10:27 ` [PATCH 5/5] arm64: dts: qcom: qcs6490-rb3gen2: enable TC9563 embedded GPIO controller Lorenzo Bianconi
@ 2026-09-01 12:20   ` Konrad Dybcio
  2026-09-03 11:05   ` Abel Vesa
  1 sibling, 0 replies; 13+ messages in thread
From: Konrad Dybcio @ 2026-09-01 12:20 UTC (permalink / raw)
  To: Lorenzo Bianconi, 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: linux-pci, devicetree, linux-gpio, linux-arm-msm

On 9/1/26 12:27 PM, Lorenzo Bianconi wrote:
> 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 controller as a "gpio" child node of the switch and use it
> to control the PERST# reset lines of the two external downstream ports
> (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.
> 
> Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
> ---

Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>

Konrad

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

* Re: [PATCH 3/5] PCI/pwrctrl: tc9563: add GPIO auxiliary device support
  2026-09-01 10:27 ` [PATCH 3/5] PCI/pwrctrl: tc9563: add GPIO auxiliary device support Lorenzo Bianconi
@ 2026-09-02 14:12   ` Bartosz Golaszewski
  2026-09-03  7:52     ` Lorenzo Bianconi
  0 siblings, 1 reply; 13+ messages in thread
From: Bartosz Golaszewski @ 2026-09-02 14:12 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: linux-pci, devicetree, linux-gpio, linux-arm-msm, 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

On Tue, 1 Sep 2026 12:27:55 +0200, Lorenzo Bianconi
<lorenzo.bianconi@oss.qualcomm.com> 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 <lorenzo.bianconi@oss.qualcomm.com>
> ---
>  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?

>  	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 <linux/array_size.h>
> +#include <linux/auxiliary_bus.h>
>  #include <linux/bitfield.h>
>  #include <linux/bits.h>
>  #include <linux/delay.h>
>  #include <linux/device.h>
>  #include <linux/gpio/consumer.h>
> +#include <linux/gpio/driver.h>
>  #include <linux/i2c.h>
>  #include <linux/module.h>
>  #include <linux/of.h>
> @@ -20,12 +22,10 @@
>  #include <linux/regulator/consumer.h>
>  #include <linux/string.h>
>  #include <linux/types.h>
> +#include <linux/soc/qcom/tc9563.h>
>
>  #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.

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

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

* Re: [PATCH 3/5] PCI/pwrctrl: tc9563: add GPIO auxiliary device support
  2026-09-02 14:12   ` Bartosz Golaszewski
@ 2026-09-03  7:52     ` Lorenzo Bianconi
  0 siblings, 0 replies; 13+ messages in thread
From: Lorenzo Bianconi @ 2026-09-03  7:52 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: linux-pci, devicetree, linux-gpio, linux-arm-msm, Bjorn Helgaas,
	Lorenzo Pieralisi, Krzysztof Wilczyński,
	Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Chaitanya Chundru, Linus Walleij, Bjorn Andersson,
	Konrad Dybcio, Michael Walle

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

> On Tue, 1 Sep 2026 12:27:55 +0200, Lorenzo Bianconi
> <lorenzo.bianconi@oss.qualcomm.com> 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 <lorenzo.bianconi@oss.qualcomm.com>
> > ---
> >  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 <linux/array_size.h>
> > +#include <linux/auxiliary_bus.h>
> >  #include <linux/bitfield.h>
> >  #include <linux/bits.h>
> >  #include <linux/delay.h>
> >  #include <linux/device.h>
> >  #include <linux/gpio/consumer.h>
> > +#include <linux/gpio/driver.h>
> >  #include <linux/i2c.h>
> >  #include <linux/module.h>
> >  #include <linux/of.h>
> > @@ -20,12 +22,10 @@
> >  #include <linux/regulator/consumer.h>
> >  #include <linux/string.h>
> >  #include <linux/types.h>
> > +#include <linux/soc/qcom/tc9563.h>
> >
> >  #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

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

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

* Re: [PATCH 5/5] arm64: dts: qcom: qcs6490-rb3gen2: enable TC9563 embedded GPIO controller
  2026-09-01 10:27 ` [PATCH 5/5] arm64: dts: qcom: qcs6490-rb3gen2: enable TC9563 embedded GPIO controller Lorenzo Bianconi
  2026-09-01 12:20   ` Konrad Dybcio
@ 2026-09-03 11:05   ` Abel Vesa
  2026-09-03 12:44     ` Bartosz Golaszewski
  1 sibling, 1 reply; 13+ messages in thread
From: Abel Vesa @ 2026-09-03 11:05 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: 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, linux-pci, devicetree, linux-gpio, linux-arm-msm

On 26-09-01 12:27:57, Lorenzo Bianconi wrote:
> 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 controller as a "gpio" child node of the switch and use it
> to control the PERST# reset lines of the two external downstream ports
> (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.
> 
> Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>

Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>

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

* Re: [PATCH 5/5] arm64: dts: qcom: qcs6490-rb3gen2: enable TC9563 embedded GPIO controller
  2026-09-03 11:05   ` Abel Vesa
@ 2026-09-03 12:44     ` Bartosz Golaszewski
  2026-09-03 12:59       ` Abel Vesa
  0 siblings, 1 reply; 13+ messages in thread
From: Bartosz Golaszewski @ 2026-09-03 12:44 UTC (permalink / raw)
  To: Abel Vesa
  Cc: 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, linux-pci, devicetree, linux-gpio, linux-arm-msm,
	Lorenzo Bianconi

On Thu, 3 Sep 2026 13:05:28 +0200, Abel Vesa <abel.vesa@oss.qualcomm.com> said:
> On 26-09-01 12:27:57, Lorenzo Bianconi wrote:
>> 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 controller as a "gpio" child node of the switch and use it
>> to control the PERST# reset lines of the two external downstream ports
>> (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.
>>
>> Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
>
> Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
>

FYI There's a v2 already on the list.

Bart

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

* Re: [PATCH 1/5] dt-bindings: PCI: toshiba,tc9563: document embedded GPIO controller
  2026-09-01 10:27 ` [PATCH 1/5] dt-bindings: PCI: toshiba,tc9563: document " Lorenzo Bianconi
@ 2026-09-03 12:51   ` Krzysztof Kozlowski
  0 siblings, 0 replies; 13+ messages in thread
From: Krzysztof Kozlowski @ 2026-09-03 12:51 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: 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, linux-pci, devicetree, linux-gpio, linux-arm-msm

On Tue, Sep 01, 2026 at 12:27:53PM +0200, Lorenzo Bianconi wrote:
> The TC9563 PCIe switch embeds a GPIO controller providing 37 GPIO
> lines. The controller is not bound by a device tree compatible string
> but is registered as an auxiliary device by the TC9563 power controller
> and accessed through the same register map, so the GPIO node has no
> compatible of its own.
> 
> Describe the embedded GPIO controller as a "gpio" child node of the
> switch, document the per-port reset-gpios property, and update the
> example to reference the controller from the downstream port reset
> lines.
> 
> Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
> ---
>  .../devicetree/bindings/pci/toshiba,tc9563.yaml    | 31 ++++++++++++++++++++++
>  1 file changed, 31 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/pci/toshiba,tc9563.yaml b/Documentation/devicetree/bindings/pci/toshiba,tc9563.yaml
> index f084830c6d0c..47cd58c14e4a 100644
> --- a/Documentation/devicetree/bindings/pci/toshiba,tc9563.yaml
> +++ b/Documentation/devicetree/bindings/pci/toshiba,tc9563.yaml
> @@ -54,6 +54,23 @@ properties:
>            - description: I2C slave address
>  
>  patternProperties:
> +  "^gpio(@[0-9a-f]+)?$":

Why the unit address is optional? And what does it even represent?


> +    description:
> +      child node describing the embedded GPIO controller available in TC9563

No, this is a PCIe switch so the children are PCI bridges. This does not
fit at all. I do not understand why this node was created in the first
place - what device does it represent?

> +      PCIe switch. The controller is registered as an auxiliary device by the
> +      TC9563 power controller and accessed through the i2c device.
> +    type: object
> +    additionalProperties: false
> +    properties:

And why there is no reg here?

> +      gpio-controller: true
> +
> +      "#gpio-cells":
> +        const: 2

Are you sure you are not re-implementing
https://lore.kernel.org/all/20260701-shikra-upstream-v1-3-e1a721eb8943@oss.qualcomm.com/
?

> +
> +    required:
> +      - gpio-controller
> +      - "#gpio-cells"
> +
>    "^pcie@[1-2],0$":
>      description:
>        child nodes describing the internal downstream ports of
> @@ -62,6 +79,11 @@ patternProperties:
>      allOf:
>        - $ref: "#/$defs/tc9563-node"
>        - $ref: /schemas/pci/pci-pci-bridge.yaml#
> +    properties:
> +      reset-gpios:
> +        maxItems: 1
> +        description:
> +          GPIO controlling the PERST# reset of the downstream port.
>      unevaluatedProperties: false
>  
>    "^pcie@[3],0$":
> @@ -149,6 +171,11 @@ examples:
>  
>                  resx-gpios = <&gpio 1 GPIO_ACTIVE_LOW>;
>  
> +                tc9563_gpio: gpio {
> +                    gpio-controller;
> +                    #gpio-cells = <2>;

Where are any resources?

Best regards,
Krzysztof


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

* Re: [PATCH 5/5] arm64: dts: qcom: qcs6490-rb3gen2: enable TC9563 embedded GPIO controller
  2026-09-03 12:44     ` Bartosz Golaszewski
@ 2026-09-03 12:59       ` Abel Vesa
  0 siblings, 0 replies; 13+ messages in thread
From: Abel Vesa @ 2026-09-03 12:59 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Bjorn Helgaas, Lorenzo Pieralisi, Krzysztof Wilczyński,
	Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Chaitanya Chundru, Linus Walleij, Bjorn Andersson,
	Konrad Dybcio, Michael Walle, linux-pci, devicetree, linux-gpio,
	linux-arm-msm, Lorenzo Bianconi

On 26-09-03 08:44:12, Bartosz Golaszewski wrote:
> On Thu, 3 Sep 2026 13:05:28 +0200, Abel Vesa <abel.vesa@oss.qualcomm.com> said:
> > On 26-09-01 12:27:57, Lorenzo Bianconi wrote:
> >> 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 controller as a "gpio" child node of the switch and use it
> >> to control the PERST# reset lines of the two external downstream ports
> >> (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.
> >>
> >> Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
> >
> > Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
> >
> 
> FYI There's a v2 already on the list.

Thanks for the pointer. Will reply there.

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

end of thread, other threads:[~2026-09-03 12:59 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-01 10:27 [PATCH 0/5] PCI/pwrctrl: tc9563: introduce support for embedded GPIO controller Lorenzo Bianconi
2026-09-01 10:27 ` [PATCH 1/5] dt-bindings: PCI: toshiba,tc9563: document " Lorenzo Bianconi
2026-09-03 12:51   ` Krzysztof Kozlowski
2026-09-01 10:27 ` [PATCH 2/5] gpio: tc9563: add support for the " Lorenzo Bianconi
2026-09-01 10:27 ` [PATCH 3/5] PCI/pwrctrl: tc9563: add GPIO auxiliary device support Lorenzo Bianconi
2026-09-02 14:12   ` Bartosz Golaszewski
2026-09-03  7:52     ` Lorenzo Bianconi
2026-09-01 10:27 ` [PATCH 4/5] PCI/pwrctrl: tc9563: switch per-port reset to GPIO descriptor API Lorenzo Bianconi
2026-09-01 10:27 ` [PATCH 5/5] arm64: dts: qcom: qcs6490-rb3gen2: enable TC9563 embedded GPIO controller Lorenzo Bianconi
2026-09-01 12:20   ` Konrad Dybcio
2026-09-03 11:05   ` Abel Vesa
2026-09-03 12:44     ` Bartosz Golaszewski
2026-09-03 12:59       ` Abel Vesa

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