summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoe Rubinstein <nrubinstein@proformatique.com>2010-12-09 18:31:33 +0100
committerNoe Rubinstein <nrubinstein@proformatique.com>2010-12-09 18:31:33 +0100
commitf8dbef0ea7d8d2949956c24b2c392837a264480f (patch)
treed361906f11a1dbc13059788c92481e5401bf0967
parent61cddfd6cae9ebbd4ef40cc8ea45ac5fc68fc162 (diff)
Use FIFO_IRQ_BLx and FIFO_FILL_BLx for reducing hardirq time and calls to DAHDI.
-rw-r--r--xhfc/xhfc.c29
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);
}