diff options
author | Magnus Damm <damm@igel.co.jp> | 2008-10-16 18:51:20 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-10-17 16:26:10 -0400 |
commit | 51354cc3e0c233803505ac8842c3683f42ff42bb (patch) | |
tree | 80aa7f1aedf79deed95a99dfe94d0cd51a868f5f /drivers | |
parent | 2c0a072e3efc17c27566c28028f4b46f79c1f0ca (diff) |
V4L/DVB (9244): video: improve sh_mobile_ceu buffer handling
This patch improves the buffer handling in the sh_mobile_ceu driver.
Instead of marking all queued buffers as VIDEOBUF_ACTIVE the code now
marks queued-but-not-active buffers as VIDEOBUF_QUEUED and buffers
involved in dma as VIDEOBUF_ACTIVE. The code is also updated with
code to cancel active buffers, thanks to Morimoto-san.
Tested-by: Kuninori Morimoto <morimoto.kuninori@renesas.com>
Signed-off-by: Magnus Damm <damm@igel.co.jp>
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/video/sh_mobile_ceu_camera.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c index fa88d382d5b5..2407607f2eff 100644 --- a/drivers/media/video/sh_mobile_ceu_camera.c +++ b/drivers/media/video/sh_mobile_ceu_camera.c | |||
@@ -165,6 +165,7 @@ static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev) | |||
165 | ceu_write(pcdev, CETCR, 0x0317f313 ^ 0x10); | 165 | ceu_write(pcdev, CETCR, 0x0317f313 ^ 0x10); |
166 | 166 | ||
167 | if (pcdev->active) { | 167 | if (pcdev->active) { |
168 | pcdev->active->state = VIDEOBUF_ACTIVE; | ||
168 | ceu_write(pcdev, CDAYR, videobuf_to_dma_contig(pcdev->active)); | 169 | ceu_write(pcdev, CDAYR, videobuf_to_dma_contig(pcdev->active)); |
169 | ceu_write(pcdev, CAPSR, 0x1); /* start capture */ | 170 | ceu_write(pcdev, CAPSR, 0x1); /* start capture */ |
170 | } | 171 | } |
@@ -236,7 +237,7 @@ static void sh_mobile_ceu_videobuf_queue(struct videobuf_queue *vq, | |||
236 | dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__, | 237 | dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__, |
237 | vb, vb->baddr, vb->bsize); | 238 | vb, vb->baddr, vb->bsize); |
238 | 239 | ||
239 | vb->state = VIDEOBUF_ACTIVE; | 240 | vb->state = VIDEOBUF_QUEUED; |
240 | spin_lock_irqsave(&pcdev->lock, flags); | 241 | spin_lock_irqsave(&pcdev->lock, flags); |
241 | list_add_tail(&vb->queue, &pcdev->capture); | 242 | list_add_tail(&vb->queue, &pcdev->capture); |
242 | 243 | ||
@@ -323,12 +324,24 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd) | |||
323 | { | 324 | { |
324 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 325 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
325 | struct sh_mobile_ceu_dev *pcdev = ici->priv; | 326 | struct sh_mobile_ceu_dev *pcdev = ici->priv; |
327 | unsigned long flags; | ||
326 | 328 | ||
327 | BUG_ON(icd != pcdev->icd); | 329 | BUG_ON(icd != pcdev->icd); |
328 | 330 | ||
329 | /* disable capture, disable interrupts */ | 331 | /* disable capture, disable interrupts */ |
330 | ceu_write(pcdev, CEIER, 0); | 332 | ceu_write(pcdev, CEIER, 0); |
331 | ceu_write(pcdev, CAPSR, 1 << 16); /* reset */ | 333 | ceu_write(pcdev, CAPSR, 1 << 16); /* reset */ |
334 | |||
335 | /* make sure active buffer is canceled */ | ||
336 | spin_lock_irqsave(&pcdev->lock, flags); | ||
337 | if (pcdev->active) { | ||
338 | list_del(&pcdev->active->queue); | ||
339 | pcdev->active->state = VIDEOBUF_ERROR; | ||
340 | wake_up_all(&pcdev->active->done); | ||
341 | pcdev->active = NULL; | ||
342 | } | ||
343 | spin_unlock_irqrestore(&pcdev->lock, flags); | ||
344 | |||
332 | icd->ops->release(icd); | 345 | icd->ops->release(icd); |
333 | 346 | ||
334 | dev_info(&icd->dev, | 347 | dev_info(&icd->dev, |