bfin_can.c revision 21afc27c9f9ae1f6370c47b323be7f3b75106569
1/* 2 * Blackfin On-Chip CAN Driver 3 * 4 * Copyright 2004-2009 Analog Devices Inc. 5 * 6 * Enter bugs at http://blackfin.uclinux.org/ 7 * 8 * Licensed under the GPL-2 or later. 9 */ 10 11#include <linux/module.h> 12#include <linux/init.h> 13#include <linux/kernel.h> 14#include <linux/bitops.h> 15#include <linux/interrupt.h> 16#include <linux/errno.h> 17#include <linux/netdevice.h> 18#include <linux/skbuff.h> 19#include <linux/platform_device.h> 20 21#include <linux/can.h> 22#include <linux/can/dev.h> 23#include <linux/can/error.h> 24 25#include <asm/bfin_can.h> 26#include <asm/portmux.h> 27 28#define DRV_NAME "bfin_can" 29#define BFIN_CAN_TIMEOUT 100 30#define TX_ECHO_SKB_MAX 1 31 32/* 33 * bfin can private data 34 */ 35struct bfin_can_priv { 36 struct can_priv can; /* must be the first member */ 37 struct net_device *dev; 38 void __iomem *membase; 39 int rx_irq; 40 int tx_irq; 41 int err_irq; 42 unsigned short *pin_list; 43}; 44 45/* 46 * bfin can timing parameters 47 */ 48static struct can_bittiming_const bfin_can_bittiming_const = { 49 .name = DRV_NAME, 50 .tseg1_min = 1, 51 .tseg1_max = 16, 52 .tseg2_min = 1, 53 .tseg2_max = 8, 54 .sjw_max = 4, 55 /* 56 * Although the BRP field can be set to any value, it is recommended 57 * that the value be greater than or equal to 4, as restrictions 58 * apply to the bit timing configuration when BRP is less than 4. 59 */ 60 .brp_min = 4, 61 .brp_max = 1024, 62 .brp_inc = 1, 63}; 64 65static int bfin_can_set_bittiming(struct net_device *dev) 66{ 67 struct bfin_can_priv *priv = netdev_priv(dev); 68 struct bfin_can_regs __iomem *reg = priv->membase; 69 struct can_bittiming *bt = &priv->can.bittiming; 70 u16 clk, timing; 71 72 clk = bt->brp - 1; 73 timing = ((bt->sjw - 1) << 8) | (bt->prop_seg + bt->phase_seg1 - 1) | 74 ((bt->phase_seg2 - 1) << 4); 75 76 /* 77 * If the SAM bit is set, the input signal is oversampled three times 78 * at the SCLK rate. 79 */ 80 if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) 81 timing |= SAM; 82 83 bfin_write16(®->clock, clk); 84 bfin_write16(®->timing, timing); 85 86 dev_info(dev->dev.parent, "setting CLOCK=0x%04x TIMING=0x%04x\n", 87 clk, timing); 88 89 return 0; 90} 91 92static void bfin_can_set_reset_mode(struct net_device *dev) 93{ 94 struct bfin_can_priv *priv = netdev_priv(dev); 95 struct bfin_can_regs __iomem *reg = priv->membase; 96 int timeout = BFIN_CAN_TIMEOUT; 97 int i; 98 99 /* disable interrupts */ 100 bfin_write16(®->mbim1, 0); 101 bfin_write16(®->mbim2, 0); 102 bfin_write16(®->gim, 0); 103 104 /* reset can and enter configuration mode */ 105 bfin_write16(®->control, SRS | CCR); 106 SSYNC(); 107 bfin_write16(®->control, CCR); 108 SSYNC(); 109 while (!(bfin_read16(®->control) & CCA)) { 110 udelay(10); 111 if (--timeout == 0) { 112 dev_err(dev->dev.parent, 113 "fail to enter configuration mode\n"); 114 BUG(); 115 } 116 } 117 118 /* 119 * All mailbox configurations are marked as inactive 120 * by writing to CAN Mailbox Configuration Registers 1 and 2 121 * For all bits: 0 - Mailbox disabled, 1 - Mailbox enabled 122 */ 123 bfin_write16(®->mc1, 0); 124 bfin_write16(®->mc2, 0); 125 126 /* Set Mailbox Direction */ 127 bfin_write16(®->md1, 0xFFFF); /* mailbox 1-16 are RX */ 128 bfin_write16(®->md2, 0); /* mailbox 17-32 are TX */ 129 130 /* RECEIVE_STD_CHL */ 131 for (i = 0; i < 2; i++) { 132 bfin_write16(®->chl[RECEIVE_STD_CHL + i].id0, 0); 133 bfin_write16(®->chl[RECEIVE_STD_CHL + i].id1, AME); 134 bfin_write16(®->chl[RECEIVE_STD_CHL + i].dlc, 0); 135 bfin_write16(®->msk[RECEIVE_STD_CHL + i].amh, 0x1FFF); 136 bfin_write16(®->msk[RECEIVE_STD_CHL + i].aml, 0xFFFF); 137 } 138 139 /* RECEIVE_EXT_CHL */ 140 for (i = 0; i < 2; i++) { 141 bfin_write16(®->chl[RECEIVE_EXT_CHL + i].id0, 0); 142 bfin_write16(®->chl[RECEIVE_EXT_CHL + i].id1, AME | IDE); 143 bfin_write16(®->chl[RECEIVE_EXT_CHL + i].dlc, 0); 144 bfin_write16(®->msk[RECEIVE_EXT_CHL + i].amh, 0x1FFF); 145 bfin_write16(®->msk[RECEIVE_EXT_CHL + i].aml, 0xFFFF); 146 } 147 148 bfin_write16(®->mc2, BIT(TRANSMIT_CHL - 16)); 149 bfin_write16(®->mc1, BIT(RECEIVE_STD_CHL) + BIT(RECEIVE_EXT_CHL)); 150 SSYNC(); 151 152 priv->can.state = CAN_STATE_STOPPED; 153} 154 155static void bfin_can_set_normal_mode(struct net_device *dev) 156{ 157 struct bfin_can_priv *priv = netdev_priv(dev); 158 struct bfin_can_regs __iomem *reg = priv->membase; 159 int timeout = BFIN_CAN_TIMEOUT; 160 161 /* 162 * leave configuration mode 163 */ 164 bfin_write16(®->control, bfin_read16(®->control) & ~CCR); 165 166 while (bfin_read16(®->status) & CCA) { 167 udelay(10); 168 if (--timeout == 0) { 169 dev_err(dev->dev.parent, 170 "fail to leave configuration mode\n"); 171 BUG(); 172 } 173 } 174 175 /* 176 * clear _All_ tx and rx interrupts 177 */ 178 bfin_write16(®->mbtif1, 0xFFFF); 179 bfin_write16(®->mbtif2, 0xFFFF); 180 bfin_write16(®->mbrif1, 0xFFFF); 181 bfin_write16(®->mbrif2, 0xFFFF); 182 183 /* 184 * clear global interrupt status register 185 */ 186 bfin_write16(®->gis, 0x7FF); /* overwrites with '1' */ 187 188 /* 189 * Initialize Interrupts 190 * - set bits in the mailbox interrupt mask register 191 * - global interrupt mask 192 */ 193 bfin_write16(®->mbim1, BIT(RECEIVE_STD_CHL) + BIT(RECEIVE_EXT_CHL)); 194 bfin_write16(®->mbim2, BIT(TRANSMIT_CHL - 16)); 195 196 bfin_write16(®->gim, EPIM | BOIM | RMLIM); 197 SSYNC(); 198} 199 200static void bfin_can_start(struct net_device *dev) 201{ 202 struct bfin_can_priv *priv = netdev_priv(dev); 203 204 /* enter reset mode */ 205 if (priv->can.state != CAN_STATE_STOPPED) 206 bfin_can_set_reset_mode(dev); 207 208 /* leave reset mode */ 209 bfin_can_set_normal_mode(dev); 210} 211 212static int bfin_can_set_mode(struct net_device *dev, enum can_mode mode) 213{ 214 switch (mode) { 215 case CAN_MODE_START: 216 bfin_can_start(dev); 217 if (netif_queue_stopped(dev)) 218 netif_wake_queue(dev); 219 break; 220 221 default: 222 return -EOPNOTSUPP; 223 } 224 225 return 0; 226} 227 228static int bfin_can_start_xmit(struct sk_buff *skb, struct net_device *dev) 229{ 230 struct bfin_can_priv *priv = netdev_priv(dev); 231 struct bfin_can_regs __iomem *reg = priv->membase; 232 struct can_frame *cf = (struct can_frame *)skb->data; 233 u8 dlc = cf->can_dlc; 234 canid_t id = cf->can_id; 235 u8 *data = cf->data; 236 u16 val; 237 int i; 238 239 if (can_dropped_invalid_skb(dev, skb)) 240 return NETDEV_TX_OK; 241 242 netif_stop_queue(dev); 243 244 /* fill id */ 245 if (id & CAN_EFF_FLAG) { 246 bfin_write16(®->chl[TRANSMIT_CHL].id0, id); 247 if (id & CAN_RTR_FLAG) 248 writew(((id & 0x1FFF0000) >> 16) | IDE | AME | RTR, 249 ®->chl[TRANSMIT_CHL].id1); 250 else 251 writew(((id & 0x1FFF0000) >> 16) | IDE | AME, 252 ®->chl[TRANSMIT_CHL].id1); 253 254 } else { 255 if (id & CAN_RTR_FLAG) 256 writew((id << 2) | AME | RTR, 257 ®->chl[TRANSMIT_CHL].id1); 258 else 259 bfin_write16(®->chl[TRANSMIT_CHL].id1, 260 (id << 2) | AME); 261 } 262 263 /* fill payload */ 264 for (i = 0; i < 8; i += 2) { 265 val = ((7 - i) < dlc ? (data[7 - i]) : 0) + 266 ((6 - i) < dlc ? (data[6 - i] << 8) : 0); 267 bfin_write16(®->chl[TRANSMIT_CHL].data[i], val); 268 } 269 270 /* fill data length code */ 271 bfin_write16(®->chl[TRANSMIT_CHL].dlc, dlc); 272 273 dev->trans_start = jiffies; 274 275 can_put_echo_skb(skb, dev, 0); 276 277 /* set transmit request */ 278 bfin_write16(®->trs2, BIT(TRANSMIT_CHL - 16)); 279 280 return 0; 281} 282 283static void bfin_can_rx(struct net_device *dev, u16 isrc) 284{ 285 struct bfin_can_priv *priv = netdev_priv(dev); 286 struct net_device_stats *stats = &dev->stats; 287 struct bfin_can_regs __iomem *reg = priv->membase; 288 struct can_frame *cf; 289 struct sk_buff *skb; 290 int obj; 291 int i; 292 u16 val; 293 294 skb = alloc_can_skb(dev, &cf); 295 if (skb == NULL) 296 return; 297 298 /* get id */ 299 if (isrc & BIT(RECEIVE_EXT_CHL)) { 300 /* extended frame format (EFF) */ 301 cf->can_id = ((bfin_read16(®->chl[RECEIVE_EXT_CHL].id1) 302 & 0x1FFF) << 16) 303 + bfin_read16(®->chl[RECEIVE_EXT_CHL].id0); 304 cf->can_id |= CAN_EFF_FLAG; 305 obj = RECEIVE_EXT_CHL; 306 } else { 307 /* standard frame format (SFF) */ 308 cf->can_id = (bfin_read16(®->chl[RECEIVE_STD_CHL].id1) 309 & 0x1ffc) >> 2; 310 obj = RECEIVE_STD_CHL; 311 } 312 if (bfin_read16(®->chl[obj].id1) & RTR) 313 cf->can_id |= CAN_RTR_FLAG; 314 315 /* get data length code */ 316 cf->can_dlc = get_can_dlc(bfin_read16(®->chl[obj].dlc) & 0xF); 317 318 /* get payload */ 319 for (i = 0; i < 8; i += 2) { 320 val = bfin_read16(®->chl[obj].data[i]); 321 cf->data[7 - i] = (7 - i) < cf->can_dlc ? val : 0; 322 cf->data[6 - i] = (6 - i) < cf->can_dlc ? (val >> 8) : 0; 323 } 324 325 netif_rx(skb); 326 327 stats->rx_packets++; 328 stats->rx_bytes += cf->can_dlc; 329} 330 331static int bfin_can_err(struct net_device *dev, u16 isrc, u16 status) 332{ 333 struct bfin_can_priv *priv = netdev_priv(dev); 334 struct bfin_can_regs __iomem *reg = priv->membase; 335 struct net_device_stats *stats = &dev->stats; 336 struct can_frame *cf; 337 struct sk_buff *skb; 338 enum can_state state = priv->can.state; 339 340 skb = alloc_can_err_skb(dev, &cf); 341 if (skb == NULL) 342 return -ENOMEM; 343 344 if (isrc & RMLIS) { 345 /* data overrun interrupt */ 346 dev_dbg(dev->dev.parent, "data overrun interrupt\n"); 347 cf->can_id |= CAN_ERR_CRTL; 348 cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; 349 stats->rx_over_errors++; 350 stats->rx_errors++; 351 } 352 353 if (isrc & BOIS) { 354 dev_dbg(dev->dev.parent, "bus-off mode interrupt\n"); 355 state = CAN_STATE_BUS_OFF; 356 cf->can_id |= CAN_ERR_BUSOFF; 357 can_bus_off(dev); 358 } 359 360 if (isrc & EPIS) { 361 /* error passive interrupt */ 362 dev_dbg(dev->dev.parent, "error passive interrupt\n"); 363 state = CAN_STATE_ERROR_PASSIVE; 364 } 365 366 if ((isrc & EWTIS) || (isrc & EWRIS)) { 367 dev_dbg(dev->dev.parent, 368 "Error Warning Transmit/Receive Interrupt\n"); 369 state = CAN_STATE_ERROR_WARNING; 370 } 371 372 if (state != priv->can.state && (state == CAN_STATE_ERROR_WARNING || 373 state == CAN_STATE_ERROR_PASSIVE)) { 374 u16 cec = bfin_read16(®->cec); 375 u8 rxerr = cec; 376 u8 txerr = cec >> 8; 377 378 cf->can_id |= CAN_ERR_CRTL; 379 if (state == CAN_STATE_ERROR_WARNING) { 380 priv->can.can_stats.error_warning++; 381 cf->data[1] = (txerr > rxerr) ? 382 CAN_ERR_CRTL_TX_WARNING : 383 CAN_ERR_CRTL_RX_WARNING; 384 } else { 385 priv->can.can_stats.error_passive++; 386 cf->data[1] = (txerr > rxerr) ? 387 CAN_ERR_CRTL_TX_PASSIVE : 388 CAN_ERR_CRTL_RX_PASSIVE; 389 } 390 } 391 392 if (status) { 393 priv->can.can_stats.bus_error++; 394 395 cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; 396 397 if (status & BEF) 398 cf->data[2] |= CAN_ERR_PROT_BIT; 399 else if (status & FER) 400 cf->data[2] |= CAN_ERR_PROT_FORM; 401 else if (status & SER) 402 cf->data[2] |= CAN_ERR_PROT_STUFF; 403 else 404 cf->data[2] |= CAN_ERR_PROT_UNSPEC; 405 } 406 407 priv->can.state = state; 408 409 netif_rx(skb); 410 411 stats->rx_packets++; 412 stats->rx_bytes += cf->can_dlc; 413 414 return 0; 415} 416 417irqreturn_t bfin_can_interrupt(int irq, void *dev_id) 418{ 419 struct net_device *dev = dev_id; 420 struct bfin_can_priv *priv = netdev_priv(dev); 421 struct bfin_can_regs __iomem *reg = priv->membase; 422 struct net_device_stats *stats = &dev->stats; 423 u16 status, isrc; 424 425 if ((irq == priv->tx_irq) && bfin_read16(®->mbtif2)) { 426 /* transmission complete interrupt */ 427 bfin_write16(®->mbtif2, 0xFFFF); 428 stats->tx_packets++; 429 stats->tx_bytes += bfin_read16(®->chl[TRANSMIT_CHL].dlc); 430 can_get_echo_skb(dev, 0); 431 netif_wake_queue(dev); 432 } else if ((irq == priv->rx_irq) && bfin_read16(®->mbrif1)) { 433 /* receive interrupt */ 434 isrc = bfin_read16(®->mbrif1); 435 bfin_write16(®->mbrif1, 0xFFFF); 436 bfin_can_rx(dev, isrc); 437 } else if ((irq == priv->err_irq) && bfin_read16(®->gis)) { 438 /* error interrupt */ 439 isrc = bfin_read16(®->gis); 440 status = bfin_read16(®->esr); 441 bfin_write16(®->gis, 0x7FF); 442 bfin_can_err(dev, isrc, status); 443 } else { 444 return IRQ_NONE; 445 } 446 447 return IRQ_HANDLED; 448} 449 450static int bfin_can_open(struct net_device *dev) 451{ 452 struct bfin_can_priv *priv = netdev_priv(dev); 453 int err; 454 455 /* set chip into reset mode */ 456 bfin_can_set_reset_mode(dev); 457 458 /* common open */ 459 err = open_candev(dev); 460 if (err) 461 goto exit_open; 462 463 /* register interrupt handler */ 464 err = request_irq(priv->rx_irq, &bfin_can_interrupt, 0, 465 "bfin-can-rx", dev); 466 if (err) 467 goto exit_rx_irq; 468 err = request_irq(priv->tx_irq, &bfin_can_interrupt, 0, 469 "bfin-can-tx", dev); 470 if (err) 471 goto exit_tx_irq; 472 err = request_irq(priv->err_irq, &bfin_can_interrupt, 0, 473 "bfin-can-err", dev); 474 if (err) 475 goto exit_err_irq; 476 477 bfin_can_start(dev); 478 479 netif_start_queue(dev); 480 481 return 0; 482 483exit_err_irq: 484 free_irq(priv->tx_irq, dev); 485exit_tx_irq: 486 free_irq(priv->rx_irq, dev); 487exit_rx_irq: 488 close_candev(dev); 489exit_open: 490 return err; 491} 492 493static int bfin_can_close(struct net_device *dev) 494{ 495 struct bfin_can_priv *priv = netdev_priv(dev); 496 497 netif_stop_queue(dev); 498 bfin_can_set_reset_mode(dev); 499 500 close_candev(dev); 501 502 free_irq(priv->rx_irq, dev); 503 free_irq(priv->tx_irq, dev); 504 free_irq(priv->err_irq, dev); 505 506 return 0; 507} 508 509struct net_device *alloc_bfin_candev(void) 510{ 511 struct net_device *dev; 512 struct bfin_can_priv *priv; 513 514 dev = alloc_candev(sizeof(*priv), TX_ECHO_SKB_MAX); 515 if (!dev) 516 return NULL; 517 518 priv = netdev_priv(dev); 519 520 priv->dev = dev; 521 priv->can.bittiming_const = &bfin_can_bittiming_const; 522 priv->can.do_set_bittiming = bfin_can_set_bittiming; 523 priv->can.do_set_mode = bfin_can_set_mode; 524 priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; 525 526 return dev; 527} 528 529static const struct net_device_ops bfin_can_netdev_ops = { 530 .ndo_open = bfin_can_open, 531 .ndo_stop = bfin_can_close, 532 .ndo_start_xmit = bfin_can_start_xmit, 533}; 534 535static int __devinit bfin_can_probe(struct platform_device *pdev) 536{ 537 int err; 538 struct net_device *dev; 539 struct bfin_can_priv *priv; 540 struct resource *res_mem, *rx_irq, *tx_irq, *err_irq; 541 unsigned short *pdata; 542 543 pdata = pdev->dev.platform_data; 544 if (!pdata) { 545 dev_err(&pdev->dev, "No platform data provided!\n"); 546 err = -EINVAL; 547 goto exit; 548 } 549 550 res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 551 rx_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 552 tx_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 1); 553 err_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 2); 554 if (!res_mem || !rx_irq || !tx_irq || !err_irq) { 555 err = -EINVAL; 556 goto exit; 557 } 558 559 if (!request_mem_region(res_mem->start, resource_size(res_mem), 560 dev_name(&pdev->dev))) { 561 err = -EBUSY; 562 goto exit; 563 } 564 565 /* request peripheral pins */ 566 err = peripheral_request_list(pdata, dev_name(&pdev->dev)); 567 if (err) 568 goto exit_mem_release; 569 570 dev = alloc_bfin_candev(); 571 if (!dev) { 572 err = -ENOMEM; 573 goto exit_peri_pin_free; 574 } 575 576 priv = netdev_priv(dev); 577 priv->membase = (void __iomem *)res_mem->start; 578 priv->rx_irq = rx_irq->start; 579 priv->tx_irq = tx_irq->start; 580 priv->err_irq = err_irq->start; 581 priv->pin_list = pdata; 582 priv->can.clock.freq = get_sclk(); 583 584 dev_set_drvdata(&pdev->dev, dev); 585 SET_NETDEV_DEV(dev, &pdev->dev); 586 587 dev->flags |= IFF_ECHO; /* we support local echo */ 588 dev->netdev_ops = &bfin_can_netdev_ops; 589 590 bfin_can_set_reset_mode(dev); 591 592 err = register_candev(dev); 593 if (err) { 594 dev_err(&pdev->dev, "registering failed (err=%d)\n", err); 595 goto exit_candev_free; 596 } 597 598 dev_info(&pdev->dev, 599 "%s device registered" 600 "(®_base=%p, rx_irq=%d, tx_irq=%d, err_irq=%d, sclk=%d)\n", 601 DRV_NAME, (void *)priv->membase, priv->rx_irq, 602 priv->tx_irq, priv->err_irq, priv->can.clock.freq); 603 return 0; 604 605exit_candev_free: 606 free_candev(dev); 607exit_peri_pin_free: 608 peripheral_free_list(pdata); 609exit_mem_release: 610 release_mem_region(res_mem->start, resource_size(res_mem)); 611exit: 612 return err; 613} 614 615static int __devexit bfin_can_remove(struct platform_device *pdev) 616{ 617 struct net_device *dev = dev_get_drvdata(&pdev->dev); 618 struct bfin_can_priv *priv = netdev_priv(dev); 619 struct resource *res; 620 621 bfin_can_set_reset_mode(dev); 622 623 unregister_candev(dev); 624 625 dev_set_drvdata(&pdev->dev, NULL); 626 627 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 628 release_mem_region(res->start, resource_size(res)); 629 630 peripheral_free_list(priv->pin_list); 631 632 free_candev(dev); 633 return 0; 634} 635 636#ifdef CONFIG_PM 637static int bfin_can_suspend(struct platform_device *pdev, pm_message_t mesg) 638{ 639 struct net_device *dev = dev_get_drvdata(&pdev->dev); 640 struct bfin_can_priv *priv = netdev_priv(dev); 641 struct bfin_can_regs __iomem *reg = priv->membase; 642 int timeout = BFIN_CAN_TIMEOUT; 643 644 if (netif_running(dev)) { 645 /* enter sleep mode */ 646 bfin_write16(®->control, bfin_read16(®->control) | SMR); 647 SSYNC(); 648 while (!(bfin_read16(®->intr) & SMACK)) { 649 udelay(10); 650 if (--timeout == 0) { 651 dev_err(dev->dev.parent, 652 "fail to enter sleep mode\n"); 653 BUG(); 654 } 655 } 656 } 657 658 return 0; 659} 660 661static int bfin_can_resume(struct platform_device *pdev) 662{ 663 struct net_device *dev = dev_get_drvdata(&pdev->dev); 664 struct bfin_can_priv *priv = netdev_priv(dev); 665 struct bfin_can_regs __iomem *reg = priv->membase; 666 667 if (netif_running(dev)) { 668 /* leave sleep mode */ 669 bfin_write16(®->intr, 0); 670 SSYNC(); 671 } 672 673 return 0; 674} 675#else 676#define bfin_can_suspend NULL 677#define bfin_can_resume NULL 678#endif /* CONFIG_PM */ 679 680static struct platform_driver bfin_can_driver = { 681 .probe = bfin_can_probe, 682 .remove = __devexit_p(bfin_can_remove), 683 .suspend = bfin_can_suspend, 684 .resume = bfin_can_resume, 685 .driver = { 686 .name = DRV_NAME, 687 .owner = THIS_MODULE, 688 }, 689}; 690 691static int __init bfin_can_init(void) 692{ 693 return platform_driver_register(&bfin_can_driver); 694} 695module_init(bfin_can_init); 696 697static void __exit bfin_can_exit(void) 698{ 699 platform_driver_unregister(&bfin_can_driver); 700} 701module_exit(bfin_can_exit); 702 703MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); 704MODULE_LICENSE("GPL"); 705MODULE_DESCRIPTION("Blackfin on-chip CAN netdevice driver"); 706