diff options
Diffstat (limited to 'drivers/gpu/nvgpu/common/linux/module.c')
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/module.c | 55 |
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 | */ | ||
649 | void 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 | ||