diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c index 80cddb322..d61656fc8 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c @@ -811,6 +811,48 @@ int gk20a_channel_open(struct inode *inode, struct file *filp) return ret; } +int gk20a_channel_open_ioctl(struct gk20a *g, + struct nvgpu_channel_open_args *args) +{ + 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, "nvhost-%s-fd%d", + dev_name(&g->dev->dev), fd); + if (!name) { + err = -ENOMEM; + goto clean_up; + } + + file = anon_inode_getfile(name, g->channel.cdev.ops, NULL, O_RDWR); + kfree(name); + if (IS_ERR(file)) { + err = PTR_ERR(file); + goto clean_up; + } + fd_install(fd, file); + + err = __gk20a_channel_open(g, file); + if (err) + goto clean_up_file; + + args->channel_fd = fd; + return 0; + +clean_up_file: + fput(file); +clean_up: + put_unused_fd(fd); + return err; +} + /* allocate private cmd buffer. used for inserting commands before/after user submitted buffers. */ static int channel_gk20a_alloc_priv_cmdbuf(struct channel_gk20a *c) @@ -2237,43 +2279,9 @@ long gk20a_channel_ioctl(struct file *filp, switch (cmd) { case NVGPU_IOCTL_CHANNEL_OPEN: - { - int fd; - struct file *file; - char *name; - - err = get_unused_fd_flags(O_RDWR); - if (err < 0) - break; - fd = err; - - name = kasprintf(GFP_KERNEL, "nvhost-%s-fd%d", - dev_name(&dev->dev), fd); - if (!name) { - err = -ENOMEM; - put_unused_fd(fd); - break; - } - - file = anon_inode_getfile(name, filp->f_op, NULL, O_RDWR); - kfree(name); - if (IS_ERR(file)) { - err = PTR_ERR(file); - put_unused_fd(fd); - break; - } - fd_install(fd, file); - - err = __gk20a_channel_open(ch->g, file); - if (err) { - put_unused_fd(fd); - fput(file); - break; - } - - ((struct nvgpu_channel_open_args *)buf)->channel_fd = fd; + err = gk20a_channel_open_ioctl(ch->g, + (struct nvgpu_channel_open_args *)buf); break; - } case NVGPU_IOCTL_CHANNEL_SET_NVMAP_FD: break; case NVGPU_IOCTL_CHANNEL_ALLOC_OBJ_CTX: diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h index 9982b1e0d..c028e3b1f 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h @@ -185,6 +185,8 @@ int gk20a_channel_resume(struct gk20a *g); /* Channel file operations */ int gk20a_channel_open(struct inode *inode, struct file *filp); +int gk20a_channel_open_ioctl(struct gk20a *g, + struct nvgpu_channel_open_args *args); long gk20a_channel_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); diff --git a/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c b/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c index c8fe34a81..d314e0788 100644 --- a/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, NVIDIA Corporation. All rights reserved. + * Copyright (c) 2011-2015, NVIDIA Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -421,6 +421,12 @@ long gk20a_ctrl_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg err = gk20a_ctrl_get_tpc_masks(g, (struct nvgpu_gpu_get_tpc_masks_args *)buf); break; + case NVGPU_GPU_IOCTL_OPEN_CHANNEL: + /* this arg type here, but ..gpu_open_channel_args in nvgpu.h + * for consistency - they are the same */ + err = gk20a_channel_open_ioctl(g, + (struct nvgpu_channel_open_args *)buf); + break; default: dev_dbg(dev_from_gk20a(g), "unrecognized gpu ioctl cmd: 0x%x", cmd); err = -ENOTTY; diff --git a/include/uapi/linux/nvgpu.h b/include/uapi/linux/nvgpu.h index 20acc66a0..1e4387754 100644 --- a/include/uapi/linux/nvgpu.h +++ b/include/uapi/linux/nvgpu.h @@ -1,7 +1,7 @@ /* * NVGPU Public Interface Header * - * Copyright (c) 2011-2014, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2011-2015, NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -238,6 +238,10 @@ struct nvgpu_gpu_get_tpc_masks_args { __u64 mask_buf_addr; }; +struct nvgpu_gpu_open_channel_args { + __s32 channel_fd; +}; + #define NVGPU_GPU_IOCTL_ZCULL_GET_CTX_SIZE \ _IOR(NVGPU_GPU_IOCTL_MAGIC, 1, struct nvgpu_gpu_zcull_get_ctx_size_args) #define NVGPU_GPU_IOCTL_ZCULL_GET_INFO \ @@ -258,9 +262,11 @@ struct nvgpu_gpu_get_tpc_masks_args { _IOWR(NVGPU_GPU_IOCTL_MAGIC, 9, struct nvgpu_gpu_open_tsg_args) #define NVGPU_GPU_IOCTL_GET_TPC_MASKS \ _IOWR(NVGPU_GPU_IOCTL_MAGIC, 10, struct nvgpu_gpu_get_tpc_masks_args) +#define NVGPU_GPU_IOCTL_OPEN_CHANNEL \ + _IOWR(NVGPU_GPU_IOCTL_MAGIC, 11, struct nvgpu_gpu_open_channel_args) #define NVGPU_GPU_IOCTL_LAST \ - _IOC_NR(NVGPU_GPU_IOCTL_GET_TPC_MASKS) + _IOC_NR(NVGPU_GPU_IOCTL_OPEN_CHANNEL) #define NVGPU_GPU_IOCTL_MAX_ARG_SIZE \ sizeof(struct nvgpu_gpu_prepare_compressible_read_args)