@@ -1475,8 +1475,8 @@ static int g2d_remove(struct platform_device *pdev)
return 0;
}
-#ifdef CONFIG_PM
-static int g2d_runtime_suspend(struct device *dev)
+#ifdef CONFIG_PM_SLEEP
+static int g2d_suspend(struct device *dev)
{
struct g2d_data *g2d = dev_get_drvdata(dev);
@@ -1490,6 +1490,25 @@ static int g2d_runtime_suspend(struct device *dev)
flush_work(&g2d->runqueue_work);
+ return 0;
+}
+
+static int g2d_resume(struct device *dev)
+{
+ struct g2d_data *g2d = dev_get_drvdata(dev);
+
+ g2d->suspended = false;
+ g2d_exec_runqueue(g2d);
+
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_PM
+static int g2d_runtime_suspend(struct device *dev)
+{
+ struct g2d_data *g2d = dev_get_drvdata(dev);
+
clk_disable_unprepare(g2d->gate_clk);
return 0;
@@ -1504,16 +1523,12 @@ static int g2d_runtime_resume(struct device *dev)
if (ret < 0)
dev_warn(dev, "failed to enable clock.\n");
- g2d->suspended = false;
- g2d_exec_runqueue(g2d);
-
return ret;
}
#endif
static const struct dev_pm_ops g2d_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
- pm_runtime_force_resume)
+ SET_SYSTEM_SLEEP_PM_OPS(g2d_suspend, g2d_resume)
SET_RUNTIME_PM_OPS(g2d_runtime_suspend, g2d_runtime_resume, NULL)
};
This reverts commit b05984e21a7e000bf5074ace00d7a574944b2c16. The change, i.e. merging the sleep and runpm operations, produces a deadlock situation: (1) exynos_g2d_exec_ioctl() prepares a runqueue node and calls g2d_exec_runqueue() (2) g2d_exec_runqueue() calls g2d_dma_start() which gets runtime PM sync (3) runtime PM core calls g2d_runtime_resume() (4) g2d_runtime_resume() calls g2d_exec_runqueue(), which loops back to (2) Due to mutexes that are in place, a deadlock situation is created. Signed-off-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de> --- drivers/gpu/drm/exynos/exynos_drm_g2d.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-)