summaryrefslogtreecommitdiff
path: root/recipes-kernel/linux/linux-toradex-mainline-4.14/0034-apalis-tk1-mfd-k20-update-supported-fw-version-to-1..patch
blob: af4d2c579aad5d51b0a81a04862a4d54b09d5de8 (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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
From aee208a3f787e9944faccfedf3feef91fb6b77ea Mon Sep 17 00:00:00 2001
From: Dominik Sliwa <dominik.sliwa@toradex.com>
Date: Wed, 30 Jan 2019 12:47:03 +0100
Subject: [PATCH] apalis-tk1: mfd: k20: update supported fw version to 1.4

Signed-off-by: Dominik Sliwa <dominik.sliwa@toradex.com>

apalis-tk1: can: mfd: k20: use level interrupts and prioritize tx

Prioritize CAN TX trafic, and move from edge to level triggered
interrupts.

Signed-off-by: Dominik Sliwa <dominik.sliwa@toradex.com>
---
 arch/arm/boot/dts/tegra124-apalis-v1.2.dtsi |  4 +--
 drivers/mfd/apalis-tk1-k20.c                |  3 +-
 drivers/net/can/apalis-tk1-k20-can.c        | 35 +++++++++++----------
 include/linux/mfd/apalis-tk1-k20-api.h      |  2 +-
 4 files changed, 23 insertions(+), 21 deletions(-)

diff --git a/arch/arm/boot/dts/tegra124-apalis-v1.2.dtsi b/arch/arm/boot/dts/tegra124-apalis-v1.2.dtsi
index 1336e8caf95d..93fce73e385a 100644
--- a/arch/arm/boot/dts/tegra124-apalis-v1.2.dtsi
+++ b/arch/arm/boot/dts/tegra124-apalis-v1.2.dtsi
@@ -1761,8 +1761,8 @@
 			spi-max-frequency = <6120000>;
 			interrupt-parent =<&gpio>;
 			interrupts = <TEGRA_GPIO(K, 2) (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)>,
-							<TEGRA_GPIO(I, 5) (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)>, /* INT3 CAN0 */
-							<TEGRA_GPIO(J, 0) (IRQ_TYPE_EDGE_FALLING  | IRQ_TYPE_EDGE_RISING)>; /* INT4 CAN1 */
+							<TEGRA_GPIO(I, 5) (IRQ_TYPE_LEVEL_HIGH)>, /* INT3 CAN0 */
+							<TEGRA_GPIO(J, 0) (IRQ_TYPE_LEVEL_HIGH)>; /* INT4 CAN1 */
 			rst-gpio = <&gpio TEGRA_GPIO(BB, 6) GPIO_ACTIVE_HIGH>;
 
 			/* GPIO based CS used to enter K20 EzPort mode */
diff --git a/drivers/mfd/apalis-tk1-k20.c b/drivers/mfd/apalis-tk1-k20.c
index a6d1c1cdc0b6..dfdd3683d527 100644
--- a/drivers/mfd/apalis-tk1-k20.c
+++ b/drivers/mfd/apalis-tk1-k20.c
@@ -351,8 +351,7 @@ int apalis_tk1_k20_irq_request(struct apalis_tk1_k20_regmap *apalis_tk1_k20,
 	} else {
 		virq = (irq == APALIS_TK1_K20_CAN0_IRQ) ?
 			apalis_tk1_k20->can0_irq:apalis_tk1_k20->can1_irq;
-		irq_flags = IRQF_ONESHOT | IRQF_TRIGGER_FALLING |
-				IRQF_TRIGGER_RISING;
+		irq_flags = IRQF_ONESHOT | IRQF_TRIGGER_HIGH;
 	}
 	return devm_request_threaded_irq(apalis_tk1_k20->dev, virq,
 			 NULL, handler, irq_flags, name, dev);
diff --git a/drivers/net/can/apalis-tk1-k20-can.c b/drivers/net/can/apalis-tk1-k20-can.c
index 0c238b8062ca..d78940e3d262 100644
--- a/drivers/net/can/apalis-tk1-k20-can.c
+++ b/drivers/net/can/apalis-tk1-k20-can.c
@@ -125,8 +125,6 @@ static void apalis_tk1_k20_can_hw_tx_frame(struct net_device *net, u8 *buf,
 				      + APALIS_TK1_K20_CAN_DEV_OFFSET(
 				      priv->pdata->id), buf, len);
 	apalis_tk1_k20_unlock(priv->apalis_tk1_k20);
-
-	priv->tx_frame = 1;
 }
 
 static void apalis_tk1_k20_can_hw_tx(struct net_device *net,
@@ -142,7 +140,7 @@ static void apalis_tk1_k20_can_hw_tx(struct net_device *net,
 			+ CAN_HEADER_MAX_LEN, tx_buf_idx);
 }
 
