xref: /openbmc/linux/lib/iommu-helper.c (revision 79c1879e)
1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
20291df8cSFUJITA Tomonori /*
30291df8cSFUJITA Tomonori  * IOMMU helper functions for the free area management
40291df8cSFUJITA Tomonori  */
50291df8cSFUJITA Tomonori 
6a66022c4SAkinobu Mita #include <linux/bitmap.h>
779c1879eSChristoph Hellwig #include <linux/iommu-helper.h>
80291df8cSFUJITA Tomonori 
iommu_area_alloc(unsigned long * map,unsigned long size,unsigned long start,unsigned int nr,unsigned long shift,unsigned long boundary_size,unsigned long align_mask)90291df8cSFUJITA Tomonori unsigned long iommu_area_alloc(unsigned long *map, unsigned long size,
100291df8cSFUJITA Tomonori 			       unsigned long start, unsigned int nr,
110291df8cSFUJITA Tomonori 			       unsigned long shift, unsigned long boundary_size,
120291df8cSFUJITA Tomonori 			       unsigned long align_mask)
130291df8cSFUJITA Tomonori {
140291df8cSFUJITA Tomonori 	unsigned long index;
15a66022c4SAkinobu Mita 
16a66022c4SAkinobu Mita 	/* We don't want the last of the limit */
17a66022c4SAkinobu Mita 	size -= 1;
180291df8cSFUJITA Tomonori again:
19a66022c4SAkinobu Mita 	index = bitmap_find_next_zero_area(map, size, start, nr, align_mask);
20a66022c4SAkinobu Mita 	if (index < size) {
213715863aSFUJITA Tomonori 		if (iommu_is_span_boundary(index, nr, shift, boundary_size)) {
22f003a1f1SSebastian Ott 			start = ALIGN(shift + index, boundary_size) - shift;
230291df8cSFUJITA Tomonori 			goto again;
240291df8cSFUJITA Tomonori 		}
25a66022c4SAkinobu Mita 		bitmap_set(map, index, nr);
260291df8cSFUJITA Tomonori 		return index;
270291df8cSFUJITA Tomonori 	}
28a66022c4SAkinobu Mita 	return -1;
29a66022c4SAkinobu Mita }
30