diff options
Diffstat (limited to 'drivers/gpu/nvgpu')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 30 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.h | 1 |
2 files changed, 21 insertions, 10 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c index c2a21b22..40766857 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c | |||
@@ -910,10 +910,8 @@ static void gk20a_wait_until_counter_is_N( | |||
910 | } | 910 | } |
911 | } | 911 | } |
912 | 912 | ||
913 | |||
914 | |||
915 | /* call ONLY when no references to the channel exist: after the last put */ | 913 | /* call ONLY when no references to the channel exist: after the last put */ |
916 | static void gk20a_free_channel(struct channel_gk20a *ch) | 914 | static void gk20a_free_channel(struct channel_gk20a *ch, bool force) |
917 | { | 915 | { |
918 | struct gk20a *g = ch->g; | 916 | struct gk20a *g = ch->g; |
919 | struct fifo_gk20a *f = &g->fifo; | 917 | struct fifo_gk20a *f = &g->fifo; |
@@ -935,9 +933,10 @@ static void gk20a_free_channel(struct channel_gk20a *ch) | |||
935 | gk20a_disable_channel(ch); | 933 | gk20a_disable_channel(ch); |
936 | 934 | ||
937 | /* wait until there's only our ref to the channel */ | 935 | /* wait until there's only our ref to the channel */ |
938 | gk20a_wait_until_counter_is_N( | 936 | if (!force) |
939 | ch, &ch->ref_count, 1, &ch->ref_count_dec_wq, | 937 | gk20a_wait_until_counter_is_N( |
940 | __func__, "references"); | 938 | ch, &ch->ref_count, 1, &ch->ref_count_dec_wq, |
939 | __func__, "references"); | ||
941 | 940 | ||
942 | /* wait until all pending interrupts for recently completed | 941 | /* wait until all pending interrupts for recently completed |
943 | * jobs are handled */ | 942 | * jobs are handled */ |
@@ -959,9 +958,10 @@ static void gk20a_free_channel(struct channel_gk20a *ch) | |||
959 | atomic_dec(&ch->ref_count); | 958 | atomic_dec(&ch->ref_count); |
960 | 959 | ||
961 | /* wait until no more refs to the channel */ | 960 | /* wait until no more refs to the channel */ |
962 | gk20a_wait_until_counter_is_N( | 961 | if (!force) |
963 | ch, &ch->ref_count, 0, &ch->ref_count_dec_wq, | 962 | gk20a_wait_until_counter_is_N( |
964 | __func__, "references"); | 963 | ch, &ch->ref_count, 0, &ch->ref_count_dec_wq, |
964 | __func__, "references"); | ||
965 | 965 | ||
966 | /* if engine reset was deferred, perform it now */ | 966 | /* if engine reset was deferred, perform it now */ |
967 | mutex_lock(&f->deferred_reset_mutex); | 967 | mutex_lock(&f->deferred_reset_mutex); |
@@ -1132,7 +1132,17 @@ void _gk20a_channel_put(struct channel_gk20a *ch, const char *caller) | |||
1132 | 1132 | ||
1133 | void gk20a_channel_close(struct channel_gk20a *ch) | 1133 | void gk20a_channel_close(struct channel_gk20a *ch) |
1134 | { | 1134 | { |
1135 | gk20a_free_channel(ch); | 1135 | gk20a_free_channel(ch, false); |
1136 | } | ||
1137 | |||
1138 | /* | ||
1139 | * Be careful with this - it is meant for terminating channels when we know the | ||
1140 | * driver is otherwise dying. Ref counts and the like are ignored by this | ||
1141 | * version of the cleanup. | ||
1142 | */ | ||
1143 | void __gk20a_channel_kill(struct channel_gk20a *ch) | ||
1144 | { | ||
1145 | gk20a_free_channel(ch, true); | ||
1136 | } | 1146 | } |
1137 | 1147 | ||
1138 | struct channel_gk20a *gk20a_get_channel_from_file(int fd) | 1148 | struct channel_gk20a *gk20a_get_channel_from_file(int fd) |
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h index 0ad1bbaa..ba9f332d 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h | |||
@@ -226,6 +226,7 @@ int gk20a_init_channel_support(struct gk20a *, u32 chid); | |||
226 | 226 | ||
227 | /* must be inside gk20a_busy()..gk20a_idle() */ | 227 | /* must be inside gk20a_busy()..gk20a_idle() */ |
228 | void gk20a_channel_close(struct channel_gk20a *ch); | 228 | void gk20a_channel_close(struct channel_gk20a *ch); |
229 | void __gk20a_channel_kill(struct channel_gk20a *ch); | ||
229 | 230 | ||
230 | bool gk20a_channel_update_and_check_timeout(struct channel_gk20a *ch, | 231 | bool gk20a_channel_update_and_check_timeout(struct channel_gk20a *ch, |
231 | u32 timeout_delta_ms, bool *progress); | 232 | u32 timeout_delta_ms, bool *progress); |