diff options
author | Deepak Nibade <dnibade@nvidia.com> | 2014-04-09 15:16:46 +0530 |
---|---|---|
committer | Seema Khowala <seemaj@nvidia.com> | 2014-04-23 14:04:36 -0700 |
commit | e732de4f19f0e628f2b77381f7a735f624673fbe (patch) | |
tree | e303bab0241a24fa537c6fc3b0ae4068f2e02c25 /drivers/video/tegra/host | |
parent | bf8d938ca0a4eeb79e90c0f067e436b9b2bfd6ca (diff) |
video: tegra: host: add syncpt get/free ioctls
Add below two new ioctls for client managed syncpts:
1) NVHOST_IOCTL_CHANNEL_GET_CLIENT_MANAGED_SYNCPOINT
To provide a client managed syncpt to user space
2) NVHOST_IOCTL_CHANNEL_FREE_CLIENT_MANAGED_SYNCPOINT
To free a client managed syncpt from user space
Bug 1482249
Bug 1305024
Change-Id: Ie9376c761024f2ad6e8a35633017153ca5cc8fe7
Signed-off-by: Deepak Nibade <dnibade@nvidia.com>
Reviewed-on: http://git-master/r/394158
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Tested-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/video/tegra/host')
-rw-r--r-- | drivers/video/tegra/host/bus_client.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/drivers/video/tegra/host/bus_client.c b/drivers/video/tegra/host/bus_client.c index 4c7c4eca1a07..d870da474ed4 100644 --- a/drivers/video/tegra/host/bus_client.c +++ b/drivers/video/tegra/host/bus_client.c @@ -781,6 +781,54 @@ static long nvhost_channelctl(struct file *filp, pdata->syncpts[arg->param] = arg->value; break; } + case NVHOST_IOCTL_CHANNEL_GET_CLIENT_MANAGED_SYNCPOINT: + { + char name[32]; + char set_name[32]; + struct nvhost_device_data *pdata = + platform_get_drvdata(priv->ch->dev); + struct nvhost_get_client_managed_syncpt_arg *args = + (struct nvhost_get_client_managed_syncpt_arg *)buf; + const char __user *args_name = + (const char __user *)(uintptr_t)args->name; + + if (args_name) { + if (strncpy_from_user(name, args_name, + sizeof(name)) < 0) + return -EFAULT; + name[sizeof(name) - 1] = '\0'; + } else { + name[0] = '\0'; + } + /* if we already have required syncpt then return it ... */ + if (pdata->client_managed_syncpt) { + args->value = pdata->client_managed_syncpt; + break; + } + /* ... otherwise get a new syncpt dynamically */ + snprintf(set_name, sizeof(set_name), + "%s_%s", dev_name(&pdata->pdev->dev), name); + args->value = nvhost_get_syncpt_client_managed(set_name); + if (!args->value) + return -EAGAIN; + /* ... and store it for further references */ + pdata->client_managed_syncpt = args->value; + break; + } + case NVHOST_IOCTL_CHANNEL_FREE_CLIENT_MANAGED_SYNCPOINT: + { + struct nvhost_free_client_managed_syncpt_arg *args = + (struct nvhost_free_client_managed_syncpt_arg *)buf; + struct nvhost_device_data *pdata = + platform_get_drvdata(priv->ch->dev); + if (!args->value) + break; + if (args->value != pdata->client_managed_syncpt) + return -EINVAL; + nvhost_free_syncpt(args->value); + pdata->client_managed_syncpt = 0; + break; + } case NVHOST_IOCTL_CHANNEL_GET_WAITBASES: { struct nvhost_device_data *pdata = \ |