diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/net/can/c_can | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'drivers/net/can/c_can')
-rw-r--r-- | drivers/net/can/c_can/Kconfig | 15 | ||||
-rw-r--r-- | drivers/net/can/c_can/Makefile | 8 | ||||
-rw-r--r-- | drivers/net/can/c_can/c_can.c | 1152 | ||||
-rw-r--r-- | drivers/net/can/c_can/c_can.h | 86 | ||||
-rw-r--r-- | drivers/net/can/c_can/c_can_platform.c | 216 |
5 files changed, 1477 insertions, 0 deletions
diff --git a/drivers/net/can/c_can/Kconfig b/drivers/net/can/c_can/Kconfig new file mode 100644 index 000000000000..ffb9773d102d --- /dev/null +++ b/drivers/net/can/c_can/Kconfig | |||
@@ -0,0 +1,15 @@ | |||
1 | menuconfig CAN_C_CAN | ||
2 | tristate "Bosch C_CAN devices" | ||
3 | depends on CAN_DEV && HAS_IOMEM | ||
4 | |||
5 | if CAN_C_CAN | ||
6 | |||
7 | config CAN_C_CAN_PLATFORM | ||
8 | tristate "Generic Platform Bus based C_CAN driver" | ||
9 | ---help--- | ||
10 | This driver adds support for the C_CAN chips connected to | ||
11 | the "platform bus" (Linux abstraction for directly to the | ||
12 | processor attached devices) which can be found on various | ||
13 | boards from ST Microelectronics (http://www.st.com) | ||
14 | like the SPEAr1310 and SPEAr320 evaluation boards. | ||
15 | endif | ||
diff --git a/drivers/net/can/c_can/Makefile b/drivers/net/can/c_can/Makefile new file mode 100644 index 000000000000..9273f6d5c4b7 --- /dev/null +++ b/drivers/net/can/c_can/Makefile | |||
@@ -0,0 +1,8 @@ | |||
1 | # | ||
2 | # Makefile for the Bosch C_CAN controller drivers. | ||
3 | # | ||
4 | |||
5 | obj-$(CONFIG_CAN_C_CAN) += c_can.o | ||
6 | obj-$(CONFIG_CAN_C_CAN_PLATFORM) += c_can_platform.o | ||
7 | |||
8 | ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG | ||
diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c new file mode 100644 index 000000000000..7e5cc0bd913d --- /dev/null +++ b/drivers/net/can/c_can/c_can.c | |||
@@ -0,0 +1,1152 @@ | |||
1 | /* | ||
2 | * CAN bus driver for Bosch C_CAN controller | ||
3 | * | ||
4 | * Copyright (C) 2010 ST Microelectronics | ||
5 | * Bhupesh Sharma <bhupesh.sharma@st.com> | ||
6 | * | ||
7 | * Borrowed heavily from the C_CAN driver originally written by: | ||
8 | * Copyright (C) 2007 | ||
9 | * - Sascha Hauer, Marc Kleine-Budde, Pengutronix <s.hauer@pengutronix.de> | ||
10 | * - Simon Kallweit, intefo AG <simon.kallweit@intefo.ch> | ||
11 | * | ||
12 | * TX and RX NAPI implementation has been borrowed from at91 CAN driver | ||
13 | * written by: | ||
14 | * Copyright | ||
15 | * (C) 2007 by Hans J. Koch <hjk@hansjkoch.de> | ||
16 | * (C) 2008, 2009 by Marc Kleine-Budde <kernel@pengutronix.de> | ||
17 | * | ||
18 | * Bosch C_CAN controller is compliant to CAN protocol version 2.0 part A and B. | ||
19 | * Bosch C_CAN user manual can be obtained from: | ||
20 | * http://www.semiconductors.bosch.de/media/en/pdf/ipmodules_1/c_can/ | ||
21 | * users_manual_c_can.pdf | ||
22 | * | ||
23 | * This file is licensed under the terms of the GNU General Public | ||
24 | * License version 2. This program is licensed "as is" without any | ||
25 | * warranty of any kind, whether express or implied. | ||
26 | */ | ||
27 | |||
28 | #include <linux/kernel.h> | ||
29 | #include <linux/version.h> | ||
30 | #include <linux/module.h> | ||
31 | #include <linux/interrupt.h> | ||
32 | #include <linux/delay.h> | ||
33 | #include <linux/netdevice.h> | ||
34 | #include <linux/if_arp.h> | ||
35 | #include <linux/if_ether.h> | ||
36 | #include <linux/list.h> | ||
37 | #include <linux/delay.h> | ||
38 | #include <linux/io.h> | ||
39 | |||
40 | #include <linux/can.h> | ||
41 | #include <linux/can/dev.h> | ||
42 | #include <linux/can/error.h> | ||
43 | |||
44 | #include "c_can.h" | ||
45 | |||
46 | /* control register */ | ||
47 | #define CONTROL_TEST BIT(7) | ||
48 | #define CONTROL_CCE BIT(6) | ||
49 | #define CONTROL_DISABLE_AR BIT(5) | ||
50 | #define CONTROL_ENABLE_AR (0 << 5) | ||
51 | #define CONTROL_EIE BIT(3) | ||
52 | #define CONTROL_SIE BIT(2) | ||
53 | #define CONTROL_IE BIT(1) | ||
54 | #define CONTROL_INIT BIT(0) | ||
55 | |||
56 | /* test register */ | ||
57 | #define TEST_RX BIT(7) | ||
58 | #define TEST_TX1 BIT(6) | ||
59 | #define TEST_TX2 BIT(5) | ||
60 | #define TEST_LBACK BIT(4) | ||
61 | #define TEST_SILENT BIT(3) | ||
62 | #define TEST_BASIC BIT(2) | ||
63 | |||
64 | /* status register */ | ||
65 | #define STATUS_BOFF BIT(7) | ||
66 | #define STATUS_EWARN BIT(6) | ||
67 | #define STATUS_EPASS BIT(5) | ||
68 | #define STATUS_RXOK BIT(4) | ||
69 | #define STATUS_TXOK BIT(3) | ||
70 | |||
71 | /* error counter register */ | ||
72 | #define ERR_CNT_TEC_MASK 0xff | ||
73 | #define ERR_CNT_TEC_SHIFT 0 | ||
74 | #define ERR_CNT_REC_SHIFT 8 | ||
75 | #define ERR_CNT_REC_MASK (0x7f << ERR_CNT_REC_SHIFT) | ||
76 | #define ERR_CNT_RP_SHIFT 15 | ||
77 | #define ERR_CNT_RP_MASK (0x1 << ERR_CNT_RP_SHIFT) | ||
78 | |||
79 | /* bit-timing register */ | ||
80 | #define BTR_BRP_MASK 0x3f | ||
81 | #define BTR_BRP_SHIFT 0 | ||
82 | #define BTR_SJW_SHIFT 6 | ||
83 | #define BTR_SJW_MASK (0x3 << BTR_SJW_SHIFT) | ||
84 | #define BTR_TSEG1_SHIFT 8 | ||
85 | #define BTR_TSEG1_MASK (0xf << BTR_TSEG1_SHIFT) | ||
86 | #define BTR_TSEG2_SHIFT 12 | ||
87 | #define BTR_TSEG2_MASK (0x7 << BTR_TSEG2_SHIFT) | ||
88 | |||
89 | /* brp extension register */ | ||
90 | #define BRP_EXT_BRPE_MASK 0x0f | ||
91 | #define BRP_EXT_BRPE_SHIFT 0 | ||
92 | |||
93 | /* IFx command request */ | ||
94 | #define IF_COMR_BUSY BIT(15) | ||
95 | |||
96 | /* IFx command mask */ | ||
97 | #define IF_COMM_WR BIT(7) | ||
98 | #define IF_COMM_MASK BIT(6) | ||
99 | #define IF_COMM_ARB BIT(5) | ||
100 | #define IF_COMM_CONTROL BIT(4) | ||
101 | #define IF_COMM_CLR_INT_PND BIT(3) | ||
102 | #define IF_COMM_TXRQST BIT(2) | ||
103 | #define IF_COMM_DATAA BIT(1) | ||
104 | #define IF_COMM_DATAB BIT(0) | ||
105 | #define IF_COMM_ALL (IF_COMM_MASK | IF_COMM_ARB | \ | ||
106 | IF_COMM_CONTROL | IF_COMM_TXRQST | \ | ||
107 | IF_COMM_DATAA | IF_COMM_DATAB) | ||
108 | |||
109 | /* IFx arbitration */ | ||
110 | #define IF_ARB_MSGVAL BIT(15) | ||
111 | #define IF_ARB_MSGXTD BIT(14) | ||
112 | #define IF_ARB_TRANSMIT BIT(13) | ||
113 | |||
114 | /* IFx message control */ | ||
115 | #define IF_MCONT_NEWDAT BIT(15) | ||
116 | #define IF_MCONT_MSGLST BIT(14) | ||
117 | #define IF_MCONT_CLR_MSGLST (0 << 14) | ||
118 | #define IF_MCONT_INTPND BIT(13) | ||
119 | #define IF_MCONT_UMASK BIT(12) | ||
120 | #define IF_MCONT_TXIE BIT(11) | ||
121 | #define IF_MCONT_RXIE BIT(10) | ||
122 | #define IF_MCONT_RMTEN BIT(9) | ||
123 | #define IF_MCONT_TXRQST BIT(8) | ||
124 | #define IF_MCONT_EOB BIT(7) | ||
125 | #define IF_MCONT_DLC_MASK 0xf | ||
126 | |||
127 | /* | ||
128 | * IFx register masks: | ||
129 | * allow easy operation on 16-bit registers when the | ||
130 | * argument is 32-bit instead | ||
131 | */ | ||
132 | #define IFX_WRITE_LOW_16BIT(x) ((x) & 0xFFFF) | ||
133 | #define IFX_WRITE_HIGH_16BIT(x) (((x) & 0xFFFF0000) >> 16) | ||
134 | |||
135 | /* message object split */ | ||
136 | #define C_CAN_NO_OF_OBJECTS 32 | ||
137 | #define C_CAN_MSG_OBJ_RX_NUM 16 | ||
138 | #define C_CAN_MSG_OBJ_TX_NUM 16 | ||
139 | |||
140 | #define C_CAN_MSG_OBJ_RX_FIRST 1 | ||
141 | #define C_CAN_MSG_OBJ_RX_LAST (C_CAN_MSG_OBJ_RX_FIRST + \ | ||
142 | C_CAN_MSG_OBJ_RX_NUM - 1) | ||
143 | |||
144 | #define C_CAN_MSG_OBJ_TX_FIRST (C_CAN_MSG_OBJ_RX_LAST + 1) | ||
145 | #define C_CAN_MSG_OBJ_TX_LAST (C_CAN_MSG_OBJ_TX_FIRST + \ | ||
146 | C_CAN_MSG_OBJ_TX_NUM - 1) | ||
147 | |||
148 | #define C_CAN_MSG_OBJ_RX_SPLIT 9 | ||
149 | #define C_CAN_MSG_RX_LOW_LAST (C_CAN_MSG_OBJ_RX_SPLIT - 1) | ||
150 | |||
151 | #define C_CAN_NEXT_MSG_OBJ_MASK (C_CAN_MSG_OBJ_TX_NUM - 1) | ||
152 | #define RECEIVE_OBJECT_BITS 0x0000ffff | ||
153 | |||
154 | /* status interrupt */ | ||
155 | #define STATUS_INTERRUPT 0x8000 | ||
156 | |||
157 | /* global interrupt masks */ | ||
158 | #define ENABLE_ALL_INTERRUPTS 1 | ||
159 | #define DISABLE_ALL_INTERRUPTS 0 | ||
160 | |||
161 | /* minimum timeout for checking BUSY status */ | ||
162 | #define MIN_TIMEOUT_VALUE 6 | ||
163 | |||
164 | /* napi related */ | ||
165 | #define C_CAN_NAPI_WEIGHT C_CAN_MSG_OBJ_RX_NUM | ||
166 | |||
167 | /* c_can lec values */ | ||
168 | enum c_can_lec_type { | ||
169 | LEC_NO_ERROR = 0, | ||
170 | LEC_STUFF_ERROR, | ||
171 | LEC_FORM_ERROR, | ||
172 | LEC_ACK_ERROR, | ||
173 | LEC_BIT1_ERROR, | ||
174 | LEC_BIT0_ERROR, | ||
175 | LEC_CRC_ERROR, | ||
176 | LEC_UNUSED, | ||
177 | }; | ||
178 | |||
179 | /* | ||
180 | * c_can error types: | ||
181 | * Bus errors (BUS_OFF, ERROR_WARNING, ERROR_PASSIVE) are supported | ||
182 | */ | ||
183 | enum c_can_bus_error_types { | ||
184 | C_CAN_NO_ERROR = 0, | ||
185 | C_CAN_BUS_OFF, | ||
186 | C_CAN_ERROR_WARNING, | ||
187 | C_CAN_ERROR_PASSIVE, | ||
188 | }; | ||
189 | |||
190 | static struct can_bittiming_const c_can_bittiming_const = { | ||
191 | .name = KBUILD_MODNAME, | ||
192 | .tseg1_min = 2, /* Time segment 1 = prop_seg + phase_seg1 */ | ||
193 | .tseg1_max = 16, | ||
194 | .tseg2_min = 1, /* Time segment 2 = phase_seg2 */ | ||
195 | .tseg2_max = 8, | ||
196 | .sjw_max = 4, | ||
197 | .brp_min = 1, | ||
198 | .brp_max = 1024, /* 6-bit BRP field + 4-bit BRPE field*/ | ||
199 | .brp_inc = 1, | ||
200 | }; | ||
201 | |||
202 | static inline int get_tx_next_msg_obj(const struct c_can_priv *priv) | ||
203 | { | ||
204 | return (priv->tx_next & C_CAN_NEXT_MSG_OBJ_MASK) + | ||
205 | C_CAN_MSG_OBJ_TX_FIRST; | ||
206 | } | ||
207 | |||
208 | static inline int get_tx_echo_msg_obj(const struct c_can_priv *priv) | ||
209 | { | ||
210 | return (priv->tx_echo & C_CAN_NEXT_MSG_OBJ_MASK) + | ||
211 | C_CAN_MSG_OBJ_TX_FIRST; | ||
212 | } | ||
213 | |||
214 | static u32 c_can_read_reg32(struct c_can_priv *priv, void *reg) | ||
215 | { | ||
216 | u32 val = priv->read_reg(priv, reg); | ||
217 | val |= ((u32) priv->read_reg(priv, reg + 2)) << 16; | ||
218 | return val; | ||
219 | } | ||
220 | |||
221 | static void c_can_enable_all_interrupts(struct c_can_priv *priv, | ||
222 | int enable) | ||
223 | { | ||
224 | unsigned int cntrl_save = priv->read_reg(priv, | ||
225 | &priv->regs->control); | ||
226 | |||
227 | if (enable) | ||
228 | cntrl_save |= (CONTROL_SIE | CONTROL_EIE | CONTROL_IE); | ||
229 | else | ||
230 | cntrl_save &= ~(CONTROL_EIE | CONTROL_IE | CONTROL_SIE); | ||
231 | |||
232 | priv->write_reg(priv, &priv->regs->control, cntrl_save); | ||
233 | } | ||
234 | |||
235 | static inline int c_can_msg_obj_is_busy(struct c_can_priv *priv, int iface) | ||
236 | { | ||
237 | int count = MIN_TIMEOUT_VALUE; | ||
238 | |||
239 | while (count && priv->read_reg(priv, | ||
240 | &priv->regs->ifregs[iface].com_req) & | ||
241 | IF_COMR_BUSY) { | ||
242 | count--; | ||
243 | udelay(1); | ||
244 | } | ||
245 | |||
246 | if (!count) | ||
247 | return 1; | ||
248 | |||
249 | return 0; | ||
250 | } | ||
251 | |||
252 | static inline void c_can_object_get(struct net_device *dev, | ||
253 | int iface, int objno, int mask) | ||
254 | { | ||
255 | struct c_can_priv *priv = netdev_priv(dev); | ||
256 | |||
257 | /* | ||
258 | * As per specs, after writting the message object number in the | ||
259 | * IF command request register the transfer b/w interface | ||
260 | * register and message RAM must be complete in 6 CAN-CLK | ||
261 | * period. | ||
262 | */ | ||
263 | priv->write_reg(priv, &priv->regs->ifregs[iface].com_mask, | ||
264 | IFX_WRITE_LOW_16BIT(mask)); | ||
265 | priv->write_reg(priv, &priv->regs->ifregs[iface].com_req, | ||
266 | IFX_WRITE_LOW_16BIT(objno)); | ||
267 | |||
268 | if (c_can_msg_obj_is_busy(priv, iface)) | ||
269 | netdev_err(dev, "timed out in object get\n"); | ||
270 | } | ||
271 | |||
272 | static inline void c_can_object_put(struct net_device *dev, | ||
273 | int iface, int objno, int mask) | ||
274 | { | ||
275 | struct c_can_priv *priv = netdev_priv(dev); | ||
276 | |||
277 | /* | ||
278 | * As per specs, after writting the message object number in the | ||
279 | * IF command request register the transfer b/w interface | ||
280 | * register and message RAM must be complete in 6 CAN-CLK | ||
281 | * period. | ||
282 | */ | ||
283 | priv->write_reg(priv, &priv->regs->ifregs[iface].com_mask, | ||
284 | (IF_COMM_WR | IFX_WRITE_LOW_16BIT(mask))); | ||
285 | priv->write_reg(priv, &priv->regs->ifregs[iface].com_req, | ||
286 | IFX_WRITE_LOW_16BIT(objno)); | ||
287 | |||
288 | if (c_can_msg_obj_is_busy(priv, iface)) | ||
289 | netdev_err(dev, "timed out in object put\n"); | ||
290 | } | ||
291 | |||
292 | static void c_can_write_msg_object(struct net_device *dev, | ||
293 | int iface, struct can_frame *frame, int objno) | ||
294 | { | ||
295 | int i; | ||
296 | u16 flags = 0; | ||
297 | unsigned int id; | ||
298 | struct c_can_priv *priv = netdev_priv(dev); | ||
299 | |||
300 | if (!(frame->can_id & CAN_RTR_FLAG)) | ||
301 | flags |= IF_ARB_TRANSMIT; | ||
302 | |||
303 | if (frame->can_id & CAN_EFF_FLAG) { | ||
304 | id = frame->can_id & CAN_EFF_MASK; | ||
305 | flags |= IF_ARB_MSGXTD; | ||
306 | } else | ||
307 | id = ((frame->can_id & CAN_SFF_MASK) << 18); | ||
308 | |||
309 | flags |= IF_ARB_MSGVAL; | ||
310 | |||
311 | priv->write_reg(priv, &priv->regs->ifregs[iface].arb1, | ||
312 | IFX_WRITE_LOW_16BIT(id)); | ||
313 | priv->write_reg(priv, &priv->regs->ifregs[iface].arb2, flags | | ||
314 | IFX_WRITE_HIGH_16BIT(id)); | ||
315 | |||
316 | for (i = 0; i < frame->can_dlc; i += 2) { | ||
317 | priv->write_reg(priv, &priv->regs->ifregs[iface].data[i / 2], | ||
318 | frame->data[i] | (frame->data[i + 1] << 8)); | ||
319 | } | ||
320 | |||
321 | /* enable interrupt for this message object */ | ||
322 | priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl, | ||
323 | IF_MCONT_TXIE | IF_MCONT_TXRQST | IF_MCONT_EOB | | ||
324 | frame->can_dlc); | ||
325 | c_can_object_put(dev, iface, objno, IF_COMM_ALL); | ||
326 | } | ||
327 | |||
328 | static inline void c_can_mark_rx_msg_obj(struct net_device *dev, | ||
329 | int iface, int ctrl_mask, | ||
330 | int obj) | ||
331 | { | ||
332 | struct c_can_priv *priv = netdev_priv(dev); | ||
333 | |||
334 | priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl, | ||
335 | ctrl_mask & ~(IF_MCONT_MSGLST | IF_MCONT_INTPND)); | ||
336 | c_can_object_put(dev, iface, obj, IF_COMM_CONTROL); | ||
337 | |||
338 | } | ||
339 | |||
340 | static inline void c_can_activate_all_lower_rx_msg_obj(struct net_device *dev, | ||
341 | int iface, | ||
342 | int ctrl_mask) | ||
343 | { | ||
344 | int i; | ||
345 | struct c_can_priv *priv = netdev_priv(dev); | ||
346 | |||
347 | for (i = C_CAN_MSG_OBJ_RX_FIRST; i <= C_CAN_MSG_RX_LOW_LAST; i++) { | ||
348 | priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl, | ||
349 | ctrl_mask & ~(IF_MCONT_MSGLST | | ||
350 | IF_MCONT_INTPND | IF_MCONT_NEWDAT)); | ||
351 | c_can_object_put(dev, iface, i, IF_COMM_CONTROL); | ||
352 | } | ||
353 | } | ||
354 | |||
355 | static inline void c_can_activate_rx_msg_obj(struct net_device *dev, | ||
356 | int iface, int ctrl_mask, | ||
357 | int obj) | ||
358 | { | ||
359 | struct c_can_priv *priv = netdev_priv(dev); | ||
360 | |||
361 | priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl, | ||
362 | ctrl_mask & ~(IF_MCONT_MSGLST | | ||
363 | IF_MCONT_INTPND | IF_MCONT_NEWDAT)); | ||
364 | c_can_object_put(dev, iface, obj, IF_COMM_CONTROL); | ||
365 | } | ||
366 | |||
367 | static void c_can_handle_lost_msg_obj(struct net_device *dev, | ||
368 | int iface, int objno) | ||
369 | { | ||
370 | struct c_can_priv *priv = netdev_priv(dev); | ||
371 | struct net_device_stats *stats = &dev->stats; | ||
372 | struct sk_buff *skb; | ||
373 | struct can_frame *frame; | ||
374 | |||
375 | netdev_err(dev, "msg lost in buffer %d\n", objno); | ||
376 | |||
377 | c_can_object_get(dev, iface, objno, IF_COMM_ALL & ~IF_COMM_TXRQST); | ||
378 | |||
379 | priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl, | ||
380 | IF_MCONT_CLR_MSGLST); | ||
381 | |||
382 | c_can_object_put(dev, 0, objno, IF_COMM_CONTROL); | ||
383 | |||
384 | /* create an error msg */ | ||
385 | skb = alloc_can_err_skb(dev, &frame); | ||
386 | if (unlikely(!skb)) | ||
387 | return; | ||
388 | |||
389 | frame->can_id |= CAN_ERR_CRTL; | ||
390 | frame->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; | ||
391 | stats->rx_errors++; | ||
392 | stats->rx_over_errors++; | ||
393 | |||
394 | netif_receive_skb(skb); | ||
395 | } | ||
396 | |||
397 | static int c_can_read_msg_object(struct net_device *dev, int iface, int ctrl) | ||
398 | { | ||
399 | u16 flags, data; | ||
400 | int i; | ||
401 | unsigned int val; | ||
402 | struct c_can_priv *priv = netdev_priv(dev); | ||
403 | struct net_device_stats *stats = &dev->stats; | ||
404 | struct sk_buff *skb; | ||
405 | struct can_frame *frame; | ||
406 | |||
407 | skb = alloc_can_skb(dev, &frame); | ||
408 | if (!skb) { | ||
409 | stats->rx_dropped++; | ||
410 | return -ENOMEM; | ||
411 | } | ||
412 | |||
413 | frame->can_dlc = get_can_dlc(ctrl & 0x0F); | ||
414 | |||
415 | flags = priv->read_reg(priv, &priv->regs->ifregs[iface].arb2); | ||
416 | val = priv->read_reg(priv, &priv->regs->ifregs[iface].arb1) | | ||
417 | (flags << 16); | ||
418 | |||
419 | if (flags & IF_ARB_MSGXTD) | ||
420 | frame->can_id = (val & CAN_EFF_MASK) | CAN_EFF_FLAG; | ||
421 | else | ||
422 | frame->can_id = (val >> 18) & CAN_SFF_MASK; | ||
423 | |||
424 | if (flags & IF_ARB_TRANSMIT) | ||
425 | frame->can_id |= CAN_RTR_FLAG; | ||
426 | else { | ||
427 | for (i = 0; i < frame->can_dlc; i += 2) { | ||
428 | data = priv->read_reg(priv, | ||
429 | &priv->regs->ifregs[iface].data[i / 2]); | ||
430 | frame->data[i] = data; | ||
431 | frame->data[i + 1] = data >> 8; | ||
432 | } | ||
433 | } | ||
434 | |||
435 | netif_receive_skb(skb); | ||
436 | |||
437 | stats->rx_packets++; | ||
438 | stats->rx_bytes += frame->can_dlc; | ||
439 | |||
440 | return 0; | ||
441 | } | ||
442 | |||
443 | static void c_can_setup_receive_object(struct net_device *dev, int iface, | ||
444 | int objno, unsigned int mask, | ||
445 | unsigned int id, unsigned int mcont) | ||
446 | { | ||
447 | struct c_can_priv *priv = netdev_priv(dev); | ||
448 | |||
449 | priv->write_reg(priv, &priv->regs->ifregs[iface].mask1, | ||
450 | IFX_WRITE_LOW_16BIT(mask)); | ||
451 | priv->write_reg(priv, &priv->regs->ifregs[iface].mask2, | ||
452 | IFX_WRITE_HIGH_16BIT(mask)); | ||
453 | |||
454 | priv->write_reg(priv, &priv->regs->ifregs[iface].arb1, | ||
455 | IFX_WRITE_LOW_16BIT(id)); | ||
456 | priv->write_reg(priv, &priv->regs->ifregs[iface].arb2, | ||
457 | (IF_ARB_MSGVAL | IFX_WRITE_HIGH_16BIT(id))); | ||
458 | |||
459 | priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl, mcont); | ||
460 | c_can_object_put(dev, iface, objno, IF_COMM_ALL & ~IF_COMM_TXRQST); | ||
461 | |||
462 | netdev_dbg(dev, "obj no:%d, msgval:0x%08x\n", objno, | ||
463 | c_can_read_reg32(priv, &priv->regs->msgval1)); | ||
464 | } | ||
465 | |||
466 | static void c_can_inval_msg_object(struct net_device *dev, int iface, int objno) | ||
467 | { | ||
468 | struct c_can_priv *priv = netdev_priv(dev); | ||
469 | |||
470 | priv->write_reg(priv, &priv->regs->ifregs[iface].arb1, 0); | ||
471 | priv->write_reg(priv, &priv->regs->ifregs[iface].arb2, 0); | ||
472 | priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl, 0); | ||
473 | |||
474 | c_can_object_put(dev, iface, objno, IF_COMM_ARB | IF_COMM_CONTROL); | ||
475 | |||
476 | netdev_dbg(dev, "obj no:%d, msgval:0x%08x\n", objno, | ||
477 | c_can_read_reg32(priv, &priv->regs->msgval1)); | ||
478 | } | ||
479 | |||
480 | static inline int c_can_is_next_tx_obj_busy(struct c_can_priv *priv, int objno) | ||
481 | { | ||
482 | int val = c_can_read_reg32(priv, &priv->regs->txrqst1); | ||
483 | |||
484 | /* | ||
485 | * as transmission request register's bit n-1 corresponds to | ||
486 | * message object n, we need to handle the same properly. | ||
487 | */ | ||
488 | if (val & (1 << (objno - 1))) | ||
489 | return 1; | ||
490 | |||
491 | return 0; | ||
492 | } | ||
493 | |||
494 | static netdev_tx_t c_can_start_xmit(struct sk_buff *skb, | ||
495 | struct net_device *dev) | ||
496 | { | ||
497 | u32 msg_obj_no; | ||
498 | struct c_can_priv *priv = netdev_priv(dev); | ||
499 | struct can_frame *frame = (struct can_frame *)skb->data; | ||
500 | |||
501 | if (can_dropped_invalid_skb(dev, skb)) | ||
502 | return NETDEV_TX_OK; | ||
503 | |||
504 | msg_obj_no = get_tx_next_msg_obj(priv); | ||
505 | |||
506 | /* prepare message object for transmission */ | ||
507 | c_can_write_msg_object(dev, 0, frame, msg_obj_no); | ||
508 | can_put_echo_skb(skb, dev, msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST); | ||
509 | |||
510 | /* | ||
511 | * we have to stop the queue in case of a wrap around or | ||
512 | * if the next TX message object is still in use | ||
513 | */ | ||
514 | priv->tx_next++; | ||
515 | if (c_can_is_next_tx_obj_busy(priv, get_tx_next_msg_obj(priv)) || | ||
516 | (priv->tx_next & C_CAN_NEXT_MSG_OBJ_MASK) == 0) | ||
517 | netif_stop_queue(dev); | ||
518 | |||
519 | return NETDEV_TX_OK; | ||
520 | } | ||
521 | |||
522 | static int c_can_set_bittiming(struct net_device *dev) | ||
523 | { | ||
524 | unsigned int reg_btr, reg_brpe, ctrl_save; | ||
525 | u8 brp, brpe, sjw, tseg1, tseg2; | ||
526 | u32 ten_bit_brp; | ||
527 | struct c_can_priv *priv = netdev_priv(dev); | ||
528 | const struct can_bittiming *bt = &priv->can.bittiming; | ||
529 | |||
530 | /* c_can provides a 6-bit brp and 4-bit brpe fields */ | ||
531 | ten_bit_brp = bt->brp - 1; | ||
532 | brp = ten_bit_brp & BTR_BRP_MASK; | ||
533 | brpe = ten_bit_brp >> 6; | ||
534 | |||
535 | sjw = bt->sjw - 1; | ||
536 | tseg1 = bt->prop_seg + bt->phase_seg1 - 1; | ||
537 | tseg2 = bt->phase_seg2 - 1; | ||
538 | reg_btr = brp | (sjw << BTR_SJW_SHIFT) | (tseg1 << BTR_TSEG1_SHIFT) | | ||
539 | (tseg2 << BTR_TSEG2_SHIFT); | ||
540 | reg_brpe = brpe & BRP_EXT_BRPE_MASK; | ||
541 | |||
542 | netdev_info(dev, | ||
543 | "setting BTR=%04x BRPE=%04x\n", reg_btr, reg_brpe); | ||
544 | |||
545 | ctrl_save = priv->read_reg(priv, &priv->regs->control); | ||
546 | priv->write_reg(priv, &priv->regs->control, | ||
547 | ctrl_save | CONTROL_CCE | CONTROL_INIT); | ||
548 | priv->write_reg(priv, &priv->regs->btr, reg_btr); | ||
549 | priv->write_reg(priv, &priv->regs->brp_ext, reg_brpe); | ||
550 | priv->write_reg(priv, &priv->regs->control, ctrl_save); | ||
551 | |||
552 | return 0; | ||
553 | } | ||
554 | |||
555 | /* | ||
556 | * Configure C_CAN message objects for Tx and Rx purposes: | ||
557 | * C_CAN provides a total of 32 message objects that can be configured | ||
558 | * either for Tx or Rx purposes. Here the first 16 message objects are used as | ||
559 | * a reception FIFO. The end of reception FIFO is signified by the EoB bit | ||
560 | * being SET. The remaining 16 message objects are kept aside for Tx purposes. | ||
561 | * See user guide document for further details on configuring message | ||
562 | * objects. | ||
563 | */ | ||
564 | static void c_can_configure_msg_objects(struct net_device *dev) | ||
565 | { | ||
566 | int i; | ||
567 | |||
568 | /* first invalidate all message objects */ | ||
569 | for (i = C_CAN_MSG_OBJ_RX_FIRST; i <= C_CAN_NO_OF_OBJECTS; i++) | ||
570 | c_can_inval_msg_object(dev, 0, i); | ||
571 | |||
572 | /* setup receive message objects */ | ||
573 | for (i = C_CAN_MSG_OBJ_RX_FIRST; i < C_CAN_MSG_OBJ_RX_LAST; i++) | ||
574 | c_can_setup_receive_object(dev, 0, i, 0, 0, | ||
575 | (IF_MCONT_RXIE | IF_MCONT_UMASK) & ~IF_MCONT_EOB); | ||
576 | |||
577 | c_can_setup_receive_object(dev, 0, C_CAN_MSG_OBJ_RX_LAST, 0, 0, | ||
578 | IF_MCONT_EOB | IF_MCONT_RXIE | IF_MCONT_UMASK); | ||
579 | } | ||
580 | |||
581 | /* | ||
582 | * Configure C_CAN chip: | ||
583 | * - enable/disable auto-retransmission | ||
584 | * - set operating mode | ||
585 | * - configure message objects | ||
586 | */ | ||
587 | static void c_can_chip_config(struct net_device *dev) | ||
588 | { | ||
589 | struct c_can_priv *priv = netdev_priv(dev); | ||
590 | |||
591 | /* enable automatic retransmission */ | ||
592 | priv->write_reg(priv, &priv->regs->control, | ||
593 | CONTROL_ENABLE_AR); | ||
594 | |||
595 | if (priv->can.ctrlmode & (CAN_CTRLMODE_LISTENONLY & | ||
596 | CAN_CTRLMODE_LOOPBACK)) { | ||
597 | /* loopback + silent mode : useful for hot self-test */ | ||
598 | priv->write_reg(priv, &priv->regs->control, CONTROL_EIE | | ||
599 | CONTROL_SIE | CONTROL_IE | CONTROL_TEST); | ||
600 | priv->write_reg(priv, &priv->regs->test, | ||
601 | TEST_LBACK | TEST_SILENT); | ||
602 | } else if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) { | ||
603 | /* loopback mode : useful for self-test function */ | ||
604 | priv->write_reg(priv, &priv->regs->control, CONTROL_EIE | | ||
605 | CONTROL_SIE | CONTROL_IE | CONTROL_TEST); | ||
606 | priv->write_reg(priv, &priv->regs->test, TEST_LBACK); | ||
607 | } else if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) { | ||
608 | /* silent mode : bus-monitoring mode */ | ||
609 | priv->write_reg(priv, &priv->regs->control, CONTROL_EIE | | ||
610 | CONTROL_SIE | CONTROL_IE | CONTROL_TEST); | ||
611 | priv->write_reg(priv, &priv->regs->test, TEST_SILENT); | ||
612 | } else | ||
613 | /* normal mode*/ | ||
614 | priv->write_reg(priv, &priv->regs->control, | ||
615 | CONTROL_EIE | CONTROL_SIE | CONTROL_IE); | ||
616 | |||
617 | /* configure message objects */ | ||
618 | c_can_configure_msg_objects(dev); | ||
619 | |||
620 | /* set a `lec` value so that we can check for updates later */ | ||
621 | priv->write_reg(priv, &priv->regs->status, LEC_UNUSED); | ||
622 | |||
623 | /* set bittiming params */ | ||
624 | c_can_set_bittiming(dev); | ||
625 | } | ||
626 | |||
627 | static void c_can_start(struct net_device *dev) | ||
628 | { | ||
629 | struct c_can_priv *priv = netdev_priv(dev); | ||
630 | |||
631 | /* basic c_can configuration */ | ||
632 | c_can_chip_config(dev); | ||
633 | |||
634 | priv->can.state = CAN_STATE_ERROR_ACTIVE; | ||
635 | |||
636 | /* reset tx helper pointers */ | ||
637 | priv->tx_next = priv->tx_echo = 0; | ||
638 | |||
639 | /* enable status change, error and module interrupts */ | ||
640 | c_can_enable_all_interrupts(priv, ENABLE_ALL_INTERRUPTS); | ||
641 | } | ||
642 | |||
643 | static void c_can_stop(struct net_device *dev) | ||
644 | { | ||
645 | struct c_can_priv *priv = netdev_priv(dev); | ||
646 | |||
647 | /* disable all interrupts */ | ||
648 | c_can_enable_all_interrupts(priv, DISABLE_ALL_INTERRUPTS); | ||
649 | |||
650 | /* set the state as STOPPED */ | ||
651 | priv->can.state = CAN_STATE_STOPPED; | ||
652 | } | ||
653 | |||
654 | static int c_can_set_mode(struct net_device *dev, enum can_mode mode) | ||
655 | { | ||
656 | switch (mode) { | ||
657 | case CAN_MODE_START: | ||
658 | c_can_start(dev); | ||
659 | netif_wake_queue(dev); | ||
660 | break; | ||
661 | default: | ||
662 | return -EOPNOTSUPP; | ||
663 | } | ||
664 | |||
665 | return 0; | ||
666 | } | ||
667 | |||
668 | static int c_can_get_berr_counter(const struct net_device *dev, | ||
669 | struct can_berr_counter *bec) | ||
670 | { | ||
671 | unsigned int reg_err_counter; | ||
672 | struct c_can_priv *priv = netdev_priv(dev); | ||
673 | |||
674 | reg_err_counter = priv->read_reg(priv, &priv->regs->err_cnt); | ||
675 | bec->rxerr = (reg_err_counter & ERR_CNT_REC_MASK) >> | ||
676 | ERR_CNT_REC_SHIFT; | ||
677 | bec->txerr = reg_err_counter & ERR_CNT_TEC_MASK; | ||
678 | |||
679 | return 0; | ||
680 | } | ||
681 | |||
682 | /* | ||
683 | * theory of operation: | ||
684 | * | ||
685 | * priv->tx_echo holds the number of the oldest can_frame put for | ||
686 | * transmission into the hardware, but not yet ACKed by the CAN tx | ||
687 | * complete IRQ. | ||
688 | * | ||
689 | * We iterate from priv->tx_echo to priv->tx_next and check if the | ||
690 | * packet has been transmitted, echo it back to the CAN framework. | ||
691 | * If we discover a not yet transmitted package, stop looking for more. | ||
692 | */ | ||
693 | static void c_can_do_tx(struct net_device *dev) | ||
694 | { | ||
695 | u32 val; | ||
696 | u32 msg_obj_no; | ||
697 | struct c_can_priv *priv = netdev_priv(dev); | ||
698 | struct net_device_stats *stats = &dev->stats; | ||
699 | |||
700 | for (/* nix */; (priv->tx_next - priv->tx_echo) > 0; priv->tx_echo++) { | ||
701 | msg_obj_no = get_tx_echo_msg_obj(priv); | ||
702 | val = c_can_read_reg32(priv, &priv->regs->txrqst1); | ||
703 | if (!(val & (1 << msg_obj_no))) { | ||
704 | can_get_echo_skb(dev, | ||
705 | msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST); | ||
706 | stats->tx_bytes += priv->read_reg(priv, | ||
707 | &priv->regs->ifregs[0].msg_cntrl) | ||
708 | & IF_MCONT_DLC_MASK; | ||
709 | stats->tx_packets++; | ||
710 | c_can_inval_msg_object(dev, 0, msg_obj_no); | ||
711 | } | ||
712 | } | ||
713 | |||
714 | /* restart queue if wrap-up or if queue stalled on last pkt */ | ||
715 | if (((priv->tx_next & C_CAN_NEXT_MSG_OBJ_MASK) != 0) || | ||
716 | ((priv->tx_echo & C_CAN_NEXT_MSG_OBJ_MASK) == 0)) | ||
717 | netif_wake_queue(dev); | ||
718 | } | ||
719 | |||
720 | /* | ||
721 | * theory of operation: | ||
722 | * | ||
723 | * c_can core saves a received CAN message into the first free message | ||
724 | * object it finds free (starting with the lowest). Bits NEWDAT and | ||
725 | * INTPND are set for this message object indicating that a new message | ||
726 | * has arrived. To work-around this issue, we keep two groups of message | ||
727 | * objects whose partitioning is defined by C_CAN_MSG_OBJ_RX_SPLIT. | ||
728 | * | ||
729 | * To ensure in-order frame reception we use the following | ||
730 | * approach while re-activating a message object to receive further | ||
731 | * frames: | ||
732 | * - if the current message object number is lower than | ||
733 | * C_CAN_MSG_RX_LOW_LAST, do not clear the NEWDAT bit while clearing | ||
734 | * the INTPND bit. | ||
735 | * - if the current message object number is equal to | ||
736 | * C_CAN_MSG_RX_LOW_LAST then clear the NEWDAT bit of all lower | ||
737 | * receive message objects. | ||
738 | * - if the current message object number is greater than | ||
739 | * C_CAN_MSG_RX_LOW_LAST then clear the NEWDAT bit of | ||
740 | * only this message object. | ||
741 | */ | ||
742 | static int c_can_do_rx_poll(struct net_device *dev, int quota) | ||
743 | { | ||
744 | u32 num_rx_pkts = 0; | ||
745 | unsigned int msg_obj, msg_ctrl_save; | ||
746 | struct c_can_priv *priv = netdev_priv(dev); | ||
747 | u32 val = c_can_read_reg32(priv, &priv->regs->intpnd1); | ||
748 | |||
749 | for (msg_obj = C_CAN_MSG_OBJ_RX_FIRST; | ||
750 | msg_obj <= C_CAN_MSG_OBJ_RX_LAST && quota > 0; | ||
751 | val = c_can_read_reg32(priv, &priv->regs->intpnd1), | ||
752 | msg_obj++) { | ||
753 | /* | ||
754 | * as interrupt pending register's bit n-1 corresponds to | ||
755 | * message object n, we need to handle the same properly. | ||
756 | */ | ||
757 | if (val & (1 << (msg_obj - 1))) { | ||
758 | c_can_object_get(dev, 0, msg_obj, IF_COMM_ALL & | ||
759 | ~IF_COMM_TXRQST); | ||
760 | msg_ctrl_save = priv->read_reg(priv, | ||
761 | &priv->regs->ifregs[0].msg_cntrl); | ||
762 | |||
763 | if (msg_ctrl_save & IF_MCONT_EOB) | ||
764 | return num_rx_pkts; | ||
765 | |||
766 | if (msg_ctrl_save & IF_MCONT_MSGLST) { | ||
767 | c_can_handle_lost_msg_obj(dev, 0, msg_obj); | ||
768 | num_rx_pkts++; | ||
769 | quota--; | ||
770 | continue; | ||
771 | } | ||
772 | |||
773 | if (!(msg_ctrl_save & IF_MCONT_NEWDAT)) | ||
774 | continue; | ||
775 | |||
776 | /* read the data from the message object */ | ||
777 | c_can_read_msg_object(dev, 0, msg_ctrl_save); | ||
778 | |||
779 | if (msg_obj < C_CAN_MSG_RX_LOW_LAST) | ||
780 | c_can_mark_rx_msg_obj(dev, 0, | ||
781 | msg_ctrl_save, msg_obj); | ||
782 | else if (msg_obj > C_CAN_MSG_RX_LOW_LAST) | ||
783 | /* activate this msg obj */ | ||
784 | c_can_activate_rx_msg_obj(dev, 0, | ||
785 | msg_ctrl_save, msg_obj); | ||
786 | else if (msg_obj == C_CAN_MSG_RX_LOW_LAST) | ||
787 | /* activate all lower message objects */ | ||
788 | c_can_activate_all_lower_rx_msg_obj(dev, | ||
789 | 0, msg_ctrl_save); | ||
790 | |||
791 | num_rx_pkts++; | ||
792 | quota--; | ||
793 | } | ||
794 | } | ||
795 | |||
796 | return num_rx_pkts; | ||
797 | } | ||
798 | |||
799 | static inline int c_can_has_and_handle_berr(struct c_can_priv *priv) | ||
800 | { | ||
801 | return (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) && | ||
802 | (priv->current_status & LEC_UNUSED); | ||
803 | } | ||
804 | |||
805 | static int c_can_handle_state_change(struct net_device *dev, | ||
806 | enum c_can_bus_error_types error_type) | ||
807 | { | ||
808 | unsigned int reg_err_counter; | ||
809 | unsigned int rx_err_passive; | ||
810 | struct c_can_priv *priv = netdev_priv(dev); | ||
811 | struct net_device_stats *stats = &dev->stats; | ||
812 | struct can_frame *cf; | ||
813 | struct sk_buff *skb; | ||
814 | struct can_berr_counter bec; | ||
815 | |||
816 | /* propagate the error condition to the CAN stack */ | ||
817 | skb = alloc_can_err_skb(dev, &cf); | ||
818 | if (unlikely(!skb)) | ||
819 | return 0; | ||
820 | |||
821 | c_can_get_berr_counter(dev, &bec); | ||
822 | reg_err_counter = priv->read_reg(priv, &priv->regs->err_cnt); | ||
823 | rx_err_passive = (reg_err_counter & ERR_CNT_RP_MASK) >> | ||
824 | ERR_CNT_RP_SHIFT; | ||
825 | |||
826 | switch (error_type) { | ||
827 | case C_CAN_ERROR_WARNING: | ||
828 | /* error warning state */ | ||
829 | priv->can.can_stats.error_warning++; | ||
830 | priv->can.state = CAN_STATE_ERROR_WARNING; | ||
831 | cf->can_id |= CAN_ERR_CRTL; | ||
832 | cf->data[1] = (bec.txerr > bec.rxerr) ? | ||
833 | CAN_ERR_CRTL_TX_WARNING : | ||
834 | CAN_ERR_CRTL_RX_WARNING; | ||
835 | cf->data[6] = bec.txerr; | ||
836 | cf->data[7] = bec.rxerr; | ||
837 | |||
838 | break; | ||
839 | case C_CAN_ERROR_PASSIVE: | ||
840 | /* error passive state */ | ||
841 | priv->can.can_stats.error_passive++; | ||
842 | priv->can.state = CAN_STATE_ERROR_PASSIVE; | ||
843 | cf->can_id |= CAN_ERR_CRTL; | ||
844 | if (rx_err_passive) | ||
845 | cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE; | ||
846 | if (bec.txerr > 127) | ||
847 | cf->data[1] |= CAN_ERR_CRTL_TX_PASSIVE; | ||
848 | |||
849 | cf->data[6] = bec.txerr; | ||
850 | cf->data[7] = bec.rxerr; | ||
851 | break; | ||
852 | case C_CAN_BUS_OFF: | ||
853 | /* bus-off state */ | ||
854 | priv->can.state = CAN_STATE_BUS_OFF; | ||
855 | cf->can_id |= CAN_ERR_BUSOFF; | ||
856 | /* | ||
857 | * disable all interrupts in bus-off mode to ensure that | ||
858 | * the CPU is not hogged down | ||
859 | */ | ||
860 | c_can_enable_all_interrupts(priv, DISABLE_ALL_INTERRUPTS); | ||
861 | can_bus_off(dev); | ||
862 | break; | ||
863 | default: | ||
864 | break; | ||
865 | } | ||
866 | |||
867 | netif_receive_skb(skb); | ||
868 | stats->rx_packets++; | ||
869 | stats->rx_bytes += cf->can_dlc; | ||
870 | |||
871 | return 1; | ||
872 | } | ||
873 | |||
874 | static int c_can_handle_bus_err(struct net_device *dev, | ||
875 | enum c_can_lec_type lec_type) | ||
876 | { | ||
877 | struct c_can_priv *priv = netdev_priv(dev); | ||
878 | struct net_device_stats *stats = &dev->stats; | ||
879 | struct can_frame *cf; | ||
880 | struct sk_buff *skb; | ||
881 | |||
882 | /* | ||
883 | * early exit if no lec update or no error. | ||
884 | * no lec update means that no CAN bus event has been detected | ||
885 | * since CPU wrote 0x7 value to status reg. | ||
886 | */ | ||
887 | if (lec_type == LEC_UNUSED || lec_type == LEC_NO_ERROR) | ||
888 | return 0; | ||
889 | |||
890 | /* propagate the error condition to the CAN stack */ | ||
891 | skb = alloc_can_err_skb(dev, &cf); | ||
892 | if (unlikely(!skb)) | ||
893 | return 0; | ||
894 | |||
895 | /* | ||
896 | * check for 'last error code' which tells us the | ||
897 | * type of the last error to occur on the CAN bus | ||
898 | */ | ||
899 | |||
900 | /* common for all type of bus errors */ | ||
901 | priv->can.can_stats.bus_error++; | ||
902 | stats->rx_errors++; | ||
903 | cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; | ||
904 | cf->data[2] |= CAN_ERR_PROT_UNSPEC; | ||
905 | |||
906 | switch (lec_type) { | ||
907 | case LEC_STUFF_ERROR: | ||
908 | netdev_dbg(dev, "stuff error\n"); | ||
909 | cf->data[2] |= CAN_ERR_PROT_STUFF; | ||
910 | break; | ||
911 | case LEC_FORM_ERROR: | ||
912 | netdev_dbg(dev, "form error\n"); | ||
913 | cf->data[2] |= CAN_ERR_PROT_FORM; | ||
914 | break; | ||
915 | case LEC_ACK_ERROR: | ||
916 | netdev_dbg(dev, "ack error\n"); | ||
917 | cf->data[2] |= (CAN_ERR_PROT_LOC_ACK | | ||
918 | CAN_ERR_PROT_LOC_ACK_DEL); | ||
919 | break; | ||
920 | case LEC_BIT1_ERROR: | ||
921 | netdev_dbg(dev, "bit1 error\n"); | ||
922 | cf->data[2] |= CAN_ERR_PROT_BIT1; | ||
923 | break; | ||
924 | case LEC_BIT0_ERROR: | ||
925 | netdev_dbg(dev, "bit0 error\n"); | ||
926 | cf->data[2] |= CAN_ERR_PROT_BIT0; | ||
927 | break; | ||
928 | case LEC_CRC_ERROR: | ||
929 | netdev_dbg(dev, "CRC error\n"); | ||
930 | cf->data[2] |= (CAN_ERR_PROT_LOC_CRC_SEQ | | ||
931 | CAN_ERR_PROT_LOC_CRC_DEL); | ||
932 | break; | ||
933 | default: | ||
934 | break; | ||
935 | } | ||
936 | |||
937 | /* set a `lec` value so that we can check for updates later */ | ||
938 | priv->write_reg(priv, &priv->regs->status, LEC_UNUSED); | ||
939 | |||
940 | netif_receive_skb(skb); | ||
941 | stats->rx_packets++; | ||
942 | stats->rx_bytes += cf->can_dlc; | ||
943 | |||
944 | return 1; | ||
945 | } | ||
946 | |||
947 | static int c_can_poll(struct napi_struct *napi, int quota) | ||
948 | { | ||
949 | u16 irqstatus; | ||
950 | int lec_type = 0; | ||
951 | int work_done = 0; | ||
952 | struct net_device *dev = napi->dev; | ||
953 | struct c_can_priv *priv = netdev_priv(dev); | ||
954 | |||
955 | irqstatus = priv->read_reg(priv, &priv->regs->interrupt); | ||
956 | if (!irqstatus) | ||
957 | goto end; | ||
958 | |||
959 | /* status events have the highest priority */ | ||
960 | if (irqstatus == STATUS_INTERRUPT) { | ||
961 | priv->current_status = priv->read_reg(priv, | ||
962 | &priv->regs->status); | ||
963 | |||
964 | /* handle Tx/Rx events */ | ||
965 | if (priv->current_status & STATUS_TXOK) | ||
966 | priv->write_reg(priv, &priv->regs->status, | ||
967 | priv->current_status & ~STATUS_TXOK); | ||
968 | |||
969 | if (priv->current_status & STATUS_RXOK) | ||
970 | priv->write_reg(priv, &priv->regs->status, | ||
971 | priv->current_status & ~STATUS_RXOK); | ||
972 | |||
973 | /* handle state changes */ | ||
974 | if ((priv->current_status & STATUS_EWARN) && | ||
975 | (!(priv->last_status & STATUS_EWARN))) { | ||
976 | netdev_dbg(dev, "entered error warning state\n"); | ||
977 | work_done += c_can_handle_state_change(dev, | ||
978 | C_CAN_ERROR_WARNING); | ||
979 | } | ||
980 | if ((priv->current_status & STATUS_EPASS) && | ||
981 | (!(priv->last_status & STATUS_EPASS))) { | ||
982 | netdev_dbg(dev, "entered error passive state\n"); | ||
983 | work_done += c_can_handle_state_change(dev, | ||
984 | C_CAN_ERROR_PASSIVE); | ||
985 | } | ||
986 | if ((priv->current_status & STATUS_BOFF) && | ||
987 | (!(priv->last_status & STATUS_BOFF))) { | ||
988 | netdev_dbg(dev, "entered bus off state\n"); | ||
989 | work_done += c_can_handle_state_change(dev, | ||
990 | C_CAN_BUS_OFF); | ||
991 | } | ||
992 | |||
993 | /* handle bus recovery events */ | ||
994 | if ((!(priv->current_status & STATUS_BOFF)) && | ||
995 | (priv->last_status & STATUS_BOFF)) { | ||
996 | netdev_dbg(dev, "left bus off state\n"); | ||
997 | priv->can.state = CAN_STATE_ERROR_ACTIVE; | ||
998 | } | ||
999 | if ((!(priv->current_status & STATUS_EPASS)) && | ||
1000 | (priv->last_status & STATUS_EPASS)) { | ||
1001 | netdev_dbg(dev, "left error passive state\n"); | ||
1002 | priv->can.state = CAN_STATE_ERROR_ACTIVE; | ||
1003 | } | ||
1004 | |||
1005 | priv->last_status = priv->current_status; | ||
1006 | |||
1007 | /* handle lec errors on the bus */ | ||
1008 | lec_type = c_can_has_and_handle_berr(priv); | ||
1009 | if (lec_type) | ||
1010 | work_done += c_can_handle_bus_err(dev, lec_type); | ||
1011 | } else if ((irqstatus >= C_CAN_MSG_OBJ_RX_FIRST) && | ||
1012 | (irqstatus <= C_CAN_MSG_OBJ_RX_LAST)) { | ||
1013 | /* handle events corresponding to receive message objects */ | ||
1014 | work_done += c_can_do_rx_poll(dev, (quota - work_done)); | ||
1015 | } else if ((irqstatus >= C_CAN_MSG_OBJ_TX_FIRST) && | ||
1016 | (irqstatus <= C_CAN_MSG_OBJ_TX_LAST)) { | ||
1017 | /* handle events corresponding to transmit message objects */ | ||
1018 | c_can_do_tx(dev); | ||
1019 | } | ||
1020 | |||
1021 | end: | ||
1022 | if (work_done < quota) { | ||
1023 | napi_complete(napi); | ||
1024 | /* enable all IRQs */ | ||
1025 | c_can_enable_all_interrupts(priv, ENABLE_ALL_INTERRUPTS); | ||
1026 | } | ||
1027 | |||
1028 | return work_done; | ||
1029 | } | ||
1030 | |||
1031 | static irqreturn_t c_can_isr(int irq, void *dev_id) | ||
1032 | { | ||
1033 | u16 irqstatus; | ||
1034 | struct net_device *dev = (struct net_device *)dev_id; | ||
1035 | struct c_can_priv *priv = netdev_priv(dev); | ||
1036 | |||
1037 | irqstatus = priv->read_reg(priv, &priv->regs->interrupt); | ||
1038 | if (!irqstatus) | ||
1039 | return IRQ_NONE; | ||
1040 | |||
1041 | /* disable all interrupts and schedule the NAPI */ | ||
1042 | c_can_enable_all_interrupts(priv, DISABLE_ALL_INTERRUPTS); | ||
1043 | napi_schedule(&priv->napi); | ||
1044 | |||
1045 | return IRQ_HANDLED; | ||
1046 | } | ||
1047 | |||
1048 | static int c_can_open(struct net_device *dev) | ||
1049 | { | ||
1050 | int err; | ||
1051 | struct c_can_priv *priv = netdev_priv(dev); | ||
1052 | |||
1053 | /* open the can device */ | ||
1054 | err = open_candev(dev); | ||
1055 | if (err) { | ||
1056 | netdev_err(dev, "failed to open can device\n"); | ||
1057 | return err; | ||
1058 | } | ||
1059 | |||
1060 | /* register interrupt handler */ | ||
1061 | err = request_irq(dev->irq, &c_can_isr, IRQF_SHARED, dev->name, | ||
1062 | dev); | ||
1063 | if (err < 0) { | ||
1064 | netdev_err(dev, "failed to request interrupt\n"); | ||
1065 | goto exit_irq_fail; | ||
1066 | } | ||
1067 | |||
1068 | /* start the c_can controller */ | ||
1069 | c_can_start(dev); | ||
1070 | |||
1071 | napi_enable(&priv->napi); | ||
1072 | netif_start_queue(dev); | ||
1073 | |||
1074 | return 0; | ||
1075 | |||
1076 | exit_irq_fail: | ||
1077 | close_candev(dev); | ||
1078 | return err; | ||
1079 | } | ||
1080 | |||
1081 | static int c_can_close(struct net_device *dev) | ||
1082 | { | ||
1083 | struct c_can_priv *priv = netdev_priv(dev); | ||
1084 | |||
1085 | netif_stop_queue(dev); | ||
1086 | napi_disable(&priv->napi); | ||
1087 | c_can_stop(dev); | ||
1088 | free_irq(dev->irq, dev); | ||
1089 | close_candev(dev); | ||
1090 | |||
1091 | return 0; | ||
1092 | } | ||
1093 | |||
1094 | struct net_device *alloc_c_can_dev(void) | ||
1095 | { | ||
1096 | struct net_device *dev; | ||
1097 | struct c_can_priv *priv; | ||
1098 | |||
1099 | dev = alloc_candev(sizeof(struct c_can_priv), C_CAN_MSG_OBJ_TX_NUM); | ||
1100 | if (!dev) | ||
1101 | return NULL; | ||
1102 | |||
1103 | priv = netdev_priv(dev); | ||
1104 | netif_napi_add(dev, &priv->napi, c_can_poll, C_CAN_NAPI_WEIGHT); | ||
1105 | |||
1106 | priv->dev = dev; | ||
1107 | priv->can.bittiming_const = &c_can_bittiming_const; | ||
1108 | priv->can.do_set_mode = c_can_set_mode; | ||
1109 | priv->can.do_get_berr_counter = c_can_get_berr_counter; | ||
1110 | priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK | | ||
1111 | CAN_CTRLMODE_LISTENONLY | | ||
1112 | CAN_CTRLMODE_BERR_REPORTING; | ||
1113 | |||
1114 | return dev; | ||
1115 | } | ||
1116 | EXPORT_SYMBOL_GPL(alloc_c_can_dev); | ||
1117 | |||
1118 | void free_c_can_dev(struct net_device *dev) | ||
1119 | { | ||
1120 | free_candev(dev); | ||
1121 | } | ||
1122 | EXPORT_SYMBOL_GPL(free_c_can_dev); | ||
1123 | |||
1124 | static const struct net_device_ops c_can_netdev_ops = { | ||
1125 | .ndo_open = c_can_open, | ||
1126 | .ndo_stop = c_can_close, | ||
1127 | .ndo_start_xmit = c_can_start_xmit, | ||
1128 | }; | ||
1129 | |||
1130 | int register_c_can_dev(struct net_device *dev) | ||
1131 | { | ||
1132 | dev->flags |= IFF_ECHO; /* we support local echo */ | ||
1133 | dev->netdev_ops = &c_can_netdev_ops; | ||
1134 | |||
1135 | return register_candev(dev); | ||
1136 | } | ||
1137 | EXPORT_SYMBOL_GPL(register_c_can_dev); | ||
1138 | |||
1139 | void unregister_c_can_dev(struct net_device *dev) | ||
1140 | { | ||
1141 | struct c_can_priv *priv = netdev_priv(dev); | ||
1142 | |||
1143 | /* disable all interrupts */ | ||
1144 | c_can_enable_all_interrupts(priv, DISABLE_ALL_INTERRUPTS); | ||
1145 | |||
1146 | unregister_candev(dev); | ||
1147 | } | ||
1148 | EXPORT_SYMBOL_GPL(unregister_c_can_dev); | ||
1149 | |||
1150 | MODULE_AUTHOR("Bhupesh Sharma <bhupesh.sharma@st.com>"); | ||
1151 | MODULE_LICENSE("GPL v2"); | ||
1152 | MODULE_DESCRIPTION("CAN bus driver for Bosch C_CAN controller"); | ||
diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h new file mode 100644 index 000000000000..9b7fbef3d09a --- /dev/null +++ b/drivers/net/can/c_can/c_can.h | |||
@@ -0,0 +1,86 @@ | |||
1 | /* | ||
2 | * CAN bus driver for Bosch C_CAN controller | ||
3 | * | ||
4 | * Copyright (C) 2010 ST Microelectronics | ||
5 | * Bhupesh Sharma <bhupesh.sharma@st.com> | ||
6 | * | ||
7 | * Borrowed heavily from the C_CAN driver originally written by: | ||
8 | * Copyright (C) 2007 | ||
9 | * - Sascha Hauer, Marc Kleine-Budde, Pengutronix <s.hauer@pengutronix.de> | ||
10 | * - Simon Kallweit, intefo AG <simon.kallweit@intefo.ch> | ||
11 | * | ||
12 | * Bosch C_CAN controller is compliant to CAN protocol version 2.0 part A and B. | ||
13 | * Bosch C_CAN user manual can be obtained from: | ||
14 | * http://www.semiconductors.bosch.de/media/en/pdf/ipmodules_1/c_can/ | ||
15 | * users_manual_c_can.pdf | ||
16 | * | ||
17 | * This file is licensed under the terms of the GNU General Public | ||
18 | * License version 2. This program is licensed "as is" without any | ||
19 | * warranty of any kind, whether express or implied. | ||
20 | */ | ||
21 | |||
22 | #ifndef C_CAN_H | ||
23 | #define C_CAN_H | ||
24 | |||
25 | /* c_can IF registers */ | ||
26 | struct c_can_if_regs { | ||
27 | u16 com_req; | ||
28 | u16 com_mask; | ||
29 | u16 mask1; | ||
30 | u16 mask2; | ||
31 | u16 arb1; | ||
32 | u16 arb2; | ||
33 | u16 msg_cntrl; | ||
34 | u16 data[4]; | ||
35 | u16 _reserved[13]; | ||
36 | }; | ||
37 | |||
38 | /* c_can hardware registers */ | ||
39 | struct c_can_regs { | ||
40 | u16 control; | ||
41 | u16 status; | ||
42 | u16 err_cnt; | ||
43 | u16 btr; | ||
44 | u16 interrupt; | ||
45 | u16 test; | ||
46 | u16 brp_ext; | ||
47 | u16 _reserved1; | ||
48 | struct c_can_if_regs ifregs[2]; /* [0] = IF1 and [1] = IF2 */ | ||
49 | u16 _reserved2[8]; | ||
50 | u16 txrqst1; | ||
51 | u16 txrqst2; | ||
52 | u16 _reserved3[6]; | ||
53 | u16 newdat1; | ||
54 | u16 newdat2; | ||
55 | u16 _reserved4[6]; | ||
56 | u16 intpnd1; | ||
57 | u16 intpnd2; | ||
58 | u16 _reserved5[6]; | ||
59 | u16 msgval1; | ||
60 | u16 msgval2; | ||
61 | u16 _reserved6[6]; | ||
62 | }; | ||
63 | |||
64 | /* c_can private data structure */ | ||
65 | struct c_can_priv { | ||
66 | struct can_priv can; /* must be the first member */ | ||
67 | struct napi_struct napi; | ||
68 | struct net_device *dev; | ||
69 | int tx_object; | ||
70 | int current_status; | ||
71 | int last_status; | ||
72 | u16 (*read_reg) (struct c_can_priv *priv, void *reg); | ||
73 | void (*write_reg) (struct c_can_priv *priv, void *reg, u16 val); | ||
74 | struct c_can_regs __iomem *regs; | ||
75 | unsigned long irq_flags; /* for request_irq() */ | ||
76 | unsigned int tx_next; | ||
77 | unsigned int tx_echo; | ||
78 | void *priv; /* for board-specific data */ | ||
79 | }; | ||
80 | |||
81 | struct net_device *alloc_c_can_dev(void); | ||
82 | void free_c_can_dev(struct net_device *dev); | ||
83 | int register_c_can_dev(struct net_device *dev); | ||
84 | void unregister_c_can_dev(struct net_device *dev); | ||
85 | |||
86 | #endif /* C_CAN_H */ | ||
diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c new file mode 100644 index 000000000000..cc90824f2c9c --- /dev/null +++ b/drivers/net/can/c_can/c_can_platform.c | |||
@@ -0,0 +1,216 @@ | |||
1 | /* | ||
2 | * Platform CAN bus driver for Bosch C_CAN controller | ||
3 | * | ||
4 | * Copyright (C) 2010 ST Microelectronics | ||
5 | * Bhupesh Sharma <bhupesh.sharma@st.com> | ||
6 | * | ||
7 | * Borrowed heavily from the C_CAN driver originally written by: | ||
8 | * Copyright (C) 2007 | ||
9 | * - Sascha Hauer, Marc Kleine-Budde, Pengutronix <s.hauer@pengutronix.de> | ||
10 | * - Simon Kallweit, intefo AG <simon.kallweit@intefo.ch> | ||
11 | * | ||
12 | * Bosch C_CAN controller is compliant to CAN protocol version 2.0 part A and B. | ||
13 | * Bosch C_CAN user manual can be obtained from: | ||
14 | * http://www.semiconductors.bosch.de/media/en/pdf/ipmodules_1/c_can/ | ||
15 | * users_manual_c_can.pdf | ||
16 | * | ||
17 | * This file is licensed under the terms of the GNU General Public | ||
18 | * License version 2. This program is licensed "as is" without any | ||
19 | * warranty of any kind, whether express or implied. | ||
20 | */ | ||
21 | |||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/version.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/interrupt.h> | ||
26 | #include <linux/delay.h> | ||
27 | #include <linux/netdevice.h> | ||
28 | #include <linux/if_arp.h> | ||
29 | #include <linux/if_ether.h> | ||
30 | #include <linux/list.h> | ||
31 | #include <linux/delay.h> | ||
32 | #include <linux/io.h> | ||
33 | #include <linux/platform_device.h> | ||
34 | #include <linux/clk.h> | ||
35 | |||
36 | #include <linux/can/dev.h> | ||
37 | |||
38 | #include "c_can.h" | ||
39 | |||
40 | /* | ||
41 | * 16-bit c_can registers can be arranged differently in the memory | ||
42 | * architecture of different implementations. For example: 16-bit | ||
43 | * registers can be aligned to a 16-bit boundary or 32-bit boundary etc. | ||
44 | * Handle the same by providing a common read/write interface. | ||
45 | */ | ||
46 | static u16 c_can_plat_read_reg_aligned_to_16bit(struct c_can_priv *priv, | ||
47 | void *reg) | ||
48 | { | ||
49 | return readw(reg); | ||
50 | } | ||
51 | |||
52 | static void c_can_plat_write_reg_aligned_to_16bit(struct c_can_priv *priv, | ||
53 | void *reg, u16 val) | ||
54 | { | ||
55 | writew(val, reg); | ||
56 | } | ||
57 | |||
58 | static u16 c_can_plat_read_reg_aligned_to_32bit(struct c_can_priv *priv, | ||
59 | void *reg) | ||
60 | { | ||
61 | return readw(reg + (long)reg - (long)priv->regs); | ||
62 | } | ||
63 | |||
64 | static void c_can_plat_write_reg_aligned_to_32bit(struct c_can_priv *priv, | ||
65 | void *reg, u16 val) | ||
66 | { | ||
67 | writew(val, reg + (long)reg - (long)priv->regs); | ||
68 | } | ||
69 | |||
70 | static int __devinit c_can_plat_probe(struct platform_device *pdev) | ||
71 | { | ||
72 | int ret; | ||
73 | void __iomem *addr; | ||
74 | struct net_device *dev; | ||
75 | struct c_can_priv *priv; | ||
76 | struct resource *mem; | ||
77 | int irq; | ||
78 | #ifdef CONFIG_HAVE_CLK | ||
79 | struct clk *clk; | ||
80 | |||
81 | /* get the appropriate clk */ | ||
82 | clk = clk_get(&pdev->dev, NULL); | ||
83 | if (IS_ERR(clk)) { | ||
84 | dev_err(&pdev->dev, "no clock defined\n"); | ||
85 | ret = -ENODEV; | ||
86 | goto exit; | ||
87 | } | ||
88 | #endif | ||
89 | |||
90 | /* get the platform data */ | ||
91 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
92 | irq = platform_get_irq(pdev, 0); | ||
93 | if (!mem || irq <= 0) { | ||
94 | ret = -ENODEV; | ||
95 | goto exit_free_clk; | ||
96 | } | ||
97 | |||
98 | if (!request_mem_region(mem->start, resource_size(mem), | ||
99 | KBUILD_MODNAME)) { | ||
100 | dev_err(&pdev->dev, "resource unavailable\n"); | ||
101 | ret = -ENODEV; | ||
102 | goto exit_free_clk; | ||
103 | } | ||
104 | |||
105 | addr = ioremap(mem->start, resource_size(mem)); | ||
106 | if (!addr) { | ||
107 | dev_err(&pdev->dev, "failed to map can port\n"); | ||
108 | ret = -ENOMEM; | ||
109 | goto exit_release_mem; | ||
110 | } | ||
111 | |||
112 | /* allocate the c_can device */ | ||
113 | dev = alloc_c_can_dev(); | ||
114 | if (!dev) { | ||
115 | ret = -ENOMEM; | ||
116 | goto exit_iounmap; | ||
117 | } | ||
118 | |||
119 | priv = netdev_priv(dev); | ||
120 | |||
121 | dev->irq = irq; | ||
122 | priv->regs = addr; | ||
123 | #ifdef CONFIG_HAVE_CLK | ||
124 | priv->can.clock.freq = clk_get_rate(clk); | ||
125 | priv->priv = clk; | ||
126 | #endif | ||
127 | |||
128 | switch (mem->flags & IORESOURCE_MEM_TYPE_MASK) { | ||
129 | case IORESOURCE_MEM_32BIT: | ||
130 | priv->read_reg = c_can_plat_read_reg_aligned_to_32bit; | ||
131 | priv->write_reg = c_can_plat_write_reg_aligned_to_32bit; | ||
132 | break; | ||
133 | case IORESOURCE_MEM_16BIT: | ||
134 | default: | ||
135 | priv->read_reg = c_can_plat_read_reg_aligned_to_16bit; | ||
136 | priv->write_reg = c_can_plat_write_reg_aligned_to_16bit; | ||
137 | break; | ||
138 | } | ||
139 | |||
140 | platform_set_drvdata(pdev, dev); | ||
141 | SET_NETDEV_DEV(dev, &pdev->dev); | ||
142 | |||
143 | ret = register_c_can_dev(dev); | ||
144 | if (ret) { | ||
145 | dev_err(&pdev->dev, "registering %s failed (err=%d)\n", | ||
146 | KBUILD_MODNAME, ret); | ||
147 | goto exit_free_device; | ||
148 | } | ||
149 | |||
150 | dev_info(&pdev->dev, "%s device registered (regs=%p, irq=%d)\n", | ||
151 | KBUILD_MODNAME, priv->regs, dev->irq); | ||
152 | return 0; | ||
153 | |||
154 | exit_free_device: | ||
155 | platform_set_drvdata(pdev, NULL); | ||
156 | free_c_can_dev(dev); | ||
157 | exit_iounmap: | ||
158 | iounmap(addr); | ||
159 | exit_release_mem: | ||
160 | release_mem_region(mem->start, resource_size(mem)); | ||
161 | exit_free_clk: | ||
162 | #ifdef CONFIG_HAVE_CLK | ||
163 | clk_put(clk); | ||
164 | exit: | ||
165 | #endif | ||
166 | dev_err(&pdev->dev, "probe failed\n"); | ||
167 | |||
168 | return ret; | ||
169 | } | ||
170 | |||
171 | static int __devexit c_can_plat_remove(struct platform_device *pdev) | ||
172 | { | ||
173 | struct net_device *dev = platform_get_drvdata(pdev); | ||
174 | struct c_can_priv *priv = netdev_priv(dev); | ||
175 | struct resource *mem; | ||
176 | |||
177 | unregister_c_can_dev(dev); | ||
178 | platform_set_drvdata(pdev, NULL); | ||
179 | |||
180 | free_c_can_dev(dev); | ||
181 | iounmap(priv->regs); | ||
182 | |||
183 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
184 | release_mem_region(mem->start, resource_size(mem)); | ||
185 | |||
186 | #ifdef CONFIG_HAVE_CLK | ||
187 | clk_put(priv->priv); | ||
188 | #endif | ||
189 | |||
190 | return 0; | ||
191 | } | ||
192 | |||
193 | static struct platform_driver c_can_plat_driver = { | ||
194 | .driver = { | ||
195 | .name = KBUILD_MODNAME, | ||
196 | .owner = THIS_MODULE, | ||
197 | }, | ||
198 | .probe = c_can_plat_probe, | ||
199 | .remove = __devexit_p(c_can_plat_remove), | ||
200 | }; | ||
201 | |||
202 | static int __init c_can_plat_init(void) | ||
203 | { | ||
204 | return platform_driver_register(&c_can_plat_driver); | ||
205 | } | ||
206 | module_init(c_can_plat_init); | ||
207 | |||
208 | static void __exit c_can_plat_exit(void) | ||
209 | { | ||
210 | platform_driver_unregister(&c_can_plat_driver); | ||
211 | } | ||
212 | module_exit(c_can_plat_exit); | ||
213 | |||
214 | MODULE_AUTHOR("Bhupesh Sharma <bhupesh.sharma@st.com>"); | ||
215 | MODULE_LICENSE("GPL v2"); | ||
216 | MODULE_DESCRIPTION("Platform CAN bus driver for Bosch C_CAN controller"); | ||