aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/IR/nuvoton-cir.c37
1 files changed, 29 insertions, 8 deletions
diff --git a/drivers/media/IR/nuvoton-cir.c b/drivers/media/IR/nuvoton-cir.c
index 1ce93599ff56..fdb280ed01ce 100644
--- a/drivers/media/IR/nuvoton-cir.c
+++ b/drivers/media/IR/nuvoton-cir.c
@@ -339,6 +339,15 @@ static void nvt_clear_tx_fifo(struct nvt_dev *nvt)
339 nvt_cir_reg_write(nvt, val | CIR_FIFOCON_TXFIFOCLR, CIR_FIFOCON); 339 nvt_cir_reg_write(nvt, val | CIR_FIFOCON_TXFIFOCLR, CIR_FIFOCON);
340} 340}
341 341
342/* enable RX Trigger Level Reach and Packet End interrupts */
343static void nvt_set_cir_iren(struct nvt_dev *nvt)
344{
345 u8 iren;
346
347 iren = CIR_IREN_RTR | CIR_IREN_PE;
348 nvt_cir_reg_write(nvt, iren, CIR_IREN);
349}
350
342static void nvt_cir_regs_init(struct nvt_dev *nvt) 351static void nvt_cir_regs_init(struct nvt_dev *nvt)
343{ 352{
344 /* set sample limit count (PE interrupt raised when reached) */ 353 /* set sample limit count (PE interrupt raised when reached) */
@@ -363,8 +372,8 @@ static void nvt_cir_regs_init(struct nvt_dev *nvt)
363 /* clear any and all stray interrupts */ 372 /* clear any and all stray interrupts */
364 nvt_cir_reg_write(nvt, 0xff, CIR_IRSTS); 373 nvt_cir_reg_write(nvt, 0xff, CIR_IRSTS);
365 374
366 /* and finally, enable RX Trigger Level Read and Packet End interrupts */ 375 /* and finally, enable interrupts */
367 nvt_cir_reg_write(nvt, CIR_IREN_RTR | CIR_IREN_PE, CIR_IREN); 376 nvt_set_cir_iren(nvt);
368} 377}
369 378
370static void nvt_cir_wake_regs_init(struct nvt_dev *nvt) 379static void nvt_cir_wake_regs_init(struct nvt_dev *nvt)
@@ -639,12 +648,22 @@ static void nvt_process_rx_ir_data(struct nvt_dev *nvt)
639 nvt_dbg_verbose("%s done", __func__); 648 nvt_dbg_verbose("%s done", __func__);
640} 649}
641 650
651static void nvt_handle_rx_fifo_overrun(struct nvt_dev *nvt)
652{
653 nvt_pr(KERN_WARNING, "RX FIFO overrun detected, flushing data!");
654
655 nvt->pkts = 0;
656 nvt_clear_cir_fifo(nvt);
657 ir_raw_event_reset(nvt->rdev);
658}
659
642/* copy data from hardware rx fifo into driver buffer */ 660/* copy data from hardware rx fifo into driver buffer */
643static void nvt_get_rx_ir_data(struct nvt_dev *nvt) 661static void nvt_get_rx_ir_data(struct nvt_dev *nvt)
644{ 662{
645 unsigned long flags; 663 unsigned long flags;
646 u8 fifocount, val; 664 u8 fifocount, val;
647 unsigned int b_idx; 665 unsigned int b_idx;
666 bool overrun = false;
648 int i; 667 int i;
649 668
650 /* Get count of how many bytes to read from RX FIFO */ 669 /* Get count of how many bytes to read from RX FIFO */
@@ -652,11 +671,10 @@ static void nvt_get_rx_ir_data(struct nvt_dev *nvt)
652 /* if we get 0xff, probably means the logical dev is disabled */ 671 /* if we get 0xff, probably means the logical dev is disabled */
653 if (fifocount == 0xff) 672 if (fifocount == 0xff)
654 return; 673 return;
655 /* this would suggest a fifo overrun, not good... */ 674 /* watch out for a fifo overrun condition */
656 else if (fifocount > RX_BUF_LEN) { 675 else if (fifocount > RX_BUF_LEN) {
657 nvt_pr(KERN_WARNING, "fifocount %d over fifo len (%d)!", 676 overrun = true;
658 fifocount, RX_BUF_LEN); 677 fifocount = RX_BUF_LEN;
659 return;
660 } 678 }
661 679
662 nvt_dbg("attempting to fetch %u bytes from hw rx fifo", fifocount); 680 nvt_dbg("attempting to fetch %u bytes from hw rx fifo", fifocount);
@@ -682,6 +700,9 @@ static void nvt_get_rx_ir_data(struct nvt_dev *nvt)
682 700
683 nvt_process_rx_ir_data(nvt); 701 nvt_process_rx_ir_data(nvt);
684 702
703 if (overrun)
704 nvt_handle_rx_fifo_overrun(nvt);
705
685 spin_unlock_irqrestore(&nvt->nvt_lock, flags); 706 spin_unlock_irqrestore(&nvt->nvt_lock, flags);
686} 707}
687 708
@@ -886,7 +907,7 @@ static void nvt_enable_cir(struct nvt_dev *nvt)
886 nvt_cir_reg_write(nvt, 0xff, CIR_IRSTS); 907 nvt_cir_reg_write(nvt, 0xff, CIR_IRSTS);
887 908
888 /* enable interrupts */ 909 /* enable interrupts */
889 nvt_cir_reg_write(nvt, CIR_IREN_RTR | CIR_IREN_PE, CIR_IREN); 910 nvt_set_cir_iren(nvt);
890} 911}
891 912
892static void nvt_disable_cir(struct nvt_dev *nvt) 913static void nvt_disable_cir(struct nvt_dev *nvt)
@@ -1155,7 +1176,7 @@ static int nvt_resume(struct pnp_dev *pdev)
1155 nvt_dbg("%s called", __func__); 1176 nvt_dbg("%s called", __func__);
1156 1177
1157 /* open interrupt */ 1178 /* open interrupt */
1158 nvt_cir_reg_write(nvt, CIR_IREN_RTR | CIR_IREN_PE, CIR_IREN); 1179 nvt_set_cir_iren(nvt);
1159 1180
1160 /* Enable CIR logical device */ 1181 /* Enable CIR logical device */
1161 nvt_efm_enable(nvt); 1182 nvt_efm_enable(nvt);