aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Walls <awalls@radix.net>2010-02-10 13:34:46 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-02-26 13:11:07 -0500
commit587808d5f59e842f9258a15e88ad530fcf6e6763 (patch)
tree07252eaff987faf5ad1b6256d520c13ab90e4554
parent00cb9f6920aaeb34bcef146085ae57e363641a85 (diff)
V4L/DVB: ivtv: Fix ivtv_api_get_data() to avoid unneeded IO during IRQ handling
ivtv_api_get_data() was performing more PCI MMIO than needed, resulting often in it accounting for more than half the total time spent in ivtv_irq_handler(). Now it only reads at most 7 of the 16 mailbox data words over the PCI bus, and in some instances only 2 or 3 data words as needed. Signed-off-by: Andy Walls <awalls@radix.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/ivtv/ivtv-firmware.c2
-rw-r--r--drivers/media/video/ivtv/ivtv-irq.c9
-rw-r--r--drivers/media/video/ivtv/ivtv-mailbox.c9
-rw-r--r--drivers/media/video/ivtv/ivtv-mailbox.h3
4 files changed, 13 insertions, 10 deletions
diff --git a/drivers/media/video/ivtv/ivtv-firmware.c b/drivers/media/video/ivtv/ivtv-firmware.c
index c1b7ec475c27..a71e8ba306b0 100644
--- a/drivers/media/video/ivtv/ivtv-firmware.c
+++ b/drivers/media/video/ivtv/ivtv-firmware.c
@@ -258,7 +258,7 @@ void ivtv_init_mpeg_decoder(struct ivtv *itv)
258 IVTV_ERR("ivtv_init_mpeg_decoder failed to start playback\n"); 258 IVTV_ERR("ivtv_init_mpeg_decoder failed to start playback\n");
259 return; 259 return;
260 } 260 }
261 ivtv_api_get_data(&itv->dec_mbox, IVTV_MBOX_DMA, data); 261 ivtv_api_get_data(&itv->dec_mbox, IVTV_MBOX_DMA, 2, data);
262 mem_offset = itv->dec_mem + data[1]; 262 mem_offset = itv->dec_mem + data[1];
263 263
264 if ((readbytes = load_fw_direct(IVTV_DECODE_INIT_MPEG_FILENAME, 264 if ((readbytes = load_fw_direct(IVTV_DECODE_INIT_MPEG_FILENAME,
diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c
index ee0cdded69f7..12d36ca91d53 100644
--- a/drivers/media/video/ivtv/ivtv-irq.c
+++ b/drivers/media/video/ivtv/ivtv-irq.c
@@ -562,7 +562,7 @@ static void ivtv_irq_enc_dma_complete(struct ivtv *itv)
562 u32 data[CX2341X_MBOX_MAX_DATA]; 562 u32 data[CX2341X_MBOX_MAX_DATA];
563 struct ivtv_stream *s; 563 struct ivtv_stream *s;
564 564
565 ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, data); 565 ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, 2, data);
566 IVTV_DEBUG_HI_IRQ("ENC DMA COMPLETE %x %d (%d)\n", data[0], data[1], itv->cur_dma_stream); 566 IVTV_DEBUG_HI_IRQ("ENC DMA COMPLETE %x %d (%d)\n", data[0], data[1], itv->cur_dma_stream);
567 567
568 del_timer(&itv->dma_timer); 568 del_timer(&itv->dma_timer);
@@ -638,7 +638,7 @@ static void ivtv_irq_dma_err(struct ivtv *itv)
638 u32 data[CX2341X_MBOX_MAX_DATA]; 638 u32 data[CX2341X_MBOX_MAX_DATA];
639 639
640 del_timer(&itv->dma_timer); 640 del_timer(&itv->dma_timer);
641 ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, data); 641 ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, 2, data);
642 IVTV_DEBUG_WARN("DMA ERROR %08x %08x %08x %d\n", data[0], data[1], 642 IVTV_DEBUG_WARN("DMA ERROR %08x %08x %08x %d\n", data[0], data[1],
643 read_reg(IVTV_REG_DMASTATUS), itv->cur_dma_stream); 643 read_reg(IVTV_REG_DMASTATUS), itv->cur_dma_stream);
644 write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS); 644 write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS);
@@ -669,7 +669,7 @@ static void ivtv_irq_enc_start_cap(struct ivtv *itv)
669 struct ivtv_stream *s; 669 struct ivtv_stream *s;
670 670
671 /* Get DMA destination and size arguments from card */ 671 /* Get DMA destination and size arguments from card */
672 ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA, data); 672 ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA, 7, data);
673 IVTV_DEBUG_HI_IRQ("ENC START CAP %d: %08x %08x\n", data[0], data[1], data[2]); 673 IVTV_DEBUG_HI_IRQ("ENC START CAP %d: %08x %08x\n", data[0], data[1], data[2]);
674 674
675 if (data[0] > 2 || data[1] == 0 || data[2] == 0) { 675 if (data[0] > 2 || data[1] == 0 || data[2] == 0) {
@@ -713,9 +713,9 @@ static void ivtv_irq_dec_data_req(struct ivtv *itv)
713 struct ivtv_stream *s; 713 struct ivtv_stream *s;
714 714
715 /* YUV or MPG */ 715 /* YUV or MPG */
716 ivtv_api_get_data(&itv->dec_mbox, IVTV_MBOX_DMA, data);
717 716
718 if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags)) { 717 if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags)) {
718 ivtv_api_get_data(&itv->dec_mbox, IVTV_MBOX_DMA, 2, data);
719 itv->dma_data_req_size = 719 itv->dma_data_req_size =
720 1080 * ((itv->yuv_info.v4l2_src_h + 31) & ~31); 720 1080 * ((itv->yuv_info.v4l2_src_h + 31) & ~31);
721 itv->dma_data_req_offset = data[1]; 721 itv->dma_data_req_offset = data[1];
@@ -724,6 +724,7 @@ static void ivtv_irq_dec_data_req(struct ivtv *itv)
724 s = &itv->streams[IVTV_DEC_STREAM_TYPE_YUV]; 724 s = &itv->streams[IVTV_DEC_STREAM_TYPE_YUV];
725 } 725 }
726 else { 726 else {
727 ivtv_api_get_data(&itv->dec_mbox, IVTV_MBOX_DMA, 3, data);
727 itv->dma_data_req_size = min_t(u32, data[2], 0x10000); 728 itv->dma_data_req_size = min_t(u32, data[2], 0x10000);
728 itv->dma_data_req_offset = data[1]; 729 itv->dma_data_req_offset = data[1];
729 s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG]; 730 s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG];
diff --git a/drivers/media/video/ivtv/ivtv-mailbox.c b/drivers/media/video/ivtv/ivtv-mailbox.c
index 1b5c0ac09a85..84577f6f41a2 100644
--- a/drivers/media/video/ivtv/ivtv-mailbox.c
+++ b/drivers/media/video/ivtv/ivtv-mailbox.c
@@ -369,10 +369,11 @@ int ivtv_vapi(struct ivtv *itv, int cmd, int args, ...)
369} 369}
370 370
371/* This one is for stuff that can't sleep.. irq handlers, etc.. */ 371/* This one is for stuff that can't sleep.. irq handlers, etc.. */
372void ivtv_api_get_data(struct ivtv_mailbox_data *mbdata, int mb, u32 data[]) 372void ivtv_api_get_data(struct ivtv_mailbox_data *mbdata, int mb,
373 int argc, u32 data[])
373{ 374{
375 volatile u32 __iomem *p = mbdata->mbox[mb].data;
374 int i; 376 int i;
375 377 for (i = 0; i < argc; i++, p++)
376 for (i = 0; i < CX2341X_MBOX_MAX_DATA; i++) 378 data[i] = readl(p);
377 data[i] = readl(&mbdata->mbox[mb].data[i]);
378} 379}
diff --git a/drivers/media/video/ivtv/ivtv-mailbox.h b/drivers/media/video/ivtv/ivtv-mailbox.h
index 6ef12091e3f3..8247662c928e 100644
--- a/drivers/media/video/ivtv/ivtv-mailbox.h
+++ b/drivers/media/video/ivtv/ivtv-mailbox.h
@@ -24,7 +24,8 @@
24#define IVTV_MBOX_DMA_END 8 24#define IVTV_MBOX_DMA_END 8
25#define IVTV_MBOX_DMA 9 25#define IVTV_MBOX_DMA 9
26 26
27void ivtv_api_get_data(struct ivtv_mailbox_data *mbox, int mb, u32 data[]); 27void ivtv_api_get_data(struct ivtv_mailbox_data *mbdata, int mb,
28 int argc, u32 data[]);
28int ivtv_api(struct ivtv *itv, int cmd, int args, u32 data[]); 29int ivtv_api(struct ivtv *itv, int cmd, int args, u32 data[]);
29int ivtv_vapi_result(struct ivtv *itv, u32 data[CX2341X_MBOX_MAX_DATA], int cmd, int args, ...); 30int ivtv_vapi_result(struct ivtv *itv, u32 data[CX2341X_MBOX_MAX_DATA], int cmd, int args, ...);
30int ivtv_vapi(struct ivtv *itv, int cmd, int args, ...); 31int ivtv_vapi(struct ivtv *itv, int cmd, int args, ...);