LCOV - code coverage report
Current view: top level - mm - dmapool.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 182 0.0 %
Date: 2022-04-01 14:58:12 Functions: 0 10 0.0 %
Branches: 0 84 0.0 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0-only
       2                 :            : /*
       3                 :            :  * DMA Pool allocator
       4                 :            :  *
       5                 :            :  * Copyright 2001 David Brownell
       6                 :            :  * Copyright 2007 Intel Corporation
       7                 :            :  *   Author: Matthew Wilcox <willy@linux.intel.com>
       8                 :            :  *
       9                 :            :  * This allocator returns small blocks of a given size which are DMA-able by
      10                 :            :  * the given device.  It uses the dma_alloc_coherent page allocator to get
      11                 :            :  * new pages, then splits them up into blocks of the required size.
      12                 :            :  * Many older drivers still have their own code to do this.
      13                 :            :  *
      14                 :            :  * The current design of this allocator is fairly simple.  The pool is
      15                 :            :  * represented by the 'struct dma_pool' which keeps a doubly-linked list of
      16                 :            :  * allocated pages.  Each page in the page_list is split into blocks of at
      17                 :            :  * least 'size' bytes.  Free blocks are tracked in an unsorted singly-linked
      18                 :            :  * list of free blocks within the page.  Used blocks aren't tracked, but we
      19                 :            :  * keep a count of how many are currently allocated from each page.
      20                 :            :  */
      21                 :            : 
      22                 :            : #include <linux/device.h>
      23                 :            : #include <linux/dma-mapping.h>
      24                 :            : #include <linux/dmapool.h>
      25                 :            : #include <linux/kernel.h>
      26                 :            : #include <linux/list.h>
      27                 :            : #include <linux/export.h>
      28                 :            : #include <linux/mutex.h>
      29                 :            : #include <linux/poison.h>
      30                 :            : #include <linux/sched.h>
      31                 :            : #include <linux/slab.h>
      32                 :            : #include <linux/stat.h>
      33                 :            : #include <linux/spinlock.h>
      34                 :            : #include <linux/string.h>
      35                 :            : #include <linux/types.h>
      36                 :            : #include <linux/wait.h>
      37                 :            : 
      38                 :            : #if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_SLUB_DEBUG_ON)
      39                 :            : #define DMAPOOL_DEBUG 1
      40                 :            : #endif
      41                 :            : 
      42                 :            : struct dma_pool {               /* the pool */
      43                 :            :         struct list_head page_list;
      44                 :            :         spinlock_t lock;
      45                 :            :         size_t size;
      46                 :            :         struct device *dev;
      47                 :            :         size_t allocation;
      48                 :            :         size_t boundary;
      49                 :            :         char name[32];
      50                 :            :         struct list_head pools;
      51                 :            : };
      52                 :            : 
      53                 :            : struct dma_page {               /* cacheable header for 'allocation' bytes */
      54                 :            :         struct list_head page_list;
      55                 :            :         void *vaddr;
      56                 :            :         dma_addr_t dma;
      57                 :            :         unsigned int in_use;
      58                 :            :         unsigned int offset;
      59                 :            : };
      60                 :            : 
      61                 :            : static DEFINE_MUTEX(pools_lock);
      62                 :            : static DEFINE_MUTEX(pools_reg_lock);
      63                 :            : 
      64                 :            : static ssize_t
      65                 :          0 : show_pools(struct device *dev, struct device_attribute *attr, char *buf)
      66                 :            : {
      67                 :          0 :         unsigned temp;
      68                 :          0 :         unsigned size;
      69                 :          0 :         char *next;
      70                 :          0 :         struct dma_page *page;
      71                 :          0 :         struct dma_pool *pool;
      72                 :            : 
      73                 :          0 :         next = buf;
      74                 :          0 :         size = PAGE_SIZE;
      75                 :            : 
      76                 :          0 :         temp = scnprintf(next, size, "poolinfo - 0.1\n");
      77                 :          0 :         size -= temp;
      78                 :          0 :         next += temp;
      79                 :            : 
      80                 :          0 :         mutex_lock(&pools_lock);
      81         [ #  # ]:          0 :         list_for_each_entry(pool, &dev->dma_pools, pools) {
      82                 :          0 :                 unsigned pages = 0;
      83                 :          0 :                 unsigned blocks = 0;
      84                 :            : 
      85                 :          0 :                 spin_lock_irq(&pool->lock);
      86         [ #  # ]:          0 :                 list_for_each_entry(page, &pool->page_list, page_list) {
      87                 :          0 :                         pages++;
      88                 :          0 :                         blocks += page->in_use;
      89                 :            :                 }
      90                 :          0 :                 spin_unlock_irq(&pool->lock);
      91                 :            : 
      92                 :            :                 /* per-pool info, no real statistics yet */
      93                 :          0 :                 temp = scnprintf(next, size, "%-16s %4u %4zu %4zu %2u\n",
      94                 :          0 :                                  pool->name, blocks,
      95                 :          0 :                                  pages * (pool->allocation / pool->size),
      96                 :            :                                  pool->size, pages);
      97                 :          0 :                 size -= temp;
      98                 :          0 :                 next += temp;
      99                 :            :         }
     100                 :          0 :         mutex_unlock(&pools_lock);
     101                 :            : 
     102                 :          0 :         return PAGE_SIZE - size;
     103                 :            : }
     104                 :            : 
     105                 :            : static DEVICE_ATTR(pools, 0444, show_pools, NULL);
     106                 :            : 
     107                 :            : /**
     108                 :            :  * dma_pool_create - Creates a pool of consistent memory blocks, for dma.
     109                 :            :  * @name: name of pool, for diagnostics
     110                 :            :  * @dev: device that will be doing the DMA
     111                 :            :  * @size: size of the blocks in this pool.
     112                 :            :  * @align: alignment requirement for blocks; must be a power of two
     113                 :            :  * @boundary: returned blocks won't cross this power of two boundary
     114                 :            :  * Context: not in_interrupt()
     115                 :            :  *
     116                 :            :  * Given one of these pools, dma_pool_alloc()
     117                 :            :  * may be used to allocate memory.  Such memory will all have "consistent"
     118                 :            :  * DMA mappings, accessible by the device and its driver without using
     119                 :            :  * cache flushing primitives.  The actual size of blocks allocated may be
     120                 :            :  * larger than requested because of alignment.
     121                 :            :  *
     122                 :            :  * If @boundary is nonzero, objects returned from dma_pool_alloc() won't
     123                 :            :  * cross that size boundary.  This is useful for devices which have
     124                 :            :  * addressing restrictions on individual DMA transfers, such as not crossing
     125                 :            :  * boundaries of 4KBytes.
     126                 :            :  *
     127                 :            :  * Return: a dma allocation pool with the requested characteristics, or
     128                 :            :  * %NULL if one can't be created.
     129                 :            :  */
     130                 :          0 : struct dma_pool *dma_pool_create(const char *name, struct device *dev,
     131                 :            :                                  size_t size, size_t align, size_t boundary)
     132                 :            : {
     133                 :          0 :         struct dma_pool *retval;
     134                 :          0 :         size_t allocation;
     135                 :          0 :         bool empty = false;
     136                 :            : 
     137         [ #  # ]:          0 :         if (align == 0)
     138                 :            :                 align = 1;
     139         [ #  # ]:          0 :         else if (align & (align - 1))
     140                 :            :                 return NULL;
     141                 :            : 
     142         [ #  # ]:          0 :         if (size == 0)
     143                 :            :                 return NULL;
     144                 :          0 :         else if (size < 4)
     145                 :            :                 size = 4;
     146                 :            : 
     147         [ #  # ]:          0 :         if ((size % align) != 0)
     148                 :          0 :                 size = ALIGN(size, align);
     149                 :            : 
     150                 :          0 :         allocation = max_t(size_t, size, PAGE_SIZE);
     151                 :            : 
     152         [ #  # ]:          0 :         if (!boundary)
     153                 :            :                 boundary = allocation;
     154   [ #  #  #  # ]:          0 :         else if ((boundary < size) || (boundary & (boundary - 1)))
     155                 :            :                 return NULL;
     156                 :            : 
     157                 :          0 :         retval = kmalloc_node(sizeof(*retval), GFP_KERNEL, dev_to_node(dev));
     158         [ #  # ]:          0 :         if (!retval)
     159                 :            :                 return retval;
     160                 :            : 
     161                 :          0 :         strlcpy(retval->name, name, sizeof(retval->name));
     162                 :            : 
     163                 :          0 :         retval->dev = dev;
     164                 :            : 
     165                 :          0 :         INIT_LIST_HEAD(&retval->page_list);
     166                 :          0 :         spin_lock_init(&retval->lock);
     167                 :          0 :         retval->size = size;
     168                 :          0 :         retval->boundary = boundary;
     169                 :          0 :         retval->allocation = allocation;
     170                 :            : 
     171                 :          0 :         INIT_LIST_HEAD(&retval->pools);
     172                 :            : 
     173                 :            :         /*
     174                 :            :          * pools_lock ensures that the ->dma_pools list does not get corrupted.
     175                 :            :          * pools_reg_lock ensures that there is not a race between
     176                 :            :          * dma_pool_create() and dma_pool_destroy() or within dma_pool_create()
     177                 :            :          * when the first invocation of dma_pool_create() failed on
     178                 :            :          * device_create_file() and the second assumes that it has been done (I
     179                 :            :          * know it is a short window).
     180                 :            :          */
     181                 :          0 :         mutex_lock(&pools_reg_lock);
     182                 :          0 :         mutex_lock(&pools_lock);
     183         [ #  # ]:          0 :         if (list_empty(&dev->dma_pools))
     184                 :          0 :                 empty = true;
     185                 :          0 :         list_add(&retval->pools, &dev->dma_pools);
     186                 :          0 :         mutex_unlock(&pools_lock);
     187         [ #  # ]:          0 :         if (empty) {
     188                 :          0 :                 int err;
     189                 :            : 
     190                 :          0 :                 err = device_create_file(dev, &dev_attr_pools);
     191         [ #  # ]:          0 :                 if (err) {
     192                 :          0 :                         mutex_lock(&pools_lock);
     193                 :          0 :                         list_del(&retval->pools);
     194                 :          0 :                         mutex_unlock(&pools_lock);
     195                 :          0 :                         mutex_unlock(&pools_reg_lock);
     196                 :          0 :                         kfree(retval);
     197                 :          0 :                         return NULL;
     198                 :            :                 }
     199                 :            :         }
     200                 :          0 :         mutex_unlock(&pools_reg_lock);
     201                 :          0 :         return retval;
     202                 :            : }
     203                 :            : EXPORT_SYMBOL(dma_pool_create);
     204                 :            : 
     205                 :          0 : static void pool_initialise_page(struct dma_pool *pool, struct dma_page *page)
     206                 :            : {
     207                 :          0 :         unsigned int offset = 0;
     208                 :          0 :         unsigned int next_boundary = pool->boundary;
     209                 :            : 
     210                 :          0 :         do {
     211                 :          0 :                 unsigned int next = offset + pool->size;
     212         [ #  # ]:          0 :                 if (unlikely((next + pool->size) >= next_boundary)) {
     213                 :          0 :                         next = next_boundary;
     214                 :          0 :                         next_boundary += pool->boundary;
     215                 :            :                 }
     216                 :          0 :                 *(int *)(page->vaddr + offset) = next;
     217                 :          0 :                 offset = next;
     218         [ #  # ]:          0 :         } while (offset < pool->allocation);
     219                 :            : }
     220                 :            : 
     221                 :          0 : static struct dma_page *pool_alloc_page(struct dma_pool *pool, gfp_t mem_flags)
     222                 :            : {
     223                 :          0 :         struct dma_page *page;
     224                 :            : 
     225         [ #  # ]:          0 :         page = kmalloc(sizeof(*page), mem_flags);
     226         [ #  # ]:          0 :         if (!page)
     227                 :            :                 return NULL;
     228                 :          0 :         page->vaddr = dma_alloc_coherent(pool->dev, pool->allocation,
     229                 :            :                                          &page->dma, mem_flags);
     230         [ #  # ]:          0 :         if (page->vaddr) {
     231                 :            : #ifdef  DMAPOOL_DEBUG
     232                 :            :                 memset(page->vaddr, POOL_POISON_FREED, pool->allocation);
     233                 :            : #endif
     234                 :          0 :                 pool_initialise_page(pool, page);
     235                 :          0 :                 page->in_use = 0;
     236                 :          0 :                 page->offset = 0;
     237                 :            :         } else {
     238                 :          0 :                 kfree(page);
     239                 :          0 :                 page = NULL;
     240                 :            :         }
     241                 :            :         return page;
     242                 :            : }
     243                 :            : 
     244                 :          0 : static inline bool is_page_busy(struct dma_page *page)
     245                 :            : {
     246                 :          0 :         return page->in_use != 0;
     247                 :            : }
     248                 :            : 
     249                 :            : static void pool_free_page(struct dma_pool *pool, struct dma_page *page)
     250                 :            : {
     251                 :            :         dma_addr_t dma = page->dma;
     252                 :            : 
     253                 :            : #ifdef  DMAPOOL_DEBUG
     254                 :            :         memset(page->vaddr, POOL_POISON_FREED, pool->allocation);
     255                 :            : #endif
     256                 :            :         dma_free_coherent(pool->dev, pool->allocation, page->vaddr, dma);
     257                 :            :         list_del(&page->page_list);
     258                 :            :         kfree(page);
     259                 :            : }
     260                 :            : 
     261                 :            : /**
     262                 :            :  * dma_pool_destroy - destroys a pool of dma memory blocks.
     263                 :            :  * @pool: dma pool that will be destroyed
     264                 :            :  * Context: !in_interrupt()
     265                 :            :  *
     266                 :            :  * Caller guarantees that no more memory from the pool is in use,
     267                 :            :  * and that nothing will try to use the pool after this call.
     268                 :            :  */
     269                 :          0 : void dma_pool_destroy(struct dma_pool *pool)
     270                 :            : {
     271                 :          0 :         bool empty = false;
     272                 :            : 
     273         [ #  # ]:          0 :         if (unlikely(!pool))
     274                 :            :                 return;
     275                 :            : 
     276                 :          0 :         mutex_lock(&pools_reg_lock);
     277                 :          0 :         mutex_lock(&pools_lock);
     278         [ #  # ]:          0 :         list_del(&pool->pools);
     279   [ #  #  #  # ]:          0 :         if (pool->dev && list_empty(&pool->dev->dma_pools))
     280                 :          0 :                 empty = true;
     281                 :          0 :         mutex_unlock(&pools_lock);
     282         [ #  # ]:          0 :         if (empty)
     283                 :          0 :                 device_remove_file(pool->dev, &dev_attr_pools);
     284                 :          0 :         mutex_unlock(&pools_reg_lock);
     285                 :            : 
     286         [ #  # ]:          0 :         while (!list_empty(&pool->page_list)) {
     287                 :          0 :                 struct dma_page *page;
     288                 :          0 :                 page = list_entry(pool->page_list.next,
     289                 :            :                                   struct dma_page, page_list);
     290         [ #  # ]:          0 :                 if (is_page_busy(page)) {
     291         [ #  # ]:          0 :                         if (pool->dev)
     292                 :          0 :                                 dev_err(pool->dev,
     293                 :            :                                         "dma_pool_destroy %s, %p busy\n",
     294                 :            :                                         pool->name, page->vaddr);
     295                 :            :                         else
     296                 :          0 :                                 pr_err("dma_pool_destroy %s, %p busy\n",
     297                 :            :                                        pool->name, page->vaddr);
     298                 :            :                         /* leak the still-in-use consistent memory */
     299                 :          0 :                         list_del(&page->page_list);
     300                 :          0 :                         kfree(page);
     301                 :            :                 } else
     302                 :          0 :                         pool_free_page(pool, page);
     303                 :            :         }
     304                 :            : 
     305                 :          0 :         kfree(pool);
     306                 :            : }
     307                 :            : EXPORT_SYMBOL(dma_pool_destroy);
     308                 :            : 
     309                 :            : /**
     310                 :            :  * dma_pool_alloc - get a block of consistent memory
     311                 :            :  * @pool: dma pool that will produce the block
     312                 :            :  * @mem_flags: GFP_* bitmask
     313                 :            :  * @handle: pointer to dma address of block
     314                 :            :  *
     315                 :            :  * Return: the kernel virtual address of a currently unused block,
     316                 :            :  * and reports its dma address through the handle.
     317                 :            :  * If such a memory block can't be allocated, %NULL is returned.
     318                 :            :  */
     319                 :          0 : void *dma_pool_alloc(struct dma_pool *pool, gfp_t mem_flags,
     320                 :            :                      dma_addr_t *handle)
     321                 :            : {
     322                 :          0 :         unsigned long flags;
     323                 :          0 :         struct dma_page *page;
     324                 :          0 :         size_t offset;
     325                 :          0 :         void *retval;
     326                 :            : 
     327         [ #  # ]:          0 :         might_sleep_if(gfpflags_allow_blocking(mem_flags));
     328                 :            : 
     329                 :          0 :         spin_lock_irqsave(&pool->lock, flags);
     330         [ #  # ]:          0 :         list_for_each_entry(page, &pool->page_list, page_list) {
     331         [ #  # ]:          0 :                 if (page->offset < pool->allocation)
     332                 :          0 :                         goto ready;
     333                 :            :         }
     334                 :            : 
     335                 :            :         /* pool_alloc_page() might sleep, so temporarily drop &pool->lock */
     336                 :          0 :         spin_unlock_irqrestore(&pool->lock, flags);
     337                 :            : 
     338                 :          0 :         page = pool_alloc_page(pool, mem_flags & (~__GFP_ZERO));
     339         [ #  # ]:          0 :         if (!page)
     340                 :            :                 return NULL;
     341                 :            : 
     342                 :          0 :         spin_lock_irqsave(&pool->lock, flags);
     343                 :            : 
     344                 :          0 :         list_add(&page->page_list, &pool->page_list);
     345                 :          0 :  ready:
     346                 :          0 :         page->in_use++;
     347                 :          0 :         offset = page->offset;
     348                 :          0 :         page->offset = *(int *)(page->vaddr + offset);
     349                 :          0 :         retval = offset + page->vaddr;
     350                 :          0 :         *handle = offset + page->dma;
     351                 :            : #ifdef  DMAPOOL_DEBUG
     352                 :            :         {
     353                 :            :                 int i;
     354                 :            :                 u8 *data = retval;
     355                 :            :                 /* page->offset is stored in first 4 bytes */
     356                 :            :                 for (i = sizeof(page->offset); i < pool->size; i++) {
     357                 :            :                         if (data[i] == POOL_POISON_FREED)
     358                 :            :                                 continue;
     359                 :            :                         if (pool->dev)
     360                 :            :                                 dev_err(pool->dev,
     361                 :            :                                         "dma_pool_alloc %s, %p (corrupted)\n",
     362                 :            :                                         pool->name, retval);
     363                 :            :                         else
     364                 :            :                                 pr_err("dma_pool_alloc %s, %p (corrupted)\n",
     365                 :            :                                         pool->name, retval);
     366                 :            : 
     367                 :            :                         /*
     368                 :            :                          * Dump the first 4 bytes even if they are not
     369                 :            :                          * POOL_POISON_FREED
     370                 :            :                          */
     371                 :            :                         print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 16, 1,
     372                 :            :                                         data, pool->size, 1);
     373                 :            :                         break;
     374                 :            :                 }
     375                 :            :         }
     376                 :            :         if (!(mem_flags & __GFP_ZERO))
     377                 :            :                 memset(retval, POOL_POISON_ALLOCATED, pool->size);
     378                 :            : #endif
     379                 :          0 :         spin_unlock_irqrestore(&pool->lock, flags);
     380                 :            : 
     381   [ #  #  #  # ]:          0 :         if (want_init_on_alloc(mem_flags))
     382                 :          0 :                 memset(retval, 0, pool->size);
     383                 :            : 
     384                 :            :         return retval;
     385                 :            : }
     386                 :            : EXPORT_SYMBOL(dma_pool_alloc);
     387                 :            : 
     388                 :          0 : static struct dma_page *pool_find_page(struct dma_pool *pool, dma_addr_t dma)
     389                 :            : {
     390                 :          0 :         struct dma_page *page;
     391                 :            : 
     392         [ #  # ]:          0 :         list_for_each_entry(page, &pool->page_list, page_list) {
     393         [ #  # ]:          0 :                 if (dma < page->dma)
     394                 :          0 :                         continue;
     395         [ #  # ]:          0 :                 if ((dma - page->dma) < pool->allocation)
     396                 :            :                         return page;
     397                 :            :         }
     398                 :            :         return NULL;
     399                 :            : }
     400                 :            : 
     401                 :            : /**
     402                 :            :  * dma_pool_free - put block back into dma pool
     403                 :            :  * @pool: the dma pool holding the block
     404                 :            :  * @vaddr: virtual address of block
     405                 :            :  * @dma: dma address of block
     406                 :            :  *
     407                 :            :  * Caller promises neither device nor driver will again touch this block
     408                 :            :  * unless it is first re-allocated.
     409                 :            :  */
     410                 :          0 : void dma_pool_free(struct dma_pool *pool, void *vaddr, dma_addr_t dma)
     411                 :            : {
     412                 :          0 :         struct dma_page *page;
     413                 :          0 :         unsigned long flags;
     414                 :          0 :         unsigned int offset;
     415                 :            : 
     416                 :          0 :         spin_lock_irqsave(&pool->lock, flags);
     417                 :          0 :         page = pool_find_page(pool, dma);
     418         [ #  # ]:          0 :         if (!page) {
     419                 :          0 :                 spin_unlock_irqrestore(&pool->lock, flags);
     420         [ #  # ]:          0 :                 if (pool->dev)
     421                 :          0 :                         dev_err(pool->dev,
     422                 :            :                                 "dma_pool_free %s, %p/%lx (bad dma)\n",
     423                 :            :                                 pool->name, vaddr, (unsigned long)dma);
     424                 :            :                 else
     425                 :          0 :                         pr_err("dma_pool_free %s, %p/%lx (bad dma)\n",
     426                 :            :                                pool->name, vaddr, (unsigned long)dma);
     427                 :          0 :                 return;
     428                 :            :         }
     429                 :            : 
     430                 :          0 :         offset = vaddr - page->vaddr;
     431   [ #  #  #  # ]:          0 :         if (want_init_on_free())
     432                 :          0 :                 memset(vaddr, 0, pool->size);
     433                 :            : #ifdef  DMAPOOL_DEBUG
     434                 :            :         if ((dma - page->dma) != offset) {
     435                 :            :                 spin_unlock_irqrestore(&pool->lock, flags);
     436                 :            :                 if (pool->dev)
     437                 :            :                         dev_err(pool->dev,
     438                 :            :                                 "dma_pool_free %s, %p (bad vaddr)/%pad\n",
     439                 :            :                                 pool->name, vaddr, &dma);
     440                 :            :                 else
     441                 :            :                         pr_err("dma_pool_free %s, %p (bad vaddr)/%pad\n",
     442                 :            :                                pool->name, vaddr, &dma);
     443                 :            :                 return;
     444                 :            :         }
     445                 :            :         {
     446                 :            :                 unsigned int chain = page->offset;
     447                 :            :                 while (chain < pool->allocation) {
     448                 :            :                         if (chain != offset) {
     449                 :            :                                 chain = *(int *)(page->vaddr + chain);
     450                 :            :                                 continue;
     451                 :            :                         }
     452                 :            :                         spin_unlock_irqrestore(&pool->lock, flags);
     453                 :            :                         if (pool->dev)
     454                 :            :                                 dev_err(pool->dev, "dma_pool_free %s, dma %pad already free\n",
     455                 :            :                                         pool->name, &dma);
     456                 :            :                         else
     457                 :            :                                 pr_err("dma_pool_free %s, dma %pad already free\n",
     458                 :            :                                        pool->name, &dma);
     459                 :            :                         return;
     460                 :            :                 }
     461                 :            :         }
     462                 :            :         memset(vaddr, POOL_POISON_FREED, pool->size);
     463                 :            : #endif
     464                 :            : 
     465                 :          0 :         page->in_use--;
     466                 :          0 :         *(int *)vaddr = page->offset;
     467                 :          0 :         page->offset = offset;
     468                 :            :         /*
     469                 :            :          * Resist a temptation to do
     470                 :            :          *    if (!is_page_busy(page)) pool_free_page(pool, page);
     471                 :            :          * Better have a few empty pages hang around.
     472                 :            :          */
     473                 :          0 :         spin_unlock_irqrestore(&pool->lock, flags);
     474                 :            : }
     475                 :            : EXPORT_SYMBOL(dma_pool_free);
     476                 :            : 
     477                 :            : /*
     478                 :            :  * Managed DMA pool
     479                 :            :  */
     480                 :          0 : static void dmam_pool_release(struct device *dev, void *res)
     481                 :            : {
     482                 :          0 :         struct dma_pool *pool = *(struct dma_pool **)res;
     483                 :            : 
     484                 :          0 :         dma_pool_destroy(pool);
     485                 :          0 : }
     486                 :            : 
     487                 :          0 : static int dmam_pool_match(struct device *dev, void *res, void *match_data)
     488                 :            : {
     489                 :          0 :         return *(struct dma_pool **)res == match_data;
     490                 :            : }
     491                 :            : 
     492                 :            : /**
     493                 :            :  * dmam_pool_create - Managed dma_pool_create()
     494                 :            :  * @name: name of pool, for diagnostics
     495                 :            :  * @dev: device that will be doing the DMA
     496                 :            :  * @size: size of the blocks in this pool.
     497                 :            :  * @align: alignment requirement for blocks; must be a power of two
     498                 :            :  * @allocation: returned blocks won't cross this boundary (or zero)
     499                 :            :  *
     500                 :            :  * Managed dma_pool_create().  DMA pool created with this function is
     501                 :            :  * automatically destroyed on driver detach.
     502                 :            :  *
     503                 :            :  * Return: a managed dma allocation pool with the requested
     504                 :            :  * characteristics, or %NULL if one can't be created.
     505                 :            :  */
     506                 :          0 : struct dma_pool *dmam_pool_create(const char *name, struct device *dev,
     507                 :            :                                   size_t size, size_t align, size_t allocation)
     508                 :            : {
     509                 :          0 :         struct dma_pool **ptr, *pool;
     510                 :            : 
     511                 :          0 :         ptr = devres_alloc(dmam_pool_release, sizeof(*ptr), GFP_KERNEL);
     512         [ #  # ]:          0 :         if (!ptr)
     513                 :            :                 return NULL;
     514                 :            : 
     515                 :          0 :         pool = *ptr = dma_pool_create(name, dev, size, align, allocation);
     516         [ #  # ]:          0 :         if (pool)
     517                 :          0 :                 devres_add(dev, ptr);
     518                 :            :         else
     519                 :          0 :                 devres_free(ptr);
     520                 :            : 
     521                 :            :         return pool;
     522                 :            : }
     523                 :            : EXPORT_SYMBOL(dmam_pool_create);
     524                 :            : 
     525                 :            : /**
     526                 :            :  * dmam_pool_destroy - Managed dma_pool_destroy()
     527                 :            :  * @pool: dma pool that will be destroyed
     528                 :            :  *
     529                 :            :  * Managed dma_pool_destroy().
     530                 :            :  */
     531                 :          0 : void dmam_pool_destroy(struct dma_pool *pool)
     532                 :            : {
     533                 :          0 :         struct device *dev = pool->dev;
     534                 :            : 
     535         [ #  # ]:          0 :         WARN_ON(devres_release(dev, dmam_pool_release, dmam_pool_match, pool));
     536                 :          0 : }
     537                 :            : EXPORT_SYMBOL(dmam_pool_destroy);

Generated by: LCOV version 1.14