diff options
author | Fancy Fang <chen.fang@nxp.com> | 2018-08-02 14:08:56 +0800 |
---|---|---|
committer | Leonard Crestez <leonard.crestez@nxp.com> | 2018-08-24 12:41:33 +0300 |
commit | 2687a644a05d57c5942b591791f7522748264afc (patch) | |
tree | 80592a62209bdcbd793804c3ea3b6cf01d40acba /drivers/gpu/imx/lcdif | |
parent | b85f4c089af11917ddcc89f6c30089f35e60783f (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.c | 19 |
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 |