diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2007-05-19 14:07:16 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-06-08 08:21:13 -0300 |
commit | dc02d50a6d71cba2b2edb78377af5a5965879a49 (patch) | |
tree | 199528db7b95dacd395004119614567b57725787 /drivers/media/video/ivtv/ivtv-queue.c | |
parent | ffeb9ec72e18e16d0b0835d959cdf01650758638 (diff) |
V4L/DVB (5675): Move big PIO accesses from the interrupt handler to a workhandler
Sliced VBI transfers use PIO instead of DMA. This was done inside the
interrupt handler, but since PIO accesses are very slow this meant that
a lot of time was spent inside the interrupt handler. All PIO copies are
now moved to a workqueue. This should fix various issues with missing time
ticks and remote key hits.
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/ivtv/ivtv-queue.c')
-rw-r--r-- | drivers/media/video/ivtv/ivtv-queue.c | 31 |
1 files changed, 23 insertions, 8 deletions
diff --git a/drivers/media/video/ivtv/ivtv-queue.c b/drivers/media/video/ivtv/ivtv-queue.c index ccfcef1ad91..a04f9387f63 100644 --- a/drivers/media/video/ivtv/ivtv-queue.c +++ b/drivers/media/video/ivtv/ivtv-queue.c @@ -195,14 +195,26 @@ int ivtv_stream_alloc(struct ivtv_stream *s) s->dma != PCI_DMA_NONE ? "DMA " : "", s->name, s->buffers, s->buf_size, s->buffers * s->buf_size / 1024); - /* Allocate DMA SG Arrays */ - if (s->dma != PCI_DMA_NONE) { - s->SGarray = (struct ivtv_SG_element *)kzalloc(SGsize, GFP_KERNEL); - if (s->SGarray == NULL) { - IVTV_ERR("Could not allocate SGarray for %s stream\n", s->name); + if (ivtv_might_use_pio(s)) { + s->PIOarray = (struct ivtv_SG_element *)kzalloc(SGsize, GFP_KERNEL); + if (s->PIOarray == NULL) { + IVTV_ERR("Could not allocate PIOarray for %s stream\n", s->name); return -ENOMEM; } - s->SG_length = 0; + } + + /* Allocate DMA SG Arrays */ + s->SGarray = (struct ivtv_SG_element *)kzalloc(SGsize, GFP_KERNEL); + if (s->SGarray == NULL) { + IVTV_ERR("Could not allocate SGarray for %s stream\n", s->name); + if (ivtv_might_use_pio(s)) { + kfree(s->PIOarray); + s->PIOarray = NULL; + } + return -ENOMEM; + } + s->SG_length = 0; + if (ivtv_might_use_dma(s)) { s->SG_handle = pci_map_single(itv->dev, s->SGarray, SGsize, s->dma); ivtv_stream_sync_for_cpu(s); } @@ -219,7 +231,7 @@ int ivtv_stream_alloc(struct ivtv_stream *s) break; } INIT_LIST_HEAD(&buf->list); - if (s->dma != PCI_DMA_NONE) { + if (ivtv_might_use_dma(s)) { buf->dma_handle = pci_map_single(s->itv->dev, buf->buf, s->buf_size + 256, s->dma); ivtv_buf_sync_for_cpu(s, buf); @@ -242,7 +254,7 @@ void ivtv_stream_free(struct ivtv_stream *s) /* empty q_free */ while ((buf = ivtv_dequeue(s, &s->q_free))) { - if (s->dma != PCI_DMA_NONE) + if (ivtv_might_use_dma(s)) pci_unmap_single(s->itv->dev, buf->dma_handle, s->buf_size + 256, s->dma); kfree(buf->buf); @@ -256,6 +268,9 @@ void ivtv_stream_free(struct ivtv_stream *s) sizeof(struct ivtv_SG_element) * s->buffers, PCI_DMA_TODEVICE); s->SG_handle = IVTV_DMA_UNMAPPED; } + kfree(s->SGarray); + kfree(s->PIOarray); + s->PIOarray = NULL; s->SGarray = NULL; s->SG_length = 0; } |