summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/gk20a.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.c44
1 files changed, 26 insertions, 18 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c
index 2046c08e..694f0e93 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.c
@@ -334,26 +334,14 @@ static irqreturn_t gk20a_intr_thread_stall(int irq, void *dev_id)
334 return g->ops.mc.isr_thread_stall(g); 334 return g->ops.mc.isr_thread_stall(g);
335} 335}
336 336
337void gk20a_remove_support(struct device *dev) 337void gk20a_remove_support(struct gk20a *g)
338{ 338{
339 struct gk20a *g = get_gk20a(dev);
340
341#ifdef CONFIG_TEGRA_COMMON 339#ifdef CONFIG_TEGRA_COMMON
342 tegra_unregister_idle_unidle(); 340 tegra_unregister_idle_unidle();
343#endif 341#endif
344 if (g->dbg_regops_tmp_buf) 342 if (g->dbg_regops_tmp_buf)
345 kfree(g->dbg_regops_tmp_buf); 343 kfree(g->dbg_regops_tmp_buf);
346 344
347 nvgpu_wait_for_deferred_interrupts(g);
348
349 gk20a_channel_cancel_pending_sema_waits(g);
350
351 if (g->nonstall_work_queue) {
352 cancel_work_sync(&g->nonstall_fn_work);
353 destroy_workqueue(g->nonstall_work_queue);
354 g->nonstall_work_queue = NULL;
355 }
356
357 if (g->pmu.remove_support) 345 if (g->pmu.remove_support)
358 g->pmu.remove_support(&g->pmu); 346 g->pmu.remove_support(&g->pmu);
359 347
@@ -1251,6 +1239,11 @@ static int gk20a_probe(struct platform_device *dev)
1251 if (gk20a->irq_stall != gk20a->irq_nonstall) 1239 if (gk20a->irq_stall != gk20a->irq_nonstall)
1252 disable_irq(gk20a->irq_nonstall); 1240 disable_irq(gk20a->irq_nonstall);
1253 1241
1242 /*
1243 * is_fmodel needs to be in gk20a struct for deferred teardown
1244 */
1245 gk20a->is_fmodel = platform->is_fmodel;
1246
1254 err = gk20a_init_support(dev); 1247 err = gk20a_init_support(dev);
1255 if (err) 1248 if (err)
1256 return err; 1249 return err;
@@ -1297,11 +1290,6 @@ static int __exit gk20a_remove(struct platform_device *pdev)
1297 if (IS_ENABLED(CONFIG_GK20A_DEVFREQ)) 1290 if (IS_ENABLED(CONFIG_GK20A_DEVFREQ))
1298 gk20a_scale_exit(dev); 1291 gk20a_scale_exit(dev);
1299 1292
1300 if (g->remove_support)
1301 g->remove_support(dev);
1302
1303 gk20a_ce_destroy(g);
1304
1305#ifdef CONFIG_ARCH_TEGRA_18x_SOC 1293#ifdef CONFIG_ARCH_TEGRA_18x_SOC
1306 nvgpu_clk_arb_cleanup_arbiter(g); 1294 nvgpu_clk_arb_cleanup_arbiter(g);
1307#endif 1295#endif
@@ -1390,7 +1378,21 @@ void gk20a_busy_noresume(struct device *dev)
1390void gk20a_driver_start_unload(struct gk20a *g) 1378void gk20a_driver_start_unload(struct gk20a *g)
1391{ 1379{
1392 gk20a_dbg(gpu_dbg_shutdown, "Driver is now going down!\n"); 1380 gk20a_dbg(gpu_dbg_shutdown, "Driver is now going down!\n");
1381
1382 down_write(&g->busy_lock);
1393 g->driver_is_dying = 1; 1383 g->driver_is_dying = 1;
1384 up_write(&g->busy_lock);
1385
1386 gk20a_wait_for_idle(g->dev);
1387
1388 nvgpu_wait_for_deferred_interrupts(g);
1389 gk20a_channel_cancel_pending_sema_waits(g);
1390
1391 if (g->nonstall_work_queue) {
1392 cancel_work_sync(&g->nonstall_fn_work);
1393 destroy_workqueue(g->nonstall_work_queue);
1394 g->nonstall_work_queue = NULL;
1395 }
1394} 1396}
1395 1397
1396int gk20a_wait_for_idle(struct device *dev) 1398int gk20a_wait_for_idle(struct device *dev)
@@ -1859,6 +1861,12 @@ static void gk20a_free_cb(struct kref *refcount)
1859 struct gk20a, refcount); 1861 struct gk20a, refcount);
1860 1862
1861 gk20a_dbg(gpu_dbg_shutdown, "Freeing GK20A struct!"); 1863 gk20a_dbg(gpu_dbg_shutdown, "Freeing GK20A struct!");
1864
1865 gk20a_ce_destroy(g);
1866
1867 if (g->remove_support)
1868 g->remove_support(g);
1869
1862 kfree(g); 1870 kfree(g);
1863} 1871}
1864 1872