summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/common/linux/pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/common/linux/pci.c')
-rw-r--r--drivers/gpu/nvgpu/common/linux/pci.c56
1 files changed, 19 insertions, 37 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/pci.c b/drivers/gpu/nvgpu/common/linux/pci.c
index 4ea86e7f..f1d12367 100644
--- a/drivers/gpu/nvgpu/common/linux/pci.c
+++ b/drivers/gpu/nvgpu/common/linux/pci.c
@@ -513,52 +513,34 @@ static int nvgpu_pci_probe(struct pci_dev *pdev,
513 513
514static void nvgpu_pci_remove(struct pci_dev *pdev) 514static void nvgpu_pci_remove(struct pci_dev *pdev)
515{ 515{
516 struct gk20a_platform *platform = gk20a_get_platform(&pdev->dev);
517 struct gk20a *g = get_gk20a(&pdev->dev); 516 struct gk20a *g = get_gk20a(&pdev->dev);
518 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); 517 struct device *dev = dev_from_gk20a(g);
518 int err;
519 519
520 gk20a_dbg(gpu_dbg_shutdown, "Removing nvgpu driver!\n"); 520 /* no support yet for unbind if DGPU is in VGPU mode */
521 if (gk20a_gpu_is_virtual(dev))
522 return;
521 523
522 if (g->irqs_enabled) 524 /* only idle the GPU if the GPU is powered on */
523 disable_irq(g->irq_stall); 525 if (g->power_on) {
526 gk20a_driver_start_unload(g);
527 err = nvgpu_quiesce(g);
528 /* TODO: handle failure to idle */
529 WARN(err, "gpu failed to idle during driver removal");
530 }
524 531
525 devm_free_irq(&pdev->dev, g->irq_stall, g); 532 nvgpu_remove(dev, &nvgpu_pci_class);
526 533
527#if defined(CONFIG_PCI_MSI) 534#if defined(CONFIG_PCI_MSI)
528 if (g->msi_enabled) { 535 if (g->msi_enabled)
529 pci_disable_msi(pdev); 536 pci_disable_msi(pdev);
530 g->msi_enabled = false; 537 else {
538 /* IRQ does not need to be enabled in MSI as the line is not
539 * shared
540 */
541 enable_irq(g->irq_stall);
531 } 542 }
532#endif 543#endif
533 gk20a_dbg(gpu_dbg_shutdown, "IRQs disabled.\n");
534
535 /*
536 * Wait for the driver to finish up all the IOCTLs it's working on
537 * before cleaning up the driver's data structures.
538 */
539 gk20a_driver_start_unload(g);
540 gk20a_dbg(gpu_dbg_shutdown, "Driver idle.\n");
541
542#ifdef CONFIG_ARCH_TEGRA_18x_SOC
543 nvgpu_clk_arb_cleanup_arbiter(g);
544#endif
545
546 gk20a_user_deinit(dev_from_gk20a(g), &nvgpu_pci_class);
547 gk20a_dbg(gpu_dbg_shutdown, "User de-init done.\b");
548
549#ifdef CONFIG_DEBUG_FS
550 debugfs_remove_recursive(l->debugfs);
551 debugfs_remove_recursive(l->debugfs_alias);
552#endif
553
554 nvgpu_remove_sysfs(dev_from_gk20a(g));
555
556 if (platform->remove)
557 platform->remove(dev_from_gk20a(g));
558 gk20a_dbg(gpu_dbg_shutdown, "Platform remove done.\b");
559
560 enable_irq(g->irq_stall);
561
562 gk20a_get_platform(&pdev->dev)->g = NULL; 544 gk20a_get_platform(&pdev->dev)->g = NULL;
563 gk20a_put(g); 545 gk20a_put(g);
564} 546}