diff options
author | Minda Chen <minda.chen@starfivetech.com> | 2023-07-03 11:14:20 +0300 |
---|---|---|
committer | Minda Chen <minda.chen@starfivetech.com> | 2023-07-03 12:16:55 +0300 |
commit | 19b64491d3ac9025661081347b3bf358daf5dea2 (patch) | |
tree | d8a946fa52ce2db0b411865aad9e6b78e7060200 | |
parent | 7986171dd9e46afe7bf6ca0eb2ede77a55780c54 (diff) | |
download | linux-19b64491d3ac9025661081347b3bf358daf5dea2.tar.xz |
usb: xhci: using dma_alloc_noncoherent to alloc low memory pool
For RISCV_NONCACHEHERENT is set, using dma_alloc_noncoherent
to alloc cached large block low memory buffer. And set default
size to 4M. (largest size of continuous memory can be supported)
Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
-rw-r--r-- | drivers/usb/host/xhci-mem.c | 27 | ||||
-rw-r--r-- | drivers/usb/host/xhci-plat.c | 9 |
2 files changed, 20 insertions, 16 deletions
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index d8ca7e694ca3..4fa9d3c7f9f9 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -1890,7 +1890,8 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) if (xhci->lowmem_pool.pool) { pool = &xhci->lowmem_pool; - dma_free_coherent(dev, pool->size, (void *)pool->cached_base, pool->dma_addr); + dma_free_noncoherent(dev, pool->size, (void *)pool->cached_base, + pool->dma_addr, DMA_BIDIRECTIONAL); gen_pool_destroy(pool->pool); pool->pool = NULL; } @@ -2397,15 +2398,15 @@ int xhci_setup_local_lowmem(struct xhci_hcd *xhci, size_t size) if (!pool->pool) { /* minimal alloc one page */ pool->pool = gen_pool_create(PAGE_SHIFT, dev_to_node(hcd->self.sysdev)); - if (IS_ERR(pool->pool)) - return PTR_ERR(pool->pool); + if (!pool->pool) + return -ENOMEM; } - buffer = dma_alloc_coherent(hcd->self.sysdev, size, &dma_addr, - GFP_KERNEL | GFP_DMA32); + buffer = dma_alloc_noncoherent(hcd->self.sysdev, size, &dma_addr, + DMA_BIDIRECTIONAL, GFP_ATOMIC); - if (IS_ERR(buffer)) { - err = PTR_ERR(buffer); + if (!buffer) { + err = -ENOMEM; goto destroy_pool; } @@ -2415,11 +2416,11 @@ int xhci_setup_local_lowmem(struct xhci_hcd *xhci, size_t size) * for it. */ err = gen_pool_add_virt(pool->pool, (unsigned long)buffer, - dma_addr, size, dev_to_node(hcd->self.sysdev)); + dma_addr, size, dev_to_node(hcd->self.sysdev)); if (err < 0) { dev_err(hcd->self.sysdev, "gen_pool_add_virt failed with %d\n", err); - dma_free_coherent(hcd->self.sysdev, size, buffer, dma_addr); + dma_free_noncoherent(hcd->self.sysdev, size, buffer, dma_addr, DMA_BIDIRECTIONAL); goto destroy_pool; } @@ -2609,9 +2610,11 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) xhci->isoc_bei_interval = AVOID_BEI_INTERVAL_MAX; if (xhci->quirks & XHCI_LOCAL_BUFFER) { - if (xhci_setup_local_lowmem(xhci, - xhci->lowmem_pool.size)) - goto fail; + ret = xhci_setup_local_lowmem(xhci, xhci->lowmem_pool.size); + if (ret) { + xhci->quirks &= ~XHCI_LOCAL_BUFFER; + xhci_warn(xhci, "WARN: Can't alloc lowmem pool\n"); + } } /* diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 855f166dd1ae..e183515da682 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -325,10 +325,11 @@ static int xhci_plat_probe(struct platform_device *pdev) if (device_property_read_bool(tmpdev, "xhci-lowmem-pool")) { xhci->quirks |= XHCI_LOCAL_BUFFER; - if (device_property_read_u32(tmpdev, "lowmem-pool-size", - &xhci->lowmem_pool.size)) { - xhci->lowmem_pool.size = 8 << 20; - } else + ret = device_property_read_u32(tmpdev, "lowmem-pool-size", + &xhci->lowmem_pool.size); + if (ret || xhci->lowmem_pool.size >= 4) + xhci->lowmem_pool.size = 4 << 20; + else xhci->lowmem_pool.size <<= 20; } device_property_read_u32(tmpdev, "imod-interval-ns", |