linux/drivers/tty/serial/ar933x_uart.c
<<
>>
Prefs
   1/*
   2 *  Atheros AR933X SoC built-in UART driver
   3 *
   4 *  Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
   5 *
   6 *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
   7 *
   8 *  This program is free software; you can redistribute it and/or modify it
   9 *  under the terms of the GNU General Public License version 2 as published
  10 *  by the Free Software Foundation.
  11 */
  12
  13#include <linux/module.h>
  14#include <linux/ioport.h>
  15#include <linux/init.h>
  16#include <linux/console.h>
  17#include <linux/sysrq.h>
  18#include <linux/delay.h>
  19#include <linux/platform_device.h>
  20#include <linux/tty.h>
  21#include <linux/tty_flip.h>
  22#include <linux/serial_core.h>
  23#include <linux/serial.h>
  24#include <linux/slab.h>
  25#include <linux/io.h>
  26#include <linux/irq.h>
  27
  28#include <asm/mach-ath79/ar933x_uart.h>
  29#include <asm/mach-ath79/ar933x_uart_platform.h>
  30
  31#define DRIVER_NAME "ar933x-uart"
  32
  33#define AR933X_DUMMY_STATUS_RD  0x01
  34
  35static struct uart_driver ar933x_uart_driver;
  36
  37struct ar933x_uart_port {
  38        struct uart_port        port;
  39        unsigned int            ier;    /* shadow Interrupt Enable Register */
  40};
  41
  42static inline unsigned int ar933x_uart_read(struct ar933x_uart_port *up,
  43                                            int offset)
  44{
  45        return readl(up->port.membase + offset);
  46}
  47
  48static inline void ar933x_uart_write(struct ar933x_uart_port *up,
  49                                     int offset, unsigned int value)
  50{
  51        writel(value, up->port.membase + offset);
  52}
  53
  54static inline void ar933x_uart_rmw(struct ar933x_uart_port *up,
  55                                  unsigned int offset,
  56                                  unsigned int mask,
  57                                  unsigned int val)
  58{
  59        unsigned int t;
  60
  61        t = ar933x_uart_read(up, offset);
  62        t &= ~mask;
  63        t |= val;
  64        ar933x_uart_write(up, offset, t);
  65}
  66
  67static inline void ar933x_uart_rmw_set(struct ar933x_uart_port *up,
  68                                       unsigned int offset,
  69                                       unsigned int val)
  70{
  71        ar933x_uart_rmw(up, offset, 0, val);
  72}
  73
  74static inline void ar933x_uart_rmw_clear(struct ar933x_uart_port *up,
  75                                         unsigned int offset,
  76                                         unsigned int val)
  77{
  78        ar933x_uart_rmw(up, offset, val, 0);
  79}
  80
  81static inline void ar933x_uart_start_tx_interrupt(struct ar933x_uart_port *up)
  82{
  83        up->ier |= AR933X_UART_INT_TX_EMPTY;
  84        ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
  85}
  86
  87static inline void ar933x_uart_stop_tx_interrupt(struct ar933x_uart_port *up)
  88{
  89        up->ier &= ~AR933X_UART_INT_TX_EMPTY;
  90        ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
  91}
  92
  93static inline void ar933x_uart_putc(struct ar933x_uart_port *up, int ch)
  94{
  95        unsigned int rdata;
  96
  97        rdata = ch & AR933X_UART_DATA_TX_RX_MASK;
  98        rdata |= AR933X_UART_DATA_TX_CSR;
  99        ar933x_uart_write(up, AR933X_UART_DATA_REG, rdata);
 100}
 101
 102static unsigned int ar933x_uart_tx_empty(struct uart_port *port)
 103{
 104        struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
 105        unsigned long flags;
 106        unsigned int rdata;
 107
 108        spin_lock_irqsave(&up->port.lock, flags);
 109        rdata = ar933x_uart_read(up, AR933X_UART_DATA_REG);
 110        spin_unlock_irqrestore(&up->port.lock, flags);
 111
 112        return (rdata & AR933X_UART_DATA_TX_CSR) ? 0 : TIOCSER_TEMT;
 113}
 114
 115static unsigned int ar933x_uart_get_mctrl(struct uart_port *port)
 116{
 117        return TIOCM_CAR;
 118}
 119
 120static void ar933x_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
 121{
 122}
 123
 124static void ar933x_uart_start_tx(struct uart_port *port)
 125{
 126        struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
 127
 128        ar933x_uart_start_tx_interrupt(up);
 129}
 130
 131static void ar933x_uart_stop_tx(struct uart_port *port)
 132{
 133        struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
 134
 135        ar933x_uart_stop_tx_interrupt(up);
 136}
 137
 138static void ar933x_uart_stop_rx(struct uart_port *port)
 139{
 140        struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
 141
 142        up->ier &= ~AR933X_UART_INT_RX_VALID;
 143        ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
 144}
 145
 146static void ar933x_uart_break_ctl(struct uart_port *port, int break_state)
 147{
 148        struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
 149        unsigned long flags;
 150
 151        spin_lock_irqsave(&up->port.lock, flags);
 152        if (break_state == -1)
 153                ar933x_uart_rmw_set(up, AR933X_UART_CS_REG,
 154                                    AR933X_UART_CS_TX_BREAK);
 155        else
 156                ar933x_uart_rmw_clear(up, AR933X_UART_CS_REG,
 157                                      AR933X_UART_CS_TX_BREAK);
 158        spin_unlock_irqrestore(&up->port.lock, flags);
 159}
 160
 161static void ar933x_uart_enable_ms(struct uart_port *port)
 162{
 163}
 164
 165static void ar933x_uart_set_termios(struct uart_port *port,
 166                                    struct ktermios *new,
 167                                    struct ktermios *old)
 168{
 169        struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
 170        unsigned int cs;
 171        unsigned long flags;
 172        unsigned int baud, scale;
 173
 174        /* Only CS8 is supported */
 175        new->c_cflag &= ~CSIZE;
 176        new->c_cflag |= CS8;
 177
 178        /* Only one stop bit is supported */
 179        new->c_cflag &= ~CSTOPB;
 180
 181        cs = 0;
 182        if (new->c_cflag & PARENB) {
 183                if (!(new->c_cflag & PARODD))
 184                        cs |= AR933X_UART_CS_PARITY_EVEN;
 185                else
 186                        cs |= AR933X_UART_CS_PARITY_ODD;
 187        } else {
 188                cs |= AR933X_UART_CS_PARITY_NONE;
 189        }
 190
 191        /* Mark/space parity is not supported */
 192        new->c_cflag &= ~CMSPAR;
 193
 194        baud = uart_get_baud_rate(port, new, old, 0, port->uartclk / 16);
 195        scale = (port->uartclk / (16 * baud)) - 1;
 196
 197        /*
 198         * Ok, we're now changing the port state. Do it with
 199         * interrupts disabled.
 200         */
 201        spin_lock_irqsave(&up->port.lock, flags);
 202
 203        /* Update the per-port timeout. */
 204        uart_update_timeout(port, new->c_cflag, baud);
 205
 206        up->port.ignore_status_mask = 0;
 207
 208        /* ignore all characters if CREAD is not set */
 209        if ((new->c_cflag & CREAD) == 0)
 210                up->port.ignore_status_mask |= AR933X_DUMMY_STATUS_RD;
 211
 212        ar933x_uart_write(up, AR933X_UART_CLOCK_REG,
 213                          scale << AR933X_UART_CLOCK_SCALE_S | 8192);
 214
 215        /* setup configuration register */
 216        ar933x_uart_rmw(up, AR933X_UART_CS_REG, AR933X_UART_CS_PARITY_M, cs);
 217
 218        /* enable host interrupt */
 219        ar933x_uart_rmw_set(up, AR933X_UART_CS_REG,
 220                            AR933X_UART_CS_HOST_INT_EN);
 221
 222        spin_unlock_irqrestore(&up->port.lock, flags);
 223
 224        if (tty_termios_baud_rate(new))
 225                tty_termios_encode_baud_rate(new, baud, baud);
 226}
 227
 228static void ar933x_uart_rx_chars(struct ar933x_uart_port *up)
 229{
 230        struct tty_struct *tty;
 231        int max_count = 256;
 232
 233        tty = tty_port_tty_get(&up->port.state->port);
 234        do {
 235                unsigned int rdata;
 236                unsigned char ch;
 237
 238                rdata = ar933x_uart_read(up, AR933X_UART_DATA_REG);
 239                if ((rdata & AR933X_UART_DATA_RX_CSR) == 0)
 240                        break;
 241
 242                /* remove the character from the FIFO */
 243                ar933x_uart_write(up, AR933X_UART_DATA_REG,
 244                                  AR933X_UART_DATA_RX_CSR);
 245
 246                if (!tty) {
 247                        /* discard the data if no tty available */
 248                        continue;
 249                }
 250
 251                up->port.icount.rx++;
 252                ch = rdata & AR933X_UART_DATA_TX_RX_MASK;
 253
 254                if (uart_handle_sysrq_char(&up->port, ch))
 255                        continue;
 256
 257                if ((up->port.ignore_status_mask & AR933X_DUMMY_STATUS_RD) == 0)
 258                        tty_insert_flip_char(tty, ch, TTY_NORMAL);
 259        } while (max_count-- > 0);
 260
 261        if (tty) {
 262                tty_flip_buffer_push(tty);
 263                tty_kref_put(tty);
 264        }
 265}
 266
 267static void ar933x_uart_tx_chars(struct ar933x_uart_port *up)
 268{
 269        struct circ_buf *xmit = &up->port.state->xmit;
 270        int count;
 271
 272        if (uart_tx_stopped(&up->port))
 273                return;
 274
 275        count = up->port.fifosize;
 276        do {
 277                unsigned int rdata;
 278
 279                rdata = ar933x_uart_read(up, AR933X_UART_DATA_REG);
 280                if ((rdata & AR933X_UART_DATA_TX_CSR) == 0)
 281                        break;
 282
 283                if (up->port.x_char) {
 284                        ar933x_uart_putc(up, up->port.x_char);
 285                        up->port.icount.tx++;
 286                        up->port.x_char = 0;
 287                        continue;
 288                }
 289
 290                if (uart_circ_empty(xmit))
 291                        break;
 292
 293                ar933x_uart_putc(up, xmit->buf[xmit->tail]);
 294
 295                xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
 296                up->port.icount.tx++;
 297        } while (--count > 0);
 298
 299        if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
 300                uart_write_wakeup(&up->port);
 301
 302        if (!uart_circ_empty(xmit))
 303                ar933x_uart_start_tx_interrupt(up);
 304}
 305
 306static irqreturn_t ar933x_uart_interrupt(int irq, void *dev_id)
 307{
 308        struct ar933x_uart_port *up = dev_id;
 309        unsigned int status;
 310
 311        status = ar933x_uart_read(up, AR933X_UART_CS_REG);
 312        if ((status & AR933X_UART_CS_HOST_INT) == 0)
 313                return IRQ_NONE;
 314
 315        spin_lock(&up->port.lock);
 316
 317        status = ar933x_uart_read(up, AR933X_UART_INT_REG);
 318        status &= ar933x_uart_read(up, AR933X_UART_INT_EN_REG);
 319
 320        if (status & AR933X_UART_INT_RX_VALID) {
 321                ar933x_uart_write(up, AR933X_UART_INT_REG,
 322                                  AR933X_UART_INT_RX_VALID);
 323                ar933x_uart_rx_chars(up);
 324        }
 325
 326        if (status & AR933X_UART_INT_TX_EMPTY) {
 327                ar933x_uart_write(up, AR933X_UART_INT_REG,
 328                                  AR933X_UART_INT_TX_EMPTY);
 329                ar933x_uart_stop_tx_interrupt(up);
 330                ar933x_uart_tx_chars(up);
 331        }
 332
 333        spin_unlock(&up->port.lock);
 334
 335        return IRQ_HANDLED;
 336}
 337
 338static int ar933x_uart_startup(struct uart_port *port)
 339{
 340        struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
 341        unsigned long flags;
 342        int ret;
 343
 344        ret = request_irq(up->port.irq, ar933x_uart_interrupt,
 345                          up->port.irqflags, dev_name(up->port.dev), up);
 346        if (ret)
 347                return ret;
 348
 349        spin_lock_irqsave(&up->port.lock, flags);
 350
 351        /* Enable HOST interrupts */
 352        ar933x_uart_rmw_set(up, AR933X_UART_CS_REG,
 353                            AR933X_UART_CS_HOST_INT_EN);
 354
 355        /* Enable RX interrupts */
 356        up->ier = AR933X_UART_INT_RX_VALID;
 357        ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
 358
 359        spin_unlock_irqrestore(&up->port.lock, flags);
 360
 361        return 0;
 362}
 363
 364static void ar933x_uart_shutdown(struct uart_port *port)
 365{
 366        struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
 367
 368        /* Disable all interrupts */
 369        up->ier = 0;
 370        ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
 371
 372        /* Disable break condition */
 373        ar933x_uart_rmw_clear(up, AR933X_UART_CS_REG,
 374                              AR933X_UART_CS_TX_BREAK);
 375
 376        free_irq(up->port.irq, up);
 377}
 378
 379static const char *ar933x_uart_type(struct uart_port *port)
 380{
 381        return (port->type == PORT_AR933X) ? "AR933X UART" : NULL;
 382}
 383
 384static void ar933x_uart_release_port(struct uart_port *port)
 385{
 386        /* Nothing to release ... */
 387}
 388
 389static int ar933x_uart_request_port(struct uart_port *port)
 390{
 391        /* UARTs always present */
 392        return 0;
 393}
 394
 395static void ar933x_uart_config_port(struct uart_port *port, int flags)
 396{
 397        if (flags & UART_CONFIG_TYPE)
 398                port->type = PORT_AR933X;
 399}
 400
 401static int ar933x_uart_verify_port(struct uart_port *port,
 402                                   struct serial_struct *ser)
 403{
 404        if (ser->type != PORT_UNKNOWN &&
 405            ser->type != PORT_AR933X)
 406                return -EINVAL;
 407
 408        if (ser->irq < 0 || ser->irq >= NR_IRQS)
 409                return -EINVAL;
 410
 411        if (ser->baud_base < 28800)
 412                return -EINVAL;
 413
 414        return 0;
 415}
 416
 417static struct uart_ops ar933x_uart_ops = {
 418        .tx_empty       = ar933x_uart_tx_empty,
 419        .set_mctrl      = ar933x_uart_set_mctrl,
 420        .get_mctrl      = ar933x_uart_get_mctrl,
 421        .stop_tx        = ar933x_uart_stop_tx,
 422        .start_tx       = ar933x_uart_start_tx,
 423        .stop_rx        = ar933x_uart_stop_rx,
 424        .enable_ms      = ar933x_uart_enable_ms,
 425        .break_ctl      = ar933x_uart_break_ctl,
 426        .startup        = ar933x_uart_startup,
 427        .shutdown       = ar933x_uart_shutdown,
 428        .set_termios    = ar933x_uart_set_termios,
 429        .type           = ar933x_uart_type,
 430        .release_port   = ar933x_uart_release_port,
 431        .request_port   = ar933x_uart_request_port,
 432        .config_port    = ar933x_uart_config_port,
 433        .verify_port    = ar933x_uart_verify_port,
 434};
 435
 436#ifdef CONFIG_SERIAL_AR933X_CONSOLE
 437
 438static struct ar933x_uart_port *
 439ar933x_console_ports[CONFIG_SERIAL_AR933X_NR_UARTS];
 440
 441static void ar933x_uart_wait_xmitr(struct ar933x_uart_port *up)
 442{
 443        unsigned int status;
 444        unsigned int timeout = 60000;
 445
 446        /* Wait up to 60ms for the character(s) to be sent. */
 447        do {
 448                status = ar933x_uart_read(up, AR933X_UART_DATA_REG);
 449                if (--timeout == 0)
 450                        break;
 451                udelay(1);
 452        } while ((status & AR933X_UART_DATA_TX_CSR) == 0);
 453}
 454
 455static void ar933x_uart_console_putchar(struct uart_port *port, int ch)
 456{
 457        struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
 458
 459        ar933x_uart_wait_xmitr(up);
 460        ar933x_uart_putc(up, ch);
 461}
 462
 463static void ar933x_uart_console_write(struct console *co, const char *s,
 464                                      unsigned int count)
 465{
 466        struct ar933x_uart_port *up = ar933x_console_ports[co->index];
 467        unsigned long flags;
 468        unsigned int int_en;
 469        int locked = 1;
 470
 471        local_irq_save(flags);
 472
 473        if (up->port.sysrq)
 474                locked = 0;
 475        else if (oops_in_progress)
 476                locked = spin_trylock(&up->port.lock);
 477        else
 478                spin_lock(&up->port.lock);
 479
 480        /*
 481         * First save the IER then disable the interrupts
 482         */
 483        int_en = ar933x_uart_read(up, AR933X_UART_INT_EN_REG);
 484        ar933x_uart_write(up, AR933X_UART_INT_EN_REG, 0);
 485
 486        uart_console_write(&up->port, s, count, ar933x_uart_console_putchar);
 487
 488        /*
 489         * Finally, wait for transmitter to become empty
 490         * and restore the IER
 491         */
 492        ar933x_uart_wait_xmitr(up);
 493        ar933x_uart_write(up, AR933X_UART_INT_EN_REG, int_en);
 494
 495        ar933x_uart_write(up, AR933X_UART_INT_REG, AR933X_UART_INT_ALLINTS);
 496
 497        if (locked)
 498                spin_unlock(&up->port.lock);
 499
 500        local_irq_restore(flags);
 501}
 502
 503static int ar933x_uart_console_setup(struct console *co, char *options)
 504{
 505        struct ar933x_uart_port *up;
 506        int baud = 115200;
 507        int bits = 8;
 508        int parity = 'n';
 509        int flow = 'n';
 510
 511        if (co->index < 0 || co->index >= CONFIG_SERIAL_AR933X_NR_UARTS)
 512                return -EINVAL;
 513
 514        up = ar933x_console_ports[co->index];
 515        if (!up)
 516                return -ENODEV;
 517
 518        if (options)
 519                uart_parse_options(options, &baud, &parity, &bits, &flow);
 520
 521        return uart_set_options(&up->port, co, baud, parity, bits, flow);
 522}
 523
 524static struct console ar933x_uart_console = {
 525        .name           = "ttyATH",
 526        .write          = ar933x_uart_console_write,
 527        .device         = uart_console_device,
 528        .setup          = ar933x_uart_console_setup,
 529        .flags          = CON_PRINTBUFFER,
 530        .index          = -1,
 531        .data           = &ar933x_uart_driver,
 532};
 533
 534static void ar933x_uart_add_console_port(struct ar933x_uart_port *up)
 535{
 536        ar933x_console_ports[up->port.line] = up;
 537}
 538
 539#define AR933X_SERIAL_CONSOLE   (&ar933x_uart_console)
 540
 541#else
 542
 543static inline void ar933x_uart_add_console_port(struct ar933x_uart_port *up) {}
 544
 545#define AR933X_SERIAL_CONSOLE   NULL
 546
 547#endif /* CONFIG_SERIAL_AR933X_CONSOLE */
 548
 549static struct uart_driver ar933x_uart_driver = {
 550        .owner          = THIS_MODULE,
 551        .driver_name    = DRIVER_NAME,
 552        .dev_name       = "ttyATH",
 553        .nr             = CONFIG_SERIAL_AR933X_NR_UARTS,
 554        .cons           = AR933X_SERIAL_CONSOLE,
 555};
 556
 557static int __devinit ar933x_uart_probe(struct platform_device *pdev)
 558{
 559        struct ar933x_uart_platform_data *pdata;
 560        struct ar933x_uart_port *up;
 561        struct uart_port *port;
 562        struct resource *mem_res;
 563        struct resource *irq_res;
 564        int id;
 565        int ret;
 566
 567        pdata = pdev->dev.platform_data;
 568        if (!pdata)
 569                return -EINVAL;
 570
 571        id = pdev->id;
 572        if (id == -1)
 573                id = 0;
 574
 575        if (id > CONFIG_SERIAL_AR933X_NR_UARTS)
 576                return -EINVAL;
 577
 578        mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 579        if (!mem_res) {
 580                dev_err(&pdev->dev, "no MEM resource\n");
 581                return -EINVAL;
 582        }
 583
 584        irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 585        if (!irq_res) {
 586                dev_err(&pdev->dev, "no IRQ resource\n");
 587                return -EINVAL;
 588        }
 589
 590        up = kzalloc(sizeof(struct ar933x_uart_port), GFP_KERNEL);
 591        if (!up)
 592                return -ENOMEM;
 593
 594        port = &up->port;
 595        port->mapbase = mem_res->start;
 596
 597        port->membase = ioremap(mem_res->start, AR933X_UART_REGS_SIZE);
 598        if (!port->membase) {
 599                ret = -ENOMEM;
 600                goto err_free_up;
 601        }
 602
 603        port->line = id;
 604        port->irq = irq_res->start;
 605        port->dev = &pdev->dev;
 606        port->type = PORT_AR933X;
 607        port->iotype = UPIO_MEM32;
 608        port->uartclk = pdata->uartclk;
 609
 610        port->regshift = 2;
 611        port->fifosize = AR933X_UART_FIFO_SIZE;
 612        port->ops = &ar933x_uart_ops;
 613
 614        ar933x_uart_add_console_port(up);
 615
 616        ret = uart_add_one_port(&ar933x_uart_driver, &up->port);
 617        if (ret)
 618                goto err_unmap;
 619
 620        platform_set_drvdata(pdev, up);
 621        return 0;
 622
 623err_unmap:
 624        iounmap(up->port.membase);
 625err_free_up:
 626        kfree(up);
 627        return ret;
 628}
 629
 630static int __devexit ar933x_uart_remove(struct platform_device *pdev)
 631{
 632        struct ar933x_uart_port *up;
 633
 634        up = platform_get_drvdata(pdev);
 635        platform_set_drvdata(pdev, NULL);
 636
 637        if (up) {
 638                uart_remove_one_port(&ar933x_uart_driver, &up->port);
 639                iounmap(up->port.membase);
 640                kfree(up);
 641        }
 642
 643        return 0;
 644}
 645
 646static struct platform_driver ar933x_uart_platform_driver = {
 647        .probe          = ar933x_uart_probe,
 648        .remove         = __devexit_p(ar933x_uart_remove),
 649        .driver         = {
 650                .name           = DRIVER_NAME,
 651                .owner          = THIS_MODULE,
 652        },
 653};
 654
 655static int __init ar933x_uart_init(void)
 656{
 657        int ret;
 658
 659        ar933x_uart_driver.nr = CONFIG_SERIAL_AR933X_NR_UARTS;
 660        ret = uart_register_driver(&ar933x_uart_driver);
 661        if (ret)
 662                goto err_out;
 663
 664        ret = platform_driver_register(&ar933x_uart_platform_driver);
 665        if (ret)
 666                goto err_unregister_uart_driver;
 667
 668        return 0;
 669
 670err_unregister_uart_driver:
 671        uart_unregister_driver(&ar933x_uart_driver);
 672err_out:
 673        return ret;
 674}
 675
 676static void __exit ar933x_uart_exit(void)
 677{
 678        platform_driver_unregister(&ar933x_uart_platform_driver);
 679        uart_unregister_driver(&ar933x_uart_driver);
 680}
 681
 682module_init(ar933x_uart_init);
 683module_exit(ar933x_uart_exit);
 684
 685MODULE_DESCRIPTION("Atheros AR933X UART driver");
 686MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
 687MODULE_LICENSE("GPL v2");
 688MODULE_ALIAS("platform:" DRIVER_NAME);
 689