aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBharat Kumar Gogada <bharat.kumar.gogada@xilinx.com>2016-09-01 06:14:41 -0400
committerBjorn Helgaas <bhelgaas@google.com>2016-09-13 11:21:36 -0400
commitb584fa1fde71aa57fb63d32f66ff6c192ff7f2c5 (patch)
tree143730eea915b3e6931789e2cbd099003a5cb80b
parentf665bd1515aceb80990fdbc91b7c8aed045f5da8 (diff)
PCI: xilinx: Keep both legacy and MSI interrupt domain references
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>
-rw-r--r--drivers/pci/host/pcie-xilinx.c26
1 files changed, 15 insertions, 11 deletions
diff --git a/drivers/pci/host/pcie-xilinx.c b/drivers/pci/host/pcie-xilinx.c
index a30e01639557..bd646772b001 100644
--- a/drivers/pci/host/pcie-xilinx.c
+++ b/drivers/pci/host/pcie-xilinx.c
@@ -101,7 +101,8 @@
101 * @msi_pages: MSI pages 101 * @msi_pages: MSI pages
102 * @root_busno: Root Bus number 102 * @root_busno: Root Bus number
103 * @dev: Device pointer 103 * @dev: Device pointer
104 * @irq_domain: IRQ domain pointer 104 * @msi_domain: MSI IRQ domain pointer
105 * @leg_domain: Legacy IRQ domain pointer
105 * @resources: Bus Resources 106 * @resources: Bus Resources
106 */ 107 */
107struct xilinx_pcie_port { 108struct xilinx_pcie_port {
@@ -110,7 +111,8 @@ struct xilinx_pcie_port {
110 unsigned long msi_pages; 111 unsigned long msi_pages;
111 u8 root_busno; 112 u8 root_busno;
112 struct device *dev; 113 struct device *dev;
113 struct irq_domain *irq_domain; 114 struct irq_domain *msi_domain;
115 struct irq_domain *leg_domain;
114 struct list_head resources; 116 struct list_head resources;
115}; 117};
116 118
@@ -281,7 +283,7 @@ static int xilinx_pcie_msi_setup_irq(struct msi_controller *chip,
281 if (hwirq < 0) 283 if (hwirq < 0)
282 return hwirq; 284 return hwirq;
283 285
284 irq = irq_create_mapping(port->irq_domain, hwirq); 286 irq = irq_create_mapping(port->msi_domain, hwirq);
285 if (!irq) 287 if (!irq)
286 return -EINVAL; 288 return -EINVAL;
287 289
@@ -443,7 +445,7 @@ static irqreturn_t xilinx_pcie_intr_handler(int irq, void *data)
443 /* Handle INTx Interrupt */ 445 /* Handle INTx Interrupt */
444 val = ((val & XILINX_PCIE_RPIFR1_INTR_MASK) >> 446 val = ((val & XILINX_PCIE_RPIFR1_INTR_MASK) >>
445 XILINX_PCIE_RPIFR1_INTR_SHIFT) + 1; 447 XILINX_PCIE_RPIFR1_INTR_SHIFT) + 1;
446 generic_handle_irq(irq_find_mapping(port->irq_domain, 448 generic_handle_irq(irq_find_mapping(port->leg_domain,
447 val)); 449 val));
448 } 450 }
449 } 451 }
@@ -526,12 +528,14 @@ static void xilinx_pcie_free_irq_domain(struct xilinx_pcie_port *port)
526 } 528 }
527 529
528 for (i = 0; i < num_irqs; i++) { 530 for (i = 0; i < num_irqs; i++) {
529 irq = irq_find_mapping(port->irq_domain, i); 531 irq = irq_find_mapping(port->leg_domain, i);
530 if (irq > 0) 532 if (irq > 0)
531 irq_dispose_mapping(irq); 533 irq_dispose_mapping(irq);
532 } 534 }
533 535 if (port->leg_domain)
534 irq_domain_remove(port->irq_domain); 536 irq_domain_remove(port->leg_domain);
537 if (port->msi_domain)
538 irq_domain_remove(port->msi_domain);
535} 539}
536 540
537/** 541/**
@@ -553,21 +557,21 @@ static int xilinx_pcie_init_irq_domain(struct xilinx_pcie_port *port)
553 return -ENODEV; 557 return -ENODEV;
554 } 558 }
555 559
556 port->irq_domain = irq_domain_add_linear(pcie_intc_node, 4, 560 port->leg_domain = irq_domain_add_linear(pcie_intc_node, 4,
557 &intx_domain_ops, 561 &intx_domain_ops,
558 port); 562 port);
559 if (!port->irq_domain) { 563 if (!port->leg_domain) {
560 dev_err(dev, "Failed to get a INTx IRQ domain\n"); 564 dev_err(dev, "Failed to get a INTx IRQ domain\n");
561 return -ENODEV; 565 return -ENODEV;
562 } 566 }
563 567
564 /* Setup MSI */ 568 /* Setup MSI */
565 if (IS_ENABLED(CONFIG_PCI_MSI)) { 569 if (IS_ENABLED(CONFIG_PCI_MSI)) {
566 port->irq_domain = irq_domain_add_linear(node, 570 port->msi_domain = irq_domain_add_linear(node,
567 XILINX_NUM_MSI_IRQS, 571 XILINX_NUM_MSI_IRQS,
568 &msi_domain_ops, 572 &msi_domain_ops,
569 &xilinx_pcie_msi_chip); 573 &xilinx_pcie_msi_chip);
570 if (!port->irq_domain) { 574 if (!port->msi_domain) {
571 dev_err(dev, "Failed to get a MSI IRQ domain\n"); 575 dev_err(dev, "Failed to get a MSI IRQ domain\n");
572 return -ENODEV; 576 return -ENODEV;
573 } 577 }