blob: ed8c2f09b5ab21b90515ffef9288fc88930c3d6d [file] [log] [blame]
/* SPDX-License-Identifier: GPL-2.0 */
/*
* GXP ranged resource allocator.
*
* Copyright (C) 2021 Google LLC
*/
#ifndef __GXP_RANGE_ALLOC_H__
#define __GXP_RANGE_ALLOC_H__
#include <linux/mutex.h>
#include <linux/slab.h>
struct range_alloc {
int total_count;
int free_count;
int start_index;
struct mutex lock;
int elements[];
};
/**
* range_alloc_create() - Creates a range allocator starting at the specified
* start (inclusive) and ends at the specified end
* (exclusive).
* @start: The start of the range (inclusive).
* @end: The end of the range (exclusive)
*
* Return:
* ptr - A pointer of the newly created allocator handle on success, an
* error pointer (PTR_ERR) otherwise.
* -EINVAL - Invalid start/end combination
* -ENOMEM - Insufficient memory to create the allocator
*/
struct range_alloc *range_alloc_create(int start, int end);
/**
* range_alloc_get() - Gets the specified element from the range.
* @r: The range allocator
* @element: The element to acquire from the range
*
* The @element argument should be within the allocator's range and has not been
* allocated before.
*
* Return:
* 0 - Successfully reserved @element
* -EINVAL - Invalid element index (negative or outside allocator range)
* -EBUSY - Element is already allocated
*/
int range_alloc_get(struct range_alloc *r, int element);
/**
* range_alloc_get_any() - Gets any free element in the range.
* @r: The range allocator
* @element: A pointer to use to store the allocated element
*
* Return:
* 0 - Successful reservation
* -ENOMEM - No elements left in the range to allocate
*/
int range_alloc_get_any(struct range_alloc *r, int *element);
/**
* range_alloc_put() - Puts an element back into the range.
* @r: The range allocator
* @element: The element to put back into the range
*
* Return:
* 0 - Successful placement back into the range
* -EINVAL - Invalid element index (negative or outside allocator range)
* -EBUSY - The element is still present in the range
*/
int range_alloc_put(struct range_alloc *r, int element);
/**
* range_alloc_num_free() - Returns the number of free elements in the range.
* @r: The range allocator
*
* Return: the number of free elements in the range
*/
int range_alloc_num_free(struct range_alloc *r);
/**
* range_alloc_destroy() - Destroys the range allocator
* @r: The range allocator to destroy
*
* The destruction does not validate that the range is empty.
*
* Return:
* 0 - Successfully destroyed range allocator
* -EFAULT - Invalid allocator address
*/
int range_alloc_destroy(struct range_alloc *r);
#endif /* __GXP_RANGE_ALLOC_H__ */