[PATCH 09/15] lib: provide stub Linux "generic" allocator API

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



We may want to port the whole of the Linux generic allocator
implementation in future as it would come in handy in drivers that need
special memory for DMA. For now, support just the use case of the
incoming Atmel NAND driver, which is mapping the whole of a mmio-sram.

Signed-off-by: Ahmad Fatoum <a.fatoum@xxxxxxxxxxxxxx>
---
 include/linux/genalloc.h |  36 ++++++++++++
 lib/Kconfig              |   5 ++
 lib/Makefile             |   1 +
 lib/genalloc.c           | 118 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 160 insertions(+)
 create mode 100644 include/linux/genalloc.h
 create mode 100644 lib/genalloc.c

diff --git a/include/linux/genalloc.h b/include/linux/genalloc.h
new file mode 100644
index 000000000000..566e62d1965c
--- /dev/null
+++ b/include/linux/genalloc.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * 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.
+ */
+
+
+#ifndef __GENALLOC_H__
+#define __GENALLOC_H__
+
+#include <linux/types.h>
+
+struct device_node;
+
+struct gen_pool;
+
+extern phys_addr_t gen_pool_virt_to_phys(struct gen_pool *pool, unsigned long);
+
+extern void *gen_pool_dma_alloc(struct gen_pool *pool, size_t size,
+		dma_addr_t *dma);
+
+extern void *gen_pool_dma_zalloc(struct gen_pool *pool, size_t size, dma_addr_t *dma);
+
+#ifdef CONFIG_OFDEVICE
+extern struct gen_pool *of_gen_pool_get(struct device_node *np,
+	const char *propname, int index);
+#else
+static inline struct gen_pool *of_gen_pool_get(struct device_node *np,
+	const char *propname, int index)
+{
+	return NULL;
+}
+#endif
+#endif /* __GENALLOC_H__ */
diff --git a/lib/Kconfig b/lib/Kconfig
index 5af7ea33f27b..b8bc9d63d4f0 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -210,4 +210,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 4717b8aec364..38478625423b 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -75,6 +75,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 000000000000..906e2dd5f14b
--- /dev/null
+++ b/lib/genalloc.c
@@ -0,0 +1,118 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// SPDX-FileCopyrightText: 2005 Jes Sorensen <jes@xxxxxxxxxxxxxxxxxx>
+/*
+ * 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 */
-- 
2.30.2





[Index of Archives]     [Linux Embedded]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux