linux/drivers/tty/serial/vr41xx_siu.c
<<
>>
Prefs
   1/*
   2 *  Driver for NEC VR4100 series Serial Interface Unit.
   3 *
   4 *  Copyright (C) 2004-2008  Yoichi Yuasa <yuasa@linux-mips.org>
   5 *
   6 *  Based on drivers/serial/8250.c, by Russell King.
   7 *
   8 *  This program is free software; you can redistribute it and/or modify
   9 *  it under the terms of the GNU General Public License as published by
  10 *  the Free Software Foundation; either version 2 of the License, or
  11 *  (at your option) any later version.
  12 *
  13 *  This program is distributed in the hope that it will be useful,
  14 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 *  GNU General Public License for more details.
  17 *
  18 *  You should have received a copy of the GNU General Public License
  19 *  along with this program; if not, write to the Free Software
  20 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  21 */
  22
  23#if defined(CONFIG_SERIAL_VR41XX_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
  24#define SUPPORT_SYSRQ
  25#endif
  26
  27#include <linux/console.h>
  28#include <linux/errno.h>
  29#include <linux/init.h>
  30#include <linux/interrupt.h>
  31#include <linux/ioport.h>
  32#include <linux/module.h>
  33#include <linux/platform_device.h>
  34#include <linux/serial.h>
  35#include <linux/serial_core.h>
  36#include <linux/serial_reg.h>
  37#include <linux/tty.h>
  38#include <linux/tty_flip.h>
  39
  40#include <asm/io.h>
  41#include <asm/vr41xx/siu.h>
  42#include <asm/vr41xx/vr41xx.h>
  43
  44#define SIU_BAUD_BASE   1152000
  45#define SIU_MAJOR       204
  46#define SIU_MINOR_BASE  82
  47
  48#define RX_MAX_COUNT    256
  49#define TX_MAX_COUNT    15
  50
  51#define SIUIRSEL        0x08
  52 #define TMICMODE       0x20
  53 #define TMICTX         0x10
  54 #define IRMSEL         0x0c
  55 #define IRMSEL_HP      0x08
  56 #define IRMSEL_TEMIC   0x04
  57 #define IRMSEL_SHARP   0x00
  58 #define IRUSESEL       0x02
  59 #define SIRSEL         0x01
  60
  61static struct uart_port siu_uart_ports[SIU_PORTS_MAX] = {
  62        [0 ... SIU_PORTS_MAX-1] = {
  63                .lock   = __SPIN_LOCK_UNLOCKED(siu_uart_ports->lock),
  64                .irq    = -1,
  65        },
  66};
  67
  68#ifdef CONFIG_SERIAL_VR41XX_CONSOLE
  69static uint8_t lsr_break_flag[SIU_PORTS_MAX];
  70#endif
  71
  72#define siu_read(port, offset)          readb((port)->membase + (offset))
  73#define siu_write(port, offset, value)  writeb((value), (port)->membase + (offset))
  74
  75void vr41xx_select_siu_interface(siu_interface_t interface)
  76{
  77        struct uart_port *port;
  78        unsigned long flags;
  79        uint8_t irsel;
  80
  81        port = &siu_uart_ports[0];
  82
  83        spin_lock_irqsave(&port->lock, flags);
  84
  85        irsel = siu_read(port, SIUIRSEL);
  86        if (interface == SIU_INTERFACE_IRDA)
  87                irsel |= SIRSEL;
  88        else
  89                irsel &= ~SIRSEL;
  90        siu_write(port, SIUIRSEL, irsel);
  91
  92        spin_unlock_irqrestore(&port->lock, flags);
  93}
  94EXPORT_SYMBOL_GPL(vr41xx_select_siu_interface);
  95
  96void vr41xx_use_irda(irda_use_t use)
  97{
  98        struct uart_port *port;
  99        unsigned long flags;
 100        uint8_t irsel;
 101
 102        port = &siu_uart_ports[0];
 103
 104        spin_lock_irqsave(&port->lock, flags);
 105
 106        irsel = siu_read(port, SIUIRSEL);
 107        if (use == FIR_USE_IRDA)
 108                irsel |= IRUSESEL;
 109        else
 110                irsel &= ~IRUSESEL;
 111        siu_write(port, SIUIRSEL, irsel);
 112
 113        spin_unlock_irqrestore(&port->lock, flags);
 114}
 115EXPORT_SYMBOL_GPL(vr41xx_use_irda);
 116
 117void vr41xx_select_irda_module(irda_module_t module, irda_speed_t speed)
 118{
 119        struct uart_port *port;
 120        unsigned long flags;
 121        uint8_t irsel;
 122
 123        port = &siu_uart_ports[0];
 124
 125        spin_lock_irqsave(&port->lock, flags);
 126
 127        irsel = siu_read(port, SIUIRSEL);
 128        irsel &= ~(IRMSEL | TMICTX | TMICMODE);
 129        switch (module) {
 130        case SHARP_IRDA:
 131                irsel |= IRMSEL_SHARP;
 132                break;
 133        case TEMIC_IRDA:
 134                irsel |= IRMSEL_TEMIC | TMICMODE;
 135                if (speed == IRDA_TX_4MBPS)
 136                        irsel |= TMICTX;
 137                break;
 138        case HP_IRDA:
 139                irsel |= IRMSEL_HP;
 140                break;
 141        default:
 142                break;
 143        }
 144        siu_write(port, SIUIRSEL, irsel);
 145
 146        spin_unlock_irqrestore(&port->lock, flags);
 147}
 148EXPORT_SYMBOL_GPL(vr41xx_select_irda_module);
 149
 150static inline void siu_clear_fifo(struct uart_port *port)
 151{
 152        siu_write(port, UART_FCR, UART_FCR_ENABLE_FIFO);
 153        siu_write(port, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR |
 154                                  UART_FCR_CLEAR_XMIT);
 155        siu_write(port, UART_FCR, 0);
 156}
 157
 158static inline unsigned long siu_port_size(struct uart_port *port)
 159{
 160        switch (port->type) {
 161        case PORT_VR41XX_SIU:
 162                return 11UL;
 163        case PORT_VR41XX_DSIU:
 164                return 8UL;
 165        }
 166
 167        return 0;
 168}
 169
 170static inline unsigned int siu_check_type(struct uart_port *port)
 171{
 172        if (port->line == 0)
 173                return PORT_VR41XX_SIU;
 174        if (port->line == 1 && port->irq != -1)
 175                return PORT_VR41XX_DSIU;
 176
 177        return PORT_UNKNOWN;
 178}
 179
 180static inline const char *siu_type_name(struct uart_port *port)
 181{
 182        switch (port->type) {
 183        case PORT_VR41XX_SIU:
 184                return "SIU";
 185        case PORT_VR41XX_DSIU:
 186                return "DSIU";
 187        }
 188
 189        return NULL;
 190}
 191
 192static unsigned int siu_tx_empty(struct uart_port *port)
 193{
 194        uint8_t lsr;
 195
 196        lsr = siu_read(port, UART_LSR);
 197        if (lsr & UART_LSR_TEMT)
 198                return TIOCSER_TEMT;
 199
 200        return 0;
 201}
 202
 203static void siu_set_mctrl(struct uart_port *port, unsigned int mctrl)
 204{
 205        uint8_t mcr = 0;
 206
 207        if (mctrl & TIOCM_DTR)
 208                mcr |= UART_MCR_DTR;
 209        if (mctrl & TIOCM_RTS)
 210                mcr |= UART_MCR_RTS;
 211        if (mctrl & TIOCM_OUT1)
 212                mcr |= UART_MCR_OUT1;
 213        if (mctrl & TIOCM_OUT2)
 214                mcr |= UART_MCR_OUT2;
 215        if (mctrl & TIOCM_LOOP)
 216                mcr |= UART_MCR_LOOP;
 217
 218        siu_write(port, UART_MCR, mcr);
 219}
 220
 221static unsigned int siu_get_mctrl(struct uart_port *port)
 222{
 223        uint8_t msr;
 224        unsigned int mctrl = 0;
 225
 226        msr = siu_read(port, UART_MSR);
 227        if (msr & UART_MSR_DCD)
 228                mctrl |= TIOCM_CAR;
 229        if (msr & UART_MSR_RI)
 230                mctrl |= TIOCM_RNG;
 231        if (msr & UART_MSR_DSR)
 232                mctrl |= TIOCM_DSR;
 233        if (msr & UART_MSR_CTS)
 234                mctrl |= TIOCM_CTS;
 235
 236        return mctrl;
 237}
 238
 239static void siu_stop_tx(struct uart_port *port)
 240{
 241        unsigned long flags;
 242        uint8_t ier;
 243
 244        spin_lock_irqsave(&port->lock, flags);
 245
 246        ier = siu_read(port, UART_IER);
 247        ier &= ~UART_IER_THRI;
 248        siu_write(port, UART_IER, ier);
 249
 250        spin_unlock_irqrestore(&port->lock, flags);
 251}
 252
 253static void siu_start_tx(struct uart_port *port)
 254{
 255        unsigned long flags;
 256        uint8_t ier;
 257
 258        spin_lock_irqsave(&port->lock, flags);
 259
 260        ier = siu_read(port, UART_IER);
 261        ier |= UART_IER_THRI;
 262        siu_write(port, UART_IER, ier);
 263
 264        spin_unlock_irqrestore(&port->lock, flags);
 265}
 266
 267static void siu_stop_rx(struct uart_port *port)
 268{
 269        unsigned long flags;
 270        uint8_t ier;
 271
 272        spin_lock_irqsave(&port->lock, flags);
 273
 274        ier = siu_read(port, UART_IER);
 275        ier &= ~UART_IER_RLSI;
 276        siu_write(port, UART_IER, ier);
 277
 278        port->read_status_mask &= ~UART_LSR_DR;
 279
 280        spin_unlock_irqrestore(&port->lock, flags);
 281}
 282
 283static void siu_enable_ms(struct uart_port *port)
 284{
 285        unsigned long flags;
 286        uint8_t ier;
 287
 288        spin_lock_irqsave(&port->lock, flags);
 289
 290        ier = siu_read(port, UART_IER);
 291        ier |= UART_IER_MSI;
 292        siu_write(port, UART_IER, ier);
 293
 294        spin_unlock_irqrestore(&port->lock, flags);
 295}
 296
 297static void siu_break_ctl(struct uart_port *port, int ctl)
 298{
 299        unsigned long flags;
 300        uint8_t lcr;
 301
 302        spin_lock_irqsave(&port->lock, flags);
 303
 304        lcr = siu_read(port, UART_LCR);
 305        if (ctl == -1)
 306                lcr |= UART_LCR_SBC;
 307        else
 308                lcr &= ~UART_LCR_SBC;
 309        siu_write(port, UART_LCR, lcr);
 310
 311        spin_unlock_irqrestore(&port->lock, flags);
 312}
 313
 314static inline void receive_chars(struct uart_port *port, uint8_t *status)
 315{
 316        struct tty_struct *tty;
 317        uint8_t lsr, ch;
 318        char flag;
 319        int max_count = RX_MAX_COUNT;
 320
 321        tty = port->state->port.tty;
 322        lsr = *status;
 323
 324        do {
 325                ch = siu_read(port, UART_RX);
 326                port->icount.rx++;
 327                flag = TTY_NORMAL;
 328
 329#ifdef CONFIG_SERIAL_VR41XX_CONSOLE
 330                lsr |= lsr_break_flag[port->line];
 331                lsr_break_flag[port->line] = 0;
 332#endif
 333                if (unlikely(lsr & (UART_LSR_BI | UART_LSR_FE |
 334                                    UART_LSR_PE | UART_LSR_OE))) {
 335                        if (lsr & UART_LSR_BI) {
 336                                lsr &= ~(UART_LSR_FE | UART_LSR_PE);
 337                                port->icount.brk++;
 338
 339                                if (uart_handle_break(port))
 340                                        goto ignore_char;
 341                        }
 342
 343                        if (lsr & UART_LSR_FE)
 344                                port->icount.frame++;
 345                        if (lsr & UART_LSR_PE)
 346                                port->icount.parity++;
 347                        if (lsr & UART_LSR_OE)
 348                                port->icount.overrun++;
 349
 350                        lsr &= port->read_status_mask;
 351                        if (lsr & UART_LSR_BI)
 352                                flag = TTY_BREAK;
 353                        if (lsr & UART_LSR_FE)
 354                                flag = TTY_FRAME;
 355                        if (lsr & UART_LSR_PE)
 356                                flag = TTY_PARITY;
 357                }
 358
 359                if (uart_handle_sysrq_char(port, ch))
 360                        goto ignore_char;
 361
 362                uart_insert_char(port, lsr, UART_LSR_OE, ch, flag);
 363
 364        ignore_char:
 365                lsr = siu_read(port, UART_LSR);
 366        } while ((lsr & UART_LSR_DR) && (max_count-- > 0));
 367
 368        tty_flip_buffer_push(tty);
 369
 370        *status = lsr;
 371}
 372
 373static inline void check_modem_status(struct uart_port *port)
 374{
 375        uint8_t msr;
 376
 377        msr = siu_read(port, UART_MSR);
 378        if ((msr & UART_MSR_ANY_DELTA) == 0)
 379                return;
 380        if (msr & UART_MSR_DDCD)
 381                uart_handle_dcd_change(port, msr & UART_MSR_DCD);
 382        if (msr & UART_MSR_TERI)
 383                port->icount.rng++;
 384        if (msr & UART_MSR_DDSR)
 385                port->icount.dsr++;
 386        if (msr & UART_MSR_DCTS)
 387                uart_handle_cts_change(port, msr & UART_MSR_CTS);
 388
 389        wake_up_interruptible(&port->state->port.delta_msr_wait);
 390}
 391
 392static inline void transmit_chars(struct uart_port *port)
 393{
 394        struct circ_buf *xmit;
 395        int max_count = TX_MAX_COUNT;
 396
 397        xmit = &port->state->xmit;
 398
 399        if (port->x_char) {
 400                siu_write(port, UART_TX, port->x_char);
 401                port->icount.tx++;
 402                port->x_char = 0;
 403                return;
 404        }
 405
 406        if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
 407                siu_stop_tx(port);
 408                return;
 409        }
 410
 411        do {
 412                siu_write(port, UART_TX, xmit->buf[xmit->tail]);
 413                xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
 414                port->icount.tx++;
 415                if (uart_circ_empty(xmit))
 416                        break;
 417        } while (max_count-- > 0);
 418
 419        if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
 420                uart_write_wakeup(port);
 421
 422        if (uart_circ_empty(xmit))
 423                siu_stop_tx(port);
 424}
 425
 426static irqreturn_t siu_interrupt(int irq, void *dev_id)
 427{
 428        struct uart_port *port;
 429        uint8_t iir, lsr;
 430
 431        port = (struct uart_port *)dev_id;
 432
 433        iir = siu_read(port, UART_IIR);
 434        if (iir & UART_IIR_NO_INT)
 435                return IRQ_NONE;
 436
 437        lsr = siu_read(port, UART_LSR);
 438        if (lsr & UART_LSR_DR)
 439                receive_chars(port, &lsr);
 440
 441        check_modem_status(port);
 442
 443        if (lsr & UART_LSR_THRE)
 444                transmit_chars(port);
 445
 446        return IRQ_HANDLED;
 447}
 448
 449static int siu_startup(struct uart_port *port)
 450{
 451        int retval;
 452
 453        if (port->membase == NULL)
 454                return -ENODEV;
 455
 456        siu_clear_fifo(port);
 457
 458        (void)siu_read(port, UART_LSR);
 459        (void)siu_read(port, UART_RX);
 460        (void)siu_read(port, UART_IIR);
 461        (void)siu_read(port, UART_MSR);
 462
 463        if (siu_read(port, UART_LSR) == 0xff)
 464                return -ENODEV;
 465
 466        retval = request_irq(port->irq, siu_interrupt, 0, siu_type_name(port), port);
 467        if (retval)
 468                return retval;
 469
 470        if (port->type == PORT_VR41XX_DSIU)
 471                vr41xx_enable_dsiuint(DSIUINT_ALL);
 472
 473        siu_write(port, UART_LCR, UART_LCR_WLEN8);
 474
 475        spin_lock_irq(&port->lock);
 476        siu_set_mctrl(port, port->mctrl);
 477        spin_unlock_irq(&port->lock);
 478
 479        siu_write(port, UART_IER, UART_IER_RLSI | UART_IER_RDI);
 480
 481        (void)siu_read(port, UART_LSR);
 482        (void)siu_read(port, UART_RX);
 483        (void)siu_read(port, UART_IIR);
 484        (void)siu_read(port, UART_MSR);
 485
 486        return 0;
 487}
 488
 489static void siu_shutdown(struct uart_port *port)
 490{
 491        unsigned long flags;
 492        uint8_t lcr;
 493
 494        siu_write(port, UART_IER, 0);
 495
 496        spin_lock_irqsave(&port->lock, flags);
 497
 498        port->mctrl &= ~TIOCM_OUT2;
 499        siu_set_mctrl(port, port->mctrl);
 500
 501        spin_unlock_irqrestore(&port->lock, flags);
 502
 503        lcr = siu_read(port, UART_LCR);
 504        lcr &= ~UART_LCR_SBC;
 505        siu_write(port, UART_LCR, lcr);
 506
 507        siu_clear_fifo(port);
 508
 509        (void)siu_read(port, UART_RX);
 510
 511        if (port->type == PORT_VR41XX_DSIU)
 512                vr41xx_disable_dsiuint(DSIUINT_ALL);
 513
 514        free_irq(port->irq, port);
 515}
 516
 517static void siu_set_termios(struct uart_port *port, struct ktermios *new,
 518                            struct ktermios *old)
 519{
 520        tcflag_t c_cflag, c_iflag;
 521        uint8_t lcr, fcr, ier;
 522        unsigned int baud, quot;
 523        unsigned long flags;
 524
 525        c_cflag = new->c_cflag;
 526        switch (c_cflag & CSIZE) {
 527        case CS5:
 528                lcr = UART_LCR_WLEN5;
 529                break;
 530        case CS6:
 531                lcr = UART_LCR_WLEN6;
 532                break;
 533        case CS7:
 534                lcr = UART_LCR_WLEN7;
 535                break;
 536        default:
 537                lcr = UART_LCR_WLEN8;
 538                break;
 539        }
 540
 541        if (c_cflag & CSTOPB)
 542                lcr |= UART_LCR_STOP;
 543        if (c_cflag & PARENB)
 544                lcr |= UART_LCR_PARITY;
 545        if ((c_cflag & PARODD) != PARODD)
 546                lcr |= UART_LCR_EPAR;
 547        if (c_cflag & CMSPAR)
 548                lcr |= UART_LCR_SPAR;
 549
 550        baud = uart_get_baud_rate(port, new, old, 0, port->uartclk/16);
 551        quot = uart_get_divisor(port, baud);
 552
 553        fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10;
 554
 555        spin_lock_irqsave(&port->lock, flags);
 556
 557        uart_update_timeout(port, c_cflag, baud);
 558
 559        c_iflag = new->c_iflag;
 560
 561        port->read_status_mask = UART_LSR_THRE | UART_LSR_OE | UART_LSR_DR;
 562        if (c_iflag & INPCK)
 563                port->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
 564        if (c_iflag & (BRKINT | PARMRK))
 565                port->read_status_mask |= UART_LSR_BI;
 566
 567        port->ignore_status_mask = 0;
 568        if (c_iflag & IGNPAR)
 569                port->ignore_status_mask |= UART_LSR_FE | UART_LSR_PE;
 570        if (c_iflag & IGNBRK) {
 571                port->ignore_status_mask |= UART_LSR_BI;
 572                if (c_iflag & IGNPAR)
 573                        port->ignore_status_mask |= UART_LSR_OE;
 574        }
 575
 576        if ((c_cflag & CREAD) == 0)
 577                port->ignore_status_mask |= UART_LSR_DR;
 578
 579        ier = siu_read(port, UART_IER);
 580        ier &= ~UART_IER_MSI;
 581        if (UART_ENABLE_MS(port, c_cflag))
 582                ier |= UART_IER_MSI;
 583        siu_write(port, UART_IER, ier);
 584
 585        siu_write(port, UART_LCR, lcr | UART_LCR_DLAB);
 586
 587        siu_write(port, UART_DLL, (uint8_t)quot);
 588        siu_write(port, UART_DLM, (uint8_t)(quot >> 8));
 589
 590        siu_write(port, UART_LCR, lcr);
 591
 592        siu_write(port, UART_FCR, fcr);
 593
 594        siu_set_mctrl(port, port->mctrl);
 595
 596        spin_unlock_irqrestore(&port->lock, flags);
 597}
 598
 599static void siu_pm(struct uart_port *port, unsigned int state, unsigned int oldstate)
 600{
 601        switch (state) {
 602        case 0:
 603                switch (port->type) {
 604                case PORT_VR41XX_SIU:
 605                        vr41xx_supply_clock(SIU_CLOCK);
 606                        break;
 607                case PORT_VR41XX_DSIU:
 608                        vr41xx_supply_clock(DSIU_CLOCK);
 609                        break;
 610                }
 611                break;
 612        case 3:
 613                switch (port->type) {
 614                case PORT_VR41XX_SIU:
 615                        vr41xx_mask_clock(SIU_CLOCK);
 616                        break;
 617                case PORT_VR41XX_DSIU:
 618                        vr41xx_mask_clock(DSIU_CLOCK);
 619                        break;
 620                }
 621                break;
 622        }
 623}
 624
 625static const char *siu_type(struct uart_port *port)
 626{
 627        return siu_type_name(port);
 628}
 629
 630static void siu_release_port(struct uart_port *port)
 631{
 632        unsigned long size;
 633
 634        if (port->flags & UPF_IOREMAP) {
 635                iounmap(port->membase);
 636                port->membase = NULL;
 637        }
 638
 639        size = siu_port_size(port);
 640        release_mem_region(port->mapbase, size);
 641}
 642
 643static int siu_request_port(struct uart_port *port)
 644{
 645        unsigned long size;
 646        struct resource *res;
 647
 648        size = siu_port_size(port);
 649        res = request_mem_region(port->mapbase, size, siu_type_name(port));
 650        if (res == NULL)
 651                return -EBUSY;
 652
 653        if (port->flags & UPF_IOREMAP) {
 654                port->membase = ioremap(port->mapbase, size);
 655                if (port->membase == NULL) {
 656                        release_resource(res);
 657                        return -ENOMEM;
 658                }
 659        }
 660
 661        return 0;
 662}
 663
 664static void siu_config_port(struct uart_port *port, int flags)
 665{
 666        if (flags & UART_CONFIG_TYPE) {
 667                port->type = siu_check_type(port);
 668                (void)siu_request_port(port);
 669        }
 670}
 671
 672static int siu_verify_port(struct uart_port *port, struct serial_struct *serial)
 673{
 674        if (port->type != PORT_VR41XX_SIU && port->type != PORT_VR41XX_DSIU)
 675                return -EINVAL;
 676        if (port->irq != serial->irq)
 677                return -EINVAL;
 678        if (port->iotype != serial->io_type)
 679                return -EINVAL;
 680        if (port->mapbase != (unsigned long)serial->iomem_base)
 681                return -EINVAL;
 682
 683        return 0;
 684}
 685
 686static struct uart_ops siu_uart_ops = {
 687        .tx_empty       = siu_tx_empty,
 688        .set_mctrl      = siu_set_mctrl,
 689        .get_mctrl      = siu_get_mctrl,
 690        .stop_tx        = siu_stop_tx,
 691        .start_tx       = siu_start_tx,
 692        .stop_rx        = siu_stop_rx,
 693        .enable_ms      = siu_enable_ms,
 694        .break_ctl      = siu_break_ctl,
 695        .startup        = siu_startup,
 696        .shutdown       = siu_shutdown,
 697        .set_termios    = siu_set_termios,
 698        .pm             = siu_pm,
 699        .type           = siu_type,
 700        .release_port   = siu_release_port,
 701        .request_port   = siu_request_port,
 702        .config_port    = siu_config_port,
 703        .verify_port    = siu_verify_port,
 704};
 705
 706static int siu_init_ports(struct platform_device *pdev)
 707{
 708        struct uart_port *port;
 709        struct resource *res;
 710        int *type = pdev->dev.platform_data;
 711        int i;
 712
 713        if (!type)
 714                return 0;
 715
 716        port = siu_uart_ports;
 717        for (i = 0; i < SIU_PORTS_MAX; i++) {
 718                port->type = type[i];
 719                if (port->type == PORT_UNKNOWN)
 720                        continue;
 721                port->irq = platform_get_irq(pdev, i);
 722                port->uartclk = SIU_BAUD_BASE * 16;
 723                port->fifosize = 16;
 724                port->regshift = 0;
 725                port->iotype = UPIO_MEM;
 726                port->flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF;
 727                port->line = i;
 728                res = platform_get_resource(pdev, IORESOURCE_MEM, i);
 729                port->mapbase = res->start;
 730                port++;
 731        }
 732
 733        return i;
 734}
 735
 736#ifdef CONFIG_SERIAL_VR41XX_CONSOLE
 737
 738#define BOTH_EMPTY      (UART_LSR_TEMT | UART_LSR_THRE)
 739
 740static void wait_for_xmitr(struct uart_port *port)
 741{
 742        int timeout = 10000;
 743        uint8_t lsr, msr;
 744
 745        do {
 746                lsr = siu_read(port, UART_LSR);
 747                if (lsr & UART_LSR_BI)
 748                        lsr_break_flag[port->line] = UART_LSR_BI;
 749
 750                if ((lsr & BOTH_EMPTY) == BOTH_EMPTY)
 751                        break;
 752        } while (timeout-- > 0);
 753
 754        if (port->flags & UPF_CONS_FLOW) {
 755                timeout = 1000000;
 756
 757                do {
 758                        msr = siu_read(port, UART_MSR);
 759                        if ((msr & UART_MSR_CTS) != 0)
 760                                break;
 761                } while (timeout-- > 0);
 762        }
 763}
 764
 765static void siu_console_putchar(struct uart_port *port, int ch)
 766{
 767        wait_for_xmitr(port);
 768        siu_write(port, UART_TX, ch);
 769}
 770
 771static void siu_console_write(struct console *con, const char *s, unsigned count)
 772{
 773        struct uart_port *port;
 774        uint8_t ier;
 775
 776        port = &siu_uart_ports[con->index];
 777
 778        ier = siu_read(port, UART_IER);
 779        siu_write(port, UART_IER, 0);
 780
 781        uart_console_write(port, s, count, siu_console_putchar);
 782
 783        wait_for_xmitr(port);
 784        siu_write(port, UART_IER, ier);
 785}
 786
 787static int __init siu_console_setup(struct console *con, char *options)
 788{
 789        struct uart_port *port;
 790        int baud = 9600;
 791        int parity = 'n';
 792        int bits = 8;
 793        int flow = 'n';
 794
 795        if (con->index >= SIU_PORTS_MAX)
 796                con->index = 0;
 797
 798        port = &siu_uart_ports[con->index];
 799        if (port->membase == NULL) {
 800                if (port->mapbase == 0)
 801                        return -ENODEV;
 802                port->membase = ioremap(port->mapbase, siu_port_size(port));
 803        }
 804
 805        if (port->type == PORT_VR41XX_SIU)
 806                vr41xx_select_siu_interface(SIU_INTERFACE_RS232C);
 807
 808        if (options != NULL)
 809                uart_parse_options(options, &baud, &parity, &bits, &flow);
 810
 811        return uart_set_options(port, con, baud, parity, bits, flow);
 812}
 813
 814static struct uart_driver siu_uart_driver;
 815
 816static struct console siu_console = {
 817        .name   = "ttyVR",
 818        .write  = siu_console_write,
 819        .device = uart_console_device,
 820        .setup  = siu_console_setup,
 821        .flags  = CON_PRINTBUFFER,
 822        .index  = -1,
 823        .data   = &siu_uart_driver,
 824};
 825
 826static int __devinit siu_console_init(void)
 827{
 828        struct uart_port *port;
 829        int i;
 830
 831        for (i = 0; i < SIU_PORTS_MAX; i++) {
 832                port = &siu_uart_ports[i];
 833                port->ops = &siu_uart_ops;
 834        }
 835
 836        register_console(&siu_console);
 837
 838        return 0;
 839}
 840
 841console_initcall(siu_console_init);
 842
 843void __init vr41xx_siu_early_setup(struct uart_port *port)
 844{
 845        if (port->type == PORT_UNKNOWN)
 846                return;
 847
 848        siu_uart_ports[port->line].line = port->line;
 849        siu_uart_ports[port->line].type = port->type;
 850        siu_uart_ports[port->line].uartclk = SIU_BAUD_BASE * 16;
 851        siu_uart_ports[port->line].mapbase = port->mapbase;
 852        siu_uart_ports[port->line].mapbase = port->mapbase;
 853        siu_uart_ports[port->line].ops = &siu_uart_ops;
 854}
 855
 856#define SERIAL_VR41XX_CONSOLE   &siu_console
 857#else
 858#define SERIAL_VR41XX_CONSOLE   NULL
 859#endif
 860
 861static struct uart_driver siu_uart_driver = {
 862        .owner          = THIS_MODULE,
 863        .driver_name    = "SIU",
 864        .dev_name       = "ttyVR",
 865        .major          = SIU_MAJOR,
 866        .minor          = SIU_MINOR_BASE,
 867        .cons           = SERIAL_VR41XX_CONSOLE,
 868};
 869
 870static int __devinit siu_probe(struct platform_device *dev)
 871{
 872        struct uart_port *port;
 873        int num, i, retval;
 874
 875        num = siu_init_ports(dev);
 876        if (num <= 0)
 877                return -ENODEV;
 878
 879        siu_uart_driver.nr = num;
 880        retval = uart_register_driver(&siu_uart_driver);
 881        if (retval)
 882                return retval;
 883
 884        for (i = 0; i < num; i++) {
 885                port = &siu_uart_ports[i];
 886                port->ops = &siu_uart_ops;
 887                port->dev = &dev->dev;
 888
 889                retval = uart_add_one_port(&siu_uart_driver, port);
 890                if (retval < 0) {
 891                        port->dev = NULL;
 892                        break;
 893                }
 894        }
 895
 896        if (i == 0 && retval < 0) {
 897                uart_unregister_driver(&siu_uart_driver);
 898                return retval;
 899        }
 900
 901        return 0;
 902}
 903
 904static int __devexit siu_remove(struct platform_device *dev)
 905{
 906        struct uart_port *port;
 907        int i;
 908
 909        for (i = 0; i < siu_uart_driver.nr; i++) {
 910                port = &siu_uart_ports[i];
 911                if (port->dev == &dev->dev) {
 912                        uart_remove_one_port(&siu_uart_driver, port);
 913                        port->dev = NULL;
 914                }
 915        }
 916
 917        uart_unregister_driver(&siu_uart_driver);
 918
 919        return 0;
 920}
 921
 922static int siu_suspend(struct platform_device *dev, pm_message_t state)
 923{
 924        struct uart_port *port;
 925        int i;
 926
 927        for (i = 0; i < siu_uart_driver.nr; i++) {
 928                port = &siu_uart_ports[i];
 929                if ((port->type == PORT_VR41XX_SIU ||
 930                     port->type == PORT_VR41XX_DSIU) && port->dev == &dev->dev)
 931                        uart_suspend_port(&siu_uart_driver, port);
 932
 933        }
 934
 935        return 0;
 936}
 937
 938static int siu_resume(struct platform_device *dev)
 939{
 940        struct uart_port *port;
 941        int i;
 942
 943        for (i = 0; i < siu_uart_driver.nr; i++) {
 944                port = &siu_uart_ports[i];
 945                if ((port->type == PORT_VR41XX_SIU ||
 946                     port->type == PORT_VR41XX_DSIU) && port->dev == &dev->dev)
 947                        uart_resume_port(&siu_uart_driver, port);
 948        }
 949
 950        return 0;
 951}
 952
 953static struct platform_driver siu_device_driver = {
 954        .probe          = siu_probe,
 955        .remove         = __devexit_p(siu_remove),
 956        .suspend        = siu_suspend,
 957        .resume         = siu_resume,
 958        .driver         = {
 959                .name   = "SIU",
 960                .owner  = THIS_MODULE,
 961        },
 962};
 963
 964static int __init vr41xx_siu_init(void)
 965{
 966        return platform_driver_register(&siu_device_driver);
 967}
 968
 969static void __exit vr41xx_siu_exit(void)
 970{
 971        platform_driver_unregister(&siu_device_driver);
 972}
 973
 974module_init(vr41xx_siu_init);
 975module_exit(vr41xx_siu_exit);
 976
 977MODULE_LICENSE("GPL");
 978MODULE_ALIAS("platform:SIU");
 979