This source file includes following definitions.
- afu_mmio_region_init
- get_region_by_index
- afu_mmio_region_add
- afu_mmio_region_destroy
- afu_mmio_region_get_by_index
- afu_mmio_region_get_by_offset
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 #include "dfl-afu.h"
  12 
  13 
  14 
  15 
  16 
  17 void afu_mmio_region_init(struct dfl_feature_platform_data *pdata)
  18 {
  19         struct dfl_afu *afu = dfl_fpga_pdata_get_private(pdata);
  20 
  21         INIT_LIST_HEAD(&afu->regions);
  22 }
  23 
  24 #define for_each_region(region, afu)    \
  25         list_for_each_entry((region), &(afu)->regions, node)
  26 
  27 static struct dfl_afu_mmio_region *get_region_by_index(struct dfl_afu *afu,
  28                                                        u32 region_index)
  29 {
  30         struct dfl_afu_mmio_region *region;
  31 
  32         for_each_region(region, afu)
  33                 if (region->index == region_index)
  34                         return region;
  35 
  36         return NULL;
  37 }
  38 
  39 
  40 
  41 
  42 
  43 
  44 
  45 
  46 
  47 
  48 
  49 int afu_mmio_region_add(struct dfl_feature_platform_data *pdata,
  50                         u32 region_index, u64 region_size, u64 phys, u32 flags)
  51 {
  52         struct dfl_afu_mmio_region *region;
  53         struct dfl_afu *afu;
  54         int ret = 0;
  55 
  56         region = devm_kzalloc(&pdata->dev->dev, sizeof(*region), GFP_KERNEL);
  57         if (!region)
  58                 return -ENOMEM;
  59 
  60         region->index = region_index;
  61         region->size = region_size;
  62         region->phys = phys;
  63         region->flags = flags;
  64 
  65         mutex_lock(&pdata->lock);
  66 
  67         afu = dfl_fpga_pdata_get_private(pdata);
  68 
  69         
  70         if (get_region_by_index(afu, region_index)) {
  71                 mutex_unlock(&pdata->lock);
  72                 ret = -EEXIST;
  73                 goto exit;
  74         }
  75 
  76         region_size = PAGE_ALIGN(region_size);
  77         region->offset = afu->region_cur_offset;
  78         list_add(®ion->node, &afu->regions);
  79 
  80         afu->region_cur_offset += region_size;
  81         afu->num_regions++;
  82         mutex_unlock(&pdata->lock);
  83 
  84         return 0;
  85 
  86 exit:
  87         devm_kfree(&pdata->dev->dev, region);
  88         return ret;
  89 }
  90 
  91 
  92 
  93 
  94 
  95 void afu_mmio_region_destroy(struct dfl_feature_platform_data *pdata)
  96 {
  97         struct dfl_afu *afu = dfl_fpga_pdata_get_private(pdata);
  98         struct dfl_afu_mmio_region *tmp, *region;
  99 
 100         list_for_each_entry_safe(region, tmp, &afu->regions, node)
 101                 devm_kfree(&pdata->dev->dev, region);
 102 }
 103 
 104 
 105 
 106 
 107 
 108 
 109 
 110 
 111 
 112 int afu_mmio_region_get_by_index(struct dfl_feature_platform_data *pdata,
 113                                  u32 region_index,
 114                                  struct dfl_afu_mmio_region *pregion)
 115 {
 116         struct dfl_afu_mmio_region *region;
 117         struct dfl_afu *afu;
 118         int ret = 0;
 119 
 120         mutex_lock(&pdata->lock);
 121         afu = dfl_fpga_pdata_get_private(pdata);
 122         region = get_region_by_index(afu, region_index);
 123         if (!region) {
 124                 ret = -EINVAL;
 125                 goto exit;
 126         }
 127         *pregion = *region;
 128 exit:
 129         mutex_unlock(&pdata->lock);
 130         return ret;
 131 }
 132 
 133 
 134 
 135 
 136 
 137 
 138 
 139 
 140 
 141 
 142 
 143 
 144 
 145 
 146 int afu_mmio_region_get_by_offset(struct dfl_feature_platform_data *pdata,
 147                                   u64 offset, u64 size,
 148                                   struct dfl_afu_mmio_region *pregion)
 149 {
 150         struct dfl_afu_mmio_region *region;
 151         struct dfl_afu *afu;
 152         int ret = 0;
 153 
 154         mutex_lock(&pdata->lock);
 155         afu = dfl_fpga_pdata_get_private(pdata);
 156         for_each_region(region, afu)
 157                 if (region->offset <= offset &&
 158                     region->offset + region->size >= offset + size) {
 159                         *pregion = *region;
 160                         goto exit;
 161                 }
 162         ret = -EINVAL;
 163 exit:
 164         mutex_unlock(&pdata->lock);
 165         return ret;
 166 }