root/arch/hexagon/kernel/dma.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. arch_dma_alloc
  2. arch_dma_free
  3. arch_sync_dma_for_device

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * DMA implementation for Hexagon
   4  *
   5  * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
   6  */
   7 
   8 #include <linux/dma-noncoherent.h>
   9 #include <linux/memblock.h>
  10 #include <linux/genalloc.h>
  11 #include <linux/module.h>
  12 #include <asm/page.h>
  13 
  14 static struct gen_pool *coherent_pool;
  15 
  16 
  17 /* Allocates from a pool of uncached memory that was reserved at boot time */
  18 
  19 void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_addr,
  20                 gfp_t flag, unsigned long attrs)
  21 {
  22         void *ret;
  23 
  24         /*
  25          * Our max_low_pfn should have been backed off by 16MB in
  26          * mm/init.c to create DMA coherent space.  Use that as the VA
  27          * for the pool.
  28          */
  29 
  30         if (coherent_pool == NULL) {
  31                 coherent_pool = gen_pool_create(PAGE_SHIFT, -1);
  32 
  33                 if (coherent_pool == NULL)
  34                         panic("Can't create %s() memory pool!", __func__);
  35                 else
  36                         gen_pool_add(coherent_pool,
  37                                 (unsigned long)pfn_to_virt(max_low_pfn),
  38                                 hexagon_coherent_pool_size, -1);
  39         }
  40 
  41         ret = (void *) gen_pool_alloc(coherent_pool, size);
  42 
  43         if (ret) {
  44                 memset(ret, 0, size);
  45                 *dma_addr = (dma_addr_t) virt_to_phys(ret);
  46         } else
  47                 *dma_addr = ~0;
  48 
  49         return ret;
  50 }
  51 
  52 void arch_dma_free(struct device *dev, size_t size, void *vaddr,
  53                 dma_addr_t dma_addr, unsigned long attrs)
  54 {
  55         gen_pool_free(coherent_pool, (unsigned long) vaddr, size);
  56 }
  57 
  58 void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr,
  59                 size_t size, enum dma_data_direction dir)
  60 {
  61         void *addr = phys_to_virt(paddr);
  62 
  63         switch (dir) {
  64         case DMA_TO_DEVICE:
  65                 hexagon_clean_dcache_range((unsigned long) addr,
  66                 (unsigned long) addr + size);
  67                 break;
  68         case DMA_FROM_DEVICE:
  69                 hexagon_inv_dcache_range((unsigned long) addr,
  70                 (unsigned long) addr + size);
  71                 break;
  72         case DMA_BIDIRECTIONAL:
  73                 flush_dcache_range((unsigned long) addr,
  74                 (unsigned long) addr + size);
  75                 break;
  76         default:
  77                 BUG();
  78         }
  79 }

/* [<][>][^][v][top][bottom][index][help] */