clear-pkgs-linux-iot-lts2018/0805-media-intel-ipu4-VIRT-...

370 lines
10 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Bandi, Kushal" <kushal.bandi@intel.com>
Date: Wed, 3 Oct 2018 20:33:08 +0000
Subject: [PATCH] media: intel-ipu4: [VIRT] Psys mediation stub para virt
driver.
Change-Id: Ife22dbe6cff74ce5ca76b2e63ccf38721cfbc675
Tracked-On: OAM-64123
Tracked-On: OAM-64294
Tracked-On: OAM-64937
Tracked-On: OLINUX-2973
Tracked-On: OLINUX-3042
Signed-off-by: Bandi, Kushal <kushal.bandi@intel.com>
---
drivers/media/pci/intel/virtio/Makefile.virt | 1 +
.../intel/virtio/intel-ipu4-para-virt-drv.c | 30 ++-
.../intel/virtio/intel-ipu4-para-virt-drv.h | 2 +-
.../intel/virtio/intel-ipu4-para-virt-psys.c | 216 ++++++++++++++++++
.../intel/virtio/intel-ipu4-para-virt-psys.h | 38 +++
5 files changed, 279 insertions(+), 8 deletions(-)
create mode 100644 drivers/media/pci/intel/virtio/intel-ipu4-para-virt-psys.c
create mode 100644 drivers/media/pci/intel/virtio/intel-ipu4-para-virt-psys.h
diff --git a/drivers/media/pci/intel/virtio/Makefile.virt b/drivers/media/pci/intel/virtio/Makefile.virt
index 75f481b3b71d..7264898c43bf 100644
--- a/drivers/media/pci/intel/virtio/Makefile.virt
+++ b/drivers/media/pci/intel/virtio/Makefile.virt
@@ -19,6 +19,7 @@ else
$(TARGET_MODULE)-objs += ../virtio/intel-ipu4-virtio-fe-payload.o
$(TARGET_MODULE)-objs += ../virtio/intel-ipu4-virtio-fe.o
$(TARGET_MODULE)-objs += ../virtio/intel-ipu4-para-virt-drv.o
+ $(TARGET_MODULE)-objs += ../virtio/intel-ipu4-para-virt-psys.o
endif
obj-$(CONFIG_VIDEO_INTEL_IPU_ACRN) := $(TARGET_MODULE).o
diff --git a/drivers/media/pci/intel/virtio/intel-ipu4-para-virt-drv.c b/drivers/media/pci/intel/virtio/intel-ipu4-para-virt-drv.c
index 06572eab985b..212132f5edc0 100644
--- a/drivers/media/pci/intel/virtio/intel-ipu4-para-virt-drv.c
+++ b/drivers/media/pci/intel/virtio/intel-ipu4-para-virt-drv.c
@@ -1255,7 +1255,7 @@ static int virt_ici_pipeline_init(void)
return 0;
}
-static int __init virt_ici_init(void)
+static int virt_ici_init(void)
{
struct virtual_stream *vstream;
int rval = 0, i;
@@ -1310,16 +1310,32 @@ static void virt_ici_pipeline_exit(void)
pr_notice("virt_ici pipeline device unregistered\n");
}
+static void virt_ici_exit(void)
+{
+ virt_ici_stream_exit();
+ virt_ici_pipeline_exit();
+}
+static int __init virt_ipu_init(void)
+{
+ int rval = 0;
+ rval = virt_ici_init();
+ if(rval)
+ pr_warn("ipu virt: ISYS init failed\n");
-static void __exit virt_ici_exit(void)
+ rval = virt_psys_init();
+ if(rval)
+ pr_warn("ipu virt: PSYS init failed\n");
+
+ return rval;
+}
+static void __exit virt_ipu_exit(void)
{
- virt_ici_stream_exit();
- virt_ici_pipeline_exit();
- ipu4_virtio_fe_req_queue_free();
+ virt_ici_exit();
+ virt_psys_exit();
}
-module_init(virt_ici_init);
-module_exit(virt_ici_exit);
+module_init(virt_ipu_init);
+module_exit(virt_ipu_exit);
MODULE_LICENSE("Dual BSD/GPL");
MODULE_DESCRIPTION("Intel IPU Para virtualize ici input system driver");
diff --git a/drivers/media/pci/intel/virtio/intel-ipu4-para-virt-drv.h b/drivers/media/pci/intel/virtio/intel-ipu4-para-virt-drv.h
index d6d9210d937a..f32c3e9bb30b 100644
--- a/drivers/media/pci/intel/virtio/intel-ipu4-para-virt-drv.h
+++ b/drivers/media/pci/intel/virtio/intel-ipu4-para-virt-drv.h
@@ -17,7 +17,7 @@
#include "./ici/ici-isys-stream-device.h"
#include "./ici/ici-isys-frame-buf.h"
#include "intel-ipu4-virtio-common.h"
-
+#include "intel-ipu4-para-virt-psys.h"
struct virtual_stream {
struct mutex mutex;
struct ici_stream_device strm_dev;
diff --git a/drivers/media/pci/intel/virtio/intel-ipu4-para-virt-psys.c b/drivers/media/pci/intel/virtio/intel-ipu4-para-virt-psys.c
new file mode 100644
index 000000000000..6e040794aef0
--- /dev/null
+++ b/drivers/media/pci/intel/virtio/intel-ipu4-para-virt-psys.c
@@ -0,0 +1,216 @@
+// SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
+/*
+ * Copyright (C) 2018 Intel Corporation
+ */
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/dma-buf.h>
+#include <linux/firmware.h>
+#include <linux/fs.h>
+#include <linux/highmem.h>
+#include <linux/init_task.h>
+#include <linux/kthread.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/poll.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
+#include <linux/sched.h>
+#else
+#include <uapi/linux/sched/types.h>
+#endif
+#include <linux/uaccess.h>
+#include <linux/vmalloc.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0)
+#include <linux/dma-attrs.h>
+#else
+#include <linux/dma-mapping.h>
+#endif
+
+#include "intel-ipu4-para-virt-psys.h"
+
+#define IPU_PSYS_NUM_DEVICES 4
+#define IPU_PSYS_NAME "intel-ipu4-psys"
+static dev_t virt_psys_dev_t;
+
+static DECLARE_BITMAP(virt_psys_devices, IPU_PSYS_NUM_DEVICES);
+static DEFINE_MUTEX(psys_mutex);
+
+static struct ipu_psys_capability caps = {
+ .version = 1,
+ .driver = "ipu-psys",
+};
+
+static unsigned int virt_psys_poll(struct file *file,
+ struct poll_table_struct *wait)
+{
+ unsigned int res = 0;
+
+ return res;
+}
+long virt_psys_compat_ioctl32(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ int err = 0;
+
+ if (err)
+ return err;
+
+ return 0;
+}
+static long virt_psys_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ union {
+ struct ipu_psys_buffer buf;
+ struct ipu_psys_command cmd;
+ struct ipu_psys_event ev;
+ struct ipu_psys_capability caps;
+ struct ipu_psys_manifest m;
+ } karg;
+
+ int err = 0;
+ void __user *up = (void __user *)arg;
+ bool copy = (cmd != IPU_IOC_MAPBUF && cmd != IPU_IOC_UNMAPBUF);
+
+ if (copy) {
+ if (_IOC_SIZE(cmd) > sizeof(karg))
+ return -ENOTTY;
+
+ if (_IOC_DIR(cmd) & _IOC_WRITE) {
+ err = copy_from_user(&karg, up, _IOC_SIZE(cmd));
+ if (err)
+ return -EFAULT;
+ }
+ }
+ switch (cmd) {
+ case IPU_IOC_MAPBUF:
+ //err = ipu_psys_mapbuf(arg, fh);
+ break;
+ case IPU_IOC_UNMAPBUF:
+ //err = ipu_psys_unmapbuf(arg, fh);
+ break;
+ case IPU_IOC_QUERYCAP:
+ karg.caps = caps;
+ break;
+ case IPU_IOC_GETBUF:
+ //err = ipu_psys_getbuf(&karg.buf, fh);
+ break;
+ case IPU_IOC_PUTBUF:
+ //err = ipu_psys_putbuf(&karg.buf, fh);
+ break;
+ case IPU_IOC_QCMD:
+ //err = ipu_psys_kcmd_new(&karg.cmd, fh);
+ break;
+ case IPU_IOC_DQEVENT:
+ //err = ipu_ioctl_dqevent(&karg.ev, fh, file->f_flags);
+ break;
+ case IPU_IOC_GET_MANIFEST:
+ //err = ipu_get_manifest(&karg.m, fh);
+ break;
+ default:
+ err = -ENOTTY;
+ break;
+ }
+ if (err)
+ return err;
+
+ return 0;
+}
+static int virt_psys_open(struct inode *inode, struct file *file)
+{
+ int rval;
+
+
+ return rval;
+}
+
+static int virt_psys_release(struct inode *inode, struct file *file)
+{
+ int rval;
+
+ return rval;
+}
+static const struct file_operations virt_psys_fops = {
+ .open = virt_psys_open,
+ .release = virt_psys_release,
+ .unlocked_ioctl = virt_psys_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = virt_psys_compat_ioctl32,
+#endif
+ .poll = virt_psys_poll,
+ .owner = THIS_MODULE,
+};
+
+static void virt_psys_dev_release(struct device *dev)
+{
+}
+void virt_psys_exit(void)
+{
+ unregister_chrdev_region(virt_psys_dev_t, IPU_PSYS_NUM_DEVICES);
+
+ pr_notice("Virtual psys device unregistered\n");
+
+}
+
+int virt_psys_init(void)
+{
+ struct virt_ipu_psys *psys;
+ unsigned int minor;
+ int rval = -E2BIG;
+
+ rval = alloc_chrdev_region(&virt_psys_dev_t, 0,
+ IPU_PSYS_NUM_DEVICES, IPU_PSYS_NAME);
+ if (rval) {
+ pr_err("can't alloc psys chrdev region (%d)\n", rval);
+ return rval;
+ }
+ mutex_lock(&psys_mutex);
+
+ minor = find_next_zero_bit(virt_psys_devices, IPU_PSYS_NUM_DEVICES, 0);
+ if (minor == IPU_PSYS_NUM_DEVICES) {
+ pr_err("too many devices\n");
+ goto out_unlock;
+ }
+
+ psys = kzalloc(sizeof(*psys), GFP_KERNEL);
+ if (!psys) {
+ rval = -ENOMEM;
+ goto out_unlock;
+ }
+
+ cdev_init(&psys->cdev, &virt_psys_fops);
+ psys->cdev.owner = virt_psys_fops.owner;
+
+ rval = cdev_add(&psys->cdev, MKDEV(MAJOR(virt_psys_dev_t), minor), 1);
+ if (rval) {
+ pr_err("cdev_add failed (%d)\n", rval);
+ goto out_unlock;
+ }
+
+ set_bit(minor, virt_psys_devices);
+
+ mutex_init(&psys->mutex);
+ psys->dev.devt = MKDEV(MAJOR(virt_psys_dev_t), minor);
+ psys->dev.release = virt_psys_dev_release;
+ dev_set_name(&psys->dev, "ipu-psys%d", minor);
+ rval = device_register(&psys->dev);
+ if (rval < 0) {
+ dev_err(&psys->dev, "psys device_register failed\n");
+ goto out_mutex_destroy;
+ }
+ /* Add the hw stepping information to caps */
+ strlcpy(caps.dev_model, IPU_MEDIA_DEV_MODEL_NAME,
+ sizeof(caps.dev_model));
+
+ pr_info("psys probe minor: %d\n", minor);
+
+out_mutex_destroy:
+ mutex_destroy(&psys->mutex);
+ cdev_del(&psys->cdev);
+out_unlock:
+ mutex_unlock (&psys_mutex);
+ return rval;
+}
+
diff --git a/drivers/media/pci/intel/virtio/intel-ipu4-para-virt-psys.h b/drivers/media/pci/intel/virtio/intel-ipu4-para-virt-psys.h
new file mode 100644
index 000000000000..f84c1e2baf31
--- /dev/null
+++ b/drivers/media/pci/intel/virtio/intel-ipu4-para-virt-psys.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) */
+/*
+ * Copyright (C) 2018 Intel Corporation
+ */
+
+#ifndef INTEL_IPU4_PARA_VIRT_PSYS_H_
+#define INTEL_IPU4_PARA_VIRT_PSYS_H_
+
+#include <linux/cdev.h>
+#include <uapi/linux/ipu-psys.h>
+
+#define IPU_MEDIA_DEV_MODEL_NAME "ipu4/Broxton B"
+
+struct virt_ipu_psys {
+ struct cdev cdev;
+ struct device dev;
+ struct mutex mutex;
+
+};
+
+struct virt_ipu_psys_fh {
+ struct virt_ipu_psys *psys;
+ struct mutex mutex; /* Protects bufmap & kcmds fields */
+ struct list_head list;
+ struct list_head bufmap;
+ struct list_head kcmds[IPU_PSYS_CMD_PRIORITY_NUM];
+ struct ipu_psys_kcmd
+ *new_kcmd_tail[IPU_PSYS_CMD_PRIORITY_NUM];
+ wait_queue_head_t wait;
+ struct mutex bs_mutex; /* Protects buf_set field */
+ struct list_head buf_sets;
+};
+int virt_psys_init(void);
+void virt_psys_exit(void);
+#define dev_to_vpsys(dev) \
+ container_of(dev, struct virt_ipu_psys, dev)
+
+#endif /* INTEL_IPU4_PARA_VIRT_PSYS_H_ */
--
https://clearlinux.org