PCI: dwc: Drop dependency on ZONE_DMA32
authorWill McVicker <willmcvicker@google.com>
Thu, 25 Aug 2022 23:54:02 +0000 (23:54 +0000)
committerLorenzo Pieralisi <lpieralisi@kernel.org>
Mon, 29 Aug 2022 07:56:33 +0000 (09:56 +0200)
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: 35797e672ff0 ("PCI: dwc: Fix MSI msi_msg DMA mapping")
Reported-by: Isaac J. Manjarres <isaacmanjarres@google.com>
Signed-off-by: Will McVicker <willmcvicker@google.com>
Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
Reviewed-by: Rob Herring <robh@kernel.org>
Acked-by: Jingoo Han <jingoohan1@gmail.com>
drivers/pci/controller/dwc/pcie-designware-host.c
drivers/pci/controller/dwc/pcie-designware.h

index 7746f94..39f3b37 100644 (file)
@@ -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->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)
@@ -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 device *dev = pci->dev;
        struct platform_device *pdev = to_platform_device(dev);
+       u64 *msi_vaddr;
        int ret;
        u32 ctrl, num_ctrls;
 
@@ -375,22 +367,16 @@ static int dw_pcie_msi_host_init(struct dw_pcie_rp *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)
                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);
-       pp->msi_data = dma_map_page(dev, pp->msi_page, 0,
-                                   PAGE_SIZE, DMA_FROM_DEVICE);
-       ret = dma_mapping_error(dev, pp->msi_data);
-       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;
+       msi_vaddr = dmam_alloc_coherent(dev, sizeof(u64), &pp->msi_data,
+                                       GFP_KERNEL);
+       if (!msi_vaddr) {
+               dev_err(dev, "Failed to alloc and map MSI data\n");
                dw_pcie_free_msi(pp);
-
-               return ret;
+               return -ENOMEM;
        }
 
        return 0;
index 09b8870..a871ae7 100644 (file)
@@ -243,7 +243,6 @@ struct dw_pcie_rp {
        struct irq_domain       *irq_domain;
        struct irq_domain       *msi_domain;
        dma_addr_t              msi_data;
-       struct page             *msi_page;
        struct irq_chip         *msi_irq_chip;
        u32                     num_vectors;
        u32                     irq_mask[MAX_MSI_CTRLS];