summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/common/linux/module.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/common/linux/module.c')
-rw-r--r--drivers/gpu/nvgpu/common/linux/module.c55
1 files changed, 37 insertions, 18 deletions
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