diff options
author | Tobias Jakobi <tjakobi@math.uni-bielefeld.de> | 2016-09-27 11:50:06 -0400 |
---|---|---|
committer | Inki Dae <daeinki@gmail.com> | 2016-09-30 11:39:38 -0400 |
commit | 05e2e4666c2609bd9a72140611713c19ce28fce1 (patch) | |
tree | 2cb5265c6d09fadbd33df499959b1416f3ec0731 /drivers/gpu | |
parent | 9276dff7a89d81e84a4e4a1a07b636232be5aab0 (diff) |
Revert "drm/exynos: g2d: fix system and runtime pm integration"
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>
Acked-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_g2d.c | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c index 9c9f4f972150..0bffd349fcad 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c | |||
@@ -1475,8 +1475,8 @@ static int g2d_remove(struct platform_device *pdev) | |||
1475 | return 0; | 1475 | return 0; |
1476 | } | 1476 | } |
1477 | 1477 | ||
1478 | #ifdef CONFIG_PM | 1478 | #ifdef CONFIG_PM_SLEEP |
1479 | static int g2d_runtime_suspend(struct device *dev) | 1479 | static int g2d_suspend(struct device *dev) |
1480 | { | 1480 | { |
1481 | struct g2d_data *g2d = dev_get_drvdata(dev); | 1481 | struct g2d_data *g2d = dev_get_drvdata(dev); |
1482 | 1482 | ||
@@ -1490,6 +1490,25 @@ static int g2d_runtime_suspend(struct device *dev) | |||
1490 | 1490 | ||
1491 | flush_work(&g2d->runqueue_work); | 1491 | flush_work(&g2d->runqueue_work); |
1492 | 1492 | ||
1493 | return 0; | ||
1494 | } | ||
1495 | |||
1496 | static int g2d_resume(struct device *dev) | ||
1497 | { | ||
1498 | struct g2d_data *g2d = dev_get_drvdata(dev); | ||
1499 | |||
1500 | g2d->suspended = false; | ||
1501 | g2d_exec_runqueue(g2d); | ||
1502 | |||
1503 | return 0; | ||
1504 | } | ||
1505 | #endif | ||
1506 | |||
1507 | #ifdef CONFIG_PM | ||
1508 | static int g2d_runtime_suspend(struct device *dev) | ||
1509 | { | ||
1510 | struct g2d_data *g2d = dev_get_drvdata(dev); | ||
1511 | |||
1493 | clk_disable_unprepare(g2d->gate_clk); | 1512 | clk_disable_unprepare(g2d->gate_clk); |
1494 | 1513 | ||
1495 | return 0; | 1514 | return 0; |
@@ -1504,16 +1523,12 @@ static int g2d_runtime_resume(struct device *dev) | |||
1504 | if (ret < 0) | 1523 | if (ret < 0) |
1505 | dev_warn(dev, "failed to enable clock.\n"); | 1524 | dev_warn(dev, "failed to enable clock.\n"); |
1506 | 1525 | ||
1507 | g2d->suspended = false; | ||
1508 | g2d_exec_runqueue(g2d); | ||
1509 | |||
1510 | return ret; | 1526 | return ret; |
1511 | } | 1527 | } |
1512 | #endif | 1528 | #endif |
1513 | 1529 | ||
1514 | static const struct dev_pm_ops g2d_pm_ops = { | 1530 | static const struct dev_pm_ops g2d_pm_ops = { |
1515 | SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, | 1531 | SET_SYSTEM_SLEEP_PM_OPS(g2d_suspend, g2d_resume) |
1516 | pm_runtime_force_resume) | ||
1517 | SET_RUNTIME_PM_OPS(g2d_runtime_suspend, g2d_runtime_resume, NULL) | 1532 | SET_RUNTIME_PM_OPS(g2d_runtime_suspend, g2d_runtime_resume, NULL) |
1518 | }; | 1533 | }; |
1519 | 1534 | ||