summaryrefslogtreecommitdiff
path: root/target/linux/layerscape/patches-4.4/7216-dpaa2-evb-Fix-interrupt-handling.patch
blob: d3d976af98b25d6e2da0a04a7bf01f71f1c416be (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
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)) {