linux/drivers/tty/serial/fsl_linflexuart.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * Freescale LINFlexD UART serial port driver
   4 *
   5 * Copyright 2012-2016 Freescale Semiconductor, Inc.
   6 * Copyright 2017-2019 NXP
   7 */
   8
   9#include <linux/console.h>
  10#include <linux/io.h>
  11#include <linux/irq.h>
  12#include <linux/module.h>
  13#include <linux/of.h>
  14#include <linux/of_device.h>
  15#include <linux/serial_core.h>
  16#include <linux/slab.h>
  17#include <linux/tty_flip.h>
  18#include <linux/delay.h>
  19
  20/* All registers are 32-bit width */
  21
  22#define LINCR1  0x0000  /* LIN control register                         */
  23#define LINIER  0x0004  /* LIN interrupt enable register                */
  24#define LINSR   0x0008  /* LIN status register                          */
  25#define LINESR  0x000C  /* LIN error status register                    */
  26#define UARTCR  0x0010  /* UART mode control register                   */
  27#define UARTSR  0x0014  /* UART mode status register                    */
  28#define LINTCSR 0x0018  /* LIN timeout control status register          */
  29#define LINOCR  0x001C  /* LIN output compare register                  */
  30#define LINTOCR 0x0020  /* LIN timeout control register                 */
  31#define LINFBRR 0x0024  /* LIN fractional baud rate register            */
  32#define LINIBRR 0x0028  /* LIN integer baud rate register               */
  33#define LINCFR  0x002C  /* LIN checksum field register                  */
  34#define LINCR2  0x0030  /* LIN control register 2                       */
  35#define BIDR    0x0034  /* Buffer identifier register                   */
  36#define BDRL    0x0038  /* Buffer data register least significant       */
  37#define BDRM    0x003C  /* Buffer data register most significant        */
  38#define IFER    0x0040  /* Identifier filter enable register            */
  39#define IFMI    0x0044  /* Identifier filter match index                */
  40#define IFMR    0x0048  /* Identifier filter mode register              */
  41#define GCR     0x004C  /* Global control register                      */
  42#define UARTPTO 0x0050  /* UART preset timeout register                 */
  43#define UARTCTO 0x0054  /* UART current timeout register                */
  44
  45/*
  46 * Register field definitions
  47 */
  48
  49#define LINFLEXD_LINCR1_INIT            BIT(0)
  50#define LINFLEXD_LINCR1_MME             BIT(4)
  51#define LINFLEXD_LINCR1_BF              BIT(7)
  52
  53#define LINFLEXD_LINSR_LINS_INITMODE    BIT(12)
  54#define LINFLEXD_LINSR_LINS_MASK        (0xF << 12)
  55
  56#define LINFLEXD_LINIER_SZIE            BIT(15)
  57#define LINFLEXD_LINIER_OCIE            BIT(14)
  58#define LINFLEXD_LINIER_BEIE            BIT(13)
  59#define LINFLEXD_LINIER_CEIE            BIT(12)
  60#define LINFLEXD_LINIER_HEIE            BIT(11)
  61#define LINFLEXD_LINIER_FEIE            BIT(8)
  62#define LINFLEXD_LINIER_BOIE            BIT(7)
  63#define LINFLEXD_LINIER_LSIE            BIT(6)
  64#define LINFLEXD_LINIER_WUIE            BIT(5)
  65#define LINFLEXD_LINIER_DBFIE           BIT(4)
  66#define LINFLEXD_LINIER_DBEIETOIE       BIT(3)
  67#define LINFLEXD_LINIER_DRIE            BIT(2)
  68#define LINFLEXD_LINIER_DTIE            BIT(1)
  69#define LINFLEXD_LINIER_HRIE            BIT(0)
  70
  71#define LINFLEXD_UARTCR_OSR_MASK        (0xF << 24)
  72#define LINFLEXD_UARTCR_OSR(uartcr)     (((uartcr) \
  73                                        & LINFLEXD_UARTCR_OSR_MASK) >> 24)
  74
  75#define LINFLEXD_UARTCR_ROSE            BIT(23)
  76
  77#define LINFLEXD_UARTCR_RFBM            BIT(9)
  78#define LINFLEXD_UARTCR_TFBM            BIT(8)
  79#define LINFLEXD_UARTCR_WL1             BIT(7)
  80#define LINFLEXD_UARTCR_PC1             BIT(6)
  81
  82#define LINFLEXD_UARTCR_RXEN            BIT(5)
  83#define LINFLEXD_UARTCR_TXEN            BIT(4)
  84#define LINFLEXD_UARTCR_PC0             BIT(3)
  85
  86#define LINFLEXD_UARTCR_PCE             BIT(2)
  87#define LINFLEXD_UARTCR_WL0             BIT(1)
  88#define LINFLEXD_UARTCR_UART            BIT(0)
  89
  90#define LINFLEXD_UARTSR_SZF             BIT(15)
  91#define LINFLEXD_UARTSR_OCF             BIT(14)
  92#define LINFLEXD_UARTSR_PE3             BIT(13)
  93#define LINFLEXD_UARTSR_PE2             BIT(12)
  94#define LINFLEXD_UARTSR_PE1             BIT(11)
  95#define LINFLEXD_UARTSR_PE0             BIT(10)
  96#define LINFLEXD_UARTSR_RMB             BIT(9)
  97#define LINFLEXD_UARTSR_FEF             BIT(8)
  98#define LINFLEXD_UARTSR_BOF             BIT(7)
  99#define LINFLEXD_UARTSR_RPS             BIT(6)
 100#define LINFLEXD_UARTSR_WUF             BIT(5)
 101#define LINFLEXD_UARTSR_4               BIT(4)
 102
 103#define LINFLEXD_UARTSR_TO              BIT(3)
 104
 105#define LINFLEXD_UARTSR_DRFRFE          BIT(2)
 106#define LINFLEXD_UARTSR_DTFTFF          BIT(1)
 107#define LINFLEXD_UARTSR_NF              BIT(0)
 108#define LINFLEXD_UARTSR_PE              (LINFLEXD_UARTSR_PE0 |\
 109                                         LINFLEXD_UARTSR_PE1 |\
 110                                         LINFLEXD_UARTSR_PE2 |\
 111                                         LINFLEXD_UARTSR_PE3)
 112
 113#define LINFLEX_LDIV_MULTIPLIER         (16)
 114
 115#define DRIVER_NAME     "fsl-linflexuart"
 116#define DEV_NAME        "ttyLF"
 117#define UART_NR         4
 118
 119#define EARLYCON_BUFFER_INITIAL_CAP     8
 120
 121#define PREINIT_DELAY                   2000 /* us */
 122
 123static const struct of_device_id linflex_dt_ids[] = {
 124        {
 125                .compatible = "fsl,s32v234-linflexuart",
 126        },
 127        { /* sentinel */ }
 128};
 129MODULE_DEVICE_TABLE(of, linflex_dt_ids);
 130
 131#ifdef CONFIG_SERIAL_FSL_LINFLEXUART_CONSOLE
 132static struct uart_port *earlycon_port;
 133static bool linflex_earlycon_same_instance;
 134static DEFINE_SPINLOCK(init_lock);
 135static bool during_init;
 136
 137static struct {
 138        char *content;
 139        unsigned int len, cap;
 140} earlycon_buf;
 141#endif
 142
 143static void linflex_stop_tx(struct uart_port *port)
 144{
 145        unsigned long ier;
 146
 147        ier = readl(port->membase + LINIER);
 148        ier &= ~(LINFLEXD_LINIER_DTIE);
 149        writel(ier, port->membase + LINIER);
 150}
 151
 152static void linflex_stop_rx(struct uart_port *port)
 153{
 154        unsigned long ier;
 155
 156        ier = readl(port->membase + LINIER);
 157        writel(ier & ~LINFLEXD_LINIER_DRIE, port->membase + LINIER);
 158}
 159
 160static inline void linflex_transmit_buffer(struct uart_port *sport)
 161{
 162        struct circ_buf *xmit = &sport->state->xmit;
 163        unsigned char c;
 164        unsigned long status;
 165
 166        while (!uart_circ_empty(xmit)) {
 167                c = xmit->buf[xmit->tail];
 168                writeb(c, sport->membase + BDRL);
 169
 170                /* Waiting for data transmission completed. */
 171                while (((status = readl(sport->membase + UARTSR)) &
 172                                        LINFLEXD_UARTSR_DTFTFF) !=
 173                                        LINFLEXD_UARTSR_DTFTFF)
 174                        ;
 175
 176                xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
 177                sport->icount.tx++;
 178
 179                writel(status | LINFLEXD_UARTSR_DTFTFF,
 180                       sport->membase + UARTSR);
 181        }
 182
 183        if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
 184                uart_write_wakeup(sport);
 185
 186        if (uart_circ_empty(xmit))
 187                linflex_stop_tx(sport);
 188}
 189
 190static void linflex_start_tx(struct uart_port *port)
 191{
 192        unsigned long ier;
 193
 194        linflex_transmit_buffer(port);
 195        ier = readl(port->membase + LINIER);
 196        writel(ier | LINFLEXD_LINIER_DTIE, port->membase + LINIER);
 197}
 198
 199static irqreturn_t linflex_txint(int irq, void *dev_id)
 200{
 201        struct uart_port *sport = dev_id;
 202        struct circ_buf *xmit = &sport->state->xmit;
 203        unsigned long flags;
 204        unsigned long status;
 205
 206        spin_lock_irqsave(&sport->lock, flags);
 207
 208        if (sport->x_char) {
 209                writeb(sport->x_char, sport->membase + BDRL);
 210
 211                /* waiting for data transmission completed */
 212                while (((status = readl(sport->membase + UARTSR)) &
 213                        LINFLEXD_UARTSR_DTFTFF) != LINFLEXD_UARTSR_DTFTFF)
 214                        ;
 215
 216                writel(status | LINFLEXD_UARTSR_DTFTFF,
 217                       sport->membase + UARTSR);
 218
 219                goto out;
 220        }
 221
 222        if (uart_circ_empty(xmit) || uart_tx_stopped(sport)) {
 223                linflex_stop_tx(sport);
 224                goto out;
 225        }
 226
 227        linflex_transmit_buffer(sport);
 228
 229        if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
 230                uart_write_wakeup(sport);
 231
 232out:
 233        spin_unlock_irqrestore(&sport->lock, flags);
 234        return IRQ_HANDLED;
 235}
 236
 237static irqreturn_t linflex_rxint(int irq, void *dev_id)
 238{
 239        struct uart_port *sport = dev_id;
 240        unsigned int flg;
 241        struct tty_port *port = &sport->state->port;
 242        unsigned long flags, status;
 243        unsigned char rx;
 244        bool brk;
 245
 246        spin_lock_irqsave(&sport->lock, flags);
 247
 248        status = readl(sport->membase + UARTSR);
 249        while (status & LINFLEXD_UARTSR_RMB) {
 250                rx = readb(sport->membase + BDRM);
 251                brk = false;
 252                flg = TTY_NORMAL;
 253                sport->icount.rx++;
 254
 255                if (status & (LINFLEXD_UARTSR_BOF | LINFLEXD_UARTSR_FEF |
 256                                LINFLEXD_UARTSR_PE)) {
 257                        if (status & LINFLEXD_UARTSR_BOF)
 258                                sport->icount.overrun++;
 259                        if (status & LINFLEXD_UARTSR_FEF) {
 260                                if (!rx) {
 261                                        brk = true;
 262                                        sport->icount.brk++;
 263                                } else
 264                                        sport->icount.frame++;
 265                        }
 266                        if (status & LINFLEXD_UARTSR_PE)
 267                                sport->icount.parity++;
 268                }
 269
 270                writel(status, sport->membase + UARTSR);
 271                status = readl(sport->membase + UARTSR);
 272
 273                if (brk) {
 274                        uart_handle_break(sport);
 275                } else {
 276                        if (uart_handle_sysrq_char(sport, (unsigned char)rx))
 277                                continue;
 278                        tty_insert_flip_char(port, rx, flg);
 279                }
 280        }
 281
 282        spin_unlock_irqrestore(&sport->lock, flags);
 283
 284        tty_flip_buffer_push(port);
 285
 286        return IRQ_HANDLED;
 287}
 288
 289static irqreturn_t linflex_int(int irq, void *dev_id)
 290{
 291        struct uart_port *sport = dev_id;
 292        unsigned long status;
 293
 294        status = readl(sport->membase + UARTSR);
 295
 296        if (status & LINFLEXD_UARTSR_DRFRFE)
 297                linflex_rxint(irq, dev_id);
 298        if (status & LINFLEXD_UARTSR_DTFTFF)
 299                linflex_txint(irq, dev_id);
 300
 301        return IRQ_HANDLED;
 302}
 303
 304/* return TIOCSER_TEMT when transmitter is not busy */
 305static unsigned int linflex_tx_empty(struct uart_port *port)
 306{
 307        unsigned long status;
 308
 309        status = readl(port->membase + UARTSR) & LINFLEXD_UARTSR_DTFTFF;
 310
 311        return status ? TIOCSER_TEMT : 0;
 312}
 313
 314static unsigned int linflex_get_mctrl(struct uart_port *port)
 315{
 316        return 0;
 317}
 318
 319static void linflex_set_mctrl(struct uart_port *port, unsigned int mctrl)
 320{
 321}
 322
 323static void linflex_break_ctl(struct uart_port *port, int break_state)
 324{
 325}
 326
 327static void linflex_setup_watermark(struct uart_port *sport)
 328{
 329        unsigned long cr, ier, cr1;
 330
 331        /* Disable transmission/reception */
 332        ier = readl(sport->membase + LINIER);
 333        ier &= ~(LINFLEXD_LINIER_DRIE | LINFLEXD_LINIER_DTIE);
 334        writel(ier, sport->membase + LINIER);
 335
 336        cr = readl(sport->membase + UARTCR);
 337        cr &= ~(LINFLEXD_UARTCR_RXEN | LINFLEXD_UARTCR_TXEN);
 338        writel(cr, sport->membase + UARTCR);
 339
 340        /* Enter initialization mode by setting INIT bit */
 341
 342        /* set the Linflex in master mode and activate by-pass filter */
 343        cr1 = LINFLEXD_LINCR1_BF | LINFLEXD_LINCR1_MME
 344              | LINFLEXD_LINCR1_INIT;
 345        writel(cr1, sport->membase + LINCR1);
 346
 347        /* wait for init mode entry */
 348        while ((readl(sport->membase + LINSR)
 349                & LINFLEXD_LINSR_LINS_MASK)
 350                != LINFLEXD_LINSR_LINS_INITMODE)
 351                ;
 352
 353        /*
 354         *      UART = 0x1;             - Linflex working in UART mode
 355         *      TXEN = 0x1;             - Enable transmission of data now
 356         *      RXEn = 0x1;             - Receiver enabled
 357         *      WL0 = 0x1;              - 8 bit data
 358         *      PCE = 0x0;              - No parity
 359         */
 360
 361        /* set UART bit to allow writing other bits */
 362        writel(LINFLEXD_UARTCR_UART, sport->membase + UARTCR);
 363
 364        cr = (LINFLEXD_UARTCR_RXEN | LINFLEXD_UARTCR_TXEN |
 365              LINFLEXD_UARTCR_WL0 | LINFLEXD_UARTCR_UART);
 366
 367        writel(cr, sport->membase + UARTCR);
 368
 369        cr1 &= ~(LINFLEXD_LINCR1_INIT);
 370
 371        writel(cr1, sport->membase + LINCR1);
 372
 373        ier = readl(sport->membase + LINIER);
 374        ier |= LINFLEXD_LINIER_DRIE;
 375        ier |= LINFLEXD_LINIER_DTIE;
 376
 377        writel(ier, sport->membase + LINIER);
 378}
 379
 380static int linflex_startup(struct uart_port *port)
 381{
 382        int ret = 0;
 383        unsigned long flags;
 384
 385        spin_lock_irqsave(&port->lock, flags);
 386
 387        linflex_setup_watermark(port);
 388
 389        spin_unlock_irqrestore(&port->lock, flags);
 390
 391        ret = devm_request_irq(port->dev, port->irq, linflex_int, 0,
 392                               DRIVER_NAME, port);
 393
 394        return ret;
 395}
 396
 397static void linflex_shutdown(struct uart_port *port)
 398{
 399        unsigned long ier;
 400        unsigned long flags;
 401
 402        spin_lock_irqsave(&port->lock, flags);
 403
 404        /* disable interrupts */
 405        ier = readl(port->membase + LINIER);
 406        ier &= ~(LINFLEXD_LINIER_DRIE | LINFLEXD_LINIER_DTIE);
 407        writel(ier, port->membase + LINIER);
 408
 409        spin_unlock_irqrestore(&port->lock, flags);
 410
 411        devm_free_irq(port->dev, port->irq, port);
 412}
 413
 414static void
 415linflex_set_termios(struct uart_port *port, struct ktermios *termios,
 416                    struct ktermios *old)
 417{
 418        unsigned long flags;
 419        unsigned long cr, old_cr, cr1;
 420        unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8;
 421
 422        cr = readl(port->membase + UARTCR);
 423        old_cr = cr;
 424
 425        /* Enter initialization mode by setting INIT bit */
 426        cr1 = readl(port->membase + LINCR1);
 427        cr1 |= LINFLEXD_LINCR1_INIT;
 428        writel(cr1, port->membase + LINCR1);
 429
 430        /* wait for init mode entry */
 431        while ((readl(port->membase + LINSR)
 432                & LINFLEXD_LINSR_LINS_MASK)
 433                != LINFLEXD_LINSR_LINS_INITMODE)
 434                ;
 435
 436        /*
 437         * only support CS8 and CS7, and for CS7 must enable PE.
 438         * supported mode:
 439         *      - (7,e/o,1)
 440         *      - (8,n,1)
 441         *      - (8,e/o,1)
 442         */
 443        /* enter the UART into configuration mode */
 444
 445        while ((termios->c_cflag & CSIZE) != CS8 &&
 446               (termios->c_cflag & CSIZE) != CS7) {
 447                termios->c_cflag &= ~CSIZE;
 448                termios->c_cflag |= old_csize;
 449                old_csize = CS8;
 450        }
 451
 452        if ((termios->c_cflag & CSIZE) == CS7) {
 453                /* Word length: WL1WL0:00 */
 454                cr = old_cr & ~LINFLEXD_UARTCR_WL1 & ~LINFLEXD_UARTCR_WL0;
 455        }
 456
 457        if ((termios->c_cflag & CSIZE) == CS8) {
 458                /* Word length: WL1WL0:01 */
 459                cr = (old_cr | LINFLEXD_UARTCR_WL0) & ~LINFLEXD_UARTCR_WL1;
 460        }
 461
 462        if (termios->c_cflag & CMSPAR) {
 463                if ((termios->c_cflag & CSIZE) != CS8) {
 464                        termios->c_cflag &= ~CSIZE;
 465                        termios->c_cflag |= CS8;
 466                }
 467                /* has a space/sticky bit */
 468                cr |= LINFLEXD_UARTCR_WL0;
 469        }
 470
 471        if (termios->c_cflag & CSTOPB)
 472                termios->c_cflag &= ~CSTOPB;
 473
 474        /* parity must be enabled when CS7 to match 8-bits format */
 475        if ((termios->c_cflag & CSIZE) == CS7)
 476                termios->c_cflag |= PARENB;
 477
 478        if ((termios->c_cflag & PARENB)) {
 479                cr |= LINFLEXD_UARTCR_PCE;
 480                if (termios->c_cflag & PARODD)
 481                        cr = (cr | LINFLEXD_UARTCR_PC0) &
 482                             (~LINFLEXD_UARTCR_PC1);
 483                else
 484                        cr = cr & (~LINFLEXD_UARTCR_PC1 &
 485                                   ~LINFLEXD_UARTCR_PC0);
 486        } else {
 487                cr &= ~LINFLEXD_UARTCR_PCE;
 488        }
 489
 490        spin_lock_irqsave(&port->lock, flags);
 491
 492        port->read_status_mask = 0;
 493
 494        if (termios->c_iflag & INPCK)
 495                port->read_status_mask |=       (LINFLEXD_UARTSR_FEF |
 496                                                 LINFLEXD_UARTSR_PE0 |
 497                                                 LINFLEXD_UARTSR_PE1 |
 498                                                 LINFLEXD_UARTSR_PE2 |
 499                                                 LINFLEXD_UARTSR_PE3);
 500        if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
 501                port->read_status_mask |= LINFLEXD_UARTSR_FEF;
 502
 503        /* characters to ignore */
 504        port->ignore_status_mask = 0;
 505        if (termios->c_iflag & IGNPAR)
 506                port->ignore_status_mask |= LINFLEXD_UARTSR_PE;
 507        if (termios->c_iflag & IGNBRK) {
 508                port->ignore_status_mask |= LINFLEXD_UARTSR_PE;
 509                /*
 510                 * if we're ignoring parity and break indicators,
 511                 * ignore overruns too (for real raw support).
 512                 */
 513                if (termios->c_iflag & IGNPAR)
 514                        port->ignore_status_mask |= LINFLEXD_UARTSR_BOF;
 515        }
 516
 517        writel(cr, port->membase + UARTCR);
 518
 519        cr1 &= ~(LINFLEXD_LINCR1_INIT);
 520
 521        writel(cr1, port->membase + LINCR1);
 522
 523        spin_unlock_irqrestore(&port->lock, flags);
 524}
 525
 526static const char *linflex_type(struct uart_port *port)
 527{
 528        return "FSL_LINFLEX";
 529}
 530
 531static void linflex_release_port(struct uart_port *port)
 532{
 533        /* nothing to do */
 534}
 535
 536static int linflex_request_port(struct uart_port *port)
 537{
 538        return 0;
 539}
 540
 541/* configure/auto-configure the port */
 542static void linflex_config_port(struct uart_port *port, int flags)
 543{
 544        if (flags & UART_CONFIG_TYPE)
 545                port->type = PORT_LINFLEXUART;
 546}
 547
 548static const struct uart_ops linflex_pops = {
 549        .tx_empty       = linflex_tx_empty,
 550        .set_mctrl      = linflex_set_mctrl,
 551        .get_mctrl      = linflex_get_mctrl,
 552        .stop_tx        = linflex_stop_tx,
 553        .start_tx       = linflex_start_tx,
 554        .stop_rx        = linflex_stop_rx,
 555        .break_ctl      = linflex_break_ctl,
 556        .startup        = linflex_startup,
 557        .shutdown       = linflex_shutdown,
 558        .set_termios    = linflex_set_termios,
 559        .type           = linflex_type,
 560        .request_port   = linflex_request_port,
 561        .release_port   = linflex_release_port,
 562        .config_port    = linflex_config_port,
 563};
 564
 565static struct uart_port *linflex_ports[UART_NR];
 566
 567#ifdef CONFIG_SERIAL_FSL_LINFLEXUART_CONSOLE
 568static void linflex_console_putchar(struct uart_port *port, int ch)
 569{
 570        unsigned long cr;
 571
 572        cr = readl(port->membase + UARTCR);
 573
 574        writeb(ch, port->membase + BDRL);
 575
 576        if (!(cr & LINFLEXD_UARTCR_TFBM))
 577                while ((readl(port->membase + UARTSR) &
 578                                        LINFLEXD_UARTSR_DTFTFF)
 579                                != LINFLEXD_UARTSR_DTFTFF)
 580                        ;
 581        else
 582                while (readl(port->membase + UARTSR) &
 583                                        LINFLEXD_UARTSR_DTFTFF)
 584                        ;
 585
 586        if (!(cr & LINFLEXD_UARTCR_TFBM)) {
 587                writel((readl(port->membase + UARTSR) |
 588                                        LINFLEXD_UARTSR_DTFTFF),
 589                                        port->membase + UARTSR);
 590        }
 591}
 592
 593static void linflex_earlycon_putchar(struct uart_port *port, int ch)
 594{
 595        unsigned long flags;
 596        char *ret;
 597
 598        if (!linflex_earlycon_same_instance) {
 599                linflex_console_putchar(port, ch);
 600                return;
 601        }
 602
 603        spin_lock_irqsave(&init_lock, flags);
 604        if (!during_init)
 605                goto outside_init;
 606
 607        if (earlycon_buf.len >= 1 << CONFIG_LOG_BUF_SHIFT)
 608                goto init_release;
 609
 610        if (!earlycon_buf.cap) {
 611                earlycon_buf.content = kmalloc(EARLYCON_BUFFER_INITIAL_CAP,
 612                                               GFP_ATOMIC);
 613                earlycon_buf.cap = earlycon_buf.content ?
 614                                   EARLYCON_BUFFER_INITIAL_CAP : 0;
 615        } else if (earlycon_buf.len == earlycon_buf.cap) {
 616                ret = krealloc(earlycon_buf.content, earlycon_buf.cap << 1,
 617                               GFP_ATOMIC);
 618                if (ret) {
 619                        earlycon_buf.content = ret;
 620                        earlycon_buf.cap <<= 1;
 621                }
 622        }
 623
 624        if (earlycon_buf.len < earlycon_buf.cap)
 625                earlycon_buf.content[earlycon_buf.len++] = ch;
 626
 627        goto init_release;
 628
 629outside_init:
 630        linflex_console_putchar(port, ch);
 631init_release:
 632        spin_unlock_irqrestore(&init_lock, flags);
 633}
 634
 635static void linflex_string_write(struct uart_port *sport, const char *s,
 636                                 unsigned int count)
 637{
 638        unsigned long cr, ier = 0;
 639
 640        ier = readl(sport->membase + LINIER);
 641        linflex_stop_tx(sport);
 642
 643        cr = readl(sport->membase + UARTCR);
 644        cr |= (LINFLEXD_UARTCR_TXEN);
 645        writel(cr, sport->membase + UARTCR);
 646
 647        uart_console_write(sport, s, count, linflex_console_putchar);
 648
 649        writel(ier, sport->membase + LINIER);
 650}
 651
 652static void
 653linflex_console_write(struct console *co, const char *s, unsigned int count)
 654{
 655        struct uart_port *sport = linflex_ports[co->index];
 656        unsigned long flags;
 657        int locked = 1;
 658
 659        if (sport->sysrq)
 660                locked = 0;
 661        else if (oops_in_progress)
 662                locked = spin_trylock_irqsave(&sport->lock, flags);
 663        else
 664                spin_lock_irqsave(&sport->lock, flags);
 665
 666        linflex_string_write(sport, s, count);
 667
 668        if (locked)
 669                spin_unlock_irqrestore(&sport->lock, flags);
 670}
 671
 672/*
 673 * if the port was already initialised (eg, by a boot loader),
 674 * try to determine the current setup.
 675 */
 676static void __init
 677linflex_console_get_options(struct uart_port *sport, int *parity, int *bits)
 678{
 679        unsigned long cr;
 680
 681        cr = readl(sport->membase + UARTCR);
 682        cr &= LINFLEXD_UARTCR_RXEN | LINFLEXD_UARTCR_TXEN;
 683
 684        if (!cr)
 685                return;
 686
 687        /* ok, the port was enabled */
 688
 689        *parity = 'n';
 690        if (cr & LINFLEXD_UARTCR_PCE) {
 691                if (cr & LINFLEXD_UARTCR_PC0)
 692                        *parity = 'o';
 693                else
 694                        *parity = 'e';
 695        }
 696
 697        if ((cr & LINFLEXD_UARTCR_WL0) && ((cr & LINFLEXD_UARTCR_WL1) == 0)) {
 698                if (cr & LINFLEXD_UARTCR_PCE)
 699                        *bits = 9;
 700                else
 701                        *bits = 8;
 702        }
 703}
 704
 705static int __init linflex_console_setup(struct console *co, char *options)
 706{
 707        struct uart_port *sport;
 708        int baud = 115200;
 709        int bits = 8;
 710        int parity = 'n';
 711        int flow = 'n';
 712        int ret;
 713        int i;
 714        unsigned long flags;
 715        /*
 716         * check whether an invalid uart number has been specified, and
 717         * if so, search for the first available port that does have
 718         * console support.
 719         */
 720        if (co->index == -1 || co->index >= ARRAY_SIZE(linflex_ports))
 721                co->index = 0;
 722
 723        sport = linflex_ports[co->index];
 724        if (!sport)
 725                return -ENODEV;
 726
 727        if (options)
 728                uart_parse_options(options, &baud, &parity, &bits, &flow);
 729        else
 730                linflex_console_get_options(sport, &parity, &bits);
 731
 732        if (earlycon_port && sport->mapbase == earlycon_port->mapbase) {
 733                linflex_earlycon_same_instance = true;
 734
 735                spin_lock_irqsave(&init_lock, flags);
 736                during_init = true;
 737                spin_unlock_irqrestore(&init_lock, flags);
 738
 739                /* Workaround for character loss or output of many invalid
 740                 * characters, when INIT mode is entered shortly after a
 741                 * character has just been printed.
 742                 */
 743                udelay(PREINIT_DELAY);
 744        }
 745
 746        linflex_setup_watermark(sport);
 747
 748        ret = uart_set_options(sport, co, baud, parity, bits, flow);
 749
 750        if (!linflex_earlycon_same_instance)
 751                goto done;
 752
 753        spin_lock_irqsave(&init_lock, flags);
 754
 755        /* Emptying buffer */
 756        if (earlycon_buf.len) {
 757                for (i = 0; i < earlycon_buf.len; i++)
 758                        linflex_console_putchar(earlycon_port,
 759                                earlycon_buf.content[i]);
 760
 761                kfree(earlycon_buf.content);
 762                earlycon_buf.len = 0;
 763        }
 764
 765        during_init = false;
 766        spin_unlock_irqrestore(&init_lock, flags);
 767
 768done:
 769        return ret;
 770}
 771
 772static struct uart_driver linflex_reg;
 773static struct console linflex_console = {
 774        .name           = DEV_NAME,
 775        .write          = linflex_console_write,
 776        .device         = uart_console_device,
 777        .setup          = linflex_console_setup,
 778        .flags          = CON_PRINTBUFFER,
 779        .index          = -1,
 780        .data           = &linflex_reg,
 781};
 782
 783static void linflex_earlycon_write(struct console *con, const char *s,
 784                                   unsigned int n)
 785{
 786        struct earlycon_device *dev = con->data;
 787
 788        uart_console_write(&dev->port, s, n, linflex_earlycon_putchar);
 789}
 790
 791static int __init linflex_early_console_setup(struct earlycon_device *device,
 792                                              const char *options)
 793{
 794        if (!device->port.membase)
 795                return -ENODEV;
 796
 797        device->con->write = linflex_earlycon_write;
 798        earlycon_port = &device->port;
 799
 800        return 0;
 801}
 802
 803OF_EARLYCON_DECLARE(linflex, "fsl,s32v234-linflexuart",
 804                    linflex_early_console_setup);
 805
 806#define LINFLEX_CONSOLE (&linflex_console)
 807#else
 808#define LINFLEX_CONSOLE NULL
 809#endif
 810
 811static struct uart_driver linflex_reg = {
 812        .owner          = THIS_MODULE,
 813        .driver_name    = DRIVER_NAME,
 814        .dev_name       = DEV_NAME,
 815        .nr             = ARRAY_SIZE(linflex_ports),
 816        .cons           = LINFLEX_CONSOLE,
 817};
 818
 819static int linflex_probe(struct platform_device *pdev)
 820{
 821        struct device_node *np = pdev->dev.of_node;
 822        struct uart_port *sport;
 823        struct resource *res;
 824        int ret;
 825
 826        sport = devm_kzalloc(&pdev->dev, sizeof(*sport), GFP_KERNEL);
 827        if (!sport)
 828                return -ENOMEM;
 829
 830        ret = of_alias_get_id(np, "serial");
 831        if (ret < 0) {
 832                dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret);
 833                return ret;
 834        }
 835        if (ret >= UART_NR) {
 836                dev_err(&pdev->dev, "driver limited to %d serial ports\n",
 837                        UART_NR);
 838                return -ENOMEM;
 839        }
 840
 841        sport->line = ret;
 842
 843        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 844        if (!res)
 845                return -ENODEV;
 846
 847        sport->mapbase = res->start;
 848        sport->membase = devm_ioremap_resource(&pdev->dev, res);
 849        if (IS_ERR(sport->membase))
 850                return PTR_ERR(sport->membase);
 851
 852        sport->dev = &pdev->dev;
 853        sport->type = PORT_LINFLEXUART;
 854        sport->iotype = UPIO_MEM;
 855        sport->irq = platform_get_irq(pdev, 0);
 856        sport->ops = &linflex_pops;
 857        sport->flags = UPF_BOOT_AUTOCONF;
 858        sport->has_sysrq = IS_ENABLED(CONFIG_SERIAL_FSL_LINFLEXUART_CONSOLE);
 859
 860        linflex_ports[sport->line] = sport;
 861
 862        platform_set_drvdata(pdev, sport);
 863
 864        ret = uart_add_one_port(&linflex_reg, sport);
 865        if (ret)
 866                return ret;
 867
 868        return 0;
 869}
 870
 871static int linflex_remove(struct platform_device *pdev)
 872{
 873        struct uart_port *sport = platform_get_drvdata(pdev);
 874
 875        uart_remove_one_port(&linflex_reg, sport);
 876
 877        return 0;
 878}
 879
 880#ifdef CONFIG_PM_SLEEP
 881static int linflex_suspend(struct device *dev)
 882{
 883        struct uart_port *sport = dev_get_drvdata(dev);
 884
 885        uart_suspend_port(&linflex_reg, sport);
 886
 887        return 0;
 888}
 889
 890static int linflex_resume(struct device *dev)
 891{
 892        struct uart_port *sport = dev_get_drvdata(dev);
 893
 894        uart_resume_port(&linflex_reg, sport);
 895
 896        return 0;
 897}
 898#endif
 899
 900static SIMPLE_DEV_PM_OPS(linflex_pm_ops, linflex_suspend, linflex_resume);
 901
 902static struct platform_driver linflex_driver = {
 903        .probe          = linflex_probe,
 904        .remove         = linflex_remove,
 905        .driver         = {
 906                .name   = DRIVER_NAME,
 907                .of_match_table = linflex_dt_ids,
 908                .pm     = &linflex_pm_ops,
 909        },
 910};
 911
 912static int __init linflex_serial_init(void)
 913{
 914        int ret;
 915
 916        ret = uart_register_driver(&linflex_reg);
 917        if (ret)
 918                return ret;
 919
 920        ret = platform_driver_register(&linflex_driver);
 921        if (ret)
 922                uart_unregister_driver(&linflex_reg);
 923
 924        return ret;
 925}
 926
 927static void __exit linflex_serial_exit(void)
 928{
 929        platform_driver_unregister(&linflex_driver);
 930        uart_unregister_driver(&linflex_reg);
 931}
 932
 933module_init(linflex_serial_init);
 934module_exit(linflex_serial_exit);
 935
 936MODULE_DESCRIPTION("Freescale LINFlexD serial port driver");
 937MODULE_LICENSE("GPL v2");
 938