summaryrefslogtreecommitdiff
path: root/drivers/edgetpu/edgetpu-fs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/edgetpu/edgetpu-fs.c')
-rw-r--r--drivers/edgetpu/edgetpu-fs.c47
1 files changed, 46 insertions, 1 deletions
diff --git a/drivers/edgetpu/edgetpu-fs.c b/drivers/edgetpu/edgetpu-fs.c
index 46de18f..599a6a7 100644
--- a/drivers/edgetpu/edgetpu-fs.c
+++ b/drivers/edgetpu/edgetpu-fs.c
@@ -6,7 +6,9 @@
*/
#include <linux/atomic.h>
+#include <linux/bitops.h>
#include <linux/cdev.h>
+#include <linux/cred.h>
#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/file.h>
@@ -25,6 +27,7 @@
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/uaccess.h>
+#include <linux/uidgid.h>
#include "edgetpu-config.h"
#include "edgetpu-device-group.h"
@@ -39,6 +42,10 @@
#include "edgetpu-wakelock.h"
#include "edgetpu.h"
+#ifdef EDGETPU_FEATURE_INTEROP
+#include <soc/google/tpu-ext.h>
+#endif
+
#define CREATE_TRACE_POINTS
#include <trace/events/edgetpu.h>
@@ -685,6 +692,40 @@ static int edgetpu_ioctl_get_fatal_errors(struct edgetpu_client *client,
return ret;
}
+#ifdef EDGETPU_FEATURE_INTEROP
+static int edgetpu_ioctl_test_external(struct edgetpu_client *client,
+ struct edgetpu_test_ext_ioctl __user *argp)
+{
+ int ret = 0;
+ struct edgetpu_test_ext_ioctl test_ext;
+ struct edgetpu_ext_client_info client_info;
+ struct edgetpu_ext_mailbox_info *info;
+
+ if (!uid_eq(current_euid(), GLOBAL_ROOT_UID))
+ return -EPERM;
+
+ if (copy_from_user(&test_ext, argp, sizeof(test_ext)))
+ return -EFAULT;
+
+ if (hweight32(test_ext.mbox_bmap) > 1)
+ return -EINVAL;
+
+ client_info.attr = (struct edgetpu_mailbox_attr __user *)test_ext.attrs;
+ client_info.tpu_fd = test_ext.fd;
+ client_info.mbox_map = test_ext.mbox_bmap;
+
+ info = kmalloc(sizeof(*info) + sizeof(struct edgetpu_ext_mailbox_descriptor *), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ ret = edgetpu_ext_driver_cmd(client->etdev->dev, test_ext.client_type, test_ext.cmd,
+ &client_info, info);
+
+ kfree(info);
+ return ret;
+}
+#endif /* EDGETPU_FEATURE_INTEROP */
+
long edgetpu_ioctl(struct file *file, uint cmd, ulong arg)
{
struct edgetpu_client *client = file->private_data;
@@ -776,7 +817,11 @@ long edgetpu_ioctl(struct file *file, uint cmd, ulong arg)
case EDGETPU_GET_FATAL_ERRORS:
ret = edgetpu_ioctl_get_fatal_errors(client, argp);
break;
-
+#ifdef EDGETPU_FEATURE_INTEROP
+ case EDGETPU_TEST_EXTERNAL:
+ ret = edgetpu_ioctl_test_external(client, argp);
+ break;
+#endif /* EDGETPU_FEATURE_INTEROP */
default:
return -ENOTTY; /* unknown command */
}