diff mbox series

[v4,2/2] PCI: xilinx-nwl: Add method to init_platform_service_irqs hook

Message ID 20220114075834.1938409-3-sr@denx.de (mailing list archive)
State New, archived
Delegated to: Lorenzo Pieralisi
Headers show
Series Add support to register platform service IRQ | expand

Commit Message

Stefan Roese Jan. 14, 2022, 7:58 a.m. UTC
From: Bharat Kumar Gogada <bharat.kumar.gogada@xilinx.com>

Add nwl_init_platform_service_irqs() hook to init_platform_service_irqs
to register the platform-specific Service Errors IRQs for this PCIe
controller to fully support e.g. AER on this platform.

Signed-off-by: Bharat Kumar Gogada <bharat.kumar.gogada@xilinx.com>
Signed-off-by: Stefan Roese <sr@denx.de>
Cc: Bjorn Helgaas <helgaas@kernel.org>
Cc: Pali Rohár <pali@kernel.org>
Cc: Michal Simek <michal.simek@xilinx.com>
---
 drivers/pci/controller/pcie-xilinx-nwl.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

Comments

Pali Rohár Jan. 14, 2022, 11:48 a.m. UTC | #1
On Friday 14 January 2022 08:58:34 Stefan Roese wrote:
> From: Bharat Kumar Gogada <bharat.kumar.gogada@xilinx.com>
> 
> Add nwl_init_platform_service_irqs() hook to init_platform_service_irqs
> to register the platform-specific Service Errors IRQs for this PCIe
> controller to fully support e.g. AER on this platform.
> 
> Signed-off-by: Bharat Kumar Gogada <bharat.kumar.gogada@xilinx.com>
> Signed-off-by: Stefan Roese <sr@denx.de>
> Cc: Bjorn Helgaas <helgaas@kernel.org>
> Cc: Pali Rohár <pali@kernel.org>
> Cc: Michal Simek <michal.simek@xilinx.com>

Reviewed-by: Pali Rohár <pali@kernel.org>

