Commit 94ce880ba756df6171da28538fe9e4f8f39c323d
1 parent
f54dc1486d
Exists in
smarc_8mm_imx_4.14.98_2.0.0_ga
and in
4 other branches
MLK-21424 can: flexcan: fix normal CAN can't receive remote frame after setting fd mode
The variable "is_canfd" will stay true after the following sequence: root@imx8qxpmek:~# ip link set can0 type can bitrate 1000000 dbitrate 4000000 fd on root@imx8qxpmek:~# ip link set can0 up root@imx8qxpmek:~# ip link set can0 down root@imx8qxpmek:~# ip link set can0 type can bitrate 1000000 It will use alloc_canfd_skb() to allocate skb for normal CAN when "is_canfd" is true, which will affect the receive of remote frame. Signed-off-by: Joakim Zhang <qiangqing.zhang@nxp.com>
Showing 1 changed file with 2 additions and 0 deletions Inline Diff
drivers/net/can/flexcan.c
1 | /* | 1 | /* |
2 | * flexcan.c - FLEXCAN CAN controller driver | 2 | * flexcan.c - FLEXCAN CAN controller driver |
3 | * | 3 | * |
4 | * Copyright (c) 2005-2006 Varma Electronics Oy | 4 | * Copyright (c) 2005-2006 Varma Electronics Oy |
5 | * Copyright (c) 2009 Sascha Hauer, Pengutronix | 5 | * Copyright (c) 2009 Sascha Hauer, Pengutronix |
6 | * Copyright (c) 2010-2017 Pengutronix, Marc Kleine-Budde <kernel@pengutronix.de> | 6 | * Copyright (c) 2010-2017 Pengutronix, Marc Kleine-Budde <kernel@pengutronix.de> |
7 | * Copyright (c) 2014 David Jander, Protonic Holland | 7 | * Copyright (c) 2014 David Jander, Protonic Holland |
8 | * | 8 | * |
9 | * Based on code originally by Andrey Volkov <avolkov@varma-el.com> | 9 | * Based on code originally by Andrey Volkov <avolkov@varma-el.com> |
10 | * | 10 | * |
11 | * LICENCE: | 11 | * LICENCE: |
12 | * This program is free software; you can redistribute it and/or | 12 | * This program is free software; you can redistribute it and/or |
13 | * modify it under the terms of the GNU General Public License as | 13 | * modify it under the terms of the GNU General Public License as |
14 | * published by the Free Software Foundation version 2. | 14 | * published by the Free Software Foundation version 2. |
15 | * | 15 | * |
16 | * This program is distributed in the hope that it will be useful, | 16 | * This program is distributed in the hope that it will be useful, |
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
19 | * GNU General Public License for more details. | 19 | * GNU General Public License for more details. |
20 | * | 20 | * |
21 | */ | 21 | */ |
22 | 22 | ||
23 | #include <linux/netdevice.h> | 23 | #include <linux/netdevice.h> |
24 | #include <linux/can.h> | 24 | #include <linux/can.h> |
25 | #include <linux/can/dev.h> | 25 | #include <linux/can/dev.h> |
26 | #include <linux/can/error.h> | 26 | #include <linux/can/error.h> |
27 | #include <linux/can/led.h> | 27 | #include <linux/can/led.h> |
28 | #include <linux/can/rx-offload.h> | 28 | #include <linux/can/rx-offload.h> |
29 | #include <linux/can/platform/flexcan.h> | 29 | #include <linux/can/platform/flexcan.h> |
30 | #include <linux/clk.h> | 30 | #include <linux/clk.h> |
31 | #include <linux/delay.h> | 31 | #include <linux/delay.h> |
32 | #include <linux/interrupt.h> | 32 | #include <linux/interrupt.h> |
33 | #include <linux/io.h> | 33 | #include <linux/io.h> |
34 | #include <linux/kernel.h> | 34 | #include <linux/kernel.h> |
35 | #include <linux/list.h> | 35 | #include <linux/list.h> |
36 | #include <linux/mfd/syscon.h> | 36 | #include <linux/mfd/syscon.h> |
37 | #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h> | 37 | #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h> |
38 | #include <linux/module.h> | 38 | #include <linux/module.h> |
39 | #include <linux/of.h> | 39 | #include <linux/of.h> |
40 | #include <linux/of_device.h> | 40 | #include <linux/of_device.h> |
41 | #include <linux/platform_device.h> | 41 | #include <linux/platform_device.h> |
42 | #include <linux/pm_runtime.h> | 42 | #include <linux/pm_runtime.h> |
43 | #include <linux/regmap.h> | 43 | #include <linux/regmap.h> |
44 | #include <linux/regulator/consumer.h> | 44 | #include <linux/regulator/consumer.h> |
45 | 45 | ||
46 | #ifdef CONFIG_ARCH_MXC_ARM64 | 46 | #ifdef CONFIG_ARCH_MXC_ARM64 |
47 | #include <soc/imx8/sc/sci.h> | 47 | #include <soc/imx8/sc/sci.h> |
48 | #endif | 48 | #endif |
49 | 49 | ||
50 | #define DRV_NAME "flexcan" | 50 | #define DRV_NAME "flexcan" |
51 | 51 | ||
52 | /* 8 for RX fifo and 2 error handling */ | 52 | /* 8 for RX fifo and 2 error handling */ |
53 | #define FLEXCAN_NAPI_WEIGHT (8 + 2) | 53 | #define FLEXCAN_NAPI_WEIGHT (8 + 2) |
54 | 54 | ||
55 | /* FLEXCAN module configuration register (CANMCR) bits */ | 55 | /* FLEXCAN module configuration register (CANMCR) bits */ |
56 | #define FLEXCAN_MCR_MDIS BIT(31) | 56 | #define FLEXCAN_MCR_MDIS BIT(31) |
57 | #define FLEXCAN_MCR_FRZ BIT(30) | 57 | #define FLEXCAN_MCR_FRZ BIT(30) |
58 | #define FLEXCAN_MCR_FEN BIT(29) | 58 | #define FLEXCAN_MCR_FEN BIT(29) |
59 | #define FLEXCAN_MCR_HALT BIT(28) | 59 | #define FLEXCAN_MCR_HALT BIT(28) |
60 | #define FLEXCAN_MCR_NOT_RDY BIT(27) | 60 | #define FLEXCAN_MCR_NOT_RDY BIT(27) |
61 | #define FLEXCAN_MCR_WAK_MSK BIT(26) | 61 | #define FLEXCAN_MCR_WAK_MSK BIT(26) |
62 | #define FLEXCAN_MCR_SOFTRST BIT(25) | 62 | #define FLEXCAN_MCR_SOFTRST BIT(25) |
63 | #define FLEXCAN_MCR_FRZ_ACK BIT(24) | 63 | #define FLEXCAN_MCR_FRZ_ACK BIT(24) |
64 | #define FLEXCAN_MCR_SUPV BIT(23) | 64 | #define FLEXCAN_MCR_SUPV BIT(23) |
65 | #define FLEXCAN_MCR_SLF_WAK BIT(22) | 65 | #define FLEXCAN_MCR_SLF_WAK BIT(22) |
66 | #define FLEXCAN_MCR_WRN_EN BIT(21) | 66 | #define FLEXCAN_MCR_WRN_EN BIT(21) |
67 | #define FLEXCAN_MCR_LPM_ACK BIT(20) | 67 | #define FLEXCAN_MCR_LPM_ACK BIT(20) |
68 | #define FLEXCAN_MCR_WAK_SRC BIT(19) | 68 | #define FLEXCAN_MCR_WAK_SRC BIT(19) |
69 | #define FLEXCAN_MCR_DOZE BIT(18) | 69 | #define FLEXCAN_MCR_DOZE BIT(18) |
70 | #define FLEXCAN_MCR_SRX_DIS BIT(17) | 70 | #define FLEXCAN_MCR_SRX_DIS BIT(17) |
71 | #define FLEXCAN_MCR_IRMQ BIT(16) | 71 | #define FLEXCAN_MCR_IRMQ BIT(16) |
72 | #define FLEXCAN_MCR_LPRIO_EN BIT(13) | 72 | #define FLEXCAN_MCR_LPRIO_EN BIT(13) |
73 | #define FLEXCAN_MCR_AEN BIT(12) | 73 | #define FLEXCAN_MCR_AEN BIT(12) |
74 | #define FLEXCAN_MCR_FDEN BIT(11) | 74 | #define FLEXCAN_MCR_FDEN BIT(11) |
75 | /* MCR_MAXMB: maximum used MBs is MAXMB + 1 */ | 75 | /* MCR_MAXMB: maximum used MBs is MAXMB + 1 */ |
76 | #define FLEXCAN_MCR_MAXMB(x) ((x) & 0x7f) | 76 | #define FLEXCAN_MCR_MAXMB(x) ((x) & 0x7f) |
77 | #define FLEXCAN_MCR_IDAM_A (0x0 << 8) | 77 | #define FLEXCAN_MCR_IDAM_A (0x0 << 8) |
78 | #define FLEXCAN_MCR_IDAM_B (0x1 << 8) | 78 | #define FLEXCAN_MCR_IDAM_B (0x1 << 8) |
79 | #define FLEXCAN_MCR_IDAM_C (0x2 << 8) | 79 | #define FLEXCAN_MCR_IDAM_C (0x2 << 8) |
80 | #define FLEXCAN_MCR_IDAM_D (0x3 << 8) | 80 | #define FLEXCAN_MCR_IDAM_D (0x3 << 8) |
81 | 81 | ||
82 | /* FLEXCAN control register (CANCTRL) bits */ | 82 | /* FLEXCAN control register (CANCTRL) bits */ |
83 | #define FLEXCAN_CTRL_PRESDIV(x) (((x) & 0xff) << 24) | 83 | #define FLEXCAN_CTRL_PRESDIV(x) (((x) & 0xff) << 24) |
84 | #define FLEXCAN_CTRL_RJW(x) (((x) & 0x03) << 22) | 84 | #define FLEXCAN_CTRL_RJW(x) (((x) & 0x03) << 22) |
85 | #define FLEXCAN_CTRL_PSEG1(x) (((x) & 0x07) << 19) | 85 | #define FLEXCAN_CTRL_PSEG1(x) (((x) & 0x07) << 19) |
86 | #define FLEXCAN_CTRL_PSEG2(x) (((x) & 0x07) << 16) | 86 | #define FLEXCAN_CTRL_PSEG2(x) (((x) & 0x07) << 16) |
87 | #define FLEXCAN_CTRL_BOFF_MSK BIT(15) | 87 | #define FLEXCAN_CTRL_BOFF_MSK BIT(15) |
88 | #define FLEXCAN_CTRL_ERR_MSK BIT(14) | 88 | #define FLEXCAN_CTRL_ERR_MSK BIT(14) |
89 | #define FLEXCAN_CTRL_CLK_SRC BIT(13) | 89 | #define FLEXCAN_CTRL_CLK_SRC BIT(13) |
90 | #define FLEXCAN_CTRL_LPB BIT(12) | 90 | #define FLEXCAN_CTRL_LPB BIT(12) |
91 | #define FLEXCAN_CTRL_TWRN_MSK BIT(11) | 91 | #define FLEXCAN_CTRL_TWRN_MSK BIT(11) |
92 | #define FLEXCAN_CTRL_RWRN_MSK BIT(10) | 92 | #define FLEXCAN_CTRL_RWRN_MSK BIT(10) |
93 | #define FLEXCAN_CTRL_SMP BIT(7) | 93 | #define FLEXCAN_CTRL_SMP BIT(7) |
94 | #define FLEXCAN_CTRL_BOFF_REC BIT(6) | 94 | #define FLEXCAN_CTRL_BOFF_REC BIT(6) |
95 | #define FLEXCAN_CTRL_TSYN BIT(5) | 95 | #define FLEXCAN_CTRL_TSYN BIT(5) |
96 | #define FLEXCAN_CTRL_LBUF BIT(4) | 96 | #define FLEXCAN_CTRL_LBUF BIT(4) |
97 | #define FLEXCAN_CTRL_LOM BIT(3) | 97 | #define FLEXCAN_CTRL_LOM BIT(3) |
98 | #define FLEXCAN_CTRL_PROPSEG(x) ((x) & 0x07) | 98 | #define FLEXCAN_CTRL_PROPSEG(x) ((x) & 0x07) |
99 | #define FLEXCAN_CTRL_ERR_BUS (FLEXCAN_CTRL_ERR_MSK) | 99 | #define FLEXCAN_CTRL_ERR_BUS (FLEXCAN_CTRL_ERR_MSK) |
100 | #define FLEXCAN_CTRL_ERR_STATE \ | 100 | #define FLEXCAN_CTRL_ERR_STATE \ |
101 | (FLEXCAN_CTRL_TWRN_MSK | FLEXCAN_CTRL_RWRN_MSK | \ | 101 | (FLEXCAN_CTRL_TWRN_MSK | FLEXCAN_CTRL_RWRN_MSK | \ |
102 | FLEXCAN_CTRL_BOFF_MSK) | 102 | FLEXCAN_CTRL_BOFF_MSK) |
103 | #define FLEXCAN_CTRL_ERR_ALL \ | 103 | #define FLEXCAN_CTRL_ERR_ALL \ |
104 | (FLEXCAN_CTRL_ERR_BUS | FLEXCAN_CTRL_ERR_STATE) | 104 | (FLEXCAN_CTRL_ERR_BUS | FLEXCAN_CTRL_ERR_STATE) |
105 | 105 | ||
106 | /* FLEXCAN control register 2 (CTRL2) bits */ | 106 | /* FLEXCAN control register 2 (CTRL2) bits */ |
107 | #define FLEXCAN_CTRL2_ECRWRE BIT(29) | 107 | #define FLEXCAN_CTRL2_ECRWRE BIT(29) |
108 | #define FLEXCAN_CTRL2_WRMFRZ BIT(28) | 108 | #define FLEXCAN_CTRL2_WRMFRZ BIT(28) |
109 | #define FLEXCAN_CTRL2_RFFN(x) (((x) & 0x0f) << 24) | 109 | #define FLEXCAN_CTRL2_RFFN(x) (((x) & 0x0f) << 24) |
110 | #define FLEXCAN_CTRL2_TASD(x) (((x) & 0x1f) << 19) | 110 | #define FLEXCAN_CTRL2_TASD(x) (((x) & 0x1f) << 19) |
111 | #define FLEXCAN_CTRL2_MRP BIT(18) | 111 | #define FLEXCAN_CTRL2_MRP BIT(18) |
112 | #define FLEXCAN_CTRL2_RRS BIT(17) | 112 | #define FLEXCAN_CTRL2_RRS BIT(17) |
113 | #define FLEXCAN_CTRL2_EACEN BIT(16) | 113 | #define FLEXCAN_CTRL2_EACEN BIT(16) |
114 | #define FLEXCAN_CTRL2_ISOCANFDEN BIT(12) | 114 | #define FLEXCAN_CTRL2_ISOCANFDEN BIT(12) |
115 | 115 | ||
116 | /* FLEXCAN memory error control register (MECR) bits */ | 116 | /* FLEXCAN memory error control register (MECR) bits */ |
117 | #define FLEXCAN_MECR_ECRWRDIS BIT(31) | 117 | #define FLEXCAN_MECR_ECRWRDIS BIT(31) |
118 | #define FLEXCAN_MECR_HANCEI_MSK BIT(19) | 118 | #define FLEXCAN_MECR_HANCEI_MSK BIT(19) |
119 | #define FLEXCAN_MECR_FANCEI_MSK BIT(18) | 119 | #define FLEXCAN_MECR_FANCEI_MSK BIT(18) |
120 | #define FLEXCAN_MECR_CEI_MSK BIT(16) | 120 | #define FLEXCAN_MECR_CEI_MSK BIT(16) |
121 | #define FLEXCAN_MECR_HAERRIE BIT(15) | 121 | #define FLEXCAN_MECR_HAERRIE BIT(15) |
122 | #define FLEXCAN_MECR_FAERRIE BIT(14) | 122 | #define FLEXCAN_MECR_FAERRIE BIT(14) |
123 | #define FLEXCAN_MECR_EXTERRIE BIT(13) | 123 | #define FLEXCAN_MECR_EXTERRIE BIT(13) |
124 | #define FLEXCAN_MECR_RERRDIS BIT(9) | 124 | #define FLEXCAN_MECR_RERRDIS BIT(9) |
125 | #define FLEXCAN_MECR_ECCDIS BIT(8) | 125 | #define FLEXCAN_MECR_ECCDIS BIT(8) |
126 | #define FLEXCAN_MECR_NCEFAFRZ BIT(7) | 126 | #define FLEXCAN_MECR_NCEFAFRZ BIT(7) |
127 | 127 | ||
128 | /* FLEXCAN error and status register (ESR) bits */ | 128 | /* FLEXCAN error and status register (ESR) bits */ |
129 | #define FLEXCAN_ESR_TWRN_INT BIT(17) | 129 | #define FLEXCAN_ESR_TWRN_INT BIT(17) |
130 | #define FLEXCAN_ESR_RWRN_INT BIT(16) | 130 | #define FLEXCAN_ESR_RWRN_INT BIT(16) |
131 | #define FLEXCAN_ESR_BIT1_ERR BIT(15) | 131 | #define FLEXCAN_ESR_BIT1_ERR BIT(15) |
132 | #define FLEXCAN_ESR_BIT0_ERR BIT(14) | 132 | #define FLEXCAN_ESR_BIT0_ERR BIT(14) |
133 | #define FLEXCAN_ESR_ACK_ERR BIT(13) | 133 | #define FLEXCAN_ESR_ACK_ERR BIT(13) |
134 | #define FLEXCAN_ESR_CRC_ERR BIT(12) | 134 | #define FLEXCAN_ESR_CRC_ERR BIT(12) |
135 | #define FLEXCAN_ESR_FRM_ERR BIT(11) | 135 | #define FLEXCAN_ESR_FRM_ERR BIT(11) |
136 | #define FLEXCAN_ESR_STF_ERR BIT(10) | 136 | #define FLEXCAN_ESR_STF_ERR BIT(10) |
137 | #define FLEXCAN_ESR_TX_WRN BIT(9) | 137 | #define FLEXCAN_ESR_TX_WRN BIT(9) |
138 | #define FLEXCAN_ESR_RX_WRN BIT(8) | 138 | #define FLEXCAN_ESR_RX_WRN BIT(8) |
139 | #define FLEXCAN_ESR_IDLE BIT(7) | 139 | #define FLEXCAN_ESR_IDLE BIT(7) |
140 | #define FLEXCAN_ESR_TXRX BIT(6) | 140 | #define FLEXCAN_ESR_TXRX BIT(6) |
141 | #define FLEXCAN_EST_FLT_CONF_SHIFT (4) | 141 | #define FLEXCAN_EST_FLT_CONF_SHIFT (4) |
142 | #define FLEXCAN_ESR_FLT_CONF_MASK (0x3 << FLEXCAN_EST_FLT_CONF_SHIFT) | 142 | #define FLEXCAN_ESR_FLT_CONF_MASK (0x3 << FLEXCAN_EST_FLT_CONF_SHIFT) |
143 | #define FLEXCAN_ESR_FLT_CONF_ACTIVE (0x0 << FLEXCAN_EST_FLT_CONF_SHIFT) | 143 | #define FLEXCAN_ESR_FLT_CONF_ACTIVE (0x0 << FLEXCAN_EST_FLT_CONF_SHIFT) |
144 | #define FLEXCAN_ESR_FLT_CONF_PASSIVE (0x1 << FLEXCAN_EST_FLT_CONF_SHIFT) | 144 | #define FLEXCAN_ESR_FLT_CONF_PASSIVE (0x1 << FLEXCAN_EST_FLT_CONF_SHIFT) |
145 | #define FLEXCAN_ESR_BOFF_INT BIT(2) | 145 | #define FLEXCAN_ESR_BOFF_INT BIT(2) |
146 | #define FLEXCAN_ESR_ERR_INT BIT(1) | 146 | #define FLEXCAN_ESR_ERR_INT BIT(1) |
147 | #define FLEXCAN_ESR_WAK_INT BIT(0) | 147 | #define FLEXCAN_ESR_WAK_INT BIT(0) |
148 | #define FLEXCAN_ESR_ERR_BUS \ | 148 | #define FLEXCAN_ESR_ERR_BUS \ |
149 | (FLEXCAN_ESR_BIT1_ERR | FLEXCAN_ESR_BIT0_ERR | \ | 149 | (FLEXCAN_ESR_BIT1_ERR | FLEXCAN_ESR_BIT0_ERR | \ |
150 | FLEXCAN_ESR_ACK_ERR | FLEXCAN_ESR_CRC_ERR | \ | 150 | FLEXCAN_ESR_ACK_ERR | FLEXCAN_ESR_CRC_ERR | \ |
151 | FLEXCAN_ESR_FRM_ERR | FLEXCAN_ESR_STF_ERR) | 151 | FLEXCAN_ESR_FRM_ERR | FLEXCAN_ESR_STF_ERR) |
152 | #define FLEXCAN_ESR_ERR_STATE \ | 152 | #define FLEXCAN_ESR_ERR_STATE \ |
153 | (FLEXCAN_ESR_TWRN_INT | FLEXCAN_ESR_RWRN_INT | FLEXCAN_ESR_BOFF_INT) | 153 | (FLEXCAN_ESR_TWRN_INT | FLEXCAN_ESR_RWRN_INT | FLEXCAN_ESR_BOFF_INT) |
154 | #define FLEXCAN_ESR_ERR_ALL \ | 154 | #define FLEXCAN_ESR_ERR_ALL \ |
155 | (FLEXCAN_ESR_ERR_BUS | FLEXCAN_ESR_ERR_STATE) | 155 | (FLEXCAN_ESR_ERR_BUS | FLEXCAN_ESR_ERR_STATE) |
156 | #define FLEXCAN_ESR_ALL_INT \ | 156 | #define FLEXCAN_ESR_ALL_INT \ |
157 | (FLEXCAN_ESR_TWRN_INT | FLEXCAN_ESR_RWRN_INT | \ | 157 | (FLEXCAN_ESR_TWRN_INT | FLEXCAN_ESR_RWRN_INT | \ |
158 | FLEXCAN_ESR_BOFF_INT | FLEXCAN_ESR_ERR_INT | \ | 158 | FLEXCAN_ESR_BOFF_INT | FLEXCAN_ESR_ERR_INT | \ |
159 | FLEXCAN_ESR_WAK_INT) | 159 | FLEXCAN_ESR_WAK_INT) |
160 | 160 | ||
161 | /* FLEXCAN Bit Timing register (CBT) bits */ | 161 | /* FLEXCAN Bit Timing register (CBT) bits */ |
162 | #define FLEXCAN_CBT_BTF BIT(31) | 162 | #define FLEXCAN_CBT_BTF BIT(31) |
163 | #define FLEXCAN_CBT_EPRESDIV(x) (((x) & 0x3ff) << 21) | 163 | #define FLEXCAN_CBT_EPRESDIV(x) (((x) & 0x3ff) << 21) |
164 | #define FLEXCAN_CBT_ERJW(x) (((x) & 0x1f) << 16) | 164 | #define FLEXCAN_CBT_ERJW(x) (((x) & 0x1f) << 16) |
165 | #define FLEXCAN_CBT_EPROPSEG(x) (((x) & 0x3f) << 10) | 165 | #define FLEXCAN_CBT_EPROPSEG(x) (((x) & 0x3f) << 10) |
166 | #define FLEXCAN_CBT_EPSEG1(x) (((x) & 0x1f) << 5) | 166 | #define FLEXCAN_CBT_EPSEG1(x) (((x) & 0x1f) << 5) |
167 | #define FLEXCAN_CBT_EPSEG2(x) ((x) & 0x1f) | 167 | #define FLEXCAN_CBT_EPSEG2(x) ((x) & 0x1f) |
168 | 168 | ||
169 | /* FLEXCAN FD Bit Timing register (FDCBT) bits */ | 169 | /* FLEXCAN FD Bit Timing register (FDCBT) bits */ |
170 | #define FLEXCAN_FDCBT_FPRESDIV(x) (((x) & 0x3ff) << 20) | 170 | #define FLEXCAN_FDCBT_FPRESDIV(x) (((x) & 0x3ff) << 20) |
171 | #define FLEXCAN_FDCBT_FRJW(x) (((x) & 0x07) << 16) | 171 | #define FLEXCAN_FDCBT_FRJW(x) (((x) & 0x07) << 16) |
172 | #define FLEXCAN_FDCBT_FPROPSEG(x) (((x) & 0x1f) << 10) | 172 | #define FLEXCAN_FDCBT_FPROPSEG(x) (((x) & 0x1f) << 10) |
173 | #define FLEXCAN_FDCBT_FPSEG1(x) (((x) & 0x07) << 5) | 173 | #define FLEXCAN_FDCBT_FPSEG1(x) (((x) & 0x07) << 5) |
174 | #define FLEXCAN_FDCBT_FPSEG2(x) ((x) & 0x07) | 174 | #define FLEXCAN_FDCBT_FPSEG2(x) ((x) & 0x07) |
175 | 175 | ||
176 | /* FLEXCAN interrupt flag register (IFLAG) bits */ | 176 | /* FLEXCAN interrupt flag register (IFLAG) bits */ |
177 | /* Errata ERR005829 step7: Reserve first valid MB */ | 177 | /* Errata ERR005829 step7: Reserve first valid MB */ |
178 | #define FLEXCAN_TX_MB_RESERVED_OFF_FIFO 8 | 178 | #define FLEXCAN_TX_MB_RESERVED_OFF_FIFO 8 |
179 | #define FLEXCAN_TX_MB_OFF_FIFO 9 | 179 | #define FLEXCAN_TX_MB_OFF_FIFO 9 |
180 | #define FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP 0 | 180 | #define FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP 0 |
181 | #define FLEXCAN_TX_MB_OFF_TIMESTAMP 1 | 181 | #define FLEXCAN_TX_MB_OFF_TIMESTAMP 1 |
182 | #define FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP_FD 0 | 182 | #define FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP_FD 0 |
183 | #define FLEXCAN_TX_MB_OFF_TIMESTAMP_FD 1 | 183 | #define FLEXCAN_TX_MB_OFF_TIMESTAMP_FD 1 |
184 | #define FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST (FLEXCAN_TX_MB_OFF_TIMESTAMP + 1) | 184 | #define FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST (FLEXCAN_TX_MB_OFF_TIMESTAMP + 1) |
185 | #define FLEXCAN_RX_MB_OFF_TIMESTAMP_LAST 63 | 185 | #define FLEXCAN_RX_MB_OFF_TIMESTAMP_LAST 63 |
186 | #define FLEXCAN_RX_MB_OFF_TIMESTAMP_FD_FIRST (FLEXCAN_TX_MB_OFF_TIMESTAMP_FD + 1) | 186 | #define FLEXCAN_RX_MB_OFF_TIMESTAMP_FD_FIRST (FLEXCAN_TX_MB_OFF_TIMESTAMP_FD + 1) |
187 | #define FLEXCAN_RX_MB_OFF_TIMESTAMP_FD_LAST 13 | 187 | #define FLEXCAN_RX_MB_OFF_TIMESTAMP_FD_LAST 13 |
188 | #define FLEXCAN_IFLAG_MB(x) BIT(x) | 188 | #define FLEXCAN_IFLAG_MB(x) BIT(x) |
189 | #define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW BIT(7) | 189 | #define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW BIT(7) |
190 | #define FLEXCAN_IFLAG_RX_FIFO_WARN BIT(6) | 190 | #define FLEXCAN_IFLAG_RX_FIFO_WARN BIT(6) |
191 | #define FLEXCAN_IFLAG_RX_FIFO_AVAILABLE BIT(5) | 191 | #define FLEXCAN_IFLAG_RX_FIFO_AVAILABLE BIT(5) |
192 | 192 | ||
193 | /* FLEXCAN message buffers */ | 193 | /* FLEXCAN message buffers */ |
194 | #define FLEXCAN_MB_CNT_EDL BIT(31) | 194 | #define FLEXCAN_MB_CNT_EDL BIT(31) |
195 | #define FLEXCAN_MB_CNT_BRS BIT(30) | 195 | #define FLEXCAN_MB_CNT_BRS BIT(30) |
196 | #define FLEXCAN_MB_CNT_ESI BIT(29) | 196 | #define FLEXCAN_MB_CNT_ESI BIT(29) |
197 | 197 | ||
198 | #define FLEXCAN_MB_CODE_MASK (0xf << 24) | 198 | #define FLEXCAN_MB_CODE_MASK (0xf << 24) |
199 | #define FLEXCAN_MB_CODE_RX_BUSY_BIT (0x1 << 24) | 199 | #define FLEXCAN_MB_CODE_RX_BUSY_BIT (0x1 << 24) |
200 | #define FLEXCAN_MB_CODE_RX_INACTIVE (0x0 << 24) | 200 | #define FLEXCAN_MB_CODE_RX_INACTIVE (0x0 << 24) |
201 | #define FLEXCAN_MB_CODE_RX_EMPTY (0x4 << 24) | 201 | #define FLEXCAN_MB_CODE_RX_EMPTY (0x4 << 24) |
202 | #define FLEXCAN_MB_CODE_RX_FULL (0x2 << 24) | 202 | #define FLEXCAN_MB_CODE_RX_FULL (0x2 << 24) |
203 | #define FLEXCAN_MB_CODE_RX_OVERRUN (0x6 << 24) | 203 | #define FLEXCAN_MB_CODE_RX_OVERRUN (0x6 << 24) |
204 | #define FLEXCAN_MB_CODE_RX_RANSWER (0xa << 24) | 204 | #define FLEXCAN_MB_CODE_RX_RANSWER (0xa << 24) |
205 | 205 | ||
206 | #define FLEXCAN_MB_CODE_TX_INACTIVE (0x8 << 24) | 206 | #define FLEXCAN_MB_CODE_TX_INACTIVE (0x8 << 24) |
207 | #define FLEXCAN_MB_CODE_TX_ABORT (0x9 << 24) | 207 | #define FLEXCAN_MB_CODE_TX_ABORT (0x9 << 24) |
208 | #define FLEXCAN_MB_CODE_TX_DATA (0xc << 24) | 208 | #define FLEXCAN_MB_CODE_TX_DATA (0xc << 24) |
209 | #define FLEXCAN_MB_CODE_TX_TANSWER (0xe << 24) | 209 | #define FLEXCAN_MB_CODE_TX_TANSWER (0xe << 24) |
210 | 210 | ||
211 | #define FLEXCAN_MB_CNT_SRR BIT(22) | 211 | #define FLEXCAN_MB_CNT_SRR BIT(22) |
212 | #define FLEXCAN_MB_CNT_IDE BIT(21) | 212 | #define FLEXCAN_MB_CNT_IDE BIT(21) |
213 | #define FLEXCAN_MB_CNT_RTR BIT(20) | 213 | #define FLEXCAN_MB_CNT_RTR BIT(20) |
214 | #define FLEXCAN_MB_CNT_LENGTH(x) (((x) & 0xf) << 16) | 214 | #define FLEXCAN_MB_CNT_LENGTH(x) (((x) & 0xf) << 16) |
215 | #define FLEXCAN_MB_CNT_TIMESTAMP(x) ((x) & 0xffff) | 215 | #define FLEXCAN_MB_CNT_TIMESTAMP(x) ((x) & 0xffff) |
216 | 216 | ||
217 | #define FLEXCAN_FDCTRL_FDRATE BIT(31) | 217 | #define FLEXCAN_FDCTRL_FDRATE BIT(31) |
218 | 218 | ||
219 | #define FLEXCAN_TIMEOUT_US (50) | 219 | #define FLEXCAN_TIMEOUT_US (50) |
220 | 220 | ||
221 | /* FLEXCAN hardware feature flags | 221 | /* FLEXCAN hardware feature flags |
222 | * | 222 | * |
223 | * Below is some version info we got: | 223 | * Below is some version info we got: |
224 | * SOC Version IP-Version Glitch- [TR]WRN_INT IRQ Err Memory err RTR re- | 224 | * SOC Version IP-Version Glitch- [TR]WRN_INT IRQ Err Memory err RTR re- |
225 | * Filter? connected? Passive detection ception in MB | 225 | * Filter? connected? Passive detection ception in MB |
226 | * MX25 FlexCAN2 03.00.00.00 no no ? no no | 226 | * MX25 FlexCAN2 03.00.00.00 no no ? no no |
227 | * MX28 FlexCAN2 03.00.04.00 yes yes no no no | 227 | * MX28 FlexCAN2 03.00.04.00 yes yes no no no |
228 | * MX35 FlexCAN2 03.00.00.00 no no ? no no | 228 | * MX35 FlexCAN2 03.00.00.00 no no ? no no |
229 | * MX53 FlexCAN2 03.00.00.00 yes no no no no | 229 | * MX53 FlexCAN2 03.00.00.00 yes no no no no |
230 | * MX6s FlexCAN3 10.00.12.00 yes yes no no yes | 230 | * MX6s FlexCAN3 10.00.12.00 yes yes no no yes |
231 | * VF610 FlexCAN3 ? no yes no yes yes? | 231 | * VF610 FlexCAN3 ? no yes no yes yes? |
232 | * | 232 | * |
233 | * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected. | 233 | * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected. |
234 | */ | 234 | */ |
235 | #define FLEXCAN_QUIRK_BROKEN_WERR_STATE BIT(1) /* [TR]WRN_INT not connected */ | 235 | #define FLEXCAN_QUIRK_BROKEN_WERR_STATE BIT(1) /* [TR]WRN_INT not connected */ |
236 | #define FLEXCAN_QUIRK_DISABLE_RXFG BIT(2) /* Disable RX FIFO Global mask */ | 236 | #define FLEXCAN_QUIRK_DISABLE_RXFG BIT(2) /* Disable RX FIFO Global mask */ |
237 | #define FLEXCAN_QUIRK_ENABLE_EACEN_RRS BIT(3) /* Enable EACEN and RRS bit in ctrl2 */ | 237 | #define FLEXCAN_QUIRK_ENABLE_EACEN_RRS BIT(3) /* Enable EACEN and RRS bit in ctrl2 */ |
238 | #define FLEXCAN_QUIRK_DISABLE_MECR BIT(4) /* Disable Memory error detection */ | 238 | #define FLEXCAN_QUIRK_DISABLE_MECR BIT(4) /* Disable Memory error detection */ |
239 | #define FLEXCAN_QUIRK_USE_OFF_TIMESTAMP BIT(5) /* Use timestamp based offloading */ | 239 | #define FLEXCAN_QUIRK_USE_OFF_TIMESTAMP BIT(5) /* Use timestamp based offloading */ |
240 | #define FLEXCAN_QUIRK_BROKEN_PERR_STATE BIT(6) /* No interrupt for error passive */ | 240 | #define FLEXCAN_QUIRK_BROKEN_PERR_STATE BIT(6) /* No interrupt for error passive */ |
241 | #define FLEXCAN_QUIRK_TIMESTAMP_SUPPORT_FD BIT(7) /* Use timestamp then support can fd mode */ | 241 | #define FLEXCAN_QUIRK_TIMESTAMP_SUPPORT_FD BIT(7) /* Use timestamp then support can fd mode */ |
242 | 242 | ||
243 | /* Message Buffer */ | 243 | /* Message Buffer */ |
244 | #define FLEXCAN_MB_CTRL 0x0 | 244 | #define FLEXCAN_MB_CTRL 0x0 |
245 | #define FLEXCAN_MB_ID 0x4 | 245 | #define FLEXCAN_MB_ID 0x4 |
246 | #define FLEXCAN_MB_DATA(n) (0x8 + ((n) << 2)) | 246 | #define FLEXCAN_MB_DATA(n) (0x8 + ((n) << 2)) |
247 | 247 | ||
248 | #define FLEXCAN_MB 0x80 | 248 | #define FLEXCAN_MB 0x80 |
249 | #define FLEXCAN_MB_NUM 64 | 249 | #define FLEXCAN_MB_NUM 64 |
250 | #define FLEXCAN_MB_FD_NUM 14 | 250 | #define FLEXCAN_MB_FD_NUM 14 |
251 | #define FLEXCAN_MB_SIZE 16 | 251 | #define FLEXCAN_MB_SIZE 16 |
252 | #define FLEXCAN_MB_FD_SIZE 72 | 252 | #define FLEXCAN_MB_FD_SIZE 72 |
253 | 253 | ||
254 | /* CAN FD Memory Partition | 254 | /* CAN FD Memory Partition |
255 | * | 255 | * |
256 | * When CAN FD is enabled, the FlexCAN RAM can be partitioned in | 256 | * When CAN FD is enabled, the FlexCAN RAM can be partitioned in |
257 | * blocks of 512 bytes. Each block can accommodate a number of | 257 | * blocks of 512 bytes. Each block can accommodate a number of |
258 | * Message Buffers which depends on the configuration provided | 258 | * Message Buffers which depends on the configuration provided |
259 | * by CAN_FDCTRL[MBDSRn] bit fields where we all set to 64 bytes | 259 | * by CAN_FDCTRL[MBDSRn] bit fields where we all set to 64 bytes |
260 | * per Message Buffer and 7 MBs per Block by default. | 260 | * per Message Buffer and 7 MBs per Block by default. |
261 | * | 261 | * |
262 | * There're two RAM blocks: RAM block 0,1 | 262 | * There're two RAM blocks: RAM block 0,1 |
263 | */ | 263 | */ |
264 | #define FLEXCAN_CANFD_MB_OFFSET(n) (((n) / 7) * 512 + ((n) % 7) * \ | 264 | #define FLEXCAN_CANFD_MB_OFFSET(n) (((n) / 7) * 512 + ((n) % 7) * \ |
265 | FLEXCAN_MB_FD_SIZE) | 265 | FLEXCAN_MB_FD_SIZE) |
266 | #define FLEXCAN_CANFD_MBDSR_MASK 0x6db0000 | 266 | #define FLEXCAN_CANFD_MBDSR_MASK 0x6db0000 |
267 | #define FLEXCAN_CANFD_MBDSR_SHIFT 16 | 267 | #define FLEXCAN_CANFD_MBDSR_SHIFT 16 |
268 | #define FLEXCAN_CANFD_MBDSR_DEFAULT 0x6db | 268 | #define FLEXCAN_CANFD_MBDSR_DEFAULT 0x6db |
269 | 269 | ||
270 | /* | 270 | /* |
271 | * NOTE: | 271 | * NOTE: |
272 | * To minimize errors when processing FD frames, use the same value | 272 | * To minimize errors when processing FD frames, use the same value |
273 | * for FPRESDIV and PRESDIV (in CAN_CBT or CAN_CTRL1). | 273 | * for FPRESDIV and PRESDIV (in CAN_CBT or CAN_CTRL1). |
274 | * For more details refer to the first NOTE in section CAN FD frames. | 274 | * For more details refer to the first NOTE in section CAN FD frames. |
275 | * | 275 | * |
276 | * CAN FD supported rates combinations | 276 | * CAN FD supported rates combinations |
277 | * | 277 | * |
278 | * Combination 1: | 278 | * Combination 1: |
279 | * Bitrate: 225000 375000 400000 425000 500000 875000 | 279 | * Bitrate: 225000 375000 400000 425000 500000 875000 |
280 | * Data rate: 1000000 | 280 | * Data rate: 1000000 |
281 | * | 281 | * |
282 | * Combination 2: | 282 | * Combination 2: |
283 | * Bitrate: 550000 600000 625000 650000 675000 750000 775000 | 283 | * Bitrate: 550000 600000 625000 650000 675000 750000 775000 |
284 | * 800000 850000 925000 950000 975000 1000000 | 284 | * 800000 850000 925000 950000 975000 1000000 |
285 | * Data rate: 1500000 2000000 2500000 3000000 3500000 4000000 | 285 | * Data rate: 1500000 2000000 2500000 3000000 3500000 4000000 |
286 | * 5000000 | 286 | * 5000000 |
287 | */ | 287 | */ |
288 | 288 | ||
289 | /* Structure of the hardware registers */ | 289 | /* Structure of the hardware registers */ |
290 | struct flexcan_regs { | 290 | struct flexcan_regs { |
291 | u32 mcr; /* 0x00 */ | 291 | u32 mcr; /* 0x00 */ |
292 | u32 ctrl; /* 0x04 */ | 292 | u32 ctrl; /* 0x04 */ |
293 | u32 timer; /* 0x08 */ | 293 | u32 timer; /* 0x08 */ |
294 | u32 _reserved1; /* 0x0c */ | 294 | u32 _reserved1; /* 0x0c */ |
295 | u32 rxgmask; /* 0x10 */ | 295 | u32 rxgmask; /* 0x10 */ |
296 | u32 rx14mask; /* 0x14 */ | 296 | u32 rx14mask; /* 0x14 */ |
297 | u32 rx15mask; /* 0x18 */ | 297 | u32 rx15mask; /* 0x18 */ |
298 | u32 ecr; /* 0x1c */ | 298 | u32 ecr; /* 0x1c */ |
299 | u32 esr; /* 0x20 */ | 299 | u32 esr; /* 0x20 */ |
300 | u32 imask2; /* 0x24 */ | 300 | u32 imask2; /* 0x24 */ |
301 | u32 imask1; /* 0x28 */ | 301 | u32 imask1; /* 0x28 */ |
302 | u32 iflag2; /* 0x2c */ | 302 | u32 iflag2; /* 0x2c */ |
303 | u32 iflag1; /* 0x30 */ | 303 | u32 iflag1; /* 0x30 */ |
304 | union { /* 0x34 */ | 304 | union { /* 0x34 */ |
305 | u32 gfwr_mx28; /* MX28, MX53 */ | 305 | u32 gfwr_mx28; /* MX28, MX53 */ |
306 | u32 ctrl2; /* MX6, VF610 */ | 306 | u32 ctrl2; /* MX6, VF610 */ |
307 | }; | 307 | }; |
308 | u32 esr2; /* 0x38 */ | 308 | u32 esr2; /* 0x38 */ |
309 | u32 imeur; /* 0x3c */ | 309 | u32 imeur; /* 0x3c */ |
310 | u32 lrfr; /* 0x40 */ | 310 | u32 lrfr; /* 0x40 */ |
311 | u32 crcr; /* 0x44 */ | 311 | u32 crcr; /* 0x44 */ |
312 | u32 rxfgmask; /* 0x48 */ | 312 | u32 rxfgmask; /* 0x48 */ |
313 | u32 rxfir; /* 0x4c */ | 313 | u32 rxfir; /* 0x4c */ |
314 | u32 cbt; /* 0x50 */ | 314 | u32 cbt; /* 0x50 */ |
315 | u32 _reserved3[11]; /* 0x54 */ | 315 | u32 _reserved3[11]; /* 0x54 */ |
316 | u32 _reserved8[64*4]; /* 0x80 */ /* 64 mailbox */ | 316 | u32 _reserved8[64*4]; /* 0x80 */ /* 64 mailbox */ |
317 | u32 _reserved4[256]; /* 0x480 */ | 317 | u32 _reserved4[256]; /* 0x480 */ |
318 | u32 rximr[64]; /* 0x880 */ | 318 | u32 rximr[64]; /* 0x880 */ |
319 | u32 _reserved5[24]; /* 0x980 */ | 319 | u32 _reserved5[24]; /* 0x980 */ |
320 | u32 gfwr_mx6; /* 0x9e0 - MX6 */ | 320 | u32 gfwr_mx6; /* 0x9e0 - MX6 */ |
321 | u32 _reserved6[63]; /* 0x9e4 */ | 321 | u32 _reserved6[63]; /* 0x9e4 */ |
322 | u32 mecr; /* 0xae0 */ | 322 | u32 mecr; /* 0xae0 */ |
323 | u32 erriar; /* 0xae4 */ | 323 | u32 erriar; /* 0xae4 */ |
324 | u32 erridpr; /* 0xae8 */ | 324 | u32 erridpr; /* 0xae8 */ |
325 | u32 errippr; /* 0xaec */ | 325 | u32 errippr; /* 0xaec */ |
326 | u32 rerrar; /* 0xaf0 */ | 326 | u32 rerrar; /* 0xaf0 */ |
327 | u32 rerrdr; /* 0xaf4 */ | 327 | u32 rerrdr; /* 0xaf4 */ |
328 | u32 rerrsynr; /* 0xaf8 */ | 328 | u32 rerrsynr; /* 0xaf8 */ |
329 | u32 errsr; /* 0xafc */ | 329 | u32 errsr; /* 0xafc */ |
330 | u32 _reserved7[64]; /* 0xb00 */ | 330 | u32 _reserved7[64]; /* 0xb00 */ |
331 | u32 fdctrl; /* 0xc00 */ | 331 | u32 fdctrl; /* 0xc00 */ |
332 | u32 fdcbt; /* 0xc04 */ | 332 | u32 fdcbt; /* 0xc04 */ |
333 | u32 fdcrc; /* 0xc08 */ | 333 | u32 fdcrc; /* 0xc08 */ |
334 | }; | 334 | }; |
335 | 335 | ||
336 | struct flexcan_devtype_data { | 336 | struct flexcan_devtype_data { |
337 | u32 quirks; /* quirks needed for different IP cores */ | 337 | u32 quirks; /* quirks needed for different IP cores */ |
338 | }; | 338 | }; |
339 | 339 | ||
340 | struct flexcan_stop_mode { | 340 | struct flexcan_stop_mode { |
341 | struct regmap *gpr; | 341 | struct regmap *gpr; |
342 | u8 req_gpr; | 342 | u8 req_gpr; |
343 | u8 req_bit; | 343 | u8 req_bit; |
344 | u8 ack_gpr; | 344 | u8 ack_gpr; |
345 | u8 ack_bit; | 345 | u8 ack_bit; |
346 | }; | 346 | }; |
347 | struct flexcan_priv { | 347 | struct flexcan_priv { |
348 | struct can_priv can; | 348 | struct can_priv can; |
349 | struct can_rx_offload offload; | 349 | struct can_rx_offload offload; |
350 | 350 | ||
351 | struct flexcan_regs __iomem *regs; | 351 | struct flexcan_regs __iomem *regs; |
352 | void __iomem *base; | 352 | void __iomem *base; |
353 | u8 tx_mb_reserved_idx; | 353 | u8 tx_mb_reserved_idx; |
354 | u8 tx_mb_idx; | 354 | u8 tx_mb_idx; |
355 | u32 reg_ctrl_default; | 355 | u32 reg_ctrl_default; |
356 | u32 reg_imask1_default; | 356 | u32 reg_imask1_default; |
357 | u32 reg_imask2_default; | 357 | u32 reg_imask2_default; |
358 | 358 | ||
359 | struct device *dev; | 359 | struct device *dev; |
360 | struct clk *clk_ipg; | 360 | struct clk *clk_ipg; |
361 | struct clk *clk_per; | 361 | struct clk *clk_per; |
362 | struct flexcan_platform_data *pdata; | 362 | struct flexcan_platform_data *pdata; |
363 | const struct flexcan_devtype_data *devtype_data; | 363 | const struct flexcan_devtype_data *devtype_data; |
364 | struct regulator *reg_xceiver; | 364 | struct regulator *reg_xceiver; |
365 | int id; | 365 | int id; |
366 | struct flexcan_stop_mode stm; | 366 | struct flexcan_stop_mode stm; |
367 | #ifdef CONFIG_ARCH_MXC_ARM64 | 367 | #ifdef CONFIG_ARCH_MXC_ARM64 |
368 | sc_ipc_t ipc_handle; | 368 | sc_ipc_t ipc_handle; |
369 | #endif | 369 | #endif |
370 | bool wakeup; | 370 | bool wakeup; |
371 | 371 | ||
372 | u32 mb_size; | 372 | u32 mb_size; |
373 | u32 mb_num; | 373 | u32 mb_num; |
374 | 374 | ||
375 | /* Selects the clock source to CAN Protocol Engine (PE), 1 by default*/ | 375 | /* Selects the clock source to CAN Protocol Engine (PE), 1 by default*/ |
376 | u32 clk_src; | 376 | u32 clk_src; |
377 | }; | 377 | }; |
378 | 378 | ||
379 | static const struct flexcan_devtype_data fsl_p1010_devtype_data = { | 379 | static const struct flexcan_devtype_data fsl_p1010_devtype_data = { |
380 | .quirks = FLEXCAN_QUIRK_BROKEN_WERR_STATE | | 380 | .quirks = FLEXCAN_QUIRK_BROKEN_WERR_STATE | |
381 | FLEXCAN_QUIRK_BROKEN_PERR_STATE, | 381 | FLEXCAN_QUIRK_BROKEN_PERR_STATE, |
382 | }; | 382 | }; |
383 | 383 | ||
384 | static const struct flexcan_devtype_data fsl_imx28_devtype_data = { | 384 | static const struct flexcan_devtype_data fsl_imx28_devtype_data = { |
385 | .quirks = FLEXCAN_QUIRK_BROKEN_PERR_STATE, | 385 | .quirks = FLEXCAN_QUIRK_BROKEN_PERR_STATE, |
386 | }; | 386 | }; |
387 | 387 | ||
388 | static const struct flexcan_devtype_data fsl_imx6q_devtype_data = { | 388 | static const struct flexcan_devtype_data fsl_imx6q_devtype_data = { |
389 | .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS | | 389 | .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS | |
390 | FLEXCAN_QUIRK_USE_OFF_TIMESTAMP | FLEXCAN_QUIRK_BROKEN_PERR_STATE, | 390 | FLEXCAN_QUIRK_USE_OFF_TIMESTAMP | FLEXCAN_QUIRK_BROKEN_PERR_STATE, |
391 | }; | 391 | }; |
392 | 392 | ||
393 | static struct flexcan_devtype_data fsl_imx8qm_devtype_data = { | 393 | static struct flexcan_devtype_data fsl_imx8qm_devtype_data = { |
394 | .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS | | 394 | .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS | |
395 | FLEXCAN_QUIRK_USE_OFF_TIMESTAMP | FLEXCAN_QUIRK_BROKEN_PERR_STATE | | 395 | FLEXCAN_QUIRK_USE_OFF_TIMESTAMP | FLEXCAN_QUIRK_BROKEN_PERR_STATE | |
396 | FLEXCAN_QUIRK_TIMESTAMP_SUPPORT_FD, | 396 | FLEXCAN_QUIRK_TIMESTAMP_SUPPORT_FD, |
397 | }; | 397 | }; |
398 | 398 | ||
399 | static const struct flexcan_devtype_data fsl_vf610_devtype_data = { | 399 | static const struct flexcan_devtype_data fsl_vf610_devtype_data = { |
400 | .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS | | 400 | .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS | |
401 | FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_USE_OFF_TIMESTAMP | | 401 | FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_USE_OFF_TIMESTAMP | |
402 | FLEXCAN_QUIRK_BROKEN_PERR_STATE, | 402 | FLEXCAN_QUIRK_BROKEN_PERR_STATE, |
403 | }; | 403 | }; |
404 | 404 | ||
405 | static const struct can_bittiming_const flexcan_bittiming_const = { | 405 | static const struct can_bittiming_const flexcan_bittiming_const = { |
406 | .name = DRV_NAME, | 406 | .name = DRV_NAME, |
407 | .tseg1_min = 4, | 407 | .tseg1_min = 4, |
408 | .tseg1_max = 16, | 408 | .tseg1_max = 16, |
409 | .tseg2_min = 2, | 409 | .tseg2_min = 2, |
410 | .tseg2_max = 8, | 410 | .tseg2_max = 8, |
411 | .sjw_max = 4, | 411 | .sjw_max = 4, |
412 | .brp_min = 1, | 412 | .brp_min = 1, |
413 | .brp_max = 256, | 413 | .brp_max = 256, |
414 | .brp_inc = 1, | 414 | .brp_inc = 1, |
415 | }; | 415 | }; |
416 | 416 | ||
417 | static const struct can_bittiming_const flexcan_fd_bittiming_const = { | 417 | static const struct can_bittiming_const flexcan_fd_bittiming_const = { |
418 | .name = DRV_NAME, | 418 | .name = DRV_NAME, |
419 | .tseg1_min = 2, | 419 | .tseg1_min = 2, |
420 | .tseg1_max = 64, | 420 | .tseg1_max = 64, |
421 | .tseg2_min = 1, | 421 | .tseg2_min = 1, |
422 | .tseg2_max = 32, | 422 | .tseg2_max = 32, |
423 | .sjw_max = 32, | 423 | .sjw_max = 32, |
424 | .brp_min = 1, | 424 | .brp_min = 1, |
425 | .brp_max = 1024, | 425 | .brp_max = 1024, |
426 | .brp_inc = 1, | 426 | .brp_inc = 1, |
427 | }; | 427 | }; |
428 | 428 | ||
429 | static const struct can_bittiming_const flexcan_fd_data_bittiming_const = { | 429 | static const struct can_bittiming_const flexcan_fd_data_bittiming_const = { |
430 | .name = DRV_NAME, | 430 | .name = DRV_NAME, |
431 | .tseg1_min = 1, | 431 | .tseg1_min = 1, |
432 | .tseg1_max = 39, | 432 | .tseg1_max = 39, |
433 | .tseg2_min = 1, | 433 | .tseg2_min = 1, |
434 | .tseg2_max = 8, | 434 | .tseg2_max = 8, |
435 | .sjw_max = 8, | 435 | .sjw_max = 8, |
436 | .brp_min = 1, | 436 | .brp_min = 1, |
437 | .brp_max = 1024, | 437 | .brp_max = 1024, |
438 | .brp_inc = 1, | 438 | .brp_inc = 1, |
439 | }; | 439 | }; |
440 | 440 | ||
441 | /* Abstract off the read/write for arm versus ppc. This | 441 | /* Abstract off the read/write for arm versus ppc. This |
442 | * assumes that PPC uses big-endian registers and everything | 442 | * assumes that PPC uses big-endian registers and everything |
443 | * else uses little-endian registers, independent of CPU | 443 | * else uses little-endian registers, independent of CPU |
444 | * endianness. | 444 | * endianness. |
445 | */ | 445 | */ |
446 | #if defined(CONFIG_PPC) | 446 | #if defined(CONFIG_PPC) |
447 | static inline u32 flexcan_read(void __iomem *addr) | 447 | static inline u32 flexcan_read(void __iomem *addr) |
448 | { | 448 | { |
449 | return in_be32(addr); | 449 | return in_be32(addr); |
450 | } | 450 | } |
451 | 451 | ||
452 | static inline void flexcan_write(u32 val, void __iomem *addr) | 452 | static inline void flexcan_write(u32 val, void __iomem *addr) |
453 | { | 453 | { |
454 | out_be32(addr, val); | 454 | out_be32(addr, val); |
455 | } | 455 | } |
456 | 456 | ||
457 | static inline u32 flexcan_mb_read(const struct flexcan_priv *priv, | 457 | static inline u32 flexcan_mb_read(const struct flexcan_priv *priv, |
458 | u32 index, unsigned int offset) | 458 | u32 index, unsigned int offset) |
459 | { | 459 | { |
460 | if (priv->can.ctrlmode & CAN_CTRLMODE_FD) | 460 | if (priv->can.ctrlmode & CAN_CTRLMODE_FD) |
461 | return in_be32(priv->base + FLEXCAN_MB + | 461 | return in_be32(priv->base + FLEXCAN_MB + |
462 | FLEXCAN_CANFD_MB_OFFSET(index) + offset); | 462 | FLEXCAN_CANFD_MB_OFFSET(index) + offset); |
463 | else | 463 | else |
464 | return in_be32(priv->base + FLEXCAN_MB + | 464 | return in_be32(priv->base + FLEXCAN_MB + |
465 | priv->mb_size * index + offset); | 465 | priv->mb_size * index + offset); |
466 | } | 466 | } |
467 | 467 | ||
468 | static inline void flexcan_mb_write(const struct flexcan_priv *priv, | 468 | static inline void flexcan_mb_write(const struct flexcan_priv *priv, |
469 | u32 index, unsigned int offset, | 469 | u32 index, unsigned int offset, |
470 | u32 val) | 470 | u32 val) |
471 | { | 471 | { |
472 | if (priv->can.ctrlmode & CAN_CTRLMODE_FD) | 472 | if (priv->can.ctrlmode & CAN_CTRLMODE_FD) |
473 | out_be32(val, priv->base + FLEXCAN_MB + | 473 | out_be32(val, priv->base + FLEXCAN_MB + |
474 | FLEXCAN_CANFD_MB_OFFSET(index) + offset); | 474 | FLEXCAN_CANFD_MB_OFFSET(index) + offset); |
475 | else | 475 | else |
476 | out_be32(val, priv->base + FLEXCAN_MB + | 476 | out_be32(val, priv->base + FLEXCAN_MB + |
477 | priv->mb_size * index + offset); | 477 | priv->mb_size * index + offset); |
478 | } | 478 | } |
479 | #else | 479 | #else |
480 | static inline u32 flexcan_read(void __iomem *addr) | 480 | static inline u32 flexcan_read(void __iomem *addr) |
481 | { | 481 | { |
482 | return readl(addr); | 482 | return readl(addr); |
483 | } | 483 | } |
484 | 484 | ||
485 | static inline void flexcan_write(u32 val, void __iomem *addr) | 485 | static inline void flexcan_write(u32 val, void __iomem *addr) |
486 | { | 486 | { |
487 | writel(val, addr); | 487 | writel(val, addr); |
488 | } | 488 | } |
489 | 489 | ||
490 | static inline u32 flexcan_mb_read(const struct flexcan_priv *priv, | 490 | static inline u32 flexcan_mb_read(const struct flexcan_priv *priv, |
491 | u32 index, unsigned int offset) | 491 | u32 index, unsigned int offset) |
492 | { | 492 | { |
493 | if (priv->can.ctrlmode & CAN_CTRLMODE_FD) | 493 | if (priv->can.ctrlmode & CAN_CTRLMODE_FD) |
494 | return readl(priv->base + FLEXCAN_MB + | 494 | return readl(priv->base + FLEXCAN_MB + |
495 | FLEXCAN_CANFD_MB_OFFSET(index) + offset); | 495 | FLEXCAN_CANFD_MB_OFFSET(index) + offset); |
496 | else | 496 | else |
497 | return readl(priv->base + FLEXCAN_MB + | 497 | return readl(priv->base + FLEXCAN_MB + |
498 | priv->mb_size * index + offset); | 498 | priv->mb_size * index + offset); |
499 | } | 499 | } |
500 | 500 | ||
501 | static inline void flexcan_mb_write(const struct flexcan_priv *priv, | 501 | static inline void flexcan_mb_write(const struct flexcan_priv *priv, |
502 | u32 index, unsigned int offset, | 502 | u32 index, unsigned int offset, |
503 | u32 val) | 503 | u32 val) |
504 | { | 504 | { |
505 | if (priv->can.ctrlmode & CAN_CTRLMODE_FD) | 505 | if (priv->can.ctrlmode & CAN_CTRLMODE_FD) |
506 | writel(val, priv->base + FLEXCAN_MB + | 506 | writel(val, priv->base + FLEXCAN_MB + |
507 | FLEXCAN_CANFD_MB_OFFSET(index) + offset); | 507 | FLEXCAN_CANFD_MB_OFFSET(index) + offset); |
508 | else | 508 | else |
509 | writel(val, priv->base + FLEXCAN_MB + | 509 | writel(val, priv->base + FLEXCAN_MB + |
510 | priv->mb_size * index + offset); | 510 | priv->mb_size * index + offset); |
511 | } | 511 | } |
512 | #endif | 512 | #endif |
513 | 513 | ||
514 | static inline void flexcan_error_irq_enable(const struct flexcan_priv *priv) | 514 | static inline void flexcan_error_irq_enable(const struct flexcan_priv *priv) |
515 | { | 515 | { |
516 | struct flexcan_regs __iomem *regs = priv->regs; | 516 | struct flexcan_regs __iomem *regs = priv->regs; |
517 | u32 reg_ctrl = (priv->reg_ctrl_default | FLEXCAN_CTRL_ERR_MSK); | 517 | u32 reg_ctrl = (priv->reg_ctrl_default | FLEXCAN_CTRL_ERR_MSK); |
518 | 518 | ||
519 | flexcan_write(reg_ctrl, ®s->ctrl); | 519 | flexcan_write(reg_ctrl, ®s->ctrl); |
520 | } | 520 | } |
521 | 521 | ||
522 | static inline void flexcan_error_irq_disable(const struct flexcan_priv *priv) | 522 | static inline void flexcan_error_irq_disable(const struct flexcan_priv *priv) |
523 | { | 523 | { |
524 | struct flexcan_regs __iomem *regs = priv->regs; | 524 | struct flexcan_regs __iomem *regs = priv->regs; |
525 | u32 reg_ctrl = (priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_MSK); | 525 | u32 reg_ctrl = (priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_MSK); |
526 | 526 | ||
527 | flexcan_write(reg_ctrl, ®s->ctrl); | 527 | flexcan_write(reg_ctrl, ®s->ctrl); |
528 | } | 528 | } |
529 | 529 | ||
530 | static int flexcan_clks_enable(const struct flexcan_priv *priv) | 530 | static int flexcan_clks_enable(const struct flexcan_priv *priv) |
531 | { | 531 | { |
532 | int err; | 532 | int err; |
533 | 533 | ||
534 | err = clk_prepare_enable(priv->clk_ipg); | 534 | err = clk_prepare_enable(priv->clk_ipg); |
535 | if (err) | 535 | if (err) |
536 | return err; | 536 | return err; |
537 | 537 | ||
538 | err = clk_prepare_enable(priv->clk_per); | 538 | err = clk_prepare_enable(priv->clk_per); |
539 | if (err) | 539 | if (err) |
540 | clk_disable_unprepare(priv->clk_ipg); | 540 | clk_disable_unprepare(priv->clk_ipg); |
541 | 541 | ||
542 | return err; | 542 | return err; |
543 | } | 543 | } |
544 | 544 | ||
545 | static void flexcan_clks_disable(const struct flexcan_priv *priv) | 545 | static void flexcan_clks_disable(const struct flexcan_priv *priv) |
546 | { | 546 | { |
547 | clk_disable_unprepare(priv->clk_ipg); | 547 | clk_disable_unprepare(priv->clk_ipg); |
548 | clk_disable_unprepare(priv->clk_per); | 548 | clk_disable_unprepare(priv->clk_per); |
549 | } | 549 | } |
550 | 550 | ||
551 | static void flexcan_wake_mask_enable(struct flexcan_priv *priv) | 551 | static void flexcan_wake_mask_enable(struct flexcan_priv *priv) |
552 | { | 552 | { |
553 | struct flexcan_regs __iomem *regs = priv->regs; | 553 | struct flexcan_regs __iomem *regs = priv->regs; |
554 | u32 reg_mcr; | 554 | u32 reg_mcr; |
555 | 555 | ||
556 | reg_mcr = flexcan_read(®s->mcr); | 556 | reg_mcr = flexcan_read(®s->mcr); |
557 | reg_mcr |= FLEXCAN_MCR_WAK_MSK; | 557 | reg_mcr |= FLEXCAN_MCR_WAK_MSK; |
558 | flexcan_write(reg_mcr, ®s->mcr); | 558 | flexcan_write(reg_mcr, ®s->mcr); |
559 | } | 559 | } |
560 | 560 | ||
561 | static void flexcan_wake_mask_disable(struct flexcan_priv *priv) | 561 | static void flexcan_wake_mask_disable(struct flexcan_priv *priv) |
562 | { | 562 | { |
563 | struct flexcan_regs __iomem *regs = priv->regs; | 563 | struct flexcan_regs __iomem *regs = priv->regs; |
564 | u32 reg_mcr; | 564 | u32 reg_mcr; |
565 | 565 | ||
566 | reg_mcr = flexcan_read(®s->mcr); | 566 | reg_mcr = flexcan_read(®s->mcr); |
567 | reg_mcr &= ~FLEXCAN_MCR_WAK_MSK; | 567 | reg_mcr &= ~FLEXCAN_MCR_WAK_MSK; |
568 | flexcan_write(reg_mcr, ®s->mcr); | 568 | flexcan_write(reg_mcr, ®s->mcr); |
569 | } | 569 | } |
570 | 570 | ||
571 | #ifdef CONFIG_ARCH_MXC_ARM64 | 571 | #ifdef CONFIG_ARCH_MXC_ARM64 |
572 | static void imx8_ipg_stop_enable(struct flexcan_priv *priv, bool enabled) | 572 | static void imx8_ipg_stop_enable(struct flexcan_priv *priv, bool enabled) |
573 | { | 573 | { |
574 | struct device_node *np = priv->dev->of_node; | 574 | struct device_node *np = priv->dev->of_node; |
575 | u32 rsrc_id, val; | 575 | u32 rsrc_id, val; |
576 | int idx; | 576 | int idx; |
577 | 577 | ||
578 | idx = of_alias_get_id(np, "can"); | 578 | idx = of_alias_get_id(np, "can"); |
579 | if (idx == 0) | 579 | if (idx == 0) |
580 | rsrc_id = SC_R_CAN_0; | 580 | rsrc_id = SC_R_CAN_0; |
581 | else if (idx == 1) | 581 | else if (idx == 1) |
582 | rsrc_id = SC_R_CAN_1; | 582 | rsrc_id = SC_R_CAN_1; |
583 | else | 583 | else |
584 | rsrc_id = SC_R_CAN_2; | 584 | rsrc_id = SC_R_CAN_2; |
585 | 585 | ||
586 | val = enabled ? 1 : 0; | 586 | val = enabled ? 1 : 0; |
587 | sc_misc_set_control(priv->ipc_handle, rsrc_id, SC_C_IPG_STOP, val); | 587 | sc_misc_set_control(priv->ipc_handle, rsrc_id, SC_C_IPG_STOP, val); |
588 | } | 588 | } |
589 | #else | 589 | #else |
590 | static void imx8_ipg_stop_enable(struct flexcan_priv *priv, bool enabled) {} | 590 | static void imx8_ipg_stop_enable(struct flexcan_priv *priv, bool enabled) {} |
591 | #endif | 591 | #endif |
592 | 592 | ||
593 | static inline void flexcan_enter_stop_mode(struct flexcan_priv *priv) | 593 | static inline void flexcan_enter_stop_mode(struct flexcan_priv *priv) |
594 | { | 594 | { |
595 | /* enable stop request */ | 595 | /* enable stop request */ |
596 | if (priv->stm.gpr) { | 596 | if (priv->stm.gpr) { |
597 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_DISABLE_RXFG) | 597 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_DISABLE_RXFG) |
598 | regmap_update_bits(priv->stm.gpr, priv->stm.req_gpr, | 598 | regmap_update_bits(priv->stm.gpr, priv->stm.req_gpr, |
599 | 1 << priv->stm.req_bit, 1 << priv->stm.req_bit); | 599 | 1 << priv->stm.req_bit, 1 << priv->stm.req_bit); |
600 | } else { | 600 | } else { |
601 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_TIMESTAMP_SUPPORT_FD) | 601 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_TIMESTAMP_SUPPORT_FD) |
602 | imx8_ipg_stop_enable(priv, true); | 602 | imx8_ipg_stop_enable(priv, true); |
603 | } | 603 | } |
604 | } | 604 | } |
605 | 605 | ||
606 | static inline void flexcan_exit_stop_mode(struct flexcan_priv *priv) | 606 | static inline void flexcan_exit_stop_mode(struct flexcan_priv *priv) |
607 | { | 607 | { |
608 | /* remove stop request */ | 608 | /* remove stop request */ |
609 | if (priv->stm.gpr) { | 609 | if (priv->stm.gpr) { |
610 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_DISABLE_RXFG) | 610 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_DISABLE_RXFG) |
611 | regmap_update_bits(priv->stm.gpr, priv->stm.req_gpr, | 611 | regmap_update_bits(priv->stm.gpr, priv->stm.req_gpr, |
612 | 1 << priv->stm.req_bit, 0); | 612 | 1 << priv->stm.req_bit, 0); |
613 | } else { | 613 | } else { |
614 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_TIMESTAMP_SUPPORT_FD) | 614 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_TIMESTAMP_SUPPORT_FD) |
615 | imx8_ipg_stop_enable(priv, false); | 615 | imx8_ipg_stop_enable(priv, false); |
616 | } | 616 | } |
617 | } | 617 | } |
618 | 618 | ||
619 | static inline int flexcan_transceiver_enable(const struct flexcan_priv *priv) | 619 | static inline int flexcan_transceiver_enable(const struct flexcan_priv *priv) |
620 | { | 620 | { |
621 | if (priv->pdata && priv->pdata->transceiver_switch) { | 621 | if (priv->pdata && priv->pdata->transceiver_switch) { |
622 | priv->pdata->transceiver_switch(1); | 622 | priv->pdata->transceiver_switch(1); |
623 | return 0; | 623 | return 0; |
624 | } | 624 | } |
625 | 625 | ||
626 | if (!priv->reg_xceiver) | 626 | if (!priv->reg_xceiver) |
627 | return 0; | 627 | return 0; |
628 | 628 | ||
629 | return regulator_enable(priv->reg_xceiver); | 629 | return regulator_enable(priv->reg_xceiver); |
630 | } | 630 | } |
631 | 631 | ||
632 | static inline int flexcan_transceiver_disable(const struct flexcan_priv *priv) | 632 | static inline int flexcan_transceiver_disable(const struct flexcan_priv *priv) |
633 | { | 633 | { |
634 | if (priv->pdata && priv->pdata->transceiver_switch) { | 634 | if (priv->pdata && priv->pdata->transceiver_switch) { |
635 | priv->pdata->transceiver_switch(0); | 635 | priv->pdata->transceiver_switch(0); |
636 | return 0; | 636 | return 0; |
637 | } | 637 | } |
638 | 638 | ||
639 | if (!priv->reg_xceiver) | 639 | if (!priv->reg_xceiver) |
640 | return 0; | 640 | return 0; |
641 | 641 | ||
642 | return regulator_disable(priv->reg_xceiver); | 642 | return regulator_disable(priv->reg_xceiver); |
643 | } | 643 | } |
644 | 644 | ||
645 | static int flexcan_chip_enable(struct flexcan_priv *priv) | 645 | static int flexcan_chip_enable(struct flexcan_priv *priv) |
646 | { | 646 | { |
647 | struct flexcan_regs __iomem *regs = priv->regs; | 647 | struct flexcan_regs __iomem *regs = priv->regs; |
648 | unsigned int timeout = FLEXCAN_TIMEOUT_US / 10; | 648 | unsigned int timeout = FLEXCAN_TIMEOUT_US / 10; |
649 | u32 reg; | 649 | u32 reg; |
650 | 650 | ||
651 | reg = flexcan_read(®s->mcr); | 651 | reg = flexcan_read(®s->mcr); |
652 | reg &= ~FLEXCAN_MCR_MDIS; | 652 | reg &= ~FLEXCAN_MCR_MDIS; |
653 | flexcan_write(reg, ®s->mcr); | 653 | flexcan_write(reg, ®s->mcr); |
654 | 654 | ||
655 | while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)) | 655 | while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)) |
656 | udelay(10); | 656 | udelay(10); |
657 | 657 | ||
658 | if (flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK) | 658 | if (flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK) |
659 | return -ETIMEDOUT; | 659 | return -ETIMEDOUT; |
660 | 660 | ||
661 | return 0; | 661 | return 0; |
662 | } | 662 | } |
663 | 663 | ||
664 | static int flexcan_chip_disable(struct flexcan_priv *priv) | 664 | static int flexcan_chip_disable(struct flexcan_priv *priv) |
665 | { | 665 | { |
666 | struct flexcan_regs __iomem *regs = priv->regs; | 666 | struct flexcan_regs __iomem *regs = priv->regs; |
667 | unsigned int timeout = FLEXCAN_TIMEOUT_US / 10; | 667 | unsigned int timeout = FLEXCAN_TIMEOUT_US / 10; |
668 | u32 reg; | 668 | u32 reg; |
669 | 669 | ||
670 | reg = flexcan_read(®s->mcr); | 670 | reg = flexcan_read(®s->mcr); |
671 | reg |= FLEXCAN_MCR_MDIS; | 671 | reg |= FLEXCAN_MCR_MDIS; |
672 | flexcan_write(reg, ®s->mcr); | 672 | flexcan_write(reg, ®s->mcr); |
673 | 673 | ||
674 | while (timeout-- && !(flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)) | 674 | while (timeout-- && !(flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)) |
675 | udelay(10); | 675 | udelay(10); |
676 | 676 | ||
677 | if (!(flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)) | 677 | if (!(flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)) |
678 | return -ETIMEDOUT; | 678 | return -ETIMEDOUT; |
679 | 679 | ||
680 | return 0; | 680 | return 0; |
681 | } | 681 | } |
682 | 682 | ||
683 | static int flexcan_chip_freeze(struct flexcan_priv *priv) | 683 | static int flexcan_chip_freeze(struct flexcan_priv *priv) |
684 | { | 684 | { |
685 | struct flexcan_regs __iomem *regs = priv->regs; | 685 | struct flexcan_regs __iomem *regs = priv->regs; |
686 | unsigned int timeout = 1000 * 1000 * 10 / priv->can.bittiming.bitrate; | 686 | unsigned int timeout = 1000 * 1000 * 10 / priv->can.bittiming.bitrate; |
687 | u32 reg; | 687 | u32 reg; |
688 | 688 | ||
689 | reg = flexcan_read(®s->mcr); | 689 | reg = flexcan_read(®s->mcr); |
690 | reg |= FLEXCAN_MCR_HALT; | 690 | reg |= FLEXCAN_MCR_HALT; |
691 | flexcan_write(reg, ®s->mcr); | 691 | flexcan_write(reg, ®s->mcr); |
692 | 692 | ||
693 | while (timeout-- && !(flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK)) | 693 | while (timeout-- && !(flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK)) |
694 | udelay(100); | 694 | udelay(100); |
695 | 695 | ||
696 | if (!(flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK)) | 696 | if (!(flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK)) |
697 | return -ETIMEDOUT; | 697 | return -ETIMEDOUT; |
698 | 698 | ||
699 | return 0; | 699 | return 0; |
700 | } | 700 | } |
701 | 701 | ||
702 | static int flexcan_chip_unfreeze(struct flexcan_priv *priv) | 702 | static int flexcan_chip_unfreeze(struct flexcan_priv *priv) |
703 | { | 703 | { |
704 | struct flexcan_regs __iomem *regs = priv->regs; | 704 | struct flexcan_regs __iomem *regs = priv->regs; |
705 | unsigned int timeout = FLEXCAN_TIMEOUT_US / 10; | 705 | unsigned int timeout = FLEXCAN_TIMEOUT_US / 10; |
706 | u32 reg; | 706 | u32 reg; |
707 | 707 | ||
708 | reg = flexcan_read(®s->mcr); | 708 | reg = flexcan_read(®s->mcr); |
709 | reg &= ~FLEXCAN_MCR_HALT; | 709 | reg &= ~FLEXCAN_MCR_HALT; |
710 | flexcan_write(reg, ®s->mcr); | 710 | flexcan_write(reg, ®s->mcr); |
711 | 711 | ||
712 | while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK)) | 712 | while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK)) |
713 | udelay(20); | 713 | udelay(20); |
714 | 714 | ||
715 | if (flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK) | 715 | if (flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK) |
716 | return -ETIMEDOUT; | 716 | return -ETIMEDOUT; |
717 | 717 | ||
718 | return 0; | 718 | return 0; |
719 | } | 719 | } |
720 | 720 | ||
721 | static int flexcan_chip_softreset(struct flexcan_priv *priv) | 721 | static int flexcan_chip_softreset(struct flexcan_priv *priv) |
722 | { | 722 | { |
723 | struct flexcan_regs __iomem *regs = priv->regs; | 723 | struct flexcan_regs __iomem *regs = priv->regs; |
724 | unsigned int timeout = FLEXCAN_TIMEOUT_US / 10; | 724 | unsigned int timeout = FLEXCAN_TIMEOUT_US / 10; |
725 | 725 | ||
726 | flexcan_write(FLEXCAN_MCR_SOFTRST, ®s->mcr); | 726 | flexcan_write(FLEXCAN_MCR_SOFTRST, ®s->mcr); |
727 | while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_SOFTRST)) | 727 | while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_SOFTRST)) |
728 | udelay(10); | 728 | udelay(10); |
729 | 729 | ||
730 | if (flexcan_read(®s->mcr) & FLEXCAN_MCR_SOFTRST) | 730 | if (flexcan_read(®s->mcr) & FLEXCAN_MCR_SOFTRST) |
731 | return -ETIMEDOUT; | 731 | return -ETIMEDOUT; |
732 | 732 | ||
733 | return 0; | 733 | return 0; |
734 | } | 734 | } |
735 | 735 | ||
736 | static int __flexcan_get_berr_counter(const struct net_device *dev, | 736 | static int __flexcan_get_berr_counter(const struct net_device *dev, |
737 | struct can_berr_counter *bec) | 737 | struct can_berr_counter *bec) |
738 | { | 738 | { |
739 | const struct flexcan_priv *priv = netdev_priv(dev); | 739 | const struct flexcan_priv *priv = netdev_priv(dev); |
740 | struct flexcan_regs __iomem *regs = priv->regs; | 740 | struct flexcan_regs __iomem *regs = priv->regs; |
741 | u32 reg = flexcan_read(®s->ecr); | 741 | u32 reg = flexcan_read(®s->ecr); |
742 | 742 | ||
743 | bec->txerr = (reg >> 0) & 0xff; | 743 | bec->txerr = (reg >> 0) & 0xff; |
744 | bec->rxerr = (reg >> 8) & 0xff; | 744 | bec->rxerr = (reg >> 8) & 0xff; |
745 | 745 | ||
746 | return 0; | 746 | return 0; |
747 | } | 747 | } |
748 | 748 | ||
749 | static int flexcan_get_berr_counter(const struct net_device *dev, | 749 | static int flexcan_get_berr_counter(const struct net_device *dev, |
750 | struct can_berr_counter *bec) | 750 | struct can_berr_counter *bec) |
751 | { | 751 | { |
752 | const struct flexcan_priv *priv = netdev_priv(dev); | 752 | const struct flexcan_priv *priv = netdev_priv(dev); |
753 | int err; | 753 | int err; |
754 | 754 | ||
755 | pm_runtime_get_sync(priv->dev); | 755 | pm_runtime_get_sync(priv->dev); |
756 | 756 | ||
757 | err = __flexcan_get_berr_counter(dev, bec); | 757 | err = __flexcan_get_berr_counter(dev, bec); |
758 | 758 | ||
759 | pm_runtime_put(priv->dev); | 759 | pm_runtime_put(priv->dev); |
760 | 760 | ||
761 | return err; | 761 | return err; |
762 | } | 762 | } |
763 | 763 | ||
764 | static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev) | 764 | static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev) |
765 | { | 765 | { |
766 | const struct flexcan_priv *priv = netdev_priv(dev); | 766 | const struct flexcan_priv *priv = netdev_priv(dev); |
767 | struct flexcan_regs __iomem *regs = priv->regs; | 767 | struct flexcan_regs __iomem *regs = priv->regs; |
768 | struct canfd_frame *cf = (struct canfd_frame *)skb->data; | 768 | struct canfd_frame *cf = (struct canfd_frame *)skb->data; |
769 | u32 can_id, reg_fdctrl; | 769 | u32 can_id, reg_fdctrl; |
770 | u32 data; | 770 | u32 data; |
771 | u32 ctrl = FLEXCAN_MB_CODE_TX_DATA | (can_len2dlc(cf->len) << 16); | 771 | u32 ctrl = FLEXCAN_MB_CODE_TX_DATA | (can_len2dlc(cf->len) << 16); |
772 | u32 i; | 772 | u32 i; |
773 | 773 | ||
774 | if (can_dropped_invalid_skb(dev, skb)) | 774 | if (can_dropped_invalid_skb(dev, skb)) |
775 | return NETDEV_TX_OK; | 775 | return NETDEV_TX_OK; |
776 | 776 | ||
777 | netif_stop_queue(dev); | 777 | netif_stop_queue(dev); |
778 | 778 | ||
779 | if (cf->can_id & CAN_EFF_FLAG) { | 779 | if (cf->can_id & CAN_EFF_FLAG) { |
780 | can_id = cf->can_id & CAN_EFF_MASK; | 780 | can_id = cf->can_id & CAN_EFF_MASK; |
781 | ctrl |= FLEXCAN_MB_CNT_IDE | FLEXCAN_MB_CNT_SRR; | 781 | ctrl |= FLEXCAN_MB_CNT_IDE | FLEXCAN_MB_CNT_SRR; |
782 | } else { | 782 | } else { |
783 | can_id = (cf->can_id & CAN_SFF_MASK) << 18; | 783 | can_id = (cf->can_id & CAN_SFF_MASK) << 18; |
784 | } | 784 | } |
785 | 785 | ||
786 | if (cf->can_id & CAN_RTR_FLAG) | 786 | if (cf->can_id & CAN_RTR_FLAG) |
787 | ctrl |= FLEXCAN_MB_CNT_RTR; | 787 | ctrl |= FLEXCAN_MB_CNT_RTR; |
788 | 788 | ||
789 | for (i = 0; i < cf->len; i += 4) { | 789 | for (i = 0; i < cf->len; i += 4) { |
790 | data = be32_to_cpup((__be32 *)&cf->data[i]); | 790 | data = be32_to_cpup((__be32 *)&cf->data[i]); |
791 | flexcan_mb_write(priv, priv->tx_mb_idx, FLEXCAN_MB_DATA(i / 4), data); | 791 | flexcan_mb_write(priv, priv->tx_mb_idx, FLEXCAN_MB_DATA(i / 4), data); |
792 | } | 792 | } |
793 | 793 | ||
794 | can_put_echo_skb(skb, dev, 0); | 794 | can_put_echo_skb(skb, dev, 0); |
795 | 795 | ||
796 | if (priv->can.ctrlmode & CAN_CTRLMODE_FD) { | 796 | if (priv->can.ctrlmode & CAN_CTRLMODE_FD) { |
797 | reg_fdctrl = flexcan_read(®s->fdctrl) & | 797 | reg_fdctrl = flexcan_read(®s->fdctrl) & |
798 | ~FLEXCAN_FDCTRL_FDRATE; | 798 | ~FLEXCAN_FDCTRL_FDRATE; |
799 | if (cf->flags & CANFD_BRS) { | 799 | if (cf->flags & CANFD_BRS) { |
800 | reg_fdctrl |= FLEXCAN_FDCTRL_FDRATE; | 800 | reg_fdctrl |= FLEXCAN_FDCTRL_FDRATE; |
801 | ctrl |= FLEXCAN_MB_CNT_BRS; | 801 | ctrl |= FLEXCAN_MB_CNT_BRS; |
802 | } | 802 | } |
803 | flexcan_write(reg_fdctrl, ®s->fdctrl); | 803 | flexcan_write(reg_fdctrl, ®s->fdctrl); |
804 | ctrl |= FLEXCAN_MB_CNT_EDL; | 804 | ctrl |= FLEXCAN_MB_CNT_EDL; |
805 | } | 805 | } |
806 | 806 | ||
807 | flexcan_mb_write(priv, priv->tx_mb_idx, FLEXCAN_MB_ID, can_id); | 807 | flexcan_mb_write(priv, priv->tx_mb_idx, FLEXCAN_MB_ID, can_id); |
808 | flexcan_mb_write(priv, priv->tx_mb_idx, FLEXCAN_MB_CTRL, ctrl); | 808 | flexcan_mb_write(priv, priv->tx_mb_idx, FLEXCAN_MB_CTRL, ctrl); |
809 | 809 | ||
810 | /* Errata ERR005829 step8: | 810 | /* Errata ERR005829 step8: |
811 | * Write twice INACTIVE(0x8) code to first MB. | 811 | * Write twice INACTIVE(0x8) code to first MB. |
812 | */ | 812 | */ |
813 | flexcan_mb_write(priv, priv->tx_mb_reserved_idx, FLEXCAN_MB_CTRL, | 813 | flexcan_mb_write(priv, priv->tx_mb_reserved_idx, FLEXCAN_MB_CTRL, |
814 | FLEXCAN_MB_CODE_TX_INACTIVE); | 814 | FLEXCAN_MB_CODE_TX_INACTIVE); |
815 | flexcan_mb_write(priv, priv->tx_mb_reserved_idx, FLEXCAN_MB_CTRL, | 815 | flexcan_mb_write(priv, priv->tx_mb_reserved_idx, FLEXCAN_MB_CTRL, |
816 | FLEXCAN_MB_CODE_TX_INACTIVE); | 816 | FLEXCAN_MB_CODE_TX_INACTIVE); |
817 | 817 | ||
818 | return NETDEV_TX_OK; | 818 | return NETDEV_TX_OK; |
819 | } | 819 | } |
820 | 820 | ||
821 | static void flexcan_irq_bus_err(struct net_device *dev, u32 reg_esr) | 821 | static void flexcan_irq_bus_err(struct net_device *dev, u32 reg_esr) |
822 | { | 822 | { |
823 | struct flexcan_priv *priv = netdev_priv(dev); | 823 | struct flexcan_priv *priv = netdev_priv(dev); |
824 | struct sk_buff *skb; | 824 | struct sk_buff *skb; |
825 | struct can_frame *cf; | 825 | struct can_frame *cf; |
826 | bool rx_errors = false, tx_errors = false; | 826 | bool rx_errors = false, tx_errors = false; |
827 | 827 | ||
828 | skb = alloc_can_err_skb(dev, &cf); | 828 | skb = alloc_can_err_skb(dev, &cf); |
829 | if (unlikely(!skb)) | 829 | if (unlikely(!skb)) |
830 | return; | 830 | return; |
831 | 831 | ||
832 | cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; | 832 | cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; |
833 | 833 | ||
834 | if (reg_esr & FLEXCAN_ESR_BIT1_ERR) { | 834 | if (reg_esr & FLEXCAN_ESR_BIT1_ERR) { |
835 | netdev_dbg(dev, "BIT1_ERR irq\n"); | 835 | netdev_dbg(dev, "BIT1_ERR irq\n"); |
836 | cf->data[2] |= CAN_ERR_PROT_BIT1; | 836 | cf->data[2] |= CAN_ERR_PROT_BIT1; |
837 | tx_errors = true; | 837 | tx_errors = true; |
838 | } | 838 | } |
839 | if (reg_esr & FLEXCAN_ESR_BIT0_ERR) { | 839 | if (reg_esr & FLEXCAN_ESR_BIT0_ERR) { |
840 | netdev_dbg(dev, "BIT0_ERR irq\n"); | 840 | netdev_dbg(dev, "BIT0_ERR irq\n"); |
841 | cf->data[2] |= CAN_ERR_PROT_BIT0; | 841 | cf->data[2] |= CAN_ERR_PROT_BIT0; |
842 | tx_errors = true; | 842 | tx_errors = true; |
843 | } | 843 | } |
844 | if (reg_esr & FLEXCAN_ESR_ACK_ERR) { | 844 | if (reg_esr & FLEXCAN_ESR_ACK_ERR) { |
845 | netdev_dbg(dev, "ACK_ERR irq\n"); | 845 | netdev_dbg(dev, "ACK_ERR irq\n"); |
846 | cf->can_id |= CAN_ERR_ACK; | 846 | cf->can_id |= CAN_ERR_ACK; |
847 | cf->data[3] = CAN_ERR_PROT_LOC_ACK; | 847 | cf->data[3] = CAN_ERR_PROT_LOC_ACK; |
848 | tx_errors = true; | 848 | tx_errors = true; |
849 | } | 849 | } |
850 | if (reg_esr & FLEXCAN_ESR_CRC_ERR) { | 850 | if (reg_esr & FLEXCAN_ESR_CRC_ERR) { |
851 | netdev_dbg(dev, "CRC_ERR irq\n"); | 851 | netdev_dbg(dev, "CRC_ERR irq\n"); |
852 | cf->data[2] |= CAN_ERR_PROT_BIT; | 852 | cf->data[2] |= CAN_ERR_PROT_BIT; |
853 | cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ; | 853 | cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ; |
854 | rx_errors = true; | 854 | rx_errors = true; |
855 | } | 855 | } |
856 | if (reg_esr & FLEXCAN_ESR_FRM_ERR) { | 856 | if (reg_esr & FLEXCAN_ESR_FRM_ERR) { |
857 | netdev_dbg(dev, "FRM_ERR irq\n"); | 857 | netdev_dbg(dev, "FRM_ERR irq\n"); |
858 | cf->data[2] |= CAN_ERR_PROT_FORM; | 858 | cf->data[2] |= CAN_ERR_PROT_FORM; |
859 | rx_errors = true; | 859 | rx_errors = true; |
860 | } | 860 | } |
861 | if (reg_esr & FLEXCAN_ESR_STF_ERR) { | 861 | if (reg_esr & FLEXCAN_ESR_STF_ERR) { |
862 | netdev_dbg(dev, "STF_ERR irq\n"); | 862 | netdev_dbg(dev, "STF_ERR irq\n"); |
863 | cf->data[2] |= CAN_ERR_PROT_STUFF; | 863 | cf->data[2] |= CAN_ERR_PROT_STUFF; |
864 | rx_errors = true; | 864 | rx_errors = true; |
865 | } | 865 | } |
866 | 866 | ||
867 | priv->can.can_stats.bus_error++; | 867 | priv->can.can_stats.bus_error++; |
868 | if (rx_errors) | 868 | if (rx_errors) |
869 | dev->stats.rx_errors++; | 869 | dev->stats.rx_errors++; |
870 | if (tx_errors) | 870 | if (tx_errors) |
871 | dev->stats.tx_errors++; | 871 | dev->stats.tx_errors++; |
872 | 872 | ||
873 | can_rx_offload_queue_tail(&priv->offload, skb); | 873 | can_rx_offload_queue_tail(&priv->offload, skb); |
874 | } | 874 | } |
875 | 875 | ||
876 | static void flexcan_irq_state(struct net_device *dev, u32 reg_esr) | 876 | static void flexcan_irq_state(struct net_device *dev, u32 reg_esr) |
877 | { | 877 | { |
878 | struct flexcan_priv *priv = netdev_priv(dev); | 878 | struct flexcan_priv *priv = netdev_priv(dev); |
879 | struct sk_buff *skb; | 879 | struct sk_buff *skb; |
880 | struct can_frame *cf; | 880 | struct can_frame *cf; |
881 | enum can_state new_state, rx_state, tx_state; | 881 | enum can_state new_state, rx_state, tx_state; |
882 | int flt; | 882 | int flt; |
883 | struct can_berr_counter bec; | 883 | struct can_berr_counter bec; |
884 | 884 | ||
885 | flt = reg_esr & FLEXCAN_ESR_FLT_CONF_MASK; | 885 | flt = reg_esr & FLEXCAN_ESR_FLT_CONF_MASK; |
886 | if (likely(flt == FLEXCAN_ESR_FLT_CONF_ACTIVE)) { | 886 | if (likely(flt == FLEXCAN_ESR_FLT_CONF_ACTIVE)) { |
887 | tx_state = unlikely(reg_esr & FLEXCAN_ESR_TX_WRN) ? | 887 | tx_state = unlikely(reg_esr & FLEXCAN_ESR_TX_WRN) ? |
888 | CAN_STATE_ERROR_WARNING : CAN_STATE_ERROR_ACTIVE; | 888 | CAN_STATE_ERROR_WARNING : CAN_STATE_ERROR_ACTIVE; |
889 | rx_state = unlikely(reg_esr & FLEXCAN_ESR_RX_WRN) ? | 889 | rx_state = unlikely(reg_esr & FLEXCAN_ESR_RX_WRN) ? |
890 | CAN_STATE_ERROR_WARNING : CAN_STATE_ERROR_ACTIVE; | 890 | CAN_STATE_ERROR_WARNING : CAN_STATE_ERROR_ACTIVE; |
891 | new_state = max(tx_state, rx_state); | 891 | new_state = max(tx_state, rx_state); |
892 | } else { | 892 | } else { |
893 | __flexcan_get_berr_counter(dev, &bec); | 893 | __flexcan_get_berr_counter(dev, &bec); |
894 | new_state = flt == FLEXCAN_ESR_FLT_CONF_PASSIVE ? | 894 | new_state = flt == FLEXCAN_ESR_FLT_CONF_PASSIVE ? |
895 | CAN_STATE_ERROR_PASSIVE : CAN_STATE_BUS_OFF; | 895 | CAN_STATE_ERROR_PASSIVE : CAN_STATE_BUS_OFF; |
896 | rx_state = bec.rxerr >= bec.txerr ? new_state : 0; | 896 | rx_state = bec.rxerr >= bec.txerr ? new_state : 0; |
897 | tx_state = bec.rxerr <= bec.txerr ? new_state : 0; | 897 | tx_state = bec.rxerr <= bec.txerr ? new_state : 0; |
898 | } | 898 | } |
899 | 899 | ||
900 | /* state hasn't changed */ | 900 | /* state hasn't changed */ |
901 | if (likely(new_state == priv->can.state)) | 901 | if (likely(new_state == priv->can.state)) |
902 | return; | 902 | return; |
903 | 903 | ||
904 | skb = alloc_can_err_skb(dev, &cf); | 904 | skb = alloc_can_err_skb(dev, &cf); |
905 | if (unlikely(!skb)) | 905 | if (unlikely(!skb)) |
906 | return; | 906 | return; |
907 | 907 | ||
908 | can_change_state(dev, cf, tx_state, rx_state); | 908 | can_change_state(dev, cf, tx_state, rx_state); |
909 | 909 | ||
910 | if (unlikely(new_state == CAN_STATE_BUS_OFF)) | 910 | if (unlikely(new_state == CAN_STATE_BUS_OFF)) |
911 | can_bus_off(dev); | 911 | can_bus_off(dev); |
912 | 912 | ||
913 | can_rx_offload_queue_tail(&priv->offload, skb); | 913 | can_rx_offload_queue_tail(&priv->offload, skb); |
914 | } | 914 | } |
915 | 915 | ||
916 | static inline struct flexcan_priv *rx_offload_to_priv(struct can_rx_offload *offload) | 916 | static inline struct flexcan_priv *rx_offload_to_priv(struct can_rx_offload *offload) |
917 | { | 917 | { |
918 | return container_of(offload, struct flexcan_priv, offload); | 918 | return container_of(offload, struct flexcan_priv, offload); |
919 | } | 919 | } |
920 | 920 | ||
921 | static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload, | 921 | static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload, |
922 | struct canfd_frame *cf, | 922 | struct canfd_frame *cf, |
923 | u32 *timestamp, unsigned int n) | 923 | u32 *timestamp, unsigned int n) |
924 | { | 924 | { |
925 | struct flexcan_priv *priv = rx_offload_to_priv(offload); | 925 | struct flexcan_priv *priv = rx_offload_to_priv(offload); |
926 | struct flexcan_regs __iomem *regs = priv->regs; | 926 | struct flexcan_regs __iomem *regs = priv->regs; |
927 | u32 reg_ctrl, reg_id, reg_iflag1; | 927 | u32 reg_ctrl, reg_id, reg_iflag1; |
928 | u32 i; | 928 | u32 i; |
929 | 929 | ||
930 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { | 930 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { |
931 | u32 code; | 931 | u32 code; |
932 | 932 | ||
933 | do { | 933 | do { |
934 | reg_ctrl = flexcan_mb_read(priv, n, FLEXCAN_MB_CTRL); | 934 | reg_ctrl = flexcan_mb_read(priv, n, FLEXCAN_MB_CTRL); |
935 | } while (reg_ctrl & FLEXCAN_MB_CODE_RX_BUSY_BIT); | 935 | } while (reg_ctrl & FLEXCAN_MB_CODE_RX_BUSY_BIT); |
936 | 936 | ||
937 | /* is this MB empty? */ | 937 | /* is this MB empty? */ |
938 | code = reg_ctrl & FLEXCAN_MB_CODE_MASK; | 938 | code = reg_ctrl & FLEXCAN_MB_CODE_MASK; |
939 | if ((code != FLEXCAN_MB_CODE_RX_FULL) && | 939 | if ((code != FLEXCAN_MB_CODE_RX_FULL) && |
940 | (code != FLEXCAN_MB_CODE_RX_OVERRUN)) | 940 | (code != FLEXCAN_MB_CODE_RX_OVERRUN)) |
941 | return 0; | 941 | return 0; |
942 | 942 | ||
943 | if (code == FLEXCAN_MB_CODE_RX_OVERRUN) { | 943 | if (code == FLEXCAN_MB_CODE_RX_OVERRUN) { |
944 | /* This MB was overrun, we lost data */ | 944 | /* This MB was overrun, we lost data */ |
945 | offload->dev->stats.rx_over_errors++; | 945 | offload->dev->stats.rx_over_errors++; |
946 | offload->dev->stats.rx_errors++; | 946 | offload->dev->stats.rx_errors++; |
947 | } | 947 | } |
948 | } else { | 948 | } else { |
949 | reg_iflag1 = flexcan_read(®s->iflag1); | 949 | reg_iflag1 = flexcan_read(®s->iflag1); |
950 | if (!(reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE)) | 950 | if (!(reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE)) |
951 | return 0; | 951 | return 0; |
952 | 952 | ||
953 | reg_ctrl = flexcan_mb_read(priv, n, FLEXCAN_MB_CTRL); | 953 | reg_ctrl = flexcan_mb_read(priv, n, FLEXCAN_MB_CTRL); |
954 | } | 954 | } |
955 | 955 | ||
956 | /* increase timstamp to full 32 bit */ | 956 | /* increase timstamp to full 32 bit */ |
957 | *timestamp = reg_ctrl << 16; | 957 | *timestamp = reg_ctrl << 16; |
958 | 958 | ||
959 | reg_id = flexcan_mb_read(priv, n, FLEXCAN_MB_ID); | 959 | reg_id = flexcan_mb_read(priv, n, FLEXCAN_MB_ID); |
960 | if (reg_ctrl & FLEXCAN_MB_CNT_IDE) | 960 | if (reg_ctrl & FLEXCAN_MB_CNT_IDE) |
961 | cf->can_id = ((reg_id >> 0) & CAN_EFF_MASK) | CAN_EFF_FLAG; | 961 | cf->can_id = ((reg_id >> 0) & CAN_EFF_MASK) | CAN_EFF_FLAG; |
962 | else | 962 | else |
963 | cf->can_id = (reg_id >> 18) & CAN_SFF_MASK; | 963 | cf->can_id = (reg_id >> 18) & CAN_SFF_MASK; |
964 | 964 | ||
965 | if (reg_ctrl & FLEXCAN_MB_CNT_EDL) | 965 | if (reg_ctrl & FLEXCAN_MB_CNT_EDL) |
966 | cf->len = can_dlc2len((reg_ctrl >> 16) & 0x0F); | 966 | cf->len = can_dlc2len((reg_ctrl >> 16) & 0x0F); |
967 | else | 967 | else |
968 | cf->len = get_can_dlc((reg_ctrl >> 16) & 0x0F); | 968 | cf->len = get_can_dlc((reg_ctrl >> 16) & 0x0F); |
969 | 969 | ||
970 | if (reg_ctrl & FLEXCAN_MB_CNT_ESI) { | 970 | if (reg_ctrl & FLEXCAN_MB_CNT_ESI) { |
971 | cf->flags |= CANFD_ESI; | 971 | cf->flags |= CANFD_ESI; |
972 | netdev_warn(priv->can.dev, "ESI Error\n"); | 972 | netdev_warn(priv->can.dev, "ESI Error\n"); |
973 | } | 973 | } |
974 | 974 | ||
975 | if (!(reg_ctrl & FLEXCAN_MB_CNT_EDL) && reg_ctrl & FLEXCAN_MB_CNT_RTR) { | 975 | if (!(reg_ctrl & FLEXCAN_MB_CNT_EDL) && reg_ctrl & FLEXCAN_MB_CNT_RTR) { |
976 | cf->can_id |= CAN_RTR_FLAG; | 976 | cf->can_id |= CAN_RTR_FLAG; |
977 | } else { | 977 | } else { |
978 | if (reg_ctrl & FLEXCAN_MB_CNT_BRS) | 978 | if (reg_ctrl & FLEXCAN_MB_CNT_BRS) |
979 | cf->flags |= CANFD_BRS; | 979 | cf->flags |= CANFD_BRS; |
980 | 980 | ||
981 | for (i = 0; i < cf->len; i += 4) | 981 | for (i = 0; i < cf->len; i += 4) |
982 | *(__be32 *)(cf->data + i) = cpu_to_be32(flexcan_mb_read(priv, | 982 | *(__be32 *)(cf->data + i) = cpu_to_be32(flexcan_mb_read(priv, |
983 | n, FLEXCAN_MB_DATA(i / 4))); | 983 | n, FLEXCAN_MB_DATA(i / 4))); |
984 | } | 984 | } |
985 | 985 | ||
986 | /* mark as read */ | 986 | /* mark as read */ |
987 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { | 987 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { |
988 | /* Clear IRQ */ | 988 | /* Clear IRQ */ |
989 | if (n < 32) | 989 | if (n < 32) |
990 | flexcan_write(BIT(n), ®s->iflag1); | 990 | flexcan_write(BIT(n), ®s->iflag1); |
991 | else | 991 | else |
992 | flexcan_write(BIT(n - 32), ®s->iflag2); | 992 | flexcan_write(BIT(n - 32), ®s->iflag2); |
993 | } else { | 993 | } else { |
994 | flexcan_write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1); | 994 | flexcan_write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1); |
995 | flexcan_read(®s->timer); | 995 | flexcan_read(®s->timer); |
996 | } | 996 | } |
997 | 997 | ||
998 | return 1; | 998 | return 1; |
999 | } | 999 | } |
1000 | 1000 | ||
1001 | 1001 | ||
1002 | static inline u64 flexcan_read_reg_iflag_rx(struct flexcan_priv *priv) | 1002 | static inline u64 flexcan_read_reg_iflag_rx(struct flexcan_priv *priv) |
1003 | { | 1003 | { |
1004 | struct flexcan_regs __iomem *regs = priv->regs; | 1004 | struct flexcan_regs __iomem *regs = priv->regs; |
1005 | u32 iflag1, iflag2; | 1005 | u32 iflag1, iflag2; |
1006 | 1006 | ||
1007 | iflag2 = flexcan_read(®s->iflag2) & priv->reg_imask2_default; | 1007 | iflag2 = flexcan_read(®s->iflag2) & priv->reg_imask2_default; |
1008 | iflag1 = flexcan_read(®s->iflag1) & priv->reg_imask1_default & | 1008 | iflag1 = flexcan_read(®s->iflag1) & priv->reg_imask1_default & |
1009 | ~FLEXCAN_IFLAG_MB(priv->tx_mb_idx); | 1009 | ~FLEXCAN_IFLAG_MB(priv->tx_mb_idx); |
1010 | 1010 | ||
1011 | return (u64)iflag2 << 32 | iflag1; | 1011 | return (u64)iflag2 << 32 | iflag1; |
1012 | } | 1012 | } |
1013 | 1013 | ||
1014 | static irqreturn_t flexcan_irq(int irq, void *dev_id) | 1014 | static irqreturn_t flexcan_irq(int irq, void *dev_id) |
1015 | { | 1015 | { |
1016 | struct net_device *dev = dev_id; | 1016 | struct net_device *dev = dev_id; |
1017 | struct net_device_stats *stats = &dev->stats; | 1017 | struct net_device_stats *stats = &dev->stats; |
1018 | struct flexcan_priv *priv = netdev_priv(dev); | 1018 | struct flexcan_priv *priv = netdev_priv(dev); |
1019 | struct flexcan_regs __iomem *regs = priv->regs; | 1019 | struct flexcan_regs __iomem *regs = priv->regs; |
1020 | irqreturn_t handled = IRQ_NONE; | 1020 | irqreturn_t handled = IRQ_NONE; |
1021 | u32 reg_iflag1, reg_esr; | 1021 | u32 reg_iflag1, reg_esr; |
1022 | enum can_state last_state = priv->can.state; | 1022 | enum can_state last_state = priv->can.state; |
1023 | 1023 | ||
1024 | reg_iflag1 = flexcan_read(®s->iflag1); | 1024 | reg_iflag1 = flexcan_read(®s->iflag1); |
1025 | 1025 | ||
1026 | /* reception interrupt */ | 1026 | /* reception interrupt */ |
1027 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { | 1027 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { |
1028 | u64 reg_iflag; | 1028 | u64 reg_iflag; |
1029 | int ret; | 1029 | int ret; |
1030 | 1030 | ||
1031 | while ((reg_iflag = flexcan_read_reg_iflag_rx(priv))) { | 1031 | while ((reg_iflag = flexcan_read_reg_iflag_rx(priv))) { |
1032 | handled = IRQ_HANDLED; | 1032 | handled = IRQ_HANDLED; |
1033 | ret = can_rx_offload_irq_offload_timestamp(&priv->offload, | 1033 | ret = can_rx_offload_irq_offload_timestamp(&priv->offload, |
1034 | reg_iflag); | 1034 | reg_iflag); |
1035 | if (!ret) | 1035 | if (!ret) |
1036 | break; | 1036 | break; |
1037 | } | 1037 | } |
1038 | } else { | 1038 | } else { |
1039 | if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE) { | 1039 | if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE) { |
1040 | handled = IRQ_HANDLED; | 1040 | handled = IRQ_HANDLED; |
1041 | can_rx_offload_irq_offload_fifo(&priv->offload); | 1041 | can_rx_offload_irq_offload_fifo(&priv->offload); |
1042 | } | 1042 | } |
1043 | 1043 | ||
1044 | /* FIFO overflow interrupt */ | 1044 | /* FIFO overflow interrupt */ |
1045 | if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_OVERFLOW) { | 1045 | if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_OVERFLOW) { |
1046 | handled = IRQ_HANDLED; | 1046 | handled = IRQ_HANDLED; |
1047 | flexcan_write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW, ®s->iflag1); | 1047 | flexcan_write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW, ®s->iflag1); |
1048 | dev->stats.rx_over_errors++; | 1048 | dev->stats.rx_over_errors++; |
1049 | dev->stats.rx_errors++; | 1049 | dev->stats.rx_errors++; |
1050 | } | 1050 | } |
1051 | } | 1051 | } |
1052 | 1052 | ||
1053 | /* transmission complete interrupt */ | 1053 | /* transmission complete interrupt */ |
1054 | if (reg_iflag1 & FLEXCAN_IFLAG_MB(priv->tx_mb_idx)) { | 1054 | if (reg_iflag1 & FLEXCAN_IFLAG_MB(priv->tx_mb_idx)) { |
1055 | handled = IRQ_HANDLED; | 1055 | handled = IRQ_HANDLED; |
1056 | stats->tx_bytes += can_get_echo_skb(dev, 0); | 1056 | stats->tx_bytes += can_get_echo_skb(dev, 0); |
1057 | stats->tx_packets++; | 1057 | stats->tx_packets++; |
1058 | can_led_event(dev, CAN_LED_EVENT_TX); | 1058 | can_led_event(dev, CAN_LED_EVENT_TX); |
1059 | 1059 | ||
1060 | /* after sending a RTR frame MB is in RX mode */ | 1060 | /* after sending a RTR frame MB is in RX mode */ |
1061 | flexcan_mb_write(priv, priv->tx_mb_idx, FLEXCAN_MB_CTRL, | 1061 | flexcan_mb_write(priv, priv->tx_mb_idx, FLEXCAN_MB_CTRL, |
1062 | FLEXCAN_MB_CODE_TX_INACTIVE); | 1062 | FLEXCAN_MB_CODE_TX_INACTIVE); |
1063 | flexcan_write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), ®s->iflag1); | 1063 | flexcan_write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), ®s->iflag1); |
1064 | netif_wake_queue(dev); | 1064 | netif_wake_queue(dev); |
1065 | } | 1065 | } |
1066 | 1066 | ||
1067 | reg_esr = flexcan_read(®s->esr); | 1067 | reg_esr = flexcan_read(®s->esr); |
1068 | 1068 | ||
1069 | /* ACK all bus error and state change IRQ sources */ | 1069 | /* ACK all bus error and state change IRQ sources */ |
1070 | if (reg_esr & FLEXCAN_ESR_ALL_INT) { | 1070 | if (reg_esr & FLEXCAN_ESR_ALL_INT) { |
1071 | handled = IRQ_HANDLED; | 1071 | handled = IRQ_HANDLED; |
1072 | flexcan_write(reg_esr & FLEXCAN_ESR_ALL_INT, ®s->esr); | 1072 | flexcan_write(reg_esr & FLEXCAN_ESR_ALL_INT, ®s->esr); |
1073 | } | 1073 | } |
1074 | 1074 | ||
1075 | /* state change interrupt or broken error state quirk fix is enabled */ | 1075 | /* state change interrupt or broken error state quirk fix is enabled */ |
1076 | if ((reg_esr & FLEXCAN_ESR_ERR_STATE) || | 1076 | if ((reg_esr & FLEXCAN_ESR_ERR_STATE) || |
1077 | (priv->devtype_data->quirks & (FLEXCAN_QUIRK_BROKEN_WERR_STATE | | 1077 | (priv->devtype_data->quirks & (FLEXCAN_QUIRK_BROKEN_WERR_STATE | |
1078 | FLEXCAN_QUIRK_BROKEN_PERR_STATE))) | 1078 | FLEXCAN_QUIRK_BROKEN_PERR_STATE))) |
1079 | flexcan_irq_state(dev, reg_esr); | 1079 | flexcan_irq_state(dev, reg_esr); |
1080 | 1080 | ||
1081 | /* bus error IRQ - handle if bus error reporting is activated */ | 1081 | /* bus error IRQ - handle if bus error reporting is activated */ |
1082 | if ((reg_esr & FLEXCAN_ESR_ERR_BUS) && | 1082 | if ((reg_esr & FLEXCAN_ESR_ERR_BUS) && |
1083 | (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)) | 1083 | (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)) |
1084 | flexcan_irq_bus_err(dev, reg_esr); | 1084 | flexcan_irq_bus_err(dev, reg_esr); |
1085 | 1085 | ||
1086 | /* availability of error interrupt among state transitions in case | 1086 | /* availability of error interrupt among state transitions in case |
1087 | * bus error reporting is de-activated and | 1087 | * bus error reporting is de-activated and |
1088 | * FLEXCAN_QUIRK_BROKEN_PERR_STATE is enabled: | 1088 | * FLEXCAN_QUIRK_BROKEN_PERR_STATE is enabled: |
1089 | * +--------------------------------------------------------------+ | 1089 | * +--------------------------------------------------------------+ |
1090 | * | +----------------------------------------------+ [stopped / | | 1090 | * | +----------------------------------------------+ [stopped / | |
1091 | * | | | sleeping] -+ | 1091 | * | | | sleeping] -+ |
1092 | * +-+-> active <-> warning <-> passive -> bus off -+ | 1092 | * +-+-> active <-> warning <-> passive -> bus off -+ |
1093 | * ___________^^^^^^^^^^^^_______________________________ | 1093 | * ___________^^^^^^^^^^^^_______________________________ |
1094 | * disabled(1) enabled disabled | 1094 | * disabled(1) enabled disabled |
1095 | * | 1095 | * |
1096 | * (1): enabled if FLEXCAN_QUIRK_BROKEN_WERR_STATE is enabled | 1096 | * (1): enabled if FLEXCAN_QUIRK_BROKEN_WERR_STATE is enabled |
1097 | */ | 1097 | */ |
1098 | if ((last_state != priv->can.state) && | 1098 | if ((last_state != priv->can.state) && |
1099 | (priv->devtype_data->quirks & FLEXCAN_QUIRK_BROKEN_PERR_STATE) && | 1099 | (priv->devtype_data->quirks & FLEXCAN_QUIRK_BROKEN_PERR_STATE) && |
1100 | !(priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)) { | 1100 | !(priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)) { |
1101 | switch (priv->can.state) { | 1101 | switch (priv->can.state) { |
1102 | case CAN_STATE_ERROR_ACTIVE: | 1102 | case CAN_STATE_ERROR_ACTIVE: |
1103 | if (priv->devtype_data->quirks & | 1103 | if (priv->devtype_data->quirks & |
1104 | FLEXCAN_QUIRK_BROKEN_WERR_STATE) | 1104 | FLEXCAN_QUIRK_BROKEN_WERR_STATE) |
1105 | flexcan_error_irq_enable(priv); | 1105 | flexcan_error_irq_enable(priv); |
1106 | else | 1106 | else |
1107 | flexcan_error_irq_disable(priv); | 1107 | flexcan_error_irq_disable(priv); |
1108 | break; | 1108 | break; |
1109 | 1109 | ||
1110 | case CAN_STATE_ERROR_WARNING: | 1110 | case CAN_STATE_ERROR_WARNING: |
1111 | flexcan_error_irq_enable(priv); | 1111 | flexcan_error_irq_enable(priv); |
1112 | break; | 1112 | break; |
1113 | 1113 | ||
1114 | case CAN_STATE_ERROR_PASSIVE: | 1114 | case CAN_STATE_ERROR_PASSIVE: |
1115 | case CAN_STATE_BUS_OFF: | 1115 | case CAN_STATE_BUS_OFF: |
1116 | flexcan_error_irq_disable(priv); | 1116 | flexcan_error_irq_disable(priv); |
1117 | break; | 1117 | break; |
1118 | 1118 | ||
1119 | default: | 1119 | default: |
1120 | break; | 1120 | break; |
1121 | } | 1121 | } |
1122 | } | 1122 | } |
1123 | 1123 | ||
1124 | return handled; | 1124 | return handled; |
1125 | } | 1125 | } |
1126 | 1126 | ||
1127 | static void flexcan_set_bittiming(struct net_device *dev) | 1127 | static void flexcan_set_bittiming(struct net_device *dev) |
1128 | { | 1128 | { |
1129 | const struct flexcan_priv *priv = netdev_priv(dev); | 1129 | const struct flexcan_priv *priv = netdev_priv(dev); |
1130 | const struct can_bittiming *bt = &priv->can.bittiming; | 1130 | const struct can_bittiming *bt = &priv->can.bittiming; |
1131 | const struct can_bittiming *dbt = &priv->can.data_bittiming; | 1131 | const struct can_bittiming *dbt = &priv->can.data_bittiming; |
1132 | struct flexcan_regs __iomem *regs = priv->regs; | 1132 | struct flexcan_regs __iomem *regs = priv->regs; |
1133 | u32 reg; | 1133 | u32 reg; |
1134 | 1134 | ||
1135 | reg = flexcan_read(®s->ctrl); | 1135 | reg = flexcan_read(®s->ctrl); |
1136 | reg &= ~(FLEXCAN_CTRL_LPB | FLEXCAN_CTRL_SMP | FLEXCAN_CTRL_LOM); | 1136 | reg &= ~(FLEXCAN_CTRL_LPB | FLEXCAN_CTRL_SMP | FLEXCAN_CTRL_LOM); |
1137 | if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) | 1137 | if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) |
1138 | reg |= FLEXCAN_CTRL_LPB; | 1138 | reg |= FLEXCAN_CTRL_LPB; |
1139 | if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) | 1139 | if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) |
1140 | reg |= FLEXCAN_CTRL_LOM; | 1140 | reg |= FLEXCAN_CTRL_LOM; |
1141 | if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) | 1141 | if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) |
1142 | reg |= FLEXCAN_CTRL_SMP; | 1142 | reg |= FLEXCAN_CTRL_SMP; |
1143 | flexcan_write(reg, ®s->ctrl); | 1143 | flexcan_write(reg, ®s->ctrl); |
1144 | 1144 | ||
1145 | if (priv->can.ctrlmode_supported & CAN_CTRLMODE_FD) { | 1145 | if (priv->can.ctrlmode_supported & CAN_CTRLMODE_FD) { |
1146 | reg = FLEXCAN_CBT_EPRESDIV(bt->brp - 1) | | 1146 | reg = FLEXCAN_CBT_EPRESDIV(bt->brp - 1) | |
1147 | FLEXCAN_CBT_EPSEG1(bt->phase_seg1 - 1) | | 1147 | FLEXCAN_CBT_EPSEG1(bt->phase_seg1 - 1) | |
1148 | FLEXCAN_CBT_EPSEG2(bt->phase_seg2 - 1) | | 1148 | FLEXCAN_CBT_EPSEG2(bt->phase_seg2 - 1) | |
1149 | FLEXCAN_CBT_ERJW(bt->sjw - 1) | | 1149 | FLEXCAN_CBT_ERJW(bt->sjw - 1) | |
1150 | FLEXCAN_CBT_EPROPSEG(bt->prop_seg - 1) | | 1150 | FLEXCAN_CBT_EPROPSEG(bt->prop_seg - 1) | |
1151 | FLEXCAN_CBT_BTF; | 1151 | FLEXCAN_CBT_BTF; |
1152 | flexcan_write(reg, ®s->cbt); | 1152 | flexcan_write(reg, ®s->cbt); |
1153 | 1153 | ||
1154 | netdev_dbg(dev, "bt: prediv %d seg1 %d seg2 %d rjw %d propseg %d\n", | 1154 | netdev_dbg(dev, "bt: prediv %d seg1 %d seg2 %d rjw %d propseg %d\n", |
1155 | bt->brp - 1, bt->phase_seg1 - 1, bt->phase_seg2 - 1, | 1155 | bt->brp - 1, bt->phase_seg1 - 1, bt->phase_seg2 - 1, |
1156 | bt->sjw - 1, bt->prop_seg - 1); | 1156 | bt->sjw - 1, bt->prop_seg - 1); |
1157 | 1157 | ||
1158 | if (priv->can.ctrlmode & CAN_CTRLMODE_FD) { | 1158 | if (priv->can.ctrlmode & CAN_CTRLMODE_FD) { |
1159 | reg = FLEXCAN_FDCBT_FPRESDIV(dbt->brp - 1) | | 1159 | reg = FLEXCAN_FDCBT_FPRESDIV(dbt->brp - 1) | |
1160 | FLEXCAN_FDCBT_FPSEG1(dbt->phase_seg1 - 1) | | 1160 | FLEXCAN_FDCBT_FPSEG1(dbt->phase_seg1 - 1) | |
1161 | FLEXCAN_FDCBT_FPSEG2(dbt->phase_seg2 - 1) | | 1161 | FLEXCAN_FDCBT_FPSEG2(dbt->phase_seg2 - 1) | |
1162 | FLEXCAN_FDCBT_FRJW(dbt->sjw - 1) | | 1162 | FLEXCAN_FDCBT_FRJW(dbt->sjw - 1) | |
1163 | FLEXCAN_FDCBT_FPROPSEG(dbt->prop_seg); | 1163 | FLEXCAN_FDCBT_FPROPSEG(dbt->prop_seg); |
1164 | flexcan_write(reg, ®s->fdcbt); | 1164 | flexcan_write(reg, ®s->fdcbt); |
1165 | 1165 | ||
1166 | if (bt->brp != dbt->brp) | 1166 | if (bt->brp != dbt->brp) |
1167 | netdev_warn(dev, "PRESDIV not the same, may risk transfer errors\n"); | 1167 | netdev_warn(dev, "PRESDIV not the same, may risk transfer errors\n"); |
1168 | 1168 | ||
1169 | netdev_dbg(dev, "fdbt: prediv %d seg1 %d seg2 %d rjw %d propseg %d\n", | 1169 | netdev_dbg(dev, "fdbt: prediv %d seg1 %d seg2 %d rjw %d propseg %d\n", |
1170 | dbt->brp - 1, dbt->phase_seg1 - 1, dbt->phase_seg2 - 1, | 1170 | dbt->brp - 1, dbt->phase_seg1 - 1, dbt->phase_seg2 - 1, |
1171 | dbt->sjw - 1, dbt->prop_seg); | 1171 | dbt->sjw - 1, dbt->prop_seg); |
1172 | 1172 | ||
1173 | netdev_dbg(dev, "%s: mcr=0x%08x ctrl=0x%08x cbt=0x%08x fdcbt=0x%08x\n", | 1173 | netdev_dbg(dev, "%s: mcr=0x%08x ctrl=0x%08x cbt=0x%08x fdcbt=0x%08x\n", |
1174 | __func__, flexcan_read(®s->mcr), | 1174 | __func__, flexcan_read(®s->mcr), |
1175 | flexcan_read(®s->ctrl), | 1175 | flexcan_read(®s->ctrl), |
1176 | flexcan_read(®s->cbt), | 1176 | flexcan_read(®s->cbt), |
1177 | flexcan_read(®s->fdcbt)); | 1177 | flexcan_read(®s->fdcbt)); |
1178 | } | 1178 | } |
1179 | } else { | 1179 | } else { |
1180 | reg = flexcan_read(®s->ctrl); | 1180 | reg = flexcan_read(®s->ctrl); |
1181 | reg &= ~(FLEXCAN_CTRL_PRESDIV(0xff) | | 1181 | reg &= ~(FLEXCAN_CTRL_PRESDIV(0xff) | |
1182 | FLEXCAN_CTRL_RJW(0x3) | | 1182 | FLEXCAN_CTRL_RJW(0x3) | |
1183 | FLEXCAN_CTRL_PSEG1(0x7) | | 1183 | FLEXCAN_CTRL_PSEG1(0x7) | |
1184 | FLEXCAN_CTRL_PSEG2(0x7) | | 1184 | FLEXCAN_CTRL_PSEG2(0x7) | |
1185 | FLEXCAN_CTRL_PROPSEG(0x7)); | 1185 | FLEXCAN_CTRL_PROPSEG(0x7)); |
1186 | 1186 | ||
1187 | reg |= FLEXCAN_CTRL_PRESDIV(bt->brp - 1) | | 1187 | reg |= FLEXCAN_CTRL_PRESDIV(bt->brp - 1) | |
1188 | FLEXCAN_CTRL_PSEG1(bt->phase_seg1 - 1) | | 1188 | FLEXCAN_CTRL_PSEG1(bt->phase_seg1 - 1) | |
1189 | FLEXCAN_CTRL_PSEG2(bt->phase_seg2 - 1) | | 1189 | FLEXCAN_CTRL_PSEG2(bt->phase_seg2 - 1) | |
1190 | FLEXCAN_CTRL_RJW(bt->sjw - 1) | | 1190 | FLEXCAN_CTRL_RJW(bt->sjw - 1) | |
1191 | FLEXCAN_CTRL_PROPSEG(bt->prop_seg - 1); | 1191 | FLEXCAN_CTRL_PROPSEG(bt->prop_seg - 1); |
1192 | flexcan_write(reg, ®s->ctrl); | 1192 | flexcan_write(reg, ®s->ctrl); |
1193 | 1193 | ||
1194 | netdev_dbg(dev, "bt: prediv %d seg1 %d seg2 %d rjw %d propseg %d\n", | 1194 | netdev_dbg(dev, "bt: prediv %d seg1 %d seg2 %d rjw %d propseg %d\n", |
1195 | bt->brp - 1, bt->phase_seg1 - 1, bt->phase_seg2 - 1, | 1195 | bt->brp - 1, bt->phase_seg1 - 1, bt->phase_seg2 - 1, |
1196 | bt->sjw - 1, bt->prop_seg - 1); | 1196 | bt->sjw - 1, bt->prop_seg - 1); |
1197 | 1197 | ||
1198 | /* print chip status */ | 1198 | /* print chip status */ |
1199 | netdev_dbg(dev, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__, | 1199 | netdev_dbg(dev, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__, |
1200 | flexcan_read(®s->mcr), flexcan_read(®s->ctrl)); | 1200 | flexcan_read(®s->mcr), flexcan_read(®s->ctrl)); |
1201 | } | 1201 | } |
1202 | } | 1202 | } |
1203 | 1203 | ||
1204 | /* flexcan_chip_start | 1204 | /* flexcan_chip_start |
1205 | * | 1205 | * |
1206 | * this functions is entered with clocks enabled | 1206 | * this functions is entered with clocks enabled |
1207 | * | 1207 | * |
1208 | */ | 1208 | */ |
1209 | static int flexcan_chip_start(struct net_device *dev) | 1209 | static int flexcan_chip_start(struct net_device *dev) |
1210 | { | 1210 | { |
1211 | struct flexcan_priv *priv = netdev_priv(dev); | 1211 | struct flexcan_priv *priv = netdev_priv(dev); |
1212 | struct flexcan_regs __iomem *regs = priv->regs; | 1212 | struct flexcan_regs __iomem *regs = priv->regs; |
1213 | u32 reg_mcr, reg_ctrl, reg_ctrl2, reg_mecr, reg_fdctrl; | 1213 | u32 reg_mcr, reg_ctrl, reg_ctrl2, reg_mecr, reg_fdctrl; |
1214 | int err, i; | 1214 | int err, i; |
1215 | 1215 | ||
1216 | /* enable module */ | 1216 | /* enable module */ |
1217 | err = flexcan_chip_enable(priv); | 1217 | err = flexcan_chip_enable(priv); |
1218 | if (err) | 1218 | if (err) |
1219 | return err; | 1219 | return err; |
1220 | 1220 | ||
1221 | /* soft reset */ | 1221 | /* soft reset */ |
1222 | err = flexcan_chip_softreset(priv); | 1222 | err = flexcan_chip_softreset(priv); |
1223 | if (err) | 1223 | if (err) |
1224 | goto out_chip_disable; | 1224 | goto out_chip_disable; |
1225 | 1225 | ||
1226 | flexcan_set_bittiming(dev); | 1226 | flexcan_set_bittiming(dev); |
1227 | 1227 | ||
1228 | /* MCR | 1228 | /* MCR |
1229 | * | 1229 | * |
1230 | * enable freeze | 1230 | * enable freeze |
1231 | * enable fifo | 1231 | * enable fifo |
1232 | * halt now | 1232 | * halt now |
1233 | * only supervisor access | 1233 | * only supervisor access |
1234 | * enable warning int | 1234 | * enable warning int |
1235 | * disable local echo | 1235 | * disable local echo |
1236 | * enable individual RX masking | 1236 | * enable individual RX masking |
1237 | * choose format C | 1237 | * choose format C |
1238 | * set max mailbox number | 1238 | * set max mailbox number |
1239 | */ | 1239 | */ |
1240 | reg_mcr = flexcan_read(®s->mcr); | 1240 | reg_mcr = flexcan_read(®s->mcr); |
1241 | reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff); | 1241 | reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff); |
1242 | reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV | | 1242 | reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV | |
1243 | FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_SRX_DIS | FLEXCAN_MCR_IRMQ | | 1243 | FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_SRX_DIS | FLEXCAN_MCR_IRMQ | |
1244 | FLEXCAN_MCR_IDAM_C; | 1244 | FLEXCAN_MCR_IDAM_C; |
1245 | 1245 | ||
1246 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { | 1246 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { |
1247 | reg_mcr &= ~FLEXCAN_MCR_FEN; | 1247 | reg_mcr &= ~FLEXCAN_MCR_FEN; |
1248 | reg_mcr |= FLEXCAN_MCR_MAXMB(priv->offload.mb_last); | 1248 | reg_mcr |= FLEXCAN_MCR_MAXMB(priv->offload.mb_last); |
1249 | } else { | 1249 | } else { |
1250 | reg_mcr |= FLEXCAN_MCR_FEN | | 1250 | reg_mcr |= FLEXCAN_MCR_FEN | |
1251 | FLEXCAN_MCR_MAXMB(priv->tx_mb_idx); | 1251 | FLEXCAN_MCR_MAXMB(priv->tx_mb_idx); |
1252 | } | 1252 | } |
1253 | 1253 | ||
1254 | /* enable self wakeup */ | 1254 | /* enable self wakeup */ |
1255 | reg_mcr |= FLEXCAN_MCR_SLF_WAK; | 1255 | reg_mcr |= FLEXCAN_MCR_SLF_WAK; |
1256 | 1256 | ||
1257 | netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr); | 1257 | netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr); |
1258 | flexcan_write(reg_mcr, ®s->mcr); | 1258 | flexcan_write(reg_mcr, ®s->mcr); |
1259 | 1259 | ||
1260 | /* CTRL | 1260 | /* CTRL |
1261 | * | 1261 | * |
1262 | * disable timer sync feature | 1262 | * disable timer sync feature |
1263 | * | 1263 | * |
1264 | * disable auto busoff recovery | 1264 | * disable auto busoff recovery |
1265 | * transmit lowest buffer first | 1265 | * transmit lowest buffer first |
1266 | * | 1266 | * |
1267 | * enable tx and rx warning interrupt | 1267 | * enable tx and rx warning interrupt |
1268 | * enable bus off interrupt | 1268 | * enable bus off interrupt |
1269 | * (== FLEXCAN_CTRL_ERR_STATE) | 1269 | * (== FLEXCAN_CTRL_ERR_STATE) |
1270 | */ | 1270 | */ |
1271 | reg_ctrl = flexcan_read(®s->ctrl); | 1271 | reg_ctrl = flexcan_read(®s->ctrl); |
1272 | reg_ctrl &= ~FLEXCAN_CTRL_TSYN; | 1272 | reg_ctrl &= ~FLEXCAN_CTRL_TSYN; |
1273 | reg_ctrl |= FLEXCAN_CTRL_BOFF_REC | FLEXCAN_CTRL_LBUF | | 1273 | reg_ctrl |= FLEXCAN_CTRL_BOFF_REC | FLEXCAN_CTRL_LBUF | |
1274 | FLEXCAN_CTRL_ERR_STATE; | 1274 | FLEXCAN_CTRL_ERR_STATE; |
1275 | 1275 | ||
1276 | /* enable the "error interrupt" (FLEXCAN_CTRL_ERR_MSK), | 1276 | /* enable the "error interrupt" (FLEXCAN_CTRL_ERR_MSK), |
1277 | * on most Flexcan cores, too. Otherwise we don't get | 1277 | * on most Flexcan cores, too. Otherwise we don't get |
1278 | * any error warning or passive interrupts. | 1278 | * any error warning or passive interrupts. |
1279 | */ | 1279 | */ |
1280 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_BROKEN_WERR_STATE || | 1280 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_BROKEN_WERR_STATE || |
1281 | priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) | 1281 | priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) |
1282 | reg_ctrl |= FLEXCAN_CTRL_ERR_MSK; | 1282 | reg_ctrl |= FLEXCAN_CTRL_ERR_MSK; |
1283 | else | 1283 | else |
1284 | reg_ctrl &= ~FLEXCAN_CTRL_ERR_MSK; | 1284 | reg_ctrl &= ~FLEXCAN_CTRL_ERR_MSK; |
1285 | 1285 | ||
1286 | /* save for later use */ | 1286 | /* save for later use */ |
1287 | priv->reg_ctrl_default = reg_ctrl; | 1287 | priv->reg_ctrl_default = reg_ctrl; |
1288 | /* leave interrupts disabled for now */ | 1288 | /* leave interrupts disabled for now */ |
1289 | reg_ctrl &= ~FLEXCAN_CTRL_ERR_ALL; | 1289 | reg_ctrl &= ~FLEXCAN_CTRL_ERR_ALL; |
1290 | netdev_dbg(dev, "%s: writing ctrl=0x%08x", __func__, reg_ctrl); | 1290 | netdev_dbg(dev, "%s: writing ctrl=0x%08x", __func__, reg_ctrl); |
1291 | flexcan_write(reg_ctrl, ®s->ctrl); | 1291 | flexcan_write(reg_ctrl, ®s->ctrl); |
1292 | 1292 | ||
1293 | if ((priv->devtype_data->quirks & FLEXCAN_QUIRK_ENABLE_EACEN_RRS)) { | 1293 | if ((priv->devtype_data->quirks & FLEXCAN_QUIRK_ENABLE_EACEN_RRS)) { |
1294 | reg_ctrl2 = flexcan_read(®s->ctrl2); | 1294 | reg_ctrl2 = flexcan_read(®s->ctrl2); |
1295 | reg_ctrl2 |= FLEXCAN_CTRL2_EACEN | FLEXCAN_CTRL2_RRS; | 1295 | reg_ctrl2 |= FLEXCAN_CTRL2_EACEN | FLEXCAN_CTRL2_RRS; |
1296 | flexcan_write(reg_ctrl2, ®s->ctrl2); | 1296 | flexcan_write(reg_ctrl2, ®s->ctrl2); |
1297 | } | 1297 | } |
1298 | 1298 | ||
1299 | /* CAN FD initialization | 1299 | /* CAN FD initialization |
1300 | * | 1300 | * |
1301 | * disable BRS by default | 1301 | * disable BRS by default |
1302 | * Message Buffer Data Size 64 bytes per MB | 1302 | * Message Buffer Data Size 64 bytes per MB |
1303 | * disable Transceiver Delay Compensation | 1303 | * disable Transceiver Delay Compensation |
1304 | * Configure Message Buffer according to CAN FD mode enabled or not | 1304 | * Configure Message Buffer according to CAN FD mode enabled or not |
1305 | */ | 1305 | */ |
1306 | if (priv->can.ctrlmode & CAN_CTRLMODE_FD) { | 1306 | if (priv->can.ctrlmode & CAN_CTRLMODE_FD) { |
1307 | reg_fdctrl = flexcan_read(®s->fdctrl) & | 1307 | reg_fdctrl = flexcan_read(®s->fdctrl) & |
1308 | ~FLEXCAN_CANFD_MBDSR_MASK; | 1308 | ~FLEXCAN_CANFD_MBDSR_MASK; |
1309 | reg_fdctrl |= FLEXCAN_CANFD_MBDSR_DEFAULT << | 1309 | reg_fdctrl |= FLEXCAN_CANFD_MBDSR_DEFAULT << |
1310 | FLEXCAN_CANFD_MBDSR_SHIFT; | 1310 | FLEXCAN_CANFD_MBDSR_SHIFT; |
1311 | flexcan_write(reg_fdctrl, ®s->fdctrl); | 1311 | flexcan_write(reg_fdctrl, ®s->fdctrl); |
1312 | reg_mcr = flexcan_read(®s->mcr); | 1312 | reg_mcr = flexcan_read(®s->mcr); |
1313 | flexcan_write(reg_mcr | FLEXCAN_MCR_FDEN, ®s->mcr); | 1313 | flexcan_write(reg_mcr | FLEXCAN_MCR_FDEN, ®s->mcr); |
1314 | 1314 | ||
1315 | if (!(priv->can.ctrlmode & CAN_CTRLMODE_FD_NON_ISO)) { | 1315 | if (!(priv->can.ctrlmode & CAN_CTRLMODE_FD_NON_ISO)) { |
1316 | reg_ctrl2 = flexcan_read(®s->ctrl2); | 1316 | reg_ctrl2 = flexcan_read(®s->ctrl2); |
1317 | flexcan_write(reg_ctrl2 | FLEXCAN_CTRL2_ISOCANFDEN, ®s->ctrl2); | 1317 | flexcan_write(reg_ctrl2 | FLEXCAN_CTRL2_ISOCANFDEN, ®s->ctrl2); |
1318 | } | 1318 | } |
1319 | 1319 | ||
1320 | priv->offload.is_canfd = true; | 1320 | priv->offload.is_canfd = true; |
1321 | 1321 | ||
1322 | priv->mb_size = FLEXCAN_MB_FD_SIZE; | 1322 | priv->mb_size = FLEXCAN_MB_FD_SIZE; |
1323 | priv->mb_num = FLEXCAN_MB_FD_NUM; | 1323 | priv->mb_num = FLEXCAN_MB_FD_NUM; |
1324 | } else { | 1324 | } else { |
1325 | priv->offload.is_canfd = false; | ||
1326 | |||
1325 | priv->mb_size = FLEXCAN_MB_SIZE; | 1327 | priv->mb_size = FLEXCAN_MB_SIZE; |
1326 | priv->mb_num = FLEXCAN_MB_NUM; | 1328 | priv->mb_num = FLEXCAN_MB_NUM; |
1327 | } | 1329 | } |
1328 | 1330 | ||
1329 | /* clear and invalidate all mailboxes first */ | 1331 | /* clear and invalidate all mailboxes first */ |
1330 | for (i = priv->tx_mb_idx; i < priv->mb_num ; i++) { | 1332 | for (i = priv->tx_mb_idx; i < priv->mb_num ; i++) { |
1331 | flexcan_mb_write(priv, i, FLEXCAN_MB_CTRL, | 1333 | flexcan_mb_write(priv, i, FLEXCAN_MB_CTRL, |
1332 | FLEXCAN_MB_CODE_RX_INACTIVE); | 1334 | FLEXCAN_MB_CODE_RX_INACTIVE); |
1333 | } | 1335 | } |
1334 | 1336 | ||
1335 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { | 1337 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { |
1336 | for (i = priv->offload.mb_first; i <= priv->offload.mb_last; i++) | 1338 | for (i = priv->offload.mb_first; i <= priv->offload.mb_last; i++) |
1337 | flexcan_mb_write(priv, i, FLEXCAN_MB_CTRL, | 1339 | flexcan_mb_write(priv, i, FLEXCAN_MB_CTRL, |
1338 | FLEXCAN_MB_CODE_RX_EMPTY); | 1340 | FLEXCAN_MB_CODE_RX_EMPTY); |
1339 | } | 1341 | } |
1340 | 1342 | ||
1341 | /* Errata ERR005829: mark first TX mailbox as INACTIVE */ | 1343 | /* Errata ERR005829: mark first TX mailbox as INACTIVE */ |
1342 | flexcan_mb_write(priv, priv->tx_mb_reserved_idx, FLEXCAN_MB_CTRL, | 1344 | flexcan_mb_write(priv, priv->tx_mb_reserved_idx, FLEXCAN_MB_CTRL, |
1343 | FLEXCAN_MB_CODE_TX_INACTIVE); | 1345 | FLEXCAN_MB_CODE_TX_INACTIVE); |
1344 | 1346 | ||
1345 | /* mark TX mailbox as INACTIVE */ | 1347 | /* mark TX mailbox as INACTIVE */ |
1346 | flexcan_mb_write(priv, priv->tx_mb_idx, FLEXCAN_MB_CTRL, | 1348 | flexcan_mb_write(priv, priv->tx_mb_idx, FLEXCAN_MB_CTRL, |
1347 | FLEXCAN_MB_CODE_TX_INACTIVE); | 1349 | FLEXCAN_MB_CODE_TX_INACTIVE); |
1348 | 1350 | ||
1349 | /* acceptance mask/acceptance code (accept everything) */ | 1351 | /* acceptance mask/acceptance code (accept everything) */ |
1350 | flexcan_write(0x0, ®s->rxgmask); | 1352 | flexcan_write(0x0, ®s->rxgmask); |
1351 | flexcan_write(0x0, ®s->rx14mask); | 1353 | flexcan_write(0x0, ®s->rx14mask); |
1352 | flexcan_write(0x0, ®s->rx15mask); | 1354 | flexcan_write(0x0, ®s->rx15mask); |
1353 | 1355 | ||
1354 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_DISABLE_RXFG) | 1356 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_DISABLE_RXFG) |
1355 | flexcan_write(0x0, ®s->rxfgmask); | 1357 | flexcan_write(0x0, ®s->rxfgmask); |
1356 | 1358 | ||
1357 | /* clear acceptance filters */ | 1359 | /* clear acceptance filters */ |
1358 | for (i = priv->tx_mb_idx; i < priv->mb_num ; i++) | 1360 | for (i = priv->tx_mb_idx; i < priv->mb_num ; i++) |
1359 | flexcan_write(0, ®s->rximr[i]); | 1361 | flexcan_write(0, ®s->rximr[i]); |
1360 | 1362 | ||
1361 | /* On Vybrid, disable memory error detection interrupts | 1363 | /* On Vybrid, disable memory error detection interrupts |
1362 | * and freeze mode. | 1364 | * and freeze mode. |
1363 | * This also works around errata e5295 which generates | 1365 | * This also works around errata e5295 which generates |
1364 | * false positive memory errors and put the device in | 1366 | * false positive memory errors and put the device in |
1365 | * freeze mode. | 1367 | * freeze mode. |
1366 | */ | 1368 | */ |
1367 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_DISABLE_MECR) { | 1369 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_DISABLE_MECR) { |
1368 | /* Follow the protocol as described in "Detection | 1370 | /* Follow the protocol as described in "Detection |
1369 | * and Correction of Memory Errors" to write to | 1371 | * and Correction of Memory Errors" to write to |
1370 | * MECR register | 1372 | * MECR register |
1371 | */ | 1373 | */ |
1372 | reg_ctrl2 = flexcan_read(®s->ctrl2); | 1374 | reg_ctrl2 = flexcan_read(®s->ctrl2); |
1373 | reg_ctrl2 |= FLEXCAN_CTRL2_ECRWRE; | 1375 | reg_ctrl2 |= FLEXCAN_CTRL2_ECRWRE; |
1374 | flexcan_write(reg_ctrl2, ®s->ctrl2); | 1376 | flexcan_write(reg_ctrl2, ®s->ctrl2); |
1375 | 1377 | ||
1376 | reg_mecr = flexcan_read(®s->mecr); | 1378 | reg_mecr = flexcan_read(®s->mecr); |
1377 | reg_mecr &= ~FLEXCAN_MECR_ECRWRDIS; | 1379 | reg_mecr &= ~FLEXCAN_MECR_ECRWRDIS; |
1378 | flexcan_write(reg_mecr, ®s->mecr); | 1380 | flexcan_write(reg_mecr, ®s->mecr); |
1379 | reg_mecr &= ~(FLEXCAN_MECR_NCEFAFRZ | FLEXCAN_MECR_HANCEI_MSK | | 1381 | reg_mecr &= ~(FLEXCAN_MECR_NCEFAFRZ | FLEXCAN_MECR_HANCEI_MSK | |
1380 | FLEXCAN_MECR_FANCEI_MSK); | 1382 | FLEXCAN_MECR_FANCEI_MSK); |
1381 | flexcan_write(reg_mecr, ®s->mecr); | 1383 | flexcan_write(reg_mecr, ®s->mecr); |
1382 | } | 1384 | } |
1383 | 1385 | ||
1384 | err = flexcan_transceiver_enable(priv); | 1386 | err = flexcan_transceiver_enable(priv); |
1385 | if (err) | 1387 | if (err) |
1386 | goto out_chip_disable; | 1388 | goto out_chip_disable; |
1387 | 1389 | ||
1388 | /* synchronize with the can bus */ | 1390 | /* synchronize with the can bus */ |
1389 | err = flexcan_chip_unfreeze(priv); | 1391 | err = flexcan_chip_unfreeze(priv); |
1390 | if (err) | 1392 | if (err) |
1391 | goto out_transceiver_disable; | 1393 | goto out_transceiver_disable; |
1392 | 1394 | ||
1393 | priv->can.state = CAN_STATE_ERROR_ACTIVE; | 1395 | priv->can.state = CAN_STATE_ERROR_ACTIVE; |
1394 | 1396 | ||
1395 | /* enable interrupts atomically */ | 1397 | /* enable interrupts atomically */ |
1396 | disable_irq(dev->irq); | 1398 | disable_irq(dev->irq); |
1397 | flexcan_write(priv->reg_ctrl_default, ®s->ctrl); | 1399 | flexcan_write(priv->reg_ctrl_default, ®s->ctrl); |
1398 | flexcan_write(priv->reg_imask1_default, ®s->imask1); | 1400 | flexcan_write(priv->reg_imask1_default, ®s->imask1); |
1399 | flexcan_write(priv->reg_imask2_default, ®s->imask2); | 1401 | flexcan_write(priv->reg_imask2_default, ®s->imask2); |
1400 | enable_irq(dev->irq); | 1402 | enable_irq(dev->irq); |
1401 | 1403 | ||
1402 | /* print chip status */ | 1404 | /* print chip status */ |
1403 | netdev_dbg(dev, "%s: reading mcr=0x%08x ctrl=0x%08x\n", __func__, | 1405 | netdev_dbg(dev, "%s: reading mcr=0x%08x ctrl=0x%08x\n", __func__, |
1404 | flexcan_read(®s->mcr), flexcan_read(®s->ctrl)); | 1406 | flexcan_read(®s->mcr), flexcan_read(®s->ctrl)); |
1405 | 1407 | ||
1406 | return 0; | 1408 | return 0; |
1407 | 1409 | ||
1408 | out_transceiver_disable: | 1410 | out_transceiver_disable: |
1409 | flexcan_transceiver_disable(priv); | 1411 | flexcan_transceiver_disable(priv); |
1410 | out_chip_disable: | 1412 | out_chip_disable: |
1411 | flexcan_chip_disable(priv); | 1413 | flexcan_chip_disable(priv); |
1412 | 1414 | ||
1413 | return err; | 1415 | return err; |
1414 | } | 1416 | } |
1415 | 1417 | ||
1416 | /* flexcan_chip_stop | 1418 | /* flexcan_chip_stop |
1417 | * | 1419 | * |
1418 | * this functions is entered with clocks enabled | 1420 | * this functions is entered with clocks enabled |
1419 | */ | 1421 | */ |
1420 | static void flexcan_chip_stop(struct net_device *dev) | 1422 | static void flexcan_chip_stop(struct net_device *dev) |
1421 | { | 1423 | { |
1422 | struct flexcan_priv *priv = netdev_priv(dev); | 1424 | struct flexcan_priv *priv = netdev_priv(dev); |
1423 | struct flexcan_regs __iomem *regs = priv->regs; | 1425 | struct flexcan_regs __iomem *regs = priv->regs; |
1424 | 1426 | ||
1425 | /* freeze + disable module */ | 1427 | /* freeze + disable module */ |
1426 | flexcan_chip_freeze(priv); | 1428 | flexcan_chip_freeze(priv); |
1427 | flexcan_chip_disable(priv); | 1429 | flexcan_chip_disable(priv); |
1428 | 1430 | ||
1429 | /* Disable all interrupts */ | 1431 | /* Disable all interrupts */ |
1430 | flexcan_write(0, ®s->imask2); | 1432 | flexcan_write(0, ®s->imask2); |
1431 | flexcan_write(0, ®s->imask1); | 1433 | flexcan_write(0, ®s->imask1); |
1432 | flexcan_write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL, | 1434 | flexcan_write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL, |
1433 | ®s->ctrl); | 1435 | ®s->ctrl); |
1434 | 1436 | ||
1435 | flexcan_transceiver_disable(priv); | 1437 | flexcan_transceiver_disable(priv); |
1436 | priv->can.state = CAN_STATE_STOPPED; | 1438 | priv->can.state = CAN_STATE_STOPPED; |
1437 | } | 1439 | } |
1438 | 1440 | ||
1439 | static int flexcan_open(struct net_device *dev) | 1441 | static int flexcan_open(struct net_device *dev) |
1440 | { | 1442 | { |
1441 | struct flexcan_priv *priv = netdev_priv(dev); | 1443 | struct flexcan_priv *priv = netdev_priv(dev); |
1442 | int err; | 1444 | int err; |
1443 | 1445 | ||
1444 | err = pm_runtime_get_sync(priv->dev); | 1446 | err = pm_runtime_get_sync(priv->dev); |
1445 | if (err) | 1447 | if (err) |
1446 | return err; | 1448 | return err; |
1447 | 1449 | ||
1448 | err = open_candev(dev); | 1450 | err = open_candev(dev); |
1449 | if (err) | 1451 | if (err) |
1450 | goto out_pm_runtime; | 1452 | goto out_pm_runtime; |
1451 | 1453 | ||
1452 | err = request_irq(dev->irq, flexcan_irq, IRQF_SHARED, dev->name, dev); | 1454 | err = request_irq(dev->irq, flexcan_irq, IRQF_SHARED, dev->name, dev); |
1453 | if (err) | 1455 | if (err) |
1454 | goto out_close; | 1456 | goto out_close; |
1455 | 1457 | ||
1456 | /* start chip and queuing */ | 1458 | /* start chip and queuing */ |
1457 | err = flexcan_chip_start(dev); | 1459 | err = flexcan_chip_start(dev); |
1458 | if (err) | 1460 | if (err) |
1459 | goto out_free_irq; | 1461 | goto out_free_irq; |
1460 | 1462 | ||
1461 | device_set_wakeup_capable(priv->dev, priv->wakeup); | 1463 | device_set_wakeup_capable(priv->dev, priv->wakeup); |
1462 | 1464 | ||
1463 | can_led_event(dev, CAN_LED_EVENT_OPEN); | 1465 | can_led_event(dev, CAN_LED_EVENT_OPEN); |
1464 | 1466 | ||
1465 | can_rx_offload_enable(&priv->offload); | 1467 | can_rx_offload_enable(&priv->offload); |
1466 | netif_start_queue(dev); | 1468 | netif_start_queue(dev); |
1467 | 1469 | ||
1468 | return 0; | 1470 | return 0; |
1469 | 1471 | ||
1470 | out_free_irq: | 1472 | out_free_irq: |
1471 | free_irq(dev->irq, dev); | 1473 | free_irq(dev->irq, dev); |
1472 | out_close: | 1474 | out_close: |
1473 | close_candev(dev); | 1475 | close_candev(dev); |
1474 | 1476 | ||
1475 | out_pm_runtime: | 1477 | out_pm_runtime: |
1476 | pm_runtime_put(priv->dev); | 1478 | pm_runtime_put(priv->dev); |
1477 | 1479 | ||
1478 | return err; | 1480 | return err; |
1479 | } | 1481 | } |
1480 | 1482 | ||
1481 | static int flexcan_close(struct net_device *dev) | 1483 | static int flexcan_close(struct net_device *dev) |
1482 | { | 1484 | { |
1483 | struct flexcan_priv *priv = netdev_priv(dev); | 1485 | struct flexcan_priv *priv = netdev_priv(dev); |
1484 | 1486 | ||
1485 | netif_stop_queue(dev); | 1487 | netif_stop_queue(dev); |
1486 | can_rx_offload_disable(&priv->offload); | 1488 | can_rx_offload_disable(&priv->offload); |
1487 | flexcan_chip_stop(dev); | 1489 | flexcan_chip_stop(dev); |
1488 | 1490 | ||
1489 | free_irq(dev->irq, dev); | 1491 | free_irq(dev->irq, dev); |
1490 | 1492 | ||
1491 | close_candev(dev); | 1493 | close_candev(dev); |
1492 | 1494 | ||
1493 | device_set_wakeup_capable(priv->dev, false); | 1495 | device_set_wakeup_capable(priv->dev, false); |
1494 | 1496 | ||
1495 | can_led_event(dev, CAN_LED_EVENT_STOP); | 1497 | can_led_event(dev, CAN_LED_EVENT_STOP); |
1496 | 1498 | ||
1497 | pm_runtime_put(priv->dev); | 1499 | pm_runtime_put(priv->dev); |
1498 | 1500 | ||
1499 | return 0; | 1501 | return 0; |
1500 | } | 1502 | } |
1501 | 1503 | ||
1502 | static int flexcan_set_mode(struct net_device *dev, enum can_mode mode) | 1504 | static int flexcan_set_mode(struct net_device *dev, enum can_mode mode) |
1503 | { | 1505 | { |
1504 | int err; | 1506 | int err; |
1505 | 1507 | ||
1506 | switch (mode) { | 1508 | switch (mode) { |
1507 | case CAN_MODE_START: | 1509 | case CAN_MODE_START: |
1508 | err = flexcan_chip_start(dev); | 1510 | err = flexcan_chip_start(dev); |
1509 | if (err) | 1511 | if (err) |
1510 | return err; | 1512 | return err; |
1511 | 1513 | ||
1512 | netif_wake_queue(dev); | 1514 | netif_wake_queue(dev); |
1513 | break; | 1515 | break; |
1514 | 1516 | ||
1515 | default: | 1517 | default: |
1516 | return -EOPNOTSUPP; | 1518 | return -EOPNOTSUPP; |
1517 | } | 1519 | } |
1518 | 1520 | ||
1519 | return 0; | 1521 | return 0; |
1520 | } | 1522 | } |
1521 | 1523 | ||
1522 | static const struct net_device_ops flexcan_netdev_ops = { | 1524 | static const struct net_device_ops flexcan_netdev_ops = { |
1523 | .ndo_open = flexcan_open, | 1525 | .ndo_open = flexcan_open, |
1524 | .ndo_stop = flexcan_close, | 1526 | .ndo_stop = flexcan_close, |
1525 | .ndo_start_xmit = flexcan_start_xmit, | 1527 | .ndo_start_xmit = flexcan_start_xmit, |
1526 | .ndo_change_mtu = can_change_mtu, | 1528 | .ndo_change_mtu = can_change_mtu, |
1527 | }; | 1529 | }; |
1528 | 1530 | ||
1529 | static int register_flexcandev(struct net_device *dev) | 1531 | static int register_flexcandev(struct net_device *dev) |
1530 | { | 1532 | { |
1531 | struct flexcan_priv *priv = netdev_priv(dev); | 1533 | struct flexcan_priv *priv = netdev_priv(dev); |
1532 | struct flexcan_regs __iomem *regs = priv->regs; | 1534 | struct flexcan_regs __iomem *regs = priv->regs; |
1533 | u32 reg, err; | 1535 | u32 reg, err; |
1534 | 1536 | ||
1535 | /* select "bus clock", chip must be disabled */ | 1537 | /* select "bus clock", chip must be disabled */ |
1536 | err = flexcan_chip_disable(priv); | 1538 | err = flexcan_chip_disable(priv); |
1537 | if (err) | 1539 | if (err) |
1538 | return err; | 1540 | return err; |
1539 | 1541 | ||
1540 | if (priv->clk_src) { | 1542 | if (priv->clk_src) { |
1541 | reg = flexcan_read(®s->ctrl); | 1543 | reg = flexcan_read(®s->ctrl); |
1542 | reg |= FLEXCAN_CTRL_CLK_SRC; | 1544 | reg |= FLEXCAN_CTRL_CLK_SRC; |
1543 | flexcan_write(reg, ®s->ctrl); | 1545 | flexcan_write(reg, ®s->ctrl); |
1544 | } | 1546 | } |
1545 | 1547 | ||
1546 | err = flexcan_chip_enable(priv); | 1548 | err = flexcan_chip_enable(priv); |
1547 | if (err) | 1549 | if (err) |
1548 | goto out_chip_disable; | 1550 | goto out_chip_disable; |
1549 | 1551 | ||
1550 | /* set freeze, halt and activate FIFO, restrict register access */ | 1552 | /* set freeze, halt and activate FIFO, restrict register access */ |
1551 | reg = flexcan_read(®s->mcr); | 1553 | reg = flexcan_read(®s->mcr); |
1552 | reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | | 1554 | reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | |
1553 | FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV; | 1555 | FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV; |
1554 | flexcan_write(reg, ®s->mcr); | 1556 | flexcan_write(reg, ®s->mcr); |
1555 | 1557 | ||
1556 | /* Currently we only support newer versions of this core | 1558 | /* Currently we only support newer versions of this core |
1557 | * featuring a RX hardware FIFO (although this driver doesn't | 1559 | * featuring a RX hardware FIFO (although this driver doesn't |
1558 | * make use of it on some cores). Older cores, found on some | 1560 | * make use of it on some cores). Older cores, found on some |
1559 | * Coldfire derivates are not tested. | 1561 | * Coldfire derivates are not tested. |
1560 | */ | 1562 | */ |
1561 | reg = flexcan_read(®s->mcr); | 1563 | reg = flexcan_read(®s->mcr); |
1562 | if (!(reg & FLEXCAN_MCR_FEN)) { | 1564 | if (!(reg & FLEXCAN_MCR_FEN)) { |
1563 | netdev_err(dev, "Could not enable RX FIFO, unsupported core\n"); | 1565 | netdev_err(dev, "Could not enable RX FIFO, unsupported core\n"); |
1564 | err = -ENODEV; | 1566 | err = -ENODEV; |
1565 | goto out_chip_disable; | 1567 | goto out_chip_disable; |
1566 | } | 1568 | } |
1567 | 1569 | ||
1568 | err = register_candev(dev); | 1570 | err = register_candev(dev); |
1569 | 1571 | ||
1570 | /* disable core and turn off clocks */ | 1572 | /* disable core and turn off clocks */ |
1571 | out_chip_disable: | 1573 | out_chip_disable: |
1572 | flexcan_chip_disable(priv); | 1574 | flexcan_chip_disable(priv); |
1573 | 1575 | ||
1574 | return err; | 1576 | return err; |
1575 | } | 1577 | } |
1576 | 1578 | ||
1577 | static void unregister_flexcandev(struct net_device *dev) | 1579 | static void unregister_flexcandev(struct net_device *dev) |
1578 | { | 1580 | { |
1579 | unregister_candev(dev); | 1581 | unregister_candev(dev); |
1580 | } | 1582 | } |
1581 | 1583 | ||
1582 | #ifdef CONFIG_ARCH_MXC_ARM64 | 1584 | #ifdef CONFIG_ARCH_MXC_ARM64 |
1583 | static int imx8_sc_ipc_fetch(struct platform_device *pdev) | 1585 | static int imx8_sc_ipc_fetch(struct platform_device *pdev) |
1584 | { | 1586 | { |
1585 | struct net_device *dev = platform_get_drvdata(pdev); | 1587 | struct net_device *dev = platform_get_drvdata(pdev); |
1586 | struct flexcan_priv *priv; | 1588 | struct flexcan_priv *priv; |
1587 | sc_err_t sc_err = SC_ERR_NONE; | 1589 | sc_err_t sc_err = SC_ERR_NONE; |
1588 | u32 mu_id; | 1590 | u32 mu_id; |
1589 | 1591 | ||
1590 | priv = netdev_priv(dev); | 1592 | priv = netdev_priv(dev); |
1591 | 1593 | ||
1592 | sc_err = sc_ipc_getMuID(&mu_id); | 1594 | sc_err = sc_ipc_getMuID(&mu_id); |
1593 | if (sc_err != SC_ERR_NONE) { | 1595 | if (sc_err != SC_ERR_NONE) { |
1594 | pr_err("FLEXCAN ipg stop: Get MU ID failed\n"); | 1596 | pr_err("FLEXCAN ipg stop: Get MU ID failed\n"); |
1595 | return sc_err; | 1597 | return sc_err; |
1596 | } | 1598 | } |
1597 | 1599 | ||
1598 | sc_err = sc_ipc_open(&priv->ipc_handle, mu_id); | 1600 | sc_err = sc_ipc_open(&priv->ipc_handle, mu_id); |
1599 | if (sc_err != SC_ERR_NONE) { | 1601 | if (sc_err != SC_ERR_NONE) { |
1600 | pr_err("FLEXCAN ipg stop: Open MU channel failed\n"); | 1602 | pr_err("FLEXCAN ipg stop: Open MU channel failed\n"); |
1601 | return sc_err; | 1603 | return sc_err; |
1602 | } | 1604 | } |
1603 | 1605 | ||
1604 | return sc_err; | 1606 | return sc_err; |
1605 | } | 1607 | } |
1606 | #else | 1608 | #else |
1607 | static int imx8_sc_ipc_fetch(struct platform_device *pdev) { return 0; } | 1609 | static int imx8_sc_ipc_fetch(struct platform_device *pdev) { return 0; } |
1608 | #endif | 1610 | #endif |
1609 | 1611 | ||
1610 | static int flexcan_of_parse_stop_mode(struct platform_device *pdev) | 1612 | static int flexcan_of_parse_stop_mode(struct platform_device *pdev) |
1611 | { | 1613 | { |
1612 | struct net_device *dev = platform_get_drvdata(pdev); | 1614 | struct net_device *dev = platform_get_drvdata(pdev); |
1613 | struct device_node *np = pdev->dev.of_node; | 1615 | struct device_node *np = pdev->dev.of_node; |
1614 | struct device_node *node; | 1616 | struct device_node *node; |
1615 | struct flexcan_priv *priv; | 1617 | struct flexcan_priv *priv; |
1616 | phandle phandle; | 1618 | phandle phandle; |
1617 | u32 out_val[5]; | 1619 | u32 out_val[5]; |
1618 | int ret; | 1620 | int ret; |
1619 | 1621 | ||
1620 | if (!np) | 1622 | if (!np) |
1621 | return -EINVAL; | 1623 | return -EINVAL; |
1622 | /* | 1624 | /* |
1623 | * stop mode property format is: | 1625 | * stop mode property format is: |
1624 | * <&gpr req_gpr req_bit ack_gpr ack_bit>. | 1626 | * <&gpr req_gpr req_bit ack_gpr ack_bit>. |
1625 | */ | 1627 | */ |
1626 | ret = of_property_read_u32_array(np, "stop-mode", out_val, 5); | 1628 | ret = of_property_read_u32_array(np, "stop-mode", out_val, 5); |
1627 | if (ret) { | 1629 | if (ret) { |
1628 | dev_dbg(&pdev->dev, "no stop-mode property\n"); | 1630 | dev_dbg(&pdev->dev, "no stop-mode property\n"); |
1629 | return ret; | 1631 | return ret; |
1630 | } | 1632 | } |
1631 | phandle = *out_val; | 1633 | phandle = *out_val; |
1632 | 1634 | ||
1633 | node = of_find_node_by_phandle(phandle); | 1635 | node = of_find_node_by_phandle(phandle); |
1634 | if (!node) { | 1636 | if (!node) { |
1635 | dev_dbg(&pdev->dev, "could not find gpr node by phandle\n"); | 1637 | dev_dbg(&pdev->dev, "could not find gpr node by phandle\n"); |
1636 | return PTR_ERR(node); | 1638 | return PTR_ERR(node); |
1637 | } | 1639 | } |
1638 | 1640 | ||
1639 | priv = netdev_priv(dev); | 1641 | priv = netdev_priv(dev); |
1640 | priv->stm.gpr = syscon_node_to_regmap(node); | 1642 | priv->stm.gpr = syscon_node_to_regmap(node); |
1641 | if (IS_ERR(priv->stm.gpr)) { | 1643 | if (IS_ERR(priv->stm.gpr)) { |
1642 | dev_dbg(&pdev->dev, "could not find gpr regmap\n"); | 1644 | dev_dbg(&pdev->dev, "could not find gpr regmap\n"); |
1643 | return PTR_ERR(priv->stm.gpr); | 1645 | return PTR_ERR(priv->stm.gpr); |
1644 | } | 1646 | } |
1645 | 1647 | ||
1646 | of_node_put(node); | 1648 | of_node_put(node); |
1647 | 1649 | ||
1648 | priv->stm.req_gpr = out_val[1]; | 1650 | priv->stm.req_gpr = out_val[1]; |
1649 | priv->stm.req_bit = out_val[2]; | 1651 | priv->stm.req_bit = out_val[2]; |
1650 | priv->stm.ack_gpr = out_val[3]; | 1652 | priv->stm.ack_gpr = out_val[3]; |
1651 | priv->stm.ack_bit = out_val[4]; | 1653 | priv->stm.ack_bit = out_val[4]; |
1652 | 1654 | ||
1653 | dev_dbg(&pdev->dev, "gpr %s req_gpr 0x%x req_bit %u ack_gpr 0x%x ack_bit %u\n", | 1655 | dev_dbg(&pdev->dev, "gpr %s req_gpr 0x%x req_bit %u ack_gpr 0x%x ack_bit %u\n", |
1654 | node->full_name, priv->stm.req_gpr, | 1656 | node->full_name, priv->stm.req_gpr, |
1655 | priv->stm.req_bit, priv->stm.ack_gpr, | 1657 | priv->stm.req_bit, priv->stm.ack_gpr, |
1656 | priv->stm.ack_bit); | 1658 | priv->stm.ack_bit); |
1657 | return 0; | 1659 | return 0; |
1658 | } | 1660 | } |
1659 | 1661 | ||
1660 | static const struct of_device_id flexcan_of_match[] = { | 1662 | static const struct of_device_id flexcan_of_match[] = { |
1661 | { .compatible = "fsl,imx8qm-flexcan", .data = &fsl_imx8qm_devtype_data, }, | 1663 | { .compatible = "fsl,imx8qm-flexcan", .data = &fsl_imx8qm_devtype_data, }, |
1662 | { .compatible = "fsl,imx6q-flexcan", .data = &fsl_imx6q_devtype_data, }, | 1664 | { .compatible = "fsl,imx6q-flexcan", .data = &fsl_imx6q_devtype_data, }, |
1663 | { .compatible = "fsl,imx28-flexcan", .data = &fsl_imx28_devtype_data, }, | 1665 | { .compatible = "fsl,imx28-flexcan", .data = &fsl_imx28_devtype_data, }, |
1664 | { .compatible = "fsl,p1010-flexcan", .data = &fsl_p1010_devtype_data, }, | 1666 | { .compatible = "fsl,p1010-flexcan", .data = &fsl_p1010_devtype_data, }, |
1665 | { .compatible = "fsl,vf610-flexcan", .data = &fsl_vf610_devtype_data, }, | 1667 | { .compatible = "fsl,vf610-flexcan", .data = &fsl_vf610_devtype_data, }, |
1666 | { /* sentinel */ }, | 1668 | { /* sentinel */ }, |
1667 | }; | 1669 | }; |
1668 | MODULE_DEVICE_TABLE(of, flexcan_of_match); | 1670 | MODULE_DEVICE_TABLE(of, flexcan_of_match); |
1669 | 1671 | ||
1670 | static const struct platform_device_id flexcan_id_table[] = { | 1672 | static const struct platform_device_id flexcan_id_table[] = { |
1671 | { .name = "flexcan", .driver_data = (kernel_ulong_t)&fsl_p1010_devtype_data, }, | 1673 | { .name = "flexcan", .driver_data = (kernel_ulong_t)&fsl_p1010_devtype_data, }, |
1672 | { /* sentinel */ }, | 1674 | { /* sentinel */ }, |
1673 | }; | 1675 | }; |
1674 | MODULE_DEVICE_TABLE(platform, flexcan_id_table); | 1676 | MODULE_DEVICE_TABLE(platform, flexcan_id_table); |
1675 | 1677 | ||
1676 | static int flexcan_probe(struct platform_device *pdev) | 1678 | static int flexcan_probe(struct platform_device *pdev) |
1677 | { | 1679 | { |
1678 | const struct of_device_id *of_id; | 1680 | const struct of_device_id *of_id; |
1679 | const struct flexcan_devtype_data *devtype_data; | 1681 | const struct flexcan_devtype_data *devtype_data; |
1680 | struct net_device *dev; | 1682 | struct net_device *dev; |
1681 | struct flexcan_priv *priv; | 1683 | struct flexcan_priv *priv; |
1682 | struct regulator *reg_xceiver; | 1684 | struct regulator *reg_xceiver; |
1683 | struct resource *mem; | 1685 | struct resource *mem; |
1684 | struct clk *clk_ipg = NULL, *clk_per = NULL; | 1686 | struct clk *clk_ipg = NULL, *clk_per = NULL; |
1685 | struct flexcan_regs __iomem *regs; | 1687 | struct flexcan_regs __iomem *regs; |
1686 | int err, irq; | 1688 | int err, irq; |
1687 | u32 clock_freq = 0; | 1689 | u32 clock_freq = 0; |
1688 | u32 clk_src = 1; | 1690 | u32 clk_src = 1; |
1689 | 1691 | ||
1690 | reg_xceiver = devm_regulator_get(&pdev->dev, "xceiver"); | 1692 | reg_xceiver = devm_regulator_get(&pdev->dev, "xceiver"); |
1691 | if (PTR_ERR(reg_xceiver) == -EPROBE_DEFER) | 1693 | if (PTR_ERR(reg_xceiver) == -EPROBE_DEFER) |
1692 | return -EPROBE_DEFER; | 1694 | return -EPROBE_DEFER; |
1693 | else if (IS_ERR(reg_xceiver)) | 1695 | else if (IS_ERR(reg_xceiver)) |
1694 | reg_xceiver = NULL; | 1696 | reg_xceiver = NULL; |
1695 | 1697 | ||
1696 | if (pdev->dev.of_node) { | 1698 | if (pdev->dev.of_node) { |
1697 | of_property_read_u32(pdev->dev.of_node, | 1699 | of_property_read_u32(pdev->dev.of_node, |
1698 | "clock-frequency", &clock_freq); | 1700 | "clock-frequency", &clock_freq); |
1699 | of_property_read_u32(pdev->dev.of_node, | 1701 | of_property_read_u32(pdev->dev.of_node, |
1700 | "clk-src", &clk_src); | 1702 | "clk-src", &clk_src); |
1701 | } | 1703 | } |
1702 | 1704 | ||
1703 | if (!clock_freq) { | 1705 | if (!clock_freq) { |
1704 | clk_ipg = devm_clk_get(&pdev->dev, "ipg"); | 1706 | clk_ipg = devm_clk_get(&pdev->dev, "ipg"); |
1705 | if (IS_ERR(clk_ipg)) { | 1707 | if (IS_ERR(clk_ipg)) { |
1706 | dev_err(&pdev->dev, "no ipg clock defined\n"); | 1708 | dev_err(&pdev->dev, "no ipg clock defined\n"); |
1707 | return PTR_ERR(clk_ipg); | 1709 | return PTR_ERR(clk_ipg); |
1708 | } | 1710 | } |
1709 | 1711 | ||
1710 | clk_per = devm_clk_get(&pdev->dev, "per"); | 1712 | clk_per = devm_clk_get(&pdev->dev, "per"); |
1711 | if (IS_ERR(clk_per)) { | 1713 | if (IS_ERR(clk_per)) { |
1712 | dev_err(&pdev->dev, "no per clock defined\n"); | 1714 | dev_err(&pdev->dev, "no per clock defined\n"); |
1713 | return PTR_ERR(clk_per); | 1715 | return PTR_ERR(clk_per); |
1714 | } | 1716 | } |
1715 | clock_freq = clk_get_rate(clk_per); | 1717 | clock_freq = clk_get_rate(clk_per); |
1716 | } | 1718 | } |
1717 | 1719 | ||
1718 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1720 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1719 | irq = platform_get_irq(pdev, 0); | 1721 | irq = platform_get_irq(pdev, 0); |
1720 | if (irq <= 0) | 1722 | if (irq <= 0) |
1721 | return -ENODEV; | 1723 | return -ENODEV; |
1722 | 1724 | ||
1723 | regs = devm_ioremap_resource(&pdev->dev, mem); | 1725 | regs = devm_ioremap_resource(&pdev->dev, mem); |
1724 | if (IS_ERR(regs)) | 1726 | if (IS_ERR(regs)) |
1725 | return PTR_ERR(regs); | 1727 | return PTR_ERR(regs); |
1726 | 1728 | ||
1727 | of_id = of_match_device(flexcan_of_match, &pdev->dev); | 1729 | of_id = of_match_device(flexcan_of_match, &pdev->dev); |
1728 | if (of_id) { | 1730 | if (of_id) { |
1729 | devtype_data = of_id->data; | 1731 | devtype_data = of_id->data; |
1730 | } else if (platform_get_device_id(pdev)->driver_data) { | 1732 | } else if (platform_get_device_id(pdev)->driver_data) { |
1731 | devtype_data = (struct flexcan_devtype_data *) | 1733 | devtype_data = (struct flexcan_devtype_data *) |
1732 | platform_get_device_id(pdev)->driver_data; | 1734 | platform_get_device_id(pdev)->driver_data; |
1733 | } else { | 1735 | } else { |
1734 | return -ENODEV; | 1736 | return -ENODEV; |
1735 | } | 1737 | } |
1736 | 1738 | ||
1737 | dev = alloc_candev(sizeof(struct flexcan_priv), 1); | 1739 | dev = alloc_candev(sizeof(struct flexcan_priv), 1); |
1738 | if (!dev) | 1740 | if (!dev) |
1739 | return -ENOMEM; | 1741 | return -ENOMEM; |
1740 | 1742 | ||
1741 | platform_set_drvdata(pdev, dev); | 1743 | platform_set_drvdata(pdev, dev); |
1742 | SET_NETDEV_DEV(dev, &pdev->dev); | 1744 | SET_NETDEV_DEV(dev, &pdev->dev); |
1743 | 1745 | ||
1744 | dev->netdev_ops = &flexcan_netdev_ops; | 1746 | dev->netdev_ops = &flexcan_netdev_ops; |
1745 | dev->irq = irq; | 1747 | dev->irq = irq; |
1746 | dev->flags |= IFF_ECHO; | 1748 | dev->flags |= IFF_ECHO; |
1747 | 1749 | ||
1748 | priv = netdev_priv(dev); | 1750 | priv = netdev_priv(dev); |
1749 | priv->dev = &pdev->dev; | 1751 | priv->dev = &pdev->dev; |
1750 | priv->clk_src = clk_src; | 1752 | priv->clk_src = clk_src; |
1751 | priv->can.clock.freq = clock_freq; | 1753 | priv->can.clock.freq = clock_freq; |
1752 | priv->can.bittiming_const = &flexcan_bittiming_const; | 1754 | priv->can.bittiming_const = &flexcan_bittiming_const; |
1753 | priv->can.data_bittiming_const = &flexcan_fd_data_bittiming_const; | 1755 | priv->can.data_bittiming_const = &flexcan_fd_data_bittiming_const; |
1754 | priv->can.do_set_mode = flexcan_set_mode; | 1756 | priv->can.do_set_mode = flexcan_set_mode; |
1755 | priv->can.do_get_berr_counter = flexcan_get_berr_counter; | 1757 | priv->can.do_get_berr_counter = flexcan_get_berr_counter; |
1756 | priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK | | 1758 | priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK | |
1757 | CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_3_SAMPLES | | 1759 | CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_3_SAMPLES | |
1758 | CAN_CTRLMODE_BERR_REPORTING; | 1760 | CAN_CTRLMODE_BERR_REPORTING; |
1759 | priv->regs = regs; | 1761 | priv->regs = regs; |
1760 | priv->base = regs; | 1762 | priv->base = regs; |
1761 | priv->clk_ipg = clk_ipg; | 1763 | priv->clk_ipg = clk_ipg; |
1762 | priv->clk_per = clk_per; | 1764 | priv->clk_per = clk_per; |
1763 | priv->pdata = dev_get_platdata(&pdev->dev); | 1765 | priv->pdata = dev_get_platdata(&pdev->dev); |
1764 | priv->devtype_data = devtype_data; | 1766 | priv->devtype_data = devtype_data; |
1765 | priv->reg_xceiver = reg_xceiver; | 1767 | priv->reg_xceiver = reg_xceiver; |
1766 | priv->offload.is_canfd = false; | 1768 | priv->offload.is_canfd = false; |
1767 | 1769 | ||
1768 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { | 1770 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { |
1769 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_TIMESTAMP_SUPPORT_FD) { | 1771 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_TIMESTAMP_SUPPORT_FD) { |
1770 | priv->can.ctrlmode_supported |= CAN_CTRLMODE_FD | CAN_CTRLMODE_FD_NON_ISO; | 1772 | priv->can.ctrlmode_supported |= CAN_CTRLMODE_FD | CAN_CTRLMODE_FD_NON_ISO; |
1771 | priv->can.bittiming_const = &flexcan_fd_bittiming_const; | 1773 | priv->can.bittiming_const = &flexcan_fd_bittiming_const; |
1772 | 1774 | ||
1773 | priv->tx_mb_reserved_idx = FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP_FD; | 1775 | priv->tx_mb_reserved_idx = FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP_FD; |
1774 | priv->tx_mb_idx = FLEXCAN_TX_MB_OFF_TIMESTAMP_FD; | 1776 | priv->tx_mb_idx = FLEXCAN_TX_MB_OFF_TIMESTAMP_FD; |
1775 | } else { | 1777 | } else { |
1776 | priv->tx_mb_reserved_idx = FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP; | 1778 | priv->tx_mb_reserved_idx = FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP; |
1777 | priv->tx_mb_idx = FLEXCAN_TX_MB_OFF_TIMESTAMP; | 1779 | priv->tx_mb_idx = FLEXCAN_TX_MB_OFF_TIMESTAMP; |
1778 | } | 1780 | } |
1779 | } else { | 1781 | } else { |
1780 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_TIMESTAMP_SUPPORT_FD) { | 1782 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_TIMESTAMP_SUPPORT_FD) { |
1781 | dev_err(&pdev->dev, "canfd mode can't work on fifo mode\n"); | 1783 | dev_err(&pdev->dev, "canfd mode can't work on fifo mode\n"); |
1782 | err = -EINVAL; | 1784 | err = -EINVAL; |
1783 | goto failed_offload; | 1785 | goto failed_offload; |
1784 | } | 1786 | } |
1785 | 1787 | ||
1786 | priv->tx_mb_reserved_idx = FLEXCAN_TX_MB_RESERVED_OFF_FIFO; | 1788 | priv->tx_mb_reserved_idx = FLEXCAN_TX_MB_RESERVED_OFF_FIFO; |
1787 | priv->tx_mb_idx = FLEXCAN_TX_MB_OFF_FIFO; | 1789 | priv->tx_mb_idx = FLEXCAN_TX_MB_OFF_FIFO; |
1788 | } | 1790 | } |
1789 | 1791 | ||
1790 | priv->reg_imask1_default = FLEXCAN_IFLAG_MB(priv->tx_mb_idx); | 1792 | priv->reg_imask1_default = FLEXCAN_IFLAG_MB(priv->tx_mb_idx); |
1791 | priv->reg_imask2_default = 0; | 1793 | priv->reg_imask2_default = 0; |
1792 | 1794 | ||
1793 | priv->offload.mailbox_read = flexcan_mailbox_read; | 1795 | priv->offload.mailbox_read = flexcan_mailbox_read; |
1794 | 1796 | ||
1795 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { | 1797 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { |
1796 | u64 imask; | 1798 | u64 imask; |
1797 | 1799 | ||
1798 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_TIMESTAMP_SUPPORT_FD) { | 1800 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_TIMESTAMP_SUPPORT_FD) { |
1799 | priv->offload.mb_first = FLEXCAN_RX_MB_OFF_TIMESTAMP_FD_FIRST; | 1801 | priv->offload.mb_first = FLEXCAN_RX_MB_OFF_TIMESTAMP_FD_FIRST; |
1800 | priv->offload.mb_last = FLEXCAN_RX_MB_OFF_TIMESTAMP_FD_LAST; | 1802 | priv->offload.mb_last = FLEXCAN_RX_MB_OFF_TIMESTAMP_FD_LAST; |
1801 | } else { | 1803 | } else { |
1802 | priv->offload.mb_first = FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST; | 1804 | priv->offload.mb_first = FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST; |
1803 | priv->offload.mb_last = FLEXCAN_RX_MB_OFF_TIMESTAMP_LAST; | 1805 | priv->offload.mb_last = FLEXCAN_RX_MB_OFF_TIMESTAMP_LAST; |
1804 | } | 1806 | } |
1805 | 1807 | ||
1806 | imask = GENMASK_ULL(priv->offload.mb_last, priv->offload.mb_first); | 1808 | imask = GENMASK_ULL(priv->offload.mb_last, priv->offload.mb_first); |
1807 | priv->reg_imask1_default |= imask; | 1809 | priv->reg_imask1_default |= imask; |
1808 | priv->reg_imask2_default |= imask >> 32; | 1810 | priv->reg_imask2_default |= imask >> 32; |
1809 | 1811 | ||
1810 | err = can_rx_offload_add_timestamp(dev, &priv->offload); | 1812 | err = can_rx_offload_add_timestamp(dev, &priv->offload); |
1811 | } else { | 1813 | } else { |
1812 | priv->reg_imask1_default |= FLEXCAN_IFLAG_RX_FIFO_OVERFLOW | | 1814 | priv->reg_imask1_default |= FLEXCAN_IFLAG_RX_FIFO_OVERFLOW | |
1813 | FLEXCAN_IFLAG_RX_FIFO_AVAILABLE; | 1815 | FLEXCAN_IFLAG_RX_FIFO_AVAILABLE; |
1814 | err = can_rx_offload_add_fifo(dev, &priv->offload, FLEXCAN_NAPI_WEIGHT); | 1816 | err = can_rx_offload_add_fifo(dev, &priv->offload, FLEXCAN_NAPI_WEIGHT); |
1815 | } | 1817 | } |
1816 | if (err) | 1818 | if (err) |
1817 | goto failed_offload; | 1819 | goto failed_offload; |
1818 | 1820 | ||
1819 | pm_runtime_enable(&pdev->dev); | 1821 | pm_runtime_enable(&pdev->dev); |
1820 | err = pm_runtime_get_sync(&pdev->dev); | 1822 | err = pm_runtime_get_sync(&pdev->dev); |
1821 | if (err < 0) { | 1823 | if (err < 0) { |
1822 | dev_err(&pdev->dev, "pm_runtime_get failed(%d)\n", err); | 1824 | dev_err(&pdev->dev, "pm_runtime_get failed(%d)\n", err); |
1823 | goto failed_rpm_disable; | 1825 | goto failed_rpm_disable; |
1824 | } | 1826 | } |
1825 | 1827 | ||
1826 | err = register_flexcandev(dev); | 1828 | err = register_flexcandev(dev); |
1827 | if (err) { | 1829 | if (err) { |
1828 | dev_err(&pdev->dev, "registering netdev failed\n"); | 1830 | dev_err(&pdev->dev, "registering netdev failed\n"); |
1829 | goto failed_rpm_put; | 1831 | goto failed_rpm_put; |
1830 | } | 1832 | } |
1831 | 1833 | ||
1832 | devm_can_led_init(dev); | 1834 | devm_can_led_init(dev); |
1833 | 1835 | ||
1834 | priv->wakeup = true; | 1836 | priv->wakeup = true; |
1835 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_TIMESTAMP_SUPPORT_FD) { | 1837 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_TIMESTAMP_SUPPORT_FD) { |
1836 | err = imx8_sc_ipc_fetch(pdev); | 1838 | err = imx8_sc_ipc_fetch(pdev); |
1837 | if (err) { | 1839 | if (err) { |
1838 | priv->wakeup = false; | 1840 | priv->wakeup = false; |
1839 | dev_dbg(&pdev->dev, "failed to fetch scu ipc\n"); | 1841 | dev_dbg(&pdev->dev, "failed to fetch scu ipc\n"); |
1840 | } | 1842 | } |
1841 | } else if (priv->devtype_data->quirks & FLEXCAN_QUIRK_DISABLE_RXFG) { | 1843 | } else if (priv->devtype_data->quirks & FLEXCAN_QUIRK_DISABLE_RXFG) { |
1842 | err = flexcan_of_parse_stop_mode(pdev); | 1844 | err = flexcan_of_parse_stop_mode(pdev); |
1843 | if (err) { | 1845 | if (err) { |
1844 | priv->wakeup = false;; | 1846 | priv->wakeup = false;; |
1845 | dev_dbg(&pdev->dev, "failed to parse stop-mode\n"); | 1847 | dev_dbg(&pdev->dev, "failed to parse stop-mode\n"); |
1846 | } | 1848 | } |
1847 | } | 1849 | } |
1848 | 1850 | ||
1849 | pm_runtime_put(&pdev->dev); | 1851 | pm_runtime_put(&pdev->dev); |
1850 | 1852 | ||
1851 | dev_info(&pdev->dev, "device registered (reg_base=%p, irq=%d)\n", | 1853 | dev_info(&pdev->dev, "device registered (reg_base=%p, irq=%d)\n", |
1852 | priv->regs, dev->irq); | 1854 | priv->regs, dev->irq); |
1853 | 1855 | ||
1854 | return 0; | 1856 | return 0; |
1855 | 1857 | ||
1856 | failed_rpm_put: | 1858 | failed_rpm_put: |
1857 | pm_runtime_put(priv->dev); | 1859 | pm_runtime_put(priv->dev); |
1858 | failed_rpm_disable: | 1860 | failed_rpm_disable: |
1859 | pm_runtime_disable(&pdev->dev); | 1861 | pm_runtime_disable(&pdev->dev); |
1860 | failed_offload: | 1862 | failed_offload: |
1861 | free_candev(dev); | 1863 | free_candev(dev); |
1862 | 1864 | ||
1863 | return err; | 1865 | return err; |
1864 | } | 1866 | } |
1865 | 1867 | ||
1866 | static int flexcan_remove(struct platform_device *pdev) | 1868 | static int flexcan_remove(struct platform_device *pdev) |
1867 | { | 1869 | { |
1868 | struct net_device *dev = platform_get_drvdata(pdev); | 1870 | struct net_device *dev = platform_get_drvdata(pdev); |
1869 | struct flexcan_priv *priv = netdev_priv(dev); | 1871 | struct flexcan_priv *priv = netdev_priv(dev); |
1870 | 1872 | ||
1871 | #ifdef CONFIG_ARCH_MXC_ARM64 | 1873 | #ifdef CONFIG_ARCH_MXC_ARM64 |
1872 | sc_ipc_close(priv->ipc_handle); | 1874 | sc_ipc_close(priv->ipc_handle); |
1873 | #endif | 1875 | #endif |
1874 | unregister_flexcandev(dev); | 1876 | unregister_flexcandev(dev); |
1875 | pm_runtime_disable(&pdev->dev); | 1877 | pm_runtime_disable(&pdev->dev); |
1876 | can_rx_offload_del(&priv->offload); | 1878 | can_rx_offload_del(&priv->offload); |
1877 | free_candev(dev); | 1879 | free_candev(dev); |
1878 | 1880 | ||
1879 | return 0; | 1881 | return 0; |
1880 | } | 1882 | } |
1881 | 1883 | ||
1882 | static int __maybe_unused flexcan_suspend(struct device *device) | 1884 | static int __maybe_unused flexcan_suspend(struct device *device) |
1883 | { | 1885 | { |
1884 | struct net_device *dev = dev_get_drvdata(device); | 1886 | struct net_device *dev = dev_get_drvdata(device); |
1885 | struct flexcan_priv *priv = netdev_priv(dev); | 1887 | struct flexcan_priv *priv = netdev_priv(dev); |
1886 | int ret = 0; | 1888 | int ret = 0; |
1887 | 1889 | ||
1888 | if (netif_running(dev)) { | 1890 | if (netif_running(dev)) { |
1889 | netif_stop_queue(dev); | 1891 | netif_stop_queue(dev); |
1890 | netif_device_detach(dev); | 1892 | netif_device_detach(dev); |
1891 | /* | 1893 | /* |
1892 | * if wakeup is enabled, enter stop mode | 1894 | * if wakeup is enabled, enter stop mode |
1893 | * else enter disabled mode. | 1895 | * else enter disabled mode. |
1894 | */ | 1896 | */ |
1895 | if (device_may_wakeup(device)) { | 1897 | if (device_may_wakeup(device)) { |
1896 | enable_irq_wake(dev->irq); | 1898 | enable_irq_wake(dev->irq); |
1897 | flexcan_enter_stop_mode(priv); | 1899 | flexcan_enter_stop_mode(priv); |
1898 | } else { | 1900 | } else { |
1899 | flexcan_chip_stop(dev); | 1901 | flexcan_chip_stop(dev); |
1900 | ret = pm_runtime_force_suspend(device); | 1902 | ret = pm_runtime_force_suspend(device); |
1901 | 1903 | ||
1902 | pinctrl_pm_select_sleep_state(device); | 1904 | pinctrl_pm_select_sleep_state(device); |
1903 | } | 1905 | } |
1904 | } | 1906 | } |
1905 | priv->can.state = CAN_STATE_SLEEPING; | 1907 | priv->can.state = CAN_STATE_SLEEPING; |
1906 | 1908 | ||
1907 | return ret; | 1909 | return ret; |
1908 | } | 1910 | } |
1909 | 1911 | ||
1910 | static int __maybe_unused flexcan_resume(struct device *device) | 1912 | static int __maybe_unused flexcan_resume(struct device *device) |
1911 | { | 1913 | { |
1912 | struct net_device *dev = dev_get_drvdata(device); | 1914 | struct net_device *dev = dev_get_drvdata(device); |
1913 | struct flexcan_priv *priv = netdev_priv(dev); | 1915 | struct flexcan_priv *priv = netdev_priv(dev); |
1914 | int err = 0; | 1916 | int err = 0; |
1915 | 1917 | ||
1916 | priv->can.state = CAN_STATE_ERROR_ACTIVE; | 1918 | priv->can.state = CAN_STATE_ERROR_ACTIVE; |
1917 | if (netif_running(dev)) { | 1919 | if (netif_running(dev)) { |
1918 | netif_device_attach(dev); | 1920 | netif_device_attach(dev); |
1919 | netif_start_queue(dev); | 1921 | netif_start_queue(dev); |
1920 | 1922 | ||
1921 | if (device_may_wakeup(device)) { | 1923 | if (device_may_wakeup(device)) { |
1922 | flexcan_wake_mask_disable(priv); | 1924 | flexcan_wake_mask_disable(priv); |
1923 | } else { | 1925 | } else { |
1924 | pinctrl_pm_select_default_state(device); | 1926 | pinctrl_pm_select_default_state(device); |
1925 | 1927 | ||
1926 | err = pm_runtime_force_resume(device); | 1928 | err = pm_runtime_force_resume(device); |
1927 | if (err) | 1929 | if (err) |
1928 | return err; | 1930 | return err; |
1929 | err = flexcan_chip_start(dev); | 1931 | err = flexcan_chip_start(dev); |
1930 | } | 1932 | } |
1931 | } | 1933 | } |
1932 | 1934 | ||
1933 | return err; | 1935 | return err; |
1934 | } | 1936 | } |
1935 | 1937 | ||
1936 | static int __maybe_unused flexcan_runtime_suspend(struct device *device) | 1938 | static int __maybe_unused flexcan_runtime_suspend(struct device *device) |
1937 | { | 1939 | { |
1938 | struct net_device *dev = dev_get_drvdata(device); | 1940 | struct net_device *dev = dev_get_drvdata(device); |
1939 | struct flexcan_priv *priv = netdev_priv(dev); | 1941 | struct flexcan_priv *priv = netdev_priv(dev); |
1940 | 1942 | ||
1941 | flexcan_clks_disable(priv); | 1943 | flexcan_clks_disable(priv); |
1942 | 1944 | ||
1943 | return 0; | 1945 | return 0; |
1944 | } | 1946 | } |
1945 | 1947 | ||
1946 | static int __maybe_unused flexcan_runtime_resume(struct device *device) | 1948 | static int __maybe_unused flexcan_runtime_resume(struct device *device) |
1947 | { | 1949 | { |
1948 | struct net_device *dev = dev_get_drvdata(device); | 1950 | struct net_device *dev = dev_get_drvdata(device); |
1949 | struct flexcan_priv *priv = netdev_priv(dev); | 1951 | struct flexcan_priv *priv = netdev_priv(dev); |
1950 | 1952 | ||
1951 | flexcan_clks_enable(priv); | 1953 | flexcan_clks_enable(priv); |
1952 | 1954 | ||
1953 | return 0; | 1955 | return 0; |
1954 | } | 1956 | } |
1955 | 1957 | ||
1956 | static int __maybe_unused flexcan_noirq_suspend(struct device *device) | 1958 | static int __maybe_unused flexcan_noirq_suspend(struct device *device) |
1957 | { | 1959 | { |
1958 | struct net_device *dev = dev_get_drvdata(device); | 1960 | struct net_device *dev = dev_get_drvdata(device); |
1959 | struct flexcan_priv *priv = netdev_priv(dev); | 1961 | struct flexcan_priv *priv = netdev_priv(dev); |
1960 | 1962 | ||
1961 | if (netif_running(dev) && device_may_wakeup(device)) { | 1963 | if (netif_running(dev) && device_may_wakeup(device)) { |
1962 | flexcan_wake_mask_enable(priv); | 1964 | flexcan_wake_mask_enable(priv); |
1963 | } | 1965 | } |
1964 | 1966 | ||
1965 | return 0; | 1967 | return 0; |
1966 | } | 1968 | } |
1967 | 1969 | ||
1968 | static int __maybe_unused flexcan_noirq_resume(struct device *device) | 1970 | static int __maybe_unused flexcan_noirq_resume(struct device *device) |
1969 | { | 1971 | { |
1970 | struct net_device *dev = dev_get_drvdata(device); | 1972 | struct net_device *dev = dev_get_drvdata(device); |
1971 | struct flexcan_priv *priv = netdev_priv(dev); | 1973 | struct flexcan_priv *priv = netdev_priv(dev); |
1972 | 1974 | ||
1973 | if (netif_running(dev) && device_may_wakeup(device)) { | 1975 | if (netif_running(dev) && device_may_wakeup(device)) { |
1974 | disable_irq_wake(dev->irq); | 1976 | disable_irq_wake(dev->irq); |
1975 | flexcan_exit_stop_mode(priv); | 1977 | flexcan_exit_stop_mode(priv); |
1976 | } | 1978 | } |
1977 | 1979 | ||
1978 | return 0; | 1980 | return 0; |
1979 | } | 1981 | } |
1980 | 1982 | ||
1981 | static const struct dev_pm_ops flexcan_pm_ops = { | 1983 | static const struct dev_pm_ops flexcan_pm_ops = { |
1982 | SET_SYSTEM_SLEEP_PM_OPS(flexcan_suspend, flexcan_resume) | 1984 | SET_SYSTEM_SLEEP_PM_OPS(flexcan_suspend, flexcan_resume) |
1983 | SET_RUNTIME_PM_OPS(flexcan_runtime_suspend, flexcan_runtime_resume, NULL) | 1985 | SET_RUNTIME_PM_OPS(flexcan_runtime_suspend, flexcan_runtime_resume, NULL) |
1984 | SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(flexcan_noirq_suspend, flexcan_noirq_resume) | 1986 | SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(flexcan_noirq_suspend, flexcan_noirq_resume) |
1985 | }; | 1987 | }; |
1986 | 1988 | ||
1987 | static struct platform_driver flexcan_driver = { | 1989 | static struct platform_driver flexcan_driver = { |
1988 | .driver = { | 1990 | .driver = { |
1989 | .name = DRV_NAME, | 1991 | .name = DRV_NAME, |
1990 | .pm = &flexcan_pm_ops, | 1992 | .pm = &flexcan_pm_ops, |
1991 | .of_match_table = flexcan_of_match, | 1993 | .of_match_table = flexcan_of_match, |
1992 | }, | 1994 | }, |
1993 | .probe = flexcan_probe, | 1995 | .probe = flexcan_probe, |
1994 | .remove = flexcan_remove, | 1996 | .remove = flexcan_remove, |
1995 | .id_table = flexcan_id_table, | 1997 | .id_table = flexcan_id_table, |
1996 | }; | 1998 | }; |
1997 | 1999 | ||
1998 | module_platform_driver(flexcan_driver); | 2000 | module_platform_driver(flexcan_driver); |
1999 | 2001 | ||
2000 | MODULE_AUTHOR("Sascha Hauer <kernel@pengutronix.de>, " | 2002 | MODULE_AUTHOR("Sascha Hauer <kernel@pengutronix.de>, " |
2001 | "Marc Kleine-Budde <kernel@pengutronix.de>"); | 2003 | "Marc Kleine-Budde <kernel@pengutronix.de>"); |
2002 | MODULE_LICENSE("GPL v2"); | 2004 | MODULE_LICENSE("GPL v2"); |
2003 | MODULE_DESCRIPTION("CAN port driver for flexcan based chip"); | 2005 | MODULE_DESCRIPTION("CAN port driver for flexcan based chip"); |
2004 | 2006 |