summaryrefslogtreecommitdiff
path: root/gxp-common-platform.c
diff options
context:
space:
mode:
Diffstat (limited to 'gxp-common-platform.c')
-rw-r--r--gxp-common-platform.c86
1 files changed, 80 insertions, 6 deletions
diff --git a/gxp-common-platform.c b/gxp-common-platform.c
index d9ac532..e8c5572 100644
--- a/gxp-common-platform.c
+++ b/gxp-common-platform.c
@@ -22,6 +22,8 @@
#include <linux/uaccess.h>
#include <linux/uidgid.h>
+#include <gcip/gcip-dma-fence.h>
+
#include "gxp-client.h"
#include "gxp-config.h"
#include "gxp-core-telemetry.h"
@@ -570,8 +572,20 @@ static int gxp_allocate_vd(struct gxp_client *client,
ret = gxp_client_allocate_virtual_device(client, ibuf.core_count,
ibuf.flags);
up_write(&client->semaphore);
+ if (ret)
+ return ret;
- return ret;
+ ibuf.vdid = client->vd->vdid;
+ if (copy_to_user(argp, &ibuf, sizeof(ibuf))) {
+ /*
+ * VD will be released once the client FD has been closed, we
+ * don't need to release VD here as this branch should never
+ * happen in usual cases.
+ */
+ return -EFAULT;
+ }
+
+ return 0;
}
static int
@@ -875,7 +889,7 @@ static int map_tpu_mbx_queue(struct gxp_client *client,
down_read(&gxp->vd_semaphore);
core_count = client->vd->num_cores;
- phys_core_list = gxp_vd_phys_core_list(client->vd);
+ phys_core_list = client->vd->core_list;
mbx_info = kmalloc(
sizeof(struct edgetpu_ext_mailbox_info) +
@@ -1525,6 +1539,48 @@ out_unlock_client_semaphore:
return ret;
}
+static int gxp_register_invalidated_eventfd(
+ struct gxp_client *client,
+ struct gxp_register_invalidated_eventfd_ioctl __user *argp)
+{
+ struct gxp_register_invalidated_eventfd_ioctl ibuf;
+ struct gxp_eventfd *eventfd;
+ int ret = 0;
+
+ if (copy_from_user(&ibuf, argp, sizeof(ibuf)))
+ return -EFAULT;
+
+ down_write(&client->semaphore);
+
+ eventfd = gxp_eventfd_create(ibuf.eventfd);
+ if (IS_ERR(eventfd)) {
+ ret = PTR_ERR(eventfd);
+ goto out;
+ }
+
+ if (client->vd_invalid_eventfd)
+ gxp_eventfd_put(client->vd_invalid_eventfd);
+ client->vd_invalid_eventfd = eventfd;
+
+out:
+ up_write(&client->semaphore);
+ return ret;
+}
+
+static int gxp_unregister_invalidated_eventfd(
+ struct gxp_client *client,
+ struct gxp_register_invalidated_eventfd_ioctl __user *argp)
+{
+ down_write(&client->semaphore);
+
+ if (client->vd_invalid_eventfd)
+ gxp_eventfd_put(client->vd_invalid_eventfd);
+ client->vd_invalid_eventfd = NULL;
+
+ up_write(&client->semaphore);
+ return 0;
+}
+
static long gxp_ioctl(struct file *file, uint cmd, ulong arg)
{
struct gxp_client *client = file->private_data;
@@ -1616,6 +1672,12 @@ static long gxp_ioctl(struct file *file, uint cmd, ulong arg)
case GXP_TRIGGER_DEBUG_DUMP:
ret = gxp_trigger_debug_dump(client, argp);
break;
+ case GXP_REGISTER_INVALIDATED_EVENTFD:
+ ret = gxp_register_invalidated_eventfd(client, argp);
+ break;
+ case GXP_UNREGISTER_INVALIDATED_EVENTFD:
+ ret = gxp_unregister_invalidated_eventfd(client, argp);
+ break;
default:
ret = -ENOTTY; /* unknown command */
}
@@ -1846,10 +1908,11 @@ static int gxp_common_platform_probe(struct platform_device *pdev, struct gxp_de
if (ret)
return ret;
+ gxp_create_debugdir(gxp);
ret = gxp_wakelock_init(gxp);
if (ret) {
dev_err(dev, "failed to init wakelock: %d", ret);
- return ret;
+ goto err_remove_debugdir;
}
ret = gxp_pm_init(gxp);
@@ -1943,16 +2006,23 @@ static int gxp_common_platform_probe(struct platform_device *pdev, struct gxp_de
dev_warn(dev, "Failed to init thermal driver: %d\n", ret);
}
+ gxp->gfence_mgr = gcip_dma_fence_manager_create(gxp->dev);
+ if (IS_ERR(gxp->gfence_mgr)) {
+ ret = PTR_ERR(gxp->gfence_mgr);
+ dev_err(dev, "Failed to init DMA fence manager: %d\n", ret);
+ goto err_thermal_destroy;
+ }
+
INIT_LIST_HEAD(&gxp->client_list);
mutex_init(&gxp->client_list_lock);
if (gxp->after_probe) {
ret = gxp->after_probe(gxp);
if (ret)
- goto err_thermal_destroy;
+ goto err_dma_fence_destroy;
}
gxp->misc_dev.minor = MISC_DYNAMIC_MINOR;
- gxp->misc_dev.name = "gxp";
+ gxp->misc_dev.name = GXP_NAME;
gxp->misc_dev.fops = &gxp_fops;
ret = misc_register(&gxp->misc_dev);
if (ret) {
@@ -1969,6 +2039,8 @@ static int gxp_common_platform_probe(struct platform_device *pdev, struct gxp_de
err_before_remove:
if (gxp->before_remove)
gxp->before_remove(gxp);
+err_dma_fence_destroy:
+ /* DMA fence manager creation doesn't need revert */
err_thermal_destroy:
/* thermal init doesn't need revert */
gxp_core_telemetry_exit(gxp);
@@ -1992,6 +2064,8 @@ err_put_tpu_dev:
gxp_pm_destroy(gxp);
err_wakelock_destroy:
/* wakelock init doesn't need revert */
+err_remove_debugdir:
+ gxp_remove_debugdir(gxp);
return ret;
}
@@ -1999,7 +2073,7 @@ static int gxp_common_platform_remove(struct platform_device *pdev)
{
struct gxp_dev *gxp = platform_get_drvdata(pdev);
- gxp_remove_debugfs(gxp);
+ gxp_remove_debugdir(gxp);
misc_deregister(&gxp->misc_dev);
if (gxp->before_remove)
gxp->before_remove(gxp);