Merge tag 'dma-mapping-5.3' of git://git.infradead.org/users/hch/dma-mapping
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 12 Jul 2019 22:13:55 +0000 (15:13 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 12 Jul 2019 22:13:55 +0000 (15:13 -0700)
Pull dma-mapping updates from Christoph Hellwig:

 - move the USB special case that bounced DMA through a device bar into
   the USB code instead of handling it in the common DMA code (Laurentiu
   Tudor and Fredrik Noring)

 - don't dip into the global CMA pool for single page allocations
   (Nicolin Chen)

 - fix a crash when allocating memory for the atomic pool failed during
   boot (Florian Fainelli)

 - move support for MIPS-style uncached segments to the common code and
   use that for MIPS and nios2 (me)

 - make support for DMA_ATTR_NON_CONSISTENT and
   DMA_ATTR_NO_KERNEL_MAPPING generic (me)

 - convert nds32 to the generic remapping allocator (me)

* tag 'dma-mapping-5.3' of git://git.infradead.org/users/hch/dma-mapping: (29 commits)
  dma-mapping: mark dma_alloc_need_uncached as __always_inline
  MIPS: only select ARCH_HAS_UNCACHED_SEGMENT for non-coherent platforms
  usb: host: Fix excessive alignment restriction for local memory allocations
  lib/genalloc.c: Add algorithm, align and zeroed family of DMA allocators
  nios2: use the generic uncached segment support in dma-direct
  nds32: use the generic remapping allocator for coherent DMA allocations
  arc: use the generic remapping allocator for coherent DMA allocations
  dma-direct: handle DMA_ATTR_NO_KERNEL_MAPPING in common code
  dma-direct: handle DMA_ATTR_NON_CONSISTENT in common code
  dma-mapping: add a dma_alloc_need_uncached helper
  openrisc: remove the partial DMA_ATTR_NON_CONSISTENT support
  arc: remove the partial DMA_ATTR_NON_CONSISTENT support
  arm-nommu: remove the partial DMA_ATTR_NON_CONSISTENT support
  ARM: dma-mapping: allow larger DMA mask than supported
  dma-mapping: truncate dma masks to what dma_addr_t can hold
  iommu/dma: Apply dma_{alloc,free}_contiguous functions
  dma-remap: Avoid de-referencing NULL atomic_pool
  MIPS: use the generic uncached segment support in dma-direct
  dma-direct: provide generic support for uncached kernel segments
  au1100fb: fix DMA API abuse
  ...

14 files changed:
1  2 
arch/arc/Kconfig
arch/arc/mm/dma.c
arch/arm/mm/dma-mapping-nommu.c
arch/arm/mm/dma-mapping.c
arch/mips/Kconfig
arch/mips/include/asm/page.h
arch/nds32/Kconfig
arch/openrisc/kernel/dma.c
arch/xtensa/kernel/pci-dma.c
drivers/iommu/dma-iommu.c
drivers/usb/Kconfig
drivers/usb/host/fotg210-hcd.c
include/linux/genalloc.h
lib/genalloc.c

diff --combined arch/arc/Kconfig
index 1c8137e7247b40526de5d703977e3cf7cbcbf148,cdad7d30ff1d699c2aa0e2d4ca9daa79b2b4a13a..8383155c8c824f486c2cadd7e46178ca627bfe5a
@@@ -1,12 -1,16 +1,13 @@@
 +# SPDX-License-Identifier: GPL-2.0-only
  #
  # Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
  #
 -# This program is free software; you can redistribute it and/or modify
 -# it under the terms of the GNU General Public License version 2 as
 -# published by the Free Software Foundation.
 -#
  
  config ARC
        def_bool y
        select ARC_TIMERS
        select ARCH_HAS_DMA_COHERENT_TO_PFN
+       select ARCH_HAS_DMA_PREP_COHERENT
        select ARCH_HAS_PTE_SPECIAL
        select ARCH_HAS_SETUP_DMA_OPS
        select ARCH_HAS_SYNC_DMA_FOR_CPU
@@@ -16,6 -20,7 +17,7 @@@
        select BUILDTIME_EXTABLE_SORT
        select CLONE_BACKWARDS
        select COMMON_CLK
+       select DMA_DIRECT_REMAP
        select GENERIC_ATOMIC64 if !ISA_ARCV2 || !(ARC_HAS_LL64 && ARC_HAS_LLSC)
        select GENERIC_CLOCKEVENTS
        select GENERIC_FIND_FIRST_BIT
diff --combined arch/arc/mm/dma.c
index 0bf1468c35a38daa707546e40cfde9a6a376ae48,0fa850709fac5907780940ed6e18bc1d59355c93..62c210e7ee4cdc5046b422d819a997e03134652f
@@@ -1,6 -1,9 +1,6 @@@
 +// SPDX-License-Identifier: GPL-2.0-only
  /*
   * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
 - *
 - * This program is free software; you can redistribute it and/or modify
 - * it under the terms of the GNU General Public License version 2 as
 - * published by the Free Software Foundation.
   */
  
  #include <linux/dma-noncoherent.h>
  #include <asm/cacheflush.h>
  
  /*
-  * ARCH specific callbacks for generic noncoherent DMA ops (dma/noncoherent.c)
+  * ARCH specific callbacks for generic noncoherent DMA ops
   *  - hardware IOC not available (or "dma-coherent" not set for device in DT)
   *  - But still handle both coherent and non-coherent requests from caller
   *
   * For DMA coherent hardware (IOC) generic code suffices
   */
- void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
-               gfp_t gfp, unsigned long attrs)
- {
-       unsigned long order = get_order(size);
-       struct page *page;
-       phys_addr_t paddr;
-       void *kvaddr;
-       bool need_coh = !(attrs & DMA_ATTR_NON_CONSISTENT);
-       /*
-        * __GFP_HIGHMEM flag is cleared by upper layer functions
-        * (in include/linux/dma-mapping.h) so we should never get a
-        * __GFP_HIGHMEM here.
-        */
-       BUG_ON(gfp & __GFP_HIGHMEM);
-       page = alloc_pages(gfp | __GFP_ZERO, order);
-       if (!page)
-               return NULL;
-       /* This is linear addr (0x8000_0000 based) */
-       paddr = page_to_phys(page);
-       *dma_handle = paddr;
-       /*
-        * A coherent buffer needs MMU mapping to enforce non-cachability.
-        * kvaddr is kernel Virtual address (0x7000_0000 based).
-        */
-       if (need_coh) {
-               kvaddr = ioremap_nocache(paddr, size);
-               if (kvaddr == NULL) {
-                       __free_pages(page, order);
-                       return NULL;
-               }
-       } else {
-               kvaddr = (void *)(u32)paddr;
-       }
  
+ void arch_dma_prep_coherent(struct page *page, size_t size)
+ {
        /*
         * Evict any existing L1 and/or L2 lines for the backing page
         * in case it was used earlier as a normal "cached" page.
         * Currently flush_cache_vmap nukes the L1 cache completely which
         * will be optimized as a separate commit
         */
-       if (need_coh)
-               dma_cache_wback_inv(paddr, size);
-       return kvaddr;
- }
- void arch_dma_free(struct device *dev, size_t size, void *vaddr,
-               dma_addr_t dma_handle, unsigned long attrs)
- {
-       phys_addr_t paddr = dma_handle;
-       struct page *page = virt_to_page(paddr);
-       if (!(attrs & DMA_ATTR_NON_CONSISTENT))
-               iounmap((void __force __iomem *)vaddr);
-       __free_pages(page, get_order(size));
- }
- long arch_dma_coherent_to_pfn(struct device *dev, void *cpu_addr,
-               dma_addr_t dma_addr)
- {
-       return __phys_to_pfn(dma_addr);
+       dma_cache_wback_inv(page_to_phys(page), size);
  }
  
  /*
@@@ -161,3 -107,9 +104,9 @@@ void arch_setup_dma_ops(struct device *
        dev_info(dev, "use %sncoherent DMA ops\n",
                 dev->dma_coherent ? "" : "non");
  }
+ static int __init atomic_pool_init(void)
+ {
+       return dma_atomic_pool_init(GFP_KERNEL, pgprot_noncached(PAGE_KERNEL));
+ }
+ postcore_initcall(atomic_pool_init);
index 1aea01ba12628463a0942a26d9cc740d9f0db081,bc003df45546fd2de0661d00d1196389c649f794..52b82559d99b3d608b4347a4060b7e686311d72a
@@@ -1,8 -1,12 +1,8 @@@
 +// SPDX-License-Identifier: GPL-2.0-only
  /*
   *  Based on linux/arch/arm/mm/dma-mapping.c
   *
   *  Copyright (C) 2000-2004 Russell King
 - *
 - * This program is free software; you can redistribute it and/or modify
 - * it under the terms of the GNU General Public License version 2 as
 - * published by the Free Software Foundation.
 - *
   */
  
  #include <linux/export.h>
@@@ -35,18 -39,7 +35,7 @@@ static void *arm_nommu_dma_alloc(struc
                                 unsigned long attrs)
  
  {
-       void *ret;
-       /*
-        * Try generic allocator first if we are advertised that
-        * consistency is not required.
-        */
-       if (attrs & DMA_ATTR_NON_CONSISTENT)
-               return dma_direct_alloc_pages(dev, size, dma_handle, gfp,
-                               attrs);
-       ret = dma_alloc_from_global_coherent(size, dma_handle);
+       void *ret = dma_alloc_from_global_coherent(size, dma_handle);
  
        /*
         * dma_alloc_from_global_coherent() may fail because:
@@@ -66,16 -59,9 +55,9 @@@ static void arm_nommu_dma_free(struct d
                               void *cpu_addr, dma_addr_t dma_addr,
                               unsigned long attrs)
  {
-       if (attrs & DMA_ATTR_NON_CONSISTENT) {
-               dma_direct_free_pages(dev, size, cpu_addr, dma_addr, attrs);
-       } else {
-               int ret = dma_release_from_global_coherent(get_order(size),
-                                                          cpu_addr);
-               WARN_ON_ONCE(ret == 0);
-       }
+       int ret = dma_release_from_global_coherent(get_order(size), cpu_addr);
  
-       return;
+       WARN_ON_ONCE(ret == 0);
  }
  
  static int arm_nommu_dma_mmap(struct device *dev, struct vm_area_struct *vma,
index 1fb5c0ca1ed8e8cf853732fb5b7a40d37ee2cd19,bdf0d236aaee36ffb659ef614e17a4b3d0d03faa..4789c60a86e34552411367282be7309f0d8f779a
@@@ -1,9 -1,12 +1,9 @@@
 +// SPDX-License-Identifier: GPL-2.0-only
  /*
   *  linux/arch/arm/mm/dma-mapping.c
   *
   *  Copyright (C) 2000-2004 Russell King
   *
 - * This program is free software; you can redistribute it and/or modify
 - * it under the terms of the GNU General Public License version 2 as
 - * published by the Free Software Foundation.
 - *
   *  DMA uncached mapping support.
   */
  #include <linux/module.h>
@@@ -216,25 -219,7 +216,7 @@@ EXPORT_SYMBOL(arm_coherent_dma_ops)
  
  static int __dma_supported(struct device *dev, u64 mask, bool warn)
  {
-       unsigned long max_dma_pfn;
-       /*
-        * If the mask allows for more memory than we can address,
-        * and we actually have that much memory, then we must
-        * indicate that DMA to this device is not supported.
-        */
-       if (sizeof(mask) != sizeof(dma_addr_t) &&
-           mask > (dma_addr_t)~0 &&
-           dma_to_pfn(dev, ~0) < max_pfn - 1) {
-               if (warn) {
-                       dev_warn(dev, "Coherent DMA mask %#llx is larger than dma_addr_t allows\n",
-                                mask);
-                       dev_warn(dev, "Driver did not use or check the return value from dma_set_coherent_mask()?\n");
-               }
-               return 0;
-       }
-       max_dma_pfn = min(max_pfn, arm_dma_pfn_limit);
+       unsigned long max_dma_pfn = min(max_pfn, arm_dma_pfn_limit);
  
        /*
         * Translate the device's DMA mask to a PFN limit.  This
@@@ -493,7 -478,8 +475,7 @@@ void __init dma_contiguous_remap(void
        }
  }
  
 -static int __dma_update_pte(pte_t *pte, pgtable_t token, unsigned long addr,
 -                          void *data)
 +static int __dma_update_pte(pte_t *pte, unsigned long addr, void *data)
  {
        struct page *page = virt_to_page(addr);
        pgprot_t prot = *(pgprot_t *)data;
diff --combined arch/mips/Kconfig
index 7957d3457156abdaf7fc03483ebde93124d04f65,caf480275a31b7ddecabee7ea4b1a603ad43f4ef..d50fafd7bf3aed0fac0729312b2d3aecd905e0c4
@@@ -34,7 -34,6 +34,7 @@@ config MIP
        select GENERIC_SCHED_CLOCK if !CAVIUM_OCTEON_SOC
        select GENERIC_SMP_IDLE_THREAD
        select GENERIC_TIME_VSYSCALL
 +      select GUP_GET_PTE_LOW_HIGH if CPU_MIPS32 && PHYS_ADDR_T_64BIT
        select HANDLE_DOMAIN_IRQ
        select HAVE_ARCH_COMPILER_H
        select HAVE_ARCH_JUMP_LABEL
@@@ -53,7 -52,6 +53,7 @@@
        select HAVE_DMA_CONTIGUOUS
        select HAVE_DYNAMIC_FTRACE
        select HAVE_EXIT_THREAD
 +      select HAVE_FAST_GUP
        select HAVE_FTRACE_MCOUNT_RECORD
        select HAVE_FUNCTION_GRAPH_TRACER
        select HAVE_FUNCTION_TRACER
@@@ -1121,6 -1119,7 +1121,7 @@@ config DMA_NONCOHEREN
        bool
        select ARCH_HAS_DMA_MMAP_PGPROT
        select ARCH_HAS_SYNC_DMA_FOR_DEVICE
+       select ARCH_HAS_UNCACHED_SEGMENT
        select NEED_DMA_MAP_STATE
        select ARCH_HAS_DMA_COHERENT_TO_PFN
        select DMA_NONCOHERENT_CACHE_SYNC
index a25643d258cb55be5830d262590f014f1d064d07,23e0f1386e0430b60e05a3a8cbbf3a1fee224818..0ba4ce6e2bf3ae3b5bfa7d366ebd4f6723baf138
@@@ -249,7 -249,7 +249,7 @@@ static inline int pfn_valid(unsigned lo
  #define virt_to_pfn(kaddr)    PFN_DOWN(virt_to_phys((void *)(kaddr)))
  #define virt_to_page(kaddr)   pfn_to_page(virt_to_pfn(kaddr))
  
 -extern int __virt_addr_valid(const volatile void *kaddr);
 +extern bool __virt_addr_valid(const volatile void *kaddr);
  #define virt_addr_valid(kaddr)                                                \
        __virt_addr_valid((const volatile void *) (kaddr))
  
         ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
         VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
  
- #define UNCAC_ADDR(addr)      (UNCAC_BASE + __pa(addr))
- #define CAC_ADDR(addr)                ((unsigned long)__va((addr) - UNCAC_BASE))
  #include <asm-generic/memory_model.h>
  #include <asm-generic/getorder.h>
  
diff --combined arch/nds32/Kconfig
index fd0d0639454f03c575275a83c613c630153762ba,643ea6b4bfa266155e297efd05c78d1a5196db19..fbd68329737f4cdf476f126ed3d7e0b7534d7c30
@@@ -1,18 -1,20 +1,20 @@@
  # SPDX-License-Identifier: GPL-2.0-only
  #
  # For a description of the syntax of this configuration file,
 -# see Documentation/kbuild/kconfig-language.txt.
 +# see Documentation/kbuild/kconfig-language.rst.
  #
  
  config NDS32
        def_bool y
        select ARCH_32BIT_OFF_T
+       select ARCH_HAS_DMA_PREP_COHERENT
        select ARCH_HAS_SYNC_DMA_FOR_CPU
        select ARCH_HAS_SYNC_DMA_FOR_DEVICE
        select ARCH_WANT_FRAME_POINTERS if FTRACE
        select CLKSRC_MMIO
        select CLONE_BACKWARDS
        select COMMON_CLK
+       select DMA_DIRECT_REMAP
        select GENERIC_ATOMIC64
        select GENERIC_CPU_DEVICES
        select GENERIC_CLOCKEVENTS
index 43e340c4cd9c9b06e89ed82582881ea42e42afde,9f25fd0fbb5d231fd16b6433b5bcc0894a2be70c..b41a79fcdbd93d749ebc9b4fef29078266c36dee
@@@ -1,4 -1,3 +1,4 @@@
 +// SPDX-License-Identifier: GPL-2.0-or-later
  /*
   * OpenRISC Linux
   *
@@@ -10,6 -9,11 +10,6 @@@
   * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
   * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
   *
 - *      This program is free software; you can redistribute it and/or
 - *      modify it under the terms of the GNU General Public License
 - *      as published by the Free Software Foundation; either version
 - *      2 of the License, or (at your option) any later version.
 - *
   * DMA mapping callbacks...
   * As alloc_coherent is the only DMA callback being used currently, that's
   * the only thing implemented properly.  The rest need looking into...
@@@ -94,15 -98,13 +94,13 @@@ arch_dma_alloc(struct device *dev, size
  
        va = (unsigned long)page;
  
-       if ((attrs & DMA_ATTR_NON_CONSISTENT) == 0) {
-               /*
-                * We need to iterate through the pages, clearing the dcache for
-                * them and setting the cache-inhibit bit.
-                */
-               if (walk_page_range(va, va + size, &walk)) {
-                       free_pages_exact(page, size);
-                       return NULL;
-               }
+       /*
+        * We need to iterate through the pages, clearing the dcache for
+        * them and setting the cache-inhibit bit.
+        */
+       if (walk_page_range(va, va + size, &walk)) {
+               free_pages_exact(page, size);
+               return NULL;
        }
  
        return (void *)va;
@@@ -118,10 -120,8 +116,8 @@@ arch_dma_free(struct device *dev, size_
                .mm = &init_mm
        };
  
-       if ((attrs & DMA_ATTR_NON_CONSISTENT) == 0) {
-               /* walk_page_range shouldn't be able to fail here */
-               WARN_ON(walk_page_range(va, va + size, &walk));
-       }
+       /* walk_page_range shouldn't be able to fail here */
+       WARN_ON(walk_page_range(va, va + size, &walk));
  
        free_pages_exact(vaddr, size);
  }
index a87f8a308cc1bcc057fd05765a838867399b44f3,206771277dff68af2ada41d86e5cbe4573b4013d..65f05776d827fecbae83a0552dac4324cd255847
@@@ -1,7 -1,11 +1,7 @@@
 +// SPDX-License-Identifier: GPL-2.0-or-later
  /*
   * DMA coherent memory allocation.
   *
 - * This program is free software; you can redistribute  it and/or modify it
 - * under  the terms of  the GNU General  Public License as published by the
 - * Free Software Foundation;  either version 2 of the  License, or (at your
 - * option) any later version.
 - *
   * Copyright (C) 2002 - 2005 Tensilica Inc.
   * Copyright (C) 2015 Cadence Design Systems Inc.
   *
@@@ -163,10 -167,6 +163,6 @@@ void *arch_dma_alloc(struct device *dev
  
        *handle = phys_to_dma(dev, page_to_phys(page));
  
-       if (attrs & DMA_ATTR_NO_KERNEL_MAPPING) {
-               return page;
-       }
  #ifdef CONFIG_MMU
        if (PageHighMem(page)) {
                void *p;
@@@ -192,9 -192,7 +188,7 @@@ void arch_dma_free(struct device *dev, 
        unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT;
        struct page *page;
  
-       if (attrs & DMA_ATTR_NO_KERNEL_MAPPING) {
-               page = vaddr;
-       } else if (platform_vaddr_uncached(vaddr)) {
+       if (platform_vaddr_uncached(vaddr)) {
                page = virt_to_page(platform_vaddr_to_cached(vaddr));
        } else {
  #ifdef CONFIG_MMU
index f802255219d3ac942f290ded71815b05d447de4b,cc0613c83d7175089db9240c494658b5ae34c72f..a7f9c3edbcb299f83f8d4c6093c274a0bc5b3387
@@@ -1,4 -1,4 +1,4 @@@
 -// SPDX-License-Identifier: GPL-2.0
 +// SPDX-License-Identifier: GPL-2.0-only
  /*
   * A fairly generic DMA-API to IOMMU-API glue layer.
   *
@@@ -226,8 -226,8 +226,8 @@@ resv_iova
                start = window->res->end - window->offset + 1;
                /* If window is last entry */
                if (window->node.next == &bridge->dma_ranges &&
 -                  end != ~(dma_addr_t)0) {
 -                      end = ~(dma_addr_t)0;
 +                  end != ~(phys_addr_t)0) {
 +                      end = ~(phys_addr_t)0;
                        goto resv_iova;
                }
        }
@@@ -951,8 -951,8 +951,8 @@@ static void __iommu_dma_free(struct dev
  
        if (pages)
                __iommu_dma_free_pages(pages, count);
-       if (page && !dma_release_from_contiguous(dev, page, count))
-               __free_pages(page, get_order(alloc_size));
+       if (page)
+               dma_free_contiguous(dev, page, alloc_size);
  }
  
  static void iommu_dma_free(struct device *dev, size_t size, void *cpu_addr,
@@@ -970,12 -970,7 +970,7 @@@ static void *iommu_dma_alloc_pages(stru
        struct page *page = NULL;
        void *cpu_addr;
  
-       if (gfpflags_allow_blocking(gfp))
-               page = dma_alloc_from_contiguous(dev, alloc_size >> PAGE_SHIFT,
-                                                get_order(alloc_size),
-                                                gfp & __GFP_NOWARN);
-       if (!page)
-               page = alloc_pages(gfp, get_order(alloc_size));
+       page = dma_alloc_contiguous(dev, alloc_size, gfp);
        if (!page)
                return NULL;
  
        memset(cpu_addr, 0, alloc_size);
        return cpu_addr;
  out_free_pages:
-       if (!dma_release_from_contiguous(dev, page, alloc_size >> PAGE_SHIFT))
-               __free_pages(page, get_order(alloc_size));
+       dma_free_contiguous(dev, page, alloc_size);
        return NULL;
  }
  
diff --combined drivers/usb/Kconfig
index 94573fb6830403319e5afd0f10ff29f06c718057,389c57d8eba7de10cb1f53291818ad21f428c836..6e59d370ef8104bd25794305146be6878219d6d2
@@@ -45,6 -45,7 +45,7 @@@ config USB_ARCH_HAS_HC
  config USB
        tristate "Support for Host-side USB"
        depends on USB_ARCH_HAS_HCD
+       select GENERIC_ALLOCATOR
        select USB_COMMON
        select NLS  # for UTF-8 strings
        ---help---
@@@ -74,7 -75,7 +75,7 @@@
          After choosing your HCD, then select drivers for the USB peripherals
          you'll be using.  You may want to check out the information provided
          in <file:Documentation/usb/> and especially the links given in
 -        <file:Documentation/usb/usb-help.txt>.
 +        <file:Documentation/usb/usb-help.rst>.
  
          To compile this driver as a module, choose M here: the
          module will be called usbcore.
index e835a22b12af6a80b6dc093cc55d67df8858c256,5d74ff61fa4c74cee8469da337d891929f1beb14..77cc36efae9500ea94f7109f5d7abed19812275a
@@@ -10,7 -10,6 +10,7 @@@
   * Most of code borrowed from the Linux-3.7 EHCI driver
   */
  #include <linux/module.h>
 +#include <linux/of.h>
  #include <linux/device.h>
  #include <linux/dmapool.h>
  #include <linux/kernel.h>
@@@ -4996,7 -4995,7 +4996,7 @@@ static int hcd_fotg210_init(struct usb_
        fotg210->command = temp;
  
        /* Accept arbitrarily long scatter-gather lists */
-       if (!(hcd->driver->flags & HCD_LOCAL_MEM))
+       if (!hcd->localmem_pool)
                hcd->self.sg_tablesize = ~0;
        return 0;
  }
@@@ -5670,18 -5669,9 +5670,18 @@@ static int fotg210_hcd_remove(struct pl
        return 0;
  }
  
 +#ifdef CONFIG_OF
 +static const struct of_device_id fotg210_of_match[] = {
 +      { .compatible = "faraday,fotg210" },
 +      {},
 +};
 +MODULE_DEVICE_TABLE(of, fotg210_of_match);
 +#endif
 +
  static struct platform_driver fotg210_hcd_driver = {
        .driver = {
                .name   = "fotg210-hcd",
 +              .of_match_table = of_match_ptr(fotg210_of_match),
        },
        .probe  = fotg210_hcd_probe,
        .remove = fotg210_hcd_remove,
diff --combined include/linux/genalloc.h
index 205f62b8d2916b8d3ad9c92ebdfd3ed00aee06fb,ed641337df8775a73d227682bacde2d488056d02..4bd583bd6934ea87e0b178b07f69a5c480d1fa48
@@@ -1,4 -1,3 +1,4 @@@
 +/* SPDX-License-Identifier: GPL-2.0-only */
  /*
   * Basic general purpose allocator for managing special purpose
   * memory, for example, memory that is not managed by the regular
@@@ -22,6 -21,9 +22,6 @@@
   * the allocator can NOT be used in NMI handler.  So code uses the
   * allocator in NMI handler should depend on
   * CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG.
 - *
 - * This source code is licensed under the GNU General Public License,
 - * Version 2.  See the file COPYING for more details.
   */
  
  
@@@ -73,7 -75,6 +73,7 @@@ struct gen_pool_chunk 
        struct list_head next_chunk;    /* next chunk in pool */
        atomic_long_t avail;
        phys_addr_t phys_addr;          /* physical starting address of memory chunk */
 +      void *owner;                    /* private data to retrieve at alloc time */
        unsigned long start_addr;       /* start address of memory chunk */
        unsigned long end_addr;         /* end address of memory chunk (inclusive) */
        unsigned long bits[0];          /* bitmap for allocating memory chunk */
@@@ -95,15 -96,8 +95,15 @@@ struct genpool_data_fixed 
  
  extern struct gen_pool *gen_pool_create(int, int);
  extern phys_addr_t gen_pool_virt_to_phys(struct gen_pool *pool, unsigned long);
 -extern int gen_pool_add_virt(struct gen_pool *, unsigned long, phys_addr_t,
 -                           size_t, int);
 +extern int gen_pool_add_owner(struct gen_pool *, unsigned long, phys_addr_t,
 +                           size_t, int, void *);
 +
 +static inline int gen_pool_add_virt(struct gen_pool *pool, unsigned long addr,
 +              phys_addr_t phys, size_t size, int nid)
 +{
 +      return gen_pool_add_owner(pool, addr, phys, size, nid, NULL);
 +}
 +
  /**
   * gen_pool_add - add a new chunk of special memory to the pool
   * @pool: pool to add new memory chunk to
@@@ -122,47 -116,21 +122,56 @@@ static inline int gen_pool_add(struct g
        return gen_pool_add_virt(pool, addr, -1, size, nid);
  }
  extern void gen_pool_destroy(struct gen_pool *);
 -extern unsigned long gen_pool_alloc(struct gen_pool *, size_t);
 -extern unsigned long gen_pool_alloc_algo(struct gen_pool *, size_t,
 -              genpool_algo_t algo, void *data);
 +unsigned long gen_pool_alloc_algo_owner(struct gen_pool *pool, size_t size,
 +              genpool_algo_t algo, void *data, void **owner);
 +
 +static inline unsigned long gen_pool_alloc_owner(struct gen_pool *pool,
 +              size_t size, void **owner)
 +{
 +      return gen_pool_alloc_algo_owner(pool, size, pool->algo, pool->data,
 +                      owner);
 +}
 +
 +static inline unsigned long gen_pool_alloc_algo(struct gen_pool *pool,
 +              size_t size, genpool_algo_t algo, void *data)
 +{
 +      return gen_pool_alloc_algo_owner(pool, size, algo, data, NULL);
 +}
 +
 +/**
 + * gen_pool_alloc - allocate special memory from the pool
 + * @pool: pool to allocate from
 + * @size: number of bytes to allocate from the pool
 + *
 + * Allocate the requested number of bytes from the specified pool.
 + * Uses the pool allocation function (with first-fit algorithm by default).
 + * Can not be used in NMI handler on architectures without
 + * NMI-safe cmpxchg implementation.
 + */
 +static inline unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size)
 +{
 +      return gen_pool_alloc_algo(pool, size, pool->algo, pool->data);
 +}
 +
  extern void *gen_pool_dma_alloc(struct gen_pool *pool, size_t size,
                dma_addr_t *dma);
 -extern void gen_pool_free(struct gen_pool *, unsigned long, size_t);
+ extern void *gen_pool_dma_alloc_algo(struct gen_pool *pool, size_t size,
+               dma_addr_t *dma, genpool_algo_t algo, void *data);
+ extern void *gen_pool_dma_alloc_align(struct gen_pool *pool, size_t size,
+               dma_addr_t *dma, int align);
+ extern void *gen_pool_dma_zalloc(struct gen_pool *pool, size_t size, dma_addr_t *dma);
+ extern void *gen_pool_dma_zalloc_algo(struct gen_pool *pool, size_t size,
+               dma_addr_t *dma, genpool_algo_t algo, void *data);
+ extern void *gen_pool_dma_zalloc_align(struct gen_pool *pool, size_t size,
+               dma_addr_t *dma, int align);
 +extern void gen_pool_free_owner(struct gen_pool *pool, unsigned long addr,
 +              size_t size, void **owner);
 +static inline void gen_pool_free(struct gen_pool *pool, unsigned long addr,
 +                size_t size)
 +{
 +      gen_pool_free_owner(pool, addr, size, NULL);
 +}
 +
  extern void gen_pool_for_each_chunk(struct gen_pool *,
        void (*)(struct gen_pool *, struct gen_pool_chunk *, void *), void *);
  extern size_t gen_pool_avail(struct gen_pool *);
diff --combined lib/genalloc.c
index 5257f74fccf3cf97951bfb150700424ea3c129dc,512623fbac51131ab824abcbc9c8dec67ffafc1f..9fc31292cfa1d0f458116f446e49926e36ed4a6e
@@@ -1,4 -1,3 +1,4 @@@
 +// SPDX-License-Identifier: GPL-2.0-only
  /*
   * Basic general purpose allocator for managing special purpose
   * memory, for example, memory that is not managed by the regular
@@@ -24,6 -23,9 +24,6 @@@
   * CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG.
   *
   * Copyright 2005 (C) Jes Sorensen <jes@trained-monkey.org>
 - *
 - * This source code is licensed under the GNU General Public License,
 - * Version 2.  See the file COPYING for more details.
   */
  
  #include <linux/slab.h>
@@@ -166,21 -168,20 +166,21 @@@ struct gen_pool *gen_pool_create(int mi
  EXPORT_SYMBOL(gen_pool_create);
  
  /**
 - * gen_pool_add_virt - add a new chunk of special memory to the pool
 + * gen_pool_add_owner- add a new chunk of special memory to the pool
   * @pool: pool to add new memory chunk to
   * @virt: virtual starting address of memory chunk to add to pool
   * @phys: physical starting address of memory chunk to add to pool
   * @size: size in bytes of the memory chunk to add to pool
   * @nid: node id of the node the chunk structure and bitmap should be
   *       allocated on, or -1
 + * @owner: private data the publisher would like to recall at alloc time
   *
   * Add a new chunk of special memory to the specified pool.
   *
   * Returns 0 on success or a -ve errno on failure.
   */
 -int gen_pool_add_virt(struct gen_pool *pool, unsigned long virt, phys_addr_t phys,
 -               size_t size, int nid)
 +int gen_pool_add_owner(struct gen_pool *pool, unsigned long virt, phys_addr_t phys,
 +               size_t size, int nid, void *owner)
  {
        struct gen_pool_chunk *chunk;
        int nbits = size >> pool->min_alloc_order;
        chunk->phys_addr = phys;
        chunk->start_addr = virt;
        chunk->end_addr = virt + size - 1;
 +      chunk->owner = owner;
        atomic_long_set(&chunk->avail, size);
  
        spin_lock(&pool->lock);
  
        return 0;
  }
 -EXPORT_SYMBOL(gen_pool_add_virt);
 +EXPORT_SYMBOL(gen_pool_add_owner);
  
  /**
   * gen_pool_virt_to_phys - return the physical address of memory
@@@ -260,20 -260,35 +260,20 @@@ void gen_pool_destroy(struct gen_pool *
  EXPORT_SYMBOL(gen_pool_destroy);
  
  /**
 - * gen_pool_alloc - allocate special memory from the pool
 - * @pool: pool to allocate from
 - * @size: number of bytes to allocate from the pool
 - *
 - * Allocate the requested number of bytes from the specified pool.
 - * Uses the pool allocation function (with first-fit algorithm by default).
 - * Can not be used in NMI handler on architectures without
 - * NMI-safe cmpxchg implementation.
 - */
 -unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size)
 -{
 -      return gen_pool_alloc_algo(pool, size, pool->algo, pool->data);
 -}
 -EXPORT_SYMBOL(gen_pool_alloc);
 -
 -/**
 - * gen_pool_alloc_algo - allocate special memory from the pool
 + * gen_pool_alloc_algo_owner - allocate special memory from the pool
   * @pool: pool to allocate from
   * @size: number of bytes to allocate from the pool
   * @algo: algorithm passed from caller
   * @data: data passed to algorithm
 + * @owner: optionally retrieve the chunk owner
   *
   * Allocate the requested number of bytes from the specified pool.
   * Uses the pool allocation function (with first-fit algorithm by default).
   * Can not be used in NMI handler on architectures without
   * NMI-safe cmpxchg implementation.
   */
 -unsigned long gen_pool_alloc_algo(struct gen_pool *pool, size_t size,
 -              genpool_algo_t algo, void *data)
 +unsigned long gen_pool_alloc_algo_owner(struct gen_pool *pool, size_t size,
 +              genpool_algo_t algo, void *data, void **owner)
  {
        struct gen_pool_chunk *chunk;
        unsigned long addr = 0;
        BUG_ON(in_nmi());
  #endif
  
 +      if (owner)
 +              *owner = NULL;
 +
        if (size == 0)
                return 0;
  
@@@ -314,34 -326,56 +314,58 @@@ retry
                addr = chunk->start_addr + ((unsigned long)start_bit << order);
                size = nbits << order;
                atomic_long_sub(size, &chunk->avail);
 +              if (owner)
 +                      *owner = chunk->owner;
                break;
        }
        rcu_read_unlock();
        return addr;
  }
 -EXPORT_SYMBOL(gen_pool_alloc_algo);
 +EXPORT_SYMBOL(gen_pool_alloc_algo_owner);
  
  /**
   * gen_pool_dma_alloc - allocate special memory from the pool for DMA usage
   * @pool: pool to allocate from
   * @size: number of bytes to allocate from the pool
-  * @dma: dma-view physical address return value.  Use NULL if unneeded.
+  * @dma: dma-view physical address return value.  Use %NULL if unneeded.
   *
   * Allocate the requested number of bytes from the specified pool.
   * Uses the pool allocation function (with first-fit algorithm by default).
   * Can not be used in NMI handler on architectures without
   * NMI-safe cmpxchg implementation.
+  *
+  * Return: virtual address of the allocated memory, or %NULL on failure
   */
  void *gen_pool_dma_alloc(struct gen_pool *pool, size_t size, dma_addr_t *dma)
+ {
+       return gen_pool_dma_alloc_algo(pool, size, dma, pool->algo, pool->data);
+ }
+ EXPORT_SYMBOL(gen_pool_dma_alloc);
+ /**
+  * gen_pool_dma_alloc_algo - allocate special memory from the pool for DMA
+  * usage with the given pool algorithm
+  * @pool: pool to allocate from
+  * @size: number of bytes to allocate from the pool
+  * @dma: DMA-view physical address return value. Use %NULL if unneeded.
+  * @algo: algorithm passed from caller
+  * @data: data passed to algorithm
+  *
+  * Allocate the requested number of bytes from the specified pool. Uses the
+  * given pool allocation function. Can not be used in NMI handler on
+  * architectures without NMI-safe cmpxchg implementation.
+  *
+  * Return: virtual address of the allocated memory, or %NULL on failure
+  */
+ void *gen_pool_dma_alloc_algo(struct gen_pool *pool, size_t size,
+               dma_addr_t *dma, genpool_algo_t algo, void *data)
  {
        unsigned long vaddr;
  
        if (!pool)
                return NULL;
  
-       vaddr = gen_pool_alloc(pool, size);
+       vaddr = gen_pool_alloc_algo(pool, size, algo, data);
        if (!vaddr)
                return NULL;
  
  
        return (void *)vaddr;
  }
- EXPORT_SYMBOL(gen_pool_dma_alloc);
+ EXPORT_SYMBOL(gen_pool_dma_alloc_algo);
+ /**
+  * gen_pool_dma_alloc_align - allocate special memory from the pool for DMA
+  * usage with the given alignment
+  * @pool: pool to allocate from
+  * @size: number of bytes to allocate from the pool
+  * @dma: DMA-view physical address return value. Use %NULL if unneeded.
+  * @align: alignment in bytes for starting address
+  *
+  * Allocate the requested number bytes from the specified pool, with the given
+  * alignment restriction. Can not be used in NMI handler on architectures
+  * without NMI-safe cmpxchg implementation.
+  *
+  * Return: virtual address of the allocated memory, or %NULL on failure
+  */
+ void *gen_pool_dma_alloc_align(struct gen_pool *pool, size_t size,
+               dma_addr_t *dma, int align)
+ {
+       struct genpool_data_align data = { .align = align };
+       return gen_pool_dma_alloc_algo(pool, size, dma,
+                       gen_pool_first_fit_align, &data);
+ }
+ EXPORT_SYMBOL(gen_pool_dma_alloc_align);
+ /**
+  * gen_pool_dma_zalloc - allocate special zeroed memory from the pool for
+  * DMA usage
+  * @pool: pool to allocate from
+  * @size: number of bytes to allocate from the pool
+  * @dma: dma-view physical address return value.  Use %NULL if unneeded.
+  *
+  * Allocate the requested number of zeroed bytes from the specified pool.
+  * Uses the pool allocation function (with first-fit algorithm by default).
+  * Can not be used in NMI handler on architectures without
+  * NMI-safe cmpxchg implementation.
+  *
+  * Return: virtual address of the allocated zeroed memory, or %NULL on failure
+  */
+ void *gen_pool_dma_zalloc(struct gen_pool *pool, size_t size, dma_addr_t *dma)
+ {
+       return gen_pool_dma_zalloc_algo(pool, size, dma, pool->algo, pool->data);
+ }
+ EXPORT_SYMBOL(gen_pool_dma_zalloc);
+ /**
+  * gen_pool_dma_zalloc_algo - allocate special zeroed memory from the pool for
+  * DMA usage with the given pool algorithm
+  * @pool: pool to allocate from
+  * @size: number of bytes to allocate from the pool
+  * @dma: DMA-view physical address return value. Use %NULL if unneeded.
+  * @algo: algorithm passed from caller
+  * @data: data passed to algorithm
+  *
+  * Allocate the requested number of zeroed bytes from the specified pool. Uses
+  * the given pool allocation function. Can not be used in NMI handler on
+  * architectures without NMI-safe cmpxchg implementation.
+  *
+  * Return: virtual address of the allocated zeroed memory, or %NULL on failure
+  */
+ void *gen_pool_dma_zalloc_algo(struct gen_pool *pool, size_t size,
+               dma_addr_t *dma, genpool_algo_t algo, void *data)
+ {
+       void *vaddr = gen_pool_dma_alloc_algo(pool, size, dma, algo, data);
+       if (vaddr)
+               memset(vaddr, 0, size);
+       return vaddr;
+ }
+ EXPORT_SYMBOL(gen_pool_dma_zalloc_algo);
+ /**
+  * gen_pool_dma_zalloc_align - allocate special zeroed memory from the pool for
+  * DMA usage with the given alignment
+  * @pool: pool to allocate from
+  * @size: number of bytes to allocate from the pool
+  * @dma: DMA-view physical address return value. Use %NULL if unneeded.
+  * @align: alignment in bytes for starting address
+  *
+  * Allocate the requested number of zeroed bytes from the specified pool,
+  * with the given alignment restriction. Can not be used in NMI handler on
+  * architectures without NMI-safe cmpxchg implementation.
+  *
+  * Return: virtual address of the allocated zeroed memory, or %NULL on failure
+  */
+ void *gen_pool_dma_zalloc_align(struct gen_pool *pool, size_t size,
+               dma_addr_t *dma, int align)
+ {
+       struct genpool_data_align data = { .align = align };
+       return gen_pool_dma_zalloc_algo(pool, size, dma,
+                       gen_pool_first_fit_align, &data);
+ }
+ EXPORT_SYMBOL(gen_pool_dma_zalloc_align);
  
  /**
   * gen_pool_free - free allocated special memory back to the pool
   * @pool: pool to free to
   * @addr: starting address of memory to free back to pool
   * @size: size in bytes of memory to free
 + * @owner: private data stashed at gen_pool_add() time
   *
   * Free previously allocated special memory back to the specified
   * pool.  Can not be used in NMI handler on architectures without
   * NMI-safe cmpxchg implementation.
   */
 -void gen_pool_free(struct gen_pool *pool, unsigned long addr, size_t size)
 +void gen_pool_free_owner(struct gen_pool *pool, unsigned long addr, size_t size,
 +              void **owner)
  {
        struct gen_pool_chunk *chunk;
        int order = pool->min_alloc_order;
        BUG_ON(in_nmi());
  #endif
  
 +      if (owner)
 +              *owner = NULL;
 +
        nbits = (size + (1UL << order) - 1) >> order;
        rcu_read_lock();
        list_for_each_entry_rcu(chunk, &pool->chunks, next_chunk) {
                        BUG_ON(remain);
                        size = nbits << order;
                        atomic_long_add(size, &chunk->avail);
 +                      if (owner)
 +                              *owner = chunk->owner;
                        rcu_read_unlock();
                        return;
                }
        rcu_read_unlock();
        BUG();
  }
 -EXPORT_SYMBOL(gen_pool_free);
 +EXPORT_SYMBOL(gen_pool_free_owner);
  
  /**
   * gen_pool_for_each_chunk - call func for every chunk of generic memory pool