]> git.karo-electronics.de Git - linux-beck.git/commitdiff
carma-fpga: fix lockdep warning
authorIra Snyder <iws@ovro.caltech.edu>
Thu, 26 Jan 2012 10:59:54 +0000 (10:59 +0000)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Mon, 27 Feb 2012 00:33:59 +0000 (11:33 +1100)
Lockdep occasionally complains with the message:
INFO: HARDIRQ-safe -> HARDIRQ-unsafe lock order detected

This is caused by calling videobuf_dma_unmap() under spin_lock_irq(). To
fix the warning, we drop the lock before unmapping and freeing the
buffer.

Signed-off-by: Ira W. Snyder <iws@ovro.caltech.edu>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
drivers/misc/carma/carma-fpga.c

index 14e974b2a7812452d14ad2d92979e8d84483da7e..4fd896deda0d8ee8878535ac700423f5f54ccd93 100644 (file)
@@ -1079,6 +1079,7 @@ static ssize_t data_read(struct file *filp, char __user *ubuf, size_t count,
        struct fpga_reader *reader = filp->private_data;
        struct fpga_device *priv = reader->priv;
        struct list_head *used = &priv->used;
+       bool drop_buffer = false;
        struct data_buf *dbuf;
        size_t avail;
        void *data;
@@ -1166,10 +1167,12 @@ have_buffer:
         * One of two things has happened, the device is disabled, or the
         * device has been reconfigured underneath us. In either case, we
         * should just throw away the buffer.
+        *
+        * Lockdep complains if this is done under the spinlock, so we
+        * handle it during the unlock path.
         */
        if (!priv->enabled || dbuf->size != priv->bufsize) {
-               videobuf_dma_unmap(priv->dev, &dbuf->vb);
-               data_free_buffer(dbuf);
+               drop_buffer = true;
                goto out_unlock;
        }
 
@@ -1178,6 +1181,12 @@ have_buffer:
 
 out_unlock:
        spin_unlock_irq(&priv->lock);
+
+       if (drop_buffer) {
+               videobuf_dma_unmap(priv->dev, &dbuf->vb);
+               data_free_buffer(dbuf);
+       }
+
        return count;
 }