layerscape: add ls1088ardb device support
[openwrt/staging/yousong.git] / target / linux / layerscape / patches-4.4 / 7216-dpaa2-evb-Fix-interrupt-handling.patch
diff --git a/target/linux/layerscape/patches-4.4/7216-dpaa2-evb-Fix-interrupt-handling.patch b/target/linux/layerscape/patches-4.4/7216-dpaa2-evb-Fix-interrupt-handling.patch
new file mode 100644 (file)
index 0000000..d3d976a
--- /dev/null
@@ -0,0 +1,69 @@
+From 4efb592d8a931669df5df04bedcae8cbc85c3700 Mon Sep 17 00:00:00 2001
+From: Razvan Stefanescu <razvan.stefanescu@freescale.com>
+Date: Wed, 17 Feb 2016 16:31:01 +0200
+Subject: [PATCH 216/226] dpaa2-evb: Fix interrupt handling
+
+Mask only the events handled by the driver - DPDMUX_IRQ_EVENT_LINK_CHANGED.
+
+Use clear-on-read mechanism for the interrupt status and avoid calling
+dpdmux_clear_irq_status(). Status contains the events handled (only link
+state change for the moment) and masks the first 16-bits, as they are used
+to store the interface ID that generated the event.
+
+Signed-off-by: Razvan Stefanescu <razvan.stefanescu@freescale.com>
+---
+ drivers/staging/fsl-dpaa2/evb/evb.c |   20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+--- a/drivers/staging/fsl-dpaa2/evb/evb.c
++++ b/drivers/staging/fsl-dpaa2/evb/evb.c
+@@ -151,7 +151,9 @@ static irqreturn_t _evb_irq0_handler_thr
+       struct fsl_mc_io *io = priv->mc_io;
+       uint16_t token = priv->mux_handle;
+       int irq_index = DPDMUX_IRQ_INDEX_IF;
+-      uint32_t status = 0, clear = 0;
++
++      /* Mask the events and the if_id reserved bits to be cleared on read */
++      uint32_t status = DPDMUX_IRQ_EVENT_LINK_CHANGED | 0xFFFF0000;
+       int err;
+       /* Sanity check */
+@@ -163,23 +165,21 @@ static irqreturn_t _evb_irq0_handler_thr
+       err = dpdmux_get_irq_status(io, 0, token, irq_index, &status);
+       if (unlikely(err)) {
+               netdev_err(netdev, "Can't get irq status (err %d)", err);
+-              clear = 0xffffffff;
++              err = dpdmux_clear_irq_status(io, 0, token, irq_index,
++                                            0xFFFFFFFF);
++              if (unlikely(err))
++                      netdev_err(netdev, "Can't clear irq status (err %d)",
++                                 err);
+               goto out;
+       }
+-      /* FIXME clear irq status */
+-
+       if (status & DPDMUX_IRQ_EVENT_LINK_CHANGED) {
+-              clear |= DPDMUX_IRQ_EVENT_LINK_CHANGED;
+-
+               err = evb_links_state_update(priv);
+               if (unlikely(err))
+                       goto out;
+       }
++
+ out:
+-      err = dpdmux_clear_irq_status(io, 0, token, irq_index, clear);
+-      if (unlikely(err))
+-              netdev_err(netdev, "Can't clear irq status (err %d)", err);
+       return IRQ_HANDLED;
+ }
+@@ -191,7 +191,7 @@ static int evb_setup_irqs(struct fsl_mc_
+       int err = 0;
+       struct fsl_mc_device_irq *irq;
+       const int irq_index = DPDMUX_IRQ_INDEX_IF;
+-      uint32_t mask = ~0x0u;  /* FIXME: unmask handled irqs */
++      uint32_t mask = DPDMUX_IRQ_EVENT_LINK_CHANGED;
+       err = fsl_mc_allocate_irqs(evb_dev);
+       if (unlikely(err)) {