summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/common/linux/intr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/common/linux/intr.c')
-rw-r--r--drivers/gpu/nvgpu/common/linux/intr.c34
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
22irqreturn_t nvgpu_intr_stall(struct gk20a *g) 23irqreturn_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
45irqreturn_t nvgpu_intr_thread_stall(struct gk20a *g) 47irqreturn_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
126void nvgpu_intr_nonstall_cb(struct work_struct *work) 136void 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}