diff options
author | Jisheng Zhang <Jisheng.Zhang@synaptics.com> | 2019-03-29 07:57:17 -0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2019-05-07 09:53:36 -0400 |
commit | dc69a3d567941784c3d00e1d0834582b42b0b3e7 (patch) | |
tree | 4976962d32629105cc89322c6a63b66cfde7c6a2 | |
parent | 3ebc269c197ee6a9788aeb76ebcc9132814a75e5 (diff) |
PCI: dwc: Free MSI IRQ page in dw_pcie_free_msi()
To avoid a memory leak, free the page allocated for MSI IRQ in
dw_pcie_free_msi().
Signed-off-by: Jisheng Zhang <Jisheng.Zhang@synaptics.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Gustavo Pimentel <gustavo.pimentel@synopsys.com>
-rw-r--r-- | drivers/pci/controller/dwc/pcie-designware-host.c | 12 | ||||
-rw-r--r-- | drivers/pci/controller/dwc/pcie-designware.h | 1 |
2 files changed, 9 insertions, 4 deletions
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c index 1040939f45b4..a71b874ae3c0 100644 --- a/drivers/pci/controller/dwc/pcie-designware-host.c +++ b/drivers/pci/controller/dwc/pcie-designware-host.c | |||
@@ -305,20 +305,24 @@ void dw_pcie_free_msi(struct pcie_port *pp) | |||
305 | 305 | ||
306 | irq_domain_remove(pp->msi_domain); | 306 | irq_domain_remove(pp->msi_domain); |
307 | irq_domain_remove(pp->irq_domain); | 307 | irq_domain_remove(pp->irq_domain); |
308 | |||
309 | if (pp->msi_page) | ||
310 | __free_page(pp->msi_page); | ||
308 | } | 311 | } |
309 | 312 | ||
310 | void dw_pcie_msi_init(struct pcie_port *pp) | 313 | void dw_pcie_msi_init(struct pcie_port *pp) |
311 | { | 314 | { |
312 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); | 315 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); |
313 | struct device *dev = pci->dev; | 316 | struct device *dev = pci->dev; |
314 | struct page *page; | ||
315 | u64 msi_target; | 317 | u64 msi_target; |
316 | 318 | ||
317 | page = alloc_page(GFP_KERNEL); | 319 | pp->msi_page = alloc_page(GFP_KERNEL); |
318 | pp->msi_data = dma_map_page(dev, page, 0, PAGE_SIZE, DMA_FROM_DEVICE); | 320 | pp->msi_data = dma_map_page(dev, pp->msi_page, 0, PAGE_SIZE, |
321 | DMA_FROM_DEVICE); | ||
319 | if (dma_mapping_error(dev, pp->msi_data)) { | 322 | if (dma_mapping_error(dev, pp->msi_data)) { |
320 | dev_err(dev, "Failed to map MSI data\n"); | 323 | dev_err(dev, "Failed to map MSI data\n"); |
321 | __free_page(page); | 324 | __free_page(pp->msi_page); |
325 | pp->msi_page = NULL; | ||
322 | return; | 326 | return; |
323 | } | 327 | } |
324 | msi_target = (u64)pp->msi_data; | 328 | msi_target = (u64)pp->msi_data; |
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h index 377f4c0b52da..6fb0a1879932 100644 --- a/drivers/pci/controller/dwc/pcie-designware.h +++ b/drivers/pci/controller/dwc/pcie-designware.h | |||
@@ -179,6 +179,7 @@ struct pcie_port { | |||
179 | struct irq_domain *irq_domain; | 179 | struct irq_domain *irq_domain; |
180 | struct irq_domain *msi_domain; | 180 | struct irq_domain *msi_domain; |
181 | dma_addr_t msi_data; | 181 | dma_addr_t msi_data; |
182 | struct page *msi_page; | ||
182 | u32 num_vectors; | 183 | u32 num_vectors; |
183 | u32 irq_mask[MAX_MSI_CTRLS]; | 184 | u32 irq_mask[MAX_MSI_CTRLS]; |
184 | raw_spinlock_t lock; | 185 | raw_spinlock_t lock; |