diff options
Diffstat (limited to 'drivers/gpu/nvgpu')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/ce2_gk20a.c | 6 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/ce2_gk20a.h | 3 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 22 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c | 3 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c | 24 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.c | 44 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.h | 7 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/mm_gk20a.c | 21 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/pci.c | 11 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/vgpu/vgpu.c | 11 |
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 | |||
696 | void 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); |
147 | void gk20a_ce_delete_context_priv(struct gk20a *g, | ||
148 | u32 ce_ctx_id); | ||
147 | void gk20a_ce_delete_context(struct device *dev, | 149 | void 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 */ |
152 | void gk20a_ce_debugfs_init(struct device *dev); | 155 | void 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) | |||
122 | static void free_channel(struct fifo_gk20a *f, | 122 | static 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 | ||
141 | int channel_gk20a_commit_va(struct channel_gk20a *c) | 150 | int 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, | |||
1344 | long gk20a_ctrl_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | 1344 | long 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, | |||
1257 | static int dbg_set_powergate(struct dbg_session_gk20a *dbg_s, u32 powermode) | 1257 | static 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 | ||
337 | void gk20a_remove_support(struct device *dev) | 337 | void 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) | |||
1390 | void gk20a_driver_start_unload(struct gk20a *g) | 1378 | void 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 | ||
1396 | int gk20a_wait_for_idle(struct device *dev) | 1398 | int 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 | ||
1456 | int gk20a_pm_init(struct device *dev); | 1459 | int gk20a_pm_init(struct device *dev); |
1457 | int gk20a_pm_finalize_poweron(struct device *dev); | 1460 | int gk20a_pm_finalize_poweron(struct device *dev); |
1458 | void gk20a_remove_support(struct device *dev); | 1461 | void gk20a_remove_support(struct gk20a *g); |
1459 | 1462 | ||
1460 | static inline struct tsg_gk20a *tsg_gk20a_from_ch(struct channel_gk20a *ch) | 1463 | static 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 | ||
1271 | int map_gmmu_pages(struct gk20a *g, struct gk20a_mm_entry *entry) | 1269 | int 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 | ||
1297 | void unmap_gmmu_pages(struct gk20a *g, struct gk20a_mm_entry *entry) | 1293 | void 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 | ||
194 | static void vgpu_remove_support(struct device *dev) | 194 | static 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); |