linux/drivers/serial/serial_ks8695.c
<<
>>
Prefs
   1/*
   2 *  drivers/serial/serial_ks8695.c
   3 *
   4 *  Driver for KS8695 serial ports
   5 *
   6 *  Based on drivers/serial/serial_amba.c, by Kam Lee.
   7 *
   8 *  Copyright 2002-2005 Micrel Inc.
   9 *
  10 * This program is free software; you can redistribute it and/or modify
  11 * it under the terms of the GNU General Public License as published by
  12 * the Free Software Foundation; either version 2 of the License, or
  13 * (at your option) any later version.
  14 *
  15 */
  16#include <linux/module.h>
  17#include <linux/tty.h>
  18#include <linux/ioport.h>
  19#include <linux/init.h>
  20#include <linux/serial.h>
  21#include <linux/console.h>
  22#include <linux/sysrq.h>
  23#include <linux/device.h>
  24
  25#include <asm/io.h>
  26#include <asm/irq.h>
  27#include <asm/mach/irq.h>
  28
  29#include <asm/arch/regs-uart.h>
  30#include <asm/arch/regs-irq.h>
  31
  32#if defined(CONFIG_SERIAL_KS8695_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
  33#define SUPPORT_SYSRQ
  34#endif
  35
  36#include <linux/serial_core.h>
  37
  38
  39#define SERIAL_KS8695_MAJOR     204
  40#define SERIAL_KS8695_MINOR     16
  41#define SERIAL_KS8695_DEVNAME   "ttyAM"
  42
  43#define SERIAL_KS8695_NR        1
  44
  45/*
  46 * Access macros for the KS8695 UART
  47 */
  48#define UART_GET_CHAR(p)        (__raw_readl((p)->membase + KS8695_URRB) & 0xFF)
  49#define UART_PUT_CHAR(p, c)     __raw_writel((c), (p)->membase + KS8695_URTH)
  50#define UART_GET_FCR(p)         __raw_readl((p)->membase + KS8695_URFC)
  51#define UART_PUT_FCR(p, c)      __raw_writel((c), (p)->membase + KS8695_URFC)
  52#define UART_GET_MSR(p)         __raw_readl((p)->membase + KS8695_URMS)
  53#define UART_GET_LSR(p)         __raw_readl((p)->membase + KS8695_URLS)
  54#define UART_GET_LCR(p)         __raw_readl((p)->membase + KS8695_URLC)
  55#define UART_PUT_LCR(p, c)      __raw_writel((c), (p)->membase + KS8695_URLC)
  56#define UART_GET_MCR(p)         __raw_readl((p)->membase + KS8695_URMC)
  57#define UART_PUT_MCR(p, c)      __raw_writel((c), (p)->membase + KS8695_URMC)
  58#define UART_GET_BRDR(p)        __raw_readl((p)->membase + KS8695_URBD)
  59#define UART_PUT_BRDR(p, c)     __raw_writel((c), (p)->membase + KS8695_URBD)
  60
  61#define KS8695_CLR_TX_INT()     __raw_writel(1 << KS8695_IRQ_UART_TX, KS8695_IRQ_VA + KS8695_INTST)
  62
  63#define UART_DUMMY_LSR_RX       0x100
  64#define UART_PORT_SIZE          (KS8695_USR - KS8695_URRB + 4)
  65
  66#define tx_enabled(port) ((port)->unused[0])
  67#define rx_enabled(port) ((port)->unused[1])
  68
  69
  70#ifdef SUPPORT_SYSRQ
  71static struct console ks8695_console;
  72#endif
  73
  74static void ks8695uart_stop_tx(struct uart_port *port)
  75{
  76        if (tx_enabled(port)) {
  77                disable_irq(KS8695_IRQ_UART_TX);
  78                tx_enabled(port) = 0;
  79        }
  80}
  81
  82static void ks8695uart_start_tx(struct uart_port *port)
  83{
  84        if (!tx_enabled(port)) {
  85                enable_irq(KS8695_IRQ_UART_TX);
  86                tx_enabled(port) = 1;
  87        }
  88}
  89
  90static void ks8695uart_stop_rx(struct uart_port *port)
  91{
  92        if (rx_enabled(port)) {
  93                disable_irq(KS8695_IRQ_UART_RX);
  94                rx_enabled(port) = 0;
  95        }
  96}
  97
  98static void ks8695uart_enable_ms(struct uart_port *port)
  99{
 100        enable_irq(KS8695_IRQ_UART_MODEM_STATUS);
 101}
 102
 103static void ks8695uart_disable_ms(struct uart_port *port)
 104{
 105        disable_irq(KS8695_IRQ_UART_MODEM_STATUS);
 106}
 107
 108static irqreturn_t ks8695uart_rx_chars(int irq, void *dev_id)
 109{
 110        struct uart_port *port = dev_id;
 111        struct tty_struct *tty = port->info->tty;
 112        unsigned int status, ch, lsr, flg, max_count = 256;
 113
 114        status = UART_GET_LSR(port);            /* clears pending LSR interrupts */
 115        while ((status & URLS_URDR) && max_count--) {
 116                ch = UART_GET_CHAR(port);
 117                flg = TTY_NORMAL;
 118
 119                port->icount.rx++;
 120
 121                /*
 122                 * Note that the error handling code is
 123                 * out of the main execution path
 124                 */
 125                lsr = UART_GET_LSR(port) | UART_DUMMY_LSR_RX;
 126                if (unlikely(lsr & (URLS_URBI | URLS_URPE | URLS_URFE | URLS_URROE))) {
 127                        if (lsr & URLS_URBI) {
 128                                lsr &= ~(URLS_URFE | URLS_URPE);
 129                                port->icount.brk++;
 130                                if (uart_handle_break(port))
 131                                        goto ignore_char;
 132                        }
 133                        if (lsr & URLS_URPE)
 134                                port->icount.parity++;
 135                        if (lsr & URLS_URFE)
 136                                port->icount.frame++;
 137                        if (lsr & URLS_URROE)
 138                                port->icount.overrun++;
 139
 140                        lsr &= port->read_status_mask;
 141
 142                        if (lsr & URLS_URBI)
 143                                flg = TTY_BREAK;
 144                        else if (lsr & URLS_URPE)
 145                                flg = TTY_PARITY;
 146                        else if (lsr & URLS_URFE)
 147                                flg = TTY_FRAME;
 148                }
 149
 150                if (uart_handle_sysrq_char(port, ch))
 151                        goto ignore_char;
 152
 153                uart_insert_char(port, lsr, URLS_URROE, ch, flg);
 154
 155ignore_char:
 156                status = UART_GET_LSR(port);
 157        }
 158        tty_flip_buffer_push(tty);
 159
 160        return IRQ_HANDLED;
 161}
 162
 163
 164static irqreturn_t ks8695uart_tx_chars(int irq, void *dev_id)
 165{
 166        struct uart_port *port = dev_id;
 167        struct circ_buf *xmit = &port->info->xmit;
 168        unsigned int count;
 169
 170        if (port->x_char) {
 171                KS8695_CLR_TX_INT();
 172                UART_PUT_CHAR(port, port->x_char);
 173                port->icount.tx++;
 174                port->x_char = 0;
 175                return IRQ_HANDLED;
 176        }
 177
 178        if (uart_tx_stopped(port) || uart_circ_empty(xmit)) {
 179                ks8695uart_stop_tx(port);
 180                return IRQ_HANDLED;
 181        }
 182
 183        count = 16;     /* fifo size */
 184        while (!uart_circ_empty(xmit) && (count-- > 0)) {
 185                KS8695_CLR_TX_INT();
 186                UART_PUT_CHAR(port, xmit->buf[xmit->tail]);
 187
 188                xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
 189                port->icount.tx++;
 190        }
 191
 192        if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
 193                uart_write_wakeup(port);
 194
 195        if (uart_circ_empty(xmit))
 196                ks8695uart_stop_tx(port);
 197
 198        return IRQ_HANDLED;
 199}
 200
 201static irqreturn_t ks8695uart_modem_status(int irq, void *dev_id)
 202{
 203        struct uart_port *port = dev_id;
 204        unsigned int status;
 205
 206        /*
 207         * clear modem interrupt by reading MSR
 208         */
 209        status = UART_GET_MSR(port);
 210
 211        if (status & URMS_URDDCD)
 212                uart_handle_dcd_change(port, status & URMS_URDDCD);
 213
 214        if (status & URMS_URDDST)
 215                port->icount.dsr++;
 216
 217        if (status & URMS_URDCTS)
 218                uart_handle_cts_change(port, status & URMS_URDCTS);
 219
 220        if (status & URMS_URTERI)
 221                port->icount.rng++;
 222
 223        wake_up_interruptible(&port->info->delta_msr_wait);
 224
 225        return IRQ_HANDLED;
 226}
 227
 228static unsigned int ks8695uart_tx_empty(struct uart_port *port)
 229{
 230        return (UART_GET_LSR(port) & URLS_URTE) ? TIOCSER_TEMT : 0;
 231}
 232
 233static unsigned int ks8695uart_get_mctrl(struct uart_port *port)
 234{
 235        unsigned int result = 0;
 236        unsigned int status;
 237
 238        status = UART_GET_MSR(port);
 239        if (status & URMS_URDCD)
 240                result |= TIOCM_CAR;
 241        if (status & URMS_URDSR)
 242                result |= TIOCM_DSR;
 243        if (status & URMS_URCTS)
 244                result |= TIOCM_CTS;
 245        if (status & URMS_URRI)
 246                result |= TIOCM_RI;
 247
 248        return result;
 249}
 250
 251static void ks8695uart_set_mctrl(struct uart_port *port, u_int mctrl)
 252{
 253        unsigned int mcr;
 254
 255        mcr = UART_GET_MCR(port);
 256        if (mctrl & TIOCM_RTS)
 257                mcr |= URMC_URRTS;
 258        else
 259                mcr &= ~URMC_URRTS;
 260
 261        if (mctrl & TIOCM_DTR)
 262                mcr |= URMC_URDTR;
 263        else
 264                mcr &= ~URMC_URDTR;
 265
 266        UART_PUT_MCR(port, mcr);
 267}
 268
 269static void ks8695uart_break_ctl(struct uart_port *port, int break_state)
 270{
 271        unsigned int lcr;
 272
 273        lcr = UART_GET_LCR(port);
 274
 275        if (break_state == -1)
 276                lcr |= URLC_URSBC;
 277        else
 278                lcr &= ~URLC_URSBC;
 279
 280        UART_PUT_LCR(port, lcr);
 281}
 282
 283static int ks8695uart_startup(struct uart_port *port)
 284{
 285        int retval;
 286
 287        set_irq_flags(KS8695_IRQ_UART_TX, IRQF_VALID | IRQF_NOAUTOEN);
 288        tx_enabled(port) = 0;
 289        rx_enabled(port) = 1;
 290
 291        /*
 292         * Allocate the IRQ
 293         */
 294        retval = request_irq(KS8695_IRQ_UART_TX, ks8695uart_tx_chars, IRQF_DISABLED, "UART TX", port);
 295        if (retval)
 296                goto err_tx;
 297
 298        retval = request_irq(KS8695_IRQ_UART_RX, ks8695uart_rx_chars, IRQF_DISABLED, "UART RX", port);
 299        if (retval)
 300                goto err_rx;
 301
 302        retval = request_irq(KS8695_IRQ_UART_LINE_STATUS, ks8695uart_rx_chars, IRQF_DISABLED, "UART LineStatus", port);
 303        if (retval)
 304                goto err_ls;
 305
 306        retval = request_irq(KS8695_IRQ_UART_MODEM_STATUS, ks8695uart_modem_status, IRQF_DISABLED, "UART ModemStatus", port);
 307        if (retval)
 308                goto err_ms;
 309
 310        return 0;
 311
 312err_ms:
 313        free_irq(KS8695_IRQ_UART_LINE_STATUS, port);
 314err_ls:
 315        free_irq(KS8695_IRQ_UART_RX, port);
 316err_rx:
 317        free_irq(KS8695_IRQ_UART_TX, port);
 318err_tx:
 319        return retval;
 320}
 321
 322static void ks8695uart_shutdown(struct uart_port *port)
 323{
 324        /*
 325         * Free the interrupt
 326         */
 327        free_irq(KS8695_IRQ_UART_RX, port);
 328        free_irq(KS8695_IRQ_UART_TX, port);
 329        free_irq(KS8695_IRQ_UART_MODEM_STATUS, port);
 330        free_irq(KS8695_IRQ_UART_LINE_STATUS, port);
 331
 332        /* disable break condition and fifos */
 333        UART_PUT_LCR(port, UART_GET_LCR(port) & ~URLC_URSBC);
 334        UART_PUT_FCR(port, UART_GET_FCR(port) & ~URFC_URFE);
 335}
 336
 337static void ks8695uart_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old)
 338{
 339        unsigned int lcr, fcr = 0;
 340        unsigned long flags;
 341        unsigned int baud, quot;
 342
 343        /*
 344         * Ask the core to calculate the divisor for us.
 345         */
 346        baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
 347        quot = uart_get_divisor(port, baud);
 348
 349        switch (termios->c_cflag & CSIZE) {
 350        case CS5:
 351                lcr = URCL_5;
 352                break;
 353        case CS6:
 354                lcr = URCL_6;
 355                break;
 356        case CS7:
 357                lcr = URCL_7;
 358                break;
 359        default:
 360                lcr = URCL_8;
 361                break;
 362        }
 363
 364        /* stop bits */
 365        if (termios->c_cflag & CSTOPB)
 366                lcr |= URLC_URSB;
 367
 368        /* parity */
 369        if (termios->c_cflag & PARENB) {
 370                if (termios->c_cflag & CMSPAR) {        /* Mark or Space parity */
 371                        if (termios->c_cflag & PARODD)
 372                                lcr |= URPE_MARK;
 373                        else
 374                                lcr |= URPE_SPACE;
 375                }
 376                else if (termios->c_cflag & PARODD)
 377                        lcr |= URPE_ODD;
 378                else
 379                        lcr |= URPE_EVEN;
 380        }
 381
 382        if (port->fifosize > 1)
 383                fcr = URFC_URFRT_8 | URFC_URTFR | URFC_URRFR | URFC_URFE;
 384
 385        spin_lock_irqsave(&port->lock, flags);
 386
 387        /*
 388         * Update the per-port timeout.
 389         */
 390        uart_update_timeout(port, termios->c_cflag, baud);
 391
 392        port->read_status_mask = URLS_URROE;
 393        if (termios->c_iflag & INPCK)
 394                port->read_status_mask |= (URLS_URFE | URLS_URPE);
 395        if (termios->c_iflag & (BRKINT | PARMRK))
 396                port->read_status_mask |= URLS_URBI;
 397
 398        /*
 399         * Characters to ignore
 400         */
 401        port->ignore_status_mask = 0;
 402        if (termios->c_iflag & IGNPAR)
 403                port->ignore_status_mask |= (URLS_URFE | URLS_URPE);
 404        if (termios->c_iflag & IGNBRK) {
 405                port->ignore_status_mask |= URLS_URBI;
 406                /*
 407                 * If we're ignoring parity and break indicators,
 408                 * ignore overruns too (for real raw support).
 409                 */
 410                if (termios->c_iflag & IGNPAR)
 411                        port->ignore_status_mask |= URLS_URROE;
 412        }
 413
 414        /*
 415         * Ignore all characters if CREAD is not set.
 416         */
 417        if ((termios->c_cflag & CREAD) == 0)
 418                port->ignore_status_mask |= UART_DUMMY_LSR_RX;
 419
 420        /* first, disable everything */
 421        if (UART_ENABLE_MS(port, termios->c_cflag))
 422                ks8695uart_enable_ms(port);
 423        else
 424                ks8695uart_disable_ms(port);
 425
 426        /* Set baud rate */
 427        UART_PUT_BRDR(port, quot);
 428
 429        UART_PUT_LCR(port, lcr);
 430        UART_PUT_FCR(port, fcr);
 431
 432        spin_unlock_irqrestore(&port->lock, flags);
 433}
 434
 435static const char *ks8695uart_type(struct uart_port *port)
 436{
 437        return port->type == PORT_KS8695 ? "KS8695" : NULL;
 438}
 439
 440/*
 441 * Release the memory region(s) being used by 'port'
 442 */
 443static void ks8695uart_release_port(struct uart_port *port)
 444{
 445        release_mem_region(port->mapbase, UART_PORT_SIZE);
 446}
 447
 448/*
 449 * Request the memory region(s) being used by 'port'
 450 */
 451static int ks8695uart_request_port(struct uart_port *port)
 452{
 453        return request_mem_region(port->mapbase, UART_PORT_SIZE,
 454                        "serial_ks8695") != NULL ? 0 : -EBUSY;
 455}
 456
 457/*
 458 * Configure/autoconfigure the port.
 459 */
 460static void ks8695uart_config_port(struct uart_port *port, int flags)
 461{
 462        if (flags & UART_CONFIG_TYPE) {
 463                port->type = PORT_KS8695;
 464                ks8695uart_request_port(port);
 465        }
 466}
 467
 468/*
 469 * verify the new serial_struct (for TIOCSSERIAL).
 470 */
 471static int ks8695uart_verify_port(struct uart_port *port, struct serial_struct *ser)
 472{
 473        int ret = 0;
 474
 475        if (ser->type != PORT_UNKNOWN && ser->type != PORT_KS8695)
 476                ret = -EINVAL;
 477        if (ser->irq != port->irq)
 478                ret = -EINVAL;
 479        if (ser->baud_base < 9600)
 480                ret = -EINVAL;
 481        return ret;
 482}
 483
 484static struct uart_ops ks8695uart_pops = {
 485        .tx_empty       = ks8695uart_tx_empty,
 486        .set_mctrl      = ks8695uart_set_mctrl,
 487        .get_mctrl      = ks8695uart_get_mctrl,
 488        .stop_tx        = ks8695uart_stop_tx,
 489        .start_tx       = ks8695uart_start_tx,
 490        .stop_rx        = ks8695uart_stop_rx,
 491        .enable_ms      = ks8695uart_enable_ms,
 492        .break_ctl      = ks8695uart_break_ctl,
 493        .startup        = ks8695uart_startup,
 494        .shutdown       = ks8695uart_shutdown,
 495        .set_termios    = ks8695uart_set_termios,
 496        .type           = ks8695uart_type,
 497        .release_port   = ks8695uart_release_port,
 498        .request_port   = ks8695uart_request_port,
 499        .config_port    = ks8695uart_config_port,
 500        .verify_port    = ks8695uart_verify_port,
 501};
 502
 503static struct uart_port ks8695uart_ports[SERIAL_KS8695_NR] = {
 504        {
 505                .membase        = (void *) KS8695_UART_VA,
 506                .mapbase        = KS8695_UART_VA,
 507                .iotype         = SERIAL_IO_MEM,
 508                .irq            = KS8695_IRQ_UART_TX,
 509                .uartclk        = CLOCK_TICK_RATE * 16,
 510                .fifosize       = 16,
 511                .ops            = &ks8695uart_pops,
 512                .flags          = ASYNC_BOOT_AUTOCONF,
 513                .line           = 0,
 514        }
 515};
 516
 517#ifdef CONFIG_SERIAL_KS8695_CONSOLE
 518static void ks8695_console_putchar(struct uart_port *port, int ch)
 519{
 520        while (!(UART_GET_LSR(port) & URLS_URTHRE))
 521                barrier();
 522
 523        UART_PUT_CHAR(port, ch);
 524}
 525
 526static void ks8695_console_write(struct console *co, const char *s, u_int count)
 527{
 528        struct uart_port *port = ks8695uart_ports + co->index;
 529
 530        uart_console_write(port, s, count, ks8695_console_putchar);
 531}
 532
 533static void __init ks8695_console_get_options(struct uart_port *port, int *baud, int *parity, int *bits)
 534{
 535        unsigned int lcr;
 536
 537        lcr = UART_GET_LCR(port);
 538
 539        switch (lcr & URLC_PARITY) {
 540                case URPE_ODD:
 541                        *parity = 'o';
 542                        break;
 543                case URPE_EVEN:
 544                        *parity = 'e';
 545                        break;
 546                default:
 547                        *parity = 'n';
 548        }
 549
 550        switch (lcr & URLC_URCL) {
 551                case URCL_5:
 552                        *bits = 5;
 553                        break;
 554                case URCL_6:
 555                        *bits = 6;
 556                        break;
 557                case URCL_7:
 558                        *bits = 7;
 559                        break;
 560                default:
 561                        *bits = 8;
 562        }
 563
 564        *baud = port->uartclk / (UART_GET_BRDR(port) & 0x0FFF);
 565        *baud /= 16;
 566        *baud &= 0xFFFFFFF0;
 567}
 568
 569static int __init ks8695_console_setup(struct console *co, char *options)
 570{
 571        struct uart_port *port;
 572        int baud = 115200;
 573        int bits = 8;
 574        int parity = 'n';
 575        int flow = 'n';
 576
 577        /*
 578         * Check whether an invalid uart number has been specified, and
 579         * if so, search for the first available port that does have
 580         * console support.
 581         */
 582        port = uart_get_console(ks8695uart_ports, SERIAL_KS8695_NR, co);
 583
 584        if (options)
 585                uart_parse_options(options, &baud, &parity, &bits, &flow);
 586        else
 587                ks8695_console_get_options(port, &baud, &parity, &bits);
 588
 589        return uart_set_options(port, co, baud, parity, bits, flow);
 590}
 591
 592static struct uart_driver ks8695_reg;
 593
 594static struct console ks8695_console = {
 595        .name           = SERIAL_KS8695_DEVNAME,
 596        .write          = ks8695_console_write,
 597        .device         = uart_console_device,
 598        .setup          = ks8695_console_setup,
 599        .flags          = CON_PRINTBUFFER,
 600        .index          = -1,
 601        .data           = &ks8695_reg,
 602};
 603
 604static int __init ks8695_console_init(void)
 605{
 606        register_console(&ks8695_console);
 607        return 0;
 608}
 609
 610console_initcall(ks8695_console_init);
 611
 612#define KS8695_CONSOLE  &ks8695_console
 613#else
 614#define KS8695_CONSOLE  NULL
 615#endif
 616
 617static struct uart_driver ks8695_reg = {
 618        .owner                  = THIS_MODULE,
 619        .driver_name            = "serial_ks8695",
 620        .dev_name               = SERIAL_KS8695_DEVNAME,
 621        .major                  = SERIAL_KS8695_MAJOR,
 622        .minor                  = SERIAL_KS8695_MINOR,
 623        .nr                     = SERIAL_KS8695_NR,
 624        .cons                   = KS8695_CONSOLE,
 625};
 626
 627static int __init ks8695uart_init(void)
 628{
 629        int i, ret;
 630
 631        printk(KERN_INFO "Serial: Micrel KS8695 UART driver\n");
 632
 633        ret = uart_register_driver(&ks8695_reg);
 634        if (ret)
 635                return ret;
 636
 637        for (i = 0; i < SERIAL_KS8695_NR; i++)
 638                uart_add_one_port(&ks8695_reg, &ks8695uart_ports[0]);
 639
 640        return 0;
 641}
 642
 643static void __exit ks8695uart_exit(void)
 644{
 645        int i;
 646
 647        for (i = 0; i < SERIAL_KS8695_NR; i++)
 648                uart_remove_one_port(&ks8695_reg, &ks8695uart_ports[0]);
 649        uart_unregister_driver(&ks8695_reg);
 650}
 651
 652module_init(ks8695uart_init);
 653module_exit(ks8695uart_exit);
 654
 655MODULE_DESCRIPTION("KS8695 serial port driver");
 656MODULE_AUTHOR("Micrel Inc.");
 657MODULE_LICENSE("GPL");
 658