From 30d22f86ef8d8821a13c77de5ba061a591d1423b Mon Sep 17 00:00:00 2001 From: Finley Xiao Date: Tue, 9 May 2017 21:31:31 +0800 Subject: [PATCH] drm/rockchip: vop: add vop enable/disable mutex lock It may disable vop_crtc when waiting for line flag, in this case, we would not get line flag any more. So the lock should be added to prevent rockchip_wait_line_flag() from vop_crtc_disable(); Change-Id: I312fd46e64006bf69e3c57f54513230b90866e21 Signed-off-by: Finley Xiao --- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 30 ++++++++++++++++----- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 096f7aa0666b..3871ca7c17a5 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -194,6 +194,8 @@ struct vop { spinlock_t reg_lock; /* lock vop irq reg */ spinlock_t irq_lock; + /* mutex vop enable and disable */ + struct mutex vop_lock; unsigned int irq; @@ -844,6 +846,7 @@ static void vop_crtc_disable(struct drm_crtc *crtc) { struct vop *vop = to_vop(crtc); + mutex_lock(&vop->vop_lock); drm_crtc_vblank_off(crtc); /* @@ -882,6 +885,7 @@ static void vop_crtc_disable(struct drm_crtc *crtc) clk_disable_unprepare(vop->dclk); clk_disable_unprepare(vop->aclk); clk_disable_unprepare(vop->hclk); + mutex_unlock(&vop->vop_lock); } static void vop_plane_destroy(struct drm_plane *plane) @@ -1505,6 +1509,7 @@ static void vop_crtc_enable(struct drm_crtc *crtc) u16 vact_end = vact_st + vdisplay; uint32_t val; + mutex_lock(&vop->vop_lock); vop_initial(crtc); val = BIT(DCLK_INVERT); @@ -1619,6 +1624,7 @@ static void vop_crtc_enable(struct drm_crtc *crtc) enable_irq(vop->irq); drm_crtc_vblank_on(crtc); + mutex_unlock(&vop->vop_lock); } static int vop_zpos_cmp(const void *a, const void *b) @@ -2401,15 +2407,22 @@ int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, unsigned int line_num, { struct vop *vop = to_vop(crtc); unsigned long jiffies_left; + int ret = 0; if (!crtc || !vop->is_enabled) return -ENODEV; - if (line_num > crtc->mode.vtotal || mstimeout <= 0) - return -EINVAL; + mutex_lock(&vop->vop_lock); + + if (line_num > crtc->mode.vtotal || mstimeout <= 0) { + ret = -EINVAL; + goto out; + } - if (vop_line_flag_irq_is_enabled(vop)) - return -EBUSY; + if (vop_line_flag_irq_is_enabled(vop)) { + ret = -EBUSY; + goto out; + } reinit_completion(&vop->line_flag_completion); vop_line_flag_irq_enable(vop, line_num); @@ -2420,10 +2433,14 @@ int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, unsigned int line_num, if (jiffies_left == 0) { dev_err(vop->dev, "Timeout waiting for IRQ\n"); - return -ETIMEDOUT; + ret = -ETIMEDOUT; + goto out; } - return 0; +out: + mutex_unlock(&vop->vop_lock); + + return ret; } EXPORT_SYMBOL(rockchip_drm_wait_line_flag); @@ -2499,6 +2516,7 @@ static int vop_bind(struct device *dev, struct device *master, void *data) spin_lock_init(&vop->reg_lock); spin_lock_init(&vop->irq_lock); + mutex_init(&vop->vop_lock); mutex_init(&vop->vsync_mutex); -- 2.34.1