From: Finley Xiao Date: Mon, 31 Jul 2017 10:53:48 +0000 (+0800) Subject: drm/rockchip: vop: add mutex lock to two vops X-Git-Tag: release-20171130_firefly~4^2~69 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=796f116833d21c7d338ce3ccda62f761f4451ebc;p=firefly-linux-kernel-4.4.55.git drm/rockchip: vop: add mutex lock to two vops Each vop should add mutex lock when do ddr frequceny change. Change-Id: Ie63c90b0b4421d1be6bf8bdc9ff3b179fdf2193d Signed-off-by: Finley Xiao --- diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 174002ca0f1b..5e11e652f1ac 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -43,6 +43,8 @@ #include "rockchip_drm_vop.h" #include "rockchip_drm_backlight.h" +#define MAX_VOPS 2 + #define VOP_REG_SUPPORT(vop, reg) \ (!reg.major || (reg.major == VOP_MAJOR(vop->data->version) && \ reg.begin_minor <= VOP_MINOR(vop->data->version) && \ @@ -231,7 +233,6 @@ struct vop { /* vop dclk reset */ struct reset_control *dclk_rst; - struct devfreq *devfreq; struct notifier_block dmc_nb; struct rockchip_dclk_pll *pll; @@ -239,7 +240,9 @@ struct vop { struct vop_win win[]; }; -struct vop *dmc_vop; +static struct vop *dmc_vop[MAX_VOPS]; +static struct devfreq *devfreq_vop; +static DEFINE_MUTEX(register_devfreq_lock); static inline void vop_writel(struct vop *vop, uint32_t offset, uint32_t v) { @@ -3033,23 +3036,38 @@ EXPORT_SYMBOL(rockchip_drm_wait_line_flag); static int dmc_notifier_call(struct notifier_block *nb, unsigned long event, void *data) { + struct vop *vop = container_of(nb, struct vop, dmc_nb); + if (event == DEVFREQ_PRECHANGE) - mutex_lock(&dmc_vop->vop_lock); + mutex_lock(&vop->vop_lock); else if (event == DEVFREQ_POSTCHANGE) - mutex_unlock(&dmc_vop->vop_lock); + mutex_unlock(&vop->vop_lock); return NOTIFY_OK; } int rockchip_drm_register_notifier_to_dmc(struct devfreq *devfreq) { - if (!dmc_vop) + int i, j = 0; + + mutex_lock(®ister_devfreq_lock); + + devfreq_vop = devfreq; + + for (i = 0; i < ARRAY_SIZE(dmc_vop); i++) { + if (!dmc_vop[i]) + continue; + dmc_vop[i]->dmc_nb.notifier_call = dmc_notifier_call; + devfreq_register_notifier(devfreq_vop, &dmc_vop[i]->dmc_nb, + DEVFREQ_TRANSITION_NOTIFIER); + j++; + } + + mutex_unlock(®ister_devfreq_lock); + + if (j == 0) return -ENOMEM; - dmc_vop->devfreq = devfreq; - dmc_vop->dmc_nb.notifier_call = dmc_notifier_call; - devfreq_register_notifier(dmc_vop->devfreq, &dmc_vop->dmc_nb, - DEVFREQ_TRANSITION_NOTIFIER); return 0; } EXPORT_SYMBOL(rockchip_drm_register_notifier_to_dmc); @@ -3213,7 +3231,22 @@ static int vop_bind(struct device *dev, struct device *master, void *data) of_rockchip_drm_sub_backlight_register(dev, &vop->crtc, &rockchip_sub_backlight_ops); - dmc_vop = vop; + mutex_lock(®ister_devfreq_lock); + + for (i = 0; i < ARRAY_SIZE(dmc_vop); i++) { + if (dmc_vop[i]) + continue; + dmc_vop[i] = vop; + if (devfreq_vop) { + dmc_vop[i]->dmc_nb.notifier_call = dmc_notifier_call; + devfreq_register_notifier(devfreq_vop, + &dmc_vop[i]->dmc_nb, + DEVFREQ_TRANSITION_NOTIFIER); + } + break; + } + + mutex_unlock(®ister_devfreq_lock); return 0; } @@ -3221,6 +3254,23 @@ static int vop_bind(struct device *dev, struct device *master, void *data) static void vop_unbind(struct device *dev, struct device *master, void *data) { struct vop *vop = dev_get_drvdata(dev); + int i; + + mutex_lock(®ister_devfreq_lock); + + for (i = 0; i < ARRAY_SIZE(dmc_vop); i++) { + if (dmc_vop[i] != vop) + continue; + dmc_vop[i] = NULL; + + if (!devfreq_vop) + break; + devfreq_unregister_notifier(devfreq_vop, &dmc_vop[i]->dmc_nb, + DEVFREQ_TRANSITION_NOTIFIER); + break; + } + + mutex_unlock(®ister_devfreq_lock); pm_runtime_disable(dev); vop_destroy_crtc(vop);