]> rtime.felk.cvut.cz Git - zynq/linux.git/commitdiff
xilinx_emacps: Dont poll interrupts petalinux-v12.12-final
authorPeter Crosthwaite <peter.crosthwaite@xilinx.com>
Tue, 11 Dec 2012 06:22:24 +0000 (16:22 +1000)
committerMichal Simek <michal.simek@xilinx.com>
Tue, 11 Dec 2012 07:09:54 +0000 (08:09 +0100)
Don't loop the interrupt service logic in the ISR. Currently it polls for
subsequent interrupts after servicing the first. This is not an error, but is
non-ideal for two reasons:

Firstly, there was a condition where the higher levels of interrupt control
could requeue the ISR while it was still acting. The first invocation would
then service the new interrupt and the second ISR invocation would be a NOP.

Secondly, there is no bound on the length of time the driver spends in ISR
context. ISRs ideally have a deterministic duration.

Fixed by just unlooping. Each ISR is now a oneshot. Interrupts that re-trigger
during servicing are handled by a subsequent incovation of the ISR.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Tested-by: Wendy Liang <wendy.liang@xilinx.com>
drivers/net/ethernet/xilinx/xilinx_emacps.c

index 3ddd39d59736b90da369609c3618129e7174c619..c6ceb09c0093bbe38949489215a314068a18a723 100644 (file)
@@ -1753,18 +1753,14 @@ static irqreturn_t xemacps_interrupt(int irq, void *dev_id)
        }
        xemacps_write(lp->baseaddr, XEMACPS_ISR_OFFSET, regisr);
 
-       while (regisr) {
-               if (regisr & (XEMACPS_IXR_TXCOMPL_MASK |
-                               XEMACPS_IXR_TX_ERR_MASK)) {
-                       xemacps_tx_poll(ndev);
-               } else {
-                       xemacps_write(lp->baseaddr, XEMACPS_IDR_OFFSET,
-                                       (XEMACPS_IXR_FRAMERX_MASK |
-                                       XEMACPS_IXR_RX_ERR_MASK));
-                       napi_schedule(&lp->napi);
-               }
-               regisr = xemacps_read(lp->baseaddr, XEMACPS_ISR_OFFSET);
-               xemacps_write(lp->baseaddr, XEMACPS_ISR_OFFSET, regisr);
+       if (regisr & (XEMACPS_IXR_TXCOMPL_MASK |
+                       XEMACPS_IXR_TX_ERR_MASK)) {
+               xemacps_tx_poll(ndev);
+       } else {
+               xemacps_write(lp->baseaddr, XEMACPS_IDR_OFFSET,
+                               (XEMACPS_IXR_FRAMERX_MASK |
+                               XEMACPS_IXR_RX_ERR_MASK));
+               napi_schedule(&lp->napi);
        }
        spin_unlock(&lp->lock);