summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/gk20a.c
diff options
context:
space:
mode:
authorSachit Kadle <skadle@nvidia.com>2016-06-28 01:53:42 -0400
committerVijayakumar Subbu <vsubbu@nvidia.com>2016-07-27 00:09:11 -0400
commit6ac44d2813f5ab1873eb5148f26746a8f9dbd4a8 (patch)
tree50603804f0e0518db87bb9cde02e4e7189db9d2d /drivers/gpu/nvgpu/gk20a/gk20a.c
parent823f00d4849c57760b0f87f05c253924f50eec9e (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: I249a4527178537c1dc53d769411f53c4451352c3 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 (cherry picked from commit 1e01a49fdc139b8cdf5164b4a6767d22ef4ad1d3) Reviewed-on: http://git-master/r/1185175 GVS: Gerrit_Virtual_Submit Reviewed-by: Thomas Fleury <tfleury@nvidia.com> Reviewed-by: Deepak Nibade <dnibade@nvidia.com> Reviewed-by: Alex Waterman <alexw@nvidia.com> Reviewed-by: Vijayakumar Subbu <vsubbu@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.c33
1 files changed, 14 insertions, 19 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c
index bb8cb33f..caa1583e 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.c
@@ -813,6 +813,10 @@ static int gk20a_pm_prepare_poweroff(struct device *dev)
813 813
814 g->power_on = false; 814 g->power_on = false;
815 815
816 /* Decrement platform power refcount */
817 if (platform->idle)
818 platform->idle(dev);
819
816 /* Stop CPU from accessing the GPU registers. */ 820 /* Stop CPU from accessing the GPU registers. */
817 gk20a_lockout_registers(g); 821 gk20a_lockout_registers(g);
818 822
@@ -859,6 +863,16 @@ int gk20a_pm_finalize_poweron(struct device *dev)
859 863
860 trace_gk20a_finalize_poweron(dev_name(dev)); 864 trace_gk20a_finalize_poweron(dev_name(dev));
861 865
866 /* Increment platform power refcount */
867 if (platform->busy) {
868 err = platform->busy(dev);
869 if (err < 0) {
870 dev_err(dev, "%s: failed to poweron platform dependency\n",
871 __func__);
872 goto done;
873 }
874 }
875
862 err = gk20a_restore_registers(g); 876 err = gk20a_restore_registers(g);
863 if (err) 877 if (err)
864 return err; 878 return err;
@@ -1787,25 +1801,12 @@ int gk20a_busy(struct device *dev)
1787{ 1801{
1788 int ret = 0; 1802 int ret = 0;
1789 struct gk20a *g = get_gk20a(dev); 1803 struct gk20a *g = get_gk20a(dev);
1790 struct gk20a_platform *platform = gk20a_get_platform(dev);
1791 1804
1792 down_read(&g->busy_lock); 1805 down_read(&g->busy_lock);
1793
1794 if (pm_runtime_enabled(dev)) { 1806 if (pm_runtime_enabled(dev)) {
1795 if (platform->busy) {
1796 ret = platform->busy(dev);
1797 if (ret < 0) {
1798 dev_err(dev, "%s: failed to poweron platform dependency\n",
1799 __func__);
1800 goto fail;
1801 }
1802 }
1803
1804 ret = pm_runtime_get_sync(dev); 1807 ret = pm_runtime_get_sync(dev);
1805 if (ret < 0) { 1808 if (ret < 0) {
1806 pm_runtime_put_noidle(dev); 1809 pm_runtime_put_noidle(dev);
1807 if (platform->idle)
1808 platform->idle(dev);
1809 goto fail; 1810 goto fail;
1810 } 1811 }
1811 } else { 1812 } else {
@@ -1818,8 +1819,6 @@ int gk20a_busy(struct device *dev)
1818 } 1819 }
1819 } 1820 }
1820 1821
1821 gk20a_scale_notify_busy(dev);
1822
1823fail: 1822fail:
1824 up_read(&g->busy_lock); 1823 up_read(&g->busy_lock);
1825 1824
@@ -1828,8 +1827,6 @@ fail:
1828 1827
1829void gk20a_idle(struct device *dev) 1828void gk20a_idle(struct device *dev)
1830{ 1829{
1831 struct gk20a_platform *platform = gk20a_get_platform(dev);
1832
1833 if (pm_runtime_enabled(dev)) { 1830 if (pm_runtime_enabled(dev)) {
1834#ifdef CONFIG_PM 1831#ifdef CONFIG_PM
1835 if (atomic_read(&dev->power.usage_count) == 1) 1832 if (atomic_read(&dev->power.usage_count) == 1)
@@ -1839,8 +1836,6 @@ void gk20a_idle(struct device *dev)
1839 pm_runtime_mark_last_busy(dev); 1836 pm_runtime_mark_last_busy(dev);
1840 pm_runtime_put_sync_autosuspend(dev); 1837 pm_runtime_put_sync_autosuspend(dev);
1841 1838
1842 if (platform->idle)
1843 platform->idle(dev);
1844 } else { 1839 } else {
1845 gk20a_scale_notify_idle(dev); 1840 gk20a_scale_notify_idle(dev);
1846 } 1841 }