summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/common
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/common')
-rw-r--r--drivers/gpu/nvgpu/common/linux/debug.c2
-rw-r--r--drivers/gpu/nvgpu/common/linux/debug_allocator.c2
-rw-r--r--drivers/gpu/nvgpu/common/linux/debug_clk.c1
-rw-r--r--drivers/gpu/nvgpu/common/linux/debug_pmu.c1
-rw-r--r--drivers/gpu/nvgpu/common/linux/module.c55
-rw-r--r--drivers/gpu/nvgpu/common/linux/module.h1
-rw-r--r--drivers/gpu/nvgpu/common/linux/pci.c13
-rw-r--r--drivers/gpu/nvgpu/common/linux/thread.c6
-rw-r--r--drivers/gpu/nvgpu/common/pmu/pmu_fw.c3
-rw-r--r--drivers/gpu/nvgpu/common/pramin.c9
10 files changed, 60 insertions, 33 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/debug.c b/drivers/gpu/nvgpu/common/linux/debug.c
index 5750800f..08d0e679 100644
--- a/drivers/gpu/nvgpu/common/linux/debug.c
+++ b/drivers/gpu/nvgpu/common/linux/debug.c
@@ -409,5 +409,5 @@ void gk20a_debug_deinit(struct gk20a *g)
409 gk20a_fifo_debugfs_deinit(g); 409 gk20a_fifo_debugfs_deinit(g);
410 410
411 debugfs_remove_recursive(l->debugfs); 411 debugfs_remove_recursive(l->debugfs);
412 debugfs_remove_recursive(l->debugfs_alias); 412 debugfs_remove(l->debugfs_alias);
413} 413}
diff --git a/drivers/gpu/nvgpu/common/linux/debug_allocator.c b/drivers/gpu/nvgpu/common/linux/debug_allocator.c
index 91ae0512..d63a9030 100644
--- a/drivers/gpu/nvgpu/common/linux/debug_allocator.c
+++ b/drivers/gpu/nvgpu/common/linux/debug_allocator.c
@@ -55,8 +55,6 @@ void nvgpu_init_alloc_debug(struct gk20a *g, struct nvgpu_allocator *a)
55 55
56void nvgpu_fini_alloc_debug(struct nvgpu_allocator *a) 56void nvgpu_fini_alloc_debug(struct nvgpu_allocator *a)
57{ 57{
58 if (!IS_ERR_OR_NULL(a->debugfs_entry))
59 debugfs_remove(a->debugfs_entry);
60} 58}
61 59
62void nvgpu_alloc_debugfs_init(struct gk20a *g) 60void nvgpu_alloc_debugfs_init(struct gk20a *g)
diff --git a/drivers/gpu/nvgpu/common/linux/debug_clk.c b/drivers/gpu/nvgpu/common/linux/debug_clk.c
index b265ca69..81839de7 100644
--- a/drivers/gpu/nvgpu/common/linux/debug_clk.c
+++ b/drivers/gpu/nvgpu/common/linux/debug_clk.c
@@ -267,6 +267,5 @@ int gm20b_clk_init_debugfs(struct gk20a *g)
267 267
268err_out: 268err_out:
269 pr_err("%s: Failed to make debugfs node\n", __func__); 269 pr_err("%s: Failed to make debugfs node\n", __func__);
270 debugfs_remove_recursive(l->debugfs);
271 return -ENOMEM; 270 return -ENOMEM;
272} 271}
diff --git a/drivers/gpu/nvgpu/common/linux/debug_pmu.c b/drivers/gpu/nvgpu/common/linux/debug_pmu.c
index 191fcb0e..ec997e28 100644
--- a/drivers/gpu/nvgpu/common/linux/debug_pmu.c
+++ b/drivers/gpu/nvgpu/common/linux/debug_pmu.c
@@ -477,6 +477,5 @@ int gk20a_pmu_debugfs_init(struct gk20a *g)
477 return 0; 477 return 0;
478err_out: 478err_out:
479 pr_err("%s: Failed to make debugfs node\n", __func__); 479 pr_err("%s: Failed to make debugfs node\n", __func__);
480 debugfs_remove_recursive(l->debugfs);
481 return -ENOMEM; 480 return -ENOMEM;
482} 481}
diff --git a/drivers/gpu/nvgpu/common/linux/module.c b/drivers/gpu/nvgpu/common/linux/module.c
index 46b89ad0..c474f36a 100644
--- a/drivers/gpu/nvgpu/common/linux/module.c
+++ b/drivers/gpu/nvgpu/common/linux/module.c
@@ -226,9 +226,12 @@ static int gk20a_pm_prepare_poweroff(struct device *dev)
226 * After this point, gk20a interrupts should not get 226 * After this point, gk20a interrupts should not get
227 * serviced. 227 * serviced.
228 */ 228 */
229 disable_irq(g->irq_stall); 229 if (g->irqs_enabled) {
230 if (g->irq_stall != g->irq_nonstall) 230 disable_irq(g->irq_stall);
231 disable_irq(g->irq_nonstall); 231 if (g->irq_stall != g->irq_nonstall)
232 disable_irq(g->irq_nonstall);
233 g->irqs_enabled = 0;
234 }
232 235
233 /* Decrement platform power refcount */ 236 /* Decrement platform power refcount */
234 if (platform->idle) 237 if (platform->idle)
@@ -641,6 +644,18 @@ static int gk20a_pm_unrailgate(struct device *dev)
641} 644}
642 645
643/* 646/*
647 * Remove association of the driver with OS interrupt handler
648 */
649void nvgpu_free_irq(struct gk20a *g)
650{
651 struct device *dev = dev_from_gk20a(g);
652
653 devm_free_irq(dev, g->irq_stall, g);
654 if (g->irq_stall != g->irq_nonstall)
655 devm_free_irq(dev, g->irq_nonstall, g);
656}
657
658/*
644 * Idle the GPU in preparation of shutdown/remove. 659 * Idle the GPU in preparation of shutdown/remove.
645 * gk20a_driver_start_unload() does not idle the GPU, but instead changes the SW 660 * gk20a_driver_start_unload() does not idle the GPU, but instead changes the SW
646 * state to prevent further activity on the driver SW side. 661 * state to prevent further activity on the driver SW side.
@@ -651,24 +666,27 @@ int nvgpu_quiesce(struct gk20a *g)
651 int err; 666 int err;
652 struct device *dev = dev_from_gk20a(g); 667 struct device *dev = dev_from_gk20a(g);
653 668
654 err = gk20a_wait_for_idle(g); 669 if (g->power_on) {
655 if (err) { 670 err = gk20a_wait_for_idle(g);
656 nvgpu_err(g, "failed to idle GPU, err=%d", err); 671 if (err) {
657 return err; 672 nvgpu_err(g, "failed to idle GPU, err=%d", err);
658 } 673 return err;
674 }
659 675
660 err = gk20a_fifo_disable_all_engine_activity(g, true); 676 err = gk20a_fifo_disable_all_engine_activity(g, true);
661 if (err) { 677 if (err) {
662 nvgpu_err(g, "failed to disable engine activity, err=%d", 678 nvgpu_err(g,
663 err); 679 "failed to disable engine activity, err=%d",
680 err);
664 return err; 681 return err;
665 } 682 }
666 683
667 err = gk20a_fifo_wait_engine_idle(g); 684 err = gk20a_fifo_wait_engine_idle(g);
668 if (err) { 685 if (err) {
669 nvgpu_err(g, "failed to idle engines, err=%d", 686 nvgpu_err(g, "failed to idle engines, err=%d",
670 err); 687 err);
671 return err; 688 return err;
689 }
672 } 690 }
673 691
674 if (gk20a_gpu_is_virtual(dev)) 692 if (gk20a_gpu_is_virtual(dev))
@@ -679,6 +697,7 @@ int nvgpu_quiesce(struct gk20a *g)
679 if (err) 697 if (err)
680 nvgpu_err(g, "failed to prepare for poweroff, err=%d", 698 nvgpu_err(g, "failed to prepare for poweroff, err=%d",
681 err); 699 err);
700
682 return err; 701 return err;
683} 702}
684 703
diff --git a/drivers/gpu/nvgpu/common/linux/module.h b/drivers/gpu/nvgpu/common/linux/module.h
index def98288..55a3b692 100644
--- a/drivers/gpu/nvgpu/common/linux/module.h
+++ b/drivers/gpu/nvgpu/common/linux/module.h
@@ -21,6 +21,7 @@ void gk20a_remove_support(struct gk20a *g);
21void gk20a_driver_start_unload(struct gk20a *g); 21void gk20a_driver_start_unload(struct gk20a *g);
22int nvgpu_quiesce(struct gk20a *g); 22int nvgpu_quiesce(struct gk20a *g);
23int nvgpu_remove(struct device *dev, struct class *class); 23int nvgpu_remove(struct device *dev, struct class *class);
24void nvgpu_free_irq(struct gk20a *g);
24 25
25extern struct class nvgpu_class; 26extern struct class nvgpu_class;
26 27
diff --git a/drivers/gpu/nvgpu/common/linux/pci.c b/drivers/gpu/nvgpu/common/linux/pci.c
index f1d12367..1a7d1842 100644
--- a/drivers/gpu/nvgpu/common/linux/pci.c
+++ b/drivers/gpu/nvgpu/common/linux/pci.c
@@ -521,13 +521,12 @@ static void nvgpu_pci_remove(struct pci_dev *pdev)
521 if (gk20a_gpu_is_virtual(dev)) 521 if (gk20a_gpu_is_virtual(dev))
522 return; 522 return;
523 523
524 /* only idle the GPU if the GPU is powered on */ 524 gk20a_driver_start_unload(g);
525 if (g->power_on) { 525 err = nvgpu_quiesce(g);
526 gk20a_driver_start_unload(g); 526 /* TODO: handle failure to idle */
527 err = nvgpu_quiesce(g); 527 WARN(err, "gpu failed to idle during driver removal");
528 /* TODO: handle failure to idle */ 528
529 WARN(err, "gpu failed to idle during driver removal"); 529 nvgpu_free_irq(g);
530 }
531 530
532 nvgpu_remove(dev, &nvgpu_pci_class); 531 nvgpu_remove(dev, &nvgpu_pci_class);
533 532
diff --git a/drivers/gpu/nvgpu/common/linux/thread.c b/drivers/gpu/nvgpu/common/linux/thread.c
index fe3906eb..92c556f2 100644
--- a/drivers/gpu/nvgpu/common/linux/thread.c
+++ b/drivers/gpu/nvgpu/common/linux/thread.c
@@ -46,8 +46,10 @@ int nvgpu_thread_create(struct nvgpu_thread *thread,
46 46
47void nvgpu_thread_stop(struct nvgpu_thread *thread) 47void nvgpu_thread_stop(struct nvgpu_thread *thread)
48{ 48{
49 kthread_stop(thread->task); 49 if (thread->task) {
50 thread->task = NULL; 50 kthread_stop(thread->task);
51 thread->task = NULL;
52 }
51}; 53};
52 54
53bool nvgpu_thread_should_stop(struct nvgpu_thread *thread) 55bool nvgpu_thread_should_stop(struct nvgpu_thread *thread)
diff --git a/drivers/gpu/nvgpu/common/pmu/pmu_fw.c b/drivers/gpu/nvgpu/common/pmu/pmu_fw.c
index 077a1bf8..5fd8121d 100644
--- a/drivers/gpu/nvgpu/common/pmu/pmu_fw.c
+++ b/drivers/gpu/nvgpu/common/pmu/pmu_fw.c
@@ -2223,7 +2223,8 @@ static void nvgpu_remove_pmu_support(struct nvgpu_pmu *pmu)
2223 if (nvgpu_alloc_initialized(&pmu->dmem)) 2223 if (nvgpu_alloc_initialized(&pmu->dmem))
2224 nvgpu_alloc_destroy(&pmu->dmem); 2224 nvgpu_alloc_destroy(&pmu->dmem);
2225 2225
2226 nvgpu_release_firmware(g, pmu->fw); 2226 if (pmu->fw)
2227 nvgpu_release_firmware(g, pmu->fw);
2227 2228
2228 nvgpu_mutex_destroy(&pmu->elpg_mutex); 2229 nvgpu_mutex_destroy(&pmu->elpg_mutex);
2229 nvgpu_mutex_destroy(&pmu->pg_mutex); 2230 nvgpu_mutex_destroy(&pmu->pg_mutex);
diff --git a/drivers/gpu/nvgpu/common/pramin.c b/drivers/gpu/nvgpu/common/pramin.c
index ae9c9b1f..7955e6c2 100644
--- a/drivers/gpu/nvgpu/common/pramin.c
+++ b/drivers/gpu/nvgpu/common/pramin.c
@@ -16,6 +16,7 @@
16 16
17#include <nvgpu/pramin.h> 17#include <nvgpu/pramin.h>
18#include <nvgpu/page_allocator.h> 18#include <nvgpu/page_allocator.h>
19#include <nvgpu/enabled.h>
19 20
20#include "gk20a/gk20a.h" 21#include "gk20a/gk20a.h"
21 22
@@ -88,6 +89,14 @@ void nvgpu_pramin_access_batched(struct gk20a *g, struct nvgpu_mem *mem,
88 void *sgl; 89 void *sgl;
89 u32 byteoff, start_reg, until_end, n; 90 u32 byteoff, start_reg, until_end, n;
90 91
92 /*
93 * TODO: Vidmem is not accesible through pramin on shutdown path.
94 * driver should be refactored to prevent this from happening, but for
95 * now it is ok just to ignore the writes
96 */
97 if (!g->regs && nvgpu_is_enabled(g, NVGPU_DRIVER_IS_DYING))
98 return;
99
91 alloc = get_vidmem_page_alloc(mem->priv.sgt->sgl); 100 alloc = get_vidmem_page_alloc(mem->priv.sgt->sgl);
92 sgt = &alloc->sgt; 101 sgt = &alloc->sgt;
93 for (sgl = sgt->sgl; sgl; sgl = nvgpu_sgt_get_next(sgt, sgl)) { 102 for (sgl = sgt->sgl; sgl; sgl = nvgpu_sgt_get_next(sgt, sgl)) {