提交 423511ec 编写于 作者: W Will McVicker 提交者: Lorenzo Pieralisi

PCI: dwc: Drop dependency on ZONE_DMA32

Re-work the msi_msg DMA allocation logic to use dmam_alloc_coherent() which
uses the coherent DMA mask to try to return an allocation within the DMA
mask limits. With that, we now can drop the msi_page parameter in struct
dw_pcie_rp. This allows kernel configurations that disable ZONE_DMA32 to
continue supporting a 32-bit DMA mask. Without this patch, the PCIe host
device will fail to probe when ZONE_DMA32 is disabled.

Link: https://lore.kernel.org/r/20220825235404.4132818-2-willmcvicker@google.com
Fixes: 35797e67 ("PCI: dwc: Fix MSI msi_msg DMA mapping")
Reported-by: NIsaac J. Manjarres <isaacmanjarres@google.com>
Signed-off-by: NWill McVicker <willmcvicker@google.com>
Signed-off-by: NLorenzo Pieralisi <lpieralisi@kernel.org>
Reviewed-by: NRob Herring <robh@kernel.org>
Acked-by: NJingoo Han <jingoohan1@gmail.com>
上级 568035b0
...@@ -267,15 +267,6 @@ static void dw_pcie_free_msi(struct dw_pcie_rp *pp) ...@@ -267,15 +267,6 @@ static void dw_pcie_free_msi(struct dw_pcie_rp *pp)
irq_domain_remove(pp->msi_domain); irq_domain_remove(pp->msi_domain);
irq_domain_remove(pp->irq_domain); irq_domain_remove(pp->irq_domain);
if (pp->msi_data) {
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
struct device *dev = pci->dev;
dma_unmap_page(dev, pp->msi_data, PAGE_SIZE, DMA_FROM_DEVICE);
if (pp->msi_page)
__free_page(pp->msi_page);
}
} }
static void dw_pcie_msi_init(struct dw_pcie_rp *pp) static void dw_pcie_msi_init(struct dw_pcie_rp *pp)
...@@ -336,6 +327,7 @@ static int dw_pcie_msi_host_init(struct dw_pcie_rp *pp) ...@@ -336,6 +327,7 @@ static int dw_pcie_msi_host_init(struct dw_pcie_rp *pp)
struct dw_pcie *pci = to_dw_pcie_from_pp(pp); struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
struct device *dev = pci->dev; struct device *dev = pci->dev;
struct platform_device *pdev = to_platform_device(dev); struct platform_device *pdev = to_platform_device(dev);
u64 *msi_vaddr;
int ret; int ret;
u32 ctrl, num_ctrls; u32 ctrl, num_ctrls;
...@@ -375,22 +367,16 @@ static int dw_pcie_msi_host_init(struct dw_pcie_rp *pp) ...@@ -375,22 +367,16 @@ static int dw_pcie_msi_host_init(struct dw_pcie_rp *pp)
dw_chained_msi_isr, pp); dw_chained_msi_isr, pp);
} }
ret = dma_set_mask(dev, DMA_BIT_MASK(32)); ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
if (ret) if (ret)
dev_warn(dev, "Failed to set DMA mask to 32-bit. Devices with only 32-bit MSI support may not work properly\n"); dev_warn(dev, "Failed to set DMA mask to 32-bit. Devices with only 32-bit MSI support may not work properly\n");
pp->msi_page = alloc_page(GFP_DMA32); msi_vaddr = dmam_alloc_coherent(dev, sizeof(u64), &pp->msi_data,
pp->msi_data = dma_map_page(dev, pp->msi_page, 0, GFP_KERNEL);
PAGE_SIZE, DMA_FROM_DEVICE); if (!msi_vaddr) {
ret = dma_mapping_error(dev, pp->msi_data); dev_err(dev, "Failed to alloc and map MSI data\n");
if (ret) {
dev_err(pci->dev, "Failed to map MSI data\n");
__free_page(pp->msi_page);
pp->msi_page = NULL;
pp->msi_data = 0;
dw_pcie_free_msi(pp); dw_pcie_free_msi(pp);
return -ENOMEM;
return ret;
} }
return 0; return 0;
......
...@@ -243,7 +243,6 @@ struct dw_pcie_rp { ...@@ -243,7 +243,6 @@ struct dw_pcie_rp {
struct irq_domain *irq_domain; struct irq_domain *irq_domain;
struct irq_domain *msi_domain; struct irq_domain *msi_domain;
dma_addr_t msi_data; dma_addr_t msi_data;
struct page *msi_page;
struct irq_chip *msi_irq_chip; struct irq_chip *msi_irq_chip;
u32 num_vectors; u32 num_vectors;
u32 irq_mask[MAX_MSI_CTRLS]; u32 irq_mask[MAX_MSI_CTRLS];
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册