mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-24 10:34:43 +03:00
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>
This commit is contained in:
committed by
Terje Bergstrom
parent
459b27f8c1
commit
1e01a49fdc
@@ -696,6 +696,7 @@ static int gk20a_init_support(struct platform_device *dev)
|
||||
static int gk20a_pm_prepare_poweroff(struct device *dev)
|
||||
{
|
||||
struct gk20a *g = get_gk20a(dev);
|
||||
struct gk20a_platform *platform = gk20a_get_platform(dev);
|
||||
int ret = 0;
|
||||
|
||||
gk20a_dbg_fn("");
|
||||
@@ -733,6 +734,10 @@ static int gk20a_pm_prepare_poweroff(struct device *dev)
|
||||
|
||||
g->power_on = false;
|
||||
|
||||
/* Decrement platform power refcount */
|
||||
if (platform->idle)
|
||||
platform->idle(dev);
|
||||
|
||||
/* Stop CPU from accessing the GPU registers. */
|
||||
gk20a_lockout_registers(g);
|
||||
|
||||
@@ -779,6 +784,16 @@ int gk20a_pm_finalize_poweron(struct device *dev)
|
||||
|
||||
trace_gk20a_finalize_poweron(dev_name(dev));
|
||||
|
||||
/* Increment platform power refcount */
|
||||
if (platform->busy) {
|
||||
err = platform->busy(dev);
|
||||
if (err < 0) {
|
||||
dev_err(dev, "%s: failed to poweron platform dependency\n",
|
||||
__func__);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
err = gk20a_restore_registers(g);
|
||||
if (err)
|
||||
return err;
|
||||
@@ -1802,27 +1817,13 @@ int gk20a_busy(struct device *dev)
|
||||
{
|
||||
int ret = 0;
|
||||
struct gk20a *g = get_gk20a(dev);
|
||||
#ifdef CONFIG_PM
|
||||
struct gk20a_platform *platform = gk20a_get_platform(dev);
|
||||
#endif
|
||||
|
||||
down_read(&g->busy_lock);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
if (platform->busy) {
|
||||
ret = platform->busy(dev);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "%s: failed to poweron platform dependency\n",
|
||||
__func__);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
ret = pm_runtime_get_sync(dev);
|
||||
if (ret < 0) {
|
||||
pm_runtime_put_noidle(dev);
|
||||
if (platform->idle)
|
||||
platform->idle(dev);
|
||||
goto fail;
|
||||
}
|
||||
#else
|
||||
@@ -1845,14 +1846,10 @@ fail:
|
||||
void gk20a_idle(struct device *dev)
|
||||
{
|
||||
#ifdef CONFIG_PM
|
||||
struct gk20a_platform *platform = gk20a_get_platform(dev);
|
||||
if (atomic_read(&dev->power.usage_count) == 1)
|
||||
gk20a_scale_notify_idle(dev);
|
||||
pm_runtime_mark_last_busy(dev);
|
||||
pm_runtime_put_sync_autosuspend(dev);
|
||||
|
||||
if (platform->idle)
|
||||
platform->idle(dev);
|
||||
#else
|
||||
gk20a_scale_notify_idle(dev);
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user