]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
drm: omapdrm: Simplify IRQ wait implementation
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Mon, 18 Apr 2016 23:47:02 +0000 (02:47 +0300)
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Mon, 19 Dec 2016 09:25:04 +0000 (11:25 +0200)
Now that the IRQ list is used for IRQ wait only we can merge
omap_drm_irq and omap_irq_wait and simplify the implementation.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
drivers/gpu/drm/omapdrm/omap_drv.h
drivers/gpu/drm/omapdrm/omap_irq.c

index dad7d61615635419eec461efa85ec2b51e924477..8ef7e8963bd96b952583b107bb3f214f900a82ab 100644 (file)
@@ -48,19 +48,6 @@ struct omap_drm_window {
        uint32_t src_w, src_h;
 };
 
-/* For transiently registering for different DSS irqs that various parts
- * of the KMS code need during setup/configuration.  We these are not
- * necessarily the same as what drm_vblank_get/put() are requesting, and
- * the hysteresis in drm_vblank_put() is not necessarily desirable for
- * internal housekeeping related irq usage.
- */
-struct omap_drm_irq {
-       struct list_head node;
-       uint32_t irqmask;
-       bool registered;
-       void (*irq)(struct omap_drm_irq *irq);
-};
-
 /* For KMS code that needs to wait for a certain # of IRQs:
  */
 struct omap_irq_wait;
@@ -101,8 +88,8 @@ struct omap_drm_private {
        struct drm_property *zorder_prop;
 
        /* irq handling: */
-       struct list_head irq_list;    /* list of omap_drm_irq */
-       uint32_t irq_mask;              /* enabled irqs in addition to irq_list */
+       struct list_head wait_list;     /* list of omap_irq_wait */
+       uint32_t irq_mask;              /* enabled irqs in addition to wait_list */
 
        /* atomic commit */
        struct {
index 1982759a1c27879d3f84c6f0d2e8a05c4be5261c..0ef2d609653e9235e741f78122e20c0be5281a2b 100644 (file)
 
 static DEFINE_SPINLOCK(list_lock);
 
+struct omap_irq_wait {
+       struct list_head node;
+       uint32_t irqmask;
+       int count;
+};
+
 /* call with list_lock and dispc runtime held */
 static void omap_irq_update(struct drm_device *dev)
 {
        struct omap_drm_private *priv = dev->dev_private;
-       struct omap_drm_irq *irq;
+       struct omap_irq_wait *wait;
        uint32_t irqmask = priv->irq_mask;
 
        assert_spin_locked(&list_lock);
 
-       list_for_each_entry(irq, &priv->irq_list, node)
-               irqmask |= irq->irqmask;
+       list_for_each_entry(wait, &priv->wait_list, node)
+               irqmask |= wait->irqmask;
 
        DBG("irqmask=%08x", irqmask);
 
@@ -39,61 +45,29 @@ static void omap_irq_update(struct drm_device *dev)
        dispc_read_irqenable();        /* flush posted write */
 }
 
-static void omap_irq_register(struct drm_device *dev, struct omap_drm_irq *irq)
-{
-       struct omap_drm_private *priv = dev->dev_private;
-       unsigned long flags;
-
-       spin_lock_irqsave(&list_lock, flags);
-
-       if (!WARN_ON(irq->registered)) {
-               irq->registered = true;
-               list_add(&irq->node, &priv->irq_list);
-               omap_irq_update(dev);
-       }
-
-       spin_unlock_irqrestore(&list_lock, flags);
-}
-
-static void omap_irq_unregister(struct drm_device *dev,
-                               struct omap_drm_irq *irq)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&list_lock, flags);
-
-       if (!WARN_ON(!irq->registered)) {
-               irq->registered = false;
-               list_del(&irq->node);
-               omap_irq_update(dev);
-       }
-
-       spin_unlock_irqrestore(&list_lock, flags);
-}
-
-struct omap_irq_wait {
-       struct omap_drm_irq irq;
-       int count;
-};
-
 static DECLARE_WAIT_QUEUE_HEAD(wait_event);
 
-static void wait_irq(struct omap_drm_irq *irq)
+static void omap_irq_wait_handler(struct omap_irq_wait *wait)
 {
-       struct omap_irq_wait *wait =
-                       container_of(irq, struct omap_irq_wait, irq);
        wait->count--;
-       wake_up_all(&wait_event);
+       wake_up(&wait_event);
 }
 
 struct omap_irq_wait * omap_irq_wait_init(struct drm_device *dev,
                uint32_t irqmask, int count)
 {
+       struct omap_drm_private *priv = dev->dev_private;
        struct omap_irq_wait *wait = kzalloc(sizeof(*wait), GFP_KERNEL);
-       wait->irq.irq = wait_irq;
-       wait->irq.irqmask = irqmask;
+       unsigned long flags;
+
+       wait->irqmask = irqmask;
        wait->count = count;
-       omap_irq_register(dev, &wait->irq);
+
+       spin_lock_irqsave(&list_lock, flags);
+       list_add(&wait->node, &priv->wait_list);
+       omap_irq_update(dev);
+       spin_unlock_irqrestore(&list_lock, flags);
+
        return wait;
 }
 
@@ -101,11 +75,16 @@ int omap_irq_wait(struct drm_device *dev, struct omap_irq_wait *wait,
                unsigned long timeout)
 {
        int ret = wait_event_timeout(wait_event, (wait->count <= 0), timeout);
-       omap_irq_unregister(dev, &wait->irq);
+       unsigned long flags;
+
+       spin_lock_irqsave(&list_lock, flags);
+       list_del(&wait->node);
+       omap_irq_update(dev);
+       spin_unlock_irqrestore(&list_lock, flags);
+
        kfree(wait);
-       if (ret == 0)
-               return -1;
-       return 0;
+
+       return ret == 0 ? -1 : 0;
 }
 
 /**
@@ -213,7 +192,7 @@ static irqreturn_t omap_irq_handler(int irq, void *arg)
 {
        struct drm_device *dev = (struct drm_device *) arg;
        struct omap_drm_private *priv = dev->dev_private;
-       struct omap_drm_irq *handler, *n;
+       struct omap_irq_wait *wait, *n;
        unsigned long flags;
        unsigned int id;
        u32 irqstatus;
@@ -241,12 +220,9 @@ static irqreturn_t omap_irq_handler(int irq, void *arg)
        omap_irq_fifo_underflow(priv, irqstatus);
 
        spin_lock_irqsave(&list_lock, flags);
-       list_for_each_entry_safe(handler, n, &priv->irq_list, node) {
-               if (handler->irqmask & irqstatus) {
-                       spin_unlock_irqrestore(&list_lock, flags);
-                       handler->irq(handler);
-                       spin_lock_irqsave(&list_lock, flags);
-               }
+       list_for_each_entry_safe(wait, n, &priv->wait_list, node) {
+               if (wait->irqmask & irqstatus)
+                       omap_irq_wait_handler(wait);
        }
        spin_unlock_irqrestore(&list_lock, flags);
 
@@ -275,7 +251,7 @@ int omap_drm_irq_install(struct drm_device *dev)
        unsigned int i;
        int ret;
 
-       INIT_LIST_HEAD(&priv->irq_list);
+       INIT_LIST_HEAD(&priv->wait_list);
 
        priv->irq_mask = DISPC_IRQ_OCP_ERR;