diff options
Diffstat (limited to 'drivers/gpu/nvgpu/common/linux/intr.c')
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/intr.c | 34 |
1 files changed, 23 insertions, 11 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/intr.c b/drivers/gpu/nvgpu/common/linux/intr.c index 7d699dee..da177b55 100644 --- a/drivers/gpu/nvgpu/common/linux/intr.c +++ b/drivers/gpu/nvgpu/common/linux/intr.c | |||
@@ -18,9 +18,11 @@ | |||
18 | 18 | ||
19 | #include <nvgpu/atomic.h> | 19 | #include <nvgpu/atomic.h> |
20 | #include <nvgpu/unit.h> | 20 | #include <nvgpu/unit.h> |
21 | #include "os_linux.h" | ||
21 | 22 | ||
22 | irqreturn_t nvgpu_intr_stall(struct gk20a *g) | 23 | irqreturn_t nvgpu_intr_stall(struct gk20a *g) |
23 | { | 24 | { |
25 | struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); | ||
24 | u32 mc_intr_0; | 26 | u32 mc_intr_0; |
25 | 27 | ||
26 | trace_mc_gk20a_intr_stall(g->name); | 28 | trace_mc_gk20a_intr_stall(g->name); |
@@ -35,7 +37,7 @@ irqreturn_t nvgpu_intr_stall(struct gk20a *g) | |||
35 | 37 | ||
36 | g->ops.mc.intr_stall_pause(g); | 38 | g->ops.mc.intr_stall_pause(g); |
37 | 39 | ||
38 | atomic_inc(&g->hw_irq_stall_count); | 40 | atomic_inc(&l->hw_irq_stall_count); |
39 | 41 | ||
40 | trace_mc_gk20a_intr_stall_done(g->name); | 42 | trace_mc_gk20a_intr_stall_done(g->name); |
41 | 43 | ||
@@ -44,14 +46,20 @@ irqreturn_t nvgpu_intr_stall(struct gk20a *g) | |||
44 | 46 | ||
45 | irqreturn_t nvgpu_intr_thread_stall(struct gk20a *g) | 47 | irqreturn_t nvgpu_intr_thread_stall(struct gk20a *g) |
46 | { | 48 | { |
49 | struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); | ||
50 | int hw_irq_count; | ||
51 | |||
47 | gk20a_dbg(gpu_dbg_intr, "interrupt thread launched"); | 52 | gk20a_dbg(gpu_dbg_intr, "interrupt thread launched"); |
48 | 53 | ||
49 | trace_mc_gk20a_intr_thread_stall(g->name); | 54 | trace_mc_gk20a_intr_thread_stall(g->name); |
50 | 55 | ||
56 | hw_irq_count = atomic_read(&l->hw_irq_stall_count); | ||
51 | g->ops.mc.isr_stall(g); | 57 | g->ops.mc.isr_stall(g); |
52 | g->ops.mc.intr_stall_resume(g); | 58 | g->ops.mc.intr_stall_resume(g); |
59 | /* sync handled irq counter before re-enabling interrupts */ | ||
60 | atomic_set(&l->sw_irq_stall_last_handled, hw_irq_count); | ||
53 | 61 | ||
54 | wake_up_all(&g->sw_irq_stall_last_handled_wq); | 62 | wake_up_all(&l->sw_irq_stall_last_handled_wq); |
55 | 63 | ||
56 | trace_mc_gk20a_intr_thread_stall_done(g->name); | 64 | trace_mc_gk20a_intr_thread_stall_done(g->name); |
57 | 65 | ||
@@ -66,6 +74,8 @@ irqreturn_t nvgpu_intr_nonstall(struct gk20a *g) | |||
66 | u32 active_engine_id = 0; | 74 | u32 active_engine_id = 0; |
67 | u32 engine_enum = ENGINE_INVAL_GK20A; | 75 | u32 engine_enum = ENGINE_INVAL_GK20A; |
68 | int ops_old, ops_new, ops = 0; | 76 | int ops_old, ops_new, ops = 0; |
77 | struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); | ||
78 | |||
69 | if (!g->power_on) | 79 | if (!g->power_on) |
70 | return IRQ_NONE; | 80 | return IRQ_NONE; |
71 | 81 | ||
@@ -103,34 +113,36 @@ irqreturn_t nvgpu_intr_nonstall(struct gk20a *g) | |||
103 | } | 113 | } |
104 | if (ops) { | 114 | if (ops) { |
105 | do { | 115 | do { |
106 | ops_old = atomic_read(&g->nonstall_ops); | 116 | ops_old = atomic_read(&l->nonstall_ops); |
107 | ops_new = ops_old | ops; | 117 | ops_new = ops_old | ops; |
108 | } while (ops_old != atomic_cmpxchg(&g->nonstall_ops, | 118 | } while (ops_old != atomic_cmpxchg(&l->nonstall_ops, |
109 | ops_old, ops_new)); | 119 | ops_old, ops_new)); |
110 | 120 | ||
111 | queue_work(g->nonstall_work_queue, &g->nonstall_fn_work); | 121 | queue_work(l->nonstall_work_queue, &l->nonstall_fn_work); |
112 | } | 122 | } |
113 | 123 | ||
114 | hw_irq_count = atomic_inc_return(&g->hw_irq_nonstall_count); | 124 | hw_irq_count = atomic_inc_return(&l->hw_irq_nonstall_count); |
115 | 125 | ||
116 | /* sync handled irq counter before re-enabling interrupts */ | 126 | /* sync handled irq counter before re-enabling interrupts */ |
117 | atomic_set(&g->sw_irq_nonstall_last_handled, hw_irq_count); | 127 | atomic_set(&l->sw_irq_nonstall_last_handled, hw_irq_count); |
118 | 128 | ||
119 | g->ops.mc.intr_nonstall_resume(g); | 129 | g->ops.mc.intr_nonstall_resume(g); |
120 | 130 | ||
121 | wake_up_all(&g->sw_irq_nonstall_last_handled_wq); | 131 | wake_up_all(&l->sw_irq_nonstall_last_handled_wq); |
122 | 132 | ||
123 | return IRQ_HANDLED; | 133 | return IRQ_HANDLED; |
124 | } | 134 | } |
125 | 135 | ||
126 | void nvgpu_intr_nonstall_cb(struct work_struct *work) | 136 | void nvgpu_intr_nonstall_cb(struct work_struct *work) |
127 | { | 137 | { |
128 | struct gk20a *g = container_of(work, struct gk20a, nonstall_fn_work); | 138 | struct nvgpu_os_linux *l = |
139 | container_of(work, struct nvgpu_os_linux, nonstall_fn_work); | ||
140 | struct gk20a *g = &l->g; | ||
129 | u32 ops; | 141 | u32 ops; |
130 | bool semaphore_wakeup, post_events; | 142 | bool semaphore_wakeup, post_events; |
131 | 143 | ||
132 | do { | 144 | do { |
133 | ops = atomic_xchg(&g->nonstall_ops, 0); | 145 | ops = atomic_xchg(&l->nonstall_ops, 0); |
134 | 146 | ||
135 | semaphore_wakeup = ops & gk20a_nonstall_ops_wakeup_semaphore; | 147 | semaphore_wakeup = ops & gk20a_nonstall_ops_wakeup_semaphore; |
136 | post_events = ops & gk20a_nonstall_ops_post_events; | 148 | post_events = ops & gk20a_nonstall_ops_post_events; |
@@ -138,5 +150,5 @@ void nvgpu_intr_nonstall_cb(struct work_struct *work) | |||
138 | if (semaphore_wakeup) | 150 | if (semaphore_wakeup) |
139 | gk20a_channel_semaphore_wakeup(g, post_events); | 151 | gk20a_channel_semaphore_wakeup(g, post_events); |
140 | 152 | ||
141 | } while (atomic_read(&g->nonstall_ops) != 0); | 153 | } while (atomic_read(&l->nonstall_ops) != 0); |
142 | } | 154 | } |