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