Instead of going through a complicated registration mechanism, just
expose the CRTC error IRQ function and call it directly from the main
IRQ handler.

Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen at ti.com>
---
 drivers/gpu/drm/omapdrm/omap_crtc.c | 12 ++----------
 drivers/gpu/drm/omapdrm/omap_drv.h  |  1 +
 drivers/gpu/drm/omapdrm/omap_irq.c  |  8 ++++++++
 3 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c 
b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 180f644e861e..cdcfda31043e 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -37,7 +37,6 @@ struct omap_crtc {
        struct omap_video_timings timings;

        struct omap_drm_irq vblank_irq;
-       struct omap_drm_irq error_irq;

        bool ignore_digit_sync_lost;

@@ -275,10 +274,9 @@ static void omap_crtc_complete_page_flip(struct drm_crtc 
*crtc)
        spin_unlock_irqrestore(&dev->event_lock, flags);
 }

-static void omap_crtc_error_irq(struct omap_drm_irq *irq, uint32_t irqstatus)
+void omap_crtc_error_irq(struct drm_crtc *crtc, uint32_t irqstatus)
 {
-       struct omap_crtc *omap_crtc =
-                       container_of(irq, struct omap_crtc, error_irq);
+       struct omap_crtc *omap_crtc = to_omap_crtc(crtc);

        if (omap_crtc->ignore_digit_sync_lost) {
                irqstatus &= ~DISPC_IRQ_SYNC_LOST_DIGIT;
@@ -325,7 +323,6 @@ static void omap_crtc_destroy(struct drm_crtc *crtc)
        DBG("%s", omap_crtc->name);

        WARN_ON(omap_crtc->vblank_irq.registered);
-       omap_irq_unregister(crtc->dev, &omap_crtc->error_irq);

        drm_crtc_cleanup(crtc);

@@ -562,11 +559,6 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
        omap_crtc->vblank_irq.irqmask = pipe2vbl(crtc);
        omap_crtc->vblank_irq.irq = omap_crtc_vblank_irq;

-       omap_crtc->error_irq.irqmask =
-                       dispc_mgr_get_sync_lost_irq(channel);
-       omap_crtc->error_irq.irq = omap_crtc_error_irq;
-       omap_irq_register(dev, &omap_crtc->error_irq);
-
        ret = drm_crtc_init_with_planes(dev, crtc, plane, NULL,
                                        &omap_crtc_funcs, NULL);
        if (ret < 0) {
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h 
b/drivers/gpu/drm/omapdrm/omap_drv.h
index 6bc1588e1c9e..7a1d8384147c 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -155,6 +155,7 @@ void omap_crtc_pre_uninit(void);
 struct drm_crtc *omap_crtc_init(struct drm_device *dev,
                struct drm_plane *plane, enum omap_channel channel, int id);
 int omap_crtc_wait_pending(struct drm_crtc *crtc);
+void omap_crtc_error_irq(struct drm_crtc *crtc, uint32_t irqstatus);

 struct drm_plane *omap_plane_init(struct drm_device *dev,
                int id, enum drm_plane_type type);
diff --git a/drivers/gpu/drm/omapdrm/omap_irq.c 
b/drivers/gpu/drm/omapdrm/omap_irq.c
index 23045f528a93..f0f110faf1e6 100644
--- a/drivers/gpu/drm/omapdrm/omap_irq.c
+++ b/drivers/gpu/drm/omapdrm/omap_irq.c
@@ -241,9 +241,13 @@ static irqreturn_t omap_irq_handler(int irq, void *arg)

        for (id = 0; id < priv->num_crtcs; id++) {
                struct drm_crtc *crtc = priv->crtcs[id];
+               enum omap_channel channel = omap_crtc_channel(crtc);

                if (irqstatus & pipe2vbl(crtc))
                        drm_handle_vblank(dev, id);
+
+               if (irqstatus & dispc_mgr_get_sync_lost_irq(channel))
+                       omap_crtc_error_irq(crtc, irqstatus);
        }

        omap_irq_fifo_underflow(priv, irqstatus);
@@ -279,6 +283,7 @@ int omap_drm_irq_install(struct drm_device *dev)
 {
        struct omap_drm_private *priv = dev->dev_private;
        struct omap_drm_irq *error_handler = &priv->error_handler;
+       unsigned int num_mgrs = dss_feat_get_num_mgrs();
        unsigned int max_planes;
        unsigned int i;
        int ret;
@@ -293,6 +298,9 @@ int omap_drm_irq_install(struct drm_device *dev)
                        priv->irq_mask |= error_irqs[i];
        }

+       for (i = 0; i < num_mgrs; ++i)
+               priv->irq_mask |= dispc_mgr_get_sync_lost_irq(i);
+
        dispc_runtime_get();
        dispc_clear_irqstatus(0xffffffff);
        dispc_runtime_put();
-- 
Regards,

Laurent Pinchart

Reply via email to