From: Zhao Qiang <qiang.zhao@freescale.com>
To: <lauraa@codeaurora.org>
Cc: <linux-kernel@vger.kernel.org>, <linuxppc-dev@lists.ozlabs.org>,
<akpm@linux-foundation.org>, <olof@lixom.net>,
<catalin.marinas@arm.com>, <scottwood@freescale.com>,
<X.xie@freescale.com>, Zhao Qiang <qiang.zhao@freescale.com>
Subject: [PATCH v13 3/6] CPM/QE: use genalloc to manage CPM/QE muram
Date: Mon, 30 Nov 2015 10:48:54 +0800 [thread overview]
Message-ID: <1448851737-33125-3-git-send-email-qiang.zhao@freescale.com> (raw)
In-Reply-To: <1448851737-33125-1-git-send-email-qiang.zhao@freescale.com>
Use genalloc to manage CPM/QE muram instead of rheap.
Signed-off-by: Zhao Qiang <qiang.zhao@freescale.com>
---
Changes for v9:
- splitted from patch 3/5, modify cpm muram management functions.
Changes for v10:
- modify cpm muram first, then move to qe_common
- modify commit.
Changes for v11:
- factor out the common alloc code
- modify min_alloc_order to zero for cpm_muram_alloc_fixed.
Changes for v12:
- Nil
Changes for v13:
- rebase
arch/powerpc/include/asm/cpm.h | 3 +
arch/powerpc/platforms/Kconfig | 4 +-
arch/powerpc/sysdev/cpm_common.c | 126 +++++++++++++++++++++++++++------------
lib/genalloc.c | 2 +-
4 files changed, 94 insertions(+), 41 deletions(-)
diff --git a/arch/powerpc/include/asm/cpm.h b/arch/powerpc/include/asm/cpm.h
index 4398a6c..46e86b5 100644
--- a/arch/powerpc/include/asm/cpm.h
+++ b/arch/powerpc/include/asm/cpm.h
@@ -2,6 +2,7 @@
#define __CPM_H
#include <linux/compiler.h>
+#include <linux/genalloc.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/of.h>
@@ -161,6 +162,8 @@ int cpm_muram_init(void);
unsigned long cpm_muram_alloc(unsigned long size, unsigned long align);
int cpm_muram_free(unsigned long offset);
unsigned long cpm_muram_alloc_fixed(unsigned long offset, unsigned long size);
+unsigned long cpm_muram_alloc_common(unsigned long size, genpool_algo_t algo,
+ void *data);
void __iomem *cpm_muram_addr(unsigned long offset);
unsigned long cpm_muram_offset(void __iomem *addr);
dma_addr_t cpm_muram_dma(void __iomem *addr);
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index b7f9c40..57069eb 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -275,7 +275,7 @@ config TAU_AVERAGE
config QUICC_ENGINE
bool "Freescale QUICC Engine (QE) Support"
depends on FSL_SOC && PPC32
- select PPC_LIB_RHEAP
+ select GENERIC_ALLOCATOR
select CRC32
help
The QUICC Engine (QE) is a new generation of communications
@@ -295,7 +295,6 @@ config CPM2
bool "Enable support for the CPM2 (Communications Processor Module)"
depends on (FSL_SOC_BOOKE && PPC32) || 8260
select CPM
- select PPC_LIB_RHEAP
select PPC_PCI_CHOICE
select ARCH_REQUIRE_GPIOLIB
help
@@ -325,6 +324,7 @@ config FSL_ULI1575
config CPM
bool
+ select GENERIC_ALLOCATOR
config OF_RTC
bool
diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c
index e00a5ee..fcc83cd 100644
--- a/arch/powerpc/sysdev/cpm_common.c
+++ b/arch/powerpc/sysdev/cpm_common.c
@@ -17,6 +17,7 @@
* published by the Free Software Foundation.
*/
+#include <linux/genalloc.h>
#include <linux/init.h>
#include <linux/of_device.h>
#include <linux/spinlock.h>
@@ -27,7 +28,6 @@
#include <asm/udbg.h>
#include <asm/io.h>
-#include <asm/rheap.h>
#include <asm/cpm.h>
#include <mm/mmu_decl.h>
@@ -65,14 +65,22 @@ void __init udbg_init_cpm(void)
}
#endif
+static struct gen_pool *muram_pool;
static spinlock_t cpm_muram_lock;
-static rh_block_t cpm_boot_muram_rh_block[16];
-static rh_info_t cpm_muram_info;
static u8 __iomem *muram_vbase;
static phys_addr_t muram_pbase;
-/* Max address size we deal with */
+struct muram_block {
+ struct list_head head;
+ unsigned long start;
+ int size;
+};
+
+static LIST_HEAD(muram_block_list);
+
+/* max address size we deal with */
#define OF_MAX_ADDR_CELLS 4
+#define GENPOOL_OFFSET (4096 * 8)
int cpm_muram_init(void)
{
@@ -87,50 +95,51 @@ int cpm_muram_init(void)
return 0;
spin_lock_init(&cpm_muram_lock);
- /* initialize the info header */
- rh_init(&cpm_muram_info, 1,
- sizeof(cpm_boot_muram_rh_block) /
- sizeof(cpm_boot_muram_rh_block[0]),
- cpm_boot_muram_rh_block);
-
np = of_find_compatible_node(NULL, NULL, "fsl,cpm-muram-data");
if (!np) {
/* try legacy bindings */
np = of_find_node_by_name(NULL, "data-only");
if (!np) {
- printk(KERN_ERR "Cannot find CPM muram data node");
+ pr_err("Cannot find CPM muram data node");
ret = -ENODEV;
- goto out;
+ goto out_muram;
}
}
+ muram_pool = gen_pool_create(0, -1);
muram_pbase = of_translate_address(np, zero);
if (muram_pbase == (phys_addr_t)OF_BAD_ADDR) {
- printk(KERN_ERR "Cannot translate zero through CPM muram node");
+ pr_err("Cannot translate zero through CPM muram node");
ret = -ENODEV;
- goto out;
+ goto out_pool;
}
while (of_address_to_resource(np, i++, &r) == 0) {
if (r.end > max)
max = r.end;
-
- rh_attach_region(&cpm_muram_info, r.start - muram_pbase,
- resource_size(&r));
+ ret = gen_pool_add(muram_pool, r.start - muram_pbase +
+ GENPOOL_OFFSET, resource_size(&r), -1);
+ if (ret) {
+ pr_err("QE: couldn't add muram to pool!\n");
+ goto out_pool;
+ }
}
muram_vbase = ioremap(muram_pbase, max - muram_pbase + 1);
if (!muram_vbase) {
- printk(KERN_ERR "Cannot map CPM muram");
+ pr_err("Cannot map QE muram");
ret = -ENOMEM;
+ goto out_pool;
}
-
-out:
+ goto out_muram;
+out_pool:
+ gen_pool_destroy(muram_pool);
+out_muram:
of_node_put(np);
return ret;
}
-/**
+/*
* cpm_muram_alloc - allocate the requested size worth of multi-user ram
* @size: number of bytes to allocate
* @align: requested alignment, in bytes
@@ -143,14 +152,13 @@ unsigned long cpm_muram_alloc(unsigned long size, unsigned long align)
{
unsigned long start;
unsigned long flags;
+ struct genpool_data_align muram_pool_data;
spin_lock_irqsave(&cpm_muram_lock, flags);
- cpm_muram_info.alignment = align;
- start = rh_alloc(&cpm_muram_info, size, "commproc");
- if (!IS_ERR_VALUE(start))
- memset_io(cpm_muram_addr(start), 0, size);
+ muram_pool_data.align = align;
+ start = cpm_muram_alloc_common(size, gen_pool_first_fit_align,
+ &muram_pool_data);
spin_unlock_irqrestore(&cpm_muram_lock, flags);
-
return start;
}
EXPORT_SYMBOL(cpm_muram_alloc);
@@ -161,23 +169,31 @@ EXPORT_SYMBOL(cpm_muram_alloc);
*/
int cpm_muram_free(unsigned long offset)
{
- int ret;
unsigned long flags;
+ int size;
+ struct muram_block *tmp;
+ size = 0;
spin_lock_irqsave(&cpm_muram_lock, flags);
- ret = rh_free(&cpm_muram_info, offset);
+ list_for_each_entry(tmp, &muram_block_list, head) {
+ if (tmp->start == offset) {
+ size = tmp->size;
+ list_del(&tmp->head);
+ kfree(tmp);
+ break;
+ }
+ }
+ gen_pool_free(muram_pool, offset + GENPOOL_OFFSET, size);
spin_unlock_irqrestore(&cpm_muram_lock, flags);
-
- return ret;
+ return size;
}
EXPORT_SYMBOL(cpm_muram_free);
-/**
+/*
* cpm_muram_alloc_fixed - reserve a specific region of multi-user ram
- * @offset: the offset into the muram area to reserve
- * @size: the number of bytes to reserve
- *
- * This function returns "start" on success, -ENOMEM on failure.
+ * @offset: offset of allocation start address
+ * @size: number of bytes to allocate
+ * This function returns an offset into the muram area
* Use cpm_dpram_addr() to get the virtual address of the area.
* Use cpm_muram_free() to free the allocation.
*/
@@ -185,16 +201,50 @@ unsigned long cpm_muram_alloc_fixed(unsigned long offset, unsigned long size)
{
unsigned long start;
unsigned long flags;
+ struct genpool_data_fixed muram_pool_data_fixed;
spin_lock_irqsave(&cpm_muram_lock, flags);
- cpm_muram_info.alignment = 1;
- start = rh_alloc_fixed(&cpm_muram_info, offset, size, "commproc");
+ muram_pool_data_fixed.offset = offset + GENPOOL_OFFSET;
+ start = cpm_muram_alloc_common(size, gen_pool_fixed_alloc,
+ &muram_pool_data_fixed);
spin_unlock_irqrestore(&cpm_muram_lock, flags);
-
return start;
}
EXPORT_SYMBOL(cpm_muram_alloc_fixed);
+/*
+ * cpm_muram_alloc_common - cpm_muram_alloc common code
+ * @size: number of bytes to allocate
+ * @algo: algorithm for alloc.
+ * @data: data for genalloc's algorithm.
+ *
+ * This function returns an offset into the muram area.
+ */
+unsigned long cpm_muram_alloc_common(unsigned long size, genpool_algo_t algo,
+ void *data)
+{
+ struct muram_block *entry;
+ unsigned long start;
+
+ start = gen_pool_alloc_algo(muram_pool, size, algo, data);
+ if (!start)
+ goto out2;
+ start = start - GENPOOL_OFFSET;
+ memset_io(cpm_muram_addr(start), 0, size);
+ entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+ if (!entry)
+ goto out1;
+ entry->start = start;
+ entry->size = size;
+ list_add(&entry->head, &muram_block_list);
+
+ return start;
+out1:
+ gen_pool_free(muram_pool, start, size);
+out2:
+ return (unsigned long)-ENOMEM;
+}
+
/**
* cpm_muram_addr - turn a muram offset into a virtual address
* @offset: muram offset to convert
diff --git a/lib/genalloc.c b/lib/genalloc.c
index 5ec83cd..0a11396 100644
--- a/lib/genalloc.c
+++ b/lib/genalloc.c
@@ -576,7 +576,7 @@ unsigned long gen_pool_fixed_alloc(unsigned long *map, unsigned long size,
fixed_data = data;
order = pool->min_alloc_order;
offset_bit = fixed_data->offset >> order;
- if (WARN_ON(fixed_data->offset & (1UL << order - 1)))
+ if (WARN_ON(fixed_data->offset & ((1UL << order) - 1)))
return size;
start_bit = bitmap_find_next_zero_area(map, size,
--
2.1.0.27.g96db324
next prev parent reply other threads:[~2015-11-30 2:56 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-11-30 2:48 [PATCH v13 1/6] genalloc:support memory-allocation with bytes-alignment to genalloc Zhao Qiang
2015-11-30 2:48 ` [PATCH v13 2/6] genalloc:support allocating specific region Zhao Qiang
2015-11-30 2:48 ` Zhao Qiang [this message]
2016-08-05 16:58 ` [PATCH v13 3/6] CPM/QE: use genalloc to manage CPM/QE muram Christophe Leroy
2016-08-08 3:00 ` Qiang Zhao
2016-08-08 17:49 ` christophe leroy
2015-11-30 2:48 ` [PATCH v13 4/6] QE/CPM: move muram management functions to qe_common Zhao Qiang
2015-11-30 2:48 ` [PATCH v13 5/6] QE: use subsys_initcall to init qe Zhao Qiang
2015-11-30 2:48 ` [PATCH v13 6/6] QE: Move QE from arch/powerpc to drivers/soc Zhao Qiang
2015-12-02 23:53 ` [PATCH v13 1/6] genalloc:support memory-allocation with bytes-alignment to genalloc Andrew Morton
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1448851737-33125-3-git-send-email-qiang.zhao@freescale.com \
--to=qiang.zhao@freescale.com \
--cc=X.xie@freescale.com \
--cc=akpm@linux-foundation.org \
--cc=catalin.marinas@arm.com \
--cc=lauraa@codeaurora.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=olof@lixom.net \
--cc=scottwood@freescale.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.