summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/nvgpu/include/nvgpu/gk20a.h3
-rw-r--r--drivers/gpu/nvgpu/os/linux/driver_common.c3
-rw-r--r--drivers/gpu/nvgpu/os/linux/module.c40
-rw-r--r--drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c22
4 files changed, 36 insertions, 32 deletions
diff --git a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h
index 0230709c..1ca6be0d 100644
--- a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h
+++ b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h
@@ -1446,8 +1446,7 @@ struct gk20a {
1446 unsigned int ch_wdt_timeout_ms; 1446 unsigned int ch_wdt_timeout_ms;
1447 u32 fifo_eng_timeout_us; 1447 u32 fifo_eng_timeout_us;
1448 1448
1449 struct nvgpu_mutex poweron_lock; 1449 struct nvgpu_mutex power_lock;
1450 struct nvgpu_mutex poweroff_lock;
1451 1450
1452 /* Channel priorities */ 1451 /* Channel priorities */
1453 u32 timeslice_low_priority_us; 1452 u32 timeslice_low_priority_us;
diff --git a/drivers/gpu/nvgpu/os/linux/driver_common.c b/drivers/gpu/nvgpu/os/linux/driver_common.c
index 6375030b..ebd0b40b 100644
--- a/drivers/gpu/nvgpu/os/linux/driver_common.c
+++ b/drivers/gpu/nvgpu/os/linux/driver_common.c
@@ -61,8 +61,7 @@ static void nvgpu_init_vars(struct gk20a *g)
61 nvgpu_mutex_init(&platform->railgate_lock); 61 nvgpu_mutex_init(&platform->railgate_lock);
62 nvgpu_mutex_init(&g->dbg_sessions_lock); 62 nvgpu_mutex_init(&g->dbg_sessions_lock);
63 nvgpu_mutex_init(&g->client_lock); 63 nvgpu_mutex_init(&g->client_lock);
64 nvgpu_mutex_init(&g->poweron_lock); 64 nvgpu_mutex_init(&g->power_lock);
65 nvgpu_mutex_init(&g->poweroff_lock);
66 nvgpu_mutex_init(&g->ctxsw_disable_lock); 65 nvgpu_mutex_init(&g->ctxsw_disable_lock);
67 nvgpu_mutex_init(&g->tpc_pg_lock); 66 nvgpu_mutex_init(&g->tpc_pg_lock);
68 nvgpu_mutex_init(&g->clk_arb_enable_lock); 67 nvgpu_mutex_init(&g->clk_arb_enable_lock);
diff --git a/drivers/gpu/nvgpu/os/linux/module.c b/drivers/gpu/nvgpu/os/linux/module.c
index 0d4cd7f1..9d84cc2f 100644
--- a/drivers/gpu/nvgpu/os/linux/module.c
+++ b/drivers/gpu/nvgpu/os/linux/module.c
@@ -129,18 +129,13 @@ int gk20a_busy(struct gk20a *g)
129 goto fail; 129 goto fail;
130 } 130 }
131 } else { 131 } else {
132 nvgpu_mutex_acquire(&g->poweron_lock); 132 ret = gk20a_gpu_is_virtual(dev) ?
133 if (!g->power_on) { 133 vgpu_pm_finalize_poweron(dev) :
134 ret = gk20a_gpu_is_virtual(dev) ? 134 gk20a_pm_finalize_poweron(dev);
135 vgpu_pm_finalize_poweron(dev) 135 if (ret) {
136 : gk20a_pm_finalize_poweron(dev); 136 atomic_dec(&g->usage_count.atomic_var);
137 if (ret) { 137 goto fail;
138 atomic_dec(&g->usage_count.atomic_var);
139 nvgpu_mutex_release(&g->poweron_lock);
140 goto fail;
141 }
142 } 138 }
143 nvgpu_mutex_release(&g->poweron_lock);
144 } 139 }
145 140
146fail: 141fail:
@@ -240,12 +235,14 @@ int gk20a_pm_finalize_poweron(struct device *dev)
240 struct gk20a *g = get_gk20a(dev); 235 struct gk20a *g = get_gk20a(dev);
241 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); 236 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
242 struct gk20a_platform *platform = gk20a_get_platform(dev); 237 struct gk20a_platform *platform = gk20a_get_platform(dev);
243 int err; 238 int err = 0;
244 239
245 nvgpu_log_fn(g, " "); 240 nvgpu_log_fn(g, " ");
246 241
242 nvgpu_mutex_acquire(&g->power_lock);
243
247 if (g->power_on) 244 if (g->power_on)
248 return 0; 245 goto done;
249 246
250 trace_gk20a_finalize_poweron(dev_name(dev)); 247 trace_gk20a_finalize_poweron(dev_name(dev));
251 248
@@ -254,13 +251,13 @@ int gk20a_pm_finalize_poweron(struct device *dev)
254 err = platform->busy(dev); 251 err = platform->busy(dev);
255 if (err < 0) { 252 if (err < 0) {
256 nvgpu_err(g, "failed to poweron platform dependency"); 253 nvgpu_err(g, "failed to poweron platform dependency");
257 return err; 254 goto done;
258 } 255 }
259 } 256 }
260 257
261 err = gk20a_restore_registers(g); 258 err = gk20a_restore_registers(g);
262 if (err) 259 if (err)
263 return err; 260 goto done;
264 261
265 /* Enable interrupt workqueue */ 262 /* Enable interrupt workqueue */
266 if (!l->nonstall_work_queue) { 263 if (!l->nonstall_work_queue) {
@@ -271,7 +268,7 @@ int gk20a_pm_finalize_poweron(struct device *dev)
271 268
272 err = gk20a_detect_chip(g); 269 err = gk20a_detect_chip(g);
273 if (err) 270 if (err)
274 return err; 271 goto done;
275 272
276 if (g->sim) { 273 if (g->sim) {
277 if (g->sim->sim_init_late) 274 if (g->sim->sim_init_late)
@@ -319,7 +316,7 @@ int gk20a_pm_finalize_poweron(struct device *dev)
319 err = gk20a_sched_ctrl_init(g); 316 err = gk20a_sched_ctrl_init(g);
320 if (err) { 317 if (err) {
321 nvgpu_err(g, "failed to init sched control"); 318 nvgpu_err(g, "failed to init sched control");
322 return err; 319 goto done;
323 } 320 }
324 321
325 g->sw_ready = true; 322 g->sw_ready = true;
@@ -328,6 +325,7 @@ done:
328 if (err) 325 if (err)
329 g->power_on = false; 326 g->power_on = false;
330 327
328 nvgpu_mutex_release(&g->power_lock);
331 return err; 329 return err;
332} 330}
333 331
@@ -356,13 +354,13 @@ static int gk20a_pm_prepare_poweroff(struct device *dev)
356#ifdef CONFIG_NVGPU_SUPPORT_CDE 354#ifdef CONFIG_NVGPU_SUPPORT_CDE
357 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); 355 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
358#endif 356#endif
359 int ret = 0;
360 struct gk20a_platform *platform = gk20a_get_platform(dev); 357 struct gk20a_platform *platform = gk20a_get_platform(dev);
361 bool irqs_enabled; 358 bool irqs_enabled;
359 int ret = 0;
362 360
363 nvgpu_log_fn(g, " "); 361 nvgpu_log_fn(g, " ");
364 362
365 nvgpu_mutex_acquire(&g->poweroff_lock); 363 nvgpu_mutex_acquire(&g->power_lock);
366 364
367 if (!g->power_on) 365 if (!g->power_on)
368 goto done; 366 goto done;
@@ -393,7 +391,7 @@ static int gk20a_pm_prepare_poweroff(struct device *dev)
393 /* Stop CPU from accessing the GPU registers. */ 391 /* Stop CPU from accessing the GPU registers. */
394 gk20a_lockout_registers(g); 392 gk20a_lockout_registers(g);
395 393
396 nvgpu_mutex_release(&g->poweroff_lock); 394 nvgpu_mutex_release(&g->power_lock);
397 return 0; 395 return 0;
398 396
399error: 397error:
@@ -407,7 +405,7 @@ error:
407 405
408 gk20a_scale_resume(dev); 406 gk20a_scale_resume(dev);
409done: 407done:
410 nvgpu_mutex_release(&g->poweroff_lock); 408 nvgpu_mutex_release(&g->power_lock);
411 409
412 return ret; 410 return ret;
413} 411}
diff --git a/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c b/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c
index 3fd944f4..7cf22d9d 100644
--- a/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c
+++ b/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c
@@ -72,8 +72,7 @@ static void vgpu_init_vars(struct gk20a *g, struct gk20a_platform *platform)
72{ 72{
73 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); 73 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
74 74
75 nvgpu_mutex_init(&g->poweron_lock); 75 nvgpu_mutex_init(&g->power_lock);
76 nvgpu_mutex_init(&g->poweroff_lock);
77 nvgpu_mutex_init(&g->ctxsw_disable_lock); 76 nvgpu_mutex_init(&g->ctxsw_disable_lock);
78 l->regs_saved = l->regs; 77 l->regs_saved = l->regs;
79 l->bar1_saved = l->bar1; 78 l->bar1_saved = l->bar1;
@@ -142,16 +141,19 @@ int vgpu_pm_prepare_poweroff(struct device *dev)
142 141
143 nvgpu_log_fn(g, " "); 142 nvgpu_log_fn(g, " ");
144 143
144 nvgpu_mutex_acquire(&g->power_lock);
145
145 if (!g->power_on) 146 if (!g->power_on)
146 return 0; 147 goto done;
147 148
148 if (g->ops.fifo.channel_suspend) 149 if (g->ops.fifo.channel_suspend)
149 ret = g->ops.fifo.channel_suspend(g); 150 ret = g->ops.fifo.channel_suspend(g);
150
151 if (ret) 151 if (ret)
152 return ret; 152 goto done;
153 153
154 g->power_on = false; 154 g->power_on = false;
155 done:
156 nvgpu_mutex_release(&g->power_lock);
155 157
156 return ret; 158 return ret;
157} 159}
@@ -160,12 +162,14 @@ int vgpu_pm_finalize_poweron(struct device *dev)
160{ 162{
161 struct gk20a *g = get_gk20a(dev); 163 struct gk20a *g = get_gk20a(dev);
162 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); 164 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
163 int err; 165 int err = 0;
164 166
165 nvgpu_log_fn(g, " "); 167 nvgpu_log_fn(g, " ");
166 168
169 nvgpu_mutex_acquire(&g->power_lock);
170
167 if (g->power_on) 171 if (g->power_on)
168 return 0; 172 goto done;
169 173
170 g->power_on = true; 174 g->power_on = true;
171 175
@@ -220,6 +224,10 @@ int vgpu_pm_finalize_poweron(struct device *dev)
220 g->sw_ready = true; 224 g->sw_ready = true;
221 225
222done: 226done:
227 if (err)
228 g->power_on = false;
229
230 nvgpu_mutex_release(&g->power_lock);
223 return err; 231 return err;
224} 232}
225 233