diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 57 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.h | 21 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.h | 7 |
3 files changed, 19 insertions, 66 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c index 4be232f1..e01d6cdb 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c | |||
@@ -444,6 +444,9 @@ static void gk20a_free_channel(struct channel_gk20a *ch, bool force) | |||
444 | 444 | ||
445 | trace_gk20a_free_channel(ch->chid); | 445 | trace_gk20a_free_channel(ch->chid); |
446 | 446 | ||
447 | if (g->os_channel.close) | ||
448 | g->os_channel.close(ch); | ||
449 | |||
447 | /* | 450 | /* |
448 | * Disable channel/TSG and unbind here. This should not be executed if | 451 | * Disable channel/TSG and unbind here. This should not be executed if |
449 | * HW access is not available during shutdown/removal path as it will | 452 | * HW access is not available during shutdown/removal path as it will |
@@ -561,12 +564,6 @@ static void gk20a_free_channel(struct channel_gk20a *ch, bool force) | |||
561 | */ | 564 | */ |
562 | nvgpu_vm_put(ch_vm); | 565 | nvgpu_vm_put(ch_vm); |
563 | 566 | ||
564 | nvgpu_spinlock_acquire(&ch->update_fn_lock); | ||
565 | ch->update_fn = NULL; | ||
566 | ch->update_fn_data = NULL; | ||
567 | nvgpu_spinlock_release(&ch->update_fn_lock); | ||
568 | cancel_work_sync(&ch->update_fn_work); | ||
569 | |||
570 | /* make sure we don't have deferred interrupts pending that | 567 | /* make sure we don't have deferred interrupts pending that |
571 | * could still touch the channel */ | 568 | * could still touch the channel */ |
572 | nvgpu_wait_for_deferred_interrupts(g); | 569 | nvgpu_wait_for_deferred_interrupts(g); |
@@ -756,40 +753,6 @@ void __gk20a_channel_kill(struct channel_gk20a *ch) | |||
756 | gk20a_free_channel(ch, true); | 753 | gk20a_free_channel(ch, true); |
757 | } | 754 | } |
758 | 755 | ||
759 | static void gk20a_channel_update_runcb_fn(struct work_struct *work) | ||
760 | { | ||
761 | struct channel_gk20a *ch = | ||
762 | container_of(work, struct channel_gk20a, update_fn_work); | ||
763 | void (*update_fn)(struct channel_gk20a *, void *); | ||
764 | void *update_fn_data; | ||
765 | |||
766 | nvgpu_spinlock_acquire(&ch->update_fn_lock); | ||
767 | update_fn = ch->update_fn; | ||
768 | update_fn_data = ch->update_fn_data; | ||
769 | nvgpu_spinlock_release(&ch->update_fn_lock); | ||
770 | |||
771 | if (update_fn) | ||
772 | update_fn(ch, update_fn_data); | ||
773 | } | ||
774 | |||
775 | struct channel_gk20a *gk20a_open_new_channel_with_cb(struct gk20a *g, | ||
776 | void (*update_fn)(struct channel_gk20a *, void *), | ||
777 | void *update_fn_data, | ||
778 | int runlist_id, | ||
779 | bool is_privileged_channel) | ||
780 | { | ||
781 | struct channel_gk20a *ch = gk20a_open_new_channel(g, runlist_id, is_privileged_channel); | ||
782 | |||
783 | if (ch) { | ||
784 | nvgpu_spinlock_acquire(&ch->update_fn_lock); | ||
785 | ch->update_fn = update_fn; | ||
786 | ch->update_fn_data = update_fn_data; | ||
787 | nvgpu_spinlock_release(&ch->update_fn_lock); | ||
788 | } | ||
789 | |||
790 | return ch; | ||
791 | } | ||
792 | |||
793 | struct channel_gk20a *gk20a_open_new_channel(struct gk20a *g, | 756 | struct channel_gk20a *gk20a_open_new_channel(struct gk20a *g, |
794 | s32 runlist_id, | 757 | s32 runlist_id, |
795 | bool is_privileged_channel) | 758 | bool is_privileged_channel) |
@@ -872,10 +835,8 @@ struct channel_gk20a *gk20a_open_new_channel(struct gk20a *g, | |||
872 | nvgpu_cond_init(&ch->notifier_wq); | 835 | nvgpu_cond_init(&ch->notifier_wq); |
873 | nvgpu_cond_init(&ch->semaphore_wq); | 836 | nvgpu_cond_init(&ch->semaphore_wq); |
874 | 837 | ||
875 | ch->update_fn = NULL; | 838 | if (g->os_channel.open) |
876 | ch->update_fn_data = NULL; | 839 | g->os_channel.open(ch); |
877 | nvgpu_spinlock_init(&ch->update_fn_lock); | ||
878 | INIT_WORK(&ch->update_fn_work, gk20a_channel_update_runcb_fn); | ||
879 | 840 | ||
880 | /* Mark the channel alive, get-able, with 1 initial use | 841 | /* Mark the channel alive, get-able, with 1 initial use |
881 | * references. The initial reference will be decreased in | 842 | * references. The initial reference will be decreased in |
@@ -2120,8 +2081,8 @@ void gk20a_channel_clean_up_jobs(struct channel_gk20a *c, | |||
2120 | 2081 | ||
2121 | nvgpu_mutex_release(&c->joblist.cleanup_lock); | 2082 | nvgpu_mutex_release(&c->joblist.cleanup_lock); |
2122 | 2083 | ||
2123 | if (job_finished && c->update_fn) | 2084 | if (job_finished && g->os_channel.work_completion_signal) |
2124 | schedule_work(&c->update_fn_work); | 2085 | g->os_channel.work_completion_signal(c); |
2125 | 2086 | ||
2126 | gk20a_channel_put(c); | 2087 | gk20a_channel_put(c); |
2127 | } | 2088 | } |
@@ -2322,8 +2283,8 @@ int gk20a_channel_suspend(struct gk20a *g) | |||
2322 | /* preempt the channel */ | 2283 | /* preempt the channel */ |
2323 | gk20a_fifo_preempt(g, ch); | 2284 | gk20a_fifo_preempt(g, ch); |
2324 | /* wait for channel update notifiers */ | 2285 | /* wait for channel update notifiers */ |
2325 | if (ch->update_fn) | 2286 | if (g->os_channel.work_completion_cancel_sync) |
2326 | cancel_work_sync(&ch->update_fn_work); | 2287 | g->os_channel.work_completion_cancel_sync(ch); |
2327 | 2288 | ||
2328 | channels_in_use = true; | 2289 | channels_in_use = true; |
2329 | 2290 | ||
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h index d865849b..8c9095b2 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h | |||
@@ -24,9 +24,6 @@ | |||
24 | #ifndef CHANNEL_GK20A_H | 24 | #ifndef CHANNEL_GK20A_H |
25 | #define CHANNEL_GK20A_H | 25 | #define CHANNEL_GK20A_H |
26 | 26 | ||
27 | /* TODO: To be removed when work_struct update_fn_work is moved out of common code */ | ||
28 | #include <linux/workqueue.h> | ||
29 | |||
30 | #include <nvgpu/list.h> | 27 | #include <nvgpu/list.h> |
31 | #include <nvgpu/lock.h> | 28 | #include <nvgpu/lock.h> |
32 | #include <nvgpu/timers.h> | 29 | #include <nvgpu/timers.h> |
@@ -288,16 +285,6 @@ struct channel_gk20a { | |||
288 | u64 virt_ctx; | 285 | u64 virt_ctx; |
289 | #endif | 286 | #endif |
290 | 287 | ||
291 | /* | ||
292 | * Signal channel owner via a callback, if set, in job cleanup with | ||
293 | * schedule_work. Means that something finished on the channel (perhaps | ||
294 | * more than one job). | ||
295 | */ | ||
296 | void (*update_fn)(struct channel_gk20a *, void *); | ||
297 | void *update_fn_data; | ||
298 | struct nvgpu_spinlock update_fn_lock; /* make access to the two above atomic */ | ||
299 | struct work_struct update_fn_work; | ||
300 | |||
301 | u32 interleave_level; | 288 | u32 interleave_level; |
302 | 289 | ||
303 | u32 runlist_id; | 290 | u32 runlist_id; |
@@ -306,6 +293,9 @@ struct channel_gk20a { | |||
306 | #ifdef CONFIG_TEGRA_19x_GPU | 293 | #ifdef CONFIG_TEGRA_19x_GPU |
307 | struct channel_t19x t19x; | 294 | struct channel_t19x t19x; |
308 | #endif | 295 | #endif |
296 | |||
297 | /* Any operating system specific data. */ | ||
298 | void *os_priv; | ||
309 | }; | 299 | }; |
310 | 300 | ||
311 | static inline struct channel_gk20a * | 301 | static inline struct channel_gk20a * |
@@ -382,11 +372,6 @@ int gk20a_wait_channel_idle(struct channel_gk20a *ch); | |||
382 | struct channel_gk20a *gk20a_open_new_channel(struct gk20a *g, | 372 | struct channel_gk20a *gk20a_open_new_channel(struct gk20a *g, |
383 | s32 runlist_id, | 373 | s32 runlist_id, |
384 | bool is_privileged_channel); | 374 | bool is_privileged_channel); |
385 | struct channel_gk20a *gk20a_open_new_channel_with_cb(struct gk20a *g, | ||
386 | void (*update_fn)(struct channel_gk20a *, void *), | ||
387 | void *update_fn_data, | ||
388 | int runlist_id, | ||
389 | bool is_privileged_channel); | ||
390 | 375 | ||
391 | int gk20a_channel_alloc_gpfifo(struct channel_gk20a *c, | 376 | int gk20a_channel_alloc_gpfifo(struct channel_gk20a *c, |
392 | unsigned int num_entries, | 377 | unsigned int num_entries, |
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index 8d6db4c7..11a99bff 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h | |||
@@ -1255,6 +1255,13 @@ struct gk20a { | |||
1255 | struct nvgpu_mutex start_lock; | 1255 | struct nvgpu_mutex start_lock; |
1256 | } channel_worker; | 1256 | } channel_worker; |
1257 | 1257 | ||
1258 | struct { | ||
1259 | void (*open)(struct channel_gk20a *ch); | ||
1260 | void (*close)(struct channel_gk20a *ch); | ||
1261 | void (*work_completion_signal)(struct channel_gk20a *ch); | ||
1262 | void (*work_completion_cancel_sync)(struct channel_gk20a *ch); | ||
1263 | } os_channel; | ||
1264 | |||
1258 | struct gk20a_scale_profile *scale_profile; | 1265 | struct gk20a_scale_profile *scale_profile; |
1259 | unsigned long last_freq; | 1266 | unsigned long last_freq; |
1260 | 1267 | ||