linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/2] PCI: Add support for PCIe wake interrupt
@ 2025-04-19  5:43 Krishna Chaitanya Chundru
  2025-04-19  5:43 ` [PATCH v2 1/2] arm64: dts: qcom: sc7280: Add wake GPIO Krishna Chaitanya Chundru
  2025-04-19  5:43 ` [PATCH v2 2/2] PCI: Add support for PCIe wake interrupt Krishna Chaitanya Chundru
  0 siblings, 2 replies; 10+ messages in thread
From: Krishna Chaitanya Chundru @ 2025-04-19  5:43 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, cros-qcom-dts-watchers, Bjorn Helgaas
  Cc: linux-arm-msm, devicetree, linux-kernel, linux-pci, quic_vbadigan,
	quic_mrana, Krishna Chaitanya Chundru

PCIe wake interrupt is needed for bringing back PCIe device state from
D3cold to D0.

This is pending from long time, there was two attempts done previously to
add wake support[1], [2]. Those series tried to add support for legacy
interrupts along with wake. Legacy interrupts are already available in
the latest kernel and we can ignore them. For the wake IRQ the series is
trying to use interrupts property define in the device tree.

This series is using gpio property instead of interrupts, from
gpio desc driver will allocate the dedicate IRQ and initiate the wake
IRQ from the port bus driver instead of pcie framework as adding in the
pcie framework will be applicable to the endpoint devices also. As the
port bus driver is for bridges, portbus driver is correct place to invoke
them.

Add two new functions, of_pci_setup_wake_irq() and of_pci_teardown_wake_irq(),
to manage wake interrupts for PCI devices using the Device Tree.

The series depend on the following series:
https://lore.kernel.org/linux-arm-msm/20250322-perst-v1-3-e5e4da74a204@oss.qualcomm.com/T/

[1]: https://lore.kernel.org/all/b2b91240-95fe-145d-502c-d52225497a34@nvidia.com/T/
[2]: https://lore.kernel.org/all/20171226023646.17722-1-jeffy.chen@rock-chips.com/

Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
---
Changes in v2:
- Move the wake irq teardown after pcie_port_device_remove
  and move of_pci_setup_wake_irq before pcie_link_rcec (Lukas)
- teardown wake irq in shutdown also.
- Link to v1: https://lore.kernel.org/r/20250401-wake_irq_support-v1-0-d2e22f4a0efd@oss.qualcomm.com

---
Krishna Chaitanya Chundru (2):
      arm64: dts: qcom: sc7280: Add wake GPIO
      PCI: Add support for PCIe wake interrupt

 arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts   |  1 +
 arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi |  1 +
 arch/arm64/boot/dts/qcom/sc7280-idp.dtsi       |  1 +
 drivers/pci/of.c                               | 60 ++++++++++++++++++++++++++
 drivers/pci/pci.h                              |  6 +++
 drivers/pci/pcie/portdrv.c                     | 12 +++++-
 6 files changed, 80 insertions(+), 1 deletion(-)
---
base-commit: 88d324e69ea9f3ae1c1905ea75d717c08bdb8e15
change-id: 20250329-wake_irq_support-79772fc8cd44
prerequisite-change-id: 20250101-perst-cb885b5a6129:v1
prerequisite-patch-id: 3cff2ef415ec12c8ddb7ce7193035ce546081243
prerequisite-patch-id: 820dbf5dc092c32c8394fbc33f9fe6b8da6e6eab
prerequisite-patch-id: 7f87f54386a87b39ca346b53d3c34ff0d0cb7911

Best regards,
-- 
Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>


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

* [PATCH v2 1/2] arm64: dts: qcom: sc7280: Add wake GPIO
  2025-04-19  5:43 [PATCH v2 0/2] PCI: Add support for PCIe wake interrupt Krishna Chaitanya Chundru
@ 2025-04-19  5:43 ` Krishna Chaitanya Chundru
  2025-06-01 15:23   ` Manivannan Sadhasivam
  2025-04-19  5:43 ` [PATCH v2 2/2] PCI: Add support for PCIe wake interrupt Krishna Chaitanya Chundru
  1 sibling, 1 reply; 10+ messages in thread
From: Krishna Chaitanya Chundru @ 2025-04-19  5:43 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, cros-qcom-dts-watchers, Bjorn Helgaas
  Cc: linux-arm-msm, devicetree, linux-kernel, linux-pci, quic_vbadigan,
	quic_mrana, Krishna Chaitanya Chundru

Add wake gpio which is needed to bring PCIe device state from D3cold to D0.

Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
---
 arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts   | 1 +
 arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi | 1 +
 arch/arm64/boot/dts/qcom/sc7280-idp.dtsi       | 1 +
 3 files changed, 3 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
index f54db6345b7af6f77bde496d4a07b857bf9d5f6e..ebfe2c5347be02ea730039e61401633fa49479d2 100644
--- a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
+++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
@@ -711,6 +711,7 @@ &mdss_edp_phy {
 
 &pcieport1 {
 	reset-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>;
+	wake-gpios = <&tlmm 3 GPIO_ACTIVE_LOW>;
 };
 
 &pcie1 {
diff --git a/arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi b/arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi
index 60b3cf50ea1d61dd5e8b573b5f1c6faa1c291eee..d435db860625d52842bf8e92d6223f67343121db 100644
--- a/arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi
@@ -477,6 +477,7 @@ &pcie1 {
 
 &pcieport1 {
 	reset-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>;
+	wake-gpios = <&tlmm 3 GPIO_ACTIVE_LOW>;
 };
 
 &pm8350c_pwm {
diff --git a/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi b/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi
index 19910670fc3a74628e6def6b8faf2fa17991d576..e107ae0d62460d0d0909c7351c17b0b15f99a235 100644
--- a/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi
@@ -416,6 +416,7 @@ &lpass_va_macro {
 
 &pcieport1 {
 	reset-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>;
+	wake-gpios = <&tlmm 3 GPIO_ACTIVE_LOW>;
 };
 
 &pcie1 {

-- 
2.34.1


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

* [PATCH v2 2/2] PCI: Add support for PCIe wake interrupt
  2025-04-19  5:43 [PATCH v2 0/2] PCI: Add support for PCIe wake interrupt Krishna Chaitanya Chundru
  2025-04-19  5:43 ` [PATCH v2 1/2] arm64: dts: qcom: sc7280: Add wake GPIO Krishna Chaitanya Chundru
