All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg Hackmann <ghackmann@google.com>
To: dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org
Cc: konkers@google.com
Subject: [RFC 4/4] video: adf: add memblock helper
Date: Wed, 28 Aug 2013 18:51:21 -0700	[thread overview]
Message-ID: <1377741081-30189-5-git-send-email-ghackmann@google.com> (raw)
In-Reply-To: <1377741081-30189-1-git-send-email-ghackmann@google.com>

Provides a dma-buf exporter for memblocks, mainly useful for ADF devices
to wrap their bootloader logos

Signed-off-by: Greg Hackmann <ghackmann@google.com>
---
 drivers/video/adf/Kconfig        |   5 ++
 drivers/video/adf/Makefile       |   2 +
 drivers/video/adf/adf_memblock.c | 150 +++++++++++++++++++++++++++++++++++++++
 include/video/adf_memblock.h     |  20 ++++++
 4 files changed, 177 insertions(+)
 create mode 100644 drivers/video/adf/adf_memblock.c
 create mode 100644 include/video/adf_memblock.h

diff --git a/drivers/video/adf/Kconfig b/drivers/video/adf/Kconfig
index 30b0611..ad0c0eb 100644
--- a/drivers/video/adf/Kconfig
+++ b/drivers/video/adf/Kconfig
@@ -8,3 +8,8 @@ menuconfig ADF_DISPLAY_CORE
 	depends on ADF
 	depends on DISPLAY_CORE
 	tristate "Helper for implementing ADF interface ops with Display Core devices"
+
+menuconfig ADF_MEMBLOCK
+	depends on ADF
+	depends on HAVE_MEMBLOCK
+	tristate "Helper for using memblocks as buffers in ADF drivers"
diff --git a/drivers/video/adf/Makefile b/drivers/video/adf/Makefile
index 30164ee..97f9c98 100644
--- a/drivers/video/adf/Makefile
+++ b/drivers/video/adf/Makefile
@@ -10,3 +10,5 @@ obj-$(CONFIG_ADF) += adf.o \
 obj-$(CONFIG_COMPAT) += adf_fops32.o
 
 obj-$(CONFIG_ADF_DISPLAY_CORE) += adf_display.o
