diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | 2 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/tsg_gk20a.c | 23 |
2 files changed, 22 insertions, 3 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c index 56ff4c87..6383b8c8 100644 --- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | |||
@@ -1779,7 +1779,7 @@ static int gk20a_fifo_update_runlist_locked(struct gk20a *g, u32 runlist_id, | |||
1779 | if (test_and_set_bit(hw_chid, | 1779 | if (test_and_set_bit(hw_chid, |
1780 | runlist->active_channels) == 1) | 1780 | runlist->active_channels) == 1) |
1781 | return 0; | 1781 | return 0; |
1782 | if (tsg && ++tsg->num_active_channels > 0) | 1782 | if (tsg && ++tsg->num_active_channels) |
1783 | set_bit(f->channel[hw_chid].tsgid, | 1783 | set_bit(f->channel[hw_chid].tsgid, |
1784 | runlist->active_tsgs); | 1784 | runlist->active_tsgs); |
1785 | } else { | 1785 | } else { |
diff --git a/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c b/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c index c84e8d0b..98e1ae2c 100644 --- a/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c | |||
@@ -27,13 +27,26 @@ | |||
27 | 27 | ||
28 | static void gk20a_tsg_release(struct kref *ref); | 28 | static void gk20a_tsg_release(struct kref *ref); |
29 | 29 | ||
30 | static void gk20a_tsg_release(struct kref *ref); | ||
31 | |||
32 | bool gk20a_is_channel_marked_as_tsg(struct channel_gk20a *ch) | 30 | bool gk20a_is_channel_marked_as_tsg(struct channel_gk20a *ch) |
33 | { | 31 | { |
34 | return !(ch->tsgid == NVGPU_INVALID_TSG_ID); | 32 | return !(ch->tsgid == NVGPU_INVALID_TSG_ID); |
35 | } | 33 | } |
36 | 34 | ||
35 | static bool gk20a_is_channel_active(struct gk20a *g, struct channel_gk20a *ch) | ||
36 | { | ||
37 | struct fifo_gk20a *f = &g->fifo; | ||
38 | struct fifo_runlist_info_gk20a *runlist; | ||
39 | int i; | ||
40 | |||
41 | for (i = 0; i < f->max_runlists; ++i) { | ||
42 | runlist = &f->runlist_info[i]; | ||
43 | if (test_bit(ch->hw_chid, runlist->active_channels)) | ||
44 | return true; | ||
45 | } | ||
46 | |||
47 | return false; | ||
48 | } | ||
49 | |||
37 | /* | 50 | /* |
38 | * API to mark channel as part of TSG | 51 | * API to mark channel as part of TSG |
39 | * | 52 | * |
@@ -50,6 +63,12 @@ static int gk20a_tsg_bind_channel(struct tsg_gk20a *tsg, int ch_fd) | |||
50 | return -EINVAL; | 63 | return -EINVAL; |
51 | } | 64 | } |
52 | 65 | ||
66 | /* channel cannot be bound to TSG if it is already active */ | ||
67 | if (gk20a_is_channel_active(tsg->g, ch)) { | ||
68 | fput(f); | ||
69 | return -EINVAL; | ||
70 | } | ||
71 | |||
53 | ch->tsgid = tsg->tsgid; | 72 | ch->tsgid = tsg->tsgid; |
54 | 73 | ||
55 | mutex_lock(&tsg->ch_list_lock); | 74 | mutex_lock(&tsg->ch_list_lock); |