Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v3.10 750 lines 17 kB view raw
1/* 2 * SC268xx.c: Serial driver for Philiphs SC2681/SC2692 devices. 3 * 4 * Copyright (C) 2006,2007 Thomas Bogendörfer (tsbogend@alpha.franken.de) 5 */ 6 7#include <linux/module.h> 8#include <linux/kernel.h> 9#include <linux/errno.h> 10#include <linux/tty.h> 11#include <linux/tty_flip.h> 12#include <linux/major.h> 13#include <linux/circ_buf.h> 14#include <linux/serial.h> 15#include <linux/sysrq.h> 16#include <linux/console.h> 17#include <linux/spinlock.h> 18#include <linux/slab.h> 19#include <linux/delay.h> 20#include <linux/init.h> 21#include <linux/platform_device.h> 22#include <linux/irq.h> 23#include <linux/io.h> 24 25#warning "Please try migrate to use new driver SCCNXP and report the status" \ 26 "in the linux-serial mailing list." 27 28#if defined(CONFIG_MAGIC_SYSRQ) 29#define SUPPORT_SYSRQ 30#endif 31 32#include <linux/serial_core.h> 33 34#define SC26XX_MAJOR 204 35#define SC26XX_MINOR_START 205 36#define SC26XX_NR 2 37 38struct uart_sc26xx_port { 39 struct uart_port port[2]; 40 u8 dsr_mask[2]; 41 u8 cts_mask[2]; 42 u8 dcd_mask[2]; 43 u8 ri_mask[2]; 44 u8 dtr_mask[2]; 45 u8 rts_mask[2]; 46 u8 imr; 47}; 48 49/* register common to both ports */ 50#define RD_ISR 0x14 51#define RD_IPR 0x34 52 53#define WR_ACR 0x10 54#define WR_IMR 0x14 55#define WR_OPCR 0x34 56#define WR_OPR_SET 0x38 57#define WR_OPR_CLR 0x3C 58 59/* access common register */ 60#define READ_SC(p, r) readb((p)->membase + RD_##r) 61#define WRITE_SC(p, r, v) writeb((v), (p)->membase + WR_##r) 62 63/* register per port */ 64#define RD_PORT_MRx 0x00 65#define RD_PORT_SR 0x04 66#define RD_PORT_RHR 0x0c 67 68#define WR_PORT_MRx 0x00 69#define WR_PORT_CSR 0x04 70#define WR_PORT_CR 0x08 71#define WR_PORT_THR 0x0c 72 73/* SR bits */ 74#define SR_BREAK (1 << 7) 75#define SR_FRAME (1 << 6) 76#define SR_PARITY (1 << 5) 77#define SR_OVERRUN (1 << 4) 78#define SR_TXRDY (1 << 2) 79#define SR_RXRDY (1 << 0) 80 81#define CR_RES_MR (1 << 4) 82#define CR_RES_RX (2 << 4) 83#define CR_RES_TX (3 << 4) 84#define CR_STRT_BRK (6 << 4) 85#define CR_STOP_BRK (7 << 4) 86#define CR_DIS_TX (1 << 3) 87#define CR_ENA_TX (1 << 2) 88#define CR_DIS_RX (1 << 1) 89#define CR_ENA_RX (1 << 0) 90 91/* ISR bits */ 92#define ISR_RXRDYB (1 << 5) 93#define ISR_TXRDYB (1 << 4) 94#define ISR_RXRDYA (1 << 1) 95#define ISR_TXRDYA (1 << 0) 96 97/* IMR bits */ 98#define IMR_RXRDY (1 << 1) 99#define IMR_TXRDY (1 << 0) 100 101/* access port register */ 102static inline u8 read_sc_port(struct uart_port *p, u8 reg) 103{ 104 return readb(p->membase + p->line * 0x20 + reg); 105} 106 107static inline void write_sc_port(struct uart_port *p, u8 reg, u8 val) 108{ 109 writeb(val, p->membase + p->line * 0x20 + reg); 110} 111 112#define READ_SC_PORT(p, r) read_sc_port(p, RD_PORT_##r) 113#define WRITE_SC_PORT(p, r, v) write_sc_port(p, WR_PORT_##r, v) 114 115static void sc26xx_enable_irq(struct uart_port *port, int mask) 116{ 117 struct uart_sc26xx_port *up; 118 int line = port->line; 119 120 port -= line; 121 up = container_of(port, struct uart_sc26xx_port, port[0]); 122 123 up->imr |= mask << (line * 4); 124 WRITE_SC(port, IMR, up->imr); 125} 126 127static void sc26xx_disable_irq(struct uart_port *port, int mask) 128{ 129 struct uart_sc26xx_port *up; 130 int line = port->line; 131 132 port -= line; 133 up = container_of(port, struct uart_sc26xx_port, port[0]); 134 135 up->imr &= ~(mask << (line * 4)); 136 WRITE_SC(port, IMR, up->imr); 137} 138 139static bool receive_chars(struct uart_port *port) 140{ 141 struct tty_port *tport = NULL; 142 int limit = 10000; 143 unsigned char ch; 144 char flag; 145 u8 status; 146 147 /* FIXME what is this trying to achieve? */ 148 if (port->state != NULL) /* Unopened serial console */ 149 tport = &port->state->port; 150 151 while (limit-- > 0) { 152 status = READ_SC_PORT(port, SR); 153 if (!(status & SR_RXRDY)) 154 break; 155 ch = READ_SC_PORT(port, RHR); 156 157 flag = TTY_NORMAL; 158 port->icount.rx++; 159 160 if (unlikely(status & (SR_BREAK | SR_FRAME | 161 SR_PARITY | SR_OVERRUN))) { 162 if (status & SR_BREAK) { 163 status &= ~(SR_PARITY | SR_FRAME); 164 port->icount.brk++; 165 if (uart_handle_break(port)) 166 continue; 167 } else if (status & SR_PARITY) 168 port->icount.parity++; 169 else if (status & SR_FRAME) 170 port->icount.frame++; 171 if (status & SR_OVERRUN) 172 port->icount.overrun++; 173 174 status &= port->read_status_mask; 175 if (status & SR_BREAK) 176 flag = TTY_BREAK; 177 else if (status & SR_PARITY) 178 flag = TTY_PARITY; 179 else if (status & SR_FRAME) 180 flag = TTY_FRAME; 181 } 182 183 if (uart_handle_sysrq_char(port, ch)) 184 continue; 185 186 if (status & port->ignore_status_mask) 187 continue; 188 189 tty_insert_flip_char(tport, ch, flag); 190 } 191 return !!tport; 192} 193 194static void transmit_chars(struct uart_port *port) 195{ 196 struct circ_buf *xmit; 197 198 if (!port->state) 199 return; 200 201 xmit = &port->state->xmit; 202 if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { 203 sc26xx_disable_irq(port, IMR_TXRDY); 204 return; 205 } 206 while (!uart_circ_empty(xmit)) { 207 if (!(READ_SC_PORT(port, SR) & SR_TXRDY)) 208 break; 209 210 WRITE_SC_PORT(port, THR, xmit->buf[xmit->tail]); 211 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); 212 port->icount.tx++; 213 } 214 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) 215 uart_write_wakeup(port); 216} 217 218static irqreturn_t sc26xx_interrupt(int irq, void *dev_id) 219{ 220 struct uart_sc26xx_port *up = dev_id; 221 unsigned long flags; 222 bool push; 223 u8 isr; 224 225 spin_lock_irqsave(&up->port[0].lock, flags); 226 227 push = false; 228 isr = READ_SC(&up->port[0], ISR); 229 if (isr & ISR_TXRDYA) 230 transmit_chars(&up->port[0]); 231 if (isr & ISR_RXRDYA) 232 push = receive_chars(&up->port[0]); 233 234 spin_unlock(&up->port[0].lock); 235 236 if (push) 237 tty_flip_buffer_push(&up->port[0].state->port); 238 239 spin_lock(&up->port[1].lock); 240 241 push = false; 242 if (isr & ISR_TXRDYB) 243 transmit_chars(&up->port[1]); 244 if (isr & ISR_RXRDYB) 245 push = receive_chars(&up->port[1]); 246 247 spin_unlock_irqrestore(&up->port[1].lock, flags); 248 249 if (push) 250 tty_flip_buffer_push(&up->port[1].state->port); 251 252 return IRQ_HANDLED; 253} 254 255/* port->lock is not held. */ 256static unsigned int sc26xx_tx_empty(struct uart_port *port) 257{ 258 return (READ_SC_PORT(port, SR) & SR_TXRDY) ? TIOCSER_TEMT : 0; 259} 260 261/* port->lock held by caller. */ 262static void sc26xx_set_mctrl(struct uart_port *port, unsigned int mctrl) 263{ 264 struct uart_sc26xx_port *up; 265 int line = port->line; 266 267 port -= line; 268 up = container_of(port, struct uart_sc26xx_port, port[0]); 269 270 if (up->dtr_mask[line]) { 271 if (mctrl & TIOCM_DTR) 272 WRITE_SC(port, OPR_SET, up->dtr_mask[line]); 273 else 274 WRITE_SC(port, OPR_CLR, up->dtr_mask[line]); 275 } 276 if (up->rts_mask[line]) { 277 if (mctrl & TIOCM_RTS) 278 WRITE_SC(port, OPR_SET, up->rts_mask[line]); 279 else 280 WRITE_SC(port, OPR_CLR, up->rts_mask[line]); 281 } 282} 283 284/* port->lock is held by caller and interrupts are disabled. */ 285static unsigned int sc26xx_get_mctrl(struct uart_port *port) 286{ 287 struct uart_sc26xx_port *up; 288 int line = port->line; 289 unsigned int mctrl = TIOCM_DSR | TIOCM_CTS | TIOCM_CAR; 290 u8 ipr; 291 292 port -= line; 293 up = container_of(port, struct uart_sc26xx_port, port[0]); 294 ipr = READ_SC(port, IPR) ^ 0xff; 295 296 if (up->dsr_mask[line]) { 297 mctrl &= ~TIOCM_DSR; 298 mctrl |= ipr & up->dsr_mask[line] ? TIOCM_DSR : 0; 299 } 300 if (up->cts_mask[line]) { 301 mctrl &= ~TIOCM_CTS; 302 mctrl |= ipr & up->cts_mask[line] ? TIOCM_CTS : 0; 303 } 304 if (up->dcd_mask[line]) { 305 mctrl &= ~TIOCM_CAR; 306 mctrl |= ipr & up->dcd_mask[line] ? TIOCM_CAR : 0; 307 } 308 if (up->ri_mask[line]) { 309 mctrl &= ~TIOCM_RNG; 310 mctrl |= ipr & up->ri_mask[line] ? TIOCM_RNG : 0; 311 } 312 return mctrl; 313} 314 315/* port->lock held by caller. */ 316static void sc26xx_stop_tx(struct uart_port *port) 317{ 318 return; 319} 320 321/* port->lock held by caller. */ 322static void sc26xx_start_tx(struct uart_port *port) 323{ 324 struct circ_buf *xmit = &port->state->xmit; 325 326 while (!uart_circ_empty(xmit)) { 327 if (!(READ_SC_PORT(port, SR) & SR_TXRDY)) { 328 sc26xx_enable_irq(port, IMR_TXRDY); 329 break; 330 } 331 WRITE_SC_PORT(port, THR, xmit->buf[xmit->tail]); 332 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); 333 port->icount.tx++; 334 } 335} 336 337/* port->lock held by caller. */ 338static void sc26xx_stop_rx(struct uart_port *port) 339{ 340} 341 342/* port->lock held by caller. */ 343static void sc26xx_enable_ms(struct uart_port *port) 344{ 345} 346 347/* port->lock is not held. */ 348static void sc26xx_break_ctl(struct uart_port *port, int break_state) 349{ 350 if (break_state == -1) 351 WRITE_SC_PORT(port, CR, CR_STRT_BRK); 352 else 353 WRITE_SC_PORT(port, CR, CR_STOP_BRK); 354} 355 356/* port->lock is not held. */ 357static int sc26xx_startup(struct uart_port *port) 358{ 359 sc26xx_disable_irq(port, IMR_TXRDY | IMR_RXRDY); 360 WRITE_SC(port, OPCR, 0); 361 362 /* reset tx and rx */ 363 WRITE_SC_PORT(port, CR, CR_RES_RX); 364 WRITE_SC_PORT(port, CR, CR_RES_TX); 365 366 /* start rx/tx */ 367 WRITE_SC_PORT(port, CR, CR_ENA_TX | CR_ENA_RX); 368 369 /* enable irqs */ 370 sc26xx_enable_irq(port, IMR_RXRDY); 371 return 0; 372} 373 374/* port->lock is not held. */ 375static void sc26xx_shutdown(struct uart_port *port) 376{ 377 /* disable interrupst */ 378 sc26xx_disable_irq(port, IMR_TXRDY | IMR_RXRDY); 379 380 /* stop tx/rx */ 381 WRITE_SC_PORT(port, CR, CR_DIS_TX | CR_DIS_RX); 382} 383 384/* port->lock is not held. */ 385static void sc26xx_set_termios(struct uart_port *port, struct ktermios *termios, 386 struct ktermios *old) 387{ 388 unsigned int baud = uart_get_baud_rate(port, termios, old, 0, 4000000); 389 unsigned int quot = uart_get_divisor(port, baud); 390 unsigned int iflag, cflag; 391 unsigned long flags; 392 u8 mr1, mr2, csr; 393 394 spin_lock_irqsave(&port->lock, flags); 395 396 while ((READ_SC_PORT(port, SR) & ((1 << 3) | (1 << 2))) != 0xc) 397 udelay(2); 398 399 WRITE_SC_PORT(port, CR, CR_DIS_TX | CR_DIS_RX); 400 401 iflag = termios->c_iflag; 402 cflag = termios->c_cflag; 403 404 port->read_status_mask = SR_OVERRUN; 405 if (iflag & INPCK) 406 port->read_status_mask |= SR_PARITY | SR_FRAME; 407 if (iflag & (BRKINT | PARMRK)) 408 port->read_status_mask |= SR_BREAK; 409 410 port->ignore_status_mask = 0; 411 if (iflag & IGNBRK) 412 port->ignore_status_mask |= SR_BREAK; 413 if ((cflag & CREAD) == 0) 414 port->ignore_status_mask |= SR_BREAK | SR_FRAME | 415 SR_PARITY | SR_OVERRUN; 416 417 switch (cflag & CSIZE) { 418 case CS5: 419 mr1 = 0x00; 420 break; 421 case CS6: 422 mr1 = 0x01; 423 break; 424 case CS7: 425 mr1 = 0x02; 426 break; 427 default: 428 case CS8: 429 mr1 = 0x03; 430 break; 431 } 432 mr2 = 0x07; 433 if (cflag & CSTOPB) 434 mr2 = 0x0f; 435 if (cflag & PARENB) { 436 if (cflag & PARODD) 437 mr1 |= (1 << 2); 438 } else 439 mr1 |= (2 << 3); 440 441 switch (baud) { 442 case 50: 443 csr = 0x00; 444 break; 445 case 110: 446 csr = 0x11; 447 break; 448 case 134: 449 csr = 0x22; 450 break; 451 case 200: 452 csr = 0x33; 453 break; 454 case 300: 455 csr = 0x44; 456 break; 457 case 600: 458 csr = 0x55; 459 break; 460 case 1200: 461 csr = 0x66; 462 break; 463 case 2400: 464 csr = 0x88; 465 break; 466 case 4800: 467 csr = 0x99; 468 break; 469 default: 470 case 9600: 471 csr = 0xbb; 472 break; 473 case 19200: 474 csr = 0xcc; 475 break; 476 } 477 478 WRITE_SC_PORT(port, CR, CR_RES_MR); 479 WRITE_SC_PORT(port, MRx, mr1); 480 WRITE_SC_PORT(port, MRx, mr2); 481 482 WRITE_SC(port, ACR, 0x80); 483 WRITE_SC_PORT(port, CSR, csr); 484 485 /* reset tx and rx */ 486 WRITE_SC_PORT(port, CR, CR_RES_RX); 487 WRITE_SC_PORT(port, CR, CR_RES_TX); 488 489 WRITE_SC_PORT(port, CR, CR_ENA_TX | CR_ENA_RX); 490 while ((READ_SC_PORT(port, SR) & ((1 << 3) | (1 << 2))) != 0xc) 491 udelay(2); 492 493 /* XXX */ 494 uart_update_timeout(port, cflag, 495 (port->uartclk / (16 * quot))); 496 497 spin_unlock_irqrestore(&port->lock, flags); 498} 499 500static const char *sc26xx_type(struct uart_port *port) 501{ 502 return "SC26XX"; 503} 504 505static void sc26xx_release_port(struct uart_port *port) 506{ 507} 508 509static int sc26xx_request_port(struct uart_port *port) 510{ 511 return 0; 512} 513 514static void sc26xx_config_port(struct uart_port *port, int flags) 515{ 516} 517 518static int sc26xx_verify_port(struct uart_port *port, struct serial_struct *ser) 519{ 520 return -EINVAL; 521} 522 523static struct uart_ops sc26xx_ops = { 524 .tx_empty = sc26xx_tx_empty, 525 .set_mctrl = sc26xx_set_mctrl, 526 .get_mctrl = sc26xx_get_mctrl, 527 .stop_tx = sc26xx_stop_tx, 528 .start_tx = sc26xx_start_tx, 529 .stop_rx = sc26xx_stop_rx, 530 .enable_ms = sc26xx_enable_ms, 531 .break_ctl = sc26xx_break_ctl, 532 .startup = sc26xx_startup, 533 .shutdown = sc26xx_shutdown, 534 .set_termios = sc26xx_set_termios, 535 .type = sc26xx_type, 536 .release_port = sc26xx_release_port, 537 .request_port = sc26xx_request_port, 538 .config_port = sc26xx_config_port, 539 .verify_port = sc26xx_verify_port, 540}; 541 542static struct uart_port *sc26xx_port; 543 544#ifdef CONFIG_SERIAL_SC26XX_CONSOLE 545static void sc26xx_console_putchar(struct uart_port *port, char c) 546{ 547 unsigned long flags; 548 int limit = 1000000; 549 550 spin_lock_irqsave(&port->lock, flags); 551 552 while (limit-- > 0) { 553 if (READ_SC_PORT(port, SR) & SR_TXRDY) { 554 WRITE_SC_PORT(port, THR, c); 555 break; 556 } 557 udelay(2); 558 } 559 560 spin_unlock_irqrestore(&port->lock, flags); 561} 562 563static void sc26xx_console_write(struct console *con, const char *s, unsigned n) 564{ 565 struct uart_port *port = sc26xx_port; 566 int i; 567 568 for (i = 0; i < n; i++) { 569 if (*s == '\n') 570 sc26xx_console_putchar(port, '\r'); 571 sc26xx_console_putchar(port, *s++); 572 } 573} 574 575static int __init sc26xx_console_setup(struct console *con, char *options) 576{ 577 struct uart_port *port = sc26xx_port; 578 int baud = 9600; 579 int bits = 8; 580 int parity = 'n'; 581 int flow = 'n'; 582 583 if (port->type != PORT_SC26XX) 584 return -1; 585 586 printk(KERN_INFO "Console: ttySC%d (SC26XX)\n", con->index); 587 if (options) 588 uart_parse_options(options, &baud, &parity, &bits, &flow); 589 590 return uart_set_options(port, con, baud, parity, bits, flow); 591} 592 593static struct uart_driver sc26xx_reg; 594static struct console sc26xx_console = { 595 .name = "ttySC", 596 .write = sc26xx_console_write, 597 .device = uart_console_device, 598 .setup = sc26xx_console_setup, 599 .flags = CON_PRINTBUFFER, 600 .index = -1, 601 .data = &sc26xx_reg, 602}; 603#define SC26XX_CONSOLE &sc26xx_console 604#else 605#define SC26XX_CONSOLE NULL 606#endif 607 608static struct uart_driver sc26xx_reg = { 609 .owner = THIS_MODULE, 610 .driver_name = "SC26xx", 611 .dev_name = "ttySC", 612 .major = SC26XX_MAJOR, 613 .minor = SC26XX_MINOR_START, 614 .nr = SC26XX_NR, 615 .cons = SC26XX_CONSOLE, 616}; 617 618static u8 sc26xx_flags2mask(unsigned int flags, unsigned int bitpos) 619{ 620 unsigned int bit = (flags >> bitpos) & 15; 621 622 return bit ? (1 << (bit - 1)) : 0; 623} 624 625static void sc26xx_init_masks(struct uart_sc26xx_port *up, 626 int line, unsigned int data) 627{ 628 up->dtr_mask[line] = sc26xx_flags2mask(data, 0); 629 up->rts_mask[line] = sc26xx_flags2mask(data, 4); 630 up->dsr_mask[line] = sc26xx_flags2mask(data, 8); 631 up->cts_mask[line] = sc26xx_flags2mask(data, 12); 632 up->dcd_mask[line] = sc26xx_flags2mask(data, 16); 633 up->ri_mask[line] = sc26xx_flags2mask(data, 20); 634} 635 636static int sc26xx_probe(struct platform_device *dev) 637{ 638 struct resource *res; 639 struct uart_sc26xx_port *up; 640 unsigned int *sc26xx_data = dev->dev.platform_data; 641 int err; 642 643 res = platform_get_resource(dev, IORESOURCE_MEM, 0); 644 if (!res) 645 return -ENODEV; 646 647 up = kzalloc(sizeof *up, GFP_KERNEL); 648 if (unlikely(!up)) 649 return -ENOMEM; 650 651 up->port[0].line = 0; 652 up->port[0].ops = &sc26xx_ops; 653 up->port[0].type = PORT_SC26XX; 654 up->port[0].uartclk = (29491200 / 16); /* arbitrary */ 655 656 up->port[0].mapbase = res->start; 657 up->port[0].membase = ioremap_nocache(up->port[0].mapbase, 0x40); 658 up->port[0].iotype = UPIO_MEM; 659 up->port[0].irq = platform_get_irq(dev, 0); 660 661 up->port[0].dev = &dev->dev; 662 663 sc26xx_init_masks(up, 0, sc26xx_data[0]); 664 665 sc26xx_port = &up->port[0]; 666 667 up->port[1].line = 1; 668 up->port[1].ops = &sc26xx_ops; 669 up->port[1].type = PORT_SC26XX; 670 up->port[1].uartclk = (29491200 / 16); /* arbitrary */ 671 672 up->port[1].mapbase = up->port[0].mapbase; 673 up->port[1].membase = up->port[0].membase; 674 up->port[1].iotype = UPIO_MEM; 675 up->port[1].irq = up->port[0].irq; 676 677 up->port[1].dev = &dev->dev; 678 679 sc26xx_init_masks(up, 1, sc26xx_data[1]); 680 681 err = uart_register_driver(&sc26xx_reg); 682 if (err) 683 goto out_free_port; 684 685 sc26xx_reg.tty_driver->name_base = sc26xx_reg.minor; 686 687 err = uart_add_one_port(&sc26xx_reg, &up->port[0]); 688 if (err) 689 goto out_unregister_driver; 690 691 err = uart_add_one_port(&sc26xx_reg, &up->port[1]); 692 if (err) 693 goto out_remove_port0; 694 695 err = request_irq(up->port[0].irq, sc26xx_interrupt, 0, "sc26xx", up); 696 if (err) 697 goto out_remove_ports; 698 699 dev_set_drvdata(&dev->dev, up); 700 return 0; 701 702out_remove_ports: 703 uart_remove_one_port(&sc26xx_reg, &up->port[1]); 704out_remove_port0: 705 uart_remove_one_port(&sc26xx_reg, &up->port[0]); 706 707out_unregister_driver: 708 uart_unregister_driver(&sc26xx_reg); 709 710out_free_port: 711 kfree(up); 712 sc26xx_port = NULL; 713 return err; 714} 715 716 717static int __exit sc26xx_driver_remove(struct platform_device *dev) 718{ 719 struct uart_sc26xx_port *up = dev_get_drvdata(&dev->dev); 720 721 free_irq(up->port[0].irq, up); 722 723 uart_remove_one_port(&sc26xx_reg, &up->port[0]); 724 uart_remove_one_port(&sc26xx_reg, &up->port[1]); 725 726 uart_unregister_driver(&sc26xx_reg); 727 728 kfree(up); 729 sc26xx_port = NULL; 730 731 dev_set_drvdata(&dev->dev, NULL); 732 return 0; 733} 734 735static struct platform_driver sc26xx_driver = { 736 .probe = sc26xx_probe, 737 .remove = sc26xx_driver_remove, 738 .driver = { 739 .name = "SC26xx", 740 .owner = THIS_MODULE, 741 }, 742}; 743 744module_platform_driver(sc26xx_driver); 745 746MODULE_AUTHOR("Thomas Bogendörfer"); 747MODULE_DESCRIPTION("SC681/SC2692 serial driver"); 748MODULE_VERSION("1.0"); 749MODULE_LICENSE("GPL"); 750MODULE_ALIAS("platform:SC26xx");