tlk_driver: 5/22 update
[tegra/ote_partner/tlk_driver.git] / ote_fs.c
index e3d427a..f58bdd6 100644 (file)
--- a/ote_fs.c
+++ b/ote_fs.c
@@ -30,6 +30,7 @@
 static DECLARE_COMPLETION(req_ready);
 static DECLARE_COMPLETION(req_complete);
 
+static struct te_ss_op_legacy *ss_op_shmem_legacy;
 static struct te_ss_op *ss_op_shmem;
 static uint32_t ss_op_size;
 
@@ -38,26 +39,26 @@ static void indicate_ss_op_complete(void)
        tlk_generic_smc(TE_SMC_SS_REQ_COMPLETE, 0, 0);
 }
 
-int te_handle_ss_ioctl(struct file *file, unsigned int ioctl_num,
+int te_handle_ss_ioctl_legacy(struct file *file, unsigned int ioctl_num,
        unsigned long ioctl_param)
 {
        switch (ioctl_num) {
-       case TE_IOCTL_SS_NEW_REQ:
+       case TE_IOCTL_SS_NEW_REQ_LEGACY:
                /* wait for a new request */
                if (wait_for_completion_interruptible(&req_ready))
                        return -ENODATA;
 
                /* transfer pending request to daemon's buffer */
-               if (copy_to_user((void __user *)ioctl_param, ss_op_shmem,
+               if (copy_to_user((void __user *)ioctl_param, ss_op_shmem_legacy,
                                        ss_op_size)) {
                        pr_err("copy_to_user failed for new request\n");
                        return -EFAULT;
                }
                break;
 
-       case TE_IOCTL_SS_REQ_COMPLETE: /* request complete */
-               if (copy_from_user(ss_op_shmem, (void __user *)ioctl_param,
-                                       ss_op_size)) {
+       case TE_IOCTL_SS_REQ_COMPLETE_LEGACY: /* request complete */
+               if (copy_from_user(ss_op_shmem_legacy,
+                       (void __user *)ioctl_param, ss_op_size)) {
                        pr_err("copy_from_user failed for request\n");
                        return -EFAULT;
                }
@@ -70,7 +71,7 @@ int te_handle_ss_ioctl(struct file *file, unsigned int ioctl_num,
        return 0;
 }
 
-void tlk_ss_op(uint32_t size)
+void tlk_ss_op_legacy(uint32_t size)
 {
        /* store size of request */
        ss_op_size = size;
@@ -85,9 +86,71 @@ void tlk_ss_op(uint32_t size)
        indicate_ss_op_complete();
 }
 
+static int __init tlk_ss_init_legacy(void)
+{
+       dma_addr_t ss_op_shmem_dma;
+
+       /* allocate shared memory buffer */
+       ss_op_shmem_legacy = dma_alloc_coherent(NULL,
+               sizeof(struct te_ss_op_legacy), &ss_op_shmem_dma, GFP_KERNEL);
+       if (!ss_op_shmem_legacy) {
+               pr_err("%s: no memory available for fs operations\n", __func__);
+               return -ENOMEM;
+       }
+
+       tlk_generic_smc(TE_SMC_SS_REGISTER_HANDLER_LEGACY,
+               (uintptr_t)tlk_ss_op_legacy, (uintptr_t)ss_op_shmem_legacy);
+
+       return 0;
+}
+
+arch_initcall(tlk_ss_init_legacy);
+
+int te_handle_ss_ioctl(struct file *file, unsigned int ioctl_num,
+       unsigned long ioctl_param)
+{
+       switch (ioctl_num) {
+       case TE_IOCTL_SS_NEW_REQ:
+               /* wait for a new request */
+               if (wait_for_completion_interruptible(&req_ready))
+                       return -ENODATA;
+
+               /* transfer pending request to daemon's buffer */
+               if (copy_to_user((void __user *)ioctl_param, ss_op_shmem->data,
+                                       ss_op_shmem->req_size)) {
+                       pr_err("copy_to_user failed for new request\n");
+                       return -EFAULT;
+               }
+               break;
+
+       case TE_IOCTL_SS_REQ_COMPLETE: /* request complete */
+               if (copy_from_user(ss_op_shmem->data,
+                       (void __user *)ioctl_param, ss_op_shmem->req_size)) {
+                       pr_err("copy_from_user failed for request\n");
+                       return -EFAULT;
+               }
+
+               /* signal the producer */
+               complete(&req_complete);
+               break;
+       }
+
+       return 0;
+}
+
+void tlk_ss_op(void)
+{
+       /* signal consumer */
+       complete(&req_ready);
+
+       /* wait for the consumer's signal */
+       wait_for_completion(&req_complete);
+}
+
 static int __init tlk_ss_init(void)
 {
        dma_addr_t ss_op_shmem_dma;
+       int32_t ret;
 
        /* allocate shared memory buffer */
        ss_op_shmem = dma_alloc_coherent(NULL, sizeof(struct te_ss_op),
@@ -97,8 +160,14 @@ static int __init tlk_ss_init(void)
                return -ENOMEM;
        }
 
-       tlk_generic_smc(TE_SMC_SS_REGISTER_HANDLER,
-                       (uintptr_t)tlk_ss_op, (uintptr_t)ss_op_shmem);
+       ret = tlk_generic_smc(TE_SMC_SS_REGISTER_HANDLER,
+                       (uintptr_t)ss_op_shmem, 0);
+       if (ret != 0) {
+               dma_free_coherent(NULL, sizeof(struct te_ss_op),
+                       (void *)ss_op_shmem, ss_op_shmem_dma);
+               ss_op_shmem = NULL;
+               return -ENOTSUPP;
+       }
 
        return 0;
 }