[OpenBIOS] [PATCH 8/8] pci: allow ob_pci_bus_set_interrupt_map() to take a callback function

Mark Cave-Ayland mark.cave-ayland at ilande.co.uk
Sun Jun 11 12:00:37 CEST 2017


This serves 2 purposes: firstly it means that each PCI bridge can set its
own custom interrupt-map and interrupt-mask if required, and secondly the
interrupt properties can be split into per-architecure sections.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland at ilande.co.uk>
---
 drivers/pci.c |   69 ++++++++++++++++++++++++++++++++++++++-------------------
 1 file changed, 46 insertions(+), 23 deletions(-)

diff --git a/drivers/pci.c b/drivers/pci.c
index 7f652a8..ac7a249 100644
--- a/drivers/pci.c
+++ b/drivers/pci.c
@@ -1547,13 +1547,9 @@ static void ob_pci_set_available(phandle_t host, unsigned long mem_base, unsigne
     set_property(host, "available", (char *)props, ncells * sizeof(props[0]));
 }
 
-/* Convert device/irq pin to interrupt property */
-#define SUN4U_INTERRUPT(dev, irq_pin) \
-            ((((dev >> 11) << 2) + irq_pin - 1) & 0x1f)
-
+#if defined(CONFIG_PPC)
 static phandle_t ob_pci_host_set_interrupt_map(phandle_t host)
 {
-#if defined(CONFIG_PPC)
     /* Set the host bridge interrupt map, returning the phandle
        of the interrupt controller */
     phandle_t dnode, target_node;
@@ -1611,12 +1607,53 @@ static phandle_t ob_pci_host_set_interrupt_map(phandle_t host)
 
         return dnode;
     }
-#endif
 
     return host;
 }
 
-static void ob_pci_bus_set_interrupt_map(phandle_t pcibus, phandle_t dnode)
+static void ob_pci_host_bus_interrupt(ucell dnode, u32 *props, int *ncells, u32 addr, u32 intno)
+{
+    *ncells += pci_encode_phys_addr(props + *ncells, 0, 0, addr, 0, 0);
+    props[(*ncells)++] = intno;
+    props[(*ncells)++] = dnode;
+    props[(*ncells)++] = arch->irqs[((intno - 1) + (addr >> 11)) & 3];
+    props[(*ncells)++] = 1;
+}
+
+#elif defined(CONFIG_SPARC64)
+
+/* Convert device/irq pin to interrupt property */
+#define SUN4U_INTERRUPT(dev, irq_pin) \
+            ((((dev >> 11) << 2) + irq_pin - 1) & 0x1f)
+            
+static phandle_t ob_pci_host_set_interrupt_map(phandle_t host)
+{
+    return host;
+}
+           
+static void ob_pci_host_bus_interrupt(ucell dnode, u32 *props, int *ncells, u32 addr, u32 intno)
+{
+    *ncells += pci_encode_phys_addr(props + *ncells, 0, 0, addr, 0, 0);
+    props[(*ncells)++] = intno;
+    props[(*ncells)++] = dnode;
+    props[(*ncells)++] = SUN4U_INTERRUPT(addr, intno);
+}
+
+#else
+
+static phandle_t ob_pci_host_set_interrupt_map(phandle_t host)
+{
+    return host;
+}
+
+static void ob_pci_host_bus_interrupt(ucell dnode, u32 *props, int *ncells, u32 addr, u32 intno)
+{
+    return;
+}
+#endif
+
+static void ob_pci_bus_set_interrupt_map(phandle_t pcibus, phandle_t dnode,
+              void (*func)(ucell dnode, u32 *props, int *ncells, u32 addr, u32 intno))
 {
     /* Set interrupt-map for PCI devices with an interrupt pin present */
     phandle_t pci_childnode = 0;
@@ -1645,21 +1682,7 @@ static void ob_pci_bus_set_interrupt_map(phandle_t pcibus, phandle_t dnode)
 
                     /* Device address is in 1st 32-bit word of encoded PCI address for config space */
                     if ((addr & PCI_RANGE_TYPE_MASK) == PCI_RANGE_CONFIG) {
-#if defined(CONFIG_SPARC64)
-                        ncells += pci_encode_phys_addr(props + ncells, 0, 0, addr, 0, 0);
-                        props[ncells++] = intno;
-                        props[ncells++] = dnode;
-                        props[ncells++] = SUN4U_INTERRUPT(addr, intno);
-#elif defined(CONFIG_PPC)
-                        ncells += pci_encode_phys_addr(props + ncells, 0, 0, addr, 0, 0);
-                        props[ncells++] = intno;
-                        props[ncells++] = dnode;
-                        props[ncells++] = arch->irqs[((intno - 1) + (addr >> 11)) & 3];
-                        props[ncells++] = 1;
-#else
-                        /* Keep compiler quiet */
-                        dnode = dnode;
-#endif
+                        (*func)(dnode, props, &ncells, addr, intno);
                     }
                 }
             }
@@ -1738,7 +1761,7 @@ int ob_pci_init(void)
 
     /* configure the host bridge interrupt map */
     intc = ob_pci_host_set_interrupt_map(phandle_host);
-    ob_pci_bus_set_interrupt_map(phandle_host, intc);
+    ob_pci_bus_set_interrupt_map(phandle_host, intc, ob_pci_host_bus_interrupt);
 
     device_end();
 
-- 
1.7.10.4




More information about the OpenBIOS mailing list