Lines Matching +full:vm +full:- +full:map
1 // SPDX-License-Identifier: GPL-2.0-only
26 * Find or create vm block based on requested @size.
30 get_vm_block(struct ct_vm *vm, unsigned int size, struct ct_atc *atc) in get_vm_block() argument
36 if (size > vm->size) { in get_vm_block()
37 dev_err(atc->card->dev, in get_vm_block()
42 mutex_lock(&vm->lock); in get_vm_block()
43 list_for_each(pos, &vm->unused) { in get_vm_block()
45 if (entry->size >= size) in get_vm_block()
48 if (pos == &vm->unused) in get_vm_block()
51 if (entry->size == size) { in get_vm_block()
52 /* Move the vm node from unused list to used list directly */ in get_vm_block()
53 list_move(&entry->list, &vm->used); in get_vm_block()
54 vm->size -= size; in get_vm_block()
63 block->addr = entry->addr; in get_vm_block()
64 block->size = size; in get_vm_block()
65 list_add(&block->list, &vm->used); in get_vm_block()
66 entry->addr += size; in get_vm_block()
67 entry->size -= size; in get_vm_block()
68 vm->size -= size; in get_vm_block()
71 mutex_unlock(&vm->lock); in get_vm_block()
75 static void put_vm_block(struct ct_vm *vm, struct ct_vm_block *block) in put_vm_block() argument
80 block->size = CT_PAGE_ALIGN(block->size); in put_vm_block()
82 mutex_lock(&vm->lock); in put_vm_block()
83 list_del(&block->list); in put_vm_block()
84 vm->size += block->size; in put_vm_block()
86 list_for_each(pos, &vm->unused) { in put_vm_block()
88 if (entry->addr >= (block->addr + block->size)) in put_vm_block()
91 if (pos == &vm->unused) { in put_vm_block()
92 list_add_tail(&block->list, &vm->unused); in put_vm_block()
95 if ((block->addr + block->size) == entry->addr) { in put_vm_block()
96 entry->addr = block->addr; in put_vm_block()
97 entry->size += block->size; in put_vm_block()
100 __list_add(&block->list, pos->prev, pos); in put_vm_block()
105 pos = &entry->list; in put_vm_block()
106 pre = pos->prev; in put_vm_block()
107 while (pre != &vm->unused) { in put_vm_block()
110 if ((pre_ent->addr + pre_ent->size) > entry->addr) in put_vm_block()
113 pre_ent->size += entry->size; in put_vm_block()
117 pre = pos->prev; in put_vm_block()
119 mutex_unlock(&vm->lock); in put_vm_block()
122 /* Map host addr (kmalloced/vmalloced) to device logical addr. */
124 ct_vm_map(struct ct_vm *vm, struct snd_pcm_substream *substream, int size) in ct_vm_map() argument
132 block = get_vm_block(vm, size, atc); in ct_vm_map()
134 dev_err(atc->card->dev, in ct_vm_map()
139 ptp = (unsigned long *)vm->ptp[0].area; in ct_vm_map()
140 pte_start = (block->addr >> CT_PAGE_SHIFT); in ct_vm_map()
141 pages = block->size >> CT_PAGE_SHIFT; in ct_vm_map()
148 block->size = size; in ct_vm_map()
152 static void ct_vm_unmap(struct ct_vm *vm, struct ct_vm_block *block) in ct_vm_unmap() argument
155 put_vm_block(vm, block); in ct_vm_unmap()
159 * return the host physical addr of the @index-th device
164 ct_get_ptp_phys(struct ct_vm *vm, int index) in ct_get_ptp_phys() argument
166 return (index >= CT_PTP_NUM) ? ~0UL : vm->ptp[index].addr; in ct_get_ptp_phys()
171 struct ct_vm *vm; in ct_vm_create() local
177 vm = kzalloc(sizeof(*vm), GFP_KERNEL); in ct_vm_create()
178 if (!vm) in ct_vm_create()
179 return -ENOMEM; in ct_vm_create()
181 mutex_init(&vm->lock); in ct_vm_create()
186 &pci->dev, in ct_vm_create()
187 PAGE_SIZE, &vm->ptp[i]); in ct_vm_create()
193 ct_vm_destroy(vm); in ct_vm_create()
194 return -ENOMEM; in ct_vm_create()
196 vm->size = CT_ADDRS_PER_PAGE * i; in ct_vm_create()
197 vm->map = ct_vm_map; in ct_vm_create()
198 vm->unmap = ct_vm_unmap; in ct_vm_create()
199 vm->get_ptp_phys = ct_get_ptp_phys; in ct_vm_create()
200 INIT_LIST_HEAD(&vm->unused); in ct_vm_create()
201 INIT_LIST_HEAD(&vm->used); in ct_vm_create()
204 block->addr = 0; in ct_vm_create()
205 block->size = vm->size; in ct_vm_create()
206 list_add(&block->list, &vm->unused); in ct_vm_create()
209 *rvm = vm; in ct_vm_create()
215 void ct_vm_destroy(struct ct_vm *vm) in ct_vm_destroy() argument
222 while (!list_empty(&vm->used)) { in ct_vm_destroy()
223 pos = vm->used.next; in ct_vm_destroy()
228 while (!list_empty(&vm->unused)) { in ct_vm_destroy()
229 pos = vm->unused.next; in ct_vm_destroy()
237 snd_dma_free_pages(&vm->ptp[i]); in ct_vm_destroy()
239 vm->size = 0; in ct_vm_destroy()
241 kfree(vm); in ct_vm_destroy()