diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 9a1f272e41c7..78ce3d232c4d 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -573,8 +573,6 @@ static int vop_enable(struct drm_crtc *crtc) spin_unlock(&vop->reg_lock); - enable_irq(vop->irq); - drm_crtc_vblank_on(crtc); return 0; @@ -618,8 +616,6 @@ static void vop_crtc_atomic_disable(struct drm_crtc *crtc, vop_dsp_hold_valid_irq_disable(vop); - disable_irq(vop->irq); - vop->is_enabled = false; /* @@ -1195,6 +1191,18 @@ static irqreturn_t vop_isr(int irq, void *data) uint32_t active_irqs; int ret = IRQ_NONE; + /* + * The irq is shared with the iommu. If the runtime-pm state of the + * vop-device is disabled the irq has to be targeted at the iommu. + */ + if (!pm_runtime_get_if_in_use(vop->dev)) + return IRQ_NONE; + + if (vop_core_clks_enable(vop)) { + DRM_DEV_ERROR_RATELIMITED(vop->dev, "couldn't enable clocks\n"); + goto out; + } + /* * interrupt register has interrupt status, enable and clear bits, we * must hold irq_lock to avoid a race with enable/disable_vblank(). @@ -1210,7 +1218,7 @@ static irqreturn_t vop_isr(int irq, void *data) /* This is expected for vop iommu irqs, since the irq is shared */ if (!active_irqs) - return IRQ_NONE; + goto out_disable; if (active_irqs & DSP_HOLD_VALID_INTR) { complete(&vop->dsp_hold_completion); @@ -1236,6 +1244,10 @@ static irqreturn_t vop_isr(int irq, void *data) DRM_DEV_ERROR(vop->dev, "Unknown VOP IRQs: %#02x\n", active_irqs); +out_disable: + vop_core_clks_disable(vop); +out: + pm_runtime_put(vop->dev); return ret; } @@ -1614,9 +1626,6 @@ static int vop_bind(struct device *dev, struct device *master, void *data) if (ret) goto err_disable_pm_runtime; - /* IRQ is initially disabled; it gets enabled in power_on */ - disable_irq(vop->irq); - return 0; err_disable_pm_runtime: