blob: ed8c2f09b5ab21b90515ffef9288fc88930c3d6d [file] [log] [blame]
John Scheiblede164752021-10-26 13:45:19 -07001/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * GXP ranged resource allocator.
4 *
5 * Copyright (C) 2021 Google LLC
6 */
7#ifndef __GXP_RANGE_ALLOC_H__
8#define __GXP_RANGE_ALLOC_H__
9
10#include <linux/mutex.h>
11#include <linux/slab.h>
12
13struct range_alloc {
14 int total_count;
15 int free_count;
16 int start_index;
17 struct mutex lock;
18 int elements[];
19};
20
21/**
22 * range_alloc_create() - Creates a range allocator starting at the specified
23 * start (inclusive) and ends at the specified end
24 * (exclusive).
25 * @start: The start of the range (inclusive).
26 * @end: The end of the range (exclusive)
27 *
28 * Return:
29 * ptr - A pointer of the newly created allocator handle on success, an
30 * error pointer (PTR_ERR) otherwise.
31 * -EINVAL - Invalid start/end combination
32 * -ENOMEM - Insufficient memory to create the allocator
33 */
34struct range_alloc *range_alloc_create(int start, int end);
35
36/**
37 * range_alloc_get() - Gets the specified element from the range.
38 * @r: The range allocator
39 * @element: The element to acquire from the range
40 *
41 * The @element argument should be within the allocator's range and has not been
42 * allocated before.
43 *
44 * Return:
45 * 0 - Successfully reserved @element
46 * -EINVAL - Invalid element index (negative or outside allocator range)
47 * -EBUSY - Element is already allocated
48 */
49int range_alloc_get(struct range_alloc *r, int element);
50
51/**
52 * range_alloc_get_any() - Gets any free element in the range.
53 * @r: The range allocator
54 * @element: A pointer to use to store the allocated element
55 *
56 * Return:
57 * 0 - Successful reservation
58 * -ENOMEM - No elements left in the range to allocate
59 */
60int range_alloc_get_any(struct range_alloc *r, int *element);
61
62/**
63 * range_alloc_put() - Puts an element back into the range.
64 * @r: The range allocator
65 * @element: The element to put back into the range
66 *
67 * Return:
68 * 0 - Successful placement back into the range
69 * -EINVAL - Invalid element index (negative or outside allocator range)
70 * -EBUSY - The element is still present in the range
71 */
72int range_alloc_put(struct range_alloc *r, int element);
73
74/**
75 * range_alloc_num_free() - Returns the number of free elements in the range.
76 * @r: The range allocator
77 *
78 * Return: the number of free elements in the range
79 */
80int range_alloc_num_free(struct range_alloc *r);
81
82/**
83 * range_alloc_destroy() - Destroys the range allocator
84 * @r: The range allocator to destroy
85 *
86 * The destruction does not validate that the range is empty.
87 *
88 * Return:
89 * 0 - Successfully destroyed range allocator
90 * -EFAULT - Invalid allocator address
91 */
92int range_alloc_destroy(struct range_alloc *r);
93
94#endif /* __GXP_RANGE_ALLOC_H__ */