[OpenBIOS] [PATCH 7/8] pci: split PCI bus interrupt maps from PCI host bridge interrupt maps

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


This is to allow us to generate interrupt maps for any PCI bus, not just the
PCI host bridge.

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

diff --git a/drivers/pci.c b/drivers/pci.c
index eafec32..7f652a8 100644
--- a/drivers/pci.c
+++ b/drivers/pci.c
@@ -1551,21 +1551,17 @@ static void ob_pci_set_available(phandle_t host, unsigned long mem_base, unsigne
 #define SUN4U_INTERRUPT(dev, irq_pin) \
             ((((dev >> 11) << 2) + irq_pin - 1) & 0x1f)
 
-static void ob_pci_host_set_interrupt_map(phandle_t host)
+static phandle_t ob_pci_host_set_interrupt_map(phandle_t host)
 {
-    phandle_t dnode = 0, pci_childnode = 0;
-    u32 props[128], intno;
-    int i, ncells, len;
-    u32 *val, addr;
-    char *reg;
-
 #if defined(CONFIG_PPC)
-    phandle_t target_node;
+    /* Set the host bridge interrupt map, returning the phandle
+       of the interrupt controller */
+    phandle_t dnode, target_node;
     char *path, buf[256];
 
     /* Oldworld macs do interrupt maps differently */
     if (!is_newworld())
-        return;
+        return 0;
 
     PCI_DPRINTF("setting up interrupt map for host %x\n", host);
     dnode = dt_iterate_type(0, "open-pic");
@@ -1612,16 +1608,29 @@ static void ob_pci_host_set_interrupt_map(phandle_t host)
 
         target_node = find_dev(path);
         set_int_property(target_node, "interrupt-parent", dnode);
+
+        return dnode;
     }
-#else
-    /* PCI host bridge is the default interrupt controller */
-    dnode = host;
 #endif
 
+    return host;
+}
+
+static void ob_pci_bus_set_interrupt_map(phandle_t pcibus, phandle_t dnode)
+{
     /* Set interrupt-map for PCI devices with an interrupt pin present */
-    ncells = 0;
+    phandle_t pci_childnode = 0;
+    u32 props[128], intno;
+    int i, ncells = 0, len;
+    u32 *val, addr;
+    char *reg;
+    
+    /* If no destination node specified, do nothing */
+    if (dnode == 0) {
+        return;
+    }
 
-    PUSH(host);
+    PUSH(pcibus);
     fword("child");
     pci_childnode = POP();
     while (pci_childnode) {
@@ -1660,13 +1669,13 @@ static void ob_pci_host_set_interrupt_map(phandle_t host)
         fword("peer");
         pci_childnode = POP();
     }
-    set_property(host, "interrupt-map", (char *)props, ncells * sizeof(props[0]));
+    set_property(pcibus, "interrupt-map", (char *)props, ncells * sizeof(props[0]));
 
     props[0] = 0x0000f800;
     props[1] = 0x0;
     props[2] = 0x0;
     props[3] = 0x7;
-    set_property(host, "interrupt-map-mask", (char *)props, 4 * sizeof(props[0]));
+    set_property(pcibus, "interrupt-map-mask", (char *)props, 4 * sizeof(props[0]));
 }
 
 int ob_pci_init(void)
@@ -1676,7 +1685,7 @@ int ob_pci_init(void)
     unsigned long mem_base, io_base;
 
     pci_config_t config = {}; /* host bridge */
-    phandle_t phandle_host = 0;
+    phandle_t phandle_host = 0, intc;
 
     PCI_DPRINTF("Initializing PCI host bridge...\n");
 
@@ -1728,7 +1737,8 @@ int ob_pci_init(void)
     ob_pci_set_available(phandle_host, mem_base, io_base);
 
     /* configure the host bridge interrupt map */
-    ob_pci_host_set_interrupt_map(phandle_host);
+    intc = ob_pci_host_set_interrupt_map(phandle_host);
+    ob_pci_bus_set_interrupt_map(phandle_host, intc);
 
     device_end();
 
-- 
1.7.10.4




More information about the OpenBIOS mailing list