diff options
Diffstat (limited to 'gxp-common-platform.c')
-rw-r--r-- | gxp-common-platform.c | 86 |
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); |