From: Laura Abbott <labbott@redhat.com>
To: Zhao Qiang <qiang.zhao@freescale.com>, scottwood@freescale.com
Cc: linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org,
lauraa@codeaurora.org, X.xie@freescale.com,
benh@kernel.crashing.org, leoli@freescale.com, paulus@samba.org
Subject: Re: [PATCH v6 3/3] qe_common: add qe_muram_ functions to manage muram
Date: Mon, 24 Aug 2015 16:32:29 -0700 [thread overview]
Message-ID: <55DBA98D.1070202@redhat.com> (raw)
In-Reply-To: <1440408703-6113-3-git-send-email-qiang.zhao@freescale.com>
On 08/24/2015 02:31 AM, Zhao Qiang wrote:
> diff --git a/drivers/soc/fsl/qe/qe_common.c b/drivers/soc/fsl/qe/qe_common.c
> new file mode 100644
> index 0000000..7f1762c
> --- /dev/null
> +++ b/drivers/soc/fsl/qe/qe_common.c
> @@ -0,0 +1,193 @@
> +/*
> + * common qe code
> + *
> + * author: scott wood <scottwood@freescale.com>
> + *
> + * copyright 2007-2008,2010 freescale Semiconductor, Inc.
> + *
> + * some parts derived from commproc.c/qe2_common.c, which is:
> + * copyright (c) 1997 dan error_act (dmalek@jlc.net)
> + * copyright (c) 1999-2001 dan Malek <dan@embeddedalley.com>
> + * copyright (c) 2000 montavista Software, Inc (source@mvista.com)
> + * 2006 (c) montavista software, Inc.
> + * vitaly bordug <vbordug@ru.mvista.com>
> + *
> + * this program is free software; you can redistribute it and/or modify
> + * it under the terms of version 2 of the GNU General Public License as
> + * published by the free software Foundation.
> + */
> +
> +#include <linux/genalloc.h>
> +#include <linux/list.h>
> +#include <linux/init.h>
> +#include <linux/of_device.h>
> +#include <linux/spinlock.h>
> +#include <linux/export.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/slab.h>
> +
> +#include <linux/io.h>
> +#include <soc/fsl/qe/qe.h>
> +
> +static struct gen_pool *muram_pool;
> +static struct genpool_data_align muram_pool_data;
> +static spinlock_t qe_muram_lock;
> +static u8 __iomem *muram_vbase;
> +static phys_addr_t muram_pbase;
> +
> +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
> +
> +int qe_muram_init(void)
> +{
> + struct device_node *np;
> + struct resource r;
> + u32 zero[OF_MAX_ADDR_CELLS] = {};
> + resource_size_t max = 0;
> + int i = 0;
> + int ret = 0;
> +
> + if (muram_pbase)
> + return 0;
> +
> + muram_pool = gen_pool_create(1, -1);
> + gen_pool_set_algo(muram_pool, gen_pool_first_fit_align,
> + &muram_pool_data);
> +
> + np = of_find_compatible_node(NULL, NULL, "fsl,qe-muram-data");
> + if (!np) {
> + /* try legacy bindings */
> + np = of_find_node_by_name(NULL, "data-only");
> + if (!np) {
> + pr_err("Cannot find CPM muram data node");
> + ret = -ENODEV;
> + goto out;
> + }
> + }
> +
> + muram_pbase = of_translate_address(np, zero);
> + if (muram_pbase == (phys_addr_t)OF_BAD_ADDR) {
> + pr_err("Cannot translate zero through CPM muram node");
> + ret = -ENODEV;
> + goto out;
> + }
> +
> + while (of_address_to_resource(np, i++, &r) == 0) {
> + if (r.end > max)
> + max = r.end;
> + ret = gen_pool_add(muram_pool, r.start - muram_pbase,
> + resource_size(&r), -1);
> + if (ret) {
> + pr_err("QE MURAM: could not add muram ");
> + pr_err("remainder to pool!\n");
Don't split the error string over two lines
> + return ret;
returning here misses the error path
> + }
> +
> + }
> +
> + muram_vbase = ioremap(muram_pbase, max - muram_pbase + 1);
> + if (!muram_vbase) {
> + pr_err("Cannot map CPM muram");
> + ret = -ENOMEM;
> + }
> +
gen_pool_destroy on the error path
> +out:
> + of_node_put(np);
> + return ret;
> +}
> +
> +/**
> + * qe_muram_alloc - allocate the requested size worth of multi-user ram
> + * @size: number of bytes to allocate
> + * @align: requested alignment, in bytes
> + *
> + * This function returns an offset into the muram area.
> + * Use qe_dpram_addr() to get the virtual address of the area.
> + * Use qe_muram_free() to free the allocation.
> + */
> +unsigned long qe_muram_alloc(unsigned long size, unsigned long align)
> +{
> + unsigned long start;
> + unsigned long flags;
> + struct muram_block *entry;
> +
> + spin_lock_irqsave(&qe_muram_lock, flags);
> + muram_pool_data.align = align;
> + start = gen_pool_alloc(muram_pool, size);
The advantage of creating gen_pool_alloc_data was so that you could
pass in the align automatically without having to modify the structure.
Is there a reason you aren't using that?
> + memset(qe_muram_addr(start), 0, size);
There doesn't seem to be a check for allocation failure from the
gen_alloc.
> + entry = kmalloc(sizeof(*entry), GFP_KERNEL);
> + if (!entry)
> + goto out;
> + entry->start = start;
> + entry->size = size;
> + list_add(&entry->head, &muram_block_list);
What's the point of keeping the block list anyway? It's used only in
this file and it only seems to duplicate what gen_alloc is doing internally.
Is there some lookup functionality you still need? Could you use a gen_alloc
API to do so?
> + spin_unlock_irqrestore(&qe_muram_lock, flags);
> +
> + return start;
> +out:
> + gen_pool_free(muram_pool, start, size);
> + return (unsigned long) -ENOMEM;
> +}
> +EXPORT_SYMBOL(qe_muram_alloc);
> +
> +/**
> + * qe_muram_free - free a chunk of multi-user ram
> + * @offset: The beginning of the chunk as returned by qe_muram_alloc().
> + */
> +int qe_muram_free(unsigned long offset)
> +{
> + unsigned long flags;
> + int size;
> + struct muram_block *tmp;
> +
> + size = 0;
> + spin_lock_irqsave(&qe_muram_lock, flags);
> + 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, size);
> + spin_unlock_irqrestore(&qe_muram_lock, flags);
> +
> + return size;
> +}
> +EXPORT_SYMBOL(qe_muram_free);
> +
> +/**
> + * qe_muram_addr - turn a muram offset into a virtual address
> + * @offset: muram offset to convert
> + */
> +void __iomem *qe_muram_addr(unsigned long offset)
> +{
> + return muram_vbase + offset;
> +}
> +EXPORT_SYMBOL(qe_muram_addr);
> +
> +unsigned long qe_muram_offset(void __iomem *addr)
> +{
> + return addr - (void __iomem *)muram_vbase;
> +}
> +EXPORT_SYMBOL(qe_muram_offset);
> +
> +/**
> + * qe_muram_dma - turn a muram virtual address into a DMA address
> + * @offset: virtual address from qe_muram_addr() to convert
> + */
> +dma_addr_t qe_muram_dma(void __iomem *addr)
> +{
> + return muram_pbase + ((u8 __iomem *)addr - muram_vbase);
> +}
> +EXPORT_SYMBOL(qe_muram_dma);
Thanks,
Laura
next prev parent reply other threads:[~2015-08-24 23:32 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-08-24 9:31 [PATCH v6 1/3] genalloc:support memory-allocation with bytes-alignment to genalloc Zhao Qiang
2015-08-24 9:31 ` [PATCH v6 2/3] QE: Move QE from arch/powerpc to drivers/soc Zhao Qiang
2015-08-24 9:31 ` [PATCH v6 3/3] qe_common: add qe_muram_ functions to manage muram Zhao Qiang
2015-08-24 16:34 ` Scott Wood
2015-08-25 7:52 ` Zhao Qiang
2015-08-25 7:52 ` Zhao Qiang
2015-08-25 16:25 ` Scott Wood
2015-08-24 23:32 ` Laura Abbott [this message]
2015-08-25 3:03 ` Zhao Qiang
2015-08-25 3:03 ` Zhao Qiang
2015-08-25 4:14 ` Laura Abbott
2015-08-25 7:19 ` Zhao Qiang
2015-08-25 7:19 ` Zhao Qiang
2015-08-25 16:22 ` Scott Wood
2015-08-26 1:49 ` Zhao Qiang
2015-08-26 1:49 ` Zhao Qiang
2015-08-26 1:52 ` Scott Wood
2015-08-24 23:10 ` [PATCH v6 1/3] genalloc:support memory-allocation with bytes-alignment to genalloc Laura Abbott
2015-08-25 2:40 ` Zhao Qiang
2015-08-25 2:40 ` Zhao Qiang
2015-08-25 4:01 ` Laura Abbott
2015-08-25 8:09 ` Zhao Qiang
2015-08-25 8:09 ` Zhao Qiang
2015-08-25 16:28 ` Scott Wood
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=55DBA98D.1070202@redhat.com \
--to=labbott@redhat.com \
--cc=X.xie@freescale.com \
--cc=benh@kernel.crashing.org \
--cc=lauraa@codeaurora.org \
--cc=leoli@freescale.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=paulus@samba.org \
--cc=qiang.zhao@freescale.com \
--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.