diff options
| -rw-r--r-- | drivers/pci/controller/pci-tegra.c | 37 |
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 | ||
| 1558 | err: | 1574 | free_irq: |
| 1575 | free_irq(msi->irq, pcie); | ||
| 1576 | free_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); |
