diff options
author | Noe Rubinstein <nrubinstein@proformatique.com> | 2010-12-09 18:31:33 +0100 |
---|---|---|
committer | Noe Rubinstein <nrubinstein@proformatique.com> | 2010-12-09 18:31:33 +0100 |
commit | f8dbef0ea7d8d2949956c24b2c392837a264480f (patch) | |
tree | d361906f11a1dbc13059788c92481e5401bf0967 | |
parent | 61cddfd6cae9ebbd4ef40cc8ea45ac5fc68fc162 (diff) |
Use FIFO_IRQ_BLx and FIFO_FILL_BLx for reducing hardirq time and calls to DAHDI.
-rw-r--r-- | xhfc/xhfc.c | 29 |
1 files changed, 14 insertions, 15 deletions
diff --git a/xhfc/xhfc.c b/xhfc/xhfc.c index ad92afc..9eebf20 100644 --- a/xhfc/xhfc.c +++ b/xhfc/xhfc.c @@ -531,6 +531,8 @@ void xhfc_hdlc_hard_xmit(struct dahdi_chan *chan) * scheduled in a tasklet instead * *****************************************************************************/ +#define fifo_test(reg, fifonum, dir) (reg[fifonum/4] & (1 << (((fifonum % 4) * 2) + dir))) + irqreturn_t xhfc_interrupt(int irq, void *dev_id, struct pt_regs* ptregs) { @@ -540,7 +542,8 @@ irqreturn_t xhfc_interrupt(int irq, void *dev_id, struct pt_regs* ptregs) int i; u8 r_su_irq; u8 misc_irq; - u32 fifo_irq = 0; + u8 fifo_irq[SPANS_PER_CHIP]; + u8 fifo_fill[SPANS_PER_CHIP]; (void) ptregs; @@ -559,14 +562,10 @@ irqreturn_t xhfc_interrupt(int irq, void *dev_id, struct pt_regs* ptregs) if (misc_irq & M_TI_IRQMSK) xhfc->ticks++; - for(i = SPANS_PER_CHIP; i; i--) { - fifo_irq |= read_xhfc(xhfc, R_FIFO_BL0_IRQ + i); - fifo_irq |= read_xhfc(xhfc, R_FILL_BL0 + i); - fifo_irq <<= 8; + for(i = 0; i < SPANS_PER_CHIP; i++) { + fifo_irq[i] = read_xhfc(xhfc, R_FIFO_BL0_IRQ + i); + fifo_fill[i] = read_xhfc(xhfc, R_FILL_BL0 + i); } - if(DBG_HDLC && fifo_irq) - printk(KERN_INFO DRIVER_NAME ": fifo_irq=0x%08x\n", fifo_irq); - for (i = 0; i < SPANS_PER_CHIP; i++) { struct xhfc_span* s = &xhfc->spans[i]; @@ -576,12 +575,11 @@ irqreturn_t xhfc_interrupt(int irq, void *dev_id, struct pt_regs* ptregs) /* No need to loop, makes no sense to receive * more than one HDLC frame per second. */ - /* d chan number = i * 4 + 2 - * rx + tx => * 2 - * rx => + 1 - */ - //if (fifo_irq & (1 << ((i * 4 + 2) * 2 + 1))) + if ( fifo_test(fifo_irq, dchan_fifo(s), RECEIVE) || + fifo_test(fifo_fill, dchan_fifo(s), RECEIVE)) + hdlc_rx_frame(s); + if (atomic_read(&s->hdlc_pending)) hdlc_tx_frame(s); #ifdef AUDIO @@ -666,6 +664,7 @@ static void enable_interrupts(struct xhfc * xhfc) /* enable global interrupts */ SET_V_GLOB_IRQ_EN(r_irq_ctrl, 1); + SET_V_FIFO_IRQ_EN(r_irq_ctrl, 1); write_xhfc(xhfc, R_IRQ_CTRL, r_irq_ctrl); } @@ -730,8 +729,8 @@ void xhfc_init_and_configure(struct xhfc* x) /* Now we need to setup the flow controller and stuff */ xhfc_config_data_flow(x); - SET_V_THRES_RX(r_fifo_thres, 1); - SET_V_THRES_TX(r_fifo_thres, 1); + SET_V_THRES_RX(r_fifo_thres, 2); + SET_V_THRES_TX(r_fifo_thres, 2); write_xhfc(x, R_FIFO_THRES, r_fifo_thres); } |