diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Kconfig | 5 | ||||
-rw-r--r-- | lib/Makefile | 1 | ||||
-rw-r--r-- | lib/genalloc.c | 118 |
3 files changed, 124 insertions, 0 deletions
diff --git a/lib/Kconfig b/lib/Kconfig index a0f28b935c..40a5fadd5c 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -205,4 +205,9 @@ config ARCH_HAS_ZERO_PAGE config HAVE_EFFICIENT_UNALIGNED_ACCESS bool +config GENERIC_ALLOCATOR + bool + help + Support is curently limited to allocaing a complete mmio-sram at once. + endmenu diff --git a/lib/Makefile b/lib/Makefile index 21afb233fa..ba3cf6443f 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -74,6 +74,7 @@ obj-$(CONFIG_CRC8) += crc8.o obj-$(CONFIG_NLS) += nls_base.o obj-$(CONFIG_FSL_QE_FIRMWARE) += fsl-qe-firmware.o obj-$(CONFIG_UBSAN) += ubsan.o +obj-$(CONFIG_GENERIC_ALLOCATOR) += genalloc.o # GCC library routines obj-$(CONFIG_GENERIC_LIB_ASHLDI3) += ashldi3.o diff --git a/lib/genalloc.c b/lib/genalloc.c new file mode 100644 index 0000000000..906e2dd5f1 --- /dev/null +++ b/lib/genalloc.c @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: GPL-2.0-only +// SPDX-FileCopyrightText: 2005 Jes Sorensen <jes@trained-monkey.org> +/* + * Basic general purpose allocator for managing special purpose + * memory, for example, memory that is not managed by the regular + * kmalloc/kfree interface. Uses for this includes on-device special + * memory, uncached memory etc. + */ + +#include <io.h> +#include <linux/ioport.h> +#include <linux/genalloc.h> +#include <linux/export.h> +#include <of.h> +#include <driver.h> +#include <linux/string.h> + +struct gen_pool { + struct resource res; +}; + +#define res_to_gen_pool(res) \ + container_of(res, struct gen_pool, res) + +/** + * gen_pool_virt_to_phys - return the physical address of memory + * @pool: pool to allocate from + * @addr: starting address of memory + * + * Returns the physical address on success, or -1 on error. + */ +phys_addr_t gen_pool_virt_to_phys(struct gen_pool *pool, unsigned long addr) +{ + return virt_to_phys((void *)addr); +} +EXPORT_SYMBOL(gen_pool_virt_to_phys); + +/** + * gen_pool_dma_alloc - allocate special memory from the pool for DMA usage + * @pool: pool to allocate from + * @size: number of bytes to allocate from the pool + * @dma: dma-view physical address return value. Use %NULL if unneeded. + * + * Allocate the requested number of bytes from the specified pool. + * Uses the pool allocation function (with first-fit algorithm by default). + * Can not be used in NMI handler on architectures without + * NMI-safe cmpxchg implementation. + * + * Return: virtual address of the allocated memory, or %NULL on failure + */ +void *gen_pool_dma_alloc(struct gen_pool *pool, size_t size, dma_addr_t *dma) +{ + unsigned long vaddr; + + if (!pool || resource_size(&pool->res) != size) + return NULL; + + vaddr = pool->res.start; + + if (dma) + *dma = gen_pool_virt_to_phys(pool, vaddr); + + return (void *)vaddr; +} +EXPORT_SYMBOL(gen_pool_dma_alloc); + +/** + * gen_pool_dma_zalloc - allocate special zeroed memory from the pool for + * DMA usage + * @pool: pool to allocate from + * @size: number of bytes to allocate from the pool + * @dma: dma-view physical address return value. Use %NULL if unneeded. + * + * Return: virtual address of the allocated zeroed memory, or %NULL on failure + */ +void *gen_pool_dma_zalloc(struct gen_pool *pool, size_t size, dma_addr_t *dma) +{ + void *vaddr = gen_pool_dma_alloc(pool, size, dma); + + if (vaddr) + memset(vaddr, 0, size); + + return vaddr; +} +EXPORT_SYMBOL(gen_pool_dma_zalloc); + +#ifdef CONFIG_OFDEVICE +/** + * of_gen_pool_get - find a pool by phandle property + * @np: device node + * @propname: property name containing phandle(s) + * @index: index into the phandle array + * + * Returns the pool that contains the chunk starting at the physical + * address of the device tree node pointed at by the phandle property, + * or NULL if not found. + */ +struct gen_pool *of_gen_pool_get(struct device_node *np, + const char *propname, int index) +{ + struct device *dev; + struct device_node *np_pool; + + np_pool = of_parse_phandle(np, propname, index); + if (!np_pool) + return NULL; + + if (!of_device_is_compatible(np_pool, "mmio-sram")) + return NULL; + + dev = of_find_device_by_node(np_pool); + if (!dev) + return NULL; + + return container_of(&dev->resource[0], struct gen_pool, res); +} +EXPORT_SYMBOL_GPL(of_gen_pool_get); +#endif /* CONFIG_OF */ |