@ 2025-04-19  5:43 ` Krishna Chaitanya Chundru
  2025-05-09  7:59   ` Krishna Chaitanya Chundru
                     ` (2 more replies)
  1 sibling, 3 replies; 10+ messages in thread
From: Krishna Chaitanya Chundru @ 2025-04-19  5:43 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, cros-qcom-dts-watchers, Bjorn Helgaas
  Cc: linux-arm-msm, devicetree, linux-kernel, linux-pci, quic_vbadigan,
	quic_mrana, Krishna Chaitanya Chundru

PCIe wake interrupt is needed for bringing back PCIe device state
from D3cold to D0.

Implement new functions, of_pci_setup_wake_irq() and
of_pci_teardown_wake_irq(), to manage wake interrupts for PCI devices
using the Device Tree.

From the port bus driver call these functions to enable wake support
for bridges.

Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
---
 drivers/pci/of.c           | 60 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/pci/pci.h          |  6 +++++
 drivers/pci/pcie/portdrv.c | 12 +++++++++-
 3 files changed, 77 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/of.c b/drivers/pci/of.c
index ab7a8252bf4137a17971c3eb8ab70ce78ca70969..13623797c88a03dfb9d9079518d87a5e1e68df38 100644
--- a/drivers/pci/of.c
+++ b/drivers/pci/of.c
@@ -7,6 +7,7 @@
 #define pr_fmt(fmt)	"PCI: OF: " fmt
 
 #include <linux/cleanup.h>
+#include <linux/gpio/consumer.h>
 #include <linux/irqdomain.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
@@ -15,6 +16,7 @@
 #include <linux/of_address.h>
 #include <linux/of_pci.h>
 #include <linux/platform_device.h>
+#include <linux/pm_wakeirq.h>
 #include "pci.h"
 
 #ifdef CONFIG_PCI
@@ -966,3 +968,61 @@ u32 of_pci_get_slot_power_limit(struct device_node *node,
 	return slot_power_limit_mw;
 }
 EXPORT_SYMBOL_GPL(of_pci_get_slot_power_limit);
+
+/**
+ * of_pci_setup_wake_irq - Set up wake interrupt for PCI device
+ * @pdev: The PCI device structure
+ *
+ * This function sets up the wake interrupt for a PCI device by getting the
+ * corresponding GPIO pin from the device tree, and configuring it as a
+ * dedicated wake interrupt.
+ *
+ * Return: 0 if the wake gpio is not available or successfully parsed else
+ * errno otherwise.
+ */
+int of_pci_setup_wake_irq(struct pci_dev *pdev)
+{
+	struct gpio_desc *wake;
+	struct device_node *dn;
+	int ret, wake_irq;
+
+	dn = pci_device_to_OF_node(pdev);
+	if (!dn)
+		return 0;
+
+	wake = devm_fwnode_gpiod_get(&pdev->dev, of_fwnode_handle(dn),
+				     "wake", GPIOD_IN, NULL);
+	if (IS_ERR(wake)) {
+		dev_warn(&pdev->dev, "Cannot get wake GPIO\n");
+		return 0;
+	}
+
+	wake_irq = gpiod_to_irq(wake);
+	device_init_wakeup(&pdev->dev, true);
+
+	ret = dev_pm_set_dedicated_wake_irq(&pdev->dev, wake_irq);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Failed to set wake IRQ: %d\n", ret);
+		device_init_wakeup(&pdev->dev, false);
+		return ret;
+	}
+	irq_set_irq_type(wake_irq, IRQ_TYPE_EDGE_FALLING);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(of_pci_setup_wake_irq);
+
+/**
+ * of_pci_teardown_wake_irq - Teardown wake interrupt setup for PCI device
+ *
+ * @pdev: The PCI device structure
+ *
+ * This function tears down the wake interrupt setup for a PCI device,
+ * clearing the dedicated wake interrupt and disabling device wake-up.
+ */
+void of_pci_teardown_wake_irq(struct pci_dev *pdev)
+{
+	dev_pm_clear_wake_irq(&pdev->dev);
+	device_init_wakeup(&pdev->dev, false);
+}
+EXPORT_SYMBOL_GPL(of_pci_teardown_wake_irq);
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index b81e99cd4b62a3022c8b07a09f212f6888674487..b2f65289f4156fa1851c2d2f20c4ca948f36258f 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -888,6 +888,9 @@ void pci_release_of_node(struct pci_dev *dev);
 void pci_set_bus_of_node(struct pci_bus *bus);
 void pci_release_bus_of_node(struct pci_bus *bus);
 
+int of_pci_setup_wake_irq(struct pci_dev *pdev);
+void of_pci_teardown_wake_irq(struct pci_dev *pdev);
+
 int devm_of_pci_bridge_init(struct device *dev, struct pci_host_bridge *bridge);
 bool of_pci_supply_present(struct device_node *np);
 
@@ -931,6 +934,9 @@ static inline int devm_of_pci_bridge_init(struct device *dev, struct pci_host_br
 	return 0;
 }
 
+static int of_pci_setup_wake_irq(struct pci_dev *pdev) { return 0; }
+static void of_pci_teardown_wake_irq(struct pci_dev *pdev) { }
+
 static inline bool of_pci_supply_present(struct device_node *np)
 {
 	return false;
diff --git a/drivers/pci/pcie/portdrv.c b/drivers/pci/pcie/portdrv.c
index e8318fd5f6ed537a1b236a3a0f054161d5710abd..33220ecf821c348d49782855eb5aa3f2fe5c335e 100644
--- a/drivers/pci/pcie/portdrv.c
+++ b/drivers/pci/pcie/portdrv.c
@@ -694,12 +694,18 @@ static int pcie_portdrv_probe(struct pci_dev *dev,
 	     (type != PCI_EXP_TYPE_RC_EC)))
 		return -ENODEV;
 
+	status = of_pci_setup_wake_irq(dev);
+	if (status)
+		return status;
+
 	if (type == PCI_EXP_TYPE_RC_EC)
 		pcie_link_rcec(dev);
 
 	status = pcie_port_device_register(dev);
-	if (status)
+	if (status) {
+		of_pci_teardown_wake_irq(dev);
 		return status;
+	}
 
 	pci_save_state(dev);
 
@@ -732,6 +738,8 @@ static void pcie_portdrv_remove(struct pci_dev *dev)
 
 	pcie_port_device_remove(dev);
 
+	of_pci_teardown_wake_irq(dev);
+
 	pci_disable_device(dev);
 }
 
@@ -744,6 +752,8 @@ static void pcie_portdrv_shutdown(struct pci_dev *dev)
 	}
 
 	pcie_port_device_remove(dev);
+
+	of_pci_teardown_wake_irq(dev);
 }
 
 static pci_ers_result_t pcie_portdrv_error_detected(struct pci_dev *dev,

-- 
2.34.1


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

* Re: [PATCH v2 2/2] PCI: Add support for PCIe wake interrupt
  2025-04-19  5:43 ` [PATCH v2 2/2] PCI: Add support for PCIe wake interrupt Krishna Chaitanya Chundru
@ 2025-05-09  7:59   ` Krishna Chaitanya Chundru
  2025-05-15  6:29     ` Sherry Sun
  2025-06-01 15:21   ` Manivannan Sadhasivam
  2025-06-03  7:42   ` neil.armstrong
  2 siblings, 1 reply; 10+ messages in thread
From: Krishna Chaitanya Chundru @ 2025-05-09  7:59 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: linux-arm-msm, Konrad Dybcio, devicetree, linux-kernel, linux-pci,
	quic_vbadigan, quic_mrana, cros-qcom-dts-watchers, Conor Dooley,
	Rob Herring, Krzysztof Kozlowski, Bjorn Andersson

A Gentle remainder.

- Krishna Chaitanya.

