diff options
Diffstat (limited to 'drivers/gpu/nvgpu/common/linux/module.c')
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/module.c | 70 |
1 files changed, 29 insertions, 41 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/module.c b/drivers/gpu/nvgpu/common/linux/module.c index 015f2bf8..e2b52dad 100644 --- a/drivers/gpu/nvgpu/common/linux/module.c +++ b/drivers/gpu/nvgpu/common/linux/module.c | |||
@@ -601,7 +601,7 @@ static int gk20a_do_unidle(void *_g) | |||
601 | } | 601 | } |
602 | #endif | 602 | #endif |
603 | 603 | ||
604 | static void __iomem *gk20a_ioremap_resource(struct platform_device *dev, int i, | 604 | void __iomem *nvgpu_ioremap_resource(struct platform_device *dev, int i, |
605 | struct resource **out) | 605 | struct resource **out) |
606 | { | 606 | { |
607 | struct resource *r = platform_get_resource(dev, IORESOURCE_MEM, i); | 607 | struct resource *r = platform_get_resource(dev, IORESOURCE_MEM, i); |
@@ -637,6 +637,7 @@ static irqreturn_t gk20a_intr_thread_stall(int irq, void *dev_id) | |||
637 | void gk20a_remove_support(struct gk20a *g) | 637 | void gk20a_remove_support(struct gk20a *g) |
638 | { | 638 | { |
639 | struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); | 639 | struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); |
640 | struct sim_nvgpu_linux *sim_linux; | ||
640 | 641 | ||
641 | tegra_unregister_idle_unidle(gk20a_do_idle); | 642 | tegra_unregister_idle_unidle(gk20a_do_idle); |
642 | 643 | ||
@@ -659,8 +660,13 @@ void gk20a_remove_support(struct gk20a *g) | |||
659 | if (g->mm.remove_support) | 660 | if (g->mm.remove_support) |
660 | g->mm.remove_support(&g->mm); | 661 | g->mm.remove_support(&g->mm); |
661 | 662 | ||
662 | if (g->sim && g->sim->remove_support) | 663 | if (g->sim) { |
663 | g->sim->remove_support(g->sim); | 664 | sim_linux = container_of(g->sim, struct sim_nvgpu_linux, sim); |
665 | if (g->sim->remove_support) | ||
666 | g->sim->remove_support(g); | ||
667 | if (sim_linux->remove_support_linux) | ||
668 | sim_linux->remove_support_linux(g); | ||
669 | } | ||
664 | 670 | ||
665 | /* free mappings to registers, etc */ | 671 | /* free mappings to registers, etc */ |
666 | if (l->regs) { | 672 | if (l->regs) { |
@@ -679,18 +685,13 @@ void gk20a_remove_support(struct gk20a *g) | |||
679 | 685 | ||
680 | static int gk20a_init_support(struct platform_device *dev) | 686 | static int gk20a_init_support(struct platform_device *dev) |
681 | { | 687 | { |
682 | int err = 0; | 688 | int err = -ENOMEM; |
683 | struct gk20a *g = get_gk20a(&dev->dev); | 689 | struct gk20a *g = get_gk20a(&dev->dev); |
684 | struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); | 690 | struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); |
685 | struct sim_gk20a_linux *sim_linux = nvgpu_kzalloc(g, sizeof(*sim_linux)); | ||
686 | if (!sim_linux) | ||
687 | goto fail; | ||
688 | |||
689 | g->sim = &sim_linux->sim; | ||
690 | 691 | ||
691 | tegra_register_idle_unidle(gk20a_do_idle, gk20a_do_unidle, g); | 692 | tegra_register_idle_unidle(gk20a_do_idle, gk20a_do_unidle, g); |
692 | 693 | ||
693 | l->regs = gk20a_ioremap_resource(dev, GK20A_BAR0_IORESOURCE_MEM, | 694 | l->regs = nvgpu_ioremap_resource(dev, GK20A_BAR0_IORESOURCE_MEM, |
694 | &l->reg_mem); | 695 | &l->reg_mem); |
695 | if (IS_ERR(l->regs)) { | 696 | if (IS_ERR(l->regs)) { |
696 | nvgpu_err(g, "failed to remap gk20a registers"); | 697 | nvgpu_err(g, "failed to remap gk20a registers"); |
@@ -698,7 +699,7 @@ static int gk20a_init_support(struct platform_device *dev) | |||
698 | goto fail; | 699 | goto fail; |
699 | } | 700 | } |
700 | 701 | ||
701 | l->bar1 = gk20a_ioremap_resource(dev, GK20A_BAR1_IORESOURCE_MEM, | 702 | l->bar1 = nvgpu_ioremap_resource(dev, GK20A_BAR1_IORESOURCE_MEM, |
702 | &l->bar1_mem); | 703 | &l->bar1_mem); |
703 | if (IS_ERR(l->bar1)) { | 704 | if (IS_ERR(l->bar1)) { |
704 | nvgpu_err(g, "failed to remap gk20a bar1"); | 705 | nvgpu_err(g, "failed to remap gk20a bar1"); |
@@ -706,29 +707,28 @@ static int gk20a_init_support(struct platform_device *dev) | |||
706 | goto fail; | 707 | goto fail; |
707 | } | 708 | } |
708 | 709 | ||
709 | if (nvgpu_platform_is_simulation(g)) { | 710 | err = nvgpu_init_sim_support_linux(g, dev); |
710 | g->sim->g = g; | 711 | if (err) |
711 | sim_linux->regs = gk20a_ioremap_resource(dev, | 712 | goto fail; |
712 | GK20A_SIM_IORESOURCE_MEM, | 713 | err = nvgpu_init_sim_support(g); |
713 | &sim_linux->reg_mem); | 714 | if (err) |
714 | if (IS_ERR(sim_linux->regs)) { | 715 | goto fail_sim; |
715 | nvgpu_err(g, "failed to remap gk20a sim regs"); | ||
716 | err = PTR_ERR(sim_linux->regs); | ||
717 | goto fail; | ||
718 | } | ||
719 | |||
720 | err = gk20a_init_sim_support(g); | ||
721 | if (err) | ||
722 | goto fail; | ||
723 | } | ||
724 | 716 | ||
725 | nvgpu_init_usermode_support(g); | 717 | nvgpu_init_usermode_support(g); |
726 | |||
727 | return 0; | 718 | return 0; |
728 | 719 | ||
720 | fail_sim: | ||
721 | nvgpu_remove_sim_support_linux(g); | ||
729 | fail: | 722 | fail: |
730 | nvgpu_kfree(g, sim_linux); | 723 | if (l->regs) { |
731 | g->sim = NULL; | 724 | iounmap(l->regs); |
725 | l->regs = NULL; | ||
726 | } | ||
727 | if (l->bar1) { | ||
728 | iounmap(l->bar1); | ||
729 | l->bar1 = NULL; | ||
730 | } | ||
731 | |||
732 | return err; | 732 | return err; |
733 | } | 733 | } |
734 | 734 | ||
@@ -1227,18 +1227,6 @@ static int gk20a_probe(struct platform_device *dev) | |||
1227 | return 0; | 1227 | return 0; |
1228 | 1228 | ||
1229 | return_err: | 1229 | return_err: |
1230 | /* | ||
1231 | * Make sure to clean up any memory allocs made in this function - | ||
1232 | * especially since we can be called many times due to probe deferal. | ||
1233 | */ | ||
1234 | if (gk20a->sim) { | ||
1235 | struct sim_gk20a_linux *sim_linux; | ||
1236 | sim_linux = container_of(gk20a->sim, | ||
1237 | struct sim_gk20a_linux, | ||
1238 | sim); | ||
1239 | nvgpu_kfree(gk20a, sim_linux); | ||
1240 | } | ||
1241 | |||
1242 | nvgpu_free_enabled_flags(gk20a); | 1230 | nvgpu_free_enabled_flags(gk20a); |
1243 | 1231 | ||
1244 | /* | 1232 | /* |