]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
gpu: nvgpu: force close all channels on shutdown
authorDeepak Nibade <dnibade@nvidia.com>
Tue, 12 Jan 2016 12:19:57 +0000 (17:49 +0530)
committermobile promotions <svcmobile_promotions@nvidia.com>
Mon, 29 Feb 2016 23:25:16 +0000 (15:25 -0800)
In gk20a_pm_shutdown(), we currently wait for 2s
for all channels to finish their work

Instead of waiting, force close all channels
(disable and preempt) during shutdown

Also, if GPU is already railgated during shutdown,
then we can just disable runtime_pm and return
without doing anything

Bug 200166139

Change-Id: I0012f1b3c0f4f676958d083f8c60a001f7015fb0
Signed-off-by: Deepak Nibade <dnibade@nvidia.com>
Reviewed-on: http://git-master/r/931706
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
drivers/gpu/nvgpu/gk20a/channel_gk20a.c
drivers/gpu/nvgpu/gk20a/channel_gk20a.h
drivers/gpu/nvgpu/gk20a/gk20a.c

index 167dd1cb753421c5094ffdace45081c91966fd43..f6da58d5b905071c836ad1799e09d43c5adc8c91 100644 (file)
@@ -1508,7 +1508,7 @@ static void gk20a_channel_schedule_job_clean_up(struct channel_gk20a *c)
        mutex_unlock(&c->clean_up.lock);
 }
 
-static void gk20a_channel_cancel_job_clean_up(struct channel_gk20a *c,
+void gk20a_channel_cancel_job_clean_up(struct channel_gk20a *c,
                                bool wait_for_completion)
 {
        if (wait_for_completion)
index 6021c434f4019460f1c63e65e03a1f43f2ef2b9a..b3186fa0e6f8c95f32d98ea93c88c24d1e86dd7e 100644 (file)
@@ -244,6 +244,9 @@ struct channel_gk20a *gk20a_open_new_channel_with_cb(struct gk20a *g,
                void *update_fn_data);
 void channel_gk20a_unbind(struct channel_gk20a *ch_gk20a);
 
+void gk20a_channel_cancel_job_clean_up(struct channel_gk20a *c,
+                               bool wait_for_completion);
+
 int gk20a_submit_channel_gpfifo(struct channel_gk20a *c,
                                struct nvgpu_gpfifo *gpfifo,
                                struct nvgpu_submit_gpfifo_args *args,
index f5c236ef55f5781b970f0d961386b65119251c47..747e769d5511e71846cc89baeaec176de024284a 100644 (file)
@@ -1134,28 +1134,46 @@ static int gk20a_pm_disable_clk(struct device *dev)
 
 static void gk20a_pm_shutdown(struct platform_device *pdev)
 {
-#ifdef CONFIG_PM_RUNTIME
-       unsigned long timeout = jiffies +
-               msecs_to_jiffies(5000);
-       int ref_cnt;
-#endif
        struct gk20a_platform *platform = platform_get_drvdata(pdev);
        int ret = 0;
+       struct gk20a *g = get_gk20a(pdev);
+       struct fifo_gk20a *f = &g->fifo;
+       int chid;
+
+       /* If GPU is already railgated, just prevent more requests, and return */
+       if (platform->is_railgated && platform->is_railgated(pdev)) {
+#ifdef CONFIG_PM_RUNTIME
+               __pm_runtime_disable(&pdev->dev, false);
+#endif
+               return;
+       }
 
        dev_info(&pdev->dev, "shutting down");
 
+       ret = gk20a_busy(pdev);
+       if (ret)
+               goto fail;
+
+       gk20a_cde_suspend(g);
+
+       for (chid = 0; chid < f->num_channels; chid++) {
+               struct channel_gk20a *ch = &f->channel[chid];
+
+               if (gk20a_channel_get(ch)) {
+                       gk20a_channel_abort(ch, true);
+                       if (ch->update_fn)
+                               cancel_work_sync(&ch->update_fn_work);
+                       gk20a_channel_cancel_job_clean_up(ch, true);
+                       gk20a_channel_put(ch);
+               }
+       }
+
+       gk20a_idle(pdev);
+
+fail:
 #ifdef CONFIG_PM_RUNTIME
        /* Prevent more requests by disabling Runtime PM */
        __pm_runtime_disable(&pdev->dev, false);
-
-       /* Wait until current running requests are finished */
-       while (time_before(jiffies, timeout)) {
-               ref_cnt = atomic_read(&pdev->dev.power.usage_count);
-               if (ref_cnt > 1)
-                       msleep(1);
-               else
-                       break;
-       }
 #endif
 
        /* Be ready for rail-gate after this point */
@@ -1163,6 +1181,8 @@ static void gk20a_pm_shutdown(struct platform_device *pdev)
 
        if (platform->railgate)
                ret = platform->railgate(pdev);
+
+       dev_info(&pdev->dev, "shut down complete\n");
 }
 
 #ifdef CONFIG_PM