Commit e358784297992b012e8071764d996191dd2b1a54
1 parent
d5a7b406c5
Exists in
smarc-imx_3.14.28_1.0.0_ga
and in
1 other branch
can: flexcan: fix mx28 detection by rearanging OF match table
The current implemetation of of_match_device() relies that the of_device_id table in the driver is sorted from most specific to least specific compatible. Without this patch the mx28 is detected as the less specific p1010. This leads to a p1010 specific workaround is activated on the mx28, which is not needed. Cc: linux-stable <stable@vger.kernel.org> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Showing 1 changed file with 2 additions and 2 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 Marc Kleine-Budde, Pengutronix | 6 | * Copyright (c) 2010 Marc Kleine-Budde, Pengutronix |
7 | * | 7 | * |
8 | * Based on code originally by Andrey Volkov <avolkov@varma-el.com> | 8 | * Based on code originally by Andrey Volkov <avolkov@varma-el.com> |
9 | * | 9 | * |
10 | * LICENCE: | 10 | * LICENCE: |
11 | * This program is free software; you can redistribute it and/or | 11 | * This program is free software; you can redistribute it and/or |
12 | * modify it under the terms of the GNU General Public License as | 12 | * modify it under the terms of the GNU General Public License as |
13 | * published by the Free Software Foundation version 2. | 13 | * published by the Free Software Foundation version 2. |
14 | * | 14 | * |
15 | * This program is distributed in the hope that it will be useful, | 15 | * This program is distributed in the hope that it will be useful, |
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
18 | * GNU General Public License for more details. | 18 | * GNU General Public License for more details. |
19 | * | 19 | * |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/netdevice.h> | 22 | #include <linux/netdevice.h> |
23 | #include <linux/can.h> | 23 | #include <linux/can.h> |
24 | #include <linux/can/dev.h> | 24 | #include <linux/can/dev.h> |
25 | #include <linux/can/error.h> | 25 | #include <linux/can/error.h> |
26 | #include <linux/can/led.h> | 26 | #include <linux/can/led.h> |
27 | #include <linux/clk.h> | 27 | #include <linux/clk.h> |
28 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
29 | #include <linux/if_arp.h> | 29 | #include <linux/if_arp.h> |
30 | #include <linux/if_ether.h> | 30 | #include <linux/if_ether.h> |
31 | #include <linux/interrupt.h> | 31 | #include <linux/interrupt.h> |
32 | #include <linux/io.h> | 32 | #include <linux/io.h> |
33 | #include <linux/kernel.h> | 33 | #include <linux/kernel.h> |
34 | #include <linux/list.h> | 34 | #include <linux/list.h> |
35 | #include <linux/module.h> | 35 | #include <linux/module.h> |
36 | #include <linux/of.h> | 36 | #include <linux/of.h> |
37 | #include <linux/of_device.h> | 37 | #include <linux/of_device.h> |
38 | #include <linux/platform_device.h> | 38 | #include <linux/platform_device.h> |
39 | #include <linux/regulator/consumer.h> | 39 | #include <linux/regulator/consumer.h> |
40 | 40 | ||
41 | #define DRV_NAME "flexcan" | 41 | #define DRV_NAME "flexcan" |
42 | 42 | ||
43 | /* 8 for RX fifo and 2 error handling */ | 43 | /* 8 for RX fifo and 2 error handling */ |
44 | #define FLEXCAN_NAPI_WEIGHT (8 + 2) | 44 | #define FLEXCAN_NAPI_WEIGHT (8 + 2) |
45 | 45 | ||
46 | /* FLEXCAN module configuration register (CANMCR) bits */ | 46 | /* FLEXCAN module configuration register (CANMCR) bits */ |
47 | #define FLEXCAN_MCR_MDIS BIT(31) | 47 | #define FLEXCAN_MCR_MDIS BIT(31) |
48 | #define FLEXCAN_MCR_FRZ BIT(30) | 48 | #define FLEXCAN_MCR_FRZ BIT(30) |
49 | #define FLEXCAN_MCR_FEN BIT(29) | 49 | #define FLEXCAN_MCR_FEN BIT(29) |
50 | #define FLEXCAN_MCR_HALT BIT(28) | 50 | #define FLEXCAN_MCR_HALT BIT(28) |
51 | #define FLEXCAN_MCR_NOT_RDY BIT(27) | 51 | #define FLEXCAN_MCR_NOT_RDY BIT(27) |
52 | #define FLEXCAN_MCR_WAK_MSK BIT(26) | 52 | #define FLEXCAN_MCR_WAK_MSK BIT(26) |
53 | #define FLEXCAN_MCR_SOFTRST BIT(25) | 53 | #define FLEXCAN_MCR_SOFTRST BIT(25) |
54 | #define FLEXCAN_MCR_FRZ_ACK BIT(24) | 54 | #define FLEXCAN_MCR_FRZ_ACK BIT(24) |
55 | #define FLEXCAN_MCR_SUPV BIT(23) | 55 | #define FLEXCAN_MCR_SUPV BIT(23) |
56 | #define FLEXCAN_MCR_SLF_WAK BIT(22) | 56 | #define FLEXCAN_MCR_SLF_WAK BIT(22) |
57 | #define FLEXCAN_MCR_WRN_EN BIT(21) | 57 | #define FLEXCAN_MCR_WRN_EN BIT(21) |
58 | #define FLEXCAN_MCR_LPM_ACK BIT(20) | 58 | #define FLEXCAN_MCR_LPM_ACK BIT(20) |
59 | #define FLEXCAN_MCR_WAK_SRC BIT(19) | 59 | #define FLEXCAN_MCR_WAK_SRC BIT(19) |
60 | #define FLEXCAN_MCR_DOZE BIT(18) | 60 | #define FLEXCAN_MCR_DOZE BIT(18) |
61 | #define FLEXCAN_MCR_SRX_DIS BIT(17) | 61 | #define FLEXCAN_MCR_SRX_DIS BIT(17) |
62 | #define FLEXCAN_MCR_BCC BIT(16) | 62 | #define FLEXCAN_MCR_BCC BIT(16) |
63 | #define FLEXCAN_MCR_LPRIO_EN BIT(13) | 63 | #define FLEXCAN_MCR_LPRIO_EN BIT(13) |
64 | #define FLEXCAN_MCR_AEN BIT(12) | 64 | #define FLEXCAN_MCR_AEN BIT(12) |
65 | #define FLEXCAN_MCR_MAXMB(x) ((x) & 0x1f) | 65 | #define FLEXCAN_MCR_MAXMB(x) ((x) & 0x1f) |
66 | #define FLEXCAN_MCR_IDAM_A (0 << 8) | 66 | #define FLEXCAN_MCR_IDAM_A (0 << 8) |
67 | #define FLEXCAN_MCR_IDAM_B (1 << 8) | 67 | #define FLEXCAN_MCR_IDAM_B (1 << 8) |
68 | #define FLEXCAN_MCR_IDAM_C (2 << 8) | 68 | #define FLEXCAN_MCR_IDAM_C (2 << 8) |
69 | #define FLEXCAN_MCR_IDAM_D (3 << 8) | 69 | #define FLEXCAN_MCR_IDAM_D (3 << 8) |
70 | 70 | ||
71 | /* FLEXCAN control register (CANCTRL) bits */ | 71 | /* FLEXCAN control register (CANCTRL) bits */ |
72 | #define FLEXCAN_CTRL_PRESDIV(x) (((x) & 0xff) << 24) | 72 | #define FLEXCAN_CTRL_PRESDIV(x) (((x) & 0xff) << 24) |
73 | #define FLEXCAN_CTRL_RJW(x) (((x) & 0x03) << 22) | 73 | #define FLEXCAN_CTRL_RJW(x) (((x) & 0x03) << 22) |
74 | #define FLEXCAN_CTRL_PSEG1(x) (((x) & 0x07) << 19) | 74 | #define FLEXCAN_CTRL_PSEG1(x) (((x) & 0x07) << 19) |
75 | #define FLEXCAN_CTRL_PSEG2(x) (((x) & 0x07) << 16) | 75 | #define FLEXCAN_CTRL_PSEG2(x) (((x) & 0x07) << 16) |
76 | #define FLEXCAN_CTRL_BOFF_MSK BIT(15) | 76 | #define FLEXCAN_CTRL_BOFF_MSK BIT(15) |
77 | #define FLEXCAN_CTRL_ERR_MSK BIT(14) | 77 | #define FLEXCAN_CTRL_ERR_MSK BIT(14) |
78 | #define FLEXCAN_CTRL_CLK_SRC BIT(13) | 78 | #define FLEXCAN_CTRL_CLK_SRC BIT(13) |
79 | #define FLEXCAN_CTRL_LPB BIT(12) | 79 | #define FLEXCAN_CTRL_LPB BIT(12) |
80 | #define FLEXCAN_CTRL_TWRN_MSK BIT(11) | 80 | #define FLEXCAN_CTRL_TWRN_MSK BIT(11) |
81 | #define FLEXCAN_CTRL_RWRN_MSK BIT(10) | 81 | #define FLEXCAN_CTRL_RWRN_MSK BIT(10) |
82 | #define FLEXCAN_CTRL_SMP BIT(7) | 82 | #define FLEXCAN_CTRL_SMP BIT(7) |
83 | #define FLEXCAN_CTRL_BOFF_REC BIT(6) | 83 | #define FLEXCAN_CTRL_BOFF_REC BIT(6) |
84 | #define FLEXCAN_CTRL_TSYN BIT(5) | 84 | #define FLEXCAN_CTRL_TSYN BIT(5) |
85 | #define FLEXCAN_CTRL_LBUF BIT(4) | 85 | #define FLEXCAN_CTRL_LBUF BIT(4) |
86 | #define FLEXCAN_CTRL_LOM BIT(3) | 86 | #define FLEXCAN_CTRL_LOM BIT(3) |
87 | #define FLEXCAN_CTRL_PROPSEG(x) ((x) & 0x07) | 87 | #define FLEXCAN_CTRL_PROPSEG(x) ((x) & 0x07) |
88 | #define FLEXCAN_CTRL_ERR_BUS (FLEXCAN_CTRL_ERR_MSK) | 88 | #define FLEXCAN_CTRL_ERR_BUS (FLEXCAN_CTRL_ERR_MSK) |
89 | #define FLEXCAN_CTRL_ERR_STATE \ | 89 | #define FLEXCAN_CTRL_ERR_STATE \ |
90 | (FLEXCAN_CTRL_TWRN_MSK | FLEXCAN_CTRL_RWRN_MSK | \ | 90 | (FLEXCAN_CTRL_TWRN_MSK | FLEXCAN_CTRL_RWRN_MSK | \ |
91 | FLEXCAN_CTRL_BOFF_MSK) | 91 | FLEXCAN_CTRL_BOFF_MSK) |
92 | #define FLEXCAN_CTRL_ERR_ALL \ | 92 | #define FLEXCAN_CTRL_ERR_ALL \ |
93 | (FLEXCAN_CTRL_ERR_BUS | FLEXCAN_CTRL_ERR_STATE) | 93 | (FLEXCAN_CTRL_ERR_BUS | FLEXCAN_CTRL_ERR_STATE) |
94 | 94 | ||
95 | /* FLEXCAN error and status register (ESR) bits */ | 95 | /* FLEXCAN error and status register (ESR) bits */ |
96 | #define FLEXCAN_ESR_TWRN_INT BIT(17) | 96 | #define FLEXCAN_ESR_TWRN_INT BIT(17) |
97 | #define FLEXCAN_ESR_RWRN_INT BIT(16) | 97 | #define FLEXCAN_ESR_RWRN_INT BIT(16) |
98 | #define FLEXCAN_ESR_BIT1_ERR BIT(15) | 98 | #define FLEXCAN_ESR_BIT1_ERR BIT(15) |
99 | #define FLEXCAN_ESR_BIT0_ERR BIT(14) | 99 | #define FLEXCAN_ESR_BIT0_ERR BIT(14) |
100 | #define FLEXCAN_ESR_ACK_ERR BIT(13) | 100 | #define FLEXCAN_ESR_ACK_ERR BIT(13) |
101 | #define FLEXCAN_ESR_CRC_ERR BIT(12) | 101 | #define FLEXCAN_ESR_CRC_ERR BIT(12) |
102 | #define FLEXCAN_ESR_FRM_ERR BIT(11) | 102 | #define FLEXCAN_ESR_FRM_ERR BIT(11) |
103 | #define FLEXCAN_ESR_STF_ERR BIT(10) | 103 | #define FLEXCAN_ESR_STF_ERR BIT(10) |
104 | #define FLEXCAN_ESR_TX_WRN BIT(9) | 104 | #define FLEXCAN_ESR_TX_WRN BIT(9) |
105 | #define FLEXCAN_ESR_RX_WRN BIT(8) | 105 | #define FLEXCAN_ESR_RX_WRN BIT(8) |
106 | #define FLEXCAN_ESR_IDLE BIT(7) | 106 | #define FLEXCAN_ESR_IDLE BIT(7) |
107 | #define FLEXCAN_ESR_TXRX BIT(6) | 107 | #define FLEXCAN_ESR_TXRX BIT(6) |
108 | #define FLEXCAN_EST_FLT_CONF_SHIFT (4) | 108 | #define FLEXCAN_EST_FLT_CONF_SHIFT (4) |
109 | #define FLEXCAN_ESR_FLT_CONF_MASK (0x3 << FLEXCAN_EST_FLT_CONF_SHIFT) | 109 | #define FLEXCAN_ESR_FLT_CONF_MASK (0x3 << FLEXCAN_EST_FLT_CONF_SHIFT) |
110 | #define FLEXCAN_ESR_FLT_CONF_ACTIVE (0x0 << FLEXCAN_EST_FLT_CONF_SHIFT) | 110 | #define FLEXCAN_ESR_FLT_CONF_ACTIVE (0x0 << FLEXCAN_EST_FLT_CONF_SHIFT) |
111 | #define FLEXCAN_ESR_FLT_CONF_PASSIVE (0x1 << FLEXCAN_EST_FLT_CONF_SHIFT) | 111 | #define FLEXCAN_ESR_FLT_CONF_PASSIVE (0x1 << FLEXCAN_EST_FLT_CONF_SHIFT) |
112 | #define FLEXCAN_ESR_BOFF_INT BIT(2) | 112 | #define FLEXCAN_ESR_BOFF_INT BIT(2) |
113 | #define FLEXCAN_ESR_ERR_INT BIT(1) | 113 | #define FLEXCAN_ESR_ERR_INT BIT(1) |
114 | #define FLEXCAN_ESR_WAK_INT BIT(0) | 114 | #define FLEXCAN_ESR_WAK_INT BIT(0) |
115 | #define FLEXCAN_ESR_ERR_BUS \ | 115 | #define FLEXCAN_ESR_ERR_BUS \ |
116 | (FLEXCAN_ESR_BIT1_ERR | FLEXCAN_ESR_BIT0_ERR | \ | 116 | (FLEXCAN_ESR_BIT1_ERR | FLEXCAN_ESR_BIT0_ERR | \ |
117 | FLEXCAN_ESR_ACK_ERR | FLEXCAN_ESR_CRC_ERR | \ | 117 | FLEXCAN_ESR_ACK_ERR | FLEXCAN_ESR_CRC_ERR | \ |
118 | FLEXCAN_ESR_FRM_ERR | FLEXCAN_ESR_STF_ERR) | 118 | FLEXCAN_ESR_FRM_ERR | FLEXCAN_ESR_STF_ERR) |
119 | #define FLEXCAN_ESR_ERR_STATE \ | 119 | #define FLEXCAN_ESR_ERR_STATE \ |
120 | (FLEXCAN_ESR_TWRN_INT | FLEXCAN_ESR_RWRN_INT | FLEXCAN_ESR_BOFF_INT) | 120 | (FLEXCAN_ESR_TWRN_INT | FLEXCAN_ESR_RWRN_INT | FLEXCAN_ESR_BOFF_INT) |
121 | #define FLEXCAN_ESR_ERR_ALL \ | 121 | #define FLEXCAN_ESR_ERR_ALL \ |
122 | (FLEXCAN_ESR_ERR_BUS | FLEXCAN_ESR_ERR_STATE) | 122 | (FLEXCAN_ESR_ERR_BUS | FLEXCAN_ESR_ERR_STATE) |
123 | #define FLEXCAN_ESR_ALL_INT \ | 123 | #define FLEXCAN_ESR_ALL_INT \ |
124 | (FLEXCAN_ESR_TWRN_INT | FLEXCAN_ESR_RWRN_INT | \ | 124 | (FLEXCAN_ESR_TWRN_INT | FLEXCAN_ESR_RWRN_INT | \ |
125 | FLEXCAN_ESR_BOFF_INT | FLEXCAN_ESR_ERR_INT) | 125 | FLEXCAN_ESR_BOFF_INT | FLEXCAN_ESR_ERR_INT) |
126 | 126 | ||
127 | /* FLEXCAN interrupt flag register (IFLAG) bits */ | 127 | /* FLEXCAN interrupt flag register (IFLAG) bits */ |
128 | #define FLEXCAN_TX_BUF_ID 8 | 128 | #define FLEXCAN_TX_BUF_ID 8 |
129 | #define FLEXCAN_IFLAG_BUF(x) BIT(x) | 129 | #define FLEXCAN_IFLAG_BUF(x) BIT(x) |
130 | #define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW BIT(7) | 130 | #define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW BIT(7) |
131 | #define FLEXCAN_IFLAG_RX_FIFO_WARN BIT(6) | 131 | #define FLEXCAN_IFLAG_RX_FIFO_WARN BIT(6) |
132 | #define FLEXCAN_IFLAG_RX_FIFO_AVAILABLE BIT(5) | 132 | #define FLEXCAN_IFLAG_RX_FIFO_AVAILABLE BIT(5) |
133 | #define FLEXCAN_IFLAG_DEFAULT \ | 133 | #define FLEXCAN_IFLAG_DEFAULT \ |
134 | (FLEXCAN_IFLAG_RX_FIFO_OVERFLOW | FLEXCAN_IFLAG_RX_FIFO_AVAILABLE | \ | 134 | (FLEXCAN_IFLAG_RX_FIFO_OVERFLOW | FLEXCAN_IFLAG_RX_FIFO_AVAILABLE | \ |
135 | FLEXCAN_IFLAG_BUF(FLEXCAN_TX_BUF_ID)) | 135 | FLEXCAN_IFLAG_BUF(FLEXCAN_TX_BUF_ID)) |
136 | 136 | ||
137 | /* FLEXCAN message buffers */ | 137 | /* FLEXCAN message buffers */ |
138 | #define FLEXCAN_MB_CNT_CODE(x) (((x) & 0xf) << 24) | 138 | #define FLEXCAN_MB_CNT_CODE(x) (((x) & 0xf) << 24) |
139 | #define FLEXCAN_MB_CNT_SRR BIT(22) | 139 | #define FLEXCAN_MB_CNT_SRR BIT(22) |
140 | #define FLEXCAN_MB_CNT_IDE BIT(21) | 140 | #define FLEXCAN_MB_CNT_IDE BIT(21) |
141 | #define FLEXCAN_MB_CNT_RTR BIT(20) | 141 | #define FLEXCAN_MB_CNT_RTR BIT(20) |
142 | #define FLEXCAN_MB_CNT_LENGTH(x) (((x) & 0xf) << 16) | 142 | #define FLEXCAN_MB_CNT_LENGTH(x) (((x) & 0xf) << 16) |
143 | #define FLEXCAN_MB_CNT_TIMESTAMP(x) ((x) & 0xffff) | 143 | #define FLEXCAN_MB_CNT_TIMESTAMP(x) ((x) & 0xffff) |
144 | 144 | ||
145 | #define FLEXCAN_MB_CODE_MASK (0xf0ffffff) | 145 | #define FLEXCAN_MB_CODE_MASK (0xf0ffffff) |
146 | 146 | ||
147 | /* | 147 | /* |
148 | * FLEXCAN hardware feature flags | 148 | * FLEXCAN hardware feature flags |
149 | * | 149 | * |
150 | * Below is some version info we got: | 150 | * Below is some version info we got: |
151 | * SOC Version IP-Version Glitch- [TR]WRN_INT | 151 | * SOC Version IP-Version Glitch- [TR]WRN_INT |
152 | * Filter? connected? | 152 | * Filter? connected? |
153 | * MX25 FlexCAN2 03.00.00.00 no no | 153 | * MX25 FlexCAN2 03.00.00.00 no no |
154 | * MX28 FlexCAN2 03.00.04.00 yes yes | 154 | * MX28 FlexCAN2 03.00.04.00 yes yes |
155 | * MX35 FlexCAN2 03.00.00.00 no no | 155 | * MX35 FlexCAN2 03.00.00.00 no no |
156 | * MX53 FlexCAN2 03.00.00.00 yes no | 156 | * MX53 FlexCAN2 03.00.00.00 yes no |
157 | * MX6s FlexCAN3 10.00.12.00 yes yes | 157 | * MX6s FlexCAN3 10.00.12.00 yes yes |
158 | * | 158 | * |
159 | * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected. | 159 | * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected. |
160 | */ | 160 | */ |
161 | #define FLEXCAN_HAS_V10_FEATURES BIT(1) /* For core version >= 10 */ | 161 | #define FLEXCAN_HAS_V10_FEATURES BIT(1) /* For core version >= 10 */ |
162 | #define FLEXCAN_HAS_BROKEN_ERR_STATE BIT(2) /* [TR]WRN_INT not connected */ | 162 | #define FLEXCAN_HAS_BROKEN_ERR_STATE BIT(2) /* [TR]WRN_INT not connected */ |
163 | 163 | ||
164 | /* Structure of the message buffer */ | 164 | /* Structure of the message buffer */ |
165 | struct flexcan_mb { | 165 | struct flexcan_mb { |
166 | u32 can_ctrl; | 166 | u32 can_ctrl; |
167 | u32 can_id; | 167 | u32 can_id; |
168 | u32 data[2]; | 168 | u32 data[2]; |
169 | }; | 169 | }; |
170 | 170 | ||
171 | /* Structure of the hardware registers */ | 171 | /* Structure of the hardware registers */ |
172 | struct flexcan_regs { | 172 | struct flexcan_regs { |
173 | u32 mcr; /* 0x00 */ | 173 | u32 mcr; /* 0x00 */ |
174 | u32 ctrl; /* 0x04 */ | 174 | u32 ctrl; /* 0x04 */ |
175 | u32 timer; /* 0x08 */ | 175 | u32 timer; /* 0x08 */ |
176 | u32 _reserved1; /* 0x0c */ | 176 | u32 _reserved1; /* 0x0c */ |
177 | u32 rxgmask; /* 0x10 */ | 177 | u32 rxgmask; /* 0x10 */ |
178 | u32 rx14mask; /* 0x14 */ | 178 | u32 rx14mask; /* 0x14 */ |
179 | u32 rx15mask; /* 0x18 */ | 179 | u32 rx15mask; /* 0x18 */ |
180 | u32 ecr; /* 0x1c */ | 180 | u32 ecr; /* 0x1c */ |
181 | u32 esr; /* 0x20 */ | 181 | u32 esr; /* 0x20 */ |
182 | u32 imask2; /* 0x24 */ | 182 | u32 imask2; /* 0x24 */ |
183 | u32 imask1; /* 0x28 */ | 183 | u32 imask1; /* 0x28 */ |
184 | u32 iflag2; /* 0x2c */ | 184 | u32 iflag2; /* 0x2c */ |
185 | u32 iflag1; /* 0x30 */ | 185 | u32 iflag1; /* 0x30 */ |
186 | u32 crl2; /* 0x34 */ | 186 | u32 crl2; /* 0x34 */ |
187 | u32 esr2; /* 0x38 */ | 187 | u32 esr2; /* 0x38 */ |
188 | u32 imeur; /* 0x3c */ | 188 | u32 imeur; /* 0x3c */ |
189 | u32 lrfr; /* 0x40 */ | 189 | u32 lrfr; /* 0x40 */ |
190 | u32 crcr; /* 0x44 */ | 190 | u32 crcr; /* 0x44 */ |
191 | u32 rxfgmask; /* 0x48 */ | 191 | u32 rxfgmask; /* 0x48 */ |
192 | u32 rxfir; /* 0x4c */ | 192 | u32 rxfir; /* 0x4c */ |
193 | u32 _reserved3[12]; | 193 | u32 _reserved3[12]; |
194 | struct flexcan_mb cantxfg[64]; | 194 | struct flexcan_mb cantxfg[64]; |
195 | }; | 195 | }; |
196 | 196 | ||
197 | struct flexcan_devtype_data { | 197 | struct flexcan_devtype_data { |
198 | u32 features; /* hardware controller features */ | 198 | u32 features; /* hardware controller features */ |
199 | }; | 199 | }; |
200 | 200 | ||
201 | struct flexcan_priv { | 201 | struct flexcan_priv { |
202 | struct can_priv can; | 202 | struct can_priv can; |
203 | struct net_device *dev; | 203 | struct net_device *dev; |
204 | struct napi_struct napi; | 204 | struct napi_struct napi; |
205 | 205 | ||
206 | void __iomem *base; | 206 | void __iomem *base; |
207 | u32 reg_esr; | 207 | u32 reg_esr; |
208 | u32 reg_ctrl_default; | 208 | u32 reg_ctrl_default; |
209 | 209 | ||
210 | struct clk *clk_ipg; | 210 | struct clk *clk_ipg; |
211 | struct clk *clk_per; | 211 | struct clk *clk_per; |
212 | struct flexcan_platform_data *pdata; | 212 | struct flexcan_platform_data *pdata; |
213 | const struct flexcan_devtype_data *devtype_data; | 213 | const struct flexcan_devtype_data *devtype_data; |
214 | struct regulator *reg_xceiver; | 214 | struct regulator *reg_xceiver; |
215 | }; | 215 | }; |
216 | 216 | ||
217 | static struct flexcan_devtype_data fsl_p1010_devtype_data = { | 217 | static struct flexcan_devtype_data fsl_p1010_devtype_data = { |
218 | .features = FLEXCAN_HAS_BROKEN_ERR_STATE, | 218 | .features = FLEXCAN_HAS_BROKEN_ERR_STATE, |
219 | }; | 219 | }; |
220 | static struct flexcan_devtype_data fsl_imx28_devtype_data; | 220 | static struct flexcan_devtype_data fsl_imx28_devtype_data; |
221 | static struct flexcan_devtype_data fsl_imx6q_devtype_data = { | 221 | static struct flexcan_devtype_data fsl_imx6q_devtype_data = { |
222 | .features = FLEXCAN_HAS_V10_FEATURES, | 222 | .features = FLEXCAN_HAS_V10_FEATURES, |
223 | }; | 223 | }; |
224 | 224 | ||
225 | static const struct can_bittiming_const flexcan_bittiming_const = { | 225 | static const struct can_bittiming_const flexcan_bittiming_const = { |
226 | .name = DRV_NAME, | 226 | .name = DRV_NAME, |
227 | .tseg1_min = 4, | 227 | .tseg1_min = 4, |
228 | .tseg1_max = 16, | 228 | .tseg1_max = 16, |
229 | .tseg2_min = 2, | 229 | .tseg2_min = 2, |
230 | .tseg2_max = 8, | 230 | .tseg2_max = 8, |
231 | .sjw_max = 4, | 231 | .sjw_max = 4, |
232 | .brp_min = 1, | 232 | .brp_min = 1, |
233 | .brp_max = 256, | 233 | .brp_max = 256, |
234 | .brp_inc = 1, | 234 | .brp_inc = 1, |
235 | }; | 235 | }; |
236 | 236 | ||
237 | /* | 237 | /* |
238 | * Abstract off the read/write for arm versus ppc. | 238 | * Abstract off the read/write for arm versus ppc. |
239 | */ | 239 | */ |
240 | #if defined(__BIG_ENDIAN) | 240 | #if defined(__BIG_ENDIAN) |
241 | static inline u32 flexcan_read(void __iomem *addr) | 241 | static inline u32 flexcan_read(void __iomem *addr) |
242 | { | 242 | { |
243 | return in_be32(addr); | 243 | return in_be32(addr); |
244 | } | 244 | } |
245 | 245 | ||
246 | static inline void flexcan_write(u32 val, void __iomem *addr) | 246 | static inline void flexcan_write(u32 val, void __iomem *addr) |
247 | { | 247 | { |
248 | out_be32(addr, val); | 248 | out_be32(addr, val); |
249 | } | 249 | } |
250 | #else | 250 | #else |
251 | static inline u32 flexcan_read(void __iomem *addr) | 251 | static inline u32 flexcan_read(void __iomem *addr) |
252 | { | 252 | { |
253 | return readl(addr); | 253 | return readl(addr); |
254 | } | 254 | } |
255 | 255 | ||
256 | static inline void flexcan_write(u32 val, void __iomem *addr) | 256 | static inline void flexcan_write(u32 val, void __iomem *addr) |
257 | { | 257 | { |
258 | writel(val, addr); | 258 | writel(val, addr); |
259 | } | 259 | } |
260 | #endif | 260 | #endif |
261 | 261 | ||
262 | static inline int flexcan_has_and_handle_berr(const struct flexcan_priv *priv, | 262 | static inline int flexcan_has_and_handle_berr(const struct flexcan_priv *priv, |
263 | u32 reg_esr) | 263 | u32 reg_esr) |
264 | { | 264 | { |
265 | return (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) && | 265 | return (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) && |
266 | (reg_esr & FLEXCAN_ESR_ERR_BUS); | 266 | (reg_esr & FLEXCAN_ESR_ERR_BUS); |
267 | } | 267 | } |
268 | 268 | ||
269 | static inline void flexcan_chip_enable(struct flexcan_priv *priv) | 269 | static inline void flexcan_chip_enable(struct flexcan_priv *priv) |
270 | { | 270 | { |
271 | struct flexcan_regs __iomem *regs = priv->base; | 271 | struct flexcan_regs __iomem *regs = priv->base; |
272 | u32 reg; | 272 | u32 reg; |
273 | 273 | ||
274 | reg = flexcan_read(®s->mcr); | 274 | reg = flexcan_read(®s->mcr); |
275 | reg &= ~FLEXCAN_MCR_MDIS; | 275 | reg &= ~FLEXCAN_MCR_MDIS; |
276 | flexcan_write(reg, ®s->mcr); | 276 | flexcan_write(reg, ®s->mcr); |
277 | 277 | ||
278 | udelay(10); | 278 | udelay(10); |
279 | } | 279 | } |
280 | 280 | ||
281 | static inline void flexcan_chip_disable(struct flexcan_priv *priv) | 281 | static inline void flexcan_chip_disable(struct flexcan_priv *priv) |
282 | { | 282 | { |
283 | struct flexcan_regs __iomem *regs = priv->base; | 283 | struct flexcan_regs __iomem *regs = priv->base; |
284 | u32 reg; | 284 | u32 reg; |
285 | 285 | ||
286 | reg = flexcan_read(®s->mcr); | 286 | reg = flexcan_read(®s->mcr); |
287 | reg |= FLEXCAN_MCR_MDIS; | 287 | reg |= FLEXCAN_MCR_MDIS; |
288 | flexcan_write(reg, ®s->mcr); | 288 | flexcan_write(reg, ®s->mcr); |
289 | } | 289 | } |
290 | 290 | ||
291 | static int flexcan_get_berr_counter(const struct net_device *dev, | 291 | static int flexcan_get_berr_counter(const struct net_device *dev, |
292 | struct can_berr_counter *bec) | 292 | struct can_berr_counter *bec) |
293 | { | 293 | { |
294 | const struct flexcan_priv *priv = netdev_priv(dev); | 294 | const struct flexcan_priv *priv = netdev_priv(dev); |
295 | struct flexcan_regs __iomem *regs = priv->base; | 295 | struct flexcan_regs __iomem *regs = priv->base; |
296 | u32 reg = flexcan_read(®s->ecr); | 296 | u32 reg = flexcan_read(®s->ecr); |
297 | 297 | ||
298 | bec->txerr = (reg >> 0) & 0xff; | 298 | bec->txerr = (reg >> 0) & 0xff; |
299 | bec->rxerr = (reg >> 8) & 0xff; | 299 | bec->rxerr = (reg >> 8) & 0xff; |
300 | 300 | ||
301 | return 0; | 301 | return 0; |
302 | } | 302 | } |
303 | 303 | ||
304 | static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev) | 304 | static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev) |
305 | { | 305 | { |
306 | const struct flexcan_priv *priv = netdev_priv(dev); | 306 | const struct flexcan_priv *priv = netdev_priv(dev); |
307 | struct flexcan_regs __iomem *regs = priv->base; | 307 | struct flexcan_regs __iomem *regs = priv->base; |
308 | struct can_frame *cf = (struct can_frame *)skb->data; | 308 | struct can_frame *cf = (struct can_frame *)skb->data; |
309 | u32 can_id; | 309 | u32 can_id; |
310 | u32 ctrl = FLEXCAN_MB_CNT_CODE(0xc) | (cf->can_dlc << 16); | 310 | u32 ctrl = FLEXCAN_MB_CNT_CODE(0xc) | (cf->can_dlc << 16); |
311 | 311 | ||
312 | if (can_dropped_invalid_skb(dev, skb)) | 312 | if (can_dropped_invalid_skb(dev, skb)) |
313 | return NETDEV_TX_OK; | 313 | return NETDEV_TX_OK; |
314 | 314 | ||
315 | netif_stop_queue(dev); | 315 | netif_stop_queue(dev); |
316 | 316 | ||
317 | if (cf->can_id & CAN_EFF_FLAG) { | 317 | if (cf->can_id & CAN_EFF_FLAG) { |
318 | can_id = cf->can_id & CAN_EFF_MASK; | 318 | can_id = cf->can_id & CAN_EFF_MASK; |
319 | ctrl |= FLEXCAN_MB_CNT_IDE | FLEXCAN_MB_CNT_SRR; | 319 | ctrl |= FLEXCAN_MB_CNT_IDE | FLEXCAN_MB_CNT_SRR; |
320 | } else { | 320 | } else { |
321 | can_id = (cf->can_id & CAN_SFF_MASK) << 18; | 321 | can_id = (cf->can_id & CAN_SFF_MASK) << 18; |
322 | } | 322 | } |
323 | 323 | ||
324 | if (cf->can_id & CAN_RTR_FLAG) | 324 | if (cf->can_id & CAN_RTR_FLAG) |
325 | ctrl |= FLEXCAN_MB_CNT_RTR; | 325 | ctrl |= FLEXCAN_MB_CNT_RTR; |
326 | 326 | ||
327 | if (cf->can_dlc > 0) { | 327 | if (cf->can_dlc > 0) { |
328 | u32 data = be32_to_cpup((__be32 *)&cf->data[0]); | 328 | u32 data = be32_to_cpup((__be32 *)&cf->data[0]); |
329 | flexcan_write(data, ®s->cantxfg[FLEXCAN_TX_BUF_ID].data[0]); | 329 | flexcan_write(data, ®s->cantxfg[FLEXCAN_TX_BUF_ID].data[0]); |
330 | } | 330 | } |
331 | if (cf->can_dlc > 3) { | 331 | if (cf->can_dlc > 3) { |
332 | u32 data = be32_to_cpup((__be32 *)&cf->data[4]); | 332 | u32 data = be32_to_cpup((__be32 *)&cf->data[4]); |
333 | flexcan_write(data, ®s->cantxfg[FLEXCAN_TX_BUF_ID].data[1]); | 333 | flexcan_write(data, ®s->cantxfg[FLEXCAN_TX_BUF_ID].data[1]); |
334 | } | 334 | } |
335 | 335 | ||
336 | can_put_echo_skb(skb, dev, 0); | 336 | can_put_echo_skb(skb, dev, 0); |
337 | 337 | ||
338 | flexcan_write(can_id, ®s->cantxfg[FLEXCAN_TX_BUF_ID].can_id); | 338 | flexcan_write(can_id, ®s->cantxfg[FLEXCAN_TX_BUF_ID].can_id); |
339 | flexcan_write(ctrl, ®s->cantxfg[FLEXCAN_TX_BUF_ID].can_ctrl); | 339 | flexcan_write(ctrl, ®s->cantxfg[FLEXCAN_TX_BUF_ID].can_ctrl); |
340 | 340 | ||
341 | return NETDEV_TX_OK; | 341 | return NETDEV_TX_OK; |
342 | } | 342 | } |
343 | 343 | ||
344 | static void do_bus_err(struct net_device *dev, | 344 | static void do_bus_err(struct net_device *dev, |
345 | struct can_frame *cf, u32 reg_esr) | 345 | struct can_frame *cf, u32 reg_esr) |
346 | { | 346 | { |
347 | struct flexcan_priv *priv = netdev_priv(dev); | 347 | struct flexcan_priv *priv = netdev_priv(dev); |
348 | int rx_errors = 0, tx_errors = 0; | 348 | int rx_errors = 0, tx_errors = 0; |
349 | 349 | ||
350 | cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; | 350 | cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; |
351 | 351 | ||
352 | if (reg_esr & FLEXCAN_ESR_BIT1_ERR) { | 352 | if (reg_esr & FLEXCAN_ESR_BIT1_ERR) { |
353 | netdev_dbg(dev, "BIT1_ERR irq\n"); | 353 | netdev_dbg(dev, "BIT1_ERR irq\n"); |
354 | cf->data[2] |= CAN_ERR_PROT_BIT1; | 354 | cf->data[2] |= CAN_ERR_PROT_BIT1; |
355 | tx_errors = 1; | 355 | tx_errors = 1; |
356 | } | 356 | } |
357 | if (reg_esr & FLEXCAN_ESR_BIT0_ERR) { | 357 | if (reg_esr & FLEXCAN_ESR_BIT0_ERR) { |
358 | netdev_dbg(dev, "BIT0_ERR irq\n"); | 358 | netdev_dbg(dev, "BIT0_ERR irq\n"); |
359 | cf->data[2] |= CAN_ERR_PROT_BIT0; | 359 | cf->data[2] |= CAN_ERR_PROT_BIT0; |
360 | tx_errors = 1; | 360 | tx_errors = 1; |
361 | } | 361 | } |
362 | if (reg_esr & FLEXCAN_ESR_ACK_ERR) { | 362 | if (reg_esr & FLEXCAN_ESR_ACK_ERR) { |
363 | netdev_dbg(dev, "ACK_ERR irq\n"); | 363 | netdev_dbg(dev, "ACK_ERR irq\n"); |
364 | cf->can_id |= CAN_ERR_ACK; | 364 | cf->can_id |= CAN_ERR_ACK; |
365 | cf->data[3] |= CAN_ERR_PROT_LOC_ACK; | 365 | cf->data[3] |= CAN_ERR_PROT_LOC_ACK; |
366 | tx_errors = 1; | 366 | tx_errors = 1; |
367 | } | 367 | } |
368 | if (reg_esr & FLEXCAN_ESR_CRC_ERR) { | 368 | if (reg_esr & FLEXCAN_ESR_CRC_ERR) { |
369 | netdev_dbg(dev, "CRC_ERR irq\n"); | 369 | netdev_dbg(dev, "CRC_ERR irq\n"); |
370 | cf->data[2] |= CAN_ERR_PROT_BIT; | 370 | cf->data[2] |= CAN_ERR_PROT_BIT; |
371 | cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ; | 371 | cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ; |
372 | rx_errors = 1; | 372 | rx_errors = 1; |
373 | } | 373 | } |
374 | if (reg_esr & FLEXCAN_ESR_FRM_ERR) { | 374 | if (reg_esr & FLEXCAN_ESR_FRM_ERR) { |
375 | netdev_dbg(dev, "FRM_ERR irq\n"); | 375 | netdev_dbg(dev, "FRM_ERR irq\n"); |
376 | cf->data[2] |= CAN_ERR_PROT_FORM; | 376 | cf->data[2] |= CAN_ERR_PROT_FORM; |
377 | rx_errors = 1; | 377 | rx_errors = 1; |
378 | } | 378 | } |
379 | if (reg_esr & FLEXCAN_ESR_STF_ERR) { | 379 | if (reg_esr & FLEXCAN_ESR_STF_ERR) { |
380 | netdev_dbg(dev, "STF_ERR irq\n"); | 380 | netdev_dbg(dev, "STF_ERR irq\n"); |
381 | cf->data[2] |= CAN_ERR_PROT_STUFF; | 381 | cf->data[2] |= CAN_ERR_PROT_STUFF; |
382 | rx_errors = 1; | 382 | rx_errors = 1; |
383 | } | 383 | } |
384 | 384 | ||
385 | priv->can.can_stats.bus_error++; | 385 | priv->can.can_stats.bus_error++; |
386 | if (rx_errors) | 386 | if (rx_errors) |
387 | dev->stats.rx_errors++; | 387 | dev->stats.rx_errors++; |
388 | if (tx_errors) | 388 | if (tx_errors) |
389 | dev->stats.tx_errors++; | 389 | dev->stats.tx_errors++; |
390 | } | 390 | } |
391 | 391 | ||
392 | static int flexcan_poll_bus_err(struct net_device *dev, u32 reg_esr) | 392 | static int flexcan_poll_bus_err(struct net_device *dev, u32 reg_esr) |
393 | { | 393 | { |
394 | struct sk_buff *skb; | 394 | struct sk_buff *skb; |
395 | struct can_frame *cf; | 395 | struct can_frame *cf; |
396 | 396 | ||
397 | skb = alloc_can_err_skb(dev, &cf); | 397 | skb = alloc_can_err_skb(dev, &cf); |
398 | if (unlikely(!skb)) | 398 | if (unlikely(!skb)) |
399 | return 0; | 399 | return 0; |
400 | 400 | ||
401 | do_bus_err(dev, cf, reg_esr); | 401 | do_bus_err(dev, cf, reg_esr); |
402 | netif_receive_skb(skb); | 402 | netif_receive_skb(skb); |
403 | 403 | ||
404 | dev->stats.rx_packets++; | 404 | dev->stats.rx_packets++; |
405 | dev->stats.rx_bytes += cf->can_dlc; | 405 | dev->stats.rx_bytes += cf->can_dlc; |
406 | 406 | ||
407 | return 1; | 407 | return 1; |
408 | } | 408 | } |
409 | 409 | ||
410 | static void do_state(struct net_device *dev, | 410 | static void do_state(struct net_device *dev, |
411 | struct can_frame *cf, enum can_state new_state) | 411 | struct can_frame *cf, enum can_state new_state) |
412 | { | 412 | { |
413 | struct flexcan_priv *priv = netdev_priv(dev); | 413 | struct flexcan_priv *priv = netdev_priv(dev); |
414 | struct can_berr_counter bec; | 414 | struct can_berr_counter bec; |
415 | 415 | ||
416 | flexcan_get_berr_counter(dev, &bec); | 416 | flexcan_get_berr_counter(dev, &bec); |
417 | 417 | ||
418 | switch (priv->can.state) { | 418 | switch (priv->can.state) { |
419 | case CAN_STATE_ERROR_ACTIVE: | 419 | case CAN_STATE_ERROR_ACTIVE: |
420 | /* | 420 | /* |
421 | * from: ERROR_ACTIVE | 421 | * from: ERROR_ACTIVE |
422 | * to : ERROR_WARNING, ERROR_PASSIVE, BUS_OFF | 422 | * to : ERROR_WARNING, ERROR_PASSIVE, BUS_OFF |
423 | * => : there was a warning int | 423 | * => : there was a warning int |
424 | */ | 424 | */ |
425 | if (new_state >= CAN_STATE_ERROR_WARNING && | 425 | if (new_state >= CAN_STATE_ERROR_WARNING && |
426 | new_state <= CAN_STATE_BUS_OFF) { | 426 | new_state <= CAN_STATE_BUS_OFF) { |
427 | netdev_dbg(dev, "Error Warning IRQ\n"); | 427 | netdev_dbg(dev, "Error Warning IRQ\n"); |
428 | priv->can.can_stats.error_warning++; | 428 | priv->can.can_stats.error_warning++; |
429 | 429 | ||
430 | cf->can_id |= CAN_ERR_CRTL; | 430 | cf->can_id |= CAN_ERR_CRTL; |
431 | cf->data[1] = (bec.txerr > bec.rxerr) ? | 431 | cf->data[1] = (bec.txerr > bec.rxerr) ? |
432 | CAN_ERR_CRTL_TX_WARNING : | 432 | CAN_ERR_CRTL_TX_WARNING : |
433 | CAN_ERR_CRTL_RX_WARNING; | 433 | CAN_ERR_CRTL_RX_WARNING; |
434 | } | 434 | } |
435 | case CAN_STATE_ERROR_WARNING: /* fallthrough */ | 435 | case CAN_STATE_ERROR_WARNING: /* fallthrough */ |
436 | /* | 436 | /* |
437 | * from: ERROR_ACTIVE, ERROR_WARNING | 437 | * from: ERROR_ACTIVE, ERROR_WARNING |
438 | * to : ERROR_PASSIVE, BUS_OFF | 438 | * to : ERROR_PASSIVE, BUS_OFF |
439 | * => : error passive int | 439 | * => : error passive int |
440 | */ | 440 | */ |
441 | if (new_state >= CAN_STATE_ERROR_PASSIVE && | 441 | if (new_state >= CAN_STATE_ERROR_PASSIVE && |
442 | new_state <= CAN_STATE_BUS_OFF) { | 442 | new_state <= CAN_STATE_BUS_OFF) { |
443 | netdev_dbg(dev, "Error Passive IRQ\n"); | 443 | netdev_dbg(dev, "Error Passive IRQ\n"); |
444 | priv->can.can_stats.error_passive++; | 444 | priv->can.can_stats.error_passive++; |
445 | 445 | ||
446 | cf->can_id |= CAN_ERR_CRTL; | 446 | cf->can_id |= CAN_ERR_CRTL; |
447 | cf->data[1] = (bec.txerr > bec.rxerr) ? | 447 | cf->data[1] = (bec.txerr > bec.rxerr) ? |
448 | CAN_ERR_CRTL_TX_PASSIVE : | 448 | CAN_ERR_CRTL_TX_PASSIVE : |
449 | CAN_ERR_CRTL_RX_PASSIVE; | 449 | CAN_ERR_CRTL_RX_PASSIVE; |
450 | } | 450 | } |
451 | break; | 451 | break; |
452 | case CAN_STATE_BUS_OFF: | 452 | case CAN_STATE_BUS_OFF: |
453 | netdev_err(dev, "BUG! " | 453 | netdev_err(dev, "BUG! " |
454 | "hardware recovered automatically from BUS_OFF\n"); | 454 | "hardware recovered automatically from BUS_OFF\n"); |
455 | break; | 455 | break; |
456 | default: | 456 | default: |
457 | break; | 457 | break; |
458 | } | 458 | } |
459 | 459 | ||
460 | /* process state changes depending on the new state */ | 460 | /* process state changes depending on the new state */ |
461 | switch (new_state) { | 461 | switch (new_state) { |
462 | case CAN_STATE_ERROR_ACTIVE: | 462 | case CAN_STATE_ERROR_ACTIVE: |
463 | netdev_dbg(dev, "Error Active\n"); | 463 | netdev_dbg(dev, "Error Active\n"); |
464 | cf->can_id |= CAN_ERR_PROT; | 464 | cf->can_id |= CAN_ERR_PROT; |
465 | cf->data[2] = CAN_ERR_PROT_ACTIVE; | 465 | cf->data[2] = CAN_ERR_PROT_ACTIVE; |
466 | break; | 466 | break; |
467 | case CAN_STATE_BUS_OFF: | 467 | case CAN_STATE_BUS_OFF: |
468 | cf->can_id |= CAN_ERR_BUSOFF; | 468 | cf->can_id |= CAN_ERR_BUSOFF; |
469 | can_bus_off(dev); | 469 | can_bus_off(dev); |
470 | break; | 470 | break; |
471 | default: | 471 | default: |
472 | break; | 472 | break; |
473 | } | 473 | } |
474 | } | 474 | } |
475 | 475 | ||
476 | static int flexcan_poll_state(struct net_device *dev, u32 reg_esr) | 476 | static int flexcan_poll_state(struct net_device *dev, u32 reg_esr) |
477 | { | 477 | { |
478 | struct flexcan_priv *priv = netdev_priv(dev); | 478 | struct flexcan_priv *priv = netdev_priv(dev); |
479 | struct sk_buff *skb; | 479 | struct sk_buff *skb; |
480 | struct can_frame *cf; | 480 | struct can_frame *cf; |
481 | enum can_state new_state; | 481 | enum can_state new_state; |
482 | int flt; | 482 | int flt; |
483 | 483 | ||
484 | flt = reg_esr & FLEXCAN_ESR_FLT_CONF_MASK; | 484 | flt = reg_esr & FLEXCAN_ESR_FLT_CONF_MASK; |
485 | if (likely(flt == FLEXCAN_ESR_FLT_CONF_ACTIVE)) { | 485 | if (likely(flt == FLEXCAN_ESR_FLT_CONF_ACTIVE)) { |
486 | if (likely(!(reg_esr & (FLEXCAN_ESR_TX_WRN | | 486 | if (likely(!(reg_esr & (FLEXCAN_ESR_TX_WRN | |
487 | FLEXCAN_ESR_RX_WRN)))) | 487 | FLEXCAN_ESR_RX_WRN)))) |
488 | new_state = CAN_STATE_ERROR_ACTIVE; | 488 | new_state = CAN_STATE_ERROR_ACTIVE; |
489 | else | 489 | else |
490 | new_state = CAN_STATE_ERROR_WARNING; | 490 | new_state = CAN_STATE_ERROR_WARNING; |
491 | } else if (unlikely(flt == FLEXCAN_ESR_FLT_CONF_PASSIVE)) | 491 | } else if (unlikely(flt == FLEXCAN_ESR_FLT_CONF_PASSIVE)) |
492 | new_state = CAN_STATE_ERROR_PASSIVE; | 492 | new_state = CAN_STATE_ERROR_PASSIVE; |
493 | else | 493 | else |
494 | new_state = CAN_STATE_BUS_OFF; | 494 | new_state = CAN_STATE_BUS_OFF; |
495 | 495 | ||
496 | /* state hasn't changed */ | 496 | /* state hasn't changed */ |
497 | if (likely(new_state == priv->can.state)) | 497 | if (likely(new_state == priv->can.state)) |
498 | return 0; | 498 | return 0; |
499 | 499 | ||
500 | skb = alloc_can_err_skb(dev, &cf); | 500 | skb = alloc_can_err_skb(dev, &cf); |
501 | if (unlikely(!skb)) | 501 | if (unlikely(!skb)) |
502 | return 0; | 502 | return 0; |
503 | 503 | ||
504 | do_state(dev, cf, new_state); | 504 | do_state(dev, cf, new_state); |
505 | priv->can.state = new_state; | 505 | priv->can.state = new_state; |
506 | netif_receive_skb(skb); | 506 | netif_receive_skb(skb); |
507 | 507 | ||
508 | dev->stats.rx_packets++; | 508 | dev->stats.rx_packets++; |
509 | dev->stats.rx_bytes += cf->can_dlc; | 509 | dev->stats.rx_bytes += cf->can_dlc; |
510 | 510 | ||
511 | return 1; | 511 | return 1; |
512 | } | 512 | } |
513 | 513 | ||
514 | static void flexcan_read_fifo(const struct net_device *dev, | 514 | static void flexcan_read_fifo(const struct net_device *dev, |
515 | struct can_frame *cf) | 515 | struct can_frame *cf) |
516 | { | 516 | { |
517 | const struct flexcan_priv *priv = netdev_priv(dev); | 517 | const struct flexcan_priv *priv = netdev_priv(dev); |
518 | struct flexcan_regs __iomem *regs = priv->base; | 518 | struct flexcan_regs __iomem *regs = priv->base; |
519 | struct flexcan_mb __iomem *mb = ®s->cantxfg[0]; | 519 | struct flexcan_mb __iomem *mb = ®s->cantxfg[0]; |
520 | u32 reg_ctrl, reg_id; | 520 | u32 reg_ctrl, reg_id; |
521 | 521 | ||
522 | reg_ctrl = flexcan_read(&mb->can_ctrl); | 522 | reg_ctrl = flexcan_read(&mb->can_ctrl); |
523 | reg_id = flexcan_read(&mb->can_id); | 523 | reg_id = flexcan_read(&mb->can_id); |
524 | if (reg_ctrl & FLEXCAN_MB_CNT_IDE) | 524 | if (reg_ctrl & FLEXCAN_MB_CNT_IDE) |
525 | cf->can_id = ((reg_id >> 0) & CAN_EFF_MASK) | CAN_EFF_FLAG; | 525 | cf->can_id = ((reg_id >> 0) & CAN_EFF_MASK) | CAN_EFF_FLAG; |
526 | else | 526 | else |
527 | cf->can_id = (reg_id >> 18) & CAN_SFF_MASK; | 527 | cf->can_id = (reg_id >> 18) & CAN_SFF_MASK; |
528 | 528 | ||
529 | if (reg_ctrl & FLEXCAN_MB_CNT_RTR) | 529 | if (reg_ctrl & FLEXCAN_MB_CNT_RTR) |
530 | cf->can_id |= CAN_RTR_FLAG; | 530 | cf->can_id |= CAN_RTR_FLAG; |
531 | cf->can_dlc = get_can_dlc((reg_ctrl >> 16) & 0xf); | 531 | cf->can_dlc = get_can_dlc((reg_ctrl >> 16) & 0xf); |
532 | 532 | ||
533 | *(__be32 *)(cf->data + 0) = cpu_to_be32(flexcan_read(&mb->data[0])); | 533 | *(__be32 *)(cf->data + 0) = cpu_to_be32(flexcan_read(&mb->data[0])); |
534 | *(__be32 *)(cf->data + 4) = cpu_to_be32(flexcan_read(&mb->data[1])); | 534 | *(__be32 *)(cf->data + 4) = cpu_to_be32(flexcan_read(&mb->data[1])); |
535 | 535 | ||
536 | /* mark as read */ | 536 | /* mark as read */ |
537 | flexcan_write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1); | 537 | flexcan_write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1); |
538 | flexcan_read(®s->timer); | 538 | flexcan_read(®s->timer); |
539 | } | 539 | } |
540 | 540 | ||
541 | static int flexcan_read_frame(struct net_device *dev) | 541 | static int flexcan_read_frame(struct net_device *dev) |
542 | { | 542 | { |
543 | struct net_device_stats *stats = &dev->stats; | 543 | struct net_device_stats *stats = &dev->stats; |
544 | struct can_frame *cf; | 544 | struct can_frame *cf; |
545 | struct sk_buff *skb; | 545 | struct sk_buff *skb; |
546 | 546 | ||
547 | skb = alloc_can_skb(dev, &cf); | 547 | skb = alloc_can_skb(dev, &cf); |
548 | if (unlikely(!skb)) { | 548 | if (unlikely(!skb)) { |
549 | stats->rx_dropped++; | 549 | stats->rx_dropped++; |
550 | return 0; | 550 | return 0; |
551 | } | 551 | } |
552 | 552 | ||
553 | flexcan_read_fifo(dev, cf); | 553 | flexcan_read_fifo(dev, cf); |
554 | netif_receive_skb(skb); | 554 | netif_receive_skb(skb); |
555 | 555 | ||
556 | stats->rx_packets++; | 556 | stats->rx_packets++; |
557 | stats->rx_bytes += cf->can_dlc; | 557 | stats->rx_bytes += cf->can_dlc; |
558 | 558 | ||
559 | can_led_event(dev, CAN_LED_EVENT_RX); | 559 | can_led_event(dev, CAN_LED_EVENT_RX); |
560 | 560 | ||
561 | return 1; | 561 | return 1; |
562 | } | 562 | } |
563 | 563 | ||
564 | static int flexcan_poll(struct napi_struct *napi, int quota) | 564 | static int flexcan_poll(struct napi_struct *napi, int quota) |
565 | { | 565 | { |
566 | struct net_device *dev = napi->dev; | 566 | struct net_device *dev = napi->dev; |
567 | const struct flexcan_priv *priv = netdev_priv(dev); | 567 | const struct flexcan_priv *priv = netdev_priv(dev); |
568 | struct flexcan_regs __iomem *regs = priv->base; | 568 | struct flexcan_regs __iomem *regs = priv->base; |
569 | u32 reg_iflag1, reg_esr; | 569 | u32 reg_iflag1, reg_esr; |
570 | int work_done = 0; | 570 | int work_done = 0; |
571 | 571 | ||
572 | /* | 572 | /* |
573 | * The error bits are cleared on read, | 573 | * The error bits are cleared on read, |
574 | * use saved value from irq handler. | 574 | * use saved value from irq handler. |
575 | */ | 575 | */ |
576 | reg_esr = flexcan_read(®s->esr) | priv->reg_esr; | 576 | reg_esr = flexcan_read(®s->esr) | priv->reg_esr; |
577 | 577 | ||
578 | /* handle state changes */ | 578 | /* handle state changes */ |
579 | work_done += flexcan_poll_state(dev, reg_esr); | 579 | work_done += flexcan_poll_state(dev, reg_esr); |
580 | 580 | ||
581 | /* handle RX-FIFO */ | 581 | /* handle RX-FIFO */ |
582 | reg_iflag1 = flexcan_read(®s->iflag1); | 582 | reg_iflag1 = flexcan_read(®s->iflag1); |
583 | while (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE && | 583 | while (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE && |
584 | work_done < quota) { | 584 | work_done < quota) { |
585 | work_done += flexcan_read_frame(dev); | 585 | work_done += flexcan_read_frame(dev); |
586 | reg_iflag1 = flexcan_read(®s->iflag1); | 586 | reg_iflag1 = flexcan_read(®s->iflag1); |
587 | } | 587 | } |
588 | 588 | ||
589 | /* report bus errors */ | 589 | /* report bus errors */ |
590 | if (flexcan_has_and_handle_berr(priv, reg_esr) && work_done < quota) | 590 | if (flexcan_has_and_handle_berr(priv, reg_esr) && work_done < quota) |
591 | work_done += flexcan_poll_bus_err(dev, reg_esr); | 591 | work_done += flexcan_poll_bus_err(dev, reg_esr); |
592 | 592 | ||
593 | if (work_done < quota) { | 593 | if (work_done < quota) { |
594 | napi_complete(napi); | 594 | napi_complete(napi); |
595 | /* enable IRQs */ | 595 | /* enable IRQs */ |
596 | flexcan_write(FLEXCAN_IFLAG_DEFAULT, ®s->imask1); | 596 | flexcan_write(FLEXCAN_IFLAG_DEFAULT, ®s->imask1); |
597 | flexcan_write(priv->reg_ctrl_default, ®s->ctrl); | 597 | flexcan_write(priv->reg_ctrl_default, ®s->ctrl); |
598 | } | 598 | } |
599 | 599 | ||
600 | return work_done; | 600 | return work_done; |
601 | } | 601 | } |
602 | 602 | ||
603 | static irqreturn_t flexcan_irq(int irq, void *dev_id) | 603 | static irqreturn_t flexcan_irq(int irq, void *dev_id) |
604 | { | 604 | { |
605 | struct net_device *dev = dev_id; | 605 | struct net_device *dev = dev_id; |
606 | struct net_device_stats *stats = &dev->stats; | 606 | struct net_device_stats *stats = &dev->stats; |
607 | struct flexcan_priv *priv = netdev_priv(dev); | 607 | struct flexcan_priv *priv = netdev_priv(dev); |
608 | struct flexcan_regs __iomem *regs = priv->base; | 608 | struct flexcan_regs __iomem *regs = priv->base; |
609 | u32 reg_iflag1, reg_esr; | 609 | u32 reg_iflag1, reg_esr; |
610 | 610 | ||
611 | reg_iflag1 = flexcan_read(®s->iflag1); | 611 | reg_iflag1 = flexcan_read(®s->iflag1); |
612 | reg_esr = flexcan_read(®s->esr); | 612 | reg_esr = flexcan_read(®s->esr); |
613 | /* ACK all bus error and state change IRQ sources */ | 613 | /* ACK all bus error and state change IRQ sources */ |
614 | if (reg_esr & FLEXCAN_ESR_ALL_INT) | 614 | if (reg_esr & FLEXCAN_ESR_ALL_INT) |
615 | flexcan_write(reg_esr & FLEXCAN_ESR_ALL_INT, ®s->esr); | 615 | flexcan_write(reg_esr & FLEXCAN_ESR_ALL_INT, ®s->esr); |
616 | 616 | ||
617 | /* | 617 | /* |
618 | * schedule NAPI in case of: | 618 | * schedule NAPI in case of: |
619 | * - rx IRQ | 619 | * - rx IRQ |
620 | * - state change IRQ | 620 | * - state change IRQ |
621 | * - bus error IRQ and bus error reporting is activated | 621 | * - bus error IRQ and bus error reporting is activated |
622 | */ | 622 | */ |
623 | if ((reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE) || | 623 | if ((reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE) || |
624 | (reg_esr & FLEXCAN_ESR_ERR_STATE) || | 624 | (reg_esr & FLEXCAN_ESR_ERR_STATE) || |
625 | flexcan_has_and_handle_berr(priv, reg_esr)) { | 625 | flexcan_has_and_handle_berr(priv, reg_esr)) { |
626 | /* | 626 | /* |
627 | * The error bits are cleared on read, | 627 | * The error bits are cleared on read, |
628 | * save them for later use. | 628 | * save them for later use. |
629 | */ | 629 | */ |
630 | priv->reg_esr = reg_esr & FLEXCAN_ESR_ERR_BUS; | 630 | priv->reg_esr = reg_esr & FLEXCAN_ESR_ERR_BUS; |
631 | flexcan_write(FLEXCAN_IFLAG_DEFAULT & | 631 | flexcan_write(FLEXCAN_IFLAG_DEFAULT & |
632 | ~FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->imask1); | 632 | ~FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->imask1); |
633 | flexcan_write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL, | 633 | flexcan_write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL, |
634 | ®s->ctrl); | 634 | ®s->ctrl); |
635 | napi_schedule(&priv->napi); | 635 | napi_schedule(&priv->napi); |
636 | } | 636 | } |
637 | 637 | ||
638 | /* FIFO overflow */ | 638 | /* FIFO overflow */ |
639 | if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_OVERFLOW) { | 639 | if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_OVERFLOW) { |
640 | flexcan_write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW, ®s->iflag1); | 640 | flexcan_write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW, ®s->iflag1); |
641 | dev->stats.rx_over_errors++; | 641 | dev->stats.rx_over_errors++; |
642 | dev->stats.rx_errors++; | 642 | dev->stats.rx_errors++; |
643 | } | 643 | } |
644 | 644 | ||
645 | /* transmission complete interrupt */ | 645 | /* transmission complete interrupt */ |
646 | if (reg_iflag1 & (1 << FLEXCAN_TX_BUF_ID)) { | 646 | if (reg_iflag1 & (1 << FLEXCAN_TX_BUF_ID)) { |
647 | stats->tx_bytes += can_get_echo_skb(dev, 0); | 647 | stats->tx_bytes += can_get_echo_skb(dev, 0); |
648 | stats->tx_packets++; | 648 | stats->tx_packets++; |
649 | can_led_event(dev, CAN_LED_EVENT_TX); | 649 | can_led_event(dev, CAN_LED_EVENT_TX); |
650 | flexcan_write((1 << FLEXCAN_TX_BUF_ID), ®s->iflag1); | 650 | flexcan_write((1 << FLEXCAN_TX_BUF_ID), ®s->iflag1); |
651 | netif_wake_queue(dev); | 651 | netif_wake_queue(dev); |
652 | } | 652 | } |
653 | 653 | ||
654 | return IRQ_HANDLED; | 654 | return IRQ_HANDLED; |
655 | } | 655 | } |
656 | 656 | ||
657 | static void flexcan_set_bittiming(struct net_device *dev) | 657 | static void flexcan_set_bittiming(struct net_device *dev) |
658 | { | 658 | { |
659 | const struct flexcan_priv *priv = netdev_priv(dev); | 659 | const struct flexcan_priv *priv = netdev_priv(dev); |
660 | const struct can_bittiming *bt = &priv->can.bittiming; | 660 | const struct can_bittiming *bt = &priv->can.bittiming; |
661 | struct flexcan_regs __iomem *regs = priv->base; | 661 | struct flexcan_regs __iomem *regs = priv->base; |
662 | u32 reg; | 662 | u32 reg; |
663 | 663 | ||
664 | reg = flexcan_read(®s->ctrl); | 664 | reg = flexcan_read(®s->ctrl); |
665 | reg &= ~(FLEXCAN_CTRL_PRESDIV(0xff) | | 665 | reg &= ~(FLEXCAN_CTRL_PRESDIV(0xff) | |
666 | FLEXCAN_CTRL_RJW(0x3) | | 666 | FLEXCAN_CTRL_RJW(0x3) | |
667 | FLEXCAN_CTRL_PSEG1(0x7) | | 667 | FLEXCAN_CTRL_PSEG1(0x7) | |
668 | FLEXCAN_CTRL_PSEG2(0x7) | | 668 | FLEXCAN_CTRL_PSEG2(0x7) | |
669 | FLEXCAN_CTRL_PROPSEG(0x7) | | 669 | FLEXCAN_CTRL_PROPSEG(0x7) | |
670 | FLEXCAN_CTRL_LPB | | 670 | FLEXCAN_CTRL_LPB | |
671 | FLEXCAN_CTRL_SMP | | 671 | FLEXCAN_CTRL_SMP | |
672 | FLEXCAN_CTRL_LOM); | 672 | FLEXCAN_CTRL_LOM); |
673 | 673 | ||
674 | reg |= FLEXCAN_CTRL_PRESDIV(bt->brp - 1) | | 674 | reg |= FLEXCAN_CTRL_PRESDIV(bt->brp - 1) | |
675 | FLEXCAN_CTRL_PSEG1(bt->phase_seg1 - 1) | | 675 | FLEXCAN_CTRL_PSEG1(bt->phase_seg1 - 1) | |
676 | FLEXCAN_CTRL_PSEG2(bt->phase_seg2 - 1) | | 676 | FLEXCAN_CTRL_PSEG2(bt->phase_seg2 - 1) | |
677 | FLEXCAN_CTRL_RJW(bt->sjw - 1) | | 677 | FLEXCAN_CTRL_RJW(bt->sjw - 1) | |
678 | FLEXCAN_CTRL_PROPSEG(bt->prop_seg - 1); | 678 | FLEXCAN_CTRL_PROPSEG(bt->prop_seg - 1); |
679 | 679 | ||
680 | if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) | 680 | if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) |
681 | reg |= FLEXCAN_CTRL_LPB; | 681 | reg |= FLEXCAN_CTRL_LPB; |
682 | if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) | 682 | if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) |
683 | reg |= FLEXCAN_CTRL_LOM; | 683 | reg |= FLEXCAN_CTRL_LOM; |
684 | if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) | 684 | if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) |
685 | reg |= FLEXCAN_CTRL_SMP; | 685 | reg |= FLEXCAN_CTRL_SMP; |
686 | 686 | ||
687 | netdev_info(dev, "writing ctrl=0x%08x\n", reg); | 687 | netdev_info(dev, "writing ctrl=0x%08x\n", reg); |
688 | flexcan_write(reg, ®s->ctrl); | 688 | flexcan_write(reg, ®s->ctrl); |
689 | 689 | ||
690 | /* print chip status */ | 690 | /* print chip status */ |
691 | netdev_dbg(dev, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__, | 691 | netdev_dbg(dev, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__, |
692 | flexcan_read(®s->mcr), flexcan_read(®s->ctrl)); | 692 | flexcan_read(®s->mcr), flexcan_read(®s->ctrl)); |
693 | } | 693 | } |
694 | 694 | ||
695 | /* | 695 | /* |
696 | * flexcan_chip_start | 696 | * flexcan_chip_start |
697 | * | 697 | * |
698 | * this functions is entered with clocks enabled | 698 | * this functions is entered with clocks enabled |
699 | * | 699 | * |
700 | */ | 700 | */ |
701 | static int flexcan_chip_start(struct net_device *dev) | 701 | static int flexcan_chip_start(struct net_device *dev) |
702 | { | 702 | { |
703 | struct flexcan_priv *priv = netdev_priv(dev); | 703 | struct flexcan_priv *priv = netdev_priv(dev); |
704 | struct flexcan_regs __iomem *regs = priv->base; | 704 | struct flexcan_regs __iomem *regs = priv->base; |
705 | int err; | 705 | int err; |
706 | u32 reg_mcr, reg_ctrl; | 706 | u32 reg_mcr, reg_ctrl; |
707 | 707 | ||
708 | /* enable module */ | 708 | /* enable module */ |
709 | flexcan_chip_enable(priv); | 709 | flexcan_chip_enable(priv); |
710 | 710 | ||
711 | /* soft reset */ | 711 | /* soft reset */ |
712 | flexcan_write(FLEXCAN_MCR_SOFTRST, ®s->mcr); | 712 | flexcan_write(FLEXCAN_MCR_SOFTRST, ®s->mcr); |
713 | udelay(10); | 713 | udelay(10); |
714 | 714 | ||
715 | reg_mcr = flexcan_read(®s->mcr); | 715 | reg_mcr = flexcan_read(®s->mcr); |
716 | if (reg_mcr & FLEXCAN_MCR_SOFTRST) { | 716 | if (reg_mcr & FLEXCAN_MCR_SOFTRST) { |
717 | netdev_err(dev, "Failed to softreset can module (mcr=0x%08x)\n", | 717 | netdev_err(dev, "Failed to softreset can module (mcr=0x%08x)\n", |
718 | reg_mcr); | 718 | reg_mcr); |
719 | err = -ENODEV; | 719 | err = -ENODEV; |
720 | goto out; | 720 | goto out; |
721 | } | 721 | } |
722 | 722 | ||
723 | flexcan_set_bittiming(dev); | 723 | flexcan_set_bittiming(dev); |
724 | 724 | ||
725 | /* | 725 | /* |
726 | * MCR | 726 | * MCR |
727 | * | 727 | * |
728 | * enable freeze | 728 | * enable freeze |
729 | * enable fifo | 729 | * enable fifo |
730 | * halt now | 730 | * halt now |
731 | * only supervisor access | 731 | * only supervisor access |
732 | * enable warning int | 732 | * enable warning int |
733 | * choose format C | 733 | * choose format C |
734 | * disable local echo | 734 | * disable local echo |
735 | * | 735 | * |
736 | */ | 736 | */ |
737 | reg_mcr = flexcan_read(®s->mcr); | 737 | reg_mcr = flexcan_read(®s->mcr); |
738 | reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff); | 738 | reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff); |
739 | reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_FEN | FLEXCAN_MCR_HALT | | 739 | reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_FEN | FLEXCAN_MCR_HALT | |
740 | FLEXCAN_MCR_SUPV | FLEXCAN_MCR_WRN_EN | | 740 | FLEXCAN_MCR_SUPV | FLEXCAN_MCR_WRN_EN | |
741 | FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_SRX_DIS | | 741 | FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_SRX_DIS | |
742 | FLEXCAN_MCR_MAXMB(FLEXCAN_TX_BUF_ID); | 742 | FLEXCAN_MCR_MAXMB(FLEXCAN_TX_BUF_ID); |
743 | netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr); | 743 | netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr); |
744 | flexcan_write(reg_mcr, ®s->mcr); | 744 | flexcan_write(reg_mcr, ®s->mcr); |
745 | 745 | ||
746 | /* | 746 | /* |
747 | * CTRL | 747 | * CTRL |
748 | * | 748 | * |
749 | * disable timer sync feature | 749 | * disable timer sync feature |
750 | * | 750 | * |
751 | * disable auto busoff recovery | 751 | * disable auto busoff recovery |
752 | * transmit lowest buffer first | 752 | * transmit lowest buffer first |
753 | * | 753 | * |
754 | * enable tx and rx warning interrupt | 754 | * enable tx and rx warning interrupt |
755 | * enable bus off interrupt | 755 | * enable bus off interrupt |
756 | * (== FLEXCAN_CTRL_ERR_STATE) | 756 | * (== FLEXCAN_CTRL_ERR_STATE) |
757 | */ | 757 | */ |
758 | reg_ctrl = flexcan_read(®s->ctrl); | 758 | reg_ctrl = flexcan_read(®s->ctrl); |
759 | reg_ctrl &= ~FLEXCAN_CTRL_TSYN; | 759 | reg_ctrl &= ~FLEXCAN_CTRL_TSYN; |
760 | reg_ctrl |= FLEXCAN_CTRL_BOFF_REC | FLEXCAN_CTRL_LBUF | | 760 | reg_ctrl |= FLEXCAN_CTRL_BOFF_REC | FLEXCAN_CTRL_LBUF | |
761 | FLEXCAN_CTRL_ERR_STATE; | 761 | FLEXCAN_CTRL_ERR_STATE; |
762 | /* | 762 | /* |
763 | * enable the "error interrupt" (FLEXCAN_CTRL_ERR_MSK), | 763 | * enable the "error interrupt" (FLEXCAN_CTRL_ERR_MSK), |
764 | * on most Flexcan cores, too. Otherwise we don't get | 764 | * on most Flexcan cores, too. Otherwise we don't get |
765 | * any error warning or passive interrupts. | 765 | * any error warning or passive interrupts. |
766 | */ | 766 | */ |
767 | if (priv->devtype_data->features & FLEXCAN_HAS_BROKEN_ERR_STATE || | 767 | if (priv->devtype_data->features & FLEXCAN_HAS_BROKEN_ERR_STATE || |
768 | priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) | 768 | priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) |
769 | reg_ctrl |= FLEXCAN_CTRL_ERR_MSK; | 769 | reg_ctrl |= FLEXCAN_CTRL_ERR_MSK; |
770 | 770 | ||
771 | /* save for later use */ | 771 | /* save for later use */ |
772 | priv->reg_ctrl_default = reg_ctrl; | 772 | priv->reg_ctrl_default = reg_ctrl; |
773 | netdev_dbg(dev, "%s: writing ctrl=0x%08x", __func__, reg_ctrl); | 773 | netdev_dbg(dev, "%s: writing ctrl=0x%08x", __func__, reg_ctrl); |
774 | flexcan_write(reg_ctrl, ®s->ctrl); | 774 | flexcan_write(reg_ctrl, ®s->ctrl); |
775 | 775 | ||
776 | /* Abort any pending TX, mark Mailbox as INACTIVE */ | 776 | /* Abort any pending TX, mark Mailbox as INACTIVE */ |
777 | flexcan_write(FLEXCAN_MB_CNT_CODE(0x4), | 777 | flexcan_write(FLEXCAN_MB_CNT_CODE(0x4), |
778 | ®s->cantxfg[FLEXCAN_TX_BUF_ID].can_ctrl); | 778 | ®s->cantxfg[FLEXCAN_TX_BUF_ID].can_ctrl); |
779 | 779 | ||
780 | /* acceptance mask/acceptance code (accept everything) */ | 780 | /* acceptance mask/acceptance code (accept everything) */ |
781 | flexcan_write(0x0, ®s->rxgmask); | 781 | flexcan_write(0x0, ®s->rxgmask); |
782 | flexcan_write(0x0, ®s->rx14mask); | 782 | flexcan_write(0x0, ®s->rx14mask); |
783 | flexcan_write(0x0, ®s->rx15mask); | 783 | flexcan_write(0x0, ®s->rx15mask); |
784 | 784 | ||
785 | if (priv->devtype_data->features & FLEXCAN_HAS_V10_FEATURES) | 785 | if (priv->devtype_data->features & FLEXCAN_HAS_V10_FEATURES) |
786 | flexcan_write(0x0, ®s->rxfgmask); | 786 | flexcan_write(0x0, ®s->rxfgmask); |
787 | 787 | ||
788 | if (priv->reg_xceiver) { | 788 | if (priv->reg_xceiver) { |
789 | err = regulator_enable(priv->reg_xceiver); | 789 | err = regulator_enable(priv->reg_xceiver); |
790 | if (err) | 790 | if (err) |
791 | goto out; | 791 | goto out; |
792 | } | 792 | } |
793 | 793 | ||
794 | /* synchronize with the can bus */ | 794 | /* synchronize with the can bus */ |
795 | reg_mcr = flexcan_read(®s->mcr); | 795 | reg_mcr = flexcan_read(®s->mcr); |
796 | reg_mcr &= ~FLEXCAN_MCR_HALT; | 796 | reg_mcr &= ~FLEXCAN_MCR_HALT; |
797 | flexcan_write(reg_mcr, ®s->mcr); | 797 | flexcan_write(reg_mcr, ®s->mcr); |
798 | 798 | ||
799 | priv->can.state = CAN_STATE_ERROR_ACTIVE; | 799 | priv->can.state = CAN_STATE_ERROR_ACTIVE; |
800 | 800 | ||
801 | /* enable FIFO interrupts */ | 801 | /* enable FIFO interrupts */ |
802 | flexcan_write(FLEXCAN_IFLAG_DEFAULT, ®s->imask1); | 802 | flexcan_write(FLEXCAN_IFLAG_DEFAULT, ®s->imask1); |
803 | 803 | ||
804 | /* print chip status */ | 804 | /* print chip status */ |
805 | netdev_dbg(dev, "%s: reading mcr=0x%08x ctrl=0x%08x\n", __func__, | 805 | netdev_dbg(dev, "%s: reading mcr=0x%08x ctrl=0x%08x\n", __func__, |
806 | flexcan_read(®s->mcr), flexcan_read(®s->ctrl)); | 806 | flexcan_read(®s->mcr), flexcan_read(®s->ctrl)); |
807 | 807 | ||
808 | return 0; | 808 | return 0; |
809 | 809 | ||
810 | out: | 810 | out: |
811 | flexcan_chip_disable(priv); | 811 | flexcan_chip_disable(priv); |
812 | return err; | 812 | return err; |
813 | } | 813 | } |
814 | 814 | ||
815 | /* | 815 | /* |
816 | * flexcan_chip_stop | 816 | * flexcan_chip_stop |
817 | * | 817 | * |
818 | * this functions is entered with clocks enabled | 818 | * this functions is entered with clocks enabled |
819 | * | 819 | * |
820 | */ | 820 | */ |
821 | static void flexcan_chip_stop(struct net_device *dev) | 821 | static void flexcan_chip_stop(struct net_device *dev) |
822 | { | 822 | { |
823 | struct flexcan_priv *priv = netdev_priv(dev); | 823 | struct flexcan_priv *priv = netdev_priv(dev); |
824 | struct flexcan_regs __iomem *regs = priv->base; | 824 | struct flexcan_regs __iomem *regs = priv->base; |
825 | u32 reg; | 825 | u32 reg; |
826 | 826 | ||
827 | /* Disable all interrupts */ | 827 | /* Disable all interrupts */ |
828 | flexcan_write(0, ®s->imask1); | 828 | flexcan_write(0, ®s->imask1); |
829 | 829 | ||
830 | /* Disable + halt module */ | 830 | /* Disable + halt module */ |
831 | reg = flexcan_read(®s->mcr); | 831 | reg = flexcan_read(®s->mcr); |
832 | reg |= FLEXCAN_MCR_MDIS | FLEXCAN_MCR_HALT; | 832 | reg |= FLEXCAN_MCR_MDIS | FLEXCAN_MCR_HALT; |
833 | flexcan_write(reg, ®s->mcr); | 833 | flexcan_write(reg, ®s->mcr); |
834 | 834 | ||
835 | if (priv->reg_xceiver) | 835 | if (priv->reg_xceiver) |
836 | regulator_disable(priv->reg_xceiver); | 836 | regulator_disable(priv->reg_xceiver); |
837 | priv->can.state = CAN_STATE_STOPPED; | 837 | priv->can.state = CAN_STATE_STOPPED; |
838 | 838 | ||
839 | return; | 839 | return; |
840 | } | 840 | } |
841 | 841 | ||
842 | static int flexcan_open(struct net_device *dev) | 842 | static int flexcan_open(struct net_device *dev) |
843 | { | 843 | { |
844 | struct flexcan_priv *priv = netdev_priv(dev); | 844 | struct flexcan_priv *priv = netdev_priv(dev); |
845 | int err; | 845 | int err; |
846 | 846 | ||
847 | err = clk_prepare_enable(priv->clk_ipg); | 847 | err = clk_prepare_enable(priv->clk_ipg); |
848 | if (err) | 848 | if (err) |
849 | return err; | 849 | return err; |
850 | 850 | ||
851 | err = clk_prepare_enable(priv->clk_per); | 851 | err = clk_prepare_enable(priv->clk_per); |
852 | if (err) | 852 | if (err) |
853 | goto out_disable_ipg; | 853 | goto out_disable_ipg; |
854 | 854 | ||
855 | err = open_candev(dev); | 855 | err = open_candev(dev); |
856 | if (err) | 856 | if (err) |
857 | goto out_disable_per; | 857 | goto out_disable_per; |
858 | 858 | ||
859 | err = request_irq(dev->irq, flexcan_irq, IRQF_SHARED, dev->name, dev); | 859 | err = request_irq(dev->irq, flexcan_irq, IRQF_SHARED, dev->name, dev); |
860 | if (err) | 860 | if (err) |
861 | goto out_close; | 861 | goto out_close; |
862 | 862 | ||
863 | /* start chip and queuing */ | 863 | /* start chip and queuing */ |
864 | err = flexcan_chip_start(dev); | 864 | err = flexcan_chip_start(dev); |
865 | if (err) | 865 | if (err) |
866 | goto out_close; | 866 | goto out_close; |
867 | 867 | ||
868 | can_led_event(dev, CAN_LED_EVENT_OPEN); | 868 | can_led_event(dev, CAN_LED_EVENT_OPEN); |
869 | 869 | ||
870 | napi_enable(&priv->napi); | 870 | napi_enable(&priv->napi); |
871 | netif_start_queue(dev); | 871 | netif_start_queue(dev); |
872 | 872 | ||
873 | return 0; | 873 | return 0; |
874 | 874 | ||
875 | out_close: | 875 | out_close: |
876 | close_candev(dev); | 876 | close_candev(dev); |
877 | out_disable_per: | 877 | out_disable_per: |
878 | clk_disable_unprepare(priv->clk_per); | 878 | clk_disable_unprepare(priv->clk_per); |
879 | out_disable_ipg: | 879 | out_disable_ipg: |
880 | clk_disable_unprepare(priv->clk_ipg); | 880 | clk_disable_unprepare(priv->clk_ipg); |
881 | 881 | ||
882 | return err; | 882 | return err; |
883 | } | 883 | } |
884 | 884 | ||
885 | static int flexcan_close(struct net_device *dev) | 885 | static int flexcan_close(struct net_device *dev) |
886 | { | 886 | { |
887 | struct flexcan_priv *priv = netdev_priv(dev); | 887 | struct flexcan_priv *priv = netdev_priv(dev); |
888 | 888 | ||
889 | netif_stop_queue(dev); | 889 | netif_stop_queue(dev); |
890 | napi_disable(&priv->napi); | 890 | napi_disable(&priv->napi); |
891 | flexcan_chip_stop(dev); | 891 | flexcan_chip_stop(dev); |
892 | 892 | ||
893 | free_irq(dev->irq, dev); | 893 | free_irq(dev->irq, dev); |
894 | clk_disable_unprepare(priv->clk_per); | 894 | clk_disable_unprepare(priv->clk_per); |
895 | clk_disable_unprepare(priv->clk_ipg); | 895 | clk_disable_unprepare(priv->clk_ipg); |
896 | 896 | ||
897 | close_candev(dev); | 897 | close_candev(dev); |
898 | 898 | ||
899 | can_led_event(dev, CAN_LED_EVENT_STOP); | 899 | can_led_event(dev, CAN_LED_EVENT_STOP); |
900 | 900 | ||
901 | return 0; | 901 | return 0; |
902 | } | 902 | } |
903 | 903 | ||
904 | static int flexcan_set_mode(struct net_device *dev, enum can_mode mode) | 904 | static int flexcan_set_mode(struct net_device *dev, enum can_mode mode) |
905 | { | 905 | { |
906 | int err; | 906 | int err; |
907 | 907 | ||
908 | switch (mode) { | 908 | switch (mode) { |
909 | case CAN_MODE_START: | 909 | case CAN_MODE_START: |
910 | err = flexcan_chip_start(dev); | 910 | err = flexcan_chip_start(dev); |
911 | if (err) | 911 | if (err) |
912 | return err; | 912 | return err; |
913 | 913 | ||
914 | netif_wake_queue(dev); | 914 | netif_wake_queue(dev); |
915 | break; | 915 | break; |
916 | 916 | ||
917 | default: | 917 | default: |
918 | return -EOPNOTSUPP; | 918 | return -EOPNOTSUPP; |
919 | } | 919 | } |
920 | 920 | ||
921 | return 0; | 921 | return 0; |
922 | } | 922 | } |
923 | 923 | ||
924 | static const struct net_device_ops flexcan_netdev_ops = { | 924 | static const struct net_device_ops flexcan_netdev_ops = { |
925 | .ndo_open = flexcan_open, | 925 | .ndo_open = flexcan_open, |
926 | .ndo_stop = flexcan_close, | 926 | .ndo_stop = flexcan_close, |
927 | .ndo_start_xmit = flexcan_start_xmit, | 927 | .ndo_start_xmit = flexcan_start_xmit, |
928 | }; | 928 | }; |
929 | 929 | ||
930 | static int register_flexcandev(struct net_device *dev) | 930 | static int register_flexcandev(struct net_device *dev) |
931 | { | 931 | { |
932 | struct flexcan_priv *priv = netdev_priv(dev); | 932 | struct flexcan_priv *priv = netdev_priv(dev); |
933 | struct flexcan_regs __iomem *regs = priv->base; | 933 | struct flexcan_regs __iomem *regs = priv->base; |
934 | u32 reg, err; | 934 | u32 reg, err; |
935 | 935 | ||
936 | err = clk_prepare_enable(priv->clk_ipg); | 936 | err = clk_prepare_enable(priv->clk_ipg); |
937 | if (err) | 937 | if (err) |
938 | return err; | 938 | return err; |
939 | 939 | ||
940 | err = clk_prepare_enable(priv->clk_per); | 940 | err = clk_prepare_enable(priv->clk_per); |
941 | if (err) | 941 | if (err) |
942 | goto out_disable_ipg; | 942 | goto out_disable_ipg; |
943 | 943 | ||
944 | /* select "bus clock", chip must be disabled */ | 944 | /* select "bus clock", chip must be disabled */ |
945 | flexcan_chip_disable(priv); | 945 | flexcan_chip_disable(priv); |
946 | reg = flexcan_read(®s->ctrl); | 946 | reg = flexcan_read(®s->ctrl); |
947 | reg |= FLEXCAN_CTRL_CLK_SRC; | 947 | reg |= FLEXCAN_CTRL_CLK_SRC; |
948 | flexcan_write(reg, ®s->ctrl); | 948 | flexcan_write(reg, ®s->ctrl); |
949 | 949 | ||
950 | flexcan_chip_enable(priv); | 950 | flexcan_chip_enable(priv); |
951 | 951 | ||
952 | /* set freeze, halt and activate FIFO, restrict register access */ | 952 | /* set freeze, halt and activate FIFO, restrict register access */ |
953 | reg = flexcan_read(®s->mcr); | 953 | reg = flexcan_read(®s->mcr); |
954 | reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | | 954 | reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | |
955 | FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV; | 955 | FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV; |
956 | flexcan_write(reg, ®s->mcr); | 956 | flexcan_write(reg, ®s->mcr); |
957 | 957 | ||
958 | /* | 958 | /* |
959 | * Currently we only support newer versions of this core | 959 | * Currently we only support newer versions of this core |
960 | * featuring a RX FIFO. Older cores found on some Coldfire | 960 | * featuring a RX FIFO. Older cores found on some Coldfire |
961 | * derivates are not yet supported. | 961 | * derivates are not yet supported. |
962 | */ | 962 | */ |
963 | reg = flexcan_read(®s->mcr); | 963 | reg = flexcan_read(®s->mcr); |
964 | if (!(reg & FLEXCAN_MCR_FEN)) { | 964 | if (!(reg & FLEXCAN_MCR_FEN)) { |
965 | netdev_err(dev, "Could not enable RX FIFO, unsupported core\n"); | 965 | netdev_err(dev, "Could not enable RX FIFO, unsupported core\n"); |
966 | err = -ENODEV; | 966 | err = -ENODEV; |
967 | goto out_disable_per; | 967 | goto out_disable_per; |
968 | } | 968 | } |
969 | 969 | ||
970 | err = register_candev(dev); | 970 | err = register_candev(dev); |
971 | 971 | ||
972 | out_disable_per: | 972 | out_disable_per: |
973 | /* disable core and turn off clocks */ | 973 | /* disable core and turn off clocks */ |
974 | flexcan_chip_disable(priv); | 974 | flexcan_chip_disable(priv); |
975 | clk_disable_unprepare(priv->clk_per); | 975 | clk_disable_unprepare(priv->clk_per); |
976 | out_disable_ipg: | 976 | out_disable_ipg: |
977 | clk_disable_unprepare(priv->clk_ipg); | 977 | clk_disable_unprepare(priv->clk_ipg); |
978 | 978 | ||
979 | return err; | 979 | return err; |
980 | } | 980 | } |
981 | 981 | ||
982 | static void unregister_flexcandev(struct net_device *dev) | 982 | static void unregister_flexcandev(struct net_device *dev) |
983 | { | 983 | { |
984 | unregister_candev(dev); | 984 | unregister_candev(dev); |
985 | } | 985 | } |
986 | 986 | ||
987 | static const struct of_device_id flexcan_of_match[] = { | 987 | static const struct of_device_id flexcan_of_match[] = { |
988 | { .compatible = "fsl,p1010-flexcan", .data = &fsl_p1010_devtype_data, }, | ||
989 | { .compatible = "fsl,imx28-flexcan", .data = &fsl_imx28_devtype_data, }, | ||
990 | { .compatible = "fsl,imx6q-flexcan", .data = &fsl_imx6q_devtype_data, }, | 988 | { .compatible = "fsl,imx6q-flexcan", .data = &fsl_imx6q_devtype_data, }, |
989 | { .compatible = "fsl,imx28-flexcan", .data = &fsl_imx28_devtype_data, }, | ||
990 | { .compatible = "fsl,p1010-flexcan", .data = &fsl_p1010_devtype_data, }, | ||
991 | { /* sentinel */ }, | 991 | { /* sentinel */ }, |
992 | }; | 992 | }; |
993 | MODULE_DEVICE_TABLE(of, flexcan_of_match); | 993 | MODULE_DEVICE_TABLE(of, flexcan_of_match); |
994 | 994 | ||
995 | static const struct platform_device_id flexcan_id_table[] = { | 995 | static const struct platform_device_id flexcan_id_table[] = { |
996 | { .name = "flexcan", .driver_data = (kernel_ulong_t)&fsl_p1010_devtype_data, }, | 996 | { .name = "flexcan", .driver_data = (kernel_ulong_t)&fsl_p1010_devtype_data, }, |
997 | { /* sentinel */ }, | 997 | { /* sentinel */ }, |
998 | }; | 998 | }; |
999 | MODULE_DEVICE_TABLE(platform, flexcan_id_table); | 999 | MODULE_DEVICE_TABLE(platform, flexcan_id_table); |
1000 | 1000 | ||
1001 | static int flexcan_probe(struct platform_device *pdev) | 1001 | static int flexcan_probe(struct platform_device *pdev) |
1002 | { | 1002 | { |
1003 | const struct of_device_id *of_id; | 1003 | const struct of_device_id *of_id; |
1004 | const struct flexcan_devtype_data *devtype_data; | 1004 | const struct flexcan_devtype_data *devtype_data; |
1005 | struct net_device *dev; | 1005 | struct net_device *dev; |
1006 | struct flexcan_priv *priv; | 1006 | struct flexcan_priv *priv; |
1007 | struct resource *mem; | 1007 | struct resource *mem; |
1008 | struct clk *clk_ipg = NULL, *clk_per = NULL; | 1008 | struct clk *clk_ipg = NULL, *clk_per = NULL; |
1009 | void __iomem *base; | 1009 | void __iomem *base; |
1010 | int err, irq; | 1010 | int err, irq; |
1011 | u32 clock_freq = 0; | 1011 | u32 clock_freq = 0; |
1012 | 1012 | ||
1013 | if (pdev->dev.of_node) | 1013 | if (pdev->dev.of_node) |
1014 | of_property_read_u32(pdev->dev.of_node, | 1014 | of_property_read_u32(pdev->dev.of_node, |
1015 | "clock-frequency", &clock_freq); | 1015 | "clock-frequency", &clock_freq); |
1016 | 1016 | ||
1017 | if (!clock_freq) { | 1017 | if (!clock_freq) { |
1018 | clk_ipg = devm_clk_get(&pdev->dev, "ipg"); | 1018 | clk_ipg = devm_clk_get(&pdev->dev, "ipg"); |
1019 | if (IS_ERR(clk_ipg)) { | 1019 | if (IS_ERR(clk_ipg)) { |
1020 | dev_err(&pdev->dev, "no ipg clock defined\n"); | 1020 | dev_err(&pdev->dev, "no ipg clock defined\n"); |
1021 | return PTR_ERR(clk_ipg); | 1021 | return PTR_ERR(clk_ipg); |
1022 | } | 1022 | } |
1023 | clock_freq = clk_get_rate(clk_ipg); | 1023 | clock_freq = clk_get_rate(clk_ipg); |
1024 | 1024 | ||
1025 | clk_per = devm_clk_get(&pdev->dev, "per"); | 1025 | clk_per = devm_clk_get(&pdev->dev, "per"); |
1026 | if (IS_ERR(clk_per)) { | 1026 | if (IS_ERR(clk_per)) { |
1027 | dev_err(&pdev->dev, "no per clock defined\n"); | 1027 | dev_err(&pdev->dev, "no per clock defined\n"); |
1028 | return PTR_ERR(clk_per); | 1028 | return PTR_ERR(clk_per); |
1029 | } | 1029 | } |
1030 | } | 1030 | } |
1031 | 1031 | ||
1032 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1032 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1033 | irq = platform_get_irq(pdev, 0); | 1033 | irq = platform_get_irq(pdev, 0); |
1034 | if (irq <= 0) | 1034 | if (irq <= 0) |
1035 | return -ENODEV; | 1035 | return -ENODEV; |
1036 | 1036 | ||
1037 | base = devm_ioremap_resource(&pdev->dev, mem); | 1037 | base = devm_ioremap_resource(&pdev->dev, mem); |
1038 | if (IS_ERR(base)) | 1038 | if (IS_ERR(base)) |
1039 | return PTR_ERR(base); | 1039 | return PTR_ERR(base); |
1040 | 1040 | ||
1041 | of_id = of_match_device(flexcan_of_match, &pdev->dev); | 1041 | of_id = of_match_device(flexcan_of_match, &pdev->dev); |
1042 | if (of_id) { | 1042 | if (of_id) { |
1043 | devtype_data = of_id->data; | 1043 | devtype_data = of_id->data; |
1044 | } else if (pdev->id_entry->driver_data) { | 1044 | } else if (pdev->id_entry->driver_data) { |
1045 | devtype_data = (struct flexcan_devtype_data *) | 1045 | devtype_data = (struct flexcan_devtype_data *) |
1046 | pdev->id_entry->driver_data; | 1046 | pdev->id_entry->driver_data; |
1047 | } else { | 1047 | } else { |
1048 | return -ENODEV; | 1048 | return -ENODEV; |
1049 | } | 1049 | } |
1050 | 1050 | ||
1051 | dev = alloc_candev(sizeof(struct flexcan_priv), 1); | 1051 | dev = alloc_candev(sizeof(struct flexcan_priv), 1); |
1052 | if (!dev) | 1052 | if (!dev) |
1053 | return -ENOMEM; | 1053 | return -ENOMEM; |
1054 | 1054 | ||
1055 | dev->netdev_ops = &flexcan_netdev_ops; | 1055 | dev->netdev_ops = &flexcan_netdev_ops; |
1056 | dev->irq = irq; | 1056 | dev->irq = irq; |
1057 | dev->flags |= IFF_ECHO; | 1057 | dev->flags |= IFF_ECHO; |
1058 | 1058 | ||
1059 | priv = netdev_priv(dev); | 1059 | priv = netdev_priv(dev); |
1060 | priv->can.clock.freq = clock_freq; | 1060 | priv->can.clock.freq = clock_freq; |
1061 | priv->can.bittiming_const = &flexcan_bittiming_const; | 1061 | priv->can.bittiming_const = &flexcan_bittiming_const; |
1062 | priv->can.do_set_mode = flexcan_set_mode; | 1062 | priv->can.do_set_mode = flexcan_set_mode; |
1063 | priv->can.do_get_berr_counter = flexcan_get_berr_counter; | 1063 | priv->can.do_get_berr_counter = flexcan_get_berr_counter; |
1064 | priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK | | 1064 | priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK | |
1065 | CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_3_SAMPLES | | 1065 | CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_3_SAMPLES | |
1066 | CAN_CTRLMODE_BERR_REPORTING; | 1066 | CAN_CTRLMODE_BERR_REPORTING; |
1067 | priv->base = base; | 1067 | priv->base = base; |
1068 | priv->dev = dev; | 1068 | priv->dev = dev; |
1069 | priv->clk_ipg = clk_ipg; | 1069 | priv->clk_ipg = clk_ipg; |
1070 | priv->clk_per = clk_per; | 1070 | priv->clk_per = clk_per; |
1071 | priv->pdata = pdev->dev.platform_data; | 1071 | priv->pdata = pdev->dev.platform_data; |
1072 | priv->devtype_data = devtype_data; | 1072 | priv->devtype_data = devtype_data; |
1073 | 1073 | ||
1074 | priv->reg_xceiver = devm_regulator_get(&pdev->dev, "xceiver"); | 1074 | priv->reg_xceiver = devm_regulator_get(&pdev->dev, "xceiver"); |
1075 | if (IS_ERR(priv->reg_xceiver)) | 1075 | if (IS_ERR(priv->reg_xceiver)) |
1076 | priv->reg_xceiver = NULL; | 1076 | priv->reg_xceiver = NULL; |
1077 | 1077 | ||
1078 | netif_napi_add(dev, &priv->napi, flexcan_poll, FLEXCAN_NAPI_WEIGHT); | 1078 | netif_napi_add(dev, &priv->napi, flexcan_poll, FLEXCAN_NAPI_WEIGHT); |
1079 | 1079 | ||
1080 | platform_set_drvdata(pdev, dev); | 1080 | platform_set_drvdata(pdev, dev); |
1081 | SET_NETDEV_DEV(dev, &pdev->dev); | 1081 | SET_NETDEV_DEV(dev, &pdev->dev); |
1082 | 1082 | ||
1083 | err = register_flexcandev(dev); | 1083 | err = register_flexcandev(dev); |
1084 | if (err) { | 1084 | if (err) { |
1085 | dev_err(&pdev->dev, "registering netdev failed\n"); | 1085 | dev_err(&pdev->dev, "registering netdev failed\n"); |
1086 | goto failed_register; | 1086 | goto failed_register; |
1087 | } | 1087 | } |
1088 | 1088 | ||
1089 | devm_can_led_init(dev); | 1089 | devm_can_led_init(dev); |
1090 | 1090 | ||
1091 | dev_info(&pdev->dev, "device registered (reg_base=%p, irq=%d)\n", | 1091 | dev_info(&pdev->dev, "device registered (reg_base=%p, irq=%d)\n", |
1092 | priv->base, dev->irq); | 1092 | priv->base, dev->irq); |
1093 | 1093 | ||
1094 | return 0; | 1094 | return 0; |
1095 | 1095 | ||
1096 | failed_register: | 1096 | failed_register: |
1097 | free_candev(dev); | 1097 | free_candev(dev); |
1098 | return err; | 1098 | return err; |
1099 | } | 1099 | } |
1100 | 1100 | ||
1101 | static int flexcan_remove(struct platform_device *pdev) | 1101 | static int flexcan_remove(struct platform_device *pdev) |
1102 | { | 1102 | { |
1103 | struct net_device *dev = platform_get_drvdata(pdev); | 1103 | struct net_device *dev = platform_get_drvdata(pdev); |
1104 | 1104 | ||
1105 | unregister_flexcandev(dev); | 1105 | unregister_flexcandev(dev); |
1106 | 1106 | ||
1107 | free_candev(dev); | 1107 | free_candev(dev); |
1108 | 1108 | ||
1109 | return 0; | 1109 | return 0; |
1110 | } | 1110 | } |
1111 | 1111 | ||
1112 | #ifdef CONFIG_PM_SLEEP | 1112 | #ifdef CONFIG_PM_SLEEP |
1113 | static int flexcan_suspend(struct device *device) | 1113 | static int flexcan_suspend(struct device *device) |
1114 | { | 1114 | { |
1115 | struct net_device *dev = dev_get_drvdata(device); | 1115 | struct net_device *dev = dev_get_drvdata(device); |
1116 | struct flexcan_priv *priv = netdev_priv(dev); | 1116 | struct flexcan_priv *priv = netdev_priv(dev); |
1117 | 1117 | ||
1118 | flexcan_chip_disable(priv); | 1118 | flexcan_chip_disable(priv); |
1119 | 1119 | ||
1120 | if (netif_running(dev)) { | 1120 | if (netif_running(dev)) { |
1121 | netif_stop_queue(dev); | 1121 | netif_stop_queue(dev); |
1122 | netif_device_detach(dev); | 1122 | netif_device_detach(dev); |
1123 | } | 1123 | } |
1124 | priv->can.state = CAN_STATE_SLEEPING; | 1124 | priv->can.state = CAN_STATE_SLEEPING; |
1125 | 1125 | ||
1126 | return 0; | 1126 | return 0; |
1127 | } | 1127 | } |
1128 | 1128 | ||
1129 | static int flexcan_resume(struct device *device) | 1129 | static int flexcan_resume(struct device *device) |
1130 | { | 1130 | { |
1131 | struct net_device *dev = dev_get_drvdata(device); | 1131 | struct net_device *dev = dev_get_drvdata(device); |
1132 | struct flexcan_priv *priv = netdev_priv(dev); | 1132 | struct flexcan_priv *priv = netdev_priv(dev); |
1133 | 1133 | ||
1134 | priv->can.state = CAN_STATE_ERROR_ACTIVE; | 1134 | priv->can.state = CAN_STATE_ERROR_ACTIVE; |
1135 | if (netif_running(dev)) { | 1135 | if (netif_running(dev)) { |
1136 | netif_device_attach(dev); | 1136 | netif_device_attach(dev); |
1137 | netif_start_queue(dev); | 1137 | netif_start_queue(dev); |
1138 | } | 1138 | } |
1139 | flexcan_chip_enable(priv); | 1139 | flexcan_chip_enable(priv); |
1140 | 1140 | ||
1141 | return 0; | 1141 | return 0; |
1142 | } | 1142 | } |
1143 | #endif /* CONFIG_PM_SLEEP */ | 1143 | #endif /* CONFIG_PM_SLEEP */ |
1144 | 1144 | ||
1145 | static SIMPLE_DEV_PM_OPS(flexcan_pm_ops, flexcan_suspend, flexcan_resume); | 1145 | static SIMPLE_DEV_PM_OPS(flexcan_pm_ops, flexcan_suspend, flexcan_resume); |
1146 | 1146 | ||
1147 | static struct platform_driver flexcan_driver = { | 1147 | static struct platform_driver flexcan_driver = { |
1148 | .driver = { | 1148 | .driver = { |
1149 | .name = DRV_NAME, | 1149 | .name = DRV_NAME, |
1150 | .owner = THIS_MODULE, | 1150 | .owner = THIS_MODULE, |
1151 | .pm = &flexcan_pm_ops, | 1151 | .pm = &flexcan_pm_ops, |
1152 | .of_match_table = flexcan_of_match, | 1152 | .of_match_table = flexcan_of_match, |
1153 | }, | 1153 | }, |
1154 | .probe = flexcan_probe, | 1154 | .probe = flexcan_probe, |
1155 | .remove = flexcan_remove, | 1155 | .remove = flexcan_remove, |
1156 | .id_table = flexcan_id_table, | 1156 | .id_table = flexcan_id_table, |
1157 | }; | 1157 | }; |
1158 | 1158 | ||
1159 | module_platform_driver(flexcan_driver); | 1159 | module_platform_driver(flexcan_driver); |
1160 | 1160 | ||
1161 | MODULE_AUTHOR("Sascha Hauer <kernel@pengutronix.de>, " | 1161 | MODULE_AUTHOR("Sascha Hauer <kernel@pengutronix.de>, " |
1162 | "Marc Kleine-Budde <kernel@pengutronix.de>"); | 1162 | "Marc Kleine-Budde <kernel@pengutronix.de>"); |
1163 | MODULE_LICENSE("GPL v2"); | 1163 | MODULE_LICENSE("GPL v2"); |