diff options
author | Andy Walls <awalls@radix.net> | 2010-02-10 13:34:46 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-02-26 13:11:07 -0500 |
commit | 587808d5f59e842f9258a15e88ad530fcf6e6763 (patch) | |
tree | 07252eaff987faf5ad1b6256d520c13ab90e4554 | |
parent | 00cb9f6920aaeb34bcef146085ae57e363641a85 (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.c | 2 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-irq.c | 9 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-mailbox.c | 9 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-mailbox.h | 3 |
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.. */ |
372 | void ivtv_api_get_data(struct ivtv_mailbox_data *mbdata, int mb, u32 data[]) | 372 | void 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 | ||
27 | void ivtv_api_get_data(struct ivtv_mailbox_data *mbox, int mb, u32 data[]); | 27 | void ivtv_api_get_data(struct ivtv_mailbox_data *mbdata, int mb, |
28 | int argc, u32 data[]); | ||
28 | int ivtv_api(struct ivtv *itv, int cmd, int args, u32 data[]); | 29 | int ivtv_api(struct ivtv *itv, int cmd, int args, u32 data[]); |
29 | int ivtv_vapi_result(struct ivtv *itv, u32 data[CX2341X_MBOX_MAX_DATA], int cmd, int args, ...); | 30 | int ivtv_vapi_result(struct ivtv *itv, u32 data[CX2341X_MBOX_MAX_DATA], int cmd, int args, ...); |
30 | int ivtv_vapi(struct ivtv *itv, int cmd, int args, ...); | 31 | int ivtv_vapi(struct ivtv *itv, int cmd, int args, ...); |