summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.c23
-rw-r--r--drivers/gpu/nvgpu/gk20a/platform_gk20a.h1
2 files changed, 21 insertions, 3 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c
index 629423c0..64be9398 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.c
@@ -1281,8 +1281,13 @@ static int _gk20a_pm_unrailgate(struct platform_device *pdev)
1281{ 1281{
1282 struct gk20a_platform *platform = platform_get_drvdata(pdev); 1282 struct gk20a_platform *platform = platform_get_drvdata(pdev);
1283 int ret = 0; 1283 int ret = 0;
1284 if (platform->unrailgate) 1284
1285 if (platform->unrailgate) {
1286 mutex_lock(&platform->railgate_lock);
1285 ret = platform->unrailgate(pdev); 1287 ret = platform->unrailgate(pdev);
1288 mutex_unlock(&platform->railgate_lock);
1289 }
1290
1286 return ret; 1291 return ret;
1287} 1292}
1288 1293
@@ -1362,6 +1367,8 @@ static int gk20a_pm_init(struct platform_device *dev)
1362 1367
1363 gk20a_dbg_fn(""); 1368 gk20a_dbg_fn("");
1364 1369
1370 mutex_init(&platform->railgate_lock);
1371
1365 /* Initialise pm runtime */ 1372 /* Initialise pm runtime */
1366 if (platform->clockgate_delay) { 1373 if (platform->clockgate_delay) {
1367 pm_runtime_set_autosuspend_delay(&dev->dev, 1374 pm_runtime_set_autosuspend_delay(&dev->dev,
@@ -1739,6 +1746,13 @@ int gk20a_do_idle(void)
1739 /* acquire busy lock to block other busy() calls */ 1746 /* acquire busy lock to block other busy() calls */
1740 down_write(&g->busy_lock); 1747 down_write(&g->busy_lock);
1741 1748
1749 /* acquire railgate lock to prevent unrailgate in midst of do_idle() */
1750 mutex_lock(&platform->railgate_lock);
1751
1752 /* check if it is already railgated ? */
1753 if (platform->is_railgated(pdev))
1754 return 0;
1755
1742 /* prevent suspend by incrementing usage counter */ 1756 /* prevent suspend by incrementing usage counter */
1743 pm_runtime_get_noresume(&pdev->dev); 1757 pm_runtime_get_noresume(&pdev->dev);
1744 1758
@@ -1776,11 +1790,12 @@ int gk20a_do_idle(void)
1776 } 1790 }
1777 1791
1778 /* GPU is not rail gated by now, return error */ 1792 /* GPU is not rail gated by now, return error */
1779 up_write(&g->busy_lock); 1793 goto fail_timeout;
1780 return -EBUSY;
1781 1794
1782fail: 1795fail:
1783 pm_runtime_put_noidle(&pdev->dev); 1796 pm_runtime_put_noidle(&pdev->dev);
1797fail_timeout:
1798 mutex_unlock(&platform->railgate_lock);
1784 up_write(&g->busy_lock); 1799 up_write(&g->busy_lock);
1785 return -EBUSY; 1800 return -EBUSY;
1786} 1801}
@@ -1794,8 +1809,10 @@ int gk20a_do_unidle(void)
1794 bus_find_device_by_name(&platform_bus_type, 1809 bus_find_device_by_name(&platform_bus_type,
1795 NULL, "gk20a.0")); 1810 NULL, "gk20a.0"));
1796 struct gk20a *g = get_gk20a(pdev); 1811 struct gk20a *g = get_gk20a(pdev);
1812 struct gk20a_platform *platform = dev_get_drvdata(&pdev->dev);
1797 1813
1798 /* release the lock and open up all other busy() calls */ 1814 /* release the lock and open up all other busy() calls */
1815 mutex_unlock(&platform->railgate_lock);
1799 up_write(&g->busy_lock); 1816 up_write(&g->busy_lock);
1800 1817
1801 return 0; 1818 return 0;
diff --git a/drivers/gpu/nvgpu/gk20a/platform_gk20a.h b/drivers/gpu/nvgpu/gk20a/platform_gk20a.h
index 231f97b3..76e9cf6c 100644
--- a/drivers/gpu/nvgpu/gk20a/platform_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/platform_gk20a.h
@@ -118,6 +118,7 @@ struct gk20a_platform {
118 118
119 /* Called to turn on the device */ 119 /* Called to turn on the device */
120 int (*unrailgate)(struct platform_device *dev); 120 int (*unrailgate)(struct platform_device *dev);
121 struct mutex railgate_lock;
121 122
122 /* Called to check state of device */ 123 /* Called to check state of device */
123 bool (*is_railgated)(struct platform_device *dev); 124 bool (*is_railgated)(struct platform_device *dev);