On 4/19/2025 11:13 AM, Krishna Chaitanya Chundru wrote:
> PCIe wake interrupt is needed for bringing back PCIe device state
> from D3cold to D0.
> 
> Implement new functions, of_pci_setup_wake_irq() and
> of_pci_teardown_wake_irq(), to manage wake interrupts for PCI devices
> using the Device Tree.
> 
>  From the port bus driver call these functions to enable wake support
> for bridges.
> 
> Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
> ---
>   drivers/pci/of.c           | 60 ++++++++++++++++++++++++++++++++++++++++++++++
>   drivers/pci/pci.h          |  6 +++++
>   drivers/pci/pcie/portdrv.c | 12 +++++++++-
>   3 files changed, 77 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pci/of.c b/drivers/pci/of.c
> index ab7a8252bf4137a17971c3eb8ab70ce78ca70969..13623797c88a03dfb9d9079518d87a5e1e68df38 100644
> --- a/drivers/pci/of.c
> +++ b/drivers/pci/of.c
> @@ -7,6 +7,7 @@
>   #define pr_fmt(fmt)	"PCI: OF: " fmt
>   
>   #include <linux/cleanup.h>
> +#include <linux/gpio/consumer.h>
>   #include <linux/irqdomain.h>
>   #include <linux/kernel.h>
>   #include <linux/pci.h>
> @@ -15,6 +16,7 @@
>   #include <linux/of_address.h>
>   #include <linux/of_pci.h>
>   #include <linux/platform_device.h>
> +#include <linux/pm_wakeirq.h>
>   #include "pci.h"
>   
>   #ifdef CONFIG_PCI
> @@ -966,3 +968,61 @@ u32 of_pci_get_slot_power_limit(struct device_node *node,
>   	return slot_power_limit_mw;
>   }
>   EXPORT_SYMBOL_GPL(of_pci_get_slot_power_limit);
> +
> +/**
> + * of_pci_setup_wake_irq - Set up wake interrupt for PCI device
> + * @pdev: The PCI device structure
> + *
> + * This function sets up the wake interrupt for a PCI device by getting the
> + * corresponding GPIO pin from the device tree, and configuring it as a
> + * dedicated wake interrupt.
> + *
> + * Return: 0 if the wake gpio is not available or successfully parsed else
> + * errno otherwise.
> + */
> +int of_pci_setup_wake_irq(struct pci_dev *pdev)
> +{
> +	struct gpio_desc *wake;
> +	struct device_node *dn;
> +	int ret, wake_irq;
> +
> +	dn = pci_device_to_OF_node(pdev);
> +	if (!dn)
> +		return 0;
> +
> +	wake = devm_fwnode_gpiod_get(&pdev->dev, of_fwnode_handle(dn),
> +				     "wake", GPIOD_IN, NULL);
> +	if (IS_ERR(wake)) {
> +		dev_warn(&pdev->dev, "Cannot get wake GPIO\n");
> +		return 0;
> +	}
> +
> +	wake_irq = gpiod_to_irq(wake);
> +	device_init_wakeup(&pdev->dev, true);
> +
> +	ret = dev_pm_set_dedicated_wake_irq(&pdev->dev, wake_irq);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "Failed to set wake IRQ: %d\n", ret);
> +		device_init_wakeup(&pdev->dev, false);
> +		return ret;
> +	}
> +	irq_set_irq_type(wake_irq, IRQ_TYPE_EDGE_FALLING);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(of_pci_setup_wake_irq);
> +
> +/**
> + * of_pci_teardown_wake_irq - Teardown wake interrupt setup for PCI device
> + *
> + * @pdev: The PCI device structure
> + *
> + * This function tears down the wake interrupt setup for a PCI device,
> + * clearing the dedicated wake interrupt and disabling device wake-up.
> + */
> +void of_pci_teardown_wake_irq(struct pci_dev *pdev)
> +{
> +	dev_pm_clear_wake_irq(&pdev->dev);
> +	device_init_wakeup(&pdev->dev, false);
> +}
> +EXPORT_SYMBOL_GPL(of_pci_teardown_wake_irq);
> diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
> index b81e99cd4b62a3022c8b07a09f212f6888674487..b2f65289f4156fa1851c2d2f20c4ca948f36258f 100644
> --- a/drivers/pci/pci.h
> +++ b/drivers/pci/pci.h
> @@ -888,6 +888,9 @@ void pci_release_of_node(struct pci_dev *dev);
>   void pci_set_bus_of_node(struct pci_bus *bus);
>   void pci_release_bus_of_node(struct pci_bus *bus);
>   
> +int of_pci_setup_wake_irq(struct pci_dev *pdev);
> +void of_pci_teardown_wake_irq(struct pci_dev *pdev);
> +
>   int devm_of_pci_bridge_init(struct device *dev, struct pci_host_bridge *bridge);
>   bool of_pci_supply_present(struct device_node *np);
>   
> @@ -931,6 +934,9 @@ static inline int devm_of_pci_bridge_init(struct device *dev, struct pci_host_br
>   	return 0;
>   }
>   
> +static int of_pci_setup_wake_irq(struct pci_dev *pdev) { return 0; }
> +static void of_pci_teardown_wake_irq(struct pci_dev *pdev) { }
> +
>   static inline bool of_pci_supply_present(struct device_node *np)
>   {
>   	return false;
> diff --git a/drivers/pci/pcie/portdrv.c b/drivers/pci/pcie/portdrv.c
> index e8318fd5f6ed537a1b236a3a0f054161d5710abd..33220ecf821c348d49782855eb5aa3f2fe5c335e 100644
> --- a/drivers/pci/pcie/portdrv.c
> +++ b/drivers/pci/pcie/portdrv.c
> @@ -694,12 +694,18 @@ static int pcie_portdrv_probe(struct pci_dev *dev,
>   	     (type != PCI_EXP_TYPE_RC_EC)))
>   		return -ENODEV;
>   
> +	status = of_pci_setup_wake_irq(dev);
> +	if (status)
> +		return status;
> +
>   	if (type == PCI_EXP_TYPE_RC_EC)
>   		pcie_link_rcec(dev);
>   
>   	status = pcie_port_device_register(dev);
> -	if (status)
> +	if (status) {
> +		of_pci_teardown_wake_irq(dev);
>   		return status;
> +	}
>   
>   	pci_save_state(dev);
>   
> @@ -732,6 +738,8 @@ static void pcie_portdrv_remove(struct pci_dev *dev)
>   
>   	pcie_port_device_remove(dev);
>   
> +	of_pci_teardown_wake_irq(dev);
> +
>   	pci_disable_device(dev);
>   }
>   
> @@ -744,6 +752,8 @@ static void pcie_portdrv_shutdown(struct pci_dev *dev)
>   	}
>   
>   	pcie_port_device_remove(dev);
> +
> +	of_pci_teardown_wake_irq(dev);
>   }
>   
>   static pci_ers_result_t pcie_portdrv_error_detected(struct pci_dev *dev,
> 

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

* RE: [PATCH v2 2/2] PCI: Add support for PCIe wake interrupt
  2025-05-09  7:59   ` Krishna Chaitanya Chundru
@ 2025-05-15  6:29     ` Sherry Sun
  2025-05-21 10:44       ` Krishna Chaitanya Chundru
  0 siblings, 1 reply; 10+ messages in thread
From: Sherry Sun @ 2025-05-15  6:29 UTC (permalink / raw)
  To: Krishna Chaitanya Chundru, Bjorn Helgaas
  Cc: linux-arm-msm@vger.kernel.org, Konrad Dybcio,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-pci@vger.kernel.org, quic_vbadigan@quicinc.com,
	quic_mrana@quicinc.com, cros-qcom-dts-watchers@chromium.org,
	Conor Dooley, Rob Herring, Krzysztof Kozlowski, Bjorn Andersson



> -----Original Message-----
> From: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
> Sent: Friday, May 9, 2025 3:59 PM
> To: Bjorn Helgaas <bhelgaas@google.com>
> Cc: linux-arm-msm@vger.kernel.org; Konrad Dybcio
> <konradybcio@kernel.org>; devicetree@vger.kernel.org; linux-
> kernel@vger.kernel.org; linux-pci@vger.kernel.org;
> quic_vbadigan@quicinc.com; quic_mrana@quicinc.com; cros-qcom-dts-
> watchers@chromium.org; Conor Dooley <conor+dt@kernel.org>; Rob Herring
> <robh@kernel.org>; Krzysztof Kozlowski <krzk+dt@kernel.org>; Bjorn
> Andersson <andersson@kernel.org>
> Subject: Re: [PATCH v2 2/2] PCI: Add support for PCIe wake interrupt
> 
> A Gentle remainder.
> 
> - Krishna Chaitanya.
> 
> On 4/19/2025 11:13 AM, Krishna Chaitanya Chundru wrote:
> > PCIe wake interrupt is needed for bringing back PCIe device state from
> > D3cold to D0.
> >
> > Implement new functions, of_pci_setup_wake_irq() and
> > of_pci_teardown_wake_irq(), to manage wake interrupts for PCI devices
> > using the Device Tree.
> >
> >  From the port bus driver call these functions to enable wake support
> > for bridges.
> >
> > Signed-off-by: Krishna Chaitanya Chundru
> > <krishna.chundru@oss.qualcomm.com>

Hi Krishna,

I have tested the patch set on i.MX platforms, it works.
you can add my Tested-by: Sherry Sun <sherry.sun@nxp.com>.

BTW, as PEWAKE is a standard feature in PCIe bus specification,
Suppose you may need to add wake-gpios property into the common
PCI root port dt-schema.

Best Regards
Sherry

> > ---
> >   drivers/pci/of.c           | 60
> ++++++++++++++++++++++++++++++++++++++++++++++
> >   drivers/pci/pci.h          |  6 +++++
> >   drivers/pci/pcie/portdrv.c | 12 +++++++++-
> >   3 files changed, 77 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/pci/of.c b/drivers/pci/of.c index
> >
> ab7a8252bf4137a17971c3eb8ab70ce78ca70969..13623797c88a03dfb9d90795
> 18d8
> > 7a5e1e68df38 100644
> > --- a/drivers/pci/of.c
> > +++ b/drivers/pci/of.c
> > @@ -7,6 +7,7 @@
> >   #define pr_fmt(fmt)	"PCI: OF: " fmt
> >
> >   #include <linux/cleanup.h>
> > +#include <linux/gpio/consumer.h>
> >   #include <linux/irqdomain.h>
> >   #include <linux/kernel.h>
> >   #include <linux/pci.h>
> > @@ -15,6 +16,7 @@
> >   #include <linux/of_address.h>
> >   #include <linux/of_pci.h>
> >   #include <linux/platform_device.h>
> > +#include <linux/pm_wakeirq.h>
> >   #include "pci.h"
> >
> >   #ifdef CONFIG_PCI
> > @@ -966,3 +968,61 @@ u32 of_pci_get_slot_power_limit(struct
> device_node *node,
> >   	return slot_power_limit_mw;
> >   }
> >   EXPORT_SYMBOL_GPL(of_pci_get_slot_power_limit);
> > +
> > +/**
> > + * of_pci_setup_wake_irq - Set up wake interrupt for PCI device
> > + * @pdev: The PCI device structure
> > + *
> > + * This function sets up the wake interrupt for a PCI device by
> > +getting the
> > + * corresponding GPIO pin from the device tree, and configuring it as
> > +a
> > + * dedicated wake interrupt.
> > + *
> > + * Return: 0 if the wake gpio is not available or successfully parsed
> > +else
> > + * errno otherwise.
> > + */
> > +int of_pci_setup_wake_irq(struct pci_dev *pdev) {
> > +	struct gpio_desc *wake;
> > +	struct device_node *dn;
> > +	int ret, wake_irq;
> > +
> > +	dn = pci_device_to_OF_node(pdev);
> > +	if (!dn)
> > +		return 0;
> > +
> > +	wake = devm_fwnode_gpiod_get(&pdev->dev,
> of_fwnode_handle(dn),
> > +				     "wake", GPIOD_IN, NULL);
> > +	if (IS_ERR(wake)) {
> > +		dev_warn(&pdev->dev, "Cannot get wake GPIO\n");
> > +		return 0;
> > +	}
> > +
> > +	wake_irq = gpiod_to_irq(wake);
> > +	device_init_wakeup(&pdev->dev, true);
> > +
> > +	ret = dev_pm_set_dedicated_wake_irq(&pdev->dev, wake_irq);
> > +	if (ret < 0) {
> > +		dev_err(&pdev->dev, "Failed to set wake IRQ: %d\n", ret);
> > +		device_init_wakeup(&pdev->dev, false);
> > +		return ret;
> > +	}
> > +	irq_set_irq_type(wake_irq, IRQ_TYPE_EDGE_FALLING);
> > +
> > +	return 0;
> > +}
> > +EXPORT_SYMBOL_GPL(of_pci_setup_wake_irq);
> > +
> > +/**
> > + * of_pci_teardown_wake_irq - Teardown wake interrupt setup for PCI
> > +device
> > + *
> > + * @pdev: The PCI device structure
> > + *
> > + * This function tears down the wake interrupt setup for a PCI
> > +device,
> > + * clearing the dedicated wake interrupt and disabling device wake-up.
> > + */
> > +void of_pci_teardown_wake_irq(struct pci_dev *pdev) {
> > +	dev_pm_clear_wake_irq(&pdev->dev);
> > +	device_init_wakeup(&pdev->dev, false); }
> > +EXPORT_SYMBOL_GPL(of_pci_teardown_wake_irq);
> > diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index
> >
> b81e99cd4b62a3022c8b07a09f212f6888674487..b2f65289f4156fa1851c2d2f2
> 0c4
> > ca948f36258f 100644
> > --- a/drivers/pci/pci.h
> > +++ b/drivers/pci/pci.h
> > @@ -888,6 +888,9 @@ void pci_release_of_node(struct pci_dev *dev);
> >   void pci_set_bus_of_node(struct pci_bus *bus);
> >   void pci_release_bus_of_node(struct pci_bus *bus);
> >
> > +int of_pci_setup_wake_irq(struct pci_dev *pdev); void
> > +of_pci_teardown_wake_irq(struct pci_dev *pdev);
> > +
> >   int devm_of_pci_bridge_init(struct device *dev, struct pci_host_bridge
> *bridge);
> >   bool of_pci_supply_present(struct device_node *np);
> >
> > @@ -931,6 +934,9 @@ static inline int devm_of_pci_bridge_init(struct
> device *dev, struct pci_host_br
> >   	return 0;
> >   }
> >
> > +static int of_pci_setup_wake_irq(struct pci_dev *pdev) { return 0; }
> > +static void of_pci_teardown_wake_irq(struct pci_dev *pdev) { }
> > +
> >   static inline bool of_pci_supply_present(struct device_node *np)
> >   {
> >   	return false;
> > diff --git a/drivers/pci/pcie/portdrv.c b/drivers/pci/pcie/portdrv.c
> > index
> >
> e8318fd5f6ed537a1b236a3a0f054161d5710abd..33220ecf821c348d49782855
> eb5a
> > a3f2fe5c335e 100644
> > --- a/drivers/pci/pcie/portdrv.c
> > +++ b/drivers/pci/pcie/portdrv.c
> > @@ -694,12 +694,18 @@ static int pcie_portdrv_probe(struct pci_dev *dev,
> >   	     (type != PCI_EXP_TYPE_RC_EC)))
> >   		return -ENODEV;
> >
> > +	status = of_pci_setup_wake_irq(dev);
> > +	if (status)
> > +		return status;
> > +
> >   	if (type == PCI_EXP_TYPE_RC_EC)
> >   		pcie_link_rcec(dev);
> >
> >   	status = pcie_port_device_register(dev);
> > -	if (status)
> > +	if (status) {
> > +		of_pci_teardown_wake_irq(dev);
> >   		return status;
> > +	}
> >
> >   	pci_save_state(dev);
> >
> > @@ -732,6 +738,8 @@ static void pcie_portdrv_remove(struct pci_dev
> > *dev)
> >
> >   	pcie_port_device_remove(dev);
> >
> > +	of_pci_teardown_wake_irq(dev);
> > +
> >   	pci_disable_device(dev);
> >   }
> >
> > @@ -744,6 +752,8 @@ static void pcie_portdrv_shutdown(struct pci_dev
> *dev)
> >   	}
> >
> >   	pcie_port_device_remove(dev);
> > +
> > +	of_pci_teardown_wake_irq(dev);
> >   }
> >
> >   static pci_ers_result_t pcie_portdrv_error_detected(struct pci_dev
> > *dev,
> >


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

* Re: [PATCH v2 2/2] PCI: Add support for PCIe wake interrupt
  2025-05-15  6:29     ` Sherry Sun
@ 2025-05-21 10:44       ` Krishna Chaitanya Chundru
  0 siblings, 0 replies; 10+ messages in thread
From: Krishna Chaitanya Chundru @ 2025-05-21 10:44 UTC (permalink / raw)
  To: Sherry Sun, Bjorn Helgaas
  Cc: linux-arm-msm@vger.kernel.org, Konrad Dybcio,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-pci@vger.kernel.org, quic_vbadigan@quicinc.com,
	quic_mrana@quicinc.com, cros-qcom-dts-watchers@chromium.org,
	Conor Dooley, Rob Herring, Krzysztof Kozlowski, Bjorn Andersson



On 5/15/2025 11:59 AM, Sherry Sun wrote:
> 
> 
>> -----Original Message-----
>> From: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
>> Sent: Friday, May 9, 2025 3:59 PM
>> To: Bjorn Helgaas <bhelgaas@google.com>
>> Cc: linux-arm-msm@vger.kernel.org; Konrad Dybcio
>> <konradybcio@kernel.org>; devicetree@vger.kernel.org; linux-
>> kernel@vger.kernel.org; linux-pci@vger.kernel.org;
>> quic_vbadigan@quicinc.com; quic_mrana@quicinc.com; cros-qcom-dts-
>> watchers@chromium.org; Conor Dooley <conor+dt@kernel.org>; Rob Herring
>> <robh@kernel.org>; Krzysztof Kozlowski <krzk+dt@kernel.org>; Bjorn
>> Andersson <andersson@kernel.org>
>> Subject: Re: [PATCH v2 2/2] PCI: Add support for PCIe wake interrupt
>>
>> A Gentle remainder.
>>
>> - Krishna Chaitanya.
>>
>> On 4/19/2025 11:13 AM, Krishna Chaitanya Chundru wrote:
>>> PCIe wake interrupt is needed for bringing back PCIe device state from
>>> D3cold to D0.
>>>
>>> Implement new functions, of_pci_setup_wake_irq() and
>>> of_pci_teardown_wake_irq(), to manage wake interrupts for PCI devices
>>> using the Device Tree.
>>>
>>>   From the port bus driver call these functions to enable wake support
>>> for bridges.
>>>
>>> Signed-off-by: Krishna Chaitanya Chundru
>>> <krishna.chundru@oss.qualcomm.com>
> 
> Hi Krishna,
> 
> I have tested the patch set on i.MX platforms, it works.
> you can add my Tested-by: Sherry Sun <sherry.sun@nxp.com>.
> 
> BTW, as PEWAKE is a standard feature in PCIe bus specification,
> Suppose you may need to add wake-gpios property into the common
> PCI root port dt-schema.
> 
I raised a patch for this:
https://lore.kernel.org/all/20250515090517.3506772-1-krishna.chundru@oss.qualcomm.com/

- Krishna Chaitanya.
> Best Regards
> Sherry
> 
>>> ---
>>>    drivers/pci/of.c           | 60
>> ++++++++++++++++++++++++++++++++++++++++++++++
>>>    drivers/pci/pci.h          |  6 +++++
>>>    drivers/pci/pcie/portdrv.c | 12 +++++++++-
>>>    3 files changed, 77 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/pci/of.c b/drivers/pci/of.c index
>>>
>> ab7a8252bf4137a17971c3eb8ab70ce78ca70969..13623797c88a03dfb9d90795
>> 18d8
>>> 7a5e1e68df38 100644
>>> --- a/drivers/pci/of.c
>>> +++ b/drivers/pci/of.c
>>> @@ -7,6 +7,7 @@
>>>    #define pr_fmt(fmt)	"PCI: OF: " fmt
>>>
>>>    #include <linux/cleanup.h>
>>> +#include <linux/gpio/consumer.h>
>>>    #include <linux/irqdomain.h>
>>>    #include <linux/kernel.h>
>>>    #include <linux/pci.h>
>>> @@ -15,6 +16,7 @@
>>>    #include <linux/of_address.h>
>>>    #include <linux/of_pci.h>
>>>    #include <linux/platform_device.h>
>>> +#include <linux/pm_wakeirq.h>
>>>    #include "pci.h"
>>>
>>>    #ifdef CONFIG_PCI
>>> @@ -966,3 +968,61 @@ u32 of_pci_get_slot_power_limit(struct
>> device_node *node,
>>>    	return slot_power_limit_mw;
>>>    }
>>>    EXPORT_SYMBOL_GPL(of_pci_get_slot_power_limit);
>>> +
>>> +/**
>>> + * of_pci_setup_wake_irq - Set up wake interrupt for PCI device
>>> + * @pdev: The PCI device structure
>>> + *
>>> + * This function sets up the wake interrupt for a PCI device by
>>> +getting the
>>> + * corresponding GPIO pin from the device tree, and configuring it as
>>> +a
>>> + * dedicated wake interrupt.
>>> + *
>>> + * Return: 0 if the wake gpio is not available or successfully parsed
>>> +else
>>> + * errno otherwise.
>>> + */
>>> +int of_pci_setup_wake_irq(struct pci_dev *pdev) {
>>> +	struct gpio_desc *wake;
>>> +	struct device_node *dn;
>>> +	int ret, wake_irq;
>>> +
>>> +	dn = pci_device_to_OF_node(pdev);
>>> +	if (!dn)
>>> +		return 0;
>>> +
>>> +	wake = devm_fwnode_gpiod_get(&pdev->dev,
>> of_fwnode_handle(dn),
>>> +				     "wake", GPIOD_IN, NULL);
>>> +	if (IS_ERR(wake)) {
>>> +		dev_warn(&pdev->dev, "Cannot get wake GPIO\n");
>>> +		return 0;
>>> +	}
>>> +
>>> +	wake_irq = gpiod_to_irq(wake);
>>> +	device_init_wakeup(&pdev->dev, true);
>>> +
>>> +	ret = dev_pm_set_dedicated_wake_irq(&pdev->dev, wake_irq);
>>> +	if (ret < 0) {
>>> +		dev_err(&pdev->dev, "Failed to set wake IRQ: %d\n", ret);
>>> +		device_init_wakeup(&pdev->dev, false);
>>> +		return ret;
>>> +	}
>>> +	irq_set_irq_type(wake_irq, IRQ_TYPE_EDGE_FALLING);
>>> +
>>> +	return 0;
>>> +}
>>> +EXPORT_SYMBOL_GPL(of_pci_setup_wake_irq);
>>> +
>>> +/**
>>> + * of_pci_teardown_wake_irq - Teardown wake interrupt setup for PCI
>>> +device
>>> + *
>>> + * @pdev: The PCI device structure
>>> + *
>>> + * This function tears down the wake interrupt setup for a PCI
>>> +device,
>>> + * clearing the dedicated wake interrupt and disabling device wake-up.
>>> + */
>>> +void of_pci_teardown_wake_irq(struct pci_dev *pdev) {
>>> +	dev_pm_clear_wake_irq(&pdev->dev);
>>> +	device_init_wakeup(&pdev->dev, false); }
>>> +EXPORT_SYMBOL_GPL(of_pci_teardown_wake_irq);
>>> diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index
>>>
>> b81e99cd4b62a3022c8b07a09f212f6888674487..b2f65289f4156fa1851c2d2f2
>> 0c4
>>> ca948f36258f 100644
>>> --- a/drivers/pci/pci.h
>>> +++ b/drivers/pci/pci.h
>>> @@ -888,6 +888,9 @@ void pci_release_of_node(struct pci_dev *dev);
>>>    void pci_set_bus_of_node(struct pci_bus *bus);
>>>    void pci_release_bus_of_node(struct pci_bus *bus);
>>>
>>> +int of_pci_setup_wake_irq(struct pci_dev *pdev); void
>>> +of_pci_teardown_wake_irq(struct pci_dev *pdev);
>>> +
>>>    int devm_of_pci_bridge_init(struct device *dev, struct pci_host_bridge
>> *bridge);
>>>    bool of_pci_supply_present(struct device_node *np);
>>>
>>> @@ -931,6 +934,9 @@ static inline int devm_of_pci_bridge_init(struct
>> device *dev, struct pci_host_br
>>>    	return 0;
>>>    }
>>>
>>> +static int of_pci_setup_wake_irq(struct pci_dev *pdev) { return 0; }
>>> +static void of_pci_teardown_wake_irq(struct pci_dev *pdev) { }
>>> +
>>>    static inline bool of_pci_supply_present(struct device_node *np)
>>>    {
>>>    	return false;
>>> diff --git a/drivers/pci/pcie/portdrv.c b/drivers/pci/pcie/portdrv.c
>>> index
>>>
>> e8318fd5f6ed537a1b236a3a0f054161d5710abd..33220ecf821c348d49782855
>> eb5a
>>> a3f2fe5c335e 100644
>>> --- a/drivers/pci/pcie/portdrv.c
>>> +++ b/drivers/pci/pcie/portdrv.c
>>> @@ -694,12 +694,18 @@ static int pcie_portdrv_probe(struct pci_dev *dev,
>>>    	     (type != PCI_EXP_TYPE_RC_EC)))
>>>    		return -ENODEV;
>>>
>>> +	status = of_pci_setup_wake_irq(dev);
>>> +	if (status)
>>> +		return status;
>>> +
>>>    	if (type == PCI_EXP_TYPE_RC_EC)
>>>    		pcie_link_rcec(dev);
>>>
>>>    	status = pcie_port_device_register(dev);
>>> -	if (status)
>>> +	if (status) {
>>> +		of_pci_teardown_wake_irq(dev);
>>>    		return status;
>>> +	}
>>>
>>>    	pci_save_state(dev);
>>>
>>> @@ -732,6 +738,8 @@ static void pcie_portdrv_remove(struct pci_dev
>>> *dev)
>>>
>>>    	pcie_port_device_remove(dev);
>>>
>>> +	of_pci_teardown_wake_irq(dev);
>>> +
>>>    	pci_disable_device(dev);
>>>    }
>>>
>>> @@ -744,6 +752,8 @@ static void pcie_portdrv_shutdown(struct pci_dev
>> *dev)
>>>    	}
>>>
>>>    	pcie_port_device_remove(dev);
>>> +
>>> +	of_pci_teardown_wake_irq(dev);
>>>    }
>>>
>>>    static pci_ers_result_t pcie_portdrv_error_detected(struct pci_dev
>>> *dev,
>>>
> 

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

* Re: [PATCH v2 2/2] PCI: Add support for PCIe wake interrupt
  2025-04-19  5:43 ` [PATCH v2 2/2] PCI: Add support for PCIe wake interrupt Krishna Chaitanya Chundru
  2025-05-09  7:59   ` Krishna Chaitanya Chundru
@ 2025-06-01 15:21   ` Manivannan Sadhasivam
  2025-06-03  6:26     ` Krishna Chaitanya Chundru
  2025-06-03  7:42   ` neil.armstrong
  2 siblings, 1 reply; 10+ messages in thread
From: Manivannan Sadhasivam @ 2025-06-01 15:21 UTC (permalink / raw)
  To: Krishna Chaitanya Chundru
  Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, cros-qcom-dts-watchers, Bjorn Helgaas,
	linux-arm-msm, devicetree, linux-kernel, linux-pci, quic_vbadigan,
	quic_mrana

On Sat, Apr 19, 2025 at 11:13:04AM +0530, Krishna Chaitanya Chundru wrote:

Subject prefix should be 'PCI/portdrv'

> PCIe wake interrupt is needed for bringing back PCIe device state
> from D3cold to D0.
> 
> Implement new functions, of_pci_setup_wake_irq() and
> of_pci_teardown_wake_irq(), to manage wake interrupts for PCI devices
> using the Device Tree.
> 
> From the port bus driver call these functions to enable wake support
> for bridges.
> 
> Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
> ---
>  drivers/pci/of.c           | 60 ++++++++++++++++++++++++++++++++++++++++++++++
>  drivers/pci/pci.h          |  6 +++++
>  drivers/pci/pcie/portdrv.c | 12 +++++++++-
>  3 files changed, 77 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pci/of.c b/drivers/pci/of.c
> index ab7a8252bf4137a17971c3eb8ab70ce78ca70969..13623797c88a03dfb9d9079518d87a5e1e68df38 100644
> --- a/drivers/pci/of.c
> +++ b/drivers/pci/of.c
> @@ -7,6 +7,7 @@
>  #define pr_fmt(fmt)	"PCI: OF: " fmt
>  
>  #include <linux/cleanup.h>
> +#include <linux/gpio/consumer.h>
>  #include <linux/irqdomain.h>
>  #include <linux/kernel.h>
>  #include <linux/pci.h>
> @@ -15,6 +16,7 @@
>  #include <linux/of_address.h>
>  #include <linux/of_pci.h>
>  #include <linux/platform_device.h>
> +#include <linux/pm_wakeirq.h>
>  #include "pci.h"
>  
>  #ifdef CONFIG_PCI
> @@ -966,3 +968,61 @@ u32 of_pci_get_slot_power_limit(struct device_node *node,
>  	return slot_power_limit_mw;
>  }
>  EXPORT_SYMBOL_GPL(of_pci_get_slot_power_limit);
> +
> +/**
> + * of_pci_setup_wake_irq - Set up wake interrupt for PCI device

This function is for setting up the wake interrupt for slot, not for endpoint
devices, isn't it? Then it should be named as such:

	of_pci_slot_setup_wake_irq()

> + * @pdev: The PCI device structure
> + *
> + * This function sets up the wake interrupt for a PCI device by getting the
> + * corresponding GPIO pin from the device tree, and configuring it as a

s/GPIO pin/WAKE# GPIO

> + * dedicated wake interrupt.
> + *
> + * Return: 0 if the wake gpio is not available or successfully parsed else

s/wake gpio/WAKE# GPIO

> + * errno otherwise.
> + */
> +int of_pci_setup_wake_irq(struct pci_dev *pdev)
> +{
> +	struct gpio_desc *wake;
> +	struct device_node *dn;
> +	int ret, wake_irq;
> +
> +	dn = pci_device_to_OF_node(pdev);
> +	if (!dn)
> +		return 0;
> +
> +	wake = devm_fwnode_gpiod_get(&pdev->dev, of_fwnode_handle(dn),
> +				     "wake", GPIOD_IN, NULL);
> +	if (IS_ERR(wake)) {
> +		dev_warn(&pdev->dev, "Cannot get wake GPIO\n");

WAKE# is an optional GPIO. So the driver should not warn users if it is not
defined in the root port node. It should however print the error log and return
errno, if the API returns other than -ENOENT.

> +		return 0;
> +	}
> +
> +	wake_irq = gpiod_to_irq(wake);
> +	device_init_wakeup(&pdev->dev, true);
> +
> +	ret = dev_pm_set_dedicated_wake_irq(&pdev->dev, wake_irq);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "Failed to set wake IRQ: %d\n", ret);
> +		device_init_wakeup(&pdev->dev, false);
> +		return ret;
> +	}
> +	irq_set_irq_type(wake_irq, IRQ_TYPE_EDGE_FALLING);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(of_pci_setup_wake_irq);
> +
> +/**
> + * of_pci_teardown_wake_irq - Teardown wake interrupt setup for PCI device

Same comment as above.

> + *
> + * @pdev: The PCI device structure
> + *
> + * This function tears down the wake interrupt setup for a PCI device,
> + * clearing the dedicated wake interrupt and disabling device wake-up.
> + */
> +void of_pci_teardown_wake_irq(struct pci_dev *pdev)
> +{
> +	dev_pm_clear_wake_irq(&pdev->dev);
> +	device_init_wakeup(&pdev->dev, false);
> +}
> +EXPORT_SYMBOL_GPL(of_pci_teardown_wake_irq);
> diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
> index b81e99cd4b62a3022c8b07a09f212f6888674487..b2f65289f4156fa1851c2d2f20c4ca948f36258f 100644
> --- a/drivers/pci/pci.h
> +++ b/drivers/pci/pci.h
> @@ -888,6 +888,9 @@ void pci_release_of_node(struct pci_dev *dev);
>  void pci_set_bus_of_node(struct pci_bus *bus);
>  void pci_release_bus_of_node(struct pci_bus *bus);
>  
> +int of_pci_setup_wake_irq(struct pci_dev *pdev);
> +void of_pci_teardown_wake_irq(struct pci_dev *pdev);
> +
>  int devm_of_pci_bridge_init(struct device *dev, struct pci_host_bridge *bridge);
>  bool of_pci_supply_present(struct device_node *np);
>  
> @@ -931,6 +934,9 @@ static inline int devm_of_pci_bridge_init(struct device *dev, struct pci_host_br
>  	return 0;
>  }
>  
> +static int of_pci_setup_wake_irq(struct pci_dev *pdev) { return 0; }
> +static void of_pci_teardown_wake_irq(struct pci_dev *pdev) { }
> +

