[RAMEN9610-12132] vipx: add API to release kernel binary
authorSanghwa Park <senius.park@samsung.com>
Wed, 13 Feb 2019 05:43:43 +0000 (14:43 +0900)
committerCosmin Tanislav <demonsingur@gmail.com>
Mon, 22 Apr 2024 17:23:16 +0000 (20:23 +0300)
Change-Id: Id55c6e9dc5d3356a5b70bb7f28dfa18e1bc6fd58
Signed-off-by: Sanghwa Park <senius.park@samsung.com>
drivers/vision/vipx/vipx-compat-ioctl.c
drivers/vision/vipx/vipx-context.c
drivers/vision/vipx/vipx-context.h
drivers/vision/vipx/vipx-core.c
drivers/vision/vipx/vipx-ioctl.c
drivers/vision/vipx/vipx-ioctl.h
drivers/vision/vipx/vipx-kernel-binary.c
drivers/vision/vipx/vipx-kernel-binary.h

index 901a019779c952897639718ebc94259fabdf86b4..1e67dce1868256bd3a576a9c5b46d5c2782ae0c0 100644 (file)
@@ -114,6 +114,14 @@ struct vipx_ioc_load_kernel_binary32 {
        int                             reserved[2];
 };
 
+struct vipx_ioc_unload_kernel_binary32 {
+       unsigned int                    size;
+       unsigned int                    global_id;
+       int                             ret;
+       struct compat_timespec          timestamp[4];
+       int                             reserved[2];
+};
+
 struct vipx_ioc_load_graph_info32 {
        unsigned int                    size;
        struct vipx_common_graph_info   graph_info;
@@ -140,12 +148,14 @@ struct vipx_ioc_execute_submodel32 {
 
 #define VIPX_IOC_LOAD_KERNEL_BINARY32  \
        _IOWR('V', 0, struct vipx_ioc_load_kernel_binary32)
+#define VIPX_IOC_UNLOAD_KERNEL_BINARY32        \
+       _IOWR('V', 1, struct vipx_ioc_unload_kernel_binary32)
 #define VIPX_IOC_LOAD_GRAPH_INFO32     \
-       _IOWR('V', 1, struct vipx_ioc_load_graph_info32)
+       _IOWR('V', 2, struct vipx_ioc_load_graph_info32)
 #define VIPX_IOC_UNLOAD_GRAPH_INFO32   \
-       _IOWR('V', 2, struct vipx_ioc_unload_graph_info32)
+       _IOWR('V', 3, struct vipx_ioc_unload_graph_info32)
 #define VIPX_IOC_EXECUTE_SUBMODEL32    \
-       _IOWR('V', 3, struct vipx_ioc_execute_submodel32)
+       _IOWR('V', 4, struct vipx_ioc_execute_submodel32)
 
 static int __vipx_ioctl_get_graph32(struct vs4l_graph *karg,
                struct vs4l_graph32 __user *uarg)
@@ -550,6 +560,56 @@ static void __vipx_ioctl_put_load_kernel_binary32(
        vipx_leave();
 }
 
+static int __vipx_ioctl_get_unload_kernel_binary32(
+               struct vipx_ioc_unload_kernel_binary *karg,
+               struct vipx_ioc_unload_kernel_binary32 __user *uarg)
+{
+       int ret;
+
+       vipx_enter();
+       if (get_user(karg->size, &uarg->size) ||
+                       get_user(karg->global_id, &uarg->global_id)) {
+               ret = -EFAULT;
+               vipx_err("Copy failed [Unload Kernel Binary(32)]\n");
+               goto p_err;
+       }
+
+       memset(karg->timestamp, 0, sizeof(karg->timestamp));
+       memset(karg->reserved, 0, sizeof(karg->reserved));
+
+       vipx_leave();
+       return 0;
+p_err:
+       return ret;
+}
+
+static void __vipx_ioctl_put_unload_kernel_binary32(
+               struct vipx_ioc_unload_kernel_binary *karg,
+               struct vipx_ioc_unload_kernel_binary32 __user *uarg)
+{
+       vipx_enter();
+       if (put_user(karg->ret, &uarg->ret) ||
+                       put_user(karg->timestamp[0].tv_sec,
+                               &uarg->timestamp[0].tv_sec) ||
+                       put_user(karg->timestamp[0].tv_nsec,
+                               &uarg->timestamp[0].tv_nsec) ||
+                       put_user(karg->timestamp[1].tv_sec,
+                               &uarg->timestamp[1].tv_sec) ||
+                       put_user(karg->timestamp[1].tv_nsec,
+                               &uarg->timestamp[1].tv_nsec) ||
+                       put_user(karg->timestamp[2].tv_sec,
+                               &uarg->timestamp[2].tv_sec) ||
+                       put_user(karg->timestamp[2].tv_nsec,
+                               &uarg->timestamp[2].tv_nsec) ||
+                       put_user(karg->timestamp[3].tv_sec,
+                               &uarg->timestamp[3].tv_sec) ||
+                       put_user(karg->timestamp[3].tv_nsec,
+                               &uarg->timestamp[3].tv_nsec)) {
+               vipx_err("Copy failed to user [Unload kernel binary(32)]\n");
+       }
+       vipx_leave();
+}
+
 static int __vipx_ioctl_get_load_graph_info32(
                struct vipx_ioc_load_graph_info *karg,
                struct vipx_ioc_load_graph_info32 __user *uarg)
@@ -651,7 +711,7 @@ static void __vipx_ioctl_put_unload_graph_info32(
                                &uarg->timestamp[3].tv_sec) ||
                        put_user(karg->timestamp[3].tv_nsec,
                                &uarg->timestamp[3].tv_nsec)) {
-               vipx_err("Copy failed to user [Load kernel binary(32)]\n");
+               vipx_err("Copy failed to user [Unload graph_info(32)]\n");
        }
        vipx_leave();
 }
