PCI: xilinx: Keep both legacy and MSI interrupt domain references
authorBharat Kumar Gogada <bharat.kumar.gogada@xilinx.com>
Thu, 1 Sep 2016 10:14:41 +0000 (15:44 +0530)
committerBjorn Helgaas <bhelgaas@google.com>
Tue, 13 Sep 2016 15:21:36 +0000 (10:21 -0500)
When built with MSI support, the legacy domain reference was being
overwritten with MSI.

Create two separate domains for MSI and legacy interrupts.

Signed-off-by: Bharat Kumar Gogada <bharatku@xilinx.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Michal Simek <michal.simek@xilinx.com>
drivers/pci/host/pcie-xilinx.c

index a30e016395575016e7f8230e676217b197345f5d..bd646772b001deb4ae240cc1b1451e8ce5be582f 100644 (file)
  * @msi_pages: MSI pages
  * @root_busno: Root Bus number
  * @dev: Device pointer
- * @irq_domain: IRQ domain pointer
+ * @msi_domain: MSI IRQ domain pointer
+ * @leg_domain: Legacy IRQ domain pointer
  * @resources: Bus Resources
  */
 struct xilinx_pcie_port {
@@ -110,7 +111,8 @@ struct xilinx_pcie_port {
        unsigned long msi_pages;
        u8 root_busno;
        struct device *dev;
-       struct irq_domain *irq_domain;
+       struct irq_domain *msi_domain;
+       struct irq_domain *leg_domain;
        struct list_head resources;
 };
 
@@ -281,7 +283,7 @@ static int xilinx_pcie_msi_setup_irq(struct msi_controller *chip,
        if (hwirq < 0)
                return hwirq;
 
-       irq = irq_create_mapping(port->irq_domain, hwirq);
+       irq = irq_create_mapping(port->msi_domain, hwirq);
        if (!irq)
                return -EINVAL;
 
@@ -443,7 +445,7 @@ static irqreturn_t xilinx_pcie_intr_handler(int irq, void *data)
                        /* Handle INTx Interrupt */
                        val = ((val & XILINX_PCIE_RPIFR1_INTR_MASK) >>
                                XILINX_PCIE_RPIFR1_INTR_SHIFT) + 1;
-                       generic_handle_irq(irq_find_mapping(port->irq_domain,
+                       generic_handle_irq(irq_find_mapping(port->leg_domain,
                                                            val));
                }
        }
@@ -526,12 +528,14 @@ static void xilinx_pcie_free_irq_domain(struct xilinx_pcie_port *port)
        }
 
        for (i = 0; i < num_irqs; i++) {
-               irq = irq_find_mapping(port->irq_domain, i);
+               irq = irq_find_mapping(port->leg_domain, i);
                if (irq > 0)
                        irq_dispose_mapping(irq);
        }
-
-       irq_domain_remove(port->irq_domain);
+       if (port->leg_domain)
+               irq_domain_remove(port->leg_domain);
+       if (port->msi_domain)
+               irq_domain_remove(port->msi_domain);
 }
 
 /**
@@ -553,21 +557,21 @@ static int xilinx_pcie_init_irq_domain(struct xilinx_pcie_port *port)
                return -ENODEV;
        }
 
-       port->irq_domain = irq_domain_add_linear(pcie_intc_node, 4,
+       port->leg_domain = irq_domain_add_linear(pcie_intc_node, 4,
                                                 &intx_domain_ops,
                                                 port);
-       if (!port->irq_domain) {
+       if (!port->leg_domain) {
                dev_err(dev, "Failed to get a INTx IRQ domain\n");
                return -ENODEV;
        }
 
        /* Setup MSI */
        if (IS_ENABLED(CONFIG_PCI_MSI)) {
-               port->irq_domain = irq_domain_add_linear(node,
+               port->msi_domain = irq_domain_add_linear(node,
                                                         XILINX_NUM_MSI_IRQS,
                                                         &msi_domain_ops,
                                                         &xilinx_pcie_msi_chip);
-               if (!port->irq_domain) {
+               if (!port->msi_domain) {
                        dev_err(dev, "Failed to get a MSI IRQ domain\n");
                        return -ENODEV;
                }