From 2a502bdd5f3c93b87286456ca901ad43b0f14906 Mon Sep 17 00:00:00 2001 From: David Nieto Date: Mon, 13 Mar 2017 18:45:37 -0700 Subject: gpu: nvgpu: pass gk20a struct to gk20a_busy After driver remove, the device structure passed in gk20a_busy can be invalid. To solve this the prototype of the function is modified to pass the gk20a struct instead of the device pointer. bug 200277762 JIRA: EVLR-1023 Change-Id: I08eb74bd3578834d45115098ed9936ebbb436fdf Signed-off-by: David Nieto Reviewed-on: http://git-master/r/1320194 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: svccoveritychecker Reviewed-by: Terje Bergstrom GVS: Gerrit_Virtual_Submit --- drivers/gpu/nvgpu/gk20a/gk20a.c | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) (limited to 'drivers/gpu/nvgpu/gk20a/gk20a.c') diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c index 72528758..59f16bf6 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gk20a.c @@ -1434,24 +1434,26 @@ static int gk20a_can_busy(struct gk20a *g) return 1; } -int gk20a_busy(struct device *dev) +int gk20a_busy(struct gk20a *g) { int ret = 0; - struct gk20a *g; - struct gk20a_platform *platform; - - if (!dev) - return -ENODEV; + struct device *dev; - g = get_gk20a(dev); - platform = gk20a_get_platform(dev); - - if (!g || !gk20a_can_busy(g)) + if (!g) return -ENODEV; atomic_inc(&g->usage_count); down_read(&g->busy_lock); + + if (!gk20a_can_busy(g)) { + ret = -ENODEV; + atomic_dec(&g->usage_count); + goto fail; + } + + dev = g->dev; + if (pm_runtime_enabled(dev)) { ret = pm_runtime_get_sync(dev); if (ret < 0) { @@ -1484,22 +1486,21 @@ void gk20a_idle_nosuspend(struct device *dev) pm_runtime_put_noidle(dev); } -void gk20a_idle(struct device *dev) +void gk20a_idle(struct gk20a *g) { - struct gk20a_platform *platform; - struct gk20a *g; + struct device *dev; - if (!dev) - return; + atomic_dec(&g->usage_count); + down_read(&g->busy_lock); - g = get_gk20a(dev); - platform = gk20a_get_platform(dev); + dev = g->dev; - atomic_dec(&g->usage_count); + if (!(dev && gk20a_can_busy(g))) + goto fail; if (pm_runtime_enabled(dev)) { #ifdef CONFIG_PM - if (atomic_read(&dev->power.usage_count) == 1) + if (atomic_read(&g->dev->power.usage_count) == 1) gk20a_scale_notify_idle(dev); #endif @@ -1509,6 +1510,8 @@ void gk20a_idle(struct device *dev) } else { gk20a_scale_notify_idle(dev); } +fail: + up_read(&g->busy_lock); } void gk20a_disable(struct gk20a *g, u32 units) -- cgit v1.2.2