From 3446d89539253f88353672792c0e198b6220487e Mon Sep 17 00:00:00 2001 From: Terje Bergstrom Date: Wed, 15 Oct 2014 10:27:52 +0300 Subject: gpu: nvgpu: Add ioctl to create new TSG Add ioctl to nvhost-ctrl to create a new TSG. Bug 200042993 Change-Id: Icdd0edb1d9e374740ace6da9eb3a10c57c62617a Signed-off-by: Terje Bergstrom --- drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c | 44 ++++++++++++++++++++++++++++++++++++ drivers/gpu/nvgpu/gk20a/tsg_gk20a.c | 27 ++++++++++++++++++---- drivers/gpu/nvgpu/gk20a/tsg_gk20a.h | 1 + 3 files changed, 67 insertions(+), 5 deletions(-) (limited to 'drivers/gpu/nvgpu/gk20a') diff --git a/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c b/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c index fbc93fc3..93831844 100644 --- a/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include "gk20a.h" @@ -181,6 +182,45 @@ clean_up: return err; } +static int gk20a_ctrl_open_tsg(struct gk20a *g, + struct nvgpu_gpu_open_tsg_args *args) +{ + struct platform_device *dev = g->dev; + int err; + int fd; + struct file *file; + char *name; + + err = get_unused_fd_flags(O_RDWR); + if (err < 0) + return err; + fd = err; + + name = kasprintf(GFP_KERNEL, "nvgpu-%s-tsg%d", + dev_name(&dev->dev), fd); + + file = anon_inode_getfile(name, g->tsg.cdev.ops, NULL, O_RDWR); + kfree(name); + if (IS_ERR(file)) { + err = PTR_ERR(file); + goto clean_up; + } + fd_install(fd, file); + + err = gk20a_tsg_open(g, file); + if (err) + goto clean_up_file; + + args->tsg_fd = fd; + return 0; + +clean_up_file: + fput(file); +clean_up: + put_unused_fd(fd); + return err; +} + long gk20a_ctrl_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct platform_device *dev = filp->private_data; @@ -346,6 +386,10 @@ long gk20a_ctrl_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg err = gk20a_ctrl_alloc_as(g, (struct nvgpu_alloc_as_args *)buf); break; + case NVGPU_GPU_IOCTL_OPEN_TSG: + err = gk20a_ctrl_open_tsg(g, + (struct nvgpu_gpu_open_tsg_args *)buf); + break; default: dev_dbg(dev_from_gk20a(g), "unrecognized gpu ioctl cmd: 0x%x", cmd); err = -ENOTTY; diff --git a/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c b/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c index 073ae680..3342e3b9 100644 --- a/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c @@ -55,7 +55,13 @@ static bool gk20a_is_channel_active(struct gk20a *g, struct channel_gk20a *ch) static int gk20a_tsg_bind_channel(struct tsg_gk20a *tsg, int ch_fd) { struct file *f = fget(ch_fd); - struct channel_gk20a *ch = f->private_data; + struct channel_gk20a *ch; + + gk20a_dbg_fn(""); + + ch = gk20a_get_channel_from_file(ch_fd); + if (!ch) + return -EINVAL; /* check if channel is already bound to some TSG */ if (gk20a_is_channel_marked_as_tsg(ch)) { @@ -82,6 +88,7 @@ static int gk20a_tsg_bind_channel(struct tsg_gk20a *tsg, int ch_fd) fput(f); + gk20a_dbg_fn("done"); return 0; } @@ -144,14 +151,11 @@ static struct tsg_gk20a *acquire_unused_tsg(struct fifo_gk20a *f) return tsg; } -int gk20a_tsg_dev_open(struct inode *inode, struct file *filp) +int gk20a_tsg_open(struct gk20a *g, struct file *filp) { struct tsg_gk20a *tsg; - struct gk20a *g; struct device *dev; - g = container_of(inode->i_cdev, - struct gk20a, tsg.cdev); dev = dev_from_gk20a(g); gk20a_dbg(gpu_dbg_fn, "tsg: %s", dev_name(dev)); @@ -174,6 +178,19 @@ int gk20a_tsg_dev_open(struct inode *inode, struct file *filp) return 0; } +int gk20a_tsg_dev_open(struct inode *inode, struct file *filp) +{ + struct gk20a *g; + int ret; + + g = container_of(inode->i_cdev, + struct gk20a, tsg.cdev); + gk20a_dbg_fn(""); + ret = gk20a_tsg_open(g, filp); + gk20a_dbg_fn("done"); + return ret; +} + static void gk20a_tsg_release(struct kref *ref) { struct tsg_gk20a *tsg = container_of(ref, struct tsg_gk20a, refcount); diff --git a/drivers/gpu/nvgpu/gk20a/tsg_gk20a.h b/drivers/gpu/nvgpu/gk20a/tsg_gk20a.h index 4ad02996..fde33863 100644 --- a/drivers/gpu/nvgpu/gk20a/tsg_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/tsg_gk20a.h @@ -22,6 +22,7 @@ bool gk20a_is_channel_marked_as_tsg(struct channel_gk20a *ch); int gk20a_tsg_dev_release(struct inode *inode, struct file *filp); int gk20a_tsg_dev_open(struct inode *inode, struct file *filp); +int gk20a_tsg_open(struct gk20a *g, struct file *filp); long gk20a_tsg_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); -- cgit v1.2.2