diff options
author | Terje Bergstrom <tbergstrom@nvidia.com> | 2014-10-15 03:27:52 -0400 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2015-03-18 15:11:50 -0400 |
commit | 3446d89539253f88353672792c0e198b6220487e (patch) | |
tree | 73f558758e1d9bb0ce0e3b2e9b2a756f5c8414c4 /drivers/gpu | |
parent | 3f3844a11ccac7957fdb7139a1c9c2a767d315a5 (diff) |
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 <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c | 44 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/tsg_gk20a.c | 27 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/tsg_gk20a.h | 1 |
3 files changed, 67 insertions, 5 deletions
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 @@ | |||
18 | #include <linux/cdev.h> | 18 | #include <linux/cdev.h> |
19 | #include <linux/file.h> | 19 | #include <linux/file.h> |
20 | #include <linux/anon_inodes.h> | 20 | #include <linux/anon_inodes.h> |
21 | #include <linux/nvgpu.h> | ||
21 | #include <uapi/linux/nvgpu.h> | 22 | #include <uapi/linux/nvgpu.h> |
22 | 23 | ||
23 | #include "gk20a.h" | 24 | #include "gk20a.h" |
@@ -181,6 +182,45 @@ clean_up: | |||
181 | return err; | 182 | return err; |
182 | } | 183 | } |
183 | 184 | ||
185 | static int gk20a_ctrl_open_tsg(struct gk20a *g, | ||
186 | struct nvgpu_gpu_open_tsg_args *args) | ||
187 | { | ||
188 | struct platform_device *dev = g->dev; | ||
189 | int err; | ||
190 | int fd; | ||
191 | struct file *file; | ||
192 | char *name; | ||
193 | |||
194 | err = get_unused_fd_flags(O_RDWR); | ||
195 | if (err < 0) | ||
196 | return err; | ||
197 | fd = err; | ||
198 | |||
199 | name = kasprintf(GFP_KERNEL, "nvgpu-%s-tsg%d", | ||
200 | dev_name(&dev->dev), fd); | ||
201 | |||
202 | file = anon_inode_getfile(name, g->tsg.cdev.ops, NULL, O_RDWR); | ||
203 | kfree(name); | ||
204 | if (IS_ERR(file)) { | ||
205 | err = PTR_ERR(file); | ||
206 | goto clean_up; | ||
207 | } | ||
208 | fd_install(fd, file); | ||
209 | |||
210 | err = gk20a_tsg_open(g, file); | ||
211 | if (err) | ||
212 | goto clean_up_file; | ||
213 | |||
214 | args->tsg_fd = fd; | ||
215 | return 0; | ||
216 | |||
217 | clean_up_file: | ||
218 | fput(file); | ||
219 | clean_up: | ||
220 | put_unused_fd(fd); | ||
221 | return err; | ||
222 | } | ||
223 | |||
184 | long gk20a_ctrl_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | 224 | long gk20a_ctrl_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
185 | { | 225 | { |
186 | struct platform_device *dev = filp->private_data; | 226 | 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 | |||
346 | err = gk20a_ctrl_alloc_as(g, | 386 | err = gk20a_ctrl_alloc_as(g, |
347 | (struct nvgpu_alloc_as_args *)buf); | 387 | (struct nvgpu_alloc_as_args *)buf); |
348 | break; | 388 | break; |
389 | case NVGPU_GPU_IOCTL_OPEN_TSG: | ||
390 | err = gk20a_ctrl_open_tsg(g, | ||
391 | (struct nvgpu_gpu_open_tsg_args *)buf); | ||
392 | break; | ||
349 | default: | 393 | default: |
350 | dev_dbg(dev_from_gk20a(g), "unrecognized gpu ioctl cmd: 0x%x", cmd); | 394 | dev_dbg(dev_from_gk20a(g), "unrecognized gpu ioctl cmd: 0x%x", cmd); |
351 | err = -ENOTTY; | 395 | 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) | |||
55 | static int gk20a_tsg_bind_channel(struct tsg_gk20a *tsg, int ch_fd) | 55 | static int gk20a_tsg_bind_channel(struct tsg_gk20a *tsg, int ch_fd) |
56 | { | 56 | { |
57 | struct file *f = fget(ch_fd); | 57 | struct file *f = fget(ch_fd); |
58 | struct channel_gk20a *ch = f->private_data; | 58 | struct channel_gk20a *ch; |
59 | |||
60 | gk20a_dbg_fn(""); | ||
61 | |||
62 | ch = gk20a_get_channel_from_file(ch_fd); | ||
63 | if (!ch) | ||
64 | return -EINVAL; | ||
59 | 65 | ||
60 | /* check if channel is already bound to some TSG */ | 66 | /* check if channel is already bound to some TSG */ |
61 | if (gk20a_is_channel_marked_as_tsg(ch)) { | 67 | 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) | |||
82 | 88 | ||
83 | fput(f); | 89 | fput(f); |
84 | 90 | ||
91 | gk20a_dbg_fn("done"); | ||
85 | return 0; | 92 | return 0; |
86 | } | 93 | } |
87 | 94 | ||
@@ -144,14 +151,11 @@ static struct tsg_gk20a *acquire_unused_tsg(struct fifo_gk20a *f) | |||
144 | return tsg; | 151 | return tsg; |
145 | } | 152 | } |
146 | 153 | ||
147 | int gk20a_tsg_dev_open(struct inode *inode, struct file *filp) | 154 | int gk20a_tsg_open(struct gk20a *g, struct file *filp) |
148 | { | 155 | { |
149 | struct tsg_gk20a *tsg; | 156 | struct tsg_gk20a *tsg; |
150 | struct gk20a *g; | ||
151 | struct device *dev; | 157 | struct device *dev; |
152 | 158 | ||
153 | g = container_of(inode->i_cdev, | ||
154 | struct gk20a, tsg.cdev); | ||
155 | dev = dev_from_gk20a(g); | 159 | dev = dev_from_gk20a(g); |
156 | 160 | ||
157 | gk20a_dbg(gpu_dbg_fn, "tsg: %s", dev_name(dev)); | 161 | 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) | |||
174 | return 0; | 178 | return 0; |
175 | } | 179 | } |
176 | 180 | ||
181 | int gk20a_tsg_dev_open(struct inode *inode, struct file *filp) | ||
182 | { | ||
183 | struct gk20a *g; | ||
184 | int ret; | ||
185 | |||
186 | g = container_of(inode->i_cdev, | ||
187 | struct gk20a, tsg.cdev); | ||
188 | gk20a_dbg_fn(""); | ||
189 | ret = gk20a_tsg_open(g, filp); | ||
190 | gk20a_dbg_fn("done"); | ||
191 | return ret; | ||
192 | } | ||
193 | |||
177 | static void gk20a_tsg_release(struct kref *ref) | 194 | static void gk20a_tsg_release(struct kref *ref) |
178 | { | 195 | { |
179 | struct tsg_gk20a *tsg = container_of(ref, struct tsg_gk20a, refcount); | 196 | 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); | |||
22 | 22 | ||
23 | int gk20a_tsg_dev_release(struct inode *inode, struct file *filp); | 23 | int gk20a_tsg_dev_release(struct inode *inode, struct file *filp); |
24 | int gk20a_tsg_dev_open(struct inode *inode, struct file *filp); | 24 | int gk20a_tsg_dev_open(struct inode *inode, struct file *filp); |
25 | int gk20a_tsg_open(struct gk20a *g, struct file *filp); | ||
25 | long gk20a_tsg_dev_ioctl(struct file *filp, | 26 | long gk20a_tsg_dev_ioctl(struct file *filp, |
26 | unsigned int cmd, unsigned long arg); | 27 | unsigned int cmd, unsigned long arg); |
27 | 28 | ||