@@ -789,6 +849,16 @@ long vipx_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                ret = ops->load_kernel_binary(vctx, &karg.kernel_bin);
                __vipx_ioctl_put_load_kernel_binary32(&karg.kernel_bin, uarg);
                break;
+       case VIPX_IOC_UNLOAD_KERNEL_BINARY32:
+               ret = __vipx_ioctl_get_unload_kernel_binary32(&karg.unload_kbin,
+                               uarg);
+               if (ret)
+                       goto p_err;
+
+               ret = ops->unload_kernel_binary(vctx, &karg.unload_kbin);
+               __vipx_ioctl_put_unload_kernel_binary32(&karg.unload_kbin,
+                               uarg);
+               break;
        case VIPX_IOC_LOAD_GRAPH_INFO32:
                ret = __vipx_ioctl_get_load_graph_info32(&karg.load_ginfo,
                                uarg);
index 74a883ac2628e0dee2ae39afe87a7e70142f1698..685de26931dd6e36784eb88202926cab20f5455d 100644 (file)
@@ -113,6 +113,25 @@ p_err:
        return ret;
 }
 
+static int vipx_context_unload_kernel_binary(struct vipx_context *vctx,
+               struct vipx_ioc_unload_kernel_binary *unload_kbin)
+{
+       int ret;
+
+       vipx_enter();
+       vipx_dbg("[%s] unload kernel binary (framework)\n", __func__);
+       vipx_dbg("model_id    : %#x\n", unload_kbin->global_id);
+
+       ret = vipx_kernel_binary_unload(vctx, unload_kbin->global_id);
+       if (ret)
+               goto p_err;
+
+       vipx_leave();
+       return 0;
+p_err:
+       return ret;
+}
+
 static int vipx_context_load_graph_info(struct vipx_context *vctx,
                struct vipx_ioc_load_graph_info *ginfo)
 {
@@ -404,6 +423,7 @@ p_err_num:
 
 static const struct vipx_context_ops vipx_context_ops = {
        .load_kernel_binary     = vipx_context_load_kernel_binary,
+       .unload_kernel_binary   = vipx_context_unload_kernel_binary,
        .load_graph_info        = vipx_context_load_graph_info,
        .unload_graph_info      = vipx_context_unload_graph_info,
        .execute_submodel       = vipx_context_execute_submodel
index 9c0bbfcacd7deca884cb9cac93331316cb1a5a9b..0c3ccf94e71e3f58cedd272b2b35b706bc94abe2 100644 (file)
@@ -31,6 +31,8 @@ struct vipx_context;
 struct vipx_context_ops {
        int (*load_kernel_binary)(struct vipx_context *vctx,
                        struct vipx_ioc_load_kernel_binary *kernel_bin);
+       int (*unload_kernel_binary)(struct vipx_context *vctx,
+                       struct vipx_ioc_unload_kernel_binary *unload_kbin);
        int (*load_graph_info)(struct vipx_context *vctx,
                        struct vipx_ioc_load_graph_info *ginfo);
        int (*unload_graph_info)(struct vipx_context *vctx,
index 4ec5893d51128c9e86a3d6651cbf80b1fd32c8c7..4af009c41937e7d855df60de690b6d945e7c09d4 100644 (file)
@@ -349,6 +349,35 @@ p_err_lock:
        return 0;
 }
 
+static int vipx_core_unload_kernel_binary(struct vipx_context *vctx,
+               struct vipx_ioc_unload_kernel_binary *args)
+{
+       int ret;
+
+       vipx_enter();
+       if (mutex_lock_interruptible(&vctx->lock)) {
+               ret = -ERESTARTSYS;
+               vipx_err("Failed to lock for loading kernel binary (%d)\n",
+                               ret);
+               goto p_err_lock;
+       }
+
+       ret = vctx->vops->unload_kernel_binary(vctx, args);
+       if (ret)
+               goto p_err_vops;
+
+       mutex_unlock(&vctx->lock);
+       args->ret = 0;
+       vipx_leave();
+       return 0;
+p_err_vops:
+       mutex_unlock(&vctx->lock);
+p_err_lock:
+       args->ret = ret;
+       /* return value is included in args->ret */
+       return 0;
+}
+
 static int vipx_core_load_graph_info(struct vipx_context *vctx,
                struct vipx_ioc_load_graph_info *args)
 {
@@ -444,6 +473,7 @@ const struct vipx_ioctl_ops vipx_core_ioctl_ops = {
        .streamoff              = vipx_core_streamoff,
 
        .load_kernel_binary     = vipx_core_load_kernel_binary,
+       .unload_kernel_binary   = vipx_core_unload_kernel_binary,
        .load_graph_info        = vipx_core_load_graph_info,
        .unload_graph_info      = vipx_core_unload_graph_info,
        .execute_submodel       = vipx_core_execute_submodel,
index 59316ec8126987425adad6b86357a5d458af58c3..0c027ae7392efa8346905fdd3e8dd48c571984b5 100644 (file)
@@ -302,6 +302,42 @@ static void __vipx_ioctl_put_load_kernel_binary(
        vipx_leave();
 }
 
+static int __vipx_ioctl_get_unload_kernel_binary(
+               struct vipx_ioc_unload_kernel_binary *karg,
+               struct vipx_ioc_unload_kernel_binary __user *uarg)
+{
+       int ret;
+
+       vipx_enter();
+       ret = copy_from_user(karg, uarg, sizeof(*uarg));
+       if (ret) {
+               vipx_err("Copy failed [Unload kernel binary] (%d)\n", ret);
+               goto p_err;
+       }
+
+       memset(karg->timestamp, 0, sizeof(karg->timestamp));
+       memset(karg->reserved, 0, sizeof(karg->reserved));
+
+       vipx_leave();
+       return 0;
+p_err:
+       return ret;
+}
+
+static void __vipx_ioctl_put_unload_kernel_binary(
+               struct vipx_ioc_unload_kernel_binary *karg,
+               struct vipx_ioc_unload_kernel_binary __user *uarg)
+{
+       int ret;
+
+       vipx_enter();
+       ret = copy_to_user(uarg, karg, sizeof(*karg));
+       if (ret)
+               vipx_err("Copy failed to user [Unload kernel binary]\n");
+
+       vipx_leave();
+}
+
 static int __vipx_ioctl_get_load_graph_info(
                struct vipx_ioc_load_graph_info *karg,
                struct vipx_ioc_load_graph_info __user *uarg)
@@ -487,6 +523,15 @@ long vipx_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                ret = ops->load_kernel_binary(vctx, &karg.kernel_bin);
                __vipx_ioctl_put_load_kernel_binary(&karg.kernel_bin, uarg);
                break;
+       case VIPX_IOC_UNLOAD_KERNEL_BINARY:
+               ret = __vipx_ioctl_get_unload_kernel_binary(&karg.unload_kbin,
+                               uarg);
+               if (ret)
+                       goto p_err;
+
+               ret = ops->unload_kernel_binary(vctx, &karg.unload_kbin);
+               __vipx_ioctl_put_unload_kernel_binary(&karg.unload_kbin, uarg);
+               break;
        case VIPX_IOC_LOAD_GRAPH_INFO:
                ret = __vipx_ioctl_get_load_graph_info(&karg.load_ginfo,
                                uarg);
index ccc2d9a2b82a9d0509136478640a7ec8f990d881..0ef11e42e3828cf0012dee6d81fff9882424373c 100644 (file)
@@ -34,6 +34,14 @@ struct vipx_ioc_load_kernel_binary {
        int                             reserved[2];
 };
 
+struct vipx_ioc_unload_kernel_binary {
+       unsigned int                    size;
+       unsigned int                    global_id;
+       int                             ret;
+       struct timespec                 timestamp[4];
+       int                             reserved[2];
+};
+
 struct vipx_ioc_load_graph_info {
        unsigned int                    size;
        struct vipx_common_graph_info   graph_info;
@@ -60,12 +68,14 @@ struct vipx_ioc_execute_submodel {
 
 #define VIPX_IOC_LOAD_KERNEL_BINARY    \
        _IOWR('V', 0, struct vipx_ioc_load_kernel_binary)
+#define VIPX_IOC_UNLOAD_KERNEL_BINARY  \
+       _IOWR('V', 1, struct vipx_ioc_unload_kernel_binary)
 #define VIPX_IOC_LOAD_GRAPH_INFO       \
-       _IOWR('V', 1, struct vipx_ioc_load_graph_info)
+       _IOWR('V', 2, struct vipx_ioc_load_graph_info)
 #define VIPX_IOC_UNLOAD_GRAPH_INFO     \
-       _IOWR('V', 2, struct vipx_ioc_unload_graph_info)
+       _IOWR('V', 3, struct vipx_ioc_unload_graph_info)
 #define VIPX_IOC_EXECUTE_SUBMODEL      \
-       _IOWR('V', 3, struct vipx_ioc_execute_submodel)
+       _IOWR('V', 4, struct vipx_ioc_execute_submodel)
 
 union vipx_ioc_arg {
        struct vs4l_graph                       graph;
@@ -75,6 +85,7 @@ union vipx_ioc_arg {
        struct vs4l_container_list              clist;
 
        struct vipx_ioc_load_kernel_binary      kernel_bin;
+       struct vipx_ioc_unload_kernel_binary    unload_kbin;
        struct vipx_ioc_load_graph_info         load_ginfo;
        struct vipx_ioc_unload_graph_info       unload_ginfo;
        struct vipx_ioc_execute_submodel        exec;
@@ -99,6 +110,8 @@ struct vipx_ioctl_ops {
        /* dal */
        int (*load_kernel_binary)(struct vipx_context *vctx,
                        struct vipx_ioc_load_kernel_binary *args);
+       int (*unload_kernel_binary)(struct vipx_context *vctx,
+                       struct vipx_ioc_unload_kernel_binary *args);
        int (*load_graph_info)(struct vipx_context *vctx,
                        struct vipx_ioc_load_graph_info *args);
        int (*unload_graph_info)(struct vipx_context *vctx,
index 0a01c58146f351b088fbe577c83f49aafae03765..4565f9727b551512f18167bfb50ad45fc401e1c0 100644 (file)
@@ -113,6 +113,22 @@ p_err:
        return ret;
 }
 
+int vipx_kernel_binary_unload(struct vipx_context *vctx, unsigned int global_id)
+{
+       struct vipx_kernel_binary *kbin, *temp;
+       unsigned int kid, mid;
+
+       vipx_enter();
+       mid = GET_COMMON_GRAPH_MODEL_ID(global_id);
+       list_for_each_entry_safe(kbin, temp, &vctx->binary_list, clist) {
+               kid = GET_COMMON_GRAPH_MODEL_ID(kbin->global_id);
+               if (kid == mid)
+                       vipx_kernel_binary_remove(kbin);
+       }
+       vipx_leave();
+       return 0;
+}
+
 void vipx_kernel_binary_remove(struct vipx_kernel_binary *kbin)
 {
        struct vipx_context *vctx;
index 5de30dad49d2862c75449b76560c0e54aae6198c..a5e18ad8ba04af63874e01634bd5ab1503f0d884 100644 (file)
@@ -28,6 +28,8 @@ int vipx_kernel_binary_set_gmodel(struct vipx_context *vctx,
                struct vipx_graph_model *gmodel);
 int vipx_kernel_binary_add(struct vipx_context *vctx, unsigned int id,
                int fd, unsigned int size);
+int vipx_kernel_binary_unload(struct vipx_context *vctx,
+               unsigned int global_id);
 void vipx_kernel_binary_remove(struct vipx_kernel_binary *kbin);
 void vipx_kernel_binary_all_remove(struct vipx_context *vctx);