linux/drivers/tty/serial/bcm63xx_uart.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Derived from many drivers using generic_serial interface.
   4 *
   5 * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
   6 *
   7 *  Serial driver for BCM63xx integrated UART.
   8 *
   9 * Hardware flow control was _not_ tested since I only have RX/TX on
  10 * my board.
  11 */
  12
  13#include <linux/kernel.h>
  14#include <linux/platform_device.h>
  15#include <linux/init.h>
  16#include <linux/delay.h>
  17#include <linux/module.h>
  18#include <linux/console.h>
  19#include <linux/clk.h>
  20#include <linux/tty.h>
  21#include <linux/tty_flip.h>
  22#include <linux/sysrq.h>
  23#include <linux/serial.h>
  24#include <linux/serial_core.h>
  25#include <linux/serial_bcm63xx.h>
  26#include <linux/io.h>
  27#include <linux/of.h>
  28
  29#define BCM63XX_NR_UARTS        2
  30
  31static struct uart_port ports[BCM63XX_NR_UARTS];
  32
  33/*
  34 * rx interrupt mask / stat
  35 *
  36 * mask:
  37 *  - rx fifo full
  38 *  - rx fifo above threshold
  39 *  - rx fifo not empty for too long
  40 */
  41#define UART_RX_INT_MASK        (UART_IR_MASK(UART_IR_RXOVER) |         \
  42                                UART_IR_MASK(UART_IR_RXTHRESH) |        \
  43                                UART_IR_MASK(UART_IR_RXTIMEOUT))
  44
  45#define UART_RX_INT_STAT        (UART_IR_STAT(UART_IR_RXOVER) |         \
  46                                UART_IR_STAT(UART_IR_RXTHRESH) |        \
  47                                UART_IR_STAT(UART_IR_RXTIMEOUT))
  48
  49/*
  50 * tx interrupt mask / stat
  51 *
  52 * mask:
  53 * - tx fifo empty
  54 * - tx fifo below threshold
  55 */
  56#define UART_TX_INT_MASK        (UART_IR_MASK(UART_IR_TXEMPTY) |        \
  57                                UART_IR_MASK(UART_IR_TXTRESH))
  58
  59#define UART_TX_INT_STAT        (UART_IR_STAT(UART_IR_TXEMPTY) |        \
  60                                UART_IR_STAT(UART_IR_TXTRESH))
  61
  62/*
  63 * external input interrupt
  64 *
  65 * mask: any edge on CTS, DCD
  66 */
  67#define UART_EXTINP_INT_MASK    (UART_EXTINP_IRMASK(UART_EXTINP_IR_CTS) | \
  68                                 UART_EXTINP_IRMASK(UART_EXTINP_IR_DCD))
  69
  70/*
  71 * handy uart register accessor
  72 */
  73static inline unsigned int bcm_uart_readl(struct uart_port *port,
  74                                         unsigned int offset)
  75{
  76        return __raw_readl(port->membase + offset);
  77}
  78
  79static inline void bcm_uart_writel(struct uart_port *port,
  80                                  unsigned int value, unsigned int offset)
  81{
  82        __raw_writel(value, port->membase + offset);
  83}
  84
  85/*
  86 * serial core request to check if uart tx fifo is empty
  87 */
  88static unsigned int bcm_uart_tx_empty(struct uart_port *port)
  89{
  90        unsigned int val;
  91
  92        val = bcm_uart_readl(port, UART_IR_REG);
  93        return (val & UART_IR_STAT(UART_IR_TXEMPTY)) ? 1 : 0;
  94}
  95
  96/*
  97 * serial core request to set RTS and DTR pin state and loopback mode
  98 */
  99static void bcm_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
 100{
 101        unsigned int val;
 102
 103        val = bcm_uart_readl(port, UART_MCTL_REG);
 104        val &= ~(UART_MCTL_DTR_MASK | UART_MCTL_RTS_MASK);
 105        /* invert of written value is reflected on the pin */
 106        if (!(mctrl & TIOCM_DTR))
 107                val |= UART_MCTL_DTR_MASK;
 108        if (!(mctrl & TIOCM_RTS))
 109                val |= UART_MCTL_RTS_MASK;
 110        bcm_uart_writel(port, val, UART_MCTL_REG);
 111
 112        val = bcm_uart_readl(port, UART_CTL_REG);
 113        if (mctrl & TIOCM_LOOP)
 114                val |= UART_CTL_LOOPBACK_MASK;
 115        else
 116                val &= ~UART_CTL_LOOPBACK_MASK;
 117        bcm_uart_writel(port, val, UART_CTL_REG);
 118}
 119
 120/*
 121 * serial core request to return RI, CTS, DCD and DSR pin state
 122 */
 123static unsigned int bcm_uart_get_mctrl(struct uart_port *port)
 124{
 125        unsigned int val, mctrl;
 126
 127        mctrl = 0;
 128        val = bcm_uart_readl(port, UART_EXTINP_REG);
 129        if (val & UART_EXTINP_RI_MASK)
 130                mctrl |= TIOCM_RI;
 131        if (val & UART_EXTINP_CTS_MASK)
 132                mctrl |= TIOCM_CTS;
 133        if (val & UART_EXTINP_DCD_MASK)
 134                mctrl |= TIOCM_CD;
 135        if (val & UART_EXTINP_DSR_MASK)
 136                mctrl |= TIOCM_DSR;
 137        return mctrl;
 138}
 139
 140/*
 141 * serial core request to disable tx ASAP (used for flow control)
 142 */
 143static void bcm_uart_stop_tx(struct uart_port *port)
 144{
 145        unsigned int val;
 146
 147        val = bcm_uart_readl(port, UART_CTL_REG);
 148        val &= ~(UART_CTL_TXEN_MASK);
 149        bcm_uart_writel(port, val, UART_CTL_REG);
 150
 151        val = bcm_uart_readl(port, UART_IR_REG);
 152        val &= ~UART_TX_INT_MASK;
 153        bcm_uart_writel(port, val, UART_IR_REG);
 154}
 155
 156/*
 157 * serial core request to (re)enable tx
 158 */
 159static void bcm_uart_start_tx(struct uart_port *port)
 160{
 161        unsigned int val;
 162
 163        val = bcm_uart_readl(port, UART_IR_REG);
 164        val |= UART_TX_INT_MASK;
 165        bcm_uart_writel(port, val, UART_IR_REG);
 166
 167        val = bcm_uart_readl(port, UART_CTL_REG);
 168        val |= UART_CTL_TXEN_MASK;
 169        bcm_uart_writel(port, val, UART_CTL_REG);
 170}
 171
 172/*
 173 * serial core request to stop rx, called before port shutdown
 174 */
 175static void bcm_uart_stop_rx(struct uart_port *port)
 176{
 177        unsigned int val;
 178
 179        val = bcm_uart_readl(port, UART_IR_REG);
 180        val &= ~UART_RX_INT_MASK;
 181        bcm_uart_writel(port, val, UART_IR_REG);
 182}
 183
 184/*
 185 * serial core request to enable modem status interrupt reporting
 186 */
 187static void bcm_uart_enable_ms(struct uart_port *port)
 188{
 189        unsigned int val;
 190
 191        val = bcm_uart_readl(port, UART_IR_REG);
 192        val |= UART_IR_MASK(UART_IR_EXTIP);
 193        bcm_uart_writel(port, val, UART_IR_REG);
 194}
 195
 196/*
 197 * serial core request to start/stop emitting break char
 198 */
 199static void bcm_uart_break_ctl(struct uart_port *port, int ctl)
 200{
 201        unsigned long flags;
 202        unsigned int val;
 203
 204        spin_lock_irqsave(&port->lock, flags);
 205
 206        val = bcm_uart_readl(port, UART_CTL_REG);
 207        if (ctl)
 208                val |= UART_CTL_XMITBRK_MASK;
 209        else
 210                val &= ~UART_CTL_XMITBRK_MASK;
 211        bcm_uart_writel(port, val, UART_CTL_REG);
 212
 213        spin_unlock_irqrestore(&port->lock, flags);
 214}
 215
 216/*
 217 * return port type in string format
 218 */
 219static const char *bcm_uart_type(struct uart_port *port)
 220{
 221        return (port->type == PORT_BCM63XX) ? "bcm63xx_uart" : NULL;
 222}
 223
 224/*
 225 * read all chars in rx fifo and send them to core
 226 */
 227static void bcm_uart_do_rx(struct uart_port *port)
 228{
 229        struct tty_port *tty_port = &port->state->port;
 230        unsigned int max_count;
 231
 232        /* limit number of char read in interrupt, should not be
 233         * higher than fifo size anyway since we're much faster than
 234         * serial port */
 235        max_count = 32;
 236        do {
 237                unsigned int iestat, c, cstat;
 238                char flag;
 239
 240                /* get overrun/fifo empty information from ier
 241                 * register */
 242                iestat = bcm_uart_readl(port, UART_IR_REG);
 243
 244                if (unlikely(iestat & UART_IR_STAT(UART_IR_RXOVER))) {
 245                        unsigned int val;
 246
 247                        /* fifo reset is required to clear
 248                         * interrupt */
 249                        val = bcm_uart_readl(port, UART_CTL_REG);
 250                        val |= UART_CTL_RSTRXFIFO_MASK;
 251                        bcm_uart_writel(port, val, UART_CTL_REG);
 252
 253                        port->icount.overrun++;
 254                        tty_insert_flip_char(tty_port, 0, TTY_OVERRUN);
 255                }
 256
 257                if (!(iestat & UART_IR_STAT(UART_IR_RXNOTEMPTY)))
 258                        break;
 259
 260                cstat = c = bcm_uart_readl(port, UART_FIFO_REG);
 261                port->icount.rx++;
 262                flag = TTY_NORMAL;
 263                c &= 0xff;
 264
 265                if (unlikely((cstat & UART_FIFO_ANYERR_MASK))) {
 266                        /* do stats first */
 267                        if (cstat & UART_FIFO_BRKDET_MASK) {
 268                                port->icount.brk++;
 269                                if (uart_handle_break(port))
 270                                        continue;
 271                        }
 272
 273                        if (cstat & UART_FIFO_PARERR_MASK)
 274                                port->icount.parity++;
 275                        if (cstat & UART_FIFO_FRAMEERR_MASK)
 276                                port->icount.frame++;
 277
 278                        /* update flag wrt read_status_mask */
 279                        cstat &= port->read_status_mask;
 280                        if (cstat & UART_FIFO_BRKDET_MASK)
 281                                flag = TTY_BREAK;
 282                        if (cstat & UART_FIFO_FRAMEERR_MASK)
 283                                flag = TTY_FRAME;
 284                        if (cstat & UART_FIFO_PARERR_MASK)
 285                                flag = TTY_PARITY;
 286                }
 287
 288                if (uart_handle_sysrq_char(port, c))
 289                        continue;
 290
 291
 292                if ((cstat & port->ignore_status_mask) == 0)
 293                        tty_insert_flip_char(tty_port, c, flag);
 294
 295        } while (--max_count);
 296
 297        tty_flip_buffer_push(tty_port);
 298}
 299
 300/*
 301 * fill tx fifo with chars to send, stop when fifo is about to be full
 302 * or when all chars have been sent.
 303 */
 304static void bcm_uart_do_tx(struct uart_port *port)
 305{
 306        struct circ_buf *xmit;
 307        unsigned int val, max_count;
 308
 309        if (port->x_char) {
 310                bcm_uart_writel(port, port->x_char, UART_FIFO_REG);
 311                port->icount.tx++;
 312                port->x_char = 0;
 313                return;
 314        }
 315
 316        if (uart_tx_stopped(port)) {
 317                bcm_uart_stop_tx(port);
 318                return;
 319        }
 320
 321        xmit = &port->state->xmit;
 322        if (uart_circ_empty(xmit))
 323                goto txq_empty;
 324
 325        val = bcm_uart_readl(port, UART_MCTL_REG);
 326        val = (val & UART_MCTL_TXFIFOFILL_MASK) >> UART_MCTL_TXFIFOFILL_SHIFT;
 327        max_count = port->fifosize - val;
 328
 329        while (max_count--) {
 330                unsigned int c;
 331
 332                c = xmit->buf[xmit->tail];
 333                bcm_uart_writel(port, c, UART_FIFO_REG);
 334                xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
 335                port->icount.tx++;
 336                if (uart_circ_empty(xmit))
 337                        break;
 338        }
 339
 340        if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
 341                uart_write_wakeup(port);
 342
 343        if (uart_circ_empty(xmit))
 344                goto txq_empty;
 345        return;
 346
 347txq_empty:
 348        /* nothing to send, disable transmit interrupt */
 349        val = bcm_uart_readl(port, UART_IR_REG);
 350        val &= ~UART_TX_INT_MASK;
 351        bcm_uart_writel(port, val, UART_IR_REG);
 352        return;
 353}
 354
 355/*
 356 * process uart interrupt
 357 */
 358static irqreturn_t bcm_uart_interrupt(int irq, void *dev_id)
 359{
 360        struct uart_port *port;
 361        unsigned int irqstat;
 362
 363        port = dev_id;
 364        spin_lock(&port->lock);
 365
 366        irqstat = bcm_uart_readl(port, UART_IR_REG);
 367        if (irqstat & UART_RX_INT_STAT)
 368                bcm_uart_do_rx(port);
 369
 370        if (irqstat & UART_TX_INT_STAT)
 371                bcm_uart_do_tx(port);
 372
 373        if (irqstat & UART_IR_MASK(UART_IR_EXTIP)) {
 374                unsigned int estat;
 375
 376                estat = bcm_uart_readl(port, UART_EXTINP_REG);
 377                if (estat & UART_EXTINP_IRSTAT(UART_EXTINP_IR_CTS))
 378                        uart_handle_cts_change(port,
 379                                               estat & UART_EXTINP_CTS_MASK);
 380                if (estat & UART_EXTINP_IRSTAT(UART_EXTINP_IR_DCD))
 381                        uart_handle_dcd_change(port,
 382                                               estat & UART_EXTINP_DCD_MASK);
 383        }
 384
 385        spin_unlock(&port->lock);
 386        return IRQ_HANDLED;
 387}
 388
 389/*
 390 * enable rx & tx operation on uart
 391 */
 392static void bcm_uart_enable(struct uart_port *port)
 393{
 394        unsigned int val;
 395
 396        val = bcm_uart_readl(port, UART_CTL_REG);
 397        val |= (UART_CTL_BRGEN_MASK | UART_CTL_TXEN_MASK | UART_CTL_RXEN_MASK);
 398        bcm_uart_writel(port, val, UART_CTL_REG);
 399}
 400
 401/*
 402 * disable rx & tx operation on uart
 403 */
 404static void bcm_uart_disable(struct uart_port *port)
 405{
 406        unsigned int val;
 407
 408        val = bcm_uart_readl(port, UART_CTL_REG);
 409        val &= ~(UART_CTL_BRGEN_MASK | UART_CTL_TXEN_MASK |
 410                 UART_CTL_RXEN_MASK);
 411        bcm_uart_writel(port, val, UART_CTL_REG);
 412}
 413
 414/*
 415 * clear all unread data in rx fifo and unsent data in tx fifo
 416 */
 417static void bcm_uart_flush(struct uart_port *port)
 418{
 419        unsigned int val;
 420
 421        /* empty rx and tx fifo */
 422        val = bcm_uart_readl(port, UART_CTL_REG);
 423        val |= UART_CTL_RSTRXFIFO_MASK | UART_CTL_RSTTXFIFO_MASK;
 424        bcm_uart_writel(port, val, UART_CTL_REG);
 425
 426        /* read any pending char to make sure all irq status are
 427         * cleared */
 428        (void)bcm_uart_readl(port, UART_FIFO_REG);
 429}
 430
 431/*
 432 * serial core request to initialize uart and start rx operation
 433 */
 434static int bcm_uart_startup(struct uart_port *port)
 435{
 436        unsigned int val;
 437        int ret;
 438
 439        /* mask all irq and flush port */
 440        bcm_uart_disable(port);
 441        bcm_uart_writel(port, 0, UART_IR_REG);
 442        bcm_uart_flush(port);
 443
 444        /* clear any pending external input interrupt */
 445        (void)bcm_uart_readl(port, UART_EXTINP_REG);
 446
 447        /* set rx/tx fifo thresh to fifo half size */
 448        val = bcm_uart_readl(port, UART_MCTL_REG);
 449        val &= ~(UART_MCTL_RXFIFOTHRESH_MASK | UART_MCTL_TXFIFOTHRESH_MASK);
 450        val |= (port->fifosize / 2) << UART_MCTL_RXFIFOTHRESH_SHIFT;
 451        val |= (port->fifosize / 2) << UART_MCTL_TXFIFOTHRESH_SHIFT;
 452        bcm_uart_writel(port, val, UART_MCTL_REG);
 453
 454        /* set rx fifo timeout to 1 char time */
 455        val = bcm_uart_readl(port, UART_CTL_REG);
 456        val &= ~UART_CTL_RXTMOUTCNT_MASK;
 457        val |= 1 << UART_CTL_RXTMOUTCNT_SHIFT;
 458        bcm_uart_writel(port, val, UART_CTL_REG);
 459
 460        /* report any edge on dcd and cts */
 461        val = UART_EXTINP_INT_MASK;
 462        val |= UART_EXTINP_DCD_NOSENSE_MASK;
 463        val |= UART_EXTINP_CTS_NOSENSE_MASK;
 464        bcm_uart_writel(port, val, UART_EXTINP_REG);
 465
 466        /* register irq and enable rx interrupts */
 467        ret = request_irq(port->irq, bcm_uart_interrupt, 0,
 468                          dev_name(port->dev), port);
 469        if (ret)
 470                return ret;
 471        bcm_uart_writel(port, UART_RX_INT_MASK, UART_IR_REG);
 472        bcm_uart_enable(port);
 473        return 0;
 474}
 475
 476/*
 477 * serial core request to flush & disable uart
 478 */
 479static void bcm_uart_shutdown(struct uart_port *port)
 480{
 481        unsigned long flags;
 482
 483        spin_lock_irqsave(&port->lock, flags);
 484        bcm_uart_writel(port, 0, UART_IR_REG);
 485        spin_unlock_irqrestore(&port->lock, flags);
 486
 487        bcm_uart_disable(port);
 488        bcm_uart_flush(port);
 489        free_irq(port->irq, port);
 490}
 491
 492/*
 493 * serial core request to change current uart setting
 494 */
 495static void bcm_uart_set_termios(struct uart_port *port,
 496                                 struct ktermios *new,
 497                                 struct ktermios *old)
 498{
 499        unsigned int ctl, baud, quot, ier;
 500        unsigned long flags;
 501        int tries;
 502
 503        spin_lock_irqsave(&port->lock, flags);
 504
 505        /* Drain the hot tub fully before we power it off for the winter. */
 506        for (tries = 3; !bcm_uart_tx_empty(port) && tries; tries--)
 507                mdelay(10);
 508
 509        /* disable uart while changing speed */
 510        bcm_uart_disable(port);
 511        bcm_uart_flush(port);
 512
 513        /* update Control register */
 514        ctl = bcm_uart_readl(port, UART_CTL_REG);
 515        ctl &= ~UART_CTL_BITSPERSYM_MASK;
 516
 517        switch (new->c_cflag & CSIZE) {
 518        case CS5:
 519                ctl |= (0 << UART_CTL_BITSPERSYM_SHIFT);
 520                break;
 521        case CS6:
 522                ctl |= (1 << UART_CTL_BITSPERSYM_SHIFT);
 523                break;
 524        case CS7:
 525                ctl |= (2 << UART_CTL_BITSPERSYM_SHIFT);
 526                break;
 527        default:
 528                ctl |= (3 << UART_CTL_BITSPERSYM_SHIFT);
 529                break;
 530        }
 531
 532        ctl &= ~UART_CTL_STOPBITS_MASK;
 533        if (new->c_cflag & CSTOPB)
 534                ctl |= UART_CTL_STOPBITS_2;
 535        else
 536                ctl |= UART_CTL_STOPBITS_1;
 537
 538        ctl &= ~(UART_CTL_RXPAREN_MASK | UART_CTL_TXPAREN_MASK);
 539        if (new->c_cflag & PARENB)
 540                ctl |= (UART_CTL_RXPAREN_MASK | UART_CTL_TXPAREN_MASK);
 541        ctl &= ~(UART_CTL_RXPAREVEN_MASK | UART_CTL_TXPAREVEN_MASK);
 542        if (new->c_cflag & PARODD)
 543                ctl |= (UART_CTL_RXPAREVEN_MASK | UART_CTL_TXPAREVEN_MASK);
 544        bcm_uart_writel(port, ctl, UART_CTL_REG);
 545
 546        /* update Baudword register */
 547        baud = uart_get_baud_rate(port, new, old, 0, port->uartclk / 16);
 548        quot = uart_get_divisor(port, baud) - 1;
 549        bcm_uart_writel(port, quot, UART_BAUD_REG);
 550
 551        /* update Interrupt register */
 552        ier = bcm_uart_readl(port, UART_IR_REG);
 553
 554        ier &= ~UART_IR_MASK(UART_IR_EXTIP);
 555        if (UART_ENABLE_MS(port, new->c_cflag))
 556                ier |= UART_IR_MASK(UART_IR_EXTIP);
 557
 558        bcm_uart_writel(port, ier, UART_IR_REG);
 559
 560        /* update read/ignore mask */
 561        port->read_status_mask = UART_FIFO_VALID_MASK;
 562        if (new->c_iflag & INPCK) {
 563                port->read_status_mask |= UART_FIFO_FRAMEERR_MASK;
 564                port->read_status_mask |= UART_FIFO_PARERR_MASK;
 565        }
 566        if (new->c_iflag & (IGNBRK | BRKINT))
 567                port->read_status_mask |= UART_FIFO_BRKDET_MASK;
 568
 569        port->ignore_status_mask = 0;
 570        if (new->c_iflag & IGNPAR)
 571                port->ignore_status_mask |= UART_FIFO_PARERR_MASK;
 572        if (new->c_iflag & IGNBRK)
 573                port->ignore_status_mask |= UART_FIFO_BRKDET_MASK;
 574        if (!(new->c_cflag & CREAD))
 575                port->ignore_status_mask |= UART_FIFO_VALID_MASK;
 576
 577        uart_update_timeout(port, new->c_cflag, baud);
 578        bcm_uart_enable(port);
 579        spin_unlock_irqrestore(&port->lock, flags);
 580}
 581
 582/*
 583 * serial core request to claim uart iomem
 584 */
 585static int bcm_uart_request_port(struct uart_port *port)
 586{
 587        /* UARTs always present */
 588        return 0;
 589}
 590
 591/*
 592 * serial core request to release uart iomem
 593 */
 594static void bcm_uart_release_port(struct uart_port *port)
 595{
 596        /* Nothing to release ... */
 597}
 598
 599/*
 600 * serial core request to do any port required autoconfiguration
 601 */
 602static void bcm_uart_config_port(struct uart_port *port, int flags)
 603{
 604        if (flags & UART_CONFIG_TYPE) {
 605                if (bcm_uart_request_port(port))
 606                        return;
 607                port->type = PORT_BCM63XX;
 608        }
 609}
 610
 611/*
 612 * serial core request to check that port information in serinfo are
 613 * suitable
 614 */
 615static int bcm_uart_verify_port(struct uart_port *port,
 616                                struct serial_struct *serinfo)
 617{
 618        if (port->type != PORT_BCM63XX)
 619                return -EINVAL;
 620        if (port->irq != serinfo->irq)
 621                return -EINVAL;
 622        if (port->iotype != serinfo->io_type)
 623                return -EINVAL;
 624        if (port->mapbase != (unsigned long)serinfo->iomem_base)
 625                return -EINVAL;
 626        return 0;
 627}
 628
 629/* serial core callbacks */
 630static const struct uart_ops bcm_uart_ops = {
 631        .tx_empty       = bcm_uart_tx_empty,
 632        .get_mctrl      = bcm_uart_get_mctrl,
 633        .set_mctrl      = bcm_uart_set_mctrl,
 634        .start_tx       = bcm_uart_start_tx,
 635        .stop_tx        = bcm_uart_stop_tx,
 636        .stop_rx        = bcm_uart_stop_rx,
 637        .enable_ms      = bcm_uart_enable_ms,
 638        .break_ctl      = bcm_uart_break_ctl,
 639        .startup        = bcm_uart_startup,
 640        .shutdown       = bcm_uart_shutdown,
 641        .set_termios    = bcm_uart_set_termios,
 642        .type           = bcm_uart_type,
 643        .release_port   = bcm_uart_release_port,
 644        .request_port   = bcm_uart_request_port,
 645        .config_port    = bcm_uart_config_port,
 646        .verify_port    = bcm_uart_verify_port,
 647};
 648
 649
 650
 651#ifdef CONFIG_SERIAL_BCM63XX_CONSOLE
 652static void wait_for_xmitr(struct uart_port *port)
 653{
 654        unsigned int tmout;
 655
 656        /* Wait up to 10ms for the character(s) to be sent. */
 657        tmout = 10000;
 658        while (--tmout) {
 659                unsigned int val;
 660
 661                val = bcm_uart_readl(port, UART_IR_REG);
 662                if (val & UART_IR_STAT(UART_IR_TXEMPTY))
 663                        break;
 664                udelay(1);
 665        }
 666
 667        /* Wait up to 1s for flow control if necessary */
 668        if (port->flags & UPF_CONS_FLOW) {
 669                tmout = 1000000;
 670                while (--tmout) {
 671                        unsigned int val;
 672
 673                        val = bcm_uart_readl(port, UART_EXTINP_REG);
 674                        if (val & UART_EXTINP_CTS_MASK)
 675                                break;
 676                        udelay(1);
 677                }
 678        }
 679}
 680
 681/*
 682 * output given char
 683 */
 684static void bcm_console_putchar(struct uart_port *port, int ch)
 685{
 686        wait_for_xmitr(port);
 687        bcm_uart_writel(port, ch, UART_FIFO_REG);
 688}
 689
 690/*
 691 * console core request to output given string
 692 */
 693static void bcm_console_write(struct console *co, const char *s,
 694                              unsigned int count)
 695{
 696        struct uart_port *port;
 697        unsigned long flags;
 698        int locked;
 699
 700        port = &ports[co->index];
 701
 702        local_irq_save(flags);
 703        if (port->sysrq) {
 704                /* bcm_uart_interrupt() already took the lock */
 705                locked = 0;
 706        } else if (oops_in_progress) {
 707                locked = spin_trylock(&port->lock);
 708        } else {
 709                spin_lock(&port->lock);
 710                locked = 1;
 711        }
 712
 713        /* call helper to deal with \r\n */
 714        uart_console_write(port, s, count, bcm_console_putchar);
 715
 716        /* and wait for char to be transmitted */
 717        wait_for_xmitr(port);
 718
 719        if (locked)
 720                spin_unlock(&port->lock);
 721        local_irq_restore(flags);
 722}
 723
 724/*
 725 * console core request to setup given console, find matching uart
 726 * port and setup it.
 727 */
 728static int bcm_console_setup(struct console *co, char *options)
 729{
 730        struct uart_port *port;
 731        int baud = 9600;
 732        int bits = 8;
 733        int parity = 'n';
 734        int flow = 'n';
 735
 736        if (co->index < 0 || co->index >= BCM63XX_NR_UARTS)
 737                return -EINVAL;
 738        port = &ports[co->index];
 739        if (!port->membase)
 740                return -ENODEV;
 741        if (options)
 742                uart_parse_options(options, &baud, &parity, &bits, &flow);
 743
 744        return uart_set_options(port, co, baud, parity, bits, flow);
 745}
 746
 747static struct uart_driver bcm_uart_driver;
 748
 749static struct console bcm63xx_console = {
 750        .name           = "ttyS",
 751        .write          = bcm_console_write,
 752        .device         = uart_console_device,
 753        .setup          = bcm_console_setup,
 754        .flags          = CON_PRINTBUFFER,
 755        .index          = -1,
 756        .data           = &bcm_uart_driver,
 757};
 758
 759static int __init bcm63xx_console_init(void)
 760{
 761        register_console(&bcm63xx_console);
 762        return 0;
 763}
 764
 765console_initcall(bcm63xx_console_init);
 766
 767static void bcm_early_write(struct console *con, const char *s, unsigned n)
 768{
 769        struct earlycon_device *dev = con->data;
 770
 771        uart_console_write(&dev->port, s, n, bcm_console_putchar);
 772        wait_for_xmitr(&dev->port);
 773}
 774
 775static int __init bcm_early_console_setup(struct earlycon_device *device,
 776                                          const char *opt)
 777{
 778        if (!device->port.membase)
 779                return -ENODEV;
 780
 781        device->con->write = bcm_early_write;
 782        return 0;
 783}
 784
 785OF_EARLYCON_DECLARE(bcm63xx_uart, "brcm,bcm6345-uart", bcm_early_console_setup);
 786
 787#define BCM63XX_CONSOLE (&bcm63xx_console)
 788#else
 789#define BCM63XX_CONSOLE NULL
 790#endif /* CONFIG_SERIAL_BCM63XX_CONSOLE */
 791
 792static struct uart_driver bcm_uart_driver = {
 793        .owner          = THIS_MODULE,
 794        .driver_name    = "bcm63xx_uart",
 795        .dev_name       = "ttyS",
 796        .major          = TTY_MAJOR,
 797        .minor          = 64,
 798        .nr             = BCM63XX_NR_UARTS,
 799        .cons           = BCM63XX_CONSOLE,
 800};
 801
 802/*
 803 * platform driver probe/remove callback
 804 */
 805static int bcm_uart_probe(struct platform_device *pdev)
 806{
 807        struct resource *res_mem, *res_irq;
 808        struct uart_port *port;
 809        struct clk *clk;
 810        int ret;
 811
 812        if (pdev->dev.of_node) {
 813                pdev->id = of_alias_get_id(pdev->dev.of_node, "serial");
 814
 815                if (pdev->id < 0)
 816                        pdev->id = of_alias_get_id(pdev->dev.of_node, "uart");
 817        }
 818
 819        if (pdev->id < 0 || pdev->id >= BCM63XX_NR_UARTS)
 820                return -EINVAL;
 821
 822        port = &ports[pdev->id];
 823        if (port->membase)
 824                return -EBUSY;
 825        memset(port, 0, sizeof(*port));
 826
 827        res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 828        if (!res_mem)
 829                return -ENODEV;
 830
 831        port->mapbase = res_mem->start;
 832        port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
 833        if (IS_ERR(port->membase))
 834                return PTR_ERR(port->membase);
 835
 836        res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 837        if (!res_irq)
 838                return -ENODEV;
 839
 840        clk = clk_get(&pdev->dev, "refclk");
 841        if (IS_ERR(clk) && pdev->dev.of_node)
 842                clk = of_clk_get(pdev->dev.of_node, 0);
 843
 844        if (IS_ERR(clk))
 845                return -ENODEV;
 846
 847        port->iotype = UPIO_MEM;
 848        port->irq = res_irq->start;
 849        port->ops = &bcm_uart_ops;
 850        port->flags = UPF_BOOT_AUTOCONF;
 851        port->dev = &pdev->dev;
 852        port->fifosize = 16;
 853        port->uartclk = clk_get_rate(clk) / 2;
 854        port->line = pdev->id;
 855        port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_BCM63XX_CONSOLE);
 856        clk_put(clk);
 857
 858        ret = uart_add_one_port(&bcm_uart_driver, port);
 859        if (ret) {
 860                ports[pdev->id].membase = NULL;
 861                return ret;
 862        }
 863        platform_set_drvdata(pdev, port);
 864        return 0;
 865}
 866
 867static int bcm_uart_remove(struct platform_device *pdev)
 868{
 869        struct uart_port *port;
 870
 871        port = platform_get_drvdata(pdev);
 872        uart_remove_one_port(&bcm_uart_driver, port);
 873        /* mark port as free */
 874        ports[pdev->id].membase = NULL;
 875        return 0;
 876}
 877
 878static const struct of_device_id bcm63xx_of_match[] = {
 879        { .compatible = "brcm,bcm6345-uart" },
 880        { /* sentinel */ }
 881};
 882MODULE_DEVICE_TABLE(of, bcm63xx_of_match);
 883
 884/*
 885 * platform driver stuff
 886 */
 887static struct platform_driver bcm_uart_platform_driver = {
 888        .probe  = bcm_uart_probe,
 889        .remove = bcm_uart_remove,
 890        .driver = {
 891                .name  = "bcm63xx_uart",
 892                .of_match_table = bcm63xx_of_match,
 893        },
 894};
 895
 896static int __init bcm_uart_init(void)
 897{
 898        int ret;
 899
 900        ret = uart_register_driver(&bcm_uart_driver);
 901        if (ret)
 902                return ret;
 903
 904        ret = platform_driver_register(&bcm_uart_platform_driver);
 905        if (ret)
 906                uart_unregister_driver(&bcm_uart_driver);
 907
 908        return ret;
 909}
 910
 911static void __exit bcm_uart_exit(void)
 912{
 913        platform_driver_unregister(&bcm_uart_platform_driver);
 914        uart_unregister_driver(&bcm_uart_driver);
 915}
 916
 917module_init(bcm_uart_init);
 918module_exit(bcm_uart_exit);
 919
 920MODULE_AUTHOR("Maxime Bizon <mbizon@freebox.fr>");
 921MODULE_DESCRIPTION("Broadcom 63xx integrated uart driver");
 922MODULE_LICENSE("GPL");
 923