diff mbox series

[19/19] PCI: Set bridge map_irq and swizzle_irq to default functions

Message ID 20200722022514.1283916-20-robh@kernel.org
State New
Headers show
Series PCI: Another round of host clean-ups | expand

Commit Message

Rob Herring July 22, 2020, 2:25 a.m. UTC
The majority of DT based host drivers use the default .map_irq() and
.swizzle_irq() functions, so let's initialize the function pointers to
the default and drop setting them in the host drivers.

Drivers like iProc which don't support legacy interrupts need to set
.map_irq() back to NULL.

Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Rob Herring <robh@kernel.org>
---
 drivers/pci/controller/cadence/pcie-cadence-host.c   | 2 --
 drivers/pci/controller/dwc/pcie-designware-host.c    | 2 --
 drivers/pci/controller/mobiveil/pcie-mobiveil-host.c | 2 --
 drivers/pci/controller/pci-aardvark.c                | 2 --
 drivers/pci/controller/pci-ftpci100.c                | 2 --
 drivers/pci/controller/pci-host-common.c             | 2 --
 drivers/pci/controller/pci-mvebu.c                   | 2 --
 drivers/pci/controller/pci-tegra.c                   | 1 -
 drivers/pci/controller/pci-v3-semi.c                 | 2 --
 drivers/pci/controller/pci-versatile.c               | 2 --
 drivers/pci/controller/pci-xgene.c                   | 2 --
 drivers/pci/controller/pcie-altera.c                 | 2 --
 drivers/pci/controller/pcie-brcmstb.c                | 2 --
 drivers/pci/controller/pcie-iproc-platform.c         | 3 ++-
 drivers/pci/controller/pcie-iproc.c                  | 1 -
 drivers/pci/controller/pcie-mediatek.c               | 2 --
 drivers/pci/controller/pcie-rcar-host.c              | 2 --
 drivers/pci/controller/pcie-rockchip-host.c          | 2 --
 drivers/pci/controller/pcie-xilinx-nwl.c             | 2 --
 drivers/pci/controller/pcie-xilinx.c                 | 2 --
 drivers/pci/of.c                                     | 3 +++
 21 files changed, 5 insertions(+), 37 deletions(-)

Comments

Bjorn Helgaas Jan. 11, 2022, 9:46 p.m. UTC | #1
[-cc many, +cc iproc, loongson, tegra maintainers]

On Tue, Jul 21, 2020 at 08:25:14PM -0600, Rob Herring wrote:
> The majority of DT based host drivers use the default .map_irq() and
> .swizzle_irq() functions, so let's initialize the function pointers to
> the default and drop setting them in the host drivers.
> 
> Drivers like iProc which don't support legacy interrupts need to set
> .map_irq() back to NULL.

Probably a dumb question...

This patch removed all the ->swizzle_irq users in drivers/pci/, which
is great -- IIUC swizzling is specified by the PCI-to-PCI Bridge Spec,
r1.2, sec 9.1, and should not be device-specific.  I assume the few
remaining arch/ users (arm and alpha) are either bugs or workarounds
for broken devices.

My question is why we still have a few users of ->map_irq: loongson,
tegra, iproc.  Shouldn't this mapping be described somehow via DT?

> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
> index fc4e38fec928..97433beff6cf 100644
> --- a/drivers/pci/controller/pci-tegra.c
> +++ b/drivers/pci/controller/pci-tegra.c
> @@ -2709,7 +2709,6 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>  
>  	host->ops = &tegra_pcie_ops;
>  	host->map_irq = tegra_pcie_map_irq;
> -	host->swizzle_irq = pci_common_swizzle;
>  
>  	err = pci_host_probe(host);
>  	if (err < 0) {

> diff --git a/drivers/pci/controller/pcie-iproc-platform.c b/drivers/pci/controller/pcie-iproc-platform.c
> index 7c10c1cb6f65..a956b0c18bd1 100644
> --- a/drivers/pci/controller/pcie-iproc-platform.c
> +++ b/drivers/pci/controller/pcie-iproc-platform.c
> @@ -99,9 +99,10 @@ static int iproc_pcie_pltfm_probe(struct platform_device *pdev)
>  	switch (pcie->type) {
>  	case IPROC_PCIE_PAXC:
>  	case IPROC_PCIE_PAXC_V2:
> +		pcie->map_irq = 0;
>  		break;
>  	default:
> -		pcie->map_irq = of_irq_parse_and_map_pci;
> +		break;
>  	}
>  
>  	ret = iproc_pcie_setup(pcie, &bridge->windows);

> diff --git a/drivers/pci/controller/pcie-iproc.c b/drivers/pci/controller/pcie-iproc.c
> index e98dafd0fff4..905e93808243 100644
> --- a/drivers/pci/controller/pcie-iproc.c
> +++ b/drivers/pci/controller/pcie-iproc.c
> @@ -1526,7 +1526,6 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)
>  	host->ops = &iproc_pcie_ops;
>  	host->sysdata = pcie;
>  	host->map_irq = pcie->map_irq;
> -	host->swizzle_irq = pci_common_swizzle;
>  
>  	ret = pci_host_probe(host);
>  	if (ret < 0) {

drivers/pci/controller/pci-loongson.c:

  static int loongson_pci_probe(struct platform_device *pdev)
  {
    ...
    bridge->map_irq = loongson_map_irq;
Jiaxun Yang Jan. 12, 2022, 12:57 p.m. UTC | #2
在2022年1月11日一月 下午9:46,Bjorn Helgaas写道:
> [-cc many, +cc iproc, loongson, tegra maintainers]
>
> On Tue, Jul 21, 2020 at 08:25:14PM -0600, Rob Herring wrote:
>> The majority of DT based host drivers use the default .map_irq() and
>> .swizzle_irq() functions, so let's initialize the function pointers to
>> the default and drop setting them in the host drivers.
>> 
>> Drivers like iProc which don't support legacy interrupts need to set
>> .map_irq() back to NULL.
>
> Probably a dumb question...
>
> This patch removed all the ->swizzle_irq users in drivers/pci/, which
> is great -- IIUC swizzling is specified by the PCI-to-PCI Bridge Spec,
> r1.2, sec 9.1, and should not be device-specific.  I assume the few
> remaining arch/ users (arm and alpha) are either bugs or workarounds
> for broken devices.
>
> My question is why we still have a few users of ->map_irq: loongson,
> tegra, iproc.  Shouldn't this mapping be described somehow via DT?
>

Hi all,

For Loongson we are describing IRQ map in DT for newer platforms.
But for legacy platforms (AMD RS780E North Bridge) with i8259 irqchip,
we need to read PCI IRQ registers to get mapping information.

It is not known until boot time, so we have to use map_irq callback.

Thanks.
- Jiaxun

[...]
Rob Herring Jan. 12, 2022, 3:09 p.m. UTC | #3
On Tue, Jan 11, 2022 at 3:46 PM Bjorn Helgaas <helgaas@kernel.org> wrote:
>
> [-cc many, +cc iproc, loongson, tegra maintainers]
>
> On Tue, Jul 21, 2020 at 08:25:14PM -0600, Rob Herring wrote:
> > The majority of DT based host drivers use the default .map_irq() and
> > .swizzle_irq() functions, so let's initialize the function pointers to
> > the default and drop setting them in the host drivers.
> >
> > Drivers like iProc which don't support legacy interrupts need to set
> > .map_irq() back to NULL.
>
> Probably a dumb question...
>
> This patch removed all the ->swizzle_irq users in drivers/pci/, which
> is great -- IIUC swizzling is specified by the PCI-to-PCI Bridge Spec,
> r1.2, sec 9.1, and should not be device-specific.  I assume the few
> remaining arch/ users (arm and alpha) are either bugs or workarounds
> for broken devices.
>
> My question is why we still have a few users of ->map_irq: loongson,
> tegra, iproc.  Shouldn't this mapping be described somehow via DT?

Tegra could perhaps be written another way. The mapping is standard,
but it's disabling an idle state when PCI interrupts are used. It just
needs some way to know if legacy interrupts are being used.

iproc looks pretty special with its bcma bus.

Adding something to DT doesn't really help because we'd still have to
support the old way.

Rob
Bjorn Helgaas Jan. 12, 2022, 3:19 p.m. UTC | #4
On Wed, Jan 12, 2022 at 12:57:44PM +0000, Jiaxun Yang wrote:
> 在2022年1月11日一月 下午9:46,Bjorn Helgaas写道:
> > [-cc many, +cc iproc, loongson, tegra maintainers]
> >
> > On Tue, Jul 21, 2020 at 08:25:14PM -0600, Rob Herring wrote:
> >> The majority of DT based host drivers use the default .map_irq() and
> >> .swizzle_irq() functions, so let's initialize the function pointers to
> >> the default and drop setting them in the host drivers.
> >> 
> >> Drivers like iProc which don't support legacy interrupts need to set
> >> .map_irq() back to NULL.
> >
> > Probably a dumb question...
> >
> > This patch removed all the ->swizzle_irq users in drivers/pci/, which
> > is great -- IIUC swizzling is specified by the PCI-to-PCI Bridge Spec,
> > r1.2, sec 9.1, and should not be device-specific.  I assume the few
> > remaining arch/ users (arm and alpha) are either bugs or workarounds
> > for broken devices.
> >
> > My question is why we still have a few users of ->map_irq: loongson,
> > tegra, iproc.  Shouldn't this mapping be described somehow via DT?
> 
> For Loongson we are describing IRQ map in DT for newer platforms.
> But for legacy platforms (AMD RS780E North Bridge) with i8259 irqchip,
> we need to read PCI IRQ registers to get mapping information.
> 
> It is not known until boot time, so we have to use map_irq callback.

I see these:

  Documentation/devicetree/bindings/pci/loongson.yaml
  arch/mips/boot/dts/loongson/rs780e-pch.dtsi

which makes me think there are Loongson systems with DT.  Are there
some Loongson systems with DT and some legacy ones without?

The only driver I see is drivers/pci/controller/pci-loongson.c.  Is
that used for all Loongson system?  It unconditionally uses ->map_irq
= loongson_map_irq().

loongson_map_irq() reads PCI_INTERRUPT_LINE; I think that depends on
firmware having previously programmed it, right?

Bjorn
Bjorn Helgaas Jan. 12, 2022, 3:32 p.m. UTC | #5
On Wed, Jan 12, 2022 at 09:09:31AM -0600, Rob Herring wrote:
> On Tue, Jan 11, 2022 at 3:46 PM Bjorn Helgaas <helgaas@kernel.org> wrote:
> > On Tue, Jul 21, 2020 at 08:25:14PM -0600, Rob Herring wrote:
> > > The majority of DT based host drivers use the default .map_irq() and
> > > .swizzle_irq() functions, so let's initialize the function pointers to
> > > the default and drop setting them in the host drivers.
> > >
> > > Drivers like iProc which don't support legacy interrupts need to set
> > > .map_irq() back to NULL.
> >
> > Probably a dumb question...
> >
> > This patch removed all the ->swizzle_irq users in drivers/pci/, which
> > is great -- IIUC swizzling is specified by the PCI-to-PCI Bridge Spec,
> > r1.2, sec 9.1, and should not be device-specific.  I assume the few
> > remaining arch/ users (arm and alpha) are either bugs or workarounds
> > for broken devices.
> >
> > My question is why we still have a few users of ->map_irq: loongson,
> > tegra, iproc.  Shouldn't this mapping be described somehow via DT?
> 
> Tegra could perhaps be written another way. The mapping is standard,
> but it's disabling an idle state when PCI interrupts are used. It just
> needs some way to know if legacy interrupts are being used.
>
> iproc looks pretty special with its bcma bus.
> 
> Adding something to DT doesn't really help because we'd still have to
> support the old way.

I guess my underlying question is whether new drivers should ever use
->swizzle_irq() and ->map_irq().  I'm hoping the answer is "no".

If we need them for pre-DT systems or things with incomplete DTs in
the field, I guess we have to live with that.

All ACPI really gives you is the _PRT, and I'm not sure that's
expressive enough to describe platforms that need these things, so
maybe this will eventually solve itself.

Bjorn
Jiaxun Yang Jan. 12, 2022, 8:08 p.m. UTC | #6
在2022年1月12日一月 下午3:19,Bjorn Helgaas写道:
> On Wed, Jan 12, 2022 at 12:57:44PM +0000, Jiaxun Yang wrote:
>> 在2022年1月11日一月 下午9:46,Bjorn Helgaas写道:
>> > [-cc many, +cc iproc, loongson, tegra maintainers]
[...]
> I see these:
>
>   Documentation/devicetree/bindings/pci/loongson.yaml
>   arch/mips/boot/dts/loongson/rs780e-pch.dtsi
>
> which makes me think there are Loongson systems with DT.  Are there
> some Loongson systems with DT and some legacy ones without?

Actually all present MIPS/Loongson systems are legacy and we just built-in
DTs in kernel and select which one to use at boot time. 

>
> The only driver I see is drivers/pci/controller/pci-loongson.c.  Is
> that used for all Loongson system?  It unconditionally uses ->map_irq
> = loongson_map_irq().

Yes, it's used among all Loongson systems.
For system using LS7A PCH the IRQ mapping is fixed so we just programed
it in DT. For RS780E we use this rountine to read PCI_INTERRUPT_LINE to
select which I8259 IRQ to use.

>
> loongson_map_irq() reads PCI_INTERRUPT_LINE; I think that depends on
> firmware having previously programmed it, right?

I'm unclear about what did firmware do but as AMD RS780E is used in x86
PCs as well it should be the same way.

Thanks.

>
> Bjorn
Bjorn Helgaas Jan. 12, 2022, 9:10 p.m. UTC | #7
On Wed, Jan 12, 2022 at 08:08:45PM +0000, Jiaxun Yang wrote:
> 在2022年1月12日一月 下午3:19,Bjorn Helgaas写道:
> > On Wed, Jan 12, 2022 at 12:57:44PM +0000, Jiaxun Yang wrote:
> >> 在2022年1月11日一月 下午9:46,Bjorn Helgaas写道:
> >> > [-cc many, +cc iproc, loongson, tegra maintainers]
> [...]
> > I see these:
> >
> >   Documentation/devicetree/bindings/pci/loongson.yaml
> >   arch/mips/boot/dts/loongson/rs780e-pch.dtsi
> >
> > which makes me think there are Loongson systems with DT.  Are there
> > some Loongson systems with DT and some legacy ones without?
> 
> Actually all present MIPS/Loongson systems are legacy and we just
> built-in DTs in kernel and select which one to use at boot time. 

So I guess you know enough about what platform it is to select which
DT to use, but you don't know enough to know the I8259 routing?

If you *could* select a DT that described the I8259 routing, I guess
maybe you could select a matching DT or update a DT in-place?

> > The only driver I see is drivers/pci/controller/pci-loongson.c.
> > Is that used for all Loongson system?  It unconditionally uses
> > ->map_irq = loongson_map_irq().
> 
> Yes, it's used among all Loongson systems.  For system using LS7A
> PCH the IRQ mapping is fixed so we just programmed it in DT. For
> RS780E we use this routine to read PCI_INTERRUPT_LINE to select
> which I8259 IRQ to use.
> 
> > loongson_map_irq() reads PCI_INTERRUPT_LINE; I think that depends
> > on firmware having previously programmed it, right?
> 
> I'm unclear about what did firmware do but as AMD RS780E is used in
> x86 PCs as well it should be the same way.

PCI devices don't use the value in PCI_INTERRUPT_LINE, and the spec
doesn't define a default value.  It's only for use by software.

I'm pretty sure that on ACPI x86, we don't depend on
PCI_INTERRUPT_LINE except for things like quirks.

I think the ACPI MADT and _PRT are supposed to contain all the INTx
routing information we need.  Obviously this isn't an ACPI system.
I'm just making the point that it *should* be possible to remove this
dependency on firmware if we can identify the specific platform (which
determines the I8259 routing).

Bjorn
Jiaxun Yang Jan. 13, 2022, 5:44 p.m. UTC | #8
在2022年1月12日一月 下午9:10,Bjorn Helgaas写道:
> On Wed, Jan 12, 2022 at 08:08:45PM +0000, Jiaxun Yang wrote:
>> 在2022年1月12日一月 下午3:19,Bjorn Helgaas写道:
>> > On Wed, Jan 12, 2022 at 12:57:44PM +0000, Jiaxun Yang wrote:
>> >> 在2022年1月11日一月 下午9:46,Bjorn Helgaas写道:
>> >> > [-cc many, +cc iproc, loongson, tegra maintainers]
>> [...]
>> > I see these:
>> >
>> >   Documentation/devicetree/bindings/pci/loongson.yaml
>> >   arch/mips/boot/dts/loongson/rs780e-pch.dtsi
>> >
>> > which makes me think there are Loongson systems with DT.  Are there
>> > some Loongson systems with DT and some legacy ones without?
>> 
>> Actually all present MIPS/Loongson systems are legacy and we just
>> built-in DTs in kernel and select which one to use at boot time. 
>
> So I guess you know enough about what platform it is to select which
> DT to use, but you don't know enough to know the I8259 routing?
>
> If you *could* select a DT that described the I8259 routing, I guess
> maybe you could select a matching DT or update a DT in-place?
>
>> > The only driver I see is drivers/pci/controller/pci-loongson.c.
>> > Is that used for all Loongson system?  It unconditionally uses
>> > ->map_irq = loongson_map_irq().
>> 
>> Yes, it's used among all Loongson systems.  For system using LS7A
>> PCH the IRQ mapping is fixed so we just programmed it in DT. For
>> RS780E we use this routine to read PCI_INTERRUPT_LINE to select
>> which I8259 IRQ to use.
>> 
>> > loongson_map_irq() reads PCI_INTERRUPT_LINE; I think that depends
>> > on firmware having previously programmed it, right?
>> 
>> I'm unclear about what did firmware do but as AMD RS780E is used in
>> x86 PCs as well it should be the same way.
>
> PCI devices don't use the value in PCI_INTERRUPT_LINE, and the spec
> doesn't define a default value.  It's only for use by software.
>
> I'm pretty sure that on ACPI x86, we don't depend on
> PCI_INTERRUPT_LINE except for things like quirks.
>
> I think the ACPI MADT and _PRT are supposed to contain all the INTx
> routing information we need.  Obviously this isn't an ACPI system.
> I'm just making the point that it *should* be possible to remove this
> dependency on firmware if we can identify the specific platform (which
> determines the I8259 routing).

Hi,

Thanks for the information, I had send a enquire to Loongson to ask about
those details.

Patching DT at boot time should be possible :-)

Thanks.

>
> Bjorn
Maciej W. Rozycki Jan. 29, 2022, 10:34 p.m. UTC | #9
On Tue, 11 Jan 2022, Bjorn Helgaas wrote:

> This patch removed all the ->swizzle_irq users in drivers/pci/, which
> is great -- IIUC swizzling is specified by the PCI-to-PCI Bridge Spec,
> r1.2, sec 9.1, and should not be device-specific.  I assume the few
> remaining arch/ users (arm and alpha) are either bugs or workarounds
> for broken devices.

 I skimmed over the Alpha stuff and it seems to mostly care about setting 
the slot value returned differently and defers to `pci_common_swizzle' for 
actual pin determination.  This could be moderately easy to sort out.

 One exception is `takara_swizzle' which looks incomplete to me; as this 
is a PICMG device[1] someone would have to fill in the missing details as 
AFAICT the PICMG connector is supposed to provide all the INT# A-D lines 
and then routing is done on the backplane using binding defined by PICMG.

 According to DEC documentation there's an alternative interrupt routing 
mode available too, using a external interrupt controller FPGA placed on 
the backplane[2], where no swizzling is done and instead each of the four 
INT# lines across all the PCI slots, up to 16, provided by a backplane is 
individually routed to 64 inputs of the interrupt controller.

 There is a paper by DEC available online[3] that could help filling in 
the missing details for either mode, especially someone who has access to 
such a system and could verify it in reality.

References:

[1] "DIGITAL 21164 PICMG SBC, User Information for the EBM21 and EBM23",
    V1.0, Digital Equipment Corporation, June 1997, Part Number: 
    EK-A0937-UG. A01

[2] "DIGITAL Modular Computing Components, OEM Information for DMCC 
    Backplanes", Version 4.1, Compaq Computer Corporation, January 1999, 
    Order Number: EK-A0929-TM. C01

[3] Ross L. Armstrong, "PCI Interrupt Controller for Industry Standard 
    PCI-ISA Bus Architecture using PCI-to-PCI Bridge Technology", Digital 
    Equipment Corporation (Scotland) Ltd., 1996

 FWIW,

  Maciej
diff mbox series

Patch

diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c b/drivers/pci/controller/cadence/pcie-cadence-host.c
index 4fe39b6b4749..0acd95b7329a 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-host.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-host.c
@@ -234,8 +234,6 @@  int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
 		goto err_init;
 
 	bridge->ops = &cdns_pcie_host_ops;
-	bridge->map_irq = of_irq_parse_and_map_pci;
-	bridge->swizzle_irq = pci_common_swizzle;
 
 	ret = pci_host_probe(bridge);
 	if (ret < 0)
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index d3d4c1e42868..d49db7d2d29a 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -467,8 +467,6 @@  int dw_pcie_host_init(struct pcie_port *pp)
 
 	bridge->sysdata = pp;
 	bridge->ops = &dw_pcie_ops;
-	bridge->map_irq = of_irq_parse_and_map_pci;
-	bridge->swizzle_irq = pci_common_swizzle;
 
 	ret = pci_scan_root_bus_bridge(bridge);
 	if (ret)
diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
index 2954d6ad8333..33ab36d73906 100644
--- a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
+++ b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
@@ -596,8 +596,6 @@  int mobiveil_pcie_host_probe(struct mobiveil_pcie *pcie)
 	/* Initialize bridge */
 	bridge->sysdata = pcie;
 	bridge->ops = &mobiveil_pcie_ops;
-	bridge->map_irq = of_irq_parse_and_map_pci;
-	bridge->swizzle_irq = pci_common_swizzle;
 
 	ret = mobiveil_bringup_link(pcie);
 	if (ret) {
diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index a4a799f52cdb..37c2e49a0408 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -1177,8 +1177,6 @@  static int advk_pcie_probe(struct platform_device *pdev)
 
 	bridge->sysdata = pcie;
 	bridge->ops = &advk_pcie_ops;
-	bridge->map_irq = of_irq_parse_and_map_pci;
-	bridge->swizzle_irq = pci_common_swizzle;
 
 	ret = pci_host_probe(bridge);
 	if (ret < 0) {
diff --git a/drivers/pci/controller/pci-ftpci100.c b/drivers/pci/controller/pci-ftpci100.c
index b1521f4f4096..dc9c25c11faa 100644
--- a/drivers/pci/controller/pci-ftpci100.c
+++ b/drivers/pci/controller/pci-ftpci100.c
@@ -438,8 +438,6 @@  static int faraday_pci_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	host->ops = &faraday_pci_ops;
-	host->map_irq = of_irq_parse_and_map_pci;
-	host->swizzle_irq = pci_common_swizzle;
 	p = pci_host_bridge_priv(host);
 	host->sysdata = p;
 	p->dev = dev;
diff --git a/drivers/pci/controller/pci-host-common.c b/drivers/pci/controller/pci-host-common.c
index 509624175260..6ce34a1deecb 100644
--- a/drivers/pci/controller/pci-host-common.c
+++ b/drivers/pci/controller/pci-host-common.c
@@ -77,8 +77,6 @@  int pci_host_common_probe(struct platform_device *pdev)
 
 	bridge->sysdata = cfg;
 	bridge->ops = (struct pci_ops *)&ops->pci_ops;
-	bridge->map_irq = of_irq_parse_and_map_pci;
-	bridge->swizzle_irq = pci_common_swizzle;
 
 	platform_set_drvdata(pdev, bridge);
 
diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
index db93823a2dcb..12d30fb6ae6e 100644
--- a/drivers/pci/controller/pci-mvebu.c
+++ b/drivers/pci/controller/pci-mvebu.c
@@ -1118,8 +1118,6 @@  static int mvebu_pcie_probe(struct platform_device *pdev)
 
 	bridge->sysdata = pcie;
 	bridge->ops = &mvebu_pcie_ops;
-	bridge->map_irq = of_irq_parse_and_map_pci;
-	bridge->swizzle_irq = pci_common_swizzle;
 	bridge->align_resource = mvebu_pcie_align_resource;
 	bridge->msi = pcie->msi;
 
diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
index fc4e38fec928..97433beff6cf 100644
--- a/drivers/pci/controller/pci-tegra.c
+++ b/drivers/pci/controller/pci-tegra.c
@@ -2709,7 +2709,6 @@  static int tegra_pcie_probe(struct platform_device *pdev)
 
 	host->ops = &tegra_pcie_ops;
 	host->map_irq = tegra_pcie_map_irq;
-	host->swizzle_irq = pci_common_swizzle;
 
 	err = pci_host_probe(host);
 	if (err < 0) {
diff --git a/drivers/pci/controller/pci-v3-semi.c b/drivers/pci/controller/pci-v3-semi.c
index 1a2cbc56b34b..a38a416bcf3b 100644
--- a/drivers/pci/controller/pci-v3-semi.c
+++ b/drivers/pci/controller/pci-v3-semi.c
@@ -722,8 +722,6 @@  static int v3_pci_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	host->ops = &v3_pci_ops;
-	host->map_irq = of_irq_parse_and_map_pci;
-	host->swizzle_irq = pci_common_swizzle;
 	v3 = pci_host_bridge_priv(host);
 	host->sysdata = v3;
 	v3->dev = dev;
diff --git a/drivers/pci/controller/pci-versatile.c b/drivers/pci/controller/pci-versatile.c
index 54a7a43d036a..c79c52556e95 100644
--- a/drivers/pci/controller/pci-versatile.c
+++ b/drivers/pci/controller/pci-versatile.c
@@ -151,8 +151,6 @@  static int versatile_pci_probe(struct platform_device *pdev)
 	pci_add_flags(PCI_REASSIGN_ALL_BUS);
 
 	bridge->ops = &pci_versatile_ops;
-	bridge->map_irq = of_irq_parse_and_map_pci;
-	bridge->swizzle_irq = pci_common_swizzle;
 
 	return pci_host_probe(bridge);
 }
diff --git a/drivers/pci/controller/pci-xgene.c b/drivers/pci/controller/pci-xgene.c
index 7f5a6595af0a..c33b385ac918 100644
--- a/drivers/pci/controller/pci-xgene.c
+++ b/drivers/pci/controller/pci-xgene.c
@@ -621,8 +621,6 @@  static int xgene_pcie_probe(struct platform_device *pdev)
 
 	bridge->sysdata = port;
 	bridge->ops = &xgene_pcie_ops;
-	bridge->map_irq = of_irq_parse_and_map_pci;
-	bridge->swizzle_irq = pci_common_swizzle;
 
 	return pci_host_probe(bridge);
 }
diff --git a/drivers/pci/controller/pcie-altera.c b/drivers/pci/controller/pcie-altera.c
index 4b515329ad35..3bacfdb357d2 100644
--- a/drivers/pci/controller/pcie-altera.c
+++ b/drivers/pci/controller/pcie-altera.c
@@ -812,8 +812,6 @@  static int altera_pcie_probe(struct platform_device *pdev)
 	bridge->sysdata = pcie;
 	bridge->busnr = pcie->root_bus_nr;
 	bridge->ops = &altera_pcie_ops;
-	bridge->map_irq = of_irq_parse_and_map_pci;
-	bridge->swizzle_irq = pci_common_swizzle;
 
 	return pci_host_probe(bridge);
 }
diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c
index b24651fad199..6b57551549e6 100644
--- a/drivers/pci/controller/pcie-brcmstb.c
+++ b/drivers/pci/controller/pcie-brcmstb.c
@@ -993,8 +993,6 @@  static int brcm_pcie_probe(struct platform_device *pdev)
 
 	bridge->ops = &brcm_pcie_ops;
 	bridge->sysdata = pcie;
-	bridge->map_irq = of_irq_parse_and_map_pci;
-	bridge->swizzle_irq = pci_common_swizzle;
 
 	platform_set_drvdata(pdev, pcie);
 
diff --git a/drivers/pci/controller/pcie-iproc-platform.c b/drivers/pci/controller/pcie-iproc-platform.c
index 7c10c1cb6f65..a956b0c18bd1 100644
--- a/drivers/pci/controller/pcie-iproc-platform.c
+++ b/drivers/pci/controller/pcie-iproc-platform.c
@@ -99,9 +99,10 @@  static int iproc_pcie_pltfm_probe(struct platform_device *pdev)
 	switch (pcie->type) {
 	case IPROC_PCIE_PAXC:
 	case IPROC_PCIE_PAXC_V2:
+		pcie->map_irq = 0;
 		break;
 	default:
-		pcie->map_irq = of_irq_parse_and_map_pci;
+		break;
 	}
 
 	ret = iproc_pcie_setup(pcie, &bridge->windows);
diff --git a/drivers/pci/controller/pcie-iproc.c b/drivers/pci/controller/pcie-iproc.c
index e98dafd0fff4..905e93808243 100644
--- a/drivers/pci/controller/pcie-iproc.c
+++ b/drivers/pci/controller/pcie-iproc.c
@@ -1526,7 +1526,6 @@  int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)
 	host->ops = &iproc_pcie_ops;
 	host->sysdata = pcie;
 	host->map_irq = pcie->map_irq;
