| .. | .. |
|---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-only */ |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Basic general purpose allocator for managing special purpose |
|---|
| 3 | 4 | * memory, for example, memory that is not managed by the regular |
|---|
| .. | .. |
|---|
| 21 | 22 | * the allocator can NOT be used in NMI handler. So code uses the |
|---|
| 22 | 23 | * allocator in NMI handler should depend on |
|---|
| 23 | 24 | * CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG. |
|---|
| 24 | | - * |
|---|
| 25 | | - * This source code is licensed under the GNU General Public License, |
|---|
| 26 | | - * Version 2. See the file COPYING for more details. |
|---|
| 27 | 25 | */ |
|---|
| 28 | 26 | |
|---|
| 29 | 27 | |
|---|
| .. | .. |
|---|
| 75 | 73 | struct list_head next_chunk; /* next chunk in pool */ |
|---|
| 76 | 74 | atomic_long_t avail; |
|---|
| 77 | 75 | phys_addr_t phys_addr; /* physical starting address of memory chunk */ |
|---|
| 76 | + void *owner; /* private data to retrieve at alloc time */ |
|---|
| 78 | 77 | unsigned long start_addr; /* start address of memory chunk */ |
|---|
| 79 | 78 | unsigned long end_addr; /* end address of memory chunk (inclusive) */ |
|---|
| 80 | | - unsigned long bits[0]; /* bitmap for allocating memory chunk */ |
|---|
| 79 | + unsigned long bits[]; /* bitmap for allocating memory chunk */ |
|---|
| 81 | 80 | }; |
|---|
| 82 | 81 | |
|---|
| 83 | 82 | /* |
|---|
| .. | .. |
|---|
| 96 | 95 | |
|---|
| 97 | 96 | extern struct gen_pool *gen_pool_create(int, int); |
|---|
| 98 | 97 | extern phys_addr_t gen_pool_virt_to_phys(struct gen_pool *pool, unsigned long); |
|---|
| 99 | | -extern int gen_pool_add_virt(struct gen_pool *, unsigned long, phys_addr_t, |
|---|
| 100 | | - size_t, int); |
|---|
| 98 | +extern int gen_pool_add_owner(struct gen_pool *, unsigned long, phys_addr_t, |
|---|
| 99 | + size_t, int, void *); |
|---|
| 100 | + |
|---|
| 101 | +static inline int gen_pool_add_virt(struct gen_pool *pool, unsigned long addr, |
|---|
| 102 | + phys_addr_t phys, size_t size, int nid) |
|---|
| 103 | +{ |
|---|
| 104 | + return gen_pool_add_owner(pool, addr, phys, size, nid, NULL); |
|---|
| 105 | +} |
|---|
| 106 | + |
|---|
| 101 | 107 | /** |
|---|
| 102 | 108 | * gen_pool_add - add a new chunk of special memory to the pool |
|---|
| 103 | 109 | * @pool: pool to add new memory chunk to |
|---|
| .. | .. |
|---|
| 116 | 122 | return gen_pool_add_virt(pool, addr, -1, size, nid); |
|---|
| 117 | 123 | } |
|---|
| 118 | 124 | extern void gen_pool_destroy(struct gen_pool *); |
|---|
| 119 | | -extern unsigned long gen_pool_alloc(struct gen_pool *, size_t); |
|---|
| 120 | | -extern unsigned long gen_pool_alloc_algo(struct gen_pool *, size_t, |
|---|
| 121 | | - genpool_algo_t algo, void *data); |
|---|
| 125 | +unsigned long gen_pool_alloc_algo_owner(struct gen_pool *pool, size_t size, |
|---|
| 126 | + genpool_algo_t algo, void *data, void **owner); |
|---|
| 127 | + |
|---|
| 128 | +static inline unsigned long gen_pool_alloc_owner(struct gen_pool *pool, |
|---|
| 129 | + size_t size, void **owner) |
|---|
| 130 | +{ |
|---|
| 131 | + return gen_pool_alloc_algo_owner(pool, size, pool->algo, pool->data, |
|---|
| 132 | + owner); |
|---|
| 133 | +} |
|---|
| 134 | + |
|---|
| 135 | +static inline unsigned long gen_pool_alloc_algo(struct gen_pool *pool, |
|---|
| 136 | + size_t size, genpool_algo_t algo, void *data) |
|---|
| 137 | +{ |
|---|
| 138 | + return gen_pool_alloc_algo_owner(pool, size, algo, data, NULL); |
|---|
| 139 | +} |
|---|
| 140 | + |
|---|
| 141 | +/** |
|---|
| 142 | + * gen_pool_alloc - allocate special memory from the pool |
|---|
| 143 | + * @pool: pool to allocate from |
|---|
| 144 | + * @size: number of bytes to allocate from the pool |
|---|
| 145 | + * |
|---|
| 146 | + * Allocate the requested number of bytes from the specified pool. |
|---|
| 147 | + * Uses the pool allocation function (with first-fit algorithm by default). |
|---|
| 148 | + * Can not be used in NMI handler on architectures without |
|---|
| 149 | + * NMI-safe cmpxchg implementation. |
|---|
| 150 | + */ |
|---|
| 151 | +static inline unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size) |
|---|
| 152 | +{ |
|---|
| 153 | + return gen_pool_alloc_algo(pool, size, pool->algo, pool->data); |
|---|
| 154 | +} |
|---|
| 155 | + |
|---|
| 122 | 156 | extern void *gen_pool_dma_alloc(struct gen_pool *pool, size_t size, |
|---|
| 123 | 157 | dma_addr_t *dma); |
|---|
| 124 | | -extern void gen_pool_free(struct gen_pool *, unsigned long, size_t); |
|---|
| 158 | +extern void *gen_pool_dma_alloc_algo(struct gen_pool *pool, size_t size, |
|---|
| 159 | + dma_addr_t *dma, genpool_algo_t algo, void *data); |
|---|
| 160 | +extern void *gen_pool_dma_alloc_align(struct gen_pool *pool, size_t size, |
|---|
| 161 | + dma_addr_t *dma, int align); |
|---|
| 162 | +extern void *gen_pool_dma_zalloc(struct gen_pool *pool, size_t size, dma_addr_t *dma); |
|---|
| 163 | +extern void *gen_pool_dma_zalloc_algo(struct gen_pool *pool, size_t size, |
|---|
| 164 | + dma_addr_t *dma, genpool_algo_t algo, void *data); |
|---|
| 165 | +extern void *gen_pool_dma_zalloc_align(struct gen_pool *pool, size_t size, |
|---|
| 166 | + dma_addr_t *dma, int align); |
|---|
| 167 | +extern void gen_pool_free_owner(struct gen_pool *pool, unsigned long addr, |
|---|
| 168 | + size_t size, void **owner); |
|---|
| 169 | +static inline void gen_pool_free(struct gen_pool *pool, unsigned long addr, |
|---|
| 170 | + size_t size) |
|---|
| 171 | +{ |
|---|
| 172 | + gen_pool_free_owner(pool, addr, size, NULL); |
|---|
| 173 | +} |
|---|
| 174 | + |
|---|
| 125 | 175 | extern void gen_pool_for_each_chunk(struct gen_pool *, |
|---|
| 126 | 176 | void (*)(struct gen_pool *, struct gen_pool_chunk *, void *), void *); |
|---|
| 127 | 177 | extern size_t gen_pool_avail(struct gen_pool *); |
|---|
| .. | .. |
|---|
| 156 | 206 | int min_alloc_order, int nid, const char *name); |
|---|
| 157 | 207 | extern struct gen_pool *gen_pool_get(struct device *dev, const char *name); |
|---|
| 158 | 208 | |
|---|
| 159 | | -bool addr_in_gen_pool(struct gen_pool *pool, unsigned long start, |
|---|
| 209 | +extern bool gen_pool_has_addr(struct gen_pool *pool, unsigned long start, |
|---|
| 160 | 210 | size_t size); |
|---|
| 161 | 211 | |
|---|
| 162 | 212 | #ifdef CONFIG_OF |
|---|