summaryrefslogtreecommitdiff
path: root/drivers/gpu/imx/lcdif
diff options
context:
space:
mode:
authorFancy Fang <chen.fang@nxp.com>2018-08-02 14:08:56 +0800
committerLeonard Crestez <leonard.crestez@nxp.com>2018-08-24 12:41:33 +0300
commit2687a644a05d57c5942b591791f7522748264afc (patch)
tree80592a62209bdcbd793804c3ea3b6cf01d40acba /drivers/gpu/imx/lcdif
parentb85f4c089af11917ddcc89f6c30089f35e60783f (diff)
MLK-19112 gpu: imx: lcdif: change 'rpm_suspended' to be atomic counter
Change the 'rpm_suspended' field to be an atomic type from boolean type to make it have the counting ability which can help to detect and avoid runtime suspend and resume calls mismatch caused problems. Signed-off-by: Fancy Fang <chen.fang@nxp.com>
Diffstat (limited to 'drivers/gpu/imx/lcdif')
-rw-r--r--drivers/gpu/imx/lcdif/lcdif-common.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/drivers/gpu/imx/lcdif/lcdif-common.c b/drivers/gpu/imx/lcdif/lcdif-common.c
index df7a940b2fae..86749e44d860 100644
--- a/drivers/gpu/imx/lcdif/lcdif-common.c
+++ b/drivers/gpu/imx/lcdif/lcdif-common.c
@@ -23,6 +23,7 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
+#include <linux/types.h>
#include <drm/drm_fourcc.h>
#include <video/imx-lcdif.h>
#include <video/videomode.h>
@@ -49,7 +50,7 @@ struct lcdif_soc {
int irq;
void __iomem *base;
struct regmap *gpr;
- bool rpm_suspended;
+ atomic_t rpm_suspended;
struct clk *clk_pix;
struct clk *clk_disp_axi;
@@ -611,8 +612,9 @@ static int imx_lcdif_probe(struct platform_device *pdev)
lcdif->dev = dev;
platform_set_drvdata(pdev, lcdif);
+ atomic_set(&lcdif->rpm_suspended, 0);
pm_runtime_enable(dev);
- lcdif->rpm_suspended = true;
+ atomic_inc(&lcdif->rpm_suspended);
dev_dbg(dev, "%s: probe end\n", __func__);
@@ -652,15 +654,13 @@ static int imx_lcdif_runtime_suspend(struct device *dev)
{
struct lcdif_soc *lcdif = dev_get_drvdata(dev);
- if (lcdif->rpm_suspended == true)
+ if (atomic_inc_return(&lcdif->rpm_suspended) > 1)
return 0;
lcdif_disable_clocks(lcdif);
release_bus_freq(BUS_FREQ_HIGH);
- lcdif->rpm_suspended = true;
-
return 0;
}
@@ -669,7 +669,12 @@ static int imx_lcdif_runtime_resume(struct device *dev)
int ret = 0;
struct lcdif_soc *lcdif = dev_get_drvdata(dev);
- if (lcdif->rpm_suspended == false)
+ if (unlikely(!atomic_read(&lcdif->rpm_suspended))) {
+ dev_warn(lcdif->dev, "Unbalanced %s!\n", __func__);
+ return 0;
+ }
+
+ if (!atomic_dec_and_test(&lcdif->rpm_suspended))
return 0;
request_bus_freq(BUS_FREQ_HIGH);
@@ -686,8 +691,6 @@ static int imx_lcdif_runtime_resume(struct device *dev)
/* Pull LCDIF out of reset */
writel(0x0, lcdif->base + LCDIF_CTRL);
- lcdif->rpm_suspended = false;
-
return ret;
}
#endif