summaryrefslogtreecommitdiffstats
path: root/drivers/misc/carma
diff options
context:
space:
mode:
authorIra Snyder <iws@ovro.caltech.edu>2012-01-26 10:59:54 +0000
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-02-27 11:33:59 +1100
commit75ff85a81680e5779383aa6210a4f89ed76e40ec (patch)
treec327f25f2a51fc32382f0fcff4fee7c0532b6f15 /drivers/misc/carma
parent6d45584fdc202fd30da655120412210153429104 (diff)
carma-fpga: fix lockdep warning
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>
Diffstat (limited to 'drivers/misc/carma')
-rw-r--r--drivers/misc/carma/carma-fpga.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/drivers/misc/carma/carma-fpga.c b/drivers/misc/carma/carma-fpga.c
index 14e974b2a78..4fd896deda0 100644
--- a/drivers/misc/carma/carma-fpga.c
+++ b/drivers/misc/carma/carma-fpga.c
@@ -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;
}