summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Nieto <dmartineznie@nvidia.com>2017-03-13 23:23:03 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2017-03-25 05:06:55 -0400
commite0f2afe5eb43fb32490ccabd504879c3e3e54623 (patch)
treed227311914fd44e88e1ab13b652870c0fa772cf1
parentb48186488d0108dee7b3fb755b2d99f4652780df (diff)
gpu: nvgpu: refactor teardown to support unbind
This change refactors the teardown in remove to ensure that it is possible to unload the driver while leaving fds open. This is achieved by making sure that the SW state is kept alive till all fds are closed and by checking that subsequent calls to ioctls after the teardown fail. Normally, this would be achieved ny calls into gk20a_busy(), but in kickoff we dont call into that to reduce latency, so we need to check the driver status directly, and also in some of the functions as we need to make sure the ioctl does not dereference the device or platform struct bug 200277762 JIRA: EVLR-1023 Change-Id: I163e47a08c29d4d5b3ab79f0eb531ef234f40bde Signed-off-by: David Nieto <dmartineznie@nvidia.com> Reviewed-on: http://git-master/r/1320219 Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-by: svccoveritychecker <svccoveritychecker@nvidia.com> Reviewed-by: Shreshtha Sahu <ssahu@nvidia.com> Reviewed-by: Vijayakumar Subbu <vsubbu@nvidia.com>
-rw-r--r--drivers/gpu/nvgpu/gk20a/ce2_gk20a.c6
-rw-r--r--drivers/gpu/nvgpu/gk20a/ce2_gk20a.h3
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.c22
-rw-r--r--drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c3
-rw-r--r--drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c24
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.c44
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.h7
-rw-r--r--drivers/gpu/nvgpu/gk20a/mm_gk20a.c21
-rw-r--r--drivers/gpu/nvgpu/pci.c11
-rw-r--r--drivers/gpu/nvgpu/vgpu/vgpu.c11
10 files changed, 91 insertions, 61 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/ce2_gk20a.c b/drivers/gpu/nvgpu/gk20a/ce2_gk20a.c
index 921ee6f8..5dfd2309 100644
--- a/drivers/gpu/nvgpu/gk20a/ce2_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/ce2_gk20a.c
@@ -690,6 +690,12 @@ void gk20a_ce_delete_context(struct device *dev,
690 u32 ce_ctx_id) 690 u32 ce_ctx_id)
691{ 691{
692 struct gk20a *g = gk20a_from_dev(dev); 692 struct gk20a *g = gk20a_from_dev(dev);
693 gk20a_ce_delete_context_priv(g, ce_ctx_id);
694}
695
696void gk20a_ce_delete_context_priv(struct gk20a *g,
697 u32 ce_ctx_id)
698{
693 struct gk20a_ce_app *ce_app = &g->ce_app; 699 struct gk20a_ce_app *ce_app = &g->ce_app;
694 struct gk20a_gpu_ctx *ce_ctx, *ce_ctx_save; 700 struct gk20a_gpu_ctx *ce_ctx, *ce_ctx_save;
695 701
diff --git a/drivers/gpu/nvgpu/gk20a/ce2_gk20a.h b/drivers/gpu/nvgpu/gk20a/ce2_gk20a.h
index 5cdd233e..7ecf130f 100644
--- a/drivers/gpu/nvgpu/gk20a/ce2_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/ce2_gk20a.h
@@ -144,9 +144,12 @@ int gk20a_ce_execute_ops(struct device *dev,
144 struct gk20a_fence *gk20a_fence_in, 144 struct gk20a_fence *gk20a_fence_in,
145 u32 submit_flags, 145 u32 submit_flags,
146 struct gk20a_fence **gk20a_fence_out); 146 struct gk20a_fence **gk20a_fence_out);
147void gk20a_ce_delete_context_priv(struct gk20a *g,
148 u32 ce_ctx_id);
147void gk20a_ce_delete_context(struct device *dev, 149void gk20a_ce_delete_context(struct device *dev,
148 u32 ce_ctx_id); 150 u32 ce_ctx_id);
149 151
152
150#ifdef CONFIG_DEBUG_FS 153#ifdef CONFIG_DEBUG_FS
151/* CE app debugfs api */ 154/* CE app debugfs api */
152void gk20a_ce_debugfs_init(struct device *dev); 155void gk20a_ce_debugfs_init(struct device *dev);
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
index 0249a1c6..d0d38f83 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
@@ -122,7 +122,8 @@ static struct channel_gk20a *allocate_channel(struct fifo_gk20a *f)
122static void free_channel(struct fifo_gk20a *f, 122static void free_channel(struct fifo_gk20a *f,
123 struct channel_gk20a *ch) 123 struct channel_gk20a *ch)
124{ 124{
125 struct gk20a_platform *platform = gk20a_get_platform(f->g->dev); 125 struct gk20a_platform *platform;
126 struct gk20a *g = f->g;
126 127
127 trace_gk20a_release_used_channel(ch->hw_chid); 128 trace_gk20a_release_used_channel(ch->hw_chid);
128 /* refcount is zero here and channel is in a freed/dead state */ 129 /* refcount is zero here and channel is in a freed/dead state */
@@ -132,10 +133,18 @@ static void free_channel(struct fifo_gk20a *f,
132 f->used_channels--; 133 f->used_channels--;
133 nvgpu_mutex_release(&f->free_chs_mutex); 134 nvgpu_mutex_release(&f->free_chs_mutex);
134 135
135 if (platform->aggressive_sync_destroy_thresh && 136 /*
137 * On teardown it is not possible to dereference platform, but ignoring
138 * this is fine then because no new channels would be created.
139 */
140 if (!g->driver_is_dying) {
141 platform = gk20a_get_platform(g->dev);
142
143 if (platform->aggressive_sync_destroy_thresh &&
136 (f->used_channels < 144 (f->used_channels <
137 platform->aggressive_sync_destroy_thresh)) 145 platform->aggressive_sync_destroy_thresh))
138 platform->aggressive_sync_destroy = false; 146 platform->aggressive_sync_destroy = false;
147 }
139} 148}
140 149
141int channel_gk20a_commit_va(struct channel_gk20a *c) 150int channel_gk20a_commit_va(struct channel_gk20a *c)
@@ -3016,7 +3025,12 @@ int gk20a_submit_channel_gpfifo(struct channel_gk20a *c,
3016 bool need_deferred_cleanup = false; 3025 bool need_deferred_cleanup = false;
3017 struct nvgpu_gpfifo __user *user_gpfifo = args ? 3026 struct nvgpu_gpfifo __user *user_gpfifo = args ?
3018 (struct nvgpu_gpfifo __user *)(uintptr_t)args->gpfifo : NULL; 3027 (struct nvgpu_gpfifo __user *)(uintptr_t)args->gpfifo : NULL;
3019 struct gk20a_platform *platform = gk20a_get_platform(d); 3028 struct gk20a_platform *platform;
3029
3030 if (g->driver_is_dying)
3031 return -ENODEV;
3032
3033 platform = gk20a_get_platform(d);
3020 3034
3021 if (c->has_timedout) 3035 if (c->has_timedout)
3022 return -ETIMEDOUT; 3036 return -ETIMEDOUT;
diff --git a/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c b/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c
index c87226c8..1ae42337 100644
--- a/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c
@@ -1344,8 +1344,7 @@ static int nvgpu_gpu_set_therm_alert_limit(struct gk20a *g,
1344long gk20a_ctrl_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 1344long gk20a_ctrl_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
1345{ 1345{
1346 struct gk20a_ctrl_priv *priv = filp->private_data; 1346 struct gk20a_ctrl_priv *priv = filp->private_data;
1347 struct device *dev = priv->dev; 1347 struct gk20a *g = priv->g;
1348 struct gk20a *g = get_gk20a(dev);
1349 struct nvgpu_gpu_zcull_get_ctx_size_args *get_ctx_size_args; 1348 struct nvgpu_gpu_zcull_get_ctx_size_args *get_ctx_size_args;
1350 struct nvgpu_gpu_zcull_get_info_args *get_info_args; 1349 struct nvgpu_gpu_zcull_get_info_args *get_info_args;
1351 struct nvgpu_gpu_zbc_set_table_args *set_table_args; 1350 struct nvgpu_gpu_zbc_set_table_args *set_table_args;
diff --git a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c
index db534318..165bcf46 100644
--- a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c
@@ -665,7 +665,7 @@ static int nvgpu_dbg_gpu_ioctl_timeout(struct dbg_session_gk20a *dbg_s,
665 struct nvgpu_dbg_gpu_timeout_args *args) 665 struct nvgpu_dbg_gpu_timeout_args *args)
666{ 666{
667 int err; 667 int err;
668 struct gk20a *g = get_gk20a(dbg_s->dev); 668 struct gk20a *g = dbg_s->g;
669 669
670 gk20a_dbg_fn("powergate mode = %d", args->enable); 670 gk20a_dbg_fn("powergate mode = %d", args->enable);
671 671
@@ -680,7 +680,7 @@ static void nvgpu_dbg_gpu_ioctl_get_timeout(struct dbg_session_gk20a *dbg_s,
680 struct nvgpu_dbg_gpu_timeout_args *args) 680 struct nvgpu_dbg_gpu_timeout_args *args)
681{ 681{
682 int status; 682 int status;
683 struct gk20a *g = get_gk20a(dbg_s->dev); 683 struct gk20a *g = dbg_s->g;
684 684
685 nvgpu_mutex_acquire(&g->dbg_sessions_lock); 685 nvgpu_mutex_acquire(&g->dbg_sessions_lock);
686 status = g->timeouts_enabled; 686 status = g->timeouts_enabled;
@@ -711,7 +711,7 @@ static int nvgpu_dbg_gpu_ioctl_read_single_sm_error_state(
711 struct dbg_session_gk20a *dbg_s, 711 struct dbg_session_gk20a *dbg_s,
712 struct nvgpu_dbg_gpu_read_single_sm_error_state_args *args) 712 struct nvgpu_dbg_gpu_read_single_sm_error_state_args *args)
713{ 713{
714 struct gk20a *g = get_gk20a(dbg_s->dev); 714 struct gk20a *g = dbg_s->g;
715 struct gr_gk20a *gr = &g->gr; 715 struct gr_gk20a *gr = &g->gr;
716 struct nvgpu_dbg_gpu_sm_error_state_record *sm_error_state; 716 struct nvgpu_dbg_gpu_sm_error_state_record *sm_error_state;
717 u32 sm_id; 717 u32 sm_id;
@@ -750,7 +750,7 @@ static int nvgpu_dbg_gpu_ioctl_clear_single_sm_error_state(
750 struct dbg_session_gk20a *dbg_s, 750 struct dbg_session_gk20a *dbg_s,
751 struct nvgpu_dbg_gpu_clear_single_sm_error_state_args *args) 751 struct nvgpu_dbg_gpu_clear_single_sm_error_state_args *args)
752{ 752{
753 struct gk20a *g = get_gk20a(dbg_s->dev); 753 struct gk20a *g = dbg_s->g;
754 struct gr_gk20a *gr = &g->gr; 754 struct gr_gk20a *gr = &g->gr;
755 u32 sm_id; 755 u32 sm_id;
756 struct channel_gk20a *ch; 756 struct channel_gk20a *ch;
@@ -781,7 +781,7 @@ static int nvgpu_dbg_gpu_ioctl_write_single_sm_error_state(
781 struct dbg_session_gk20a *dbg_s, 781 struct dbg_session_gk20a *dbg_s,
782 struct nvgpu_dbg_gpu_write_single_sm_error_state_args *args) 782 struct nvgpu_dbg_gpu_write_single_sm_error_state_args *args)
783{ 783{
784 struct gk20a *g = get_gk20a(dbg_s->dev); 784 struct gk20a *g = dbg_s->g;
785 struct gr_gk20a *gr = &g->gr; 785 struct gr_gk20a *gr = &g->gr;
786 u32 sm_id; 786 u32 sm_id;
787 struct channel_gk20a *ch; 787 struct channel_gk20a *ch;
@@ -952,7 +952,7 @@ long gk20a_dbg_gpu_dev_ioctl(struct file *filp, unsigned int cmd,
952 unsigned long arg) 952 unsigned long arg)
953{ 953{
954 struct dbg_session_gk20a *dbg_s = filp->private_data; 954 struct dbg_session_gk20a *dbg_s = filp->private_data;
955 struct gk20a *g = get_gk20a(dbg_s->dev); 955 struct gk20a *g = dbg_s->g;
956 u8 buf[NVGPU_DBG_GPU_IOCTL_MAX_ARG_SIZE]; 956 u8 buf[NVGPU_DBG_GPU_IOCTL_MAX_ARG_SIZE];
957 int err = 0; 957 int err = 0;
958 958
@@ -1141,7 +1141,7 @@ static int nvgpu_ioctl_channel_reg_ops(struct dbg_session_gk20a *dbg_s,
1141 bool is_pg_disabled = false; 1141 bool is_pg_disabled = false;
1142 1142
1143 struct device *dev = dbg_s->dev; 1143 struct device *dev = dbg_s->dev;
1144 struct gk20a *g = get_gk20a(dbg_s->dev); 1144 struct gk20a *g = dbg_s->g;
1145 struct channel_gk20a *ch; 1145 struct channel_gk20a *ch;
1146 1146
1147 gk20a_dbg_fn("%d ops, max fragment %d", args->num_ops, g->dbg_regops_tmp_buf_ops); 1147 gk20a_dbg_fn("%d ops, max fragment %d", args->num_ops, g->dbg_regops_tmp_buf_ops);
@@ -1257,7 +1257,7 @@ static int nvgpu_ioctl_channel_reg_ops(struct dbg_session_gk20a *dbg_s,
1257static int dbg_set_powergate(struct dbg_session_gk20a *dbg_s, u32 powermode) 1257static int dbg_set_powergate(struct dbg_session_gk20a *dbg_s, u32 powermode)
1258{ 1258{
1259 int err = 0; 1259 int err = 0;
1260 struct gk20a *g = get_gk20a(dbg_s->dev); 1260 struct gk20a *g = dbg_s->g;
1261 1261
1262 /* This function must be called with g->dbg_sessions_lock held */ 1262 /* This function must be called with g->dbg_sessions_lock held */
1263 1263
@@ -1360,7 +1360,7 @@ static int nvgpu_ioctl_powergate_gk20a(struct dbg_session_gk20a *dbg_s,
1360 struct nvgpu_dbg_gpu_powergate_args *args) 1360 struct nvgpu_dbg_gpu_powergate_args *args)
1361{ 1361{
1362 int err; 1362 int err;
1363 struct gk20a *g = get_gk20a(dbg_s->dev); 1363 struct gk20a *g = dbg_s->g;
1364 gk20a_dbg_fn("%s powergate mode = %d", 1364 gk20a_dbg_fn("%s powergate mode = %d",
1365 dev_name(dbg_s->dev), args->mode); 1365 dev_name(dbg_s->dev), args->mode);
1366 1366
@@ -1374,7 +1374,7 @@ static int nvgpu_dbg_gpu_ioctl_smpc_ctxsw_mode(struct dbg_session_gk20a *dbg_s,
1374 struct nvgpu_dbg_gpu_smpc_ctxsw_mode_args *args) 1374 struct nvgpu_dbg_gpu_smpc_ctxsw_mode_args *args)
1375{ 1375{
1376 int err; 1376 int err;
1377 struct gk20a *g = get_gk20a(dbg_s->dev); 1377 struct gk20a *g = dbg_s->g;
1378 struct channel_gk20a *ch_gk20a; 1378 struct channel_gk20a *ch_gk20a;
1379 1379
1380 gk20a_dbg_fn("%s smpc ctxsw mode = %d", 1380 gk20a_dbg_fn("%s smpc ctxsw mode = %d",
@@ -1416,7 +1416,7 @@ static int nvgpu_dbg_gpu_ioctl_hwpm_ctxsw_mode(struct dbg_session_gk20a *dbg_s,
1416 struct nvgpu_dbg_gpu_hwpm_ctxsw_mode_args *args) 1416 struct nvgpu_dbg_gpu_hwpm_ctxsw_mode_args *args)
1417{ 1417{
1418 int err; 1418 int err;
1419 struct gk20a *g = get_gk20a(dbg_s->dev); 1419 struct gk20a *g = dbg_s->g;
1420 struct channel_gk20a *ch_gk20a; 1420 struct channel_gk20a *ch_gk20a;
1421 1421
1422 gk20a_dbg_fn("%s pm ctxsw mode = %d", 1422 gk20a_dbg_fn("%s pm ctxsw mode = %d",
@@ -1468,7 +1468,7 @@ static int nvgpu_dbg_gpu_ioctl_suspend_resume_sm(
1468 struct dbg_session_gk20a *dbg_s, 1468 struct dbg_session_gk20a *dbg_s,
1469 struct nvgpu_dbg_gpu_suspend_resume_all_sms_args *args) 1469 struct nvgpu_dbg_gpu_suspend_resume_all_sms_args *args)
1470{ 1470{
1471 struct gk20a *g = get_gk20a(dbg_s->dev); 1471 struct gk20a *g = dbg_s->g;
1472 struct channel_gk20a *ch; 1472 struct channel_gk20a *ch;
1473 int err = 0, action = args->mode; 1473 int err = 0, action = args->mode;
1474 1474
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
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h
index 30f1b371..f4ca5649 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.h
@@ -877,6 +877,9 @@ struct gk20a {
877 atomic_t nonstall_ops; 877 atomic_t nonstall_ops;
878 struct work_struct nonstall_fn_work; 878 struct work_struct nonstall_fn_work;
879 struct workqueue_struct *nonstall_work_queue; 879 struct workqueue_struct *nonstall_work_queue;
880
881 bool is_fmodel;
882
880 struct kref refcount; 883 struct kref refcount;
881 884
882 struct resource *reg_mem; 885 struct resource *reg_mem;
@@ -987,7 +990,7 @@ struct gk20a {
987 bool global_profiler_reservation_held; 990 bool global_profiler_reservation_held;
988 int profiler_reservation_count; 991 int profiler_reservation_count;
989 992
990 void (*remove_support)(struct device *); 993 void (*remove_support)(struct gk20a *);
991 994
992 u64 pg_ingating_time_us; 995 u64 pg_ingating_time_us;
993 u64 pg_ungating_time_us; 996 u64 pg_ungating_time_us;
@@ -1455,7 +1458,7 @@ extern struct class nvgpu_class;
1455 1458
1456int gk20a_pm_init(struct device *dev); 1459int gk20a_pm_init(struct device *dev);
1457int gk20a_pm_finalize_poweron(struct device *dev); 1460int gk20a_pm_finalize_poweron(struct device *dev);
1458void gk20a_remove_support(struct device *dev); 1461void gk20a_remove_support(struct gk20a *g);
1459 1462
1460static inline struct tsg_gk20a *tsg_gk20a_from_ch(struct channel_gk20a *ch) 1463static inline struct tsg_gk20a *tsg_gk20a_from_ch(struct channel_gk20a *ch)
1461{ 1464{
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
index 7b08387e..9e6dc74c 100644
--- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
@@ -809,7 +809,7 @@ static void gk20a_remove_mm_ce_support(struct mm_gk20a *mm)
809 struct gk20a *g = gk20a_from_mm(mm); 809 struct gk20a *g = gk20a_from_mm(mm);
810 810
811 if (mm->vidmem.ce_ctx_id != (u32)~0) 811 if (mm->vidmem.ce_ctx_id != (u32)~0)
812 gk20a_ce_delete_context(g->dev, mm->vidmem.ce_ctx_id); 812 gk20a_ce_delete_context_priv(g, mm->vidmem.ce_ctx_id);
813 813
814 mm->vidmem.ce_ctx_id = (u32)~0; 814 mm->vidmem.ce_ctx_id = (u32)~0;
815 815
@@ -1220,11 +1220,10 @@ static int alloc_gmmu_pages(struct vm_gk20a *vm, u32 order,
1220 u32 num_pages = 1 << order; 1220 u32 num_pages = 1 << order;
1221 u32 len = num_pages * PAGE_SIZE; 1221 u32 len = num_pages * PAGE_SIZE;
1222 int err; 1222 int err;
1223 struct gk20a_platform *platform = dev_get_drvdata(g->dev);
1224 1223
1225 gk20a_dbg_fn(""); 1224 gk20a_dbg_fn("");
1226 1225
1227 if (platform->is_fmodel) 1226 if (g->is_fmodel)
1228 return alloc_gmmu_phys_pages(vm, order, entry); 1227 return alloc_gmmu_phys_pages(vm, order, entry);
1229 1228
1230 /* 1229 /*
@@ -1250,7 +1249,6 @@ void free_gmmu_pages(struct vm_gk20a *vm,
1250 struct gk20a_mm_entry *entry) 1249 struct gk20a_mm_entry *entry)
1251{ 1250{
1252 struct gk20a *g = gk20a_from_vm(vm); 1251 struct gk20a *g = gk20a_from_vm(vm);
1253 struct gk20a_platform *platform = dev_get_drvdata(g->dev);
1254 1252
1255 gk20a_dbg_fn(""); 1253 gk20a_dbg_fn("");
1256 1254
@@ -1260,7 +1258,7 @@ void free_gmmu_pages(struct vm_gk20a *vm,
1260 if (entry->woffset) /* fake shadow mem */ 1258 if (entry->woffset) /* fake shadow mem */
1261 return; 1259 return;
1262 1260
1263 if (platform->is_fmodel) { 1261 if (g->is_fmodel) {
1264 free_gmmu_phys_pages(vm, entry); 1262 free_gmmu_phys_pages(vm, entry);
1265 return; 1263 return;
1266 } 1264 }
@@ -1270,11 +1268,9 @@ void free_gmmu_pages(struct vm_gk20a *vm,
1270 1268
1271int map_gmmu_pages(struct gk20a *g, struct gk20a_mm_entry *entry) 1269int map_gmmu_pages(struct gk20a *g, struct gk20a_mm_entry *entry)
1272{ 1270{
1273 struct gk20a_platform *platform = dev_get_drvdata(g->dev);
1274
1275 gk20a_dbg_fn(""); 1271 gk20a_dbg_fn("");
1276 1272
1277 if (platform->is_fmodel) 1273 if (g->is_fmodel)
1278 return map_gmmu_phys_pages(entry); 1274 return map_gmmu_phys_pages(entry);
1279 1275
1280 if (IS_ENABLED(CONFIG_ARM64)) { 1276 if (IS_ENABLED(CONFIG_ARM64)) {
@@ -1296,11 +1292,9 @@ int map_gmmu_pages(struct gk20a *g, struct gk20a_mm_entry *entry)
1296 1292
1297void unmap_gmmu_pages(struct gk20a *g, struct gk20a_mm_entry *entry) 1293void unmap_gmmu_pages(struct gk20a *g, struct gk20a_mm_entry *entry)
1298{ 1294{
1299 struct gk20a_platform *platform = dev_get_drvdata(g->dev);
1300
1301 gk20a_dbg_fn(""); 1295 gk20a_dbg_fn("");
1302 1296
1303 if (platform->is_fmodel) { 1297 if (g->is_fmodel) {
1304 unmap_gmmu_phys_pages(entry); 1298 unmap_gmmu_phys_pages(entry);
1305 return; 1299 return;
1306 } 1300 }
@@ -4070,6 +4064,7 @@ static void gk20a_vm_remove_support_nofree(struct vm_gk20a *vm)
4070 struct mapped_buffer_node *mapped_buffer; 4064 struct mapped_buffer_node *mapped_buffer;
4071 struct vm_reserved_va_node *va_node, *va_node_tmp; 4065 struct vm_reserved_va_node *va_node, *va_node_tmp;
4072 struct rb_node *node; 4066 struct rb_node *node;
4067 struct gk20a *g = vm->mm->g;
4073 4068
4074 gk20a_dbg_fn(""); 4069 gk20a_dbg_fn("");
4075 4070
@@ -4078,7 +4073,7 @@ static void gk20a_vm_remove_support_nofree(struct vm_gk20a *vm)
4078 * pool involves unmapping a GMMU mapping which means aquiring the 4073 * pool involves unmapping a GMMU mapping which means aquiring the
4079 * update_gmmu_lock. 4074 * update_gmmu_lock.
4080 */ 4075 */
4081 if (!gk20a_platform_has_syncpoints(gk20a_from_vm(vm)->dev)) { 4076 if (!(g->gpu_characteristics.flags & NVGPU_GPU_FLAGS_HAS_SYNCPOINTS)) {
4082 if (vm->sema_pool) { 4077 if (vm->sema_pool) {
4083 nvgpu_semaphore_pool_unmap(vm->sema_pool, vm); 4078 nvgpu_semaphore_pool_unmap(vm->sema_pool, vm);
4084 nvgpu_semaphore_pool_put(vm->sema_pool); 4079 nvgpu_semaphore_pool_put(vm->sema_pool);
@@ -4172,7 +4167,7 @@ static int gk20a_init_sema_pool(struct vm_gk20a *vm)
4172 /* 4167 /*
4173 * Don't waste the memory on semaphores if we don't need them. 4168 * Don't waste the memory on semaphores if we don't need them.
4174 */ 4169 */
4175 if (gk20a_platform_has_syncpoints(g->dev)) 4170 if (g->gpu_characteristics.flags & NVGPU_GPU_FLAGS_HAS_SYNCPOINTS)
4176 return 0; 4171 return 0;
4177 4172
4178 if (vm->sema_pool) 4173 if (vm->sema_pool)
diff --git a/drivers/gpu/nvgpu/pci.c b/drivers/gpu/nvgpu/pci.c
index 114e9af7..a7899f7e 100644
--- a/drivers/gpu/nvgpu/pci.c
+++ b/drivers/gpu/nvgpu/pci.c
@@ -393,6 +393,11 @@ static int nvgpu_pci_probe(struct pci_dev *pdev,
393 } 393 }
394 disable_irq(g->irq_stall); 394 disable_irq(g->irq_stall);
395 395
396 /*
397 * is_fmodel needs to be in gk20a struct for deferred teardown
398 */
399 g->is_fmodel = platform->is_fmodel;
400
396 err = nvgpu_pci_init_support(pdev); 401 err = nvgpu_pci_init_support(pdev);
397 if (err) 402 if (err)
398 return err; 403 return err;
@@ -426,7 +431,6 @@ static void nvgpu_pci_remove(struct pci_dev *pdev)
426 struct gk20a *g = get_gk20a(&pdev->dev); 431 struct gk20a *g = get_gk20a(&pdev->dev);
427 432
428 gk20a_dbg(gpu_dbg_shutdown, "Removing nvgpu driver!\n"); 433 gk20a_dbg(gpu_dbg_shutdown, "Removing nvgpu driver!\n");
429 gk20a_driver_start_unload(g);
430 434
431 if (g->irqs_enabled) 435 if (g->irqs_enabled)
432 disable_irq(g->irq_stall); 436 disable_irq(g->irq_stall);
@@ -445,7 +449,7 @@ static void nvgpu_pci_remove(struct pci_dev *pdev)
445 * Wait for the driver to finish up all the IOCTLs it's working on 449 * Wait for the driver to finish up all the IOCTLs it's working on
446 * before cleaning up the driver's data structures. 450 * before cleaning up the driver's data structures.
447 */ 451 */
448 gk20a_wait_for_idle(&pdev->dev); 452 gk20a_driver_start_unload(g);
449 gk20a_dbg(gpu_dbg_shutdown, "Driver idle.\n"); 453 gk20a_dbg(gpu_dbg_shutdown, "Driver idle.\n");
450 454
451#ifdef CONFIG_ARCH_TEGRA_18x_SOC 455#ifdef CONFIG_ARCH_TEGRA_18x_SOC
@@ -455,9 +459,6 @@ static void nvgpu_pci_remove(struct pci_dev *pdev)
455 gk20a_user_deinit(g->dev, &nvgpu_pci_class); 459 gk20a_user_deinit(g->dev, &nvgpu_pci_class);
456 gk20a_dbg(gpu_dbg_shutdown, "User de-init done.\b"); 460 gk20a_dbg(gpu_dbg_shutdown, "User de-init done.\b");
457 461
458 if (g->remove_support)
459 g->remove_support(g->dev);
460
461 debugfs_remove_recursive(platform->debugfs); 462 debugfs_remove_recursive(platform->debugfs);
462 debugfs_remove_recursive(platform->debugfs_alias); 463 debugfs_remove_recursive(platform->debugfs_alias);
463 464
diff --git a/drivers/gpu/nvgpu/vgpu/vgpu.c b/drivers/gpu/nvgpu/vgpu/vgpu.c
index 72606952..df793be7 100644
--- a/drivers/gpu/nvgpu/vgpu/vgpu.c
+++ b/drivers/gpu/nvgpu/vgpu/vgpu.c
@@ -191,10 +191,9 @@ static int vgpu_intr_thread(void *dev_id)
191 return 0; 191 return 0;
192} 192}
193 193
194static void vgpu_remove_support(struct device *dev) 194static void vgpu_remove_support(struct gk20a *g)
195{ 195{
196 struct gk20a *g = get_gk20a(dev); 196 struct vgpu_priv_data *priv = vgpu_get_priv_data_from_dev(g->dev);
197 struct vgpu_priv_data *priv = vgpu_get_priv_data_from_dev(dev);
198 struct tegra_vgpu_intr_msg msg; 197 struct tegra_vgpu_intr_msg msg;
199 int err; 198 int err;
200 199
@@ -265,7 +264,7 @@ static int vgpu_init_support(struct platform_device *pdev)
265 return 0; 264 return 0;
266 265
267 fail: 266 fail:
268 vgpu_remove_support(&pdev->dev); 267 vgpu_remove_support(g);
269 return err; 268 return err;
270} 269}
271 270
@@ -571,6 +570,8 @@ int vgpu_probe(struct platform_device *pdev)
571 platform->vgpu_priv = priv; 570 platform->vgpu_priv = priv;
572 gk20a->dev = dev; 571 gk20a->dev = dev;
573 572
573 gk20a->is_fmodel = platform->is_fmodel;
574
574 nvgpu_kmem_init(gk20a); 575 nvgpu_kmem_init(gk20a);
575 576
576 err = gk20a_user_init(dev, INTERFACE_NAME, &nvgpu_class); 577 err = gk20a_user_init(dev, INTERFACE_NAME, &nvgpu_class);
@@ -653,7 +654,7 @@ int vgpu_remove(struct platform_device *pdev)
653 654
654 vgpu_pm_qos_remove(dev); 655 vgpu_pm_qos_remove(dev);
655 if (g->remove_support) 656 if (g->remove_support)
656 g->remove_support(dev); 657 g->remove_support(g);
657 658
658 vgpu_comm_deinit(); 659 vgpu_comm_deinit();
659 gk20a_sched_ctrl_cleanup(g); 660 gk20a_sched_ctrl_cleanup(g);