-static void apalis_tk1_k20_can_hw_rx(struct net_device *net, int buf_idx)
+static int apalis_tk1_k20_can_hw_rx(struct net_device *net, int buf_idx)
 {
 	int i = 0;
 	struct apalis_tk1_k20_priv *priv = netdev_priv(net);
@@ -169,7 +167,7 @@ static void apalis_tk1_k20_can_hw_rx(struct net_device *net, int buf_idx)
 		if (!skb) {
 			dev_err(&net->dev, "cannot allocate RX skb\n");
 			priv->net->stats.rx_dropped++;
-			return;
+			return -ENOMEM;
 		}
 		memcpy(&frame->can_id, &buf[i * CAN_TRANSFER_BUF_LEN]
 				 + MB_EID_OFF, MB_EID_LEN);
@@ -187,6 +185,7 @@ static void apalis_tk1_k20_can_hw_rx(struct net_device *net, int buf_idx)
 		netif_rx_ni(skb);
 	}
 
+	return frame_available;
 
 }
 
@@ -436,6 +435,7 @@ static void apalis_tk1_k20_can_tx_work_handler(struct work_struct *ws)
 			priv->tx_len = 1 + frame->can_dlc;
 			can_put_echo_skb(priv->tx_skb, net, 0);
 			priv->tx_skb = NULL;
+			priv->tx_frame = 1;
 		}
 	}
 	mutex_unlock(&priv->apalis_tk1_k20_can_lock);
@@ -546,7 +546,7 @@ static irqreturn_t apalis_tk1_k20_can_ist(int irq, void *dev_id)
 	mutex_lock(&priv->apalis_tk1_k20_can_lock);
 	while (!priv->force_quit) {
 		enum can_state new_state = CAN_STATE_ERROR_ACTIVE;
-		int ret;
+		int ret, rx_cnt = 0;
 		u32 intf, eflag;
 		u8 clear_intf = 0;
 		int can_id = 0, data1 = 0;
@@ -566,31 +566,31 @@ static irqreturn_t apalis_tk1_k20_can_ist(int irq, void *dev_id)
 
 		intf &= CANCTRL_INTMASK;
 
-		if (!(intf & CANINTF_TX) &&
+		if (intf == 0)
+			break;
+
+		/* TX complete */
+		if ((intf & CANINTF_TX) &&
 				(priv->tx_frame == 1)) {
 			priv->tx_frame = 0;
 			net->stats.tx_packets++;
-			net->stats.tx_bytes += priv->tx_len - 1;
-			can_led_event(net, CAN_LED_EVENT_TX);
 			if (priv->tx_len) {
+				net->stats.tx_bytes += priv->tx_len - 1;
+				can_led_event(net, CAN_LED_EVENT_TX);
 				can_get_echo_skb(net, 0);
 				priv->tx_len = 0;
 			}
 			netif_wake_queue(net);
-			if (!(intf & (CANINTF_RX | CANINTF_ERR)))
-				break;
+			clear_intf |= CANINTF_TX;
 		}
-
-		if (intf == 0)
-			break;
-
 		/* receive */
 		if (intf & CANINTF_RX)
-			apalis_tk1_k20_can_hw_rx(net, 0);
+			rx_cnt = apalis_tk1_k20_can_hw_rx(net, 0);
 
 		/* any error interrupt we need to clear? */
 		if (intf & CANINTF_ERR)
-			clear_intf |= intf & CANINTF_ERR;
+			clear_intf |= CANINTF_ERR;
+
 		apalis_tk1_k20_lock(priv->apalis_tk1_k20);
 		if (clear_intf)
 			ret = apalis_tk1_k20_reg_write(priv->apalis_tk1_k20,
@@ -677,6 +677,9 @@ static irqreturn_t apalis_tk1_k20_can_ist(int irq, void *dev_id)
 			break;
 		}
 
+		if (priv->tx_skb != NULL) {
+			break;
+		}
 
 	}
 	mutex_unlock(&priv->apalis_tk1_k20_can_lock);
diff --git a/include/linux/mfd/apalis-tk1-k20-api.h b/include/linux/mfd/apalis-tk1-k20-api.h
index 75c7821ec43f..333d20f7852b 100644
--- a/include/linux/mfd/apalis-tk1-k20-api.h
+++ b/include/linux/mfd/apalis-tk1-k20-api.h
@@ -104,7 +104,7 @@
 #define APALIS_TK1_K20_TSC_IRQ			4
 #define APALIS_TK1_K20_GPIO_IRQ			5
 
-#define APALIS_TK1_K20_FW_VER			0x13
+#define APALIS_TK1_K20_FW_VER			0x14
 #define APALIS_TK1_K20_TESTER_FW_VER		0xFE
 
 #define FW_MINOR (APALIS_TK1_K20_FW_VER & 0x0F)
-- 
2.20.1