]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
video: tegra: host: Implement shutdown
authorArto Merilainen <amerilainen@nvidia.com>
Mon, 15 Dec 2014 16:16:42 +0000 (18:16 +0200)
committerArto Merilainen <amerilainen@nvidia.com>
Thu, 18 Dec 2014 09:34:25 +0000 (01:34 -0800)
In rare occassions something starts waiting for a syncpoint
when we are starting shutdown and as a result the shutdown process
may get disrupted when the syncpoint value is not achieved.

This patch adds shutdown routine to host1x. During shutdown we..:
- Release all syncpoint waiters with -ETIMEDOUT error code
- Prevent new requests by disabling pm runtime from host1x

Bug 200064323

Change-Id: If20fcf78af14a3ee639496da2c8f9f8ef43733db
Signed-off-by: Arto Merilainen <amerilainen@nvidia.com>
Reviewed-on: http://git-master/r/663956

drivers/video/tegra/host/host1x/host1x.c
drivers/video/tegra/host/host1x/host1x.h
drivers/video/tegra/host/nvhost_syncpt.c

index c96c49ffb1369360006c03b597337b33417cefdc..dd7615584e235144513cca0e850fec33610622f0 100644 (file)
@@ -894,6 +894,7 @@ static int nvhost_probe(struct platform_device *dev)
                        sizeof(struct host1x_device_info));
 
        pdata->pdev = dev;
+       atomic_set(&host->shutdown, 0);
 
        /* set common host1x device data */
        platform_set_drvdata(dev, pdata);
@@ -1048,6 +1049,15 @@ static int nvhost_resume(struct device *dev)
        return 0;
 }
 
+static void nvhost_shutdown(struct platform_device *pdev)
+{
+       struct nvhost_master *host = nvhost_get_host(pdev);
+
+       dev_info(&pdev->dev, "shutting down");
+       atomic_set(&host->shutdown, 1);
+       __pm_runtime_disable(&pdev->dev, false);
+}
+
 static const struct dev_pm_ops host1x_pm_ops = {
        .prepare = nvhost_suspend_prepare,
        .complete = nvhost_suspend_complete,
@@ -1059,6 +1069,9 @@ static const struct dev_pm_ops host1x_pm_ops = {
 static struct platform_driver platform_driver = {
        .probe = nvhost_probe,
        .remove = __exit_p(nvhost_remove),
+#ifdef CONFIG_PM
+       .shutdown = nvhost_shutdown,
+#endif
        .driver = {
                .owner = THIS_MODULE,
                .name = DRIVER_NAME,
index 9aecf7804abe582326be0e3eef68fe60e47109b4..c6b67f6ab8a7e9edcad55aed944ab23c1f247cfd 100644 (file)
@@ -86,6 +86,7 @@ struct nvhost_master {
        struct mutex chlist_mutex;      /* mutex for channel list */
        unsigned long allocated_channels;
        unsigned long next_free_ch;
+       atomic_t shutdown;
 };
 
 extern struct nvhost_master *nvhost;
index 8406d9fd01340388b04f636a09e57b484e314570..6d4316e0cbb96ac8b36371fc6be535e73c71110f 100644 (file)
@@ -296,6 +296,13 @@ int nvhost_syncpt_wait_timeout(struct nvhost_syncpt *sp, u32 id,
                        err = 0;
                        break;
                }
+
+               /* short-circuit if we are turning off the system */
+               if (atomic_read(&host->shutdown)) {
+                       err = -ETIMEDOUT;
+                       break;
+               }
+
                if (remain < 0) {
                        err = remain;
                        break;