linux/drivers/tty/serial/sc26xx.c
<<
>>
Prefs
   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");
 751