- 论坛徽章:
- 0
|
mx1_camera_dma_irq函数里有个spin_lock_irqsave(&pcdev->lock, flags); 对应out:spin_unlock_irqresore(&pcdev->lock, flags);
正常条件下 走到 mx1_camera_wakeup(pcdev, vb, buf); 在这个函数里我也没看到解锁操作. 求大神解释解释为什么不用解锁.??
2.6~3.x的内核 驱动里的代码
static void mx1_camera_wakeup(struct mx1_camera_dev *pcdev,
struct videobuf_buffer *vb,
struct mx1_buffer *buf)
{
/* _init is used to debug races, see comment in mx1_camera_reqbufs() */
list_del_init(&vb->queue);
vb->state = VIDEOBUF_DONE;
do_gettimeofday(&vb->ts);
vb->field_count++;
wake_up(&vb->done);
if (list_empty(&pcdev->capture)) {
pcdev->active = NULL;
return;
}
pcdev->active = list_entry(pcdev->capture.next,
struct mx1_buffer, vb.queue);
/* setup sg list for future DMA */
if (likely(!mx1_camera_setup_dma(pcdev))) {
unsigned int temp;
/* enable SOF irq */
temp = __raw_readl(pcdev->base + CSICR1) | CSICR1_SOF_INTEN;
__raw_writel(temp, pcdev->base + CSICR1);
}
}
static void mx1_camera_dma_irq(int channel, void *data)
{
struct mx1_camera_dev *pcdev = data;
struct device *dev = pcdev->icd->dev.parent;
struct mx1_buffer *buf;
struct videobuf_buffer *vb;
unsigned long flags;
spin_lock_irqsave(&pcdev->lock, flags);
imx_dma_disable(channel);
if (unlikely(!pcdev->active)) {
dev_err(dev, "DMA End IRQ with no active buffer\n");
goto out;
}
vb = &pcdev->active->vb;
buf = container_of(vb, struct mx1_buffer, vb);
WARN_ON(buf->inwork || list_empty(&vb->queue));
dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
vb, vb->baddr, vb->bsize);
mx1_camera_wakeup(pcdev, vb, buf);
out:
spin_unlock_irqrestore(&pcdev->lock, flags);
}
static struct videobuf_queue_ops mx1_videobuf_ops = {
.buf_setup = mx1_videobuf_setup,
.buf_prepare = mx1_videobuf_prepare,
.buf_queue = mx1_videobuf_queue,
.buf_release = mx1_videobuf_release,
};
static void mx1_camera_init_videobuf(struct videobuf_queue *q,
struct soc_camera_device *icd)
{
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct mx1_camera_dev *pcdev = ici->priv;
videobuf_queue_dma_contig_init(q, &mx1_videobuf_ops, icd->dev.parent,
&pcdev->lock,
V4L2_BUF_TYPE_VIDEO_CAPTURE,
V4L2_FIELD_NONE,
sizeof(struct mx1_buffer), icd);
} |
|