From 600fcaba98d835220edb260eb16c51d5a9b45032 Mon Sep 17 00:00:00 2001
From: Pawel Osciak
Date: Mon, 11 Oct 2010 10:58:53 -0300
Subject: [PATCH] --- yaml --- r: 241757 b: refs/heads/master c:
3c18ff06d811f743d380e6436fac0143ffcf1266 h: refs/heads/master i: 241755:
9e01fb92d52acafe56f294ee3e4e7a3a47f45800 v: v3
---
[refs] | 2 +-
trunk/drivers/media/video/Kconfig | 5 +
trunk/drivers/media/video/Makefile | 1 +
trunk/drivers/media/video/videobuf2-vmalloc.c | 132 ++++++++++++++++++
trunk/include/media/videobuf2-vmalloc.h | 20 +++
5 files changed, 159 insertions(+), 1 deletion(-)
create mode 100644 trunk/drivers/media/video/videobuf2-vmalloc.c
create mode 100644 trunk/include/media/videobuf2-vmalloc.h
diff --git a/[refs] b/[refs]
index d1db9d0bdb70..e1765a335f2b 100644
--- a/[refs]
+++ b/[refs]
@@ -1,2 +1,2 @@
---
-refs/heads/master: 004cc3781c40a577b0349eef825efaaebc42dd43
+refs/heads/master: 3c18ff06d811f743d380e6436fac0143ffcf1266
diff --git a/trunk/drivers/media/video/Kconfig b/trunk/drivers/media/video/Kconfig
index aae5005cf86d..b8c21a729b86 100644
--- a/trunk/drivers/media/video/Kconfig
+++ b/trunk/drivers/media/video/Kconfig
@@ -50,6 +50,11 @@ config VIDEOBUF2_CORE
config VIDEOBUF2_MEMOPS
tristate
+config VIDEOBUF2_VMALLOC
+ select VIDEOBUF2_CORE
+ select VIDEOBUF2_MEMOPS
+ tristate
+
#
# Multimedia Video device configuration
#
diff --git a/trunk/drivers/media/video/Makefile b/trunk/drivers/media/video/Makefile
index fca0444b66b1..e31c88e9ca76 100644
--- a/trunk/drivers/media/video/Makefile
+++ b/trunk/drivers/media/video/Makefile
@@ -113,6 +113,7 @@ obj-$(CONFIG_VIDEO_BTCX) += btcx-risc.o
obj-$(CONFIG_VIDEOBUF2_CORE) += videobuf2-core.o
obj-$(CONFIG_VIDEOBUF2_MEMOPS) += videobuf2-memops.o
+obj-$(CONFIG_VIDEOBUF2_VMALLOC) += videobuf2-vmalloc.o
obj-$(CONFIG_V4L2_MEM2MEM_DEV) += v4l2-mem2mem.o
diff --git a/trunk/drivers/media/video/videobuf2-vmalloc.c b/trunk/drivers/media/video/videobuf2-vmalloc.c
new file mode 100644
index 000000000000..b5e6936fb628
--- /dev/null
+++ b/trunk/drivers/media/video/videobuf2-vmalloc.c
@@ -0,0 +1,132 @@
+/*
+ * videobuf2-vmalloc.c - vmalloc memory allocator for videobuf2
+ *
+ * Copyright (C) 2010 Samsung Electronics
+ *
+ * Author: Pawel Osciak
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation.
+ */
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+struct vb2_vmalloc_buf {
+ void *vaddr;
+ unsigned long size;
+ atomic_t refcount;
+ struct vb2_vmarea_handler handler;
+};
+
+static void vb2_vmalloc_put(void *buf_priv);
+
+static void *vb2_vmalloc_alloc(void *alloc_ctx, unsigned long size)
+{
+ struct vb2_vmalloc_buf *buf;
+
+ buf = kzalloc(sizeof *buf, GFP_KERNEL);
+ if (!buf)
+ return NULL;
+
+ buf->size = size;
+ buf->vaddr = vmalloc_user(buf->size);
+ buf->handler.refcount = &buf->refcount;
+ buf->handler.put = vb2_vmalloc_put;
+ buf->handler.arg = buf;
+
+ if (!buf->vaddr) {
+ printk(KERN_ERR "vmalloc of size %ld failed\n", buf->size);
+ kfree(buf);
+ return NULL;
+ }
+
+ atomic_inc(&buf->refcount);
+ printk(KERN_DEBUG "Allocated vmalloc buffer of size %ld at vaddr=%p\n",
+ buf->size, buf->vaddr);
+
+ return buf;
+}
+
+static void vb2_vmalloc_put(void *buf_priv)
+{
+ struct vb2_vmalloc_buf *buf = buf_priv;
+
+ if (atomic_dec_and_test(&buf->refcount)) {
+ printk(KERN_DEBUG "%s: Freeing vmalloc mem at vaddr=%p\n",
+ __func__, buf->vaddr);
+ vfree(buf->vaddr);
+ kfree(buf);
+ }
+}
+
+static void *vb2_vmalloc_vaddr(void *buf_priv)
+{
+ struct vb2_vmalloc_buf *buf = buf_priv;
+
+ BUG_ON(!buf);
+
+ if (!buf->vaddr) {
+ printk(KERN_ERR "Address of an unallocated plane requested\n");
+ return NULL;
+ }
+
+ return buf->vaddr;
+}
+
+static unsigned int vb2_vmalloc_num_users(void *buf_priv)
+{
+ struct vb2_vmalloc_buf *buf = buf_priv;
+ return atomic_read(&buf->refcount);
+}
+
+static int vb2_vmalloc_mmap(void *buf_priv, struct vm_area_struct *vma)
+{
+ struct vb2_vmalloc_buf *buf = buf_priv;
+ int ret;
+
+ if (!buf) {
+ printk(KERN_ERR "No memory to map\n");
+ return -EINVAL;
+ }
+
+ ret = remap_vmalloc_range(vma, buf->vaddr, 0);
+ if (ret) {
+ printk(KERN_ERR "Remapping vmalloc memory, error: %d\n", ret);
+ return ret;
+ }
+
+ /*
+ * Make sure that vm_areas for 2 buffers won't be merged together
+ */
+ vma->vm_flags |= VM_DONTEXPAND;
+
+ /*
+ * Use common vm_area operations to track buffer refcount.
+ */
+ vma->vm_private_data = &buf->handler;
+ vma->vm_ops = &vb2_common_vm_ops;
+
+ vma->vm_ops->open(vma);
+
+ return 0;
+}
+
+const struct vb2_mem_ops vb2_vmalloc_memops = {
+ .alloc = vb2_vmalloc_alloc,
+ .put = vb2_vmalloc_put,
+ .vaddr = vb2_vmalloc_vaddr,
+ .mmap = vb2_vmalloc_mmap,
+ .num_users = vb2_vmalloc_num_users,
+};
+EXPORT_SYMBOL_GPL(vb2_vmalloc_memops);
+
+MODULE_DESCRIPTION("vmalloc memory handling routines for videobuf2");
+MODULE_AUTHOR("Pawel Osciak");
+MODULE_LICENSE("GPL");
diff --git a/trunk/include/media/videobuf2-vmalloc.h b/trunk/include/media/videobuf2-vmalloc.h
new file mode 100644
index 000000000000..a76b8afaa31e
--- /dev/null
+++ b/trunk/include/media/videobuf2-vmalloc.h
@@ -0,0 +1,20 @@
+/*
+ * videobuf2-vmalloc.h - vmalloc memory allocator for videobuf2
+ *
+ * Copyright (C) 2010 Samsung Electronics
+ *
+ * Author: Pawel Osciak
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation.
+ */
+
+#ifndef _MEDIA_VIDEOBUF2_VMALLOC_H
+#define _MEDIA_VIDEOBUF2_VMALLOC_H
+
+#include
+
+extern const struct vb2_mem_ops vb2_vmalloc_memops;
+
+#endif