diff options
Diffstat (limited to 'drivers/gpu/nvgpu/common/linux/pci.c')
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/pci.c | 56 |
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 | ||
514 | static void nvgpu_pci_remove(struct pci_dev *pdev) | 514 | static 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 | } |