aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/controller/pci-tegra.c37
1 files changed, 28 insertions, 9 deletions
diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
index f4f53d092e00..464ba2538d52 100644
--- a/drivers/pci/controller/pci-tegra.c
+++ b/drivers/pci/controller/pci-tegra.c
@@ -231,9 +231,9 @@ struct tegra_msi {
231 struct msi_controller chip; 231 struct msi_controller chip;
232 DECLARE_BITMAP(used, INT_PCI_MSI_NR); 232 DECLARE_BITMAP(used, INT_PCI_MSI_NR);
233 struct irq_domain *domain; 233 struct irq_domain *domain;
234 unsigned long pages;
235 struct mutex lock; 234 struct mutex lock;
236 u64 phys; 235 void *virt;
236 dma_addr_t phys;
237 int irq; 237 int irq;
238}; 238};
239 239
@@ -1536,7 +1536,7 @@ static int tegra_pcie_msi_setup(struct tegra_pcie *pcie)
1536 err = platform_get_irq_byname(pdev, "msi"); 1536 err = platform_get_irq_byname(pdev, "msi");
1537 if (err < 0) { 1537 if (err < 0) {
1538 dev_err(dev, "failed to get IRQ: %d\n", err); 1538 dev_err(dev, "failed to get IRQ: %d\n", err);
1539 goto err; 1539 goto free_irq_domain;
1540 } 1540 }
1541 1541
1542 msi->irq = err; 1542 msi->irq = err;
@@ -1545,17 +1545,35 @@ static int tegra_pcie_msi_setup(struct tegra_pcie *pcie)
1545 tegra_msi_irq_chip.name, pcie); 1545 tegra_msi_irq_chip.name, pcie);
1546 if (err < 0) { 1546 if (err < 0) {
1547 dev_err(dev, "failed to request IRQ: %d\n", err); 1547 dev_err(dev, "failed to request IRQ: %d\n", err);
1548 goto err; 1548 goto free_irq_domain;
1549 }
1550
1551 /* Though the PCIe controller can address >32-bit address space, to
1552 * facilitate endpoints that support only 32-bit MSI target address,
1553 * the mask is set to 32-bit to make sure that MSI target address is
1554 * always a 32-bit address
1555 */
1556 err = dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
1557 if (err < 0) {
1558 dev_err(dev, "failed to set DMA coherent mask: %d\n", err);
1559 goto free_irq;
1560 }
1561
1562 msi->virt = dma_alloc_attrs(dev, PAGE_SIZE, &msi->phys, GFP_KERNEL,
1563 DMA_ATTR_NO_KERNEL_MAPPING);
1564 if (!msi->virt) {
1565 dev_err(dev, "failed to allocate DMA memory for MSI\n");
1566 err = -ENOMEM;
1567 goto free_irq;
1549 } 1568 }
1550 1569
1551 /* setup AFI/FPCI range */
1552 msi->pages = __get_free_pages(GFP_KERNEL, 0);
1553 msi->phys = virt_to_phys((void *)msi->pages);
1554 host->msi = &msi->chip; 1570 host->msi = &msi->chip;
1555 1571
1556 return 0; 1572 return 0;
1557 1573
1558err: 1574free_irq:
1575 free_irq(msi->irq, pcie);
1576free_irq_domain:
1559 irq_domain_remove(msi->domain); 1577 irq_domain_remove(msi->domain);
1560 return err; 1578 return err;
1561} 1579}
@@ -1592,7 +1610,8 @@ static void tegra_pcie_msi_teardown(struct tegra_pcie *pcie)
1592 struct tegra_msi *msi = &pcie->msi; 1610 struct tegra_msi *msi = &pcie->msi;
1593 unsigned int i, irq; 1611 unsigned int i, irq;
1594 1612
1595 free_pages(msi->pages, 0); 1613 dma_free_attrs(pcie->dev, PAGE_SIZE, msi->virt, msi->phys,
1614 DMA_ATTR_NO_KERNEL_MAPPING);
1596 1615
1597 if (msi->irq > 0) 1616 if (msi->irq > 0)
1598 free_irq(msi->irq, pcie); 1617 free_irq(msi->irq, pcie);