+
+obj-$(CONFIG_ADF_MEMBLOCK) += adf_memblock.o
diff --git a/drivers/video/adf/adf_memblock.c b/drivers/video/adf/adf_memblock.c
new file mode 100644
index 0000000..a1b7ec6
--- /dev/null
+++ b/drivers/video/adf/adf_memblock.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2013 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/dma-buf.h>
+#include <linux/highmem.h>
+#include <linux/memblock.h>
+#include <linux/slab.h>
+
+struct adf_memblock_pdata {
+	phys_addr_t base;
+};
+
+struct sg_table *adf_memblock_map(struct dma_buf_attachment *attach,
+		enum dma_data_direction direction)
+{
+	struct adf_memblock_pdata *pdata = attach->dmabuf->priv;
+	unsigned long pfn = (pdata->base >> PAGE_SHIFT);
+	struct page *page = pfn_to_page(pfn);
+	struct sg_table *table;
+	int ret;
+
+	table = kzalloc(sizeof(*table), GFP_KERNEL);
+	if (!table)
+		return ERR_PTR(-ENOMEM);
+
+	ret = sg_alloc_table(table, 1, GFP_KERNEL);
+	if (ret < 0)
+		goto err;
+
+	sg_set_page(table->sgl, page, attach->dmabuf->size, 0);
+	return table;
+
+err:
+	kfree(table);
+	return ERR_PTR(ret);
+}
+
+void adf_memblock_unmap(struct dma_buf_attachment *attach,
+		struct sg_table *table, enum dma_data_direction direction)
+{
+	sg_free_table(table);
+}
+
+static void __init_memblock adf_memblock_release(struct dma_buf *buf)
+{
+	struct adf_memblock_pdata *pdata = buf->priv;
+	int err = memblock_free(pdata->base, buf->size);
+
+	if (err < 0)
+		pr_warn("%s: freeing memblock failed: %d\n", __func__, err);
+	kfree(pdata);
+}
+
+static void *adf_memblock_do_kmap(struct dma_buf *buf, unsigned long pgoffset,
+		bool atomic)
+{
+	struct adf_memblock_pdata *pdata = buf->priv;
+	unsigned long pfn = (pdata->base >> PAGE_SHIFT) + pgoffset;
+	struct page *page = pfn_to_page(pfn);
+
+	if (atomic)
+		return kmap_atomic(page);
+	else
+		return kmap(page);
+}
+
+static void *adf_memblock_kmap_atomic(struct dma_buf *buf,
+		unsigned long pgoffset)
+{
+	return adf_memblock_do_kmap(buf, pgoffset, true);
+}
+
+static void adf_memblock_kunmap_atomic(struct dma_buf *buf,
+		unsigned long pgoffset, void *vaddr)
+{
+	kunmap_atomic(vaddr);
+}
+
+static void *adf_memblock_kmap(struct dma_buf *buf, unsigned long pgoffset)
+{
+	return adf_memblock_do_kmap(buf, pgoffset, false);
+}
+
+static void adf_memblock_kunmap(struct dma_buf *buf, unsigned long pgoffset,
+		void *vaddr)
+{
+	kunmap(vaddr);
+}
+
+static int adf_memblock_mmap(struct dma_buf *buf, struct vm_area_struct *vma)
+{
+	struct adf_memblock_pdata *pdata = buf->priv;
+	unsigned long pfn = pdata->base >> PAGE_SHIFT;
+
+	return remap_pfn_range(vma, vma->vm_start, pfn,
+			vma->vm_end - vma->vm_start, vma->vm_page_prot);
+}
+
+struct dma_buf_ops adf_memblock_ops = {
+	.map_dma_buf = adf_memblock_map,
+	.unmap_dma_buf = adf_memblock_unmap,
+	.release = adf_memblock_release,
+	.kmap_atomic = adf_memblock_kmap_atomic,
+	.kunmap_atomic = adf_memblock_kunmap_atomic,
+	.kmap = adf_memblock_kmap,
+	.kunmap = adf_memblock_kunmap,
+	.mmap = adf_memblock_mmap,
+};
+
+/**
+ * adf_memblock_export - export a memblock reserved area as a dma-buf
+ *
+ * @base: base physical address
+ * @size: memblock size
+ * @flags: mode flags for the dma-buf's file
+ *
+ * @base and @size must be page-aligned.
+ *
+ * Returns a dma-buf on success or ERR_PTR(-errno) on failure.
+ */
+struct dma_buf *adf_memblock_export(phys_addr_t base, size_t size, int flags)
+{
+	struct adf_memblock_pdata *pdata;
+	struct dma_buf *buf;
+
+	if (PAGE_ALIGN(base) != base || PAGE_ALIGN(size) != size)
+		return ERR_PTR(-EINVAL);
+
+	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		return ERR_PTR(-ENOMEM);
+
+	pdata->base = base;
+	buf = dma_buf_export(pdata, &adf_memblock_ops, size, flags);
+	if (IS_ERR(buf))
+		kfree(pdata);
+
+	return buf;
+}
diff --git a/include/video/adf_memblock.h b/include/video/adf_memblock.h
new file mode 100644
index 0000000..6256e0e
--- /dev/null
+++ b/include/video/adf_memblock.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2013 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _VIDEO_ADF_MEMBLOCK_H_
+#define _VIDEO_ADF_MEMBLOCK_H_
+
+struct dma_buf *adf_memblock_export(phys_addr_t base, size_t size, int flags);
+
+#endif /* _VIDEO_ADF_MEMBLOCK_H_ */
-- 
1.8.0

  parent reply	other threads:[~2013-08-29  1:51 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-08-29  1:51 [RFC 0/4] Atomic Display Framework Greg Hackmann
2013-08-29  1:51 ` [RFC 1/4] video: Add generic display entity core Greg Hackmann
2013-08-29  1:51 ` [RFC 2/4] video: add atomic display framework Greg Hackmann
2013-08-29  1:51 ` [RFC 3/4] video: adf: add display core helper Greg Hackmann
2013-08-29  1:51 ` Greg Hackmann [this message]
2013-08-29  3:51 ` [RFC 0/4] Atomic Display Framework Rob Clark
2013-08-29  7:01   ` [Linaro-mm-sig] " Daniel Vetter
2013-08-29  7:58     ` Ville Syrjälä
2013-08-29  8:52       ` Damien Lespiau
2013-08-29 12:59       ` Rob Clark
2013-08-29 12:25     ` Rob Clark
2013-08-29  7:36   ` Ville Syrjälä
2013-08-29 12:54     ` Rob Clark
2013-08-29 23:34       ` Greg Hackmann
2013-08-30 14:00         ` Rob Clark
2013-08-30 14:11           ` Ville Syrjälä
2013-09-02  7:39           ` Daniel Vetter
2013-09-02 13:19             ` Rob Clark
2013-09-02 15:26               ` Alex Deucher
2013-08-29 23:26     ` Greg Hackmann
2013-08-30 13:55       ` Rob Clark
2013-08-30 14:01       ` Ville Syrjälä

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=1377741081-30189-5-git-send-email-ghackmann@google.com \
    --to=ghackmann@google.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=konkers@google.com \
    --cc=linaro-mm-sig@lists.linaro.org \
    /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.