summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSachit Kadle <skadle@nvidia.com>2016-06-28 01:53:42 -0400
committerTerje Bergstrom <tbergstrom@nvidia.com>2016-06-30 18:10:45 -0400
commit1e01a49fdc139b8cdf5164b4a6767d22ef4ad1d3 (patch)
treecb935b3966d68f80fc4198f0e7e1b9d3a2d8ccb8 /drivers
parent459b27f8c15a5062c0d84436a829147931261f6d (diff)
gpu: nvgpu: take platform power ref at power on
Currently, host1x power refcount may decrement to 0, while GPU is still powered on and we're still servicing IRQs. So to prevent this situation,, take a ref while GPU is being powered on, and decrement it during power off. Since we are always holding one reference while GPU is powered on, we can remove this handling from gk20a_busy/idle(). Bug 200187507 Change-Id: Idabe88754f009f1e8de8dc821d53be3e013dc657 Signed-off-by: Sachit Kadle <skadle@nvidia.com> Reviewed-on: http://git-master/r/1172320 (cherry picked from commit 3e27e6a5820f5c1ad05596553d75e8979b71f1bd) Reviewed-on: http://git-master/r/1172607 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.c33
1 files changed, 15 insertions, 18 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c
index 44ed4e51..05599649 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.c
@@ -696,6 +696,7 @@ static int gk20a_init_support(struct platform_device *dev)
696static int gk20a_pm_prepare_poweroff(struct device *dev) 696static int gk20a_pm_prepare_poweroff(struct device *dev)
697{ 697{
698 struct gk20a *g = get_gk20a(dev); 698 struct gk20a *g = get_gk20a(dev);
699 struct gk20a_platform *platform = gk20a_get_platform(dev);
699 int ret = 0; 700 int ret = 0;
700 701
701 gk20a_dbg_fn(""); 702 gk20a_dbg_fn("");
@@ -733,6 +734,10 @@ static int gk20a_pm_prepare_poweroff(struct device *dev)
733 734
734 g->power_on = false; 735 g->power_on = false;
735 736
737 /* Decrement platform power refcount */
738 if (platform->idle)
739 platform->idle(dev);
740
736 /* Stop CPU from accessing the GPU registers. */ 741 /* Stop CPU from accessing the GPU registers. */
737 gk20a_lockout_registers(g); 742 gk20a_lockout_registers(g);
738 743
@@ -779,6 +784,16 @@ int gk20a_pm_finalize_poweron(struct device *dev)
779 784
780 trace_gk20a_finalize_poweron(dev_name(dev)); 785 trace_gk20a_finalize_poweron(dev_name(dev));
781 786
787 /* Increment platform power refcount */
788 if (platform->busy) {
789 err = platform->busy(dev);
790 if (err < 0) {
791 dev_err(dev, "%s: failed to poweron platform dependency\n",
792 __func__);
793 return err;
794 }
795 }
796
782 err = gk20a_restore_registers(g); 797 err = gk20a_restore_registers(g);
783 if (err) 798 if (err)
784 return err; 799 return err;
@@ -1802,27 +1817,13 @@ int gk20a_busy(struct device *dev)
1802{ 1817{
1803 int ret = 0; 1818 int ret = 0;
1804 struct gk20a *g = get_gk20a(dev); 1819 struct gk20a *g = get_gk20a(dev);
1805#ifdef CONFIG_PM
1806 struct gk20a_platform *platform = gk20a_get_platform(dev);
1807#endif
1808 1820
1809 down_read(&g->busy_lock); 1821 down_read(&g->busy_lock);
1810 1822
1811#ifdef CONFIG_PM 1823#ifdef CONFIG_PM
1812 if (platform->busy) {
1813 ret = platform->busy(dev);
1814 if (ret < 0) {
1815 dev_err(dev, "%s: failed to poweron platform dependency\n",
1816 __func__);
1817 goto fail;
1818 }
1819 }
1820
1821 ret = pm_runtime_get_sync(dev); 1824 ret = pm_runtime_get_sync(dev);
1822 if (ret < 0) { 1825 if (ret < 0) {
1823 pm_runtime_put_noidle(dev); 1826 pm_runtime_put_noidle(dev);
1824 if (platform->idle)
1825 platform->idle(dev);
1826 goto fail; 1827 goto fail;
1827 } 1828 }
1828#else 1829#else
@@ -1845,14 +1846,10 @@ fail:
1845void gk20a_idle(struct device *dev) 1846void gk20a_idle(struct device *dev)
1846{ 1847{
1847#ifdef CONFIG_PM 1848#ifdef CONFIG_PM
1848 struct gk20a_platform *platform = gk20a_get_platform(dev);
1849 if (atomic_read(&dev->power.usage_count) == 1) 1849 if (atomic_read(&dev->power.usage_count) == 1)
1850 gk20a_scale_notify_idle(dev); 1850 gk20a_scale_notify_idle(dev);
1851 pm_runtime_mark_last_busy(dev); 1851 pm_runtime_mark_last_busy(dev);
1852 pm_runtime_put_sync_autosuspend(dev); 1852 pm_runtime_put_sync_autosuspend(dev);
1853
1854 if (platform->idle)
1855 platform->idle(dev);
1856#else 1853#else
1857 gk20a_scale_notify_idle(dev); 1854 gk20a_scale_notify_idle(dev);
1858#endif 1855#endif