From 9e9be005830e1ebd6c19e2449e687ae1d492254a Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Tue, 25 Aug 2009 11:46:51 -0300 Subject: [PATCH] --- yaml --- r: 164223 b: refs/heads/master c: cca0e54905259a456d97652d4f1e2fe8b188b6ad h: refs/heads/master i: 164221: f91d5ebf9bc958bb0a5e2358de8f7b9d0357ff78 164219: 99498124cecb5c42259a75814bed446d464c966f 164215: 6178aa9836fe80c0a38dddb5e89c0e435d0c2be2 164207: 446de1da065b4401a0b6865ac703db392e8d148a 164191: 32a468c8bbadd77dcbe05d5b98a4c4f19de22144 164159: ed608c5f3c538c9973bfa3d4bdc028decfecc01a 164095: b4f5e5e90b8e648d1b70cb265b414799988d354e v: v3 --- [refs] | 2 +- .../media/video/sh_mobile_ceu_camera.c | 27 +++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index ce65aca9f70a..8368d3412d4e 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: fa48984e36ee73e964eeb994a45de6525114e871 +refs/heads/master: cca0e54905259a456d97652d4f1e2fe8b188b6ad diff --git a/trunk/drivers/media/video/sh_mobile_ceu_camera.c b/trunk/drivers/media/video/sh_mobile_ceu_camera.c index 4c4b60c32263..c0dc4a1e8e52 100644 --- a/trunk/drivers/media/video/sh_mobile_ceu_camera.c +++ b/trunk/drivers/media/video/sh_mobile_ceu_camera.c @@ -307,6 +307,27 @@ static void sh_mobile_ceu_videobuf_queue(struct videobuf_queue *vq, static void sh_mobile_ceu_videobuf_release(struct videobuf_queue *vq, struct videobuf_buffer *vb) { + struct soc_camera_device *icd = vq->priv_data; + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct sh_mobile_ceu_dev *pcdev = ici->priv; + unsigned long flags; + + spin_lock_irqsave(&pcdev->lock, flags); + + if (pcdev->active == vb) { + /* disable capture (release DMA buffer), reset */ + ceu_write(pcdev, CAPSR, 1 << 16); + pcdev->active = NULL; + } + + if ((vb->state == VIDEOBUF_ACTIVE || vb->state == VIDEOBUF_QUEUED) && + !list_empty(&vb->queue)) { + vb->state = VIDEOBUF_ERROR; + list_del_init(&vb->queue); + } + + spin_unlock_irqrestore(&pcdev->lock, flags); + free_buffer(vq, container_of(vb, struct sh_mobile_ceu_buffer, vb)); } @@ -326,6 +347,10 @@ static irqreturn_t sh_mobile_ceu_irq(int irq, void *data) spin_lock_irqsave(&pcdev->lock, flags); vb = pcdev->active; + if (!vb) + /* Stale interrupt from a released buffer */ + goto out; + list_del_init(&vb->queue); if (!list_empty(&pcdev->capture)) @@ -340,6 +365,8 @@ static irqreturn_t sh_mobile_ceu_irq(int irq, void *data) do_gettimeofday(&vb->ts); vb->field_count++; wake_up(&vb->done); + +out: spin_unlock_irqrestore(&pcdev->lock, flags); return IRQ_HANDLED;