Thread (50 messages) 50 messages, 7 authors, 2017-06-02
STALE3308d

[RFC/RFT PATCH 18/18] ARM/ARM64: PCI: Drop pci_fixup_irqs() usage for DT based host controllers

From: Lorenzo Pieralisi <hidden>
Date: 2017-05-03 10:51:30
Also in: linux-pci

On Fri, Apr 28, 2017 at 03:05:44PM +0200, Arnd Bergmann wrote:
On Wed, Apr 26, 2017 at 1:18 PM, Lorenzo Pieralisi
[off-list ref] wrote:
quoted
DT based PCI host controllers are currently relying on
pci_fixup_irqs() to assign legacy PCI irqs to devices. This is
broken in that pci_fixup_irqs() assign IRQs for all PCI devices
present in a given system some of which may well be enabled by
the time pci_fixup_irqs() is called (ie a system with multiple
host controllers). With the introduction of
struct pci_host_bridge.map_irq pointer it is possible to assign IRQs
for all devices originating from a PCI host bridge at probe time;
this is implemented through pci_assign_irq() that relies on the
struct pci_host_bridge.map_irq pointer to map IRQ for a given device.

The benefits this brings are twofold:

- the IRQ for a device is assigned once at probe time
- the IRQ assignment works also for hotplugged devices

Remove pci_fixup_irqs() call from all DT based PCI host controller
drivers. The map_irq() and swizzle_irq() struct pci_host_bridge callbacks
are either set-up in the respective PCI host controller driver or
delegated to ARM/ARM64 pcibios_root_bridge_prepare() implementations,
where, upon DT probe detection, the functions are set to DT defaults (ie
of_irq_parse_and_map_pci() and pci_common_swizzle() respectively.

Signed-off-by: Lorenzo Pieralisi <redacted>
Nice!
quoted
+int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
+{
+       /*
+        * Set-up IRQ mapping/swizzingly functions.
+        * If the either function pointer is already set,
+        * do not override any of them since it is a host
+        * controller specific mapping/swizzling function.
+        */
+       if (!bridge->map_irq && !bridge->swizzle_irq) {
+               struct device *parent = bridge->dev.parent;
+               /*
+                * If we have a parent pointer with a valid
+                * OF node this means we are probing a PCI host
+                * controller configured through DT firmware.
+                */
+               if (IS_ENABLED(CONFIG_OF) && parent && parent->of_node) {
+                       bridge->map_irq = of_irq_parse_and_map_pci;
+                       bridge->swizzle_irq = pci_common_swizzle;
+               }
+       }
+
+       return 0;
+}
I think it would be better to reduce the number of global functions defined
by common code to be called from PCI core code, and instead use
additional callback pointers from the pci_host_bridge operations.
Yes but this means duplicating the whole map_irq/swizzle_irq
initialization thing in all DT PCI host controllers, it is getting
quite cumbersome to be frank, we should try to consolidate DT PCI
host controllers code, it is becoming a bit unwieldy to manage and
there is too much code duplication.
In particular, there are only very few existing users of
pcibios_root_bridge_prepare() at the moment, so we should
be able to get rid of those quite easily now.
I could do but please see my comment above.
quoted
diff --git a/drivers/pci/host/pcie-iproc.c b/drivers/pci/host/pcie-iproc.c
index 0f39bd2..bc9e36a 100644
--- a/drivers/pci/host/pcie-iproc.c
+++ b/drivers/pci/host/pcie-iproc.c
@@ -1205,7 +1205,8 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)
        struct device *dev;
        int ret;
        void *sysdata;
-       struct pci_bus *bus, *child;
+       struct pci_bus *child;
+       struct pci_host_bridge *host;

        dev = pcie->dev;
@@ -1252,15 +1253,30 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)
        sysdata = pcie;
 #endif

-       bus = pci_create_root_bus(dev, 0, &iproc_pcie_ops, sysdata, res);
-       if (!bus) {
Could this be a separate patch?
Yes, I can split it from the pci_fixup_irqs() removal.

Thanks,
Lorenzo
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help