diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/channel_gk20a.c')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c index f554cf77..f48ef35f 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c | |||
@@ -682,8 +682,11 @@ void gk20a_free_channel(struct channel_gk20a *ch, bool finish) | |||
682 | else | 682 | else |
683 | gk20a_vm_put(ch_vm); | 683 | gk20a_vm_put(ch_vm); |
684 | 684 | ||
685 | spin_lock(&ch->update_fn_lock); | ||
685 | ch->update_fn = NULL; | 686 | ch->update_fn = NULL; |
686 | ch->update_fn_data = NULL; | 687 | ch->update_fn_data = NULL; |
688 | spin_unlock(&ch->update_fn_lock); | ||
689 | cancel_work_sync(&ch->update_fn_work); | ||
687 | 690 | ||
688 | unbind: | 691 | unbind: |
689 | if (gk20a_is_channel_marked_as_tsg(ch)) | 692 | if (gk20a_is_channel_marked_as_tsg(ch)) |
@@ -745,7 +748,16 @@ static void gk20a_channel_update_runcb_fn(struct work_struct *work) | |||
745 | { | 748 | { |
746 | struct channel_gk20a *ch = | 749 | struct channel_gk20a *ch = |
747 | container_of(work, struct channel_gk20a, update_fn_work); | 750 | container_of(work, struct channel_gk20a, update_fn_work); |
748 | ch->update_fn(ch, ch->update_fn_data); | 751 | void (*update_fn)(struct channel_gk20a *, void *); |
752 | void *update_fn_data; | ||
753 | |||
754 | spin_lock(&ch->update_fn_lock); | ||
755 | update_fn = ch->update_fn; | ||
756 | update_fn_data = ch->update_fn_data; | ||
757 | spin_unlock(&ch->update_fn_lock); | ||
758 | |||
759 | if (update_fn) | ||
760 | update_fn(ch, update_fn_data); | ||
749 | } | 761 | } |
750 | 762 | ||
751 | struct channel_gk20a *gk20a_open_new_channel_with_cb(struct gk20a *g, | 763 | struct channel_gk20a *gk20a_open_new_channel_with_cb(struct gk20a *g, |
@@ -755,8 +767,10 @@ struct channel_gk20a *gk20a_open_new_channel_with_cb(struct gk20a *g, | |||
755 | struct channel_gk20a *ch = gk20a_open_new_channel(g); | 767 | struct channel_gk20a *ch = gk20a_open_new_channel(g); |
756 | 768 | ||
757 | if (ch) { | 769 | if (ch) { |
770 | spin_lock(&ch->update_fn_lock); | ||
758 | ch->update_fn = update_fn; | 771 | ch->update_fn = update_fn; |
759 | ch->update_fn_data = update_fn_data; | 772 | ch->update_fn_data = update_fn_data; |
773 | spin_unlock(&ch->update_fn_lock); | ||
760 | } | 774 | } |
761 | 775 | ||
762 | return ch; | 776 | return ch; |
@@ -811,7 +825,7 @@ struct channel_gk20a *gk20a_open_new_channel(struct gk20a *g) | |||
811 | 825 | ||
812 | ch->update_fn = NULL; | 826 | ch->update_fn = NULL; |
813 | ch->update_fn_data = NULL; | 827 | ch->update_fn_data = NULL; |
814 | 828 | spin_lock_init(&ch->update_fn_lock); | |
815 | INIT_WORK(&ch->update_fn_work, gk20a_channel_update_runcb_fn); | 829 | INIT_WORK(&ch->update_fn_work, gk20a_channel_update_runcb_fn); |
816 | 830 | ||
817 | return ch; | 831 | return ch; |