Merge tag 'dma-mapping-5.20-2022-08-06' of git://git.infradead.org/users/hch/dma...
[sfrench/cifs-2.6.git] / drivers / usb / core / hcd.c
index a6a87c5d1b05c5d6a1da9ea6d6108307921bdbf0..94b305bbd621b4b41d90b778c7ebded548ff62df 100644 (file)
@@ -1251,7 +1251,8 @@ void usb_hcd_unlink_urb_from_ep(struct usb_hcd *hcd, struct urb *urb)
 EXPORT_SYMBOL_GPL(usb_hcd_unlink_urb_from_ep);
 
 /*
- * Some usb host controllers can only perform dma using a small SRAM area.
+ * Some usb host controllers can only perform dma using a small SRAM area,
+ * or have restrictions on addressable DRAM.
  * The usb core itself is however optimized for host controllers that can dma
  * using regular system memory - like pci devices doing bus mastering.
  *
@@ -3127,8 +3128,18 @@ int usb_hcd_setup_local_mem(struct usb_hcd *hcd, phys_addr_t phys_addr,
        if (IS_ERR(hcd->localmem_pool))
                return PTR_ERR(hcd->localmem_pool);
 
-       local_mem = devm_memremap(hcd->self.sysdev, phys_addr,
-                                 size, MEMREMAP_WC);
+       /*
+        * if a physical SRAM address was passed, map it, otherwise
+        * allocate system memory as a buffer.
+        */
+       if (phys_addr)
+               local_mem = devm_memremap(hcd->self.sysdev, phys_addr,
+                                         size, MEMREMAP_WC);
+       else
+               local_mem = dmam_alloc_attrs(hcd->self.sysdev, size, &dma,
+                                            GFP_KERNEL,
+                                            DMA_ATTR_WRITE_COMBINE);
+
        if (IS_ERR(local_mem))
                return PTR_ERR(local_mem);