Provide stub for these APIs if CONFIG_OF is not enabled.

- Mani

-- 
மணிவண்ணன் சதாசிவம்

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

* Re: [PATCH v2 1/2] arm64: dts: qcom: sc7280: Add wake GPIO
  2025-04-19  5:43 ` [PATCH v2 1/2] arm64: dts: qcom: sc7280: Add wake GPIO Krishna Chaitanya Chundru
@ 2025-06-01 15:23   ` Manivannan Sadhasivam
  0 siblings, 0 replies; 10+ messages in thread
From: Manivannan Sadhasivam @ 2025-06-01 15:23 UTC (permalink / raw)
  To: Krishna Chaitanya Chundru
  Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, cros-qcom-dts-watchers, Bjorn Helgaas,
	linux-arm-msm, devicetree, linux-kernel, linux-pci, quic_vbadigan,
	quic_mrana

On Sat, Apr 19, 2025 at 11:13:03AM +0530, Krishna Chaitanya Chundru wrote:
> Add wake gpio which is needed to bring PCIe device state from D3cold to D0.

WAKE# GPIO

> 
> Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>

- Mani

> ---
>  arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts   | 1 +
>  arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi | 1 +
>  arch/arm64/boot/dts/qcom/sc7280-idp.dtsi       | 1 +
>  3 files changed, 3 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
> index f54db6345b7af6f77bde496d4a07b857bf9d5f6e..ebfe2c5347be02ea730039e61401633fa49479d2 100644
> --- a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
> +++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
> @@ -711,6 +711,7 @@ &mdss_edp_phy {
>  
>  &pcieport1 {
>  	reset-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>;
> +	wake-gpios = <&tlmm 3 GPIO_ACTIVE_LOW>;
>  };
>  
>  &pcie1 {
> diff --git a/arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi b/arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi
> index 60b3cf50ea1d61dd5e8b573b5f1c6faa1c291eee..d435db860625d52842bf8e92d6223f67343121db 100644
> --- a/arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi
> +++ b/arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi
> @@ -477,6 +477,7 @@ &pcie1 {
>  
>  &pcieport1 {
>  	reset-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>;
> +	wake-gpios = <&tlmm 3 GPIO_ACTIVE_LOW>;
>  };
>  
>  &pm8350c_pwm {
> diff --git a/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi b/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi
> index 19910670fc3a74628e6def6b8faf2fa17991d576..e107ae0d62460d0d0909c7351c17b0b15f99a235 100644
> --- a/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi
> +++ b/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi
> @@ -416,6 +416,7 @@ &lpass_va_macro {
>  
>  &pcieport1 {
>  	reset-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>;
> +	wake-gpios = <&tlmm 3 GPIO_ACTIVE_LOW>;
>  };
>  
>  &pcie1 {
> 
> -- 
> 2.34.1
> 
> 

-- 
மணிவண்ணன் சதாசிவம்

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

* Re: [PATCH v2 2/2] PCI: Add support for PCIe wake interrupt
  2025-06-01 15:21   ` Manivannan Sadhasivam
@ 2025-06-03  6:26     ` Krishna Chaitanya Chundru
  0 siblings, 0 replies; 10+ messages in thread
From: Krishna Chaitanya Chundru @ 2025-06-03  6:26 UTC (permalink / raw)
  To: Manivannan Sadhasivam
  Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, cros-qcom-dts-watchers, Bjorn Helgaas,
	linux-arm-msm, devicetree, linux-kernel, linux-pci, quic_vbadigan,
	quic_mrana



On 6/1/2025 8:51 PM, Manivannan Sadhasivam wrote:
> On Sat, Apr 19, 2025 at 11:13:04AM +0530, Krishna Chaitanya Chundru wrote:
> 
> Subject prefix should be 'PCI/portdrv'
> 
>> PCIe wake interrupt is needed for bringing back PCIe device state
>> from D3cold to D0.
>>
>> Implement new functions, of_pci_setup_wake_irq() and
>> of_pci_teardown_wake_irq(), to manage wake interrupts for PCI devices
>> using the Device Tree.
>>
>>  From the port bus driver call these functions to enable wake support
>> for bridges.
>>
>> Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
>> ---
>>   drivers/pci/of.c           | 60 ++++++++++++++++++++++++++++++++++++++++++++++
>>   drivers/pci/pci.h          |  6 +++++
>>   drivers/pci/pcie/portdrv.c | 12 +++++++++-
>>   3 files changed, 77 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/pci/of.c b/drivers/pci/of.c
>> index ab7a8252bf4137a17971c3eb8ab70ce78ca70969..13623797c88a03dfb9d9079518d87a5e1e68df38 100644
>> --- a/drivers/pci/of.c
>> +++ b/drivers/pci/of.c
>> @@ -7,6 +7,7 @@
>>   #define pr_fmt(fmt)	"PCI: OF: " fmt
>>   
>>   #include <linux/cleanup.h>
>> +#include <linux/gpio/consumer.h>
>>   #include <linux/irqdomain.h>
>>   #include <linux/kernel.h>
>>   #include <linux/pci.h>
>> @@ -15,6 +16,7 @@
>>   #include <linux/of_address.h>
>>   #include <linux/of_pci.h>
>>   #include <linux/platform_device.h>
>> +#include <linux/pm_wakeirq.h>
>>   #include "pci.h"
>>   
>>   #ifdef CONFIG_PCI
>> @@ -966,3 +968,61 @@ u32 of_pci_get_slot_power_limit(struct device_node *node,
>>   	return slot_power_limit_mw;
>>   }
>>   EXPORT_SYMBOL_GPL(of_pci_get_slot_power_limit);
>> +
>> +/**
>> + * of_pci_setup_wake_irq - Set up wake interrupt for PCI device
> 
> This function is for setting up the wake interrupt for slot, not for endpoint
> devices, isn't it? Then it should be named as such:
> 
> 	of_pci_slot_setup_wake_irq()
> 
>> + * @pdev: The PCI device structure
>> + *
>> + * This function sets up the wake interrupt for a PCI device by getting the
>> + * corresponding GPIO pin from the device tree, and configuring it as a
> 
> s/GPIO pin/WAKE# GPIO
> 
>> + * dedicated wake interrupt.
>> + *
>> + * Return: 0 if the wake gpio is not available or successfully parsed else
> 
> s/wake gpio/WAKE# GPIO
> 
>> + * errno otherwise.
>> + */
>> +int of_pci_setup_wake_irq(struct pci_dev *pdev)
>> +{
>> +	struct gpio_desc *wake;
>> +	struct device_node *dn;
>> +	int ret, wake_irq;
>> +
>> +	dn = pci_device_to_OF_node(pdev);
>> +	if (!dn)
>> +		return 0;
>> +
>> +	wake = devm_fwnode_gpiod_get(&pdev->dev, of_fwnode_handle(dn),
>> +				     "wake", GPIOD_IN, NULL);
>> +	if (IS_ERR(wake)) {
>> +		dev_warn(&pdev->dev, "Cannot get wake GPIO\n");
> 
> WAKE# is an optional GPIO. So the driver should not warn users if it is not
> defined in the root port node. It should however print the error log and return
> errno, if the API returns other than -ENOENT.
> 
>> +		return 0;
>> +	}
>> +
>> +	wake_irq = gpiod_to_irq(wake);
>> +	device_init_wakeup(&pdev->dev, true);
>> +
>> +	ret = dev_pm_set_dedicated_wake_irq(&pdev->dev, wake_irq);
>> +	if (ret < 0) {
>> +		dev_err(&pdev->dev, "Failed to set wake IRQ: %d\n", ret);
>> +		device_init_wakeup(&pdev->dev, false);
>> +		return ret;
>> +	}
>> +	irq_set_irq_type(wake_irq, IRQ_TYPE_EDGE_FALLING);
>> +
>> +	return 0;
>> +}
>> +EXPORT_SYMBOL_GPL(of_pci_setup_wake_irq);
>> +
>> +/**
>> + * of_pci_teardown_wake_irq - Teardown wake interrupt setup for PCI device
> 
> Same comment as above.
> 
>> + *
>> + * @pdev: The PCI device structure
>> + *
>> + * This function tears down the wake interrupt setup for a PCI device,
>> + * clearing the dedicated wake interrupt and disabling device wake-up.
>> + */
>> +void of_pci_teardown_wake_irq(struct pci_dev *pdev)
>> +{
>> +	dev_pm_clear_wake_irq(&pdev->dev);
>> +	device_init_wakeup(&pdev->dev, false);
>> +}
>> +EXPORT_SYMBOL_GPL(of_pci_teardown_wake_irq);
>> diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
>> index b81e99cd4b62a3022c8b07a09f212f6888674487..b2f65289f4156fa1851c2d2f20c4ca948f36258f 100644
>> --- a/drivers/pci/pci.h
>> +++ b/drivers/pci/pci.h
>> @@ -888,6 +888,9 @@ void pci_release_of_node(struct pci_dev *dev);
>>   void pci_set_bus_of_node(struct pci_bus *bus);
>>   void pci_release_bus_of_node(struct pci_bus *bus);
>>   
>> +int of_pci_setup_wake_irq(struct pci_dev *pdev);
>> +void of_pci_teardown_wake_irq(struct pci_dev *pdev);
>> +
>>   int devm_of_pci_bridge_init(struct device *dev, struct pci_host_bridge *bridge);
>>   bool of_pci_supply_present(struct device_node *np);
>>   
>> @@ -931,6 +934,9 @@ static inline int devm_of_pci_bridge_init(struct device *dev, struct pci_host_br
>>   	return 0;
>>   }
>>   
>> +static int of_pci_setup_wake_irq(struct pci_dev *pdev) { return 0; }
>> +static void of_pci_teardown_wake_irq(struct pci_dev *pdev) { }
>> +
> 
> Provide stub for these APIs if CONFIG_OF is not enabled.
> 
These are the stub functions when CONFIG_OF is not enabled.

- Krishna Chaitanya.
> - Mani
> 

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

* Re: [PATCH v2 2/2] PCI: Add support for PCIe wake interrupt
  2025-04-19  5:43 ` [PATCH v2 2/2] PCI: Add support for PCIe wake interrupt Krishna Chaitanya Chundru
  2025-05-09  7:59   ` Krishna Chaitanya Chundru
  2025-06-01 15:21   ` Manivannan Sadhasivam
@ 2025-06-03  7:42   ` neil.armstrong
  2 siblings, 0 replies; 10+ messages in thread
From: neil.armstrong @ 2025-06-03  7:42 UTC (permalink / raw)
  To: Krishna Chaitanya Chundru, Bjorn Andersson, Konrad Dybcio,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	cros-qcom-dts-watchers, Bjorn Helgaas
  Cc: linux-arm-msm, devicetree, linux-kernel, linux-pci, quic_vbadigan,
	quic_mrana

On 19/04/2025 07:43, Krishna Chaitanya Chundru wrote:
> PCIe wake interrupt is needed for bringing back PCIe device state
> from D3cold to D0.
> 
> Implement new functions, of_pci_setup_wake_irq() and
> of_pci_teardown_wake_irq(), to manage wake interrupts for PCI devices
> using the Device Tree.
> 
>  From the port bus driver call these functions to enable wake support
> for bridges.
> 
> Signed-off-by: Krishna Chaitanya Chundru <krishna.chundru@oss.qualcomm.com>
> ---
>   drivers/pci/of.c           | 60 ++++++++++++++++++++++++++++++++++++++++++++++
>   drivers/pci/pci.h          |  6 +++++
>   drivers/pci/pcie/portdrv.c | 12 +++++++++-
>   3 files changed, 77 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pci/of.c b/drivers/pci/of.c
> index ab7a8252bf4137a17971c3eb8ab70ce78ca70969..13623797c88a03dfb9d9079518d87a5e1e68df38 100644
> --- a/drivers/pci/of.c
> +++ b/drivers/pci/of.c
> @@ -7,6 +7,7 @@
>   #define pr_fmt(fmt)	"PCI: OF: " fmt
>   
>   #include <linux/cleanup.h>
> +#include <linux/gpio/consumer.h>
>   #include <linux/irqdomain.h>
>   #include <linux/kernel.h>
>   #include <linux/pci.h>
> @@ -15,6 +16,7 @@
>   #include <linux/of_address.h>
>   #include <linux/of_pci.h>
>   #include <linux/platform_device.h>
> +#include <linux/pm_wakeirq.h>
>   #include "pci.h"
>   
>   #ifdef CONFIG_PCI
> @@ -966,3 +968,61 @@ u32 of_pci_get_slot_power_limit(struct device_node *node,
>   	return slot_power_limit_mw;
>   }
>   EXPORT_SYMBOL_GPL(of_pci_get_slot_power_limit);
> +
> +/**
> + * of_pci_setup_wake_irq - Set up wake interrupt for PCI device
> + * @pdev: The PCI device structure
> + *
> + * This function sets up the wake interrupt for a PCI device by getting the
> + * corresponding GPIO pin from the device tree, and configuring it as a
> + * dedicated wake interrupt.
> + *
> + * Return: 0 if the wake gpio is not available or successfully parsed else
> + * errno otherwise.
> + */
> +int of_pci_setup_wake_irq(struct pci_dev *pdev)
> +{
> +	struct gpio_desc *wake;
> +	struct device_node *dn;
> +	int ret, wake_irq;
> +
> +	dn = pci_device_to_OF_node(pdev);
> +	if (!dn)
> +		return 0;
> +
> +	wake = devm_fwnode_gpiod_get(&pdev->dev, of_fwnode_handle(dn),
> +				     "wake", GPIOD_IN, NULL);
> +	if (IS_ERR(wake)) {
> +		dev_warn(&pdev->dev, "Cannot get wake GPIO\n");
> +		return 0;
> +	}
> +
> +	wake_irq = gpiod_to_irq(wake);

gpiod_to_irq can fail, not all gpio driver can provide an irq number
for a gpio, check the error and to not fail on error.

Thanks,
Neil

> +	device_init_wakeup(&pdev->dev, true);
> +
> +	ret = dev_pm_set_dedicated_wake_irq(&pdev->dev, wake_irq);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "Failed to set wake IRQ: %d\n", ret);
> +		device_init_wakeup(&pdev->dev, false);
> +		return ret;
> +	}
> +	irq_set_irq_type(wake_irq, IRQ_TYPE_EDGE_FALLING);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(of_pci_setup_wake_irq);
> +
> +/**
> + * of_pci_teardown_wake_irq - Teardown wake interrupt setup for PCI device
> + *
> + * @pdev: The PCI device structure
> + *
> + * This function tears down the wake interrupt setup for a PCI device,
> + * clearing the dedicated wake interrupt and disabling device wake-up.
> + */
> +void of_pci_teardown_wake_irq(struct pci_dev *pdev)
> +{
> +	dev_pm_clear_wake_irq(&pdev->dev);
> +	device_init_wakeup(&pdev->dev, false);
> +}
> +EXPORT_SYMBOL_GPL(of_pci_teardown_wake_irq);
> diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
> index b81e99cd4b62a3022c8b07a09f212f6888674487..b2f65289f4156fa1851c2d2f20c4ca948f36258f 100644
> --- a/drivers/pci/pci.h
> +++ b/drivers/pci/pci.h
> @@ -888,6 +888,9 @@ void pci_release_of_node(struct pci_dev *dev);
>   void pci_set_bus_of_node(struct pci_bus *bus);
>   void pci_release_bus_of_node(struct pci_bus *bus);
>   
> +int of_pci_setup_wake_irq(struct pci_dev *pdev);
> +void of_pci_teardown_wake_irq(struct pci_dev *pdev);
> +
>   int devm_of_pci_bridge_init(struct device *dev, struct pci_host_bridge *bridge);
>   bool of_pci_supply_present(struct device_node *np);
>   
> @@ -931,6 +934,9 @@ static inline int devm_of_pci_bridge_init(struct device *dev, struct pci_host_br
>   	return 0;
>   }
>   
> +static int of_pci_setup_wake_irq(struct pci_dev *pdev) { return 0; }
> +static void of_pci_teardown_wake_irq(struct pci_dev *pdev) { }
> +
>   static inline bool of_pci_supply_present(struct device_node *np)
>   {
>   	return false;
> diff --git a/drivers/pci/pcie/portdrv.c b/drivers/pci/pcie/portdrv.c
> index e8318fd5f6ed537a1b236a3a0f054161d5710abd..33220ecf821c348d49782855eb5aa3f2fe5c335e 100644
> --- a/drivers/pci/pcie/portdrv.c
> +++ b/drivers/pci/pcie/portdrv.c
> @@ -694,12 +694,18 @@ static int pcie_portdrv_probe(struct pci_dev *dev,
>   	     (type != PCI_EXP_TYPE_RC_EC)))
>   		return -ENODEV;
>   
> +	status = of_pci_setup_wake_irq(dev);
> +	if (status)
> +		return status;
> +
>   	if (type == PCI_EXP_TYPE_RC_EC)
>   		pcie_link_rcec(dev);
>   
>   	status = pcie_port_device_register(dev);
> -	if (status)
> +	if (status) {
> +		of_pci_teardown_wake_irq(dev);
>   		return status;
> +	}
>   
>   	pci_save_state(dev);
>   
> @@ -732,6 +738,8 @@ static void pcie_portdrv_remove(struct pci_dev *dev)
>   
>   	pcie_port_device_remove(dev);
>   
> +	of_pci_teardown_wake_irq(dev);
> +
>   	pci_disable_device(dev);
>   }
>   
> @@ -744,6 +752,8 @@ static void pcie_portdrv_shutdown(struct pci_dev *dev)
>   	}
>   
>   	pcie_port_device_remove(dev);
> +
> +	of_pci_teardown_wake_irq(dev);
>   }
>   
>   static pci_ers_result_t pcie_portdrv_error_detected(struct pci_dev *dev,
> 


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

end of thread, other threads:[~2025-06-03  7:42 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-19  5:43 [PATCH v2 0/2] PCI: Add support for PCIe wake interrupt Krishna Chaitanya Chundru
2025-04-19  5:43 ` [PATCH v2 1/2] arm64: dts: qcom: sc7280: Add wake GPIO Krishna Chaitanya Chundru
2025-06-01 15:23   ` Manivannan Sadhasivam
2025-04-19  5:43 ` [PATCH v2 2/2] PCI: Add support for PCIe wake interrupt Krishna Chaitanya Chundru
2025-05-09  7:59   ` Krishna Chaitanya Chundru
2025-05-15  6:29     ` Sherry Sun
2025-05-21 10:44       ` Krishna Chaitanya Chundru
2025-06-01 15:21   ` Manivannan Sadhasivam
2025-06-03  6:26     ` Krishna Chaitanya Chundru
2025-06-03  7:42   ` neil.armstrong

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).