summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNitin Kumbhar <nkumbhar@nvidia.com>2018-05-25 07:09:07 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2018-07-06 16:24:45 -0400
commit4b889fb8b02e7b65eb7054463c0c1bda37688762 (patch)
tree02d94028beac3f39ba204ad1857a1fc2e7f177fc
parentc8347c83697b75823f6e5141b06b8e4669061b99 (diff)
gpu: nvgpu: use devm variants to ioremap
While removing nvgpu driver, devm mapped reg mappings are released on driver_unregister. For iGPU, these regs are explicitly unmapped with iounmap(). This results in "Trying to vfree() nonexistent vm area" warnings on driver removal. Address this by using devm* variants to map all IO regions of both iGPU and dGPU and let the driver unregister release these mappings. Also, lock out GPU regs in driver removal path. Bug 1987855 Change-Id: I0388daf90bea3eaf8752255059cfd3ceabf66e7d Signed-off-by: Nitin Kumbhar <nkumbhar@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1730539 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
-rw-r--r--drivers/gpu/nvgpu/os/linux/module.c50
-rw-r--r--drivers/gpu/nvgpu/os/linux/module.h4
-rw-r--r--drivers/gpu/nvgpu/os/linux/pci.c18
-rw-r--r--drivers/gpu/nvgpu/os/linux/sim.c6
4 files changed, 38 insertions, 40 deletions
diff --git a/drivers/gpu/nvgpu/os/linux/module.c b/drivers/gpu/nvgpu/os/linux/module.c
index 2df8ab42..28ade90f 100644
--- a/drivers/gpu/nvgpu/os/linux/module.c
+++ b/drivers/gpu/nvgpu/os/linux/module.c
@@ -606,8 +606,8 @@ static int gk20a_do_unidle(void *_g)
606} 606}
607#endif 607#endif
608 608
609void __iomem *nvgpu_ioremap_resource(struct platform_device *dev, int i, 609void __iomem *nvgpu_devm_ioremap_resource(struct platform_device *dev, int i,
610 struct resource **out) 610 struct resource **out)
611{ 611{
612 struct resource *r = platform_get_resource(dev, IORESOURCE_MEM, i); 612 struct resource *r = platform_get_resource(dev, IORESOURCE_MEM, i);
613 613
@@ -618,6 +618,12 @@ void __iomem *nvgpu_ioremap_resource(struct platform_device *dev, int i,
618 return devm_ioremap_resource(&dev->dev, r); 618 return devm_ioremap_resource(&dev->dev, r);
619} 619}
620 620
621void __iomem *nvgpu_devm_ioremap(struct device *dev, resource_size_t offset,
622 resource_size_t size)
623{
624 return devm_ioremap(dev, offset, size);
625}
626
621static irqreturn_t gk20a_intr_isr_stall(int irq, void *dev_id) 627static irqreturn_t gk20a_intr_isr_stall(int irq, void *dev_id)
622{ 628{
623 struct gk20a *g = dev_id; 629 struct gk20a *g = dev_id;
@@ -673,46 +679,41 @@ void gk20a_remove_support(struct gk20a *g)
673 sim_linux->remove_support_linux(g); 679 sim_linux->remove_support_linux(g);
674 } 680 }
675 681
676 /* free mappings to registers, etc */
677 if (l->regs) {
678 iounmap(l->regs);
679 l->regs = NULL;
680 }
681 if (l->bar1) {
682 iounmap(l->bar1);
683 l->bar1 = NULL;
684 }
685
686 nvgpu_remove_usermode_support(g); 682 nvgpu_remove_usermode_support(g);
687 683
688 nvgpu_free_enabled_flags(g); 684 nvgpu_free_enabled_flags(g);
685
686 gk20a_lockout_registers(g);
689} 687}
690 688
691static int gk20a_init_support(struct platform_device *dev) 689static int gk20a_init_support(struct platform_device *pdev)
692{ 690{
693 int err = -ENOMEM; 691 struct device *dev = &pdev->dev;
694 struct gk20a *g = get_gk20a(&dev->dev); 692 struct gk20a *g = get_gk20a(dev);
695 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); 693 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
694 int err = -ENOMEM;
696 695
697 tegra_register_idle_unidle(gk20a_do_idle, gk20a_do_unidle, g); 696 tegra_register_idle_unidle(gk20a_do_idle, gk20a_do_unidle, g);
698 697
699 l->regs = nvgpu_ioremap_resource(dev, GK20A_BAR0_IORESOURCE_MEM, 698 l->regs = nvgpu_devm_ioremap_resource(pdev,
700 &l->reg_mem); 699 GK20A_BAR0_IORESOURCE_MEM,
700 &l->reg_mem);
701 if (IS_ERR(l->regs)) { 701 if (IS_ERR(l->regs)) {
702 nvgpu_err(g, "failed to remap gk20a registers"); 702 nvgpu_err(g, "failed to remap gk20a registers");
703 err = PTR_ERR(l->regs); 703 err = PTR_ERR(l->regs);
704 goto fail; 704 goto fail;
705 } 705 }
706 706
707 l->bar1 = nvgpu_ioremap_resource(dev, GK20A_BAR1_IORESOURCE_MEM, 707 l->bar1 = nvgpu_devm_ioremap_resource(pdev,
708 &l->bar1_mem); 708 GK20A_BAR1_IORESOURCE_MEM,
709 &l->bar1_mem);
709 if (IS_ERR(l->bar1)) { 710 if (IS_ERR(l->bar1)) {
710 nvgpu_err(g, "failed to remap gk20a bar1"); 711 nvgpu_err(g, "failed to remap gk20a bar1");
711 err = PTR_ERR(l->bar1); 712 err = PTR_ERR(l->bar1);
712 goto fail; 713 goto fail;
713 } 714 }
714 715
715 err = nvgpu_init_sim_support_linux(g, dev); 716 err = nvgpu_init_sim_support_linux(g, pdev);
716 if (err) 717 if (err)
717 goto fail; 718 goto fail;
718 err = nvgpu_init_sim_support(g); 719 err = nvgpu_init_sim_support(g);
@@ -725,14 +726,11 @@ static int gk20a_init_support(struct platform_device *dev)
725fail_sim: 726fail_sim:
726 nvgpu_remove_sim_support_linux(g); 727 nvgpu_remove_sim_support_linux(g);
727fail: 728fail:
728 if (l->regs) { 729 if (l->regs)
729 iounmap(l->regs);
730 l->regs = NULL; 730 l->regs = NULL;
731 } 731
732 if (l->bar1) { 732 if (l->bar1)
733 iounmap(l->bar1);
734 l->bar1 = NULL; 733 l->bar1 = NULL;
735 }
736 734
737 return err; 735 return err;
738} 736}
diff --git a/drivers/gpu/nvgpu/os/linux/module.h b/drivers/gpu/nvgpu/os/linux/module.h
index ab4bca03..da61425d 100644
--- a/drivers/gpu/nvgpu/os/linux/module.h
+++ b/drivers/gpu/nvgpu/os/linux/module.h
@@ -25,8 +25,10 @@ int nvgpu_quiesce(struct gk20a *g);
25int nvgpu_remove(struct device *dev, struct class *class); 25int nvgpu_remove(struct device *dev, struct class *class);
26void nvgpu_free_irq(struct gk20a *g); 26void nvgpu_free_irq(struct gk20a *g);
27struct device_node *nvgpu_get_node(struct gk20a *g); 27struct device_node *nvgpu_get_node(struct gk20a *g);
28void __iomem *nvgpu_ioremap_resource(struct platform_device *dev, int i, 28void __iomem *nvgpu_devm_ioremap_resource(struct platform_device *dev, int i,
29 struct resource **out); 29 struct resource **out);
30void __iomem *nvgpu_devm_ioremap(struct device *dev, resource_size_t offset,
31 resource_size_t size);
30extern struct class nvgpu_class; 32extern struct class nvgpu_class;
31 33
32#endif 34#endif
diff --git a/drivers/gpu/nvgpu/os/linux/pci.c b/drivers/gpu/nvgpu/os/linux/pci.c
index f62dacab..dba8a5df 100644
--- a/drivers/gpu/nvgpu/os/linux/pci.c
+++ b/drivers/gpu/nvgpu/os/linux/pci.c
@@ -525,17 +525,18 @@ static int nvgpu_pci_init_support(struct pci_dev *pdev)
525 int err = 0; 525 int err = 0;
526 struct gk20a *g = get_gk20a(&pdev->dev); 526 struct gk20a *g = get_gk20a(&pdev->dev);
527 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); 527 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
528 struct device *dev = &pdev->dev;
528 529
529 l->regs = ioremap(pci_resource_start(pdev, 0), 530 l->regs = nvgpu_devm_ioremap(dev, pci_resource_start(pdev, 0),
530 pci_resource_len(pdev, 0)); 531 pci_resource_len(pdev, 0));
531 if (IS_ERR(l->regs)) { 532 if (IS_ERR(l->regs)) {
532 nvgpu_err(g, "failed to remap gk20a registers"); 533 nvgpu_err(g, "failed to remap gk20a registers");
533 err = PTR_ERR(l->regs); 534 err = PTR_ERR(l->regs);
534 goto fail; 535 goto fail;
535 } 536 }
536 537
537 l->bar1 = ioremap(pci_resource_start(pdev, 1), 538 l->bar1 = nvgpu_devm_ioremap(dev, pci_resource_start(pdev, 1),
538 pci_resource_len(pdev, 1)); 539 pci_resource_len(pdev, 1));
539 if (IS_ERR(l->bar1)) { 540 if (IS_ERR(l->bar1)) {
540 nvgpu_err(g, "failed to remap gk20a bar1"); 541 nvgpu_err(g, "failed to remap gk20a bar1");
541 err = PTR_ERR(l->bar1); 542 err = PTR_ERR(l->bar1);
@@ -556,14 +557,11 @@ static int nvgpu_pci_init_support(struct pci_dev *pdev)
556 fail_sim: 557 fail_sim:
557 nvgpu_remove_sim_support_linux_pci(g); 558 nvgpu_remove_sim_support_linux_pci(g);
558 fail: 559 fail:
559 if (l->regs) { 560 if (l->regs)
560 iounmap(l->regs);
561 l->regs = NULL; 561 l->regs = NULL;
562 } 562
563 if (l->bar1) { 563 if (l->bar1)
564 iounmap(l->bar1);
565 l->bar1 = NULL; 564 l->bar1 = NULL;
566 }
567 565
568 return err; 566 return err;
569} 567}
diff --git a/drivers/gpu/nvgpu/os/linux/sim.c b/drivers/gpu/nvgpu/os/linux/sim.c
index 8e964f39..abef45c7 100644
--- a/drivers/gpu/nvgpu/os/linux/sim.c
+++ b/drivers/gpu/nvgpu/os/linux/sim.c
@@ -78,9 +78,9 @@ int nvgpu_init_sim_support_linux(struct gk20a *g,
78 return err; 78 return err;
79 g->sim = &sim_linux->sim; 79 g->sim = &sim_linux->sim;
80 g->sim->g = g; 80 g->sim->g = g;
81 sim_linux->regs = nvgpu_ioremap_resource(dev, 81 sim_linux->regs = nvgpu_devm_ioremap_resource(dev,
82 GK20A_SIM_IORESOURCE_MEM, 82 GK20A_SIM_IORESOURCE_MEM,
83 &sim_linux->reg_mem); 83 &sim_linux->reg_mem);
84 if (IS_ERR(sim_linux->regs)) { 84 if (IS_ERR(sim_linux->regs)) {
85 nvgpu_err(g, "failed to remap gk20a sim regs"); 85 nvgpu_err(g, "failed to remap gk20a sim regs");
86 err = PTR_ERR(sim_linux->regs); 86 err = PTR_ERR(sim_linux->regs);