> ---
>  drivers/pci/controller/pcie-xilinx-nwl.c | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
> 
> diff --git a/drivers/pci/controller/pcie-xilinx-nwl.c b/drivers/pci/controller/pcie-xilinx-nwl.c
> index 414b679175b3..540536bbe3f8 100644
> --- a/drivers/pci/controller/pcie-xilinx-nwl.c
> +++ b/drivers/pci/controller/pcie-xilinx-nwl.c
> @@ -24,6 +24,7 @@
>  #include <linux/irqchip/chained_irq.h>
>  
>  #include "../pci.h"
> +#include "../pcie/portdrv.h"
>  
>  /* Bridge core config registers */
>  #define BRCFG_PCIE_RX0			0x00000000
> @@ -806,6 +807,22 @@ static int nwl_pcie_parse_dt(struct nwl_pcie *pcie,
>  	return 0;
>  }
>  
> +static int nwl_init_platform_service_irqs(struct pci_dev *dev, int *irqs,
> +					  int plat_mask)
> +{
> +	struct pci_host_bridge *bridge;
> +	struct nwl_pcie *pcie;
> +
> +	bridge = pci_find_host_bridge(dev->bus);
> +	pcie = pci_host_bridge_priv(bridge);
> +	if (plat_mask & PCIE_PORT_SERVICE_AER) {
> +		irqs[PCIE_PORT_SERVICE_AER_SHIFT] = pcie->irq_misc;
> +		return 0; /* platform-specific service IRQ installed */
> +	}

Just I want to be sure, with this change PME and HP interrupts are not
provided even when plat_mask argument contains them.

> +
> +	return -ENODEV; /* platform-specific service IRQ not installed */
> +}
> +
>  static const struct of_device_id nwl_pcie_of_match[] = {
>  	{ .compatible = "xlnx,nwl-pcie-2.11", },
>  	{}
> @@ -857,6 +874,7 @@ static int nwl_pcie_probe(struct platform_device *pdev)
>  
>  	bridge->sysdata = pcie;
>  	bridge->ops = &nwl_pcie_ops;
> +	bridge->init_platform_service_irqs = nwl_init_platform_service_irqs;
>  
>  	if (IS_ENABLED(CONFIG_PCI_MSI)) {
>  		err = nwl_pcie_enable_msi(pcie);
> -- 
> 2.34.1
>
Stefan Roese Jan. 14, 2022, 12:13 p.m. UTC | #2
On 1/14/22 12:48, Pali Rohár wrote:
> On Friday 14 January 2022 08:58:34 Stefan Roese wrote:
>> From: Bharat Kumar Gogada <bharat.kumar.gogada@xilinx.com>
>>
>> Add nwl_init_platform_service_irqs() hook to init_platform_service_irqs
>> to register the platform-specific Service Errors IRQs for this PCIe
>> controller to fully support e.g. AER on this platform.
>>
>> Signed-off-by: Bharat Kumar Gogada <bharat.kumar.gogada@xilinx.com>
>> Signed-off-by: Stefan Roese <sr@denx.de>
>> Cc: Bjorn Helgaas <helgaas@kernel.org>
>> Cc: Pali Rohár <pali@kernel.org>
>> Cc: Michal Simek <michal.simek@xilinx.com>
> 
> Reviewed-by: Pali Rohár <pali@kernel.org>
> 
>> ---
>>   drivers/pci/controller/pcie-xilinx-nwl.c | 18 ++++++++++++++++++
>>   1 file changed, 18 insertions(+)
>>
>> diff --git a/drivers/pci/controller/pcie-xilinx-nwl.c b/drivers/pci/controller/pcie-xilinx-nwl.c
>> index 414b679175b3..540536bbe3f8 100644
>> --- a/drivers/pci/controller/pcie-xilinx-nwl.c
>> +++ b/drivers/pci/controller/pcie-xilinx-nwl.c
>> @@ -24,6 +24,7 @@
>>   #include <linux/irqchip/chained_irq.h>
>>   
>>   #include "../pci.h"
>> +#include "../pcie/portdrv.h"
>>   
>>   /* Bridge core config registers */
>>   #define BRCFG_PCIE_RX0			0x00000000
>> @@ -806,6 +807,22 @@ static int nwl_pcie_parse_dt(struct nwl_pcie *pcie,
>>   	return 0;
>>   }
>>   
>> +static int nwl_init_platform_service_irqs(struct pci_dev *dev, int *irqs,
>> +					  int plat_mask)
>> +{
>> +	struct pci_host_bridge *bridge;
>> +	struct nwl_pcie *pcie;
>> +
>> +	bridge = pci_find_host_bridge(dev->bus);
>> +	pcie = pci_host_bridge_priv(bridge);
>> +	if (plat_mask & PCIE_PORT_SERVICE_AER) {
>> +		irqs[PCIE_PORT_SERVICE_AER_SHIFT] = pcie->irq_misc;
>> +		return 0; /* platform-specific service IRQ installed */
>> +	}
> 
> Just I want to be sure, with this change PME and HP interrupts are not
> provided even when plat_mask argument contains them.

This function is only used for Root Ports. E.g. HP at the downstream
ports of the PCIe switch still works in our case, as here
pcie_init_service_irqs() still gets called:

# cat /proc/interrupts | grep pci
  44:          0          0          0          0     GICv2 150 Level 
   nwl_pcie:misc, aerdrv
  61:          2          0          0          0  nwl_pcie:msi 1064960 
Edge      pciehp
  63:          0          0          0          0  nwl_pcie:msi 1081344 
Edge      pciehp
  65:          4          0          0          0  nwl_pcie:msi 1097728 
Edge      pciehp

Thanks,
Stefan

>> +
>> +	return -ENODEV; /* platform-specific service IRQ not installed */
>> +}
>> +
>>   static const struct of_device_id nwl_pcie_of_match[] = {
>>   	{ .compatible = "xlnx,nwl-pcie-2.11", },
>>   	{}
>> @@ -857,6 +874,7 @@ static int nwl_pcie_probe(struct platform_device *pdev)
>>   
>>   	bridge->sysdata = pcie;
>>   	bridge->ops = &nwl_pcie_ops;
>> +	bridge->init_platform_service_irqs = nwl_init_platform_service_irqs;
>>   
>>   	if (IS_ENABLED(CONFIG_PCI_MSI)) {
>>   		err = nwl_pcie_enable_msi(pcie);
>> -- 
>> 2.34.1
>>

Viele Grüße,
Stefan Roese
Pali Rohár Jan. 14, 2022, 12:34 p.m. UTC | #3
On Friday 14 January 2022 13:13:16 Stefan Roese wrote:
> On 1/14/22 12:48, Pali Rohár wrote:
> > On Friday 14 January 2022 08:58:34 Stefan Roese wrote:
> > > From: Bharat Kumar Gogada <bharat.kumar.gogada@xilinx.com>
> > > 
> > > Add nwl_init_platform_service_irqs() hook to init_platform_service_irqs
> > > to register the platform-specific Service Errors IRQs for this PCIe
> > > controller to fully support e.g. AER on this platform.
> > > 
> > > Signed-off-by: Bharat Kumar Gogada <bharat.kumar.gogada@xilinx.com>
> > > Signed-off-by: Stefan Roese <sr@denx.de>
> > > Cc: Bjorn Helgaas <helgaas@kernel.org>
> > > Cc: Pali Rohár <pali@kernel.org>
> > > Cc: Michal Simek <michal.simek@xilinx.com>
> > 
> > Reviewed-by: Pali Rohár <pali@kernel.org>
> > 
> > > ---
> > >   drivers/pci/controller/pcie-xilinx-nwl.c | 18 ++++++++++++++++++
> > >   1 file changed, 18 insertions(+)
> > > 
> > > diff --git a/drivers/pci/controller/pcie-xilinx-nwl.c b/drivers/pci/controller/pcie-xilinx-nwl.c
> > > index 414b679175b3..540536bbe3f8 100644
> > > --- a/drivers/pci/controller/pcie-xilinx-nwl.c
> > > +++ b/drivers/pci/controller/pcie-xilinx-nwl.c
> > > @@ -24,6 +24,7 @@
> > >   #include <linux/irqchip/chained_irq.h>
> > >   #include "../pci.h"
> > > +#include "../pcie/portdrv.h"
> > >   /* Bridge core config registers */
> > >   #define BRCFG_PCIE_RX0			0x00000000
> > > @@ -806,6 +807,22 @@ static int nwl_pcie_parse_dt(struct nwl_pcie *pcie,
> > >   	return 0;
> > >   }
> > > +static int nwl_init_platform_service_irqs(struct pci_dev *dev, int *irqs,
> > > +					  int plat_mask)
> > > +{
> > > +	struct pci_host_bridge *bridge;
> > > +	struct nwl_pcie *pcie;
> > > +
> > > +	bridge = pci_find_host_bridge(dev->bus);
> > > +	pcie = pci_host_bridge_priv(bridge);
> > > +	if (plat_mask & PCIE_PORT_SERVICE_AER) {
> > > +		irqs[PCIE_PORT_SERVICE_AER_SHIFT] = pcie->irq_misc;
> > > +		return 0; /* platform-specific service IRQ installed */
> > > +	}
> > 
> > Just I want to be sure, with this change PME and HP interrupts are not
> > provided even when plat_mask argument contains them.
> 
> This function is only used for Root Ports.

Technically, also Root Ports can support hot plugging. But that it
probably not the case of your board if it has PCIe switch connected to
the Root Port which is not removable.

But hot plug interrupt can be optionally used also for signalling change
of Data Link Layer state. And this information can be useful also in
Root Port if to it is connected non-removable device.

So if init_platform_service_irqs callback explicitly do not specify PME
or HP interrupts for the Root Port then kernel would not load pme or
pciehp service for the Root Port.

This is note for me, that when I will go to use this callback in other
drivers, I need to check that I provide interrupts for all supported
services...

> E.g. HP at the downstream
> ports of the PCIe switch still works in our case, as here
> pcie_init_service_irqs() still gets called:
> 
> # cat /proc/interrupts | grep pci
>  44:          0          0          0          0     GICv2 150 Level
> nwl_pcie:misc, aerdrv
>  61:          2          0          0          0  nwl_pcie:msi 1064960 Edge
> pciehp
>  63:          0          0          0          0  nwl_pcie:msi 1081344 Edge
> pciehp
>  65:          4          0          0          0  nwl_pcie:msi 1097728 Edge
> pciehp

Yes, as PCIe switch is different device it should work fine.

> Thanks,
> Stefan
> 
> > > +
> > > +	return -ENODEV; /* platform-specific service IRQ not installed */
> > > +}
> > > +
> > >   static const struct of_device_id nwl_pcie_of_match[] = {
> > >   	{ .compatible = "xlnx,nwl-pcie-2.11", },
> > >   	{}
> > > @@ -857,6 +874,7 @@ static int nwl_pcie_probe(struct platform_device *pdev)
> > >   	bridge->sysdata = pcie;
> > >   	bridge->ops = &nwl_pcie_ops;
> > > +	bridge->init_platform_service_irqs = nwl_init_platform_service_irqs;
> > >   	if (IS_ENABLED(CONFIG_PCI_MSI)) {
> > >   		err = nwl_pcie_enable_msi(pcie);
> > > -- 
> > > 2.34.1
> > > 
> 
> Viele Grüße,
> Stefan Roese
> 
> -- 
> DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
> HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
> Phone: (+49)-8142-66989-51 Fax: (+49)-8142-66989-80 Email: sr@denx.de
Stefan Roese Jan. 14, 2022, 5:03 p.m. UTC | #4
On 1/14/22 13:34, Pali Rohár wrote:
> On Friday 14 January 2022 13:13:16 Stefan Roese wrote:
>> On 1/14/22 12:48, Pali Rohár wrote:
>>> On Friday 14 January 2022 08:58:34 Stefan Roese wrote:
>>>> From: Bharat Kumar Gogada <bharat.kumar.gogada@xilinx.com>
>>>>
>>>> Add nwl_init_platform_service_irqs() hook to init_platform_service_irqs
>>>> to register the platform-specific Service Errors IRQs for this PCIe
>>>> controller to fully support e.g. AER on this platform.
>>>>
>>>> Signed-off-by: Bharat Kumar Gogada <bharat.kumar.gogada@xilinx.com>
>>>> Signed-off-by: Stefan Roese <sr@denx.de>
>>>> Cc: Bjorn Helgaas <helgaas@kernel.org>
>>>> Cc: Pali Rohár <pali@kernel.org>
>>>> Cc: Michal Simek <michal.simek@xilinx.com>
>>>
>>> Reviewed-by: Pali Rohár <pali@kernel.org>
>>>
>>>> ---
>>>>    drivers/pci/controller/pcie-xilinx-nwl.c | 18 ++++++++++++++++++
>>>>    1 file changed, 18 insertions(+)
>>>>
>>>> diff --git a/drivers/pci/controller/pcie-xilinx-nwl.c b/drivers/pci/controller/pcie-xilinx-nwl.c
>>>> index 414b679175b3..540536bbe3f8 100644
>>>> --- a/drivers/pci/controller/pcie-xilinx-nwl.c
>>>> +++ b/drivers/pci/controller/pcie-xilinx-nwl.c
>>>> @@ -24,6 +24,7 @@
>>>>    #include <linux/irqchip/chained_irq.h>
>>>>    #include "../pci.h"
>>>> +#include "../pcie/portdrv.h"
>>>>    /* Bridge core config registers */
>>>>    #define BRCFG_PCIE_RX0			0x00000000
>>>> @@ -806,6 +807,22 @@ static int nwl_pcie_parse_dt(struct nwl_pcie *pcie,
>>>>    	return 0;
>>>>    }
>>>> +static int nwl_init_platform_service_irqs(struct pci_dev *dev, int *irqs,
>>>> +					  int plat_mask)
>>>> +{
>>>> +	struct pci_host_bridge *bridge;
>>>> +	struct nwl_pcie *pcie;
>>>> +
>>>> +	bridge = pci_find_host_bridge(dev->bus);
>>>> +	pcie = pci_host_bridge_priv(bridge);
>>>> +	if (plat_mask & PCIE_PORT_SERVICE_AER) {
>>>> +		irqs[PCIE_PORT_SERVICE_AER_SHIFT] = pcie->irq_misc;
>>>> +		return 0; /* platform-specific service IRQ installed */
>>>> +	}
>>>
>>> Just I want to be sure, with this change PME and HP interrupts are not
>>> provided even when plat_mask argument contains them.
>>
>> This function is only used for Root Ports.
> 
> Technically, also Root Ports can support hot plugging. But that it
> probably not the case of your board if it has PCIe switch connected to
> the Root Port which is not removable.
> 
> But hot plug interrupt can be optionally used also for signalling change
> of Data Link Layer state. And this information can be useful also in
> Root Port if to it is connected non-removable device.
> 
> So if init_platform_service_irqs callback explicitly do not specify PME
> or HP interrupts for the Root Port then kernel would not load pme or
> pciehp service for the Root Port.
> 
> This is note for me, that when I will go to use this callback in other
> drivers, I need to check that I provide interrupts for all supported
> services...

It might very well be the case, that this current implementation does
not fully handle all use-cases (controller specific). The code can be
extended and/or fixed, once other users will show up.

Thanks,
Stefan

>> E.g. HP at the downstream
>> ports of the PCIe switch still works in our case, as here
>> pcie_init_service_irqs() still gets called:
>>
>> # cat /proc/interrupts | grep pci
>>   44:          0          0          0          0     GICv2 150 Level
>> nwl_pcie:misc, aerdrv
>>   61:          2          0          0          0  nwl_pcie:msi 1064960 Edge
>> pciehp
>>   63:          0          0          0          0  nwl_pcie:msi 1081344 Edge
>> pciehp
>>   65:          4          0          0          0  nwl_pcie:msi 1097728 Edge
>> pciehp
> 
> Yes, as PCIe switch is different device it should work fine.
> 
>> Thanks,
>> Stefan
>>
>>>> +
>>>> +	return -ENODEV; /* platform-specific service IRQ not installed */
>>>> +}
>>>> +
>>>>    static const struct of_device_id nwl_pcie_of_match[] = {
>>>>    	{ .compatible = "xlnx,nwl-pcie-2.11", },
>>>>    	{}
>>>> @@ -857,6 +874,7 @@ static int nwl_pcie_probe(struct platform_device *pdev)
>>>>    	bridge->sysdata = pcie;
>>>>    	bridge->ops = &nwl_pcie_ops;
>>>> +	bridge->init_platform_service_irqs = nwl_init_platform_service_irqs;
>>>>    	if (IS_ENABLED(CONFIG_PCI_MSI)) {
>>>>    		err = nwl_pcie_enable_msi(pcie);
>>>> -- 
>>>> 2.34.1
>>>>
>>
>> Viele Grüße,
>> Stefan Roese
>>
>> -- 
>> DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
>> HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
>> Phone: (+49)-8142-66989-51 Fax: (+49)-8142-66989-80 Email: sr@denx.de

Viele Grüße,
Stefan Roese
diff mbox series

Patch

diff --git a/drivers/pci/controller/pcie-xilinx-nwl.c b/drivers/pci/controller/pcie-xilinx-nwl.c
index 414b679175b3..540536bbe3f8 100644
--- a/drivers/pci/controller/pcie-xilinx-nwl.c
+++ b/drivers/pci/controller/pcie-xilinx-nwl.c
@@ -24,6 +24,7 @@ 
 #include <linux/irqchip/chained_irq.h>
 
 #include "../pci.h"
+#include "../pcie/portdrv.h"
 
 /* Bridge core config registers */
 #define BRCFG_PCIE_RX0			0x00000000
@@ -806,6 +807,22 @@  static int nwl_pcie_parse_dt(struct nwl_pcie *pcie,
 	return 0;
 }
 
+static int nwl_init_platform_service_irqs(struct pci_dev *dev, int *irqs,
+					  int plat_mask)
+{
+	struct pci_host_bridge *bridge;
+	struct nwl_pcie *pcie;
+
+	bridge = pci_find_host_bridge(dev->bus);
+	pcie = pci_host_bridge_priv(bridge);
+	if (plat_mask & PCIE_PORT_SERVICE_AER) {
+		irqs[PCIE_PORT_SERVICE_AER_SHIFT] = pcie->irq_misc;
+		return 0; /* platform-specific service IRQ installed */
+	}
+
+	return -ENODEV; /* platform-specific service IRQ not installed */
+}
+
 static const struct of_device_id nwl_pcie_of_match[] = {
 	{ .compatible = "xlnx,nwl-pcie-2.11", },
 	{}
@@ -857,6 +874,7 @@  static int nwl_pcie_probe(struct platform_device *pdev)
 
 	bridge->sysdata = pcie;
 	bridge->ops = &nwl_pcie_ops;
+	bridge->init_platform_service_irqs = nwl_init_platform_service_irqs;
 
 	if (IS_ENABLED(CONFIG_PCI_MSI)) {
 		err = nwl_pcie_enable_msi(pcie);