From 6049301229b184d15873f907a35d22eb473c38a0 Mon Sep 17 00:00:00 2001 From: Konsta Holtta Date: Wed, 5 Nov 2014 18:09:26 +0200 Subject: gpu: nvgpu: remove platform device on exit Add ->remove() for undoing the ->probe() and ->late_probe() in gk20a_platform devices, and call it when gk20a is removed. Bug 1476801 Change-Id: Ic9b29c0a7ea4a4cae7b5a0f66774bd799eb28434 Signed-off-by: Konsta Holtta Reviewed-on: http://git-master/r/594443 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Terje Bergstrom --- drivers/gpu/nvgpu/gk20a/gk20a.c | 3 +++ drivers/gpu/nvgpu/gk20a/platform_gk20a.h | 4 ++++ drivers/gpu/nvgpu/gk20a/platform_gk20a_generic.c | 10 ++++++++++ drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c | 25 ++++++++++++++++++++++++ 4 files changed, 42 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c index ab9dd037..3d887d85 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gk20a.c @@ -1478,6 +1478,9 @@ static int __exit gk20a_remove(struct platform_device *dev) else gk20a_pm_disable_clk(&dev->dev); + if (platform->remove) + platform->remove(dev); + set_gk20a(dev, NULL); kfree(g); diff --git a/drivers/gpu/nvgpu/gk20a/platform_gk20a.h b/drivers/gpu/nvgpu/gk20a/platform_gk20a.h index 7638cf15..f4301dab 100644 --- a/drivers/gpu/nvgpu/gk20a/platform_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/platform_gk20a.h @@ -103,6 +103,10 @@ struct gk20a_platform { */ int (*late_probe)(struct platform_device *dev); + /* Remove device after power management has been done + */ + int (*remove)(struct platform_device *dev); + /* Poweron platform dependencies */ int (*busy)(struct platform_device *dev); diff --git a/drivers/gpu/nvgpu/gk20a/platform_gk20a_generic.c b/drivers/gpu/nvgpu/gk20a/platform_gk20a_generic.c index d5b82fcc..ee176b8b 100644 --- a/drivers/gpu/nvgpu/gk20a/platform_gk20a_generic.c +++ b/drivers/gpu/nvgpu/gk20a/platform_gk20a_generic.c @@ -120,6 +120,15 @@ static int gk20a_generic_late_probe(struct platform_device *dev) return 0; } +static int gk20a_generic_remove(struct platform_device *dev) +{ + struct gk20a_platform *platform = gk20a_get_platform(dev); + + tegra_pd_remove_sd(&platform->g->pd); + + return 0; +} + struct gk20a_platform gk20a_generic_platform = { .railgate = gk20a_generic_railgate, .unrailgate = gk20a_generic_unrailgate, @@ -127,5 +136,6 @@ struct gk20a_platform gk20a_generic_platform = { .probe = gk20a_generic_probe, .late_probe = gk20a_generic_late_probe, + .remove = gk20a_generic_remove, .default_big_page_size = SZ_128K, }; diff --git a/drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c b/drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c index 415e4020..dfbc1ae0 100644 --- a/drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c +++ b/drivers/gpu/nvgpu/gk20a/platform_gk20a_tegra.c @@ -381,6 +381,15 @@ static void gk20a_tegra_scale_init(struct platform_device *pdev) profile->private_data = emc_params; } +static void gk20a_tegra_scale_exit(struct platform_device *pdev) +{ + struct gk20a_platform *platform = gk20a_get_platform(pdev); + struct gk20a_scale_profile *profile = platform->g->scale_profile; + + if (profile) + kfree(profile->private_data); +} + void gk20a_tegra_debug_dump(struct platform_device *pdev) { struct gk20a_platform *platform = gk20a_get_platform(pdev); @@ -466,6 +475,19 @@ static int gk20a_tegra_late_probe(struct platform_device *dev) return 0; } +static int gk20a_tegra_remove(struct platform_device *dev) +{ + struct gk20a_platform *platform = gk20a_get_platform(dev); + + /* remove gk20a power subdomain from host1x */ + nvhost_unregister_client_domain(&platform->g->pd); + + /* deinitialise tegra specific scaling quirks */ + gk20a_tegra_scale_exit(dev); + + return 0; +} + static int gk20a_tegra_suspend(struct device *dev) { tegra_edp_notify_gpu_load(0, 0); @@ -491,6 +513,7 @@ static struct gk20a_platform t132_gk20a_tegra_platform = { .probe = gk20a_tegra_probe, .late_probe = gk20a_tegra_late_probe, + .remove = gk20a_tegra_remove, /* power management callbacks */ .suspend = gk20a_tegra_suspend, @@ -534,6 +557,7 @@ struct gk20a_platform gk20a_tegra_platform = { .probe = gk20a_tegra_probe, .late_probe = gk20a_tegra_late_probe, + .remove = gk20a_tegra_remove, /* power management callbacks */ .suspend = gk20a_tegra_suspend, @@ -578,6 +602,7 @@ struct gk20a_platform gm20b_tegra_platform = { .probe = gk20a_tegra_probe, .late_probe = gk20a_tegra_late_probe, + .remove = gk20a_tegra_remove, /* power management callbacks */ .suspend = gk20a_tegra_suspend, -- cgit v1.2.2