-	host->swizzle_irq = pci_common_swizzle;
 
 	ret = pci_host_probe(host);
 	if (ret < 0) {
diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c
index ca12b2d6892b..4565affe1a2c 100644
--- a/drivers/pci/controller/pcie-mediatek.c
+++ b/drivers/pci/controller/pcie-mediatek.c
@@ -1085,8 +1085,6 @@  static int mtk_pcie_probe(struct platform_device *pdev)
 		return err;
 
 	host->ops = pcie->soc->ops;
-	host->map_irq = of_irq_parse_and_map_pci;
-	host->swizzle_irq = pci_common_swizzle;
 	host->sysdata = pcie;
 
 	err = pci_host_probe(host);
diff --git a/drivers/pci/controller/pcie-rcar-host.c b/drivers/pci/controller/pcie-rcar-host.c
index 67f2a9d3bc29..f6f41db31d47 100644
--- a/drivers/pci/controller/pcie-rcar-host.c
+++ b/drivers/pci/controller/pcie-rcar-host.c
@@ -294,8 +294,6 @@  static int rcar_pcie_enable(struct rcar_pcie_host *host)
 
 	bridge->sysdata = host;
 	bridge->ops = &rcar_pcie_ops;
-	bridge->map_irq = of_irq_parse_and_map_pci;
-	bridge->swizzle_irq = pci_common_swizzle;
 	if (IS_ENABLED(CONFIG_PCI_MSI))
 		bridge->msi = &host->msi.chip;
 
diff --git a/drivers/pci/controller/pcie-rockchip-host.c b/drivers/pci/controller/pcie-rockchip-host.c
index fed4f6cd1b7b..153bc95ab29f 100644
--- a/drivers/pci/controller/pcie-rockchip-host.c
+++ b/drivers/pci/controller/pcie-rockchip-host.c
@@ -1001,8 +1001,6 @@  static int rockchip_pcie_probe(struct platform_device *pdev)
 
 	bridge->sysdata = rockchip;
 	bridge->ops = &rockchip_pcie_ops;
-	bridge->map_irq = of_irq_parse_and_map_pci;
-	bridge->swizzle_irq = pci_common_swizzle;
 
 	err = pci_host_probe(bridge);
 	if (err < 0)
diff --git a/drivers/pci/controller/pcie-xilinx-nwl.c b/drivers/pci/controller/pcie-xilinx-nwl.c
index 7e7c23c555c7..97305bfe81b5 100644
--- a/drivers/pci/controller/pcie-xilinx-nwl.c
+++ b/drivers/pci/controller/pcie-xilinx-nwl.c
@@ -846,8 +846,6 @@  static int nwl_pcie_probe(struct platform_device *pdev)
 
 	bridge->sysdata = pcie;
 	bridge->ops = &nwl_pcie_ops;
-	bridge->map_irq = of_irq_parse_and_map_pci;
-	bridge->swizzle_irq = pci_common_swizzle;
 
 	if (IS_ENABLED(CONFIG_PCI_MSI)) {
 		err = nwl_pcie_enable_msi(pcie);
diff --git a/drivers/pci/controller/pcie-xilinx.c b/drivers/pci/controller/pcie-xilinx.c
index f8b8ccea5cbc..8523be61bba5 100644
--- a/drivers/pci/controller/pcie-xilinx.c
+++ b/drivers/pci/controller/pcie-xilinx.c
@@ -643,8 +643,6 @@  static int xilinx_pcie_probe(struct platform_device *pdev)
 
 	bridge->sysdata = port;
 	bridge->ops = &xilinx_pcie_ops;
-	bridge->map_irq = of_irq_parse_and_map_pci;
-	bridge->swizzle_irq = pci_common_swizzle;
 
 #ifdef CONFIG_PCI_MSI
 	xilinx_pcie_msi_chip.dev = dev;
diff --git a/drivers/pci/of.c b/drivers/pci/of.c
index 5e06aae1b4cd..8f478d923196 100644
--- a/drivers/pci/of.c
+++ b/drivers/pci/of.c
@@ -569,6 +569,9 @@  int devm_of_pci_bridge_init(struct device *dev, struct pci_host_bridge *bridge)
 	if (!dev->of_node)
 		return 0;
 
+	bridge->swizzle_irq = pci_common_swizzle;
+	bridge->map_irq = of_irq_parse_and_map_pci;
+
 	return pci_parse_request_of_pci_ranges(dev, bridge);
 }