summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/nvgpu/common/linux/ioctl_tsg.c46
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.c6
2 files changed, 48 insertions, 4 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/ioctl_tsg.c b/drivers/gpu/nvgpu/common/linux/ioctl_tsg.c
index d0bfd55a..4ef99ded 100644
--- a/drivers/gpu/nvgpu/common/linux/ioctl_tsg.c
+++ b/drivers/gpu/nvgpu/common/linux/ioctl_tsg.c
@@ -120,6 +120,33 @@ mutex_release:
120 return err; 120 return err;
121} 121}
122 122
123static int gk20a_tsg_unbind_channel_fd(struct tsg_gk20a *tsg, int ch_fd)
124{
125 struct channel_gk20a *ch;
126 int err = 0;
127
128 ch = gk20a_get_channel_from_file(ch_fd);
129 if (!ch)
130 return -EINVAL;
131
132 if (ch->tsgid != tsg->tsgid) {
133 err = -EINVAL;
134 goto out;
135 }
136
137 err = gk20a_tsg_unbind_channel(ch);
138
139 /*
140 * Mark the channel timedout since channel unbound from TSG
141 * has no context of its own so it can't serve any job
142 */
143 ch->has_timedout = true;
144
145out:
146 gk20a_channel_put(ch);
147 return err;
148}
149
123static int gk20a_tsg_get_event_data_from_id(struct tsg_gk20a *tsg, 150static int gk20a_tsg_get_event_data_from_id(struct tsg_gk20a *tsg,
124 unsigned int event_id, 151 unsigned int event_id,
125 struct gk20a_event_id_data **event_id_data) 152 struct gk20a_event_id_data **event_id_data)
@@ -552,10 +579,23 @@ long nvgpu_ioctl_tsg_dev_ioctl(struct file *filp, unsigned int cmd,
552 } 579 }
553 580
554 case NVGPU_TSG_IOCTL_UNBIND_CHANNEL: 581 case NVGPU_TSG_IOCTL_UNBIND_CHANNEL:
555 /* We do not support explicitly unbinding channel from TSG. 582 {
556 * Channel will be unbounded from TSG when it is closed. 583 int ch_fd = *(int *)buf;
557 */ 584
585 if (ch_fd < 0) {
586 err = -EINVAL;
587 break;
588 }
589 err = gk20a_busy(g);
590 if (err) {
591 nvgpu_err(g,
592 "failed to host gk20a for ioctl cmd: 0x%x", cmd);
593 break;
594 }
595 err = gk20a_tsg_unbind_channel_fd(tsg, ch_fd);
596 gk20a_idle(g);
558 break; 597 break;
598 }
559 599
560 case NVGPU_IOCTL_TSG_ENABLE: 600 case NVGPU_IOCTL_TSG_ENABLE:
561 { 601 {
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
index 21abdf9a..0c199146 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
@@ -314,7 +314,11 @@ static void gk20a_free_channel(struct channel_gk20a *ch, bool force)
314 "failed to unbind channel %d from TSG", 314 "failed to unbind channel %d from TSG",
315 ch->chid); 315 ch->chid);
316 } else { 316 } else {
317 gk20a_disable_channel(ch); 317 /*
318 * Channel is already unbound from TSG by User with
319 * explicit call
320 * Nothing to do here in that case
321 */
318 } 322 }
319 } 323 }
320 /* wait until there's only our ref to the channel */ 324 /* wait until there's only our ref to the channel */