summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMinda Chen <minda.chen@starfivetech.com>2023-07-03 11:14:20 +0300
committerMinda Chen <minda.chen@starfivetech.com>2023-07-03 12:16:55 +0300
commit19b64491d3ac9025661081347b3bf358daf5dea2 (patch)
treed8a946fa52ce2db0b411865aad9e6b78e7060200
parent7986171dd9e46afe7bf6ca0eb2ede77a55780c54 (diff)
downloadlinux-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.c27
-rw-r--r--drivers/usb/host/xhci-plat.c9
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",