linux/drivers/serial/netx-serial.c
<<
>>
Prefs
   1/*
   2 * drivers/serial/netx-serial.c
   3 *
   4 * Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2
   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#if defined(CONFIG_SERIAL_NETX_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
  21#define SUPPORT_SYSRQ
  22#endif
  23
  24#include <linux/device.h>
  25#include <linux/module.h>
  26#include <linux/ioport.h>
  27#include <linux/init.h>
  28#include <linux/console.h>
  29#include <linux/sysrq.h>
  30#include <linux/platform_device.h>
  31#include <linux/tty.h>
  32#include <linux/tty_flip.h>
  33#include <linux/serial_core.h>
  34#include <linux/serial.h>
  35
  36#include <asm/io.h>
  37#include <asm/irq.h>
  38#include <mach/hardware.h>
  39#include <mach/netx-regs.h>
  40
  41/* We've been assigned a range on the "Low-density serial ports" major */
  42#define SERIAL_NX_MAJOR 204
  43#define MINOR_START     170
  44
  45enum uart_regs {
  46        UART_DR              = 0x00,
  47        UART_SR              = 0x04,
  48        UART_LINE_CR         = 0x08,
  49        UART_BAUDDIV_MSB     = 0x0c,
  50        UART_BAUDDIV_LSB     = 0x10,
  51        UART_CR              = 0x14,
  52        UART_FR              = 0x18,
  53        UART_IIR             = 0x1c,
  54        UART_ILPR            = 0x20,
  55        UART_RTS_CR          = 0x24,
  56        UART_RTS_LEAD        = 0x28,
  57        UART_RTS_TRAIL       = 0x2c,
  58        UART_DRV_ENABLE      = 0x30,
  59        UART_BRM_CR          = 0x34,
  60        UART_RXFIFO_IRQLEVEL = 0x38,
  61        UART_TXFIFO_IRQLEVEL = 0x3c,
  62};
  63
  64#define SR_FE (1<<0)
  65#define SR_PE (1<<1)
  66#define SR_BE (1<<2)
  67#define SR_OE (1<<3)
  68
  69#define LINE_CR_BRK       (1<<0)
  70#define LINE_CR_PEN       (1<<1)
  71#define LINE_CR_EPS       (1<<2)
  72#define LINE_CR_STP2      (1<<3)
  73#define LINE_CR_FEN       (1<<4)
  74#define LINE_CR_5BIT      (0<<5)
  75#define LINE_CR_6BIT      (1<<5)
  76#define LINE_CR_7BIT      (2<<5)
  77#define LINE_CR_8BIT      (3<<5)
  78#define LINE_CR_BITS_MASK (3<<5)
  79
  80#define CR_UART_EN (1<<0)
  81#define CR_SIREN   (1<<1)
  82#define CR_SIRLP   (1<<2)
  83#define CR_MSIE    (1<<3)
  84#define CR_RIE     (1<<4)
  85#define CR_TIE     (1<<5)
  86#define CR_RTIE    (1<<6)
  87#define CR_LBE     (1<<7)
  88
  89#define FR_CTS  (1<<0)
  90#define FR_DSR  (1<<1)
  91#define FR_DCD  (1<<2)
  92#define FR_BUSY (1<<3)
  93#define FR_RXFE (1<<4)
  94#define FR_TXFF (1<<5)
  95#define FR_RXFF (1<<6)
  96#define FR_TXFE (1<<7)
  97
  98#define IIR_MIS (1<<0)
  99#define IIR_RIS (1<<1)
 100#define IIR_TIS (1<<2)
 101#define IIR_RTIS (1<<3)
 102#define IIR_MASK 0xf
 103
 104#define RTS_CR_AUTO (1<<0)
 105#define RTS_CR_RTS  (1<<1)
 106#define RTS_CR_COUNT (1<<2)
 107#define RTS_CR_MOD2  (1<<3)
 108#define RTS_CR_RTS_POL (1<<4)
 109#define RTS_CR_CTS_CTR (1<<5)
 110#define RTS_CR_CTS_POL (1<<6)
 111#define RTS_CR_STICK   (1<<7)
 112
 113#define UART_PORT_SIZE 0x40
 114#define DRIVER_NAME "netx-uart"
 115
 116struct netx_port {
 117        struct uart_port        port;
 118};
 119
 120static void netx_stop_tx(struct uart_port *port)
 121{
 122        unsigned int val;
 123        val = readl(port->membase + UART_CR);
 124        writel(val & ~CR_TIE,  port->membase + UART_CR);
 125}
 126
 127static void netx_stop_rx(struct uart_port *port)
 128{
 129        unsigned int val;
 130        val = readl(port->membase + UART_CR);
 131        writel(val & ~CR_RIE,  port->membase + UART_CR);
 132}
 133
 134static void netx_enable_ms(struct uart_port *port)
 135{
 136        unsigned int val;
 137        val = readl(port->membase + UART_CR);
 138        writel(val | CR_MSIE, port->membase + UART_CR);
 139}
 140
 141static inline void netx_transmit_buffer(struct uart_port *port)
 142{
 143        struct circ_buf *xmit = &port->state->xmit;
 144
 145        if (port->x_char) {
 146                writel(port->x_char, port->membase + UART_DR);
 147                port->icount.tx++;
 148                port->x_char = 0;
 149                return;
 150        }
 151
 152        if (uart_tx_stopped(port) || uart_circ_empty(xmit)) {
 153                netx_stop_tx(port);
 154                return;
 155        }
 156
 157        do {
 158                /* send xmit->buf[xmit->tail]
 159                 * out the port here */
 160                writel(xmit->buf[xmit->tail], port->membase + UART_DR);
 161                xmit->tail = (xmit->tail + 1) &
 162                         (UART_XMIT_SIZE - 1);
 163                port->icount.tx++;
 164                if (uart_circ_empty(xmit))
 165                        break;
 166        } while (!(readl(port->membase + UART_FR) & FR_TXFF));
 167
 168        if (uart_circ_empty(xmit))
 169                netx_stop_tx(port);
 170}
 171
 172static void netx_start_tx(struct uart_port *port)
 173{
 174        writel(
 175            readl(port->membase + UART_CR) | CR_TIE, port->membase + UART_CR);
 176
 177        if (!(readl(port->membase + UART_FR) & FR_TXFF))
 178                netx_transmit_buffer(port);
 179}
 180
 181static unsigned int netx_tx_empty(struct uart_port *port)
 182{
 183        return readl(port->membase + UART_FR) & FR_BUSY ? 0 : TIOCSER_TEMT;
 184}
 185
 186static void netx_txint(struct uart_port *port)
 187{
 188        struct circ_buf *xmit = &port->state->xmit;
 189
 190        if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
 191                netx_stop_tx(port);
 192                return;
 193        }
 194
 195        netx_transmit_buffer(port);
 196
 197        if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
 198                uart_write_wakeup(port);
 199}
 200
 201static void netx_rxint(struct uart_port *port)
 202{
 203        unsigned char rx, flg, status;
 204        struct tty_struct *tty = port->state->port.tty;
 205
 206        while (!(readl(port->membase + UART_FR) & FR_RXFE)) {
 207                rx = readl(port->membase + UART_DR);
 208                flg = TTY_NORMAL;
 209                port->icount.rx++;
 210                status = readl(port->membase + UART_SR);
 211                if (status & SR_BE) {
 212                        writel(0, port->membase + UART_SR);
 213                        if (uart_handle_break(port))
 214                                continue;
 215                }
 216
 217                if (unlikely(status & (SR_FE | SR_PE | SR_OE))) {
 218
 219                        if (status & SR_PE)
 220                                port->icount.parity++;
 221                        else if (status & SR_FE)
 222                                port->icount.frame++;
 223                        if (status & SR_OE)
 224                                port->icount.overrun++;
 225
 226                        status &= port->read_status_mask;
 227
 228                        if (status & SR_BE)
 229                                flg = TTY_BREAK;
 230                        else if (status & SR_PE)
 231                                flg = TTY_PARITY;
 232                        else if (status & SR_FE)
 233                                flg = TTY_FRAME;
 234                }
 235
 236                if (uart_handle_sysrq_char(port, rx))
 237                        continue;
 238
 239                uart_insert_char(port, status, SR_OE, rx, flg);
 240        }
 241
 242        tty_flip_buffer_push(tty);
 243        return;
 244}
 245
 246static irqreturn_t netx_int(int irq, void *dev_id)
 247{
 248        struct uart_port *port = dev_id;
 249        unsigned long flags;
 250        unsigned char status;
 251
 252        spin_lock_irqsave(&port->lock,flags);
 253
 254        status = readl(port->membase + UART_IIR) & IIR_MASK;
 255        while (status) {
 256                if (status & IIR_RIS)
 257                        netx_rxint(port);
 258                if (status & IIR_TIS)
 259                        netx_txint(port);
 260                if (status & IIR_MIS) {
 261                        if (readl(port->membase + UART_FR) & FR_CTS)
 262                                uart_handle_cts_change(port, 1);
 263                        else
 264                                uart_handle_cts_change(port, 0);
 265                }
 266                writel(0, port->membase + UART_IIR);
 267                status = readl(port->membase + UART_IIR) & IIR_MASK;
 268        }
 269
 270        spin_unlock_irqrestore(&port->lock,flags);
 271        return IRQ_HANDLED;
 272}
 273
 274static unsigned int netx_get_mctrl(struct uart_port *port)
 275{
 276        unsigned int ret = TIOCM_DSR | TIOCM_CAR;
 277
 278        if (readl(port->membase + UART_FR) & FR_CTS)
 279                ret |= TIOCM_CTS;
 280
 281        return ret;
 282}
 283
 284static void netx_set_mctrl(struct uart_port *port, unsigned int mctrl)
 285{
 286        unsigned int val;
 287
 288        /* FIXME: Locking needed ? */
 289        if (mctrl & TIOCM_RTS) {
 290                val = readl(port->membase + UART_RTS_CR);
 291                writel(val | RTS_CR_RTS, port->membase + UART_RTS_CR);
 292        }
 293}
 294
 295static void netx_break_ctl(struct uart_port *port, int break_state)
 296{
 297        unsigned int line_cr;
 298        spin_lock_irq(&port->lock);
 299
 300        line_cr = readl(port->membase + UART_LINE_CR);
 301        if (break_state != 0)
 302                line_cr |= LINE_CR_BRK;
 303        else
 304                line_cr &= ~LINE_CR_BRK;
 305        writel(line_cr, port->membase + UART_LINE_CR);
 306
 307        spin_unlock_irq(&port->lock);
 308}
 309
 310static int netx_startup(struct uart_port *port)
 311{
 312        int ret;
 313
 314        ret = request_irq(port->irq, netx_int, 0,
 315                             DRIVER_NAME, port);
 316        if (ret) {
 317                dev_err(port->dev, "unable to grab irq%d\n",port->irq);
 318                goto exit;
 319        }
 320
 321        writel(readl(port->membase + UART_LINE_CR) | LINE_CR_FEN,
 322                port->membase + UART_LINE_CR);
 323
 324        writel(CR_MSIE | CR_RIE | CR_TIE | CR_RTIE | CR_UART_EN,
 325                port->membase + UART_CR);
 326
 327exit:
 328        return ret;
 329}
 330
 331static void netx_shutdown(struct uart_port *port)
 332{
 333        writel(0, port->membase + UART_CR) ;
 334
 335        free_irq(port->irq, port);
 336}
 337
 338static void
 339netx_set_termios(struct uart_port *port, struct ktermios *termios,
 340                   struct ktermios *old)
 341{
 342        unsigned int baud, quot;
 343        unsigned char old_cr;
 344        unsigned char line_cr = LINE_CR_FEN;
 345        unsigned char rts_cr = 0;
 346
 347        switch (termios->c_cflag & CSIZE) {
 348        case CS5:
 349                line_cr |= LINE_CR_5BIT;
 350                break;
 351        case CS6:
 352                line_cr |= LINE_CR_6BIT;
 353                break;
 354        case CS7:
 355                line_cr |= LINE_CR_7BIT;
 356                break;
 357        case CS8:
 358                line_cr |= LINE_CR_8BIT;
 359                break;
 360        }
 361
 362        if (termios->c_cflag & CSTOPB)
 363                line_cr |= LINE_CR_STP2;
 364
 365        if (termios->c_cflag & PARENB) {
 366                line_cr |= LINE_CR_PEN;
 367                if (!(termios->c_cflag & PARODD))
 368                        line_cr |= LINE_CR_EPS;
 369        }
 370
 371        if (termios->c_cflag & CRTSCTS)
 372                rts_cr = RTS_CR_AUTO | RTS_CR_CTS_CTR | RTS_CR_RTS_POL;
 373
 374        baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
 375        quot = baud * 4096;
 376        quot /= 1000;
 377        quot *= 256;
 378        quot /= 100000;
 379
 380        spin_lock_irq(&port->lock);
 381
 382        uart_update_timeout(port, termios->c_cflag, baud);
 383
 384        old_cr = readl(port->membase + UART_CR);
 385
 386        /* disable interrupts */
 387        writel(old_cr & ~(CR_MSIE | CR_RIE | CR_TIE | CR_RTIE),
 388                port->membase + UART_CR);
 389
 390        /* drain transmitter */
 391        while (readl(port->membase + UART_FR) & FR_BUSY);
 392
 393        /* disable UART */
 394        writel(old_cr & ~CR_UART_EN, port->membase + UART_CR);
 395
 396        /* modem status interrupts */
 397        old_cr &= ~CR_MSIE;
 398        if (UART_ENABLE_MS(port, termios->c_cflag))
 399                old_cr |= CR_MSIE;
 400
 401        writel((quot>>8) & 0xff, port->membase + UART_BAUDDIV_MSB);
 402        writel(quot & 0xff, port->membase + UART_BAUDDIV_LSB);
 403        writel(line_cr, port->membase + UART_LINE_CR);
 404
 405        writel(rts_cr, port->membase + UART_RTS_CR);
 406
 407        /*
 408         * Characters to ignore
 409         */
 410        port->ignore_status_mask = 0;
 411        if (termios->c_iflag & IGNPAR)
 412                port->ignore_status_mask |= SR_PE;
 413        if (termios->c_iflag & IGNBRK) {
 414                port->ignore_status_mask |= SR_BE;
 415                /*
 416                 * If we're ignoring parity and break indicators,
 417                 * ignore overruns too (for real raw support).
 418                 */
 419                if (termios->c_iflag & IGNPAR)
 420                        port->ignore_status_mask |= SR_PE;
 421        }
 422
 423        port->read_status_mask = 0;
 424        if (termios->c_iflag & (BRKINT | PARMRK))
 425                port->read_status_mask |= SR_BE;
 426        if (termios->c_iflag & INPCK)
 427                port->read_status_mask |= SR_PE | SR_FE;
 428
 429        writel(old_cr, port->membase + UART_CR);
 430
 431        spin_unlock_irq(&port->lock);
 432}
 433
 434static const char *netx_type(struct uart_port *port)
 435{
 436        return port->type == PORT_NETX ? "NETX" : NULL;
 437}
 438
 439static void netx_release_port(struct uart_port *port)
 440{
 441        release_mem_region(port->mapbase, UART_PORT_SIZE);
 442}
 443
 444static int netx_request_port(struct uart_port *port)
 445{
 446        return request_mem_region(port->mapbase, UART_PORT_SIZE,
 447                        DRIVER_NAME) != NULL ? 0 : -EBUSY;
 448}
 449
 450static void netx_config_port(struct uart_port *port, int flags)
 451{
 452        if (flags & UART_CONFIG_TYPE && netx_request_port(port) == 0)
 453                port->type = PORT_NETX;
 454}
 455
 456static int
 457netx_verify_port(struct uart_port *port, struct serial_struct *ser)
 458{
 459        int ret = 0;
 460
 461        if (ser->type != PORT_UNKNOWN && ser->type != PORT_NETX)
 462                ret = -EINVAL;
 463
 464        return ret;
 465}
 466
 467static struct uart_ops netx_pops = {
 468        .tx_empty       = netx_tx_empty,
 469        .set_mctrl      = netx_set_mctrl,
 470        .get_mctrl      = netx_get_mctrl,
 471        .stop_tx        = netx_stop_tx,
 472        .start_tx       = netx_start_tx,
 473        .stop_rx        = netx_stop_rx,
 474        .enable_ms      = netx_enable_ms,
 475        .break_ctl      = netx_break_ctl,
 476        .startup        = netx_startup,
 477        .shutdown       = netx_shutdown,
 478        .set_termios    = netx_set_termios,
 479        .type           = netx_type,
 480        .release_port   = netx_release_port,
 481        .request_port   = netx_request_port,
 482        .config_port    = netx_config_port,
 483        .verify_port    = netx_verify_port,
 484};
 485
 486static struct netx_port netx_ports[] = {
 487        {
 488        .port = {
 489                .type = PORT_NETX,
 490                .iotype = UPIO_MEM,
 491                .membase = (char __iomem *)io_p2v(NETX_PA_UART0),
 492                .mapbase = NETX_PA_UART0,
 493                .irq = NETX_IRQ_UART0,
 494                .uartclk = 100000000,
 495                .fifosize = 16,
 496                .flags = UPF_BOOT_AUTOCONF,
 497                .ops = &netx_pops,
 498                .line = 0,
 499        },
 500        }, {
 501        .port = {
 502                .type = PORT_NETX,
 503                .iotype = UPIO_MEM,
 504                .membase = (char __iomem *)io_p2v(NETX_PA_UART1),
 505                .mapbase = NETX_PA_UART1,
 506                .irq = NETX_IRQ_UART1,
 507                .uartclk = 100000000,
 508                .fifosize = 16,
 509                .flags = UPF_BOOT_AUTOCONF,
 510                .ops = &netx_pops,
 511                .line = 1,
 512        },
 513        }, {
 514        .port = {
 515                .type = PORT_NETX,
 516                .iotype = UPIO_MEM,
 517                .membase = (char __iomem *)io_p2v(NETX_PA_UART2),
 518                .mapbase = NETX_PA_UART2,
 519                .irq = NETX_IRQ_UART2,
 520                .uartclk = 100000000,
 521                .fifosize = 16,
 522                .flags = UPF_BOOT_AUTOCONF,
 523                .ops = &netx_pops,
 524                .line = 2,
 525        },
 526        }
 527};
 528
 529#ifdef CONFIG_SERIAL_NETX_CONSOLE
 530
 531static void netx_console_putchar(struct uart_port *port, int ch)
 532{
 533        while (readl(port->membase + UART_FR) & FR_BUSY);
 534        writel(ch, port->membase + UART_DR);
 535}
 536
 537static void
 538netx_console_write(struct console *co, const char *s, unsigned int count)
 539{
 540        struct uart_port *port = &netx_ports[co->index].port;
 541        unsigned char cr_save;
 542
 543        cr_save = readl(port->membase + UART_CR);
 544        writel(cr_save | CR_UART_EN, port->membase + UART_CR);
 545
 546        uart_console_write(port, s, count, netx_console_putchar);
 547
 548        while (readl(port->membase + UART_FR) & FR_BUSY);
 549        writel(cr_save, port->membase + UART_CR);
 550}
 551
 552static void __init
 553netx_console_get_options(struct uart_port *port, int *baud,
 554                        int *parity, int *bits, int *flow)
 555{
 556        unsigned char line_cr;
 557
 558        *baud = (readl(port->membase + UART_BAUDDIV_MSB) << 8) |
 559                readl(port->membase + UART_BAUDDIV_LSB);
 560        *baud *= 1000;
 561        *baud /= 4096;
 562        *baud *= 1000;
 563        *baud /= 256;
 564        *baud *= 100;
 565
 566        line_cr = readl(port->membase + UART_LINE_CR);
 567        *parity = 'n';
 568        if (line_cr & LINE_CR_PEN) {
 569                if (line_cr & LINE_CR_EPS)
 570                        *parity = 'e';
 571                else
 572                        *parity = 'o';
 573        }
 574
 575        switch (line_cr & LINE_CR_BITS_MASK) {
 576        case LINE_CR_8BIT:
 577                *bits = 8;
 578                break;
 579        case LINE_CR_7BIT:
 580                *bits = 7;
 581                break;
 582        case LINE_CR_6BIT:
 583                *bits = 6;
 584                break;
 585        case LINE_CR_5BIT:
 586                *bits = 5;
 587                break;
 588        }
 589
 590        if (readl(port->membase + UART_RTS_CR) & RTS_CR_AUTO)
 591                *flow = 'r';
 592}
 593
 594static int __init
 595netx_console_setup(struct console *co, char *options)
 596{
 597        struct netx_port *sport;
 598        int baud = 9600;
 599        int bits = 8;
 600        int parity = 'n';
 601        int flow = 'n';
 602
 603        /*
 604         * Check whether an invalid uart number has been specified, and
 605         * if so, search for the first available port that does have
 606         * console support.
 607         */
 608        if (co->index == -1 || co->index >= ARRAY_SIZE(netx_ports))
 609                co->index = 0;
 610        sport = &netx_ports[co->index];
 611
 612        if (options) {
 613                uart_parse_options(options, &baud, &parity, &bits, &flow);
 614        } else {
 615                /* if the UART is enabled, assume it has been correctly setup
 616                 * by the bootloader and get the options
 617                 */
 618                if (readl(sport->port.membase + UART_CR) & CR_UART_EN) {
 619                        netx_console_get_options(&sport->port, &baud,
 620                        &parity, &bits, &flow);
 621                }
 622
 623        }
 624
 625        return uart_set_options(&sport->port, co, baud, parity, bits, flow);
 626}
 627
 628static struct uart_driver netx_reg;
 629static struct console netx_console = {
 630        .name           = "ttyNX",
 631        .write          = netx_console_write,
 632        .device         = uart_console_device,
 633        .setup          = netx_console_setup,
 634        .flags          = CON_PRINTBUFFER,
 635        .index          = -1,
 636        .data           = &netx_reg,
 637};
 638
 639static int __init netx_console_init(void)
 640{
 641        register_console(&netx_console);
 642        return 0;
 643}
 644console_initcall(netx_console_init);
 645
 646#define NETX_CONSOLE    &netx_console
 647#else
 648#define NETX_CONSOLE    NULL
 649#endif
 650
 651static struct uart_driver netx_reg = {
 652        .owner          = THIS_MODULE,
 653        .driver_name    = DRIVER_NAME,
 654        .dev_name       = "ttyNX",
 655        .major          = SERIAL_NX_MAJOR,
 656        .minor          = MINOR_START,
 657        .nr             = ARRAY_SIZE(netx_ports),
 658        .cons           = NETX_CONSOLE,
 659};
 660
 661static int serial_netx_suspend(struct platform_device *pdev, pm_message_t state)
 662{
 663        struct netx_port *sport = platform_get_drvdata(pdev);
 664
 665        if (sport)
 666                uart_suspend_port(&netx_reg, &sport->port);
 667
 668        return 0;
 669}
 670
 671static int serial_netx_resume(struct platform_device *pdev)
 672{
 673        struct netx_port *sport = platform_get_drvdata(pdev);
 674
 675        if (sport)
 676                uart_resume_port(&netx_reg, &sport->port);
 677
 678        return 0;
 679}
 680
 681static int serial_netx_probe(struct platform_device *pdev)
 682{
 683        struct uart_port *port = &netx_ports[pdev->id].port;
 684
 685        dev_info(&pdev->dev, "initialising\n");
 686
 687        port->dev = &pdev->dev;
 688
 689        writel(1, port->membase + UART_RXFIFO_IRQLEVEL);
 690        uart_add_one_port(&netx_reg, &netx_ports[pdev->id].port);
 691        platform_set_drvdata(pdev, &netx_ports[pdev->id]);
 692
 693        return 0;
 694}
 695
 696static int serial_netx_remove(struct platform_device *pdev)
 697{
 698        struct netx_port *sport = platform_get_drvdata(pdev);
 699
 700        platform_set_drvdata(pdev, NULL);
 701
 702        if (sport)
 703                uart_remove_one_port(&netx_reg, &sport->port);
 704
 705        return 0;
 706}
 707
 708static struct platform_driver serial_netx_driver = {
 709        .probe          = serial_netx_probe,
 710        .remove         = serial_netx_remove,
 711
 712        .suspend        = serial_netx_suspend,
 713        .resume         = serial_netx_resume,
 714
 715        .driver         = {
 716                .name   = DRIVER_NAME,
 717                .owner  = THIS_MODULE,
 718        },
 719};
 720
 721static int __init netx_serial_init(void)
 722{
 723        int ret;
 724
 725        printk(KERN_INFO "Serial: NetX driver\n");
 726
 727        ret = uart_register_driver(&netx_reg);
 728        if (ret)
 729                return ret;
 730
 731        ret = platform_driver_register(&serial_netx_driver);
 732        if (ret != 0)
 733                uart_unregister_driver(&netx_reg);
 734
 735        return 0;
 736}
 737
 738static void __exit netx_serial_exit(void)
 739{
 740        platform_driver_unregister(&serial_netx_driver);
 741        uart_unregister_driver(&netx_reg);
 742}
 743
 744module_init(netx_serial_init);
 745module_exit(netx_serial_exit);
 746
 747MODULE_AUTHOR("Sascha Hauer");
 748MODULE_DESCRIPTION("NetX serial port driver");
 749MODULE_LICENSE("GPL");
 750MODULE_ALIAS("platform:" DRIVER_NAME);
 751