blob: 954b2959b6b23d594bb2ef72b2796cf701374d9a [file] [log] [blame]
Kurt Van Dijck03fd3cf2011-01-11 04:32:31 +00001/*
2 * Copyright (C) 2008-2010
3 *
4 * - Kurt Van Dijck, EIA Electronics
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the version 2 of the GNU General Public License
8 * as published by the Free Software Foundation
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#include <linux/version.h>
21#include <linux/module.h>
22#include <linux/init.h>
23#include <linux/interrupt.h>
Alexey Dobriyanb7f080c2011-06-16 11:01:34 +000024#include <asm/io.h>
Kurt Van Dijck03fd3cf2011-01-11 04:32:31 +000025
26#include "softing.h"
27
28#define TX_ECHO_SKB_MAX (((TXMAX+1)/2)-1)
29
30/*
31 * test is a specific CAN netdev
32 * is online (ie. up 'n running, not sleeping, not busoff
33 */
34static inline int canif_is_active(struct net_device *netdev)
35{
36 struct can_priv *can = netdev_priv(netdev);
37
38 if (!netif_running(netdev))
39 return 0;
40 return (can->state <= CAN_STATE_ERROR_PASSIVE);
41}
42
43/* reset DPRAM */
44static inline void softing_set_reset_dpram(struct softing *card)
45{
46 if (card->pdat->generation >= 2) {
47 spin_lock_bh(&card->spin);
48 iowrite8(ioread8(&card->dpram[DPRAM_V2_RESET]) & ~1,
49 &card->dpram[DPRAM_V2_RESET]);
50 spin_unlock_bh(&card->spin);
51 }
52}
53
54static inline void softing_clr_reset_dpram(struct softing *card)
55{
56 if (card->pdat->generation >= 2) {
57 spin_lock_bh(&card->spin);
58 iowrite8(ioread8(&card->dpram[DPRAM_V2_RESET]) | 1,
59 &card->dpram[DPRAM_V2_RESET]);
60 spin_unlock_bh(&card->spin);
61 }
62}
63
64/* trigger the tx queue-ing */
65static netdev_tx_t softing_netdev_start_xmit(struct sk_buff *skb,
66 struct net_device *dev)
67{
68 struct softing_priv *priv = netdev_priv(dev);
69 struct softing *card = priv->card;
70 int ret;
71 uint8_t *ptr;
72 uint8_t fifo_wr, fifo_rd;
73 struct can_frame *cf = (struct can_frame *)skb->data;
74 uint8_t buf[DPRAM_TX_SIZE];
75
76 if (can_dropped_invalid_skb(dev, skb))
77 return NETDEV_TX_OK;
78
79 spin_lock(&card->spin);
80
81 ret = NETDEV_TX_BUSY;
82 if (!card->fw.up ||
83 (card->tx.pending >= TXMAX) ||
84 (priv->tx.pending >= TX_ECHO_SKB_MAX))
85 goto xmit_done;
86 fifo_wr = ioread8(&card->dpram[DPRAM_TX_WR]);
87 fifo_rd = ioread8(&card->dpram[DPRAM_TX_RD]);
88 if (fifo_wr == fifo_rd)
89 /* fifo full */
90 goto xmit_done;
91 memset(buf, 0, sizeof(buf));
92 ptr = buf;
93 *ptr = CMD_TX;
94 if (cf->can_id & CAN_RTR_FLAG)
95 *ptr |= CMD_RTR;
96 if (cf->can_id & CAN_EFF_FLAG)
97 *ptr |= CMD_XTD;
98 if (priv->index)
99 *ptr |= CMD_BUS2;
100 ++ptr;
101 *ptr++ = cf->can_dlc;
102 *ptr++ = (cf->can_id >> 0);
103 *ptr++ = (cf->can_id >> 8);
104 if (cf->can_id & CAN_EFF_FLAG) {
105 *ptr++ = (cf->can_id >> 16);
106 *ptr++ = (cf->can_id >> 24);
107 } else {
108 /* increment 1, not 2 as you might think */
109 ptr += 1;
110 }
111 if (!(cf->can_id & CAN_RTR_FLAG))
112 memcpy(ptr, &cf->data[0], cf->can_dlc);
113 memcpy_toio(&card->dpram[DPRAM_TX + DPRAM_TX_SIZE * fifo_wr],
114 buf, DPRAM_TX_SIZE);
115 if (++fifo_wr >= DPRAM_TX_CNT)
116 fifo_wr = 0;
117 iowrite8(fifo_wr, &card->dpram[DPRAM_TX_WR]);
118 card->tx.last_bus = priv->index;
119 ++card->tx.pending;
120 ++priv->tx.pending;
121 can_put_echo_skb(skb, dev, priv->tx.echo_put);
122 ++priv->tx.echo_put;
123 if (priv->tx.echo_put >= TX_ECHO_SKB_MAX)
124 priv->tx.echo_put = 0;
125 /* can_put_echo_skb() saves the skb, safe to return TX_OK */
126 ret = NETDEV_TX_OK;
127xmit_done:
128 spin_unlock(&card->spin);
129 if (card->tx.pending >= TXMAX) {
130 int j;
131 for (j = 0; j < ARRAY_SIZE(card->net); ++j) {
132 if (card->net[j])
133 netif_stop_queue(card->net[j]);
134 }
135 }
136 if (ret != NETDEV_TX_OK)
137 netif_stop_queue(dev);
138
139 return ret;
140}
141
142/*
143 * shortcut for skb delivery
144 */
145int softing_netdev_rx(struct net_device *netdev, const struct can_frame *msg,
146 ktime_t ktime)
147{
148 struct sk_buff *skb;
149 struct can_frame *cf;
150
151 skb = alloc_can_skb(netdev, &cf);
152 if (!skb)
153 return -ENOMEM;
154 memcpy(cf, msg, sizeof(*msg));
155 skb->tstamp = ktime;
156 return netif_rx(skb);
157}
158
159/*
160 * softing_handle_1
161 * pop 1 entry from the DPRAM queue, and process
162 */
163static int softing_handle_1(struct softing *card)
164{
165 struct net_device *netdev;
166 struct softing_priv *priv;
167 ktime_t ktime;
168 struct can_frame msg;
169 int cnt = 0, lost_msg;
170 uint8_t fifo_rd, fifo_wr, cmd;
171 uint8_t *ptr;
172 uint32_t tmp_u32;
173 uint8_t buf[DPRAM_RX_SIZE];
174
175 memset(&msg, 0, sizeof(msg));
176 /* test for lost msgs */
177 lost_msg = ioread8(&card->dpram[DPRAM_RX_LOST]);
178 if (lost_msg) {
179 int j;
180 /* reset condition */
181 iowrite8(0, &card->dpram[DPRAM_RX_LOST]);
182 /* prepare msg */
183 msg.can_id = CAN_ERR_FLAG | CAN_ERR_CRTL;
184 msg.can_dlc = CAN_ERR_DLC;
185 msg.data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
186 /*
187 * service to all busses, we don't know which it was applicable
188 * but only service busses that are online
189 */
190 for (j = 0; j < ARRAY_SIZE(card->net); ++j) {
191 netdev = card->net[j];
192 if (!netdev)
193 continue;
194 if (!canif_is_active(netdev))
195 /* a dead bus has no overflows */
196 continue;
197 ++netdev->stats.rx_over_errors;
198 softing_netdev_rx(netdev, &msg, ktime_set(0, 0));
199 }
200 /* prepare for other use */
201 memset(&msg, 0, sizeof(msg));
202 ++cnt;
203 }
204
205 fifo_rd = ioread8(&card->dpram[DPRAM_RX_RD]);
206 fifo_wr = ioread8(&card->dpram[DPRAM_RX_WR]);
207
208 if (++fifo_rd >= DPRAM_RX_CNT)
209 fifo_rd = 0;
210 if (fifo_wr == fifo_rd)
211 return cnt;
212
213 memcpy_fromio(buf, &card->dpram[DPRAM_RX + DPRAM_RX_SIZE*fifo_rd],
214 DPRAM_RX_SIZE);
215 mb();
216 /* trigger dual port RAM */
217 iowrite8(fifo_rd, &card->dpram[DPRAM_RX_RD]);
218
219 ptr = buf;
220 cmd = *ptr++;
221 if (cmd == 0xff)
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300222 /* not quite useful, probably the card has got out */
Kurt Van Dijck03fd3cf2011-01-11 04:32:31 +0000223 return 0;
224 netdev = card->net[0];
225 if (cmd & CMD_BUS2)
226 netdev = card->net[1];
227 priv = netdev_priv(netdev);
228
229 if (cmd & CMD_ERR) {
230 uint8_t can_state, state;
231
232 state = *ptr++;
233
234 msg.can_id = CAN_ERR_FLAG;
235 msg.can_dlc = CAN_ERR_DLC;
236
237 if (state & SF_MASK_BUSOFF) {
238 can_state = CAN_STATE_BUS_OFF;
239 msg.can_id |= CAN_ERR_BUSOFF;
240 state = STATE_BUSOFF;
241 } else if (state & SF_MASK_EPASSIVE) {
242 can_state = CAN_STATE_ERROR_PASSIVE;
243 msg.can_id |= CAN_ERR_CRTL;
244 msg.data[1] = CAN_ERR_CRTL_TX_PASSIVE;
245 state = STATE_EPASSIVE;
246 } else {
247 can_state = CAN_STATE_ERROR_ACTIVE;
248 msg.can_id |= CAN_ERR_CRTL;
249 state = STATE_EACTIVE;
250 }
251 /* update DPRAM */
252 iowrite8(state, &card->dpram[priv->index ?
253 DPRAM_INFO_BUSSTATE2 : DPRAM_INFO_BUSSTATE]);
254 /* timestamp */
255 tmp_u32 = le32_to_cpup((void *)ptr);
256 ptr += 4;
257 ktime = softing_raw2ktime(card, tmp_u32);
258
259 ++netdev->stats.rx_errors;
260 /* update internal status */
261 if (can_state != priv->can.state) {
262 priv->can.state = can_state;
263 if (can_state == CAN_STATE_ERROR_PASSIVE)
264 ++priv->can.can_stats.error_passive;
265 else if (can_state == CAN_STATE_BUS_OFF) {
266 /* this calls can_close_cleanup() */
267 can_bus_off(netdev);
268 netif_stop_queue(netdev);
269 }
270 /* trigger socketcan */
271 softing_netdev_rx(netdev, &msg, ktime);
272 }
273
274 } else {
275 if (cmd & CMD_RTR)
276 msg.can_id |= CAN_RTR_FLAG;
277 msg.can_dlc = get_can_dlc(*ptr++);
278 if (cmd & CMD_XTD) {
279 msg.can_id |= CAN_EFF_FLAG;
280 msg.can_id |= le32_to_cpup((void *)ptr);
281 ptr += 4;
282 } else {
283 msg.can_id |= le16_to_cpup((void *)ptr);
284 ptr += 2;
285 }
286 /* timestamp */
287 tmp_u32 = le32_to_cpup((void *)ptr);
288 ptr += 4;
289 ktime = softing_raw2ktime(card, tmp_u32);
290 if (!(msg.can_id & CAN_RTR_FLAG))
291 memcpy(&msg.data[0], ptr, 8);
292 ptr += 8;
293 /* update socket */
294 if (cmd & CMD_ACK) {
295 /* acknowledge, was tx msg */
296 struct sk_buff *skb;
297 skb = priv->can.echo_skb[priv->tx.echo_get];
298 if (skb)
299 skb->tstamp = ktime;
300 can_get_echo_skb(netdev, priv->tx.echo_get);
301 ++priv->tx.echo_get;
302 if (priv->tx.echo_get >= TX_ECHO_SKB_MAX)
303 priv->tx.echo_get = 0;
304 if (priv->tx.pending)
305 --priv->tx.pending;
306 if (card->tx.pending)
307 --card->tx.pending;
308 ++netdev->stats.tx_packets;
309 if (!(msg.can_id & CAN_RTR_FLAG))
310 netdev->stats.tx_bytes += msg.can_dlc;
311 } else {
312 int ret;
313
314 ret = softing_netdev_rx(netdev, &msg, ktime);
315 if (ret == NET_RX_SUCCESS) {
316 ++netdev->stats.rx_packets;
317 if (!(msg.can_id & CAN_RTR_FLAG))
318 netdev->stats.rx_bytes += msg.can_dlc;
319 } else {
320 ++netdev->stats.rx_dropped;
321 }
322 }
323 }
324 ++cnt;
325 return cnt;
326}
327
328/*
329 * real interrupt handler
330 */
331static irqreturn_t softing_irq_thread(int irq, void *dev_id)
332{
333 struct softing *card = (struct softing *)dev_id;
334 struct net_device *netdev;
335 struct softing_priv *priv;
336 int j, offset, work_done;
337
338 work_done = 0;
339 spin_lock_bh(&card->spin);
340 while (softing_handle_1(card) > 0) {
341 ++card->irq.svc_count;
342 ++work_done;
343 }
344 spin_unlock_bh(&card->spin);
345 /* resume tx queue's */
346 offset = card->tx.last_bus;
347 for (j = 0; j < ARRAY_SIZE(card->net); ++j) {
348 if (card->tx.pending >= TXMAX)
349 break;
350 netdev = card->net[(j + offset + 1) % card->pdat->nbus];
351 if (!netdev)
352 continue;
353 priv = netdev_priv(netdev);
354 if (!canif_is_active(netdev))
355 /* it makes no sense to wake dead busses */
356 continue;
357 if (priv->tx.pending >= TX_ECHO_SKB_MAX)
358 continue;
359 ++work_done;
360 netif_wake_queue(netdev);
361 }
362 return work_done ? IRQ_HANDLED : IRQ_NONE;
363}
364
365/*
366 * interrupt routines:
367 * schedule the 'real interrupt handler'
368 */
369static irqreturn_t softing_irq_v2(int irq, void *dev_id)
370{
371 struct softing *card = (struct softing *)dev_id;
372 uint8_t ir;
373
374 ir = ioread8(&card->dpram[DPRAM_V2_IRQ_TOHOST]);
375 iowrite8(0, &card->dpram[DPRAM_V2_IRQ_TOHOST]);
376 return (1 == ir) ? IRQ_WAKE_THREAD : IRQ_NONE;
377}
378
379static irqreturn_t softing_irq_v1(int irq, void *dev_id)
380{
381 struct softing *card = (struct softing *)dev_id;
382 uint8_t ir;
383
384 ir = ioread8(&card->dpram[DPRAM_IRQ_TOHOST]);
385 iowrite8(0, &card->dpram[DPRAM_IRQ_TOHOST]);
386 return ir ? IRQ_WAKE_THREAD : IRQ_NONE;
387}
388
389/*
390 * netdev/candev inter-operability
391 */
392static int softing_netdev_open(struct net_device *ndev)
393{
394 int ret;
395
396 /* check or determine and set bittime */
397 ret = open_candev(ndev);
398 if (!ret)
399 ret = softing_startstop(ndev, 1);
400 return ret;
401}
402
403static int softing_netdev_stop(struct net_device *ndev)
404{
405 int ret;
406
407 netif_stop_queue(ndev);
408
409 /* softing cycle does close_candev() */
410 ret = softing_startstop(ndev, 0);
411 return ret;
412}
413
414static int softing_candev_set_mode(struct net_device *ndev, enum can_mode mode)
415{
416 int ret;
417
418 switch (mode) {
419 case CAN_MODE_START:
420 /* softing_startstop does close_candev() */
421 ret = softing_startstop(ndev, 1);
422 return ret;
423 case CAN_MODE_STOP:
424 case CAN_MODE_SLEEP:
425 return -EOPNOTSUPP;
426 }
427 return 0;
428}
429
430/*
431 * Softing device management helpers
432 */
433int softing_enable_irq(struct softing *card, int enable)
434{
435 int ret;
436
437 if (!card->irq.nr) {
438 return 0;
439 } else if (card->irq.requested && !enable) {
440 free_irq(card->irq.nr, card);
441 card->irq.requested = 0;
442 } else if (!card->irq.requested && enable) {
443 ret = request_threaded_irq(card->irq.nr,
444 (card->pdat->generation >= 2) ?
445 softing_irq_v2 : softing_irq_v1,
446 softing_irq_thread, IRQF_SHARED,
447 dev_name(&card->pdev->dev), card);
448 if (ret) {
449 dev_alert(&card->pdev->dev,
450 "request_threaded_irq(%u) failed\n",
451 card->irq.nr);
452 return ret;
453 }
454 card->irq.requested = 1;
455 }
456 return 0;
457}
458
459static void softing_card_shutdown(struct softing *card)
460{
461 int fw_up = 0;
462
463 if (mutex_lock_interruptible(&card->fw.lock))
464 /* return -ERESTARTSYS */;
465 fw_up = card->fw.up;
466 card->fw.up = 0;
467
468 if (card->irq.requested && card->irq.nr) {
469 free_irq(card->irq.nr, card);
470 card->irq.requested = 0;
471 }
472 if (fw_up) {
473 if (card->pdat->enable_irq)
474 card->pdat->enable_irq(card->pdev, 0);
475 softing_set_reset_dpram(card);
476 if (card->pdat->reset)
477 card->pdat->reset(card->pdev, 1);
478 }
479 mutex_unlock(&card->fw.lock);
480}
481
482static __devinit int softing_card_boot(struct softing *card)
483{
484 int ret, j;
485 static const uint8_t stream[] = {
486 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, };
487 unsigned char back[sizeof(stream)];
488
489 if (mutex_lock_interruptible(&card->fw.lock))
490 return -ERESTARTSYS;
491 if (card->fw.up) {
492 mutex_unlock(&card->fw.lock);
493 return 0;
494 }
495 /* reset board */
496 if (card->pdat->enable_irq)
497 card->pdat->enable_irq(card->pdev, 1);
498 /* boot card */
499 softing_set_reset_dpram(card);
500 if (card->pdat->reset)
501 card->pdat->reset(card->pdev, 1);
502 for (j = 0; (j + sizeof(stream)) < card->dpram_size;
503 j += sizeof(stream)) {
504
505 memcpy_toio(&card->dpram[j], stream, sizeof(stream));
506 /* flush IO cache */
507 mb();
508 memcpy_fromio(back, &card->dpram[j], sizeof(stream));
509
510 if (!memcmp(back, stream, sizeof(stream)))
511 continue;
512 /* memory is not equal */
513 dev_alert(&card->pdev->dev, "dpram failed at 0x%04x\n", j);
514 ret = -EIO;
515 goto failed;
516 }
517 wmb();
518 /* load boot firmware */
519 ret = softing_load_fw(card->pdat->boot.fw, card, card->dpram,
520 card->dpram_size,
521 card->pdat->boot.offs - card->pdat->boot.addr);
522 if (ret < 0)
523 goto failed;
524 /* load loader firmware */
525 ret = softing_load_fw(card->pdat->load.fw, card, card->dpram,
526 card->dpram_size,
527 card->pdat->load.offs - card->pdat->load.addr);
528 if (ret < 0)
529 goto failed;
530
531 if (card->pdat->reset)
532 card->pdat->reset(card->pdev, 0);
533 softing_clr_reset_dpram(card);
534 ret = softing_bootloader_command(card, 0, "card boot");
535 if (ret < 0)
536 goto failed;
537 ret = softing_load_app_fw(card->pdat->app.fw, card);
538 if (ret < 0)
539 goto failed;
540
541 ret = softing_chip_poweron(card);
542 if (ret < 0)
543 goto failed;
544
545 card->fw.up = 1;
546 mutex_unlock(&card->fw.lock);
547 return 0;
548failed:
549 card->fw.up = 0;
550 if (card->pdat->enable_irq)
551 card->pdat->enable_irq(card->pdev, 0);
552 softing_set_reset_dpram(card);
553 if (card->pdat->reset)
554 card->pdat->reset(card->pdev, 1);
555 mutex_unlock(&card->fw.lock);
556 return ret;
557}
558
559/*
560 * netdev sysfs
561 */
562static ssize_t show_channel(struct device *dev, struct device_attribute *attr,
563 char *buf)
564{
565 struct net_device *ndev = to_net_dev(dev);
566 struct softing_priv *priv = netdev2softing(ndev);
567
568 return sprintf(buf, "%i\n", priv->index);
569}
570
571static ssize_t show_chip(struct device *dev, struct device_attribute *attr,
572 char *buf)
573{
574 struct net_device *ndev = to_net_dev(dev);
575 struct softing_priv *priv = netdev2softing(ndev);
576
577 return sprintf(buf, "%i\n", priv->chip);
578}
579
580static ssize_t show_output(struct device *dev, struct device_attribute *attr,
581 char *buf)
582{
583 struct net_device *ndev = to_net_dev(dev);
584 struct softing_priv *priv = netdev2softing(ndev);
585
586 return sprintf(buf, "0x%02x\n", priv->output);
587}
588
589static ssize_t store_output(struct device *dev, struct device_attribute *attr,
590 const char *buf, size_t count)
591{
592 struct net_device *ndev = to_net_dev(dev);
593 struct softing_priv *priv = netdev2softing(ndev);
594 struct softing *card = priv->card;
595 unsigned long val;
596 int ret;
597
598 ret = strict_strtoul(buf, 0, &val);
599 if (ret < 0)
600 return ret;
601 val &= 0xFF;
602
603 ret = mutex_lock_interruptible(&card->fw.lock);
604 if (ret)
605 return -ERESTARTSYS;
606 if (netif_running(ndev)) {
607 mutex_unlock(&card->fw.lock);
608 return -EBUSY;
609 }
610 priv->output = val;
611 mutex_unlock(&card->fw.lock);
612 return count;
613}
614
615static const DEVICE_ATTR(channel, S_IRUGO, show_channel, NULL);
616static const DEVICE_ATTR(chip, S_IRUGO, show_chip, NULL);
617static const DEVICE_ATTR(output, S_IRUGO | S_IWUSR, show_output, store_output);
618
619static const struct attribute *const netdev_sysfs_attrs[] = {
620 &dev_attr_channel.attr,
621 &dev_attr_chip.attr,
622 &dev_attr_output.attr,
623 NULL,
624};
625static const struct attribute_group netdev_sysfs_group = {
626 .name = NULL,
627 .attrs = (struct attribute **)netdev_sysfs_attrs,
628};
629
630static const struct net_device_ops softing_netdev_ops = {
631 .ndo_open = softing_netdev_open,
632 .ndo_stop = softing_netdev_stop,
633 .ndo_start_xmit = softing_netdev_start_xmit,
634};
635
636static const struct can_bittiming_const softing_btr_const = {
Kurt Van Dijckdad3d442011-02-20 23:04:22 +0000637 .name = "softing",
Kurt Van Dijck03fd3cf2011-01-11 04:32:31 +0000638 .tseg1_min = 1,
639 .tseg1_max = 16,
640 .tseg2_min = 1,
641 .tseg2_max = 8,
642 .sjw_max = 4, /* overruled */
643 .brp_min = 1,
644 .brp_max = 32, /* overruled */
645 .brp_inc = 1,
646};
647
648
649static __devinit struct net_device *softing_netdev_create(struct softing *card,
650 uint16_t chip_id)
651{
652 struct net_device *netdev;
653 struct softing_priv *priv;
654
655 netdev = alloc_candev(sizeof(*priv), TX_ECHO_SKB_MAX);
656 if (!netdev) {
657 dev_alert(&card->pdev->dev, "alloc_candev failed\n");
658 return NULL;
659 }
660 priv = netdev_priv(netdev);
661 priv->netdev = netdev;
662 priv->card = card;
663 memcpy(&priv->btr_const, &softing_btr_const, sizeof(priv->btr_const));
664 priv->btr_const.brp_max = card->pdat->max_brp;
665 priv->btr_const.sjw_max = card->pdat->max_sjw;
666 priv->can.bittiming_const = &priv->btr_const;
667 priv->can.clock.freq = 8000000;
668 priv->chip = chip_id;
669 priv->output = softing_default_output(netdev);
670 SET_NETDEV_DEV(netdev, &card->pdev->dev);
671
672 netdev->flags |= IFF_ECHO;
673 netdev->netdev_ops = &softing_netdev_ops;
674 priv->can.do_set_mode = softing_candev_set_mode;
675 priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
676
677 return netdev;
678}
679
680static __devinit int softing_netdev_register(struct net_device *netdev)
681{
682 int ret;
683
684 netdev->sysfs_groups[0] = &netdev_sysfs_group;
685 ret = register_candev(netdev);
686 if (ret) {
687 dev_alert(&netdev->dev, "register failed\n");
688 return ret;
689 }
690 return 0;
691}
692
693static void softing_netdev_cleanup(struct net_device *netdev)
694{
695 unregister_candev(netdev);
696 free_candev(netdev);
697}
698
699/*
700 * sysfs for Platform device
701 */
702#define DEV_ATTR_RO(name, member) \
703static ssize_t show_##name(struct device *dev, \
704 struct device_attribute *attr, char *buf) \
705{ \
706 struct softing *card = platform_get_drvdata(to_platform_device(dev)); \
707 return sprintf(buf, "%u\n", card->member); \
708} \
709static DEVICE_ATTR(name, 0444, show_##name, NULL)
710
711#define DEV_ATTR_RO_STR(name, member) \
712static ssize_t show_##name(struct device *dev, \
713 struct device_attribute *attr, char *buf) \
714{ \
715 struct softing *card = platform_get_drvdata(to_platform_device(dev)); \
716 return sprintf(buf, "%s\n", card->member); \
717} \
718static DEVICE_ATTR(name, 0444, show_##name, NULL)
719
720DEV_ATTR_RO(serial, id.serial);
721DEV_ATTR_RO_STR(firmware, pdat->app.fw);
722DEV_ATTR_RO(firmware_version, id.fw_version);
723DEV_ATTR_RO_STR(hardware, pdat->name);
724DEV_ATTR_RO(hardware_version, id.hw_version);
725DEV_ATTR_RO(license, id.license);
726DEV_ATTR_RO(frequency, id.freq);
727DEV_ATTR_RO(txpending, tx.pending);
728
729static struct attribute *softing_pdev_attrs[] = {
730 &dev_attr_serial.attr,
731 &dev_attr_firmware.attr,
732 &dev_attr_firmware_version.attr,
733 &dev_attr_hardware.attr,
734 &dev_attr_hardware_version.attr,
735 &dev_attr_license.attr,
736 &dev_attr_frequency.attr,
737 &dev_attr_txpending.attr,
738 NULL,
739};
740
741static const struct attribute_group softing_pdev_group = {
742 .name = NULL,
743 .attrs = softing_pdev_attrs,
744};
745
746/*
747 * platform driver
748 */
749static __devexit int softing_pdev_remove(struct platform_device *pdev)
750{
751 struct softing *card = platform_get_drvdata(pdev);
752 int j;
753
754 /* first, disable card*/
755 softing_card_shutdown(card);
756
757 for (j = 0; j < ARRAY_SIZE(card->net); ++j) {
758 if (!card->net[j])
759 continue;
760 softing_netdev_cleanup(card->net[j]);
761 card->net[j] = NULL;
762 }
763 sysfs_remove_group(&pdev->dev.kobj, &softing_pdev_group);
764
765 iounmap(card->dpram);
766 kfree(card);
767 return 0;
768}
769
770static __devinit int softing_pdev_probe(struct platform_device *pdev)
771{
772 const struct softing_platform_data *pdat = pdev->dev.platform_data;
773 struct softing *card;
774 struct net_device *netdev;
775 struct softing_priv *priv;
776 struct resource *pres;
777 int ret;
778 int j;
779
780 if (!pdat) {
781 dev_warn(&pdev->dev, "no platform data\n");
782 return -EINVAL;
783 }
784 if (pdat->nbus > ARRAY_SIZE(card->net)) {
785 dev_warn(&pdev->dev, "%u nets??\n", pdat->nbus);
786 return -EINVAL;
787 }
788
789 card = kzalloc(sizeof(*card), GFP_KERNEL);
790 if (!card)
791 return -ENOMEM;
792 card->pdat = pdat;
793 card->pdev = pdev;
794 platform_set_drvdata(pdev, card);
795 mutex_init(&card->fw.lock);
796 spin_lock_init(&card->spin);
797
798 ret = -EINVAL;
799 pres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
800 if (!pres)
Justin P. Mattock6eab04a2011-04-08 19:49:08 -0700801 goto platform_resource_failed;
Kurt Van Dijck03fd3cf2011-01-11 04:32:31 +0000802 card->dpram_phys = pres->start;
803 card->dpram_size = pres->end - pres->start + 1;
804 card->dpram = ioremap_nocache(card->dpram_phys, card->dpram_size);
805 if (!card->dpram) {
806 dev_alert(&card->pdev->dev, "dpram ioremap failed\n");
807 goto ioremap_failed;
808 }
809
810 pres = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
811 if (pres)
812 card->irq.nr = pres->start;
813
814 /* reset card */
815 ret = softing_card_boot(card);
816 if (ret < 0) {
817 dev_alert(&pdev->dev, "failed to boot\n");
818 goto boot_failed;
819 }
820
821 /* only now, the chip's are known */
822 card->id.freq = card->pdat->freq;
823
824 ret = sysfs_create_group(&pdev->dev.kobj, &softing_pdev_group);
825 if (ret < 0) {
826 dev_alert(&card->pdev->dev, "sysfs failed\n");
827 goto sysfs_failed;
828 }
829
830 ret = -ENOMEM;
831 for (j = 0; j < ARRAY_SIZE(card->net); ++j) {
832 card->net[j] = netdev =
833 softing_netdev_create(card, card->id.chip[j]);
834 if (!netdev) {
835 dev_alert(&pdev->dev, "failed to make can[%i]", j);
836 goto netdev_failed;
837 }
838 priv = netdev_priv(card->net[j]);
839 priv->index = j;
840 ret = softing_netdev_register(netdev);
841 if (ret) {
842 free_candev(netdev);
843 card->net[j] = NULL;
844 dev_alert(&card->pdev->dev,
845 "failed to register can[%i]\n", j);
846 goto netdev_failed;
847 }
848 }
849 dev_info(&card->pdev->dev, "%s ready.\n", card->pdat->name);
850 return 0;
851
852netdev_failed:
853 for (j = 0; j < ARRAY_SIZE(card->net); ++j) {
854 if (!card->net[j])
855 continue;
856 softing_netdev_cleanup(card->net[j]);
857 }
858 sysfs_remove_group(&pdev->dev.kobj, &softing_pdev_group);
859sysfs_failed:
860 softing_card_shutdown(card);
861boot_failed:
862 iounmap(card->dpram);
863ioremap_failed:
864platform_resource_failed:
865 kfree(card);
866 return ret;
867}
868
869static struct platform_driver softing_driver = {
870 .driver = {
871 .name = "softing",
872 .owner = THIS_MODULE,
873 },
874 .probe = softing_pdev_probe,
875 .remove = __devexit_p(softing_pdev_remove),
876};
877
878MODULE_ALIAS("platform:softing");
879
880static int __init softing_start(void)
881{
882 return platform_driver_register(&softing_driver);
883}
884
885static void __exit softing_stop(void)
886{
887 platform_driver_unregister(&softing_driver);
888}
889
890module_init(softing_start);
891module_exit(softing_stop);
892
893MODULE_DESCRIPTION("Softing DPRAM CAN driver");
894MODULE_AUTHOR("Kurt Van Dijck <kurt.van.dijck@eia.be>");
895MODULE_LICENSE("GPL v2");