linux/drivers/tty/serial/apbuart.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 *  Driver for GRLIB serial ports (APBUART)
   4 *
   5 *  Based on linux/drivers/serial/amba.c
   6 *
   7 *  Copyright (C) 2000 Deep Blue Solutions Ltd.
   8 *  Copyright (C) 2003 Konrad Eisele <eiselekd@web.de>
   9 *  Copyright (C) 2006 Daniel Hellstrom <daniel@gaisler.com>, Aeroflex Gaisler AB
  10 *  Copyright (C) 2008 Gilead Kutnick <kutnickg@zin-tech.com>
  11 *  Copyright (C) 2009 Kristoffer Glembo <kristoffer@gaisler.com>, Aeroflex Gaisler AB
  12 */
  13
  14#include <linux/module.h>
  15#include <linux/tty.h>
  16#include <linux/tty_flip.h>
  17#include <linux/ioport.h>
  18#include <linux/init.h>
  19#include <linux/serial.h>
  20#include <linux/console.h>
  21#include <linux/sysrq.h>
  22#include <linux/kthread.h>
  23#include <linux/device.h>
  24#include <linux/of.h>
  25#include <linux/of_device.h>
  26#include <linux/of_platform.h>
  27#include <linux/of_irq.h>
  28#include <linux/platform_device.h>
  29#include <linux/io.h>
  30#include <linux/serial_core.h>
  31#include <asm/irq.h>
  32
  33#include "apbuart.h"
  34
  35#define SERIAL_APBUART_MAJOR    TTY_MAJOR
  36#define SERIAL_APBUART_MINOR    64
  37#define UART_DUMMY_RSR_RX       0x8000  /* for ignore all read */
  38
  39static void apbuart_tx_chars(struct uart_port *port);
  40
  41static void apbuart_stop_tx(struct uart_port *port)
  42{
  43        unsigned int cr;
  44
  45        cr = UART_GET_CTRL(port);
  46        cr &= ~UART_CTRL_TI;
  47        UART_PUT_CTRL(port, cr);
  48}
  49
  50static void apbuart_start_tx(struct uart_port *port)
  51{
  52        unsigned int cr;
  53
  54        cr = UART_GET_CTRL(port);
  55        cr |= UART_CTRL_TI;
  56        UART_PUT_CTRL(port, cr);
  57
  58        if (UART_GET_STATUS(port) & UART_STATUS_THE)
  59                apbuart_tx_chars(port);
  60}
  61
  62static void apbuart_stop_rx(struct uart_port *port)
  63{
  64        unsigned int cr;
  65
  66        cr = UART_GET_CTRL(port);
  67        cr &= ~(UART_CTRL_RI);
  68        UART_PUT_CTRL(port, cr);
  69}
  70
  71static void apbuart_rx_chars(struct uart_port *port)
  72{
  73        unsigned int status, ch, rsr, flag;
  74        unsigned int max_chars = port->fifosize;
  75
  76        status = UART_GET_STATUS(port);
  77
  78        while (UART_RX_DATA(status) && (max_chars--)) {
  79
  80                ch = UART_GET_CHAR(port);
  81                flag = TTY_NORMAL;
  82
  83                port->icount.rx++;
  84
  85                rsr = UART_GET_STATUS(port) | UART_DUMMY_RSR_RX;
  86                UART_PUT_STATUS(port, 0);
  87                if (rsr & UART_STATUS_ERR) {
  88
  89                        if (rsr & UART_STATUS_BR) {
  90                                rsr &= ~(UART_STATUS_FE | UART_STATUS_PE);
  91                                port->icount.brk++;
  92                                if (uart_handle_break(port))
  93                                        goto ignore_char;
  94                        } else if (rsr & UART_STATUS_PE) {
  95                                port->icount.parity++;
  96                        } else if (rsr & UART_STATUS_FE) {
  97                                port->icount.frame++;
  98                        }
  99                        if (rsr & UART_STATUS_OE)
 100                                port->icount.overrun++;
 101
 102                        rsr &= port->read_status_mask;
 103
 104                        if (rsr & UART_STATUS_PE)
 105                                flag = TTY_PARITY;
 106                        else if (rsr & UART_STATUS_FE)
 107                                flag = TTY_FRAME;
 108                }
 109
 110                if (uart_handle_sysrq_char(port, ch))
 111                        goto ignore_char;
 112
 113                uart_insert_char(port, rsr, UART_STATUS_OE, ch, flag);
 114
 115
 116              ignore_char:
 117                status = UART_GET_STATUS(port);
 118        }
 119
 120        tty_flip_buffer_push(&port->state->port);
 121}
 122
 123static void apbuart_tx_chars(struct uart_port *port)
 124{
 125        struct circ_buf *xmit = &port->state->xmit;
 126        int count;
 127
 128        if (port->x_char) {
 129                UART_PUT_CHAR(port, port->x_char);
 130                port->icount.tx++;
 131                port->x_char = 0;
 132                return;
 133        }
 134
 135        if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
 136                apbuart_stop_tx(port);
 137                return;
 138        }
 139
 140        /* amba: fill FIFO */
 141        count = port->fifosize >> 1;
 142        do {
 143                UART_PUT_CHAR(port, xmit->buf[xmit->tail]);
 144                xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
 145                port->icount.tx++;
 146                if (uart_circ_empty(xmit))
 147                        break;
 148        } while (--count > 0);
 149
 150        if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
 151                uart_write_wakeup(port);
 152
 153        if (uart_circ_empty(xmit))
 154                apbuart_stop_tx(port);
 155}
 156
 157static irqreturn_t apbuart_int(int irq, void *dev_id)
 158{
 159        struct uart_port *port = dev_id;
 160        unsigned int status;
 161
 162        spin_lock(&port->lock);
 163
 164        status = UART_GET_STATUS(port);
 165        if (status & UART_STATUS_DR)
 166                apbuart_rx_chars(port);
 167        if (status & UART_STATUS_THE)
 168                apbuart_tx_chars(port);
 169
 170        spin_unlock(&port->lock);
 171
 172        return IRQ_HANDLED;
 173}
 174
 175static unsigned int apbuart_tx_empty(struct uart_port *port)
 176{
 177        unsigned int status = UART_GET_STATUS(port);
 178        return status & UART_STATUS_THE ? TIOCSER_TEMT : 0;
 179}
 180
 181static unsigned int apbuart_get_mctrl(struct uart_port *port)
 182{
 183        /* The GRLIB APBUART handles flow control in hardware */
 184        return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
 185}
 186
 187static void apbuart_set_mctrl(struct uart_port *port, unsigned int mctrl)
 188{
 189        /* The GRLIB APBUART handles flow control in hardware */
 190}
 191
 192static void apbuart_break_ctl(struct uart_port *port, int break_state)
 193{
 194        /* We don't support sending break */
 195}
 196
 197static int apbuart_startup(struct uart_port *port)
 198{
 199        int retval;
 200        unsigned int cr;
 201
 202        /* Allocate the IRQ */
 203        retval = request_irq(port->irq, apbuart_int, 0, "apbuart", port);
 204        if (retval)
 205                return retval;
 206
 207        /* Finally, enable interrupts */
 208        cr = UART_GET_CTRL(port);
 209        UART_PUT_CTRL(port,
 210                      cr | UART_CTRL_RE | UART_CTRL_TE |
 211                      UART_CTRL_RI | UART_CTRL_TI);
 212
 213        return 0;
 214}
 215
 216static void apbuart_shutdown(struct uart_port *port)
 217{
 218        unsigned int cr;
 219
 220        /* disable all interrupts, disable the port */
 221        cr = UART_GET_CTRL(port);
 222        UART_PUT_CTRL(port,
 223                      cr & ~(UART_CTRL_RE | UART_CTRL_TE |
 224                             UART_CTRL_RI | UART_CTRL_TI));
 225
 226        /* Free the interrupt */
 227        free_irq(port->irq, port);
 228}
 229
 230static void apbuart_set_termios(struct uart_port *port,
 231                                struct ktermios *termios, struct ktermios *old)
 232{
 233        unsigned int cr;
 234        unsigned long flags;
 235        unsigned int baud, quot;
 236
 237        /* Ask the core to calculate the divisor for us. */
 238        baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16);
 239        if (baud == 0)
 240                panic("invalid baudrate %i\n", port->uartclk / 16);
 241
 242        /* uart_get_divisor calc a *16 uart freq, apbuart is *8 */
 243        quot = (uart_get_divisor(port, baud)) * 2;
 244        cr = UART_GET_CTRL(port);
 245        cr &= ~(UART_CTRL_PE | UART_CTRL_PS);
 246
 247        if (termios->c_cflag & PARENB) {
 248                cr |= UART_CTRL_PE;
 249                if ((termios->c_cflag & PARODD))
 250                        cr |= UART_CTRL_PS;
 251        }
 252
 253        /* Enable flow control. */
 254        if (termios->c_cflag & CRTSCTS)
 255                cr |= UART_CTRL_FL;
 256
 257        spin_lock_irqsave(&port->lock, flags);
 258
 259        /* Update the per-port timeout. */
 260        uart_update_timeout(port, termios->c_cflag, baud);
 261
 262        port->read_status_mask = UART_STATUS_OE;
 263        if (termios->c_iflag & INPCK)
 264                port->read_status_mask |= UART_STATUS_FE | UART_STATUS_PE;
 265
 266        /* Characters to ignore */
 267        port->ignore_status_mask = 0;
 268        if (termios->c_iflag & IGNPAR)
 269                port->ignore_status_mask |= UART_STATUS_FE | UART_STATUS_PE;
 270
 271        /* Ignore all characters if CREAD is not set. */
 272        if ((termios->c_cflag & CREAD) == 0)
 273                port->ignore_status_mask |= UART_DUMMY_RSR_RX;
 274
 275        /* Set baud rate */
 276        quot -= 1;
 277        UART_PUT_SCAL(port, quot);
 278        UART_PUT_CTRL(port, cr);
 279
 280        spin_unlock_irqrestore(&port->lock, flags);
 281}
 282
 283static const char *apbuart_type(struct uart_port *port)
 284{
 285        return port->type == PORT_APBUART ? "GRLIB/APBUART" : NULL;
 286}
 287
 288static void apbuart_release_port(struct uart_port *port)
 289{
 290        release_mem_region(port->mapbase, 0x100);
 291}
 292
 293static int apbuart_request_port(struct uart_port *port)
 294{
 295        return request_mem_region(port->mapbase, 0x100, "grlib-apbuart")
 296            != NULL ? 0 : -EBUSY;
 297        return 0;
 298}
 299
 300/* Configure/autoconfigure the port */
 301static void apbuart_config_port(struct uart_port *port, int flags)
 302{
 303        if (flags & UART_CONFIG_TYPE) {
 304                port->type = PORT_APBUART;
 305                apbuart_request_port(port);
 306        }
 307}
 308
 309/* Verify the new serial_struct (for TIOCSSERIAL) */
 310static int apbuart_verify_port(struct uart_port *port,
 311                               struct serial_struct *ser)
 312{
 313        int ret = 0;
 314        if (ser->type != PORT_UNKNOWN && ser->type != PORT_APBUART)
 315                ret = -EINVAL;
 316        if (ser->irq < 0 || ser->irq >= NR_IRQS)
 317                ret = -EINVAL;
 318        if (ser->baud_base < 9600)
 319                ret = -EINVAL;
 320        return ret;
 321}
 322
 323static const struct uart_ops grlib_apbuart_ops = {
 324        .tx_empty = apbuart_tx_empty,
 325        .set_mctrl = apbuart_set_mctrl,
 326        .get_mctrl = apbuart_get_mctrl,
 327        .stop_tx = apbuart_stop_tx,
 328        .start_tx = apbuart_start_tx,
 329        .stop_rx = apbuart_stop_rx,
 330        .break_ctl = apbuart_break_ctl,
 331        .startup = apbuart_startup,
 332        .shutdown = apbuart_shutdown,
 333        .set_termios = apbuart_set_termios,
 334        .type = apbuart_type,
 335        .release_port = apbuart_release_port,
 336        .request_port = apbuart_request_port,
 337        .config_port = apbuart_config_port,
 338        .verify_port = apbuart_verify_port,
 339};
 340
 341static struct uart_port grlib_apbuart_ports[UART_NR];
 342static struct device_node *grlib_apbuart_nodes[UART_NR];
 343
 344static int apbuart_scan_fifo_size(struct uart_port *port, int portnumber)
 345{
 346        int ctrl, loop = 0;
 347        int status;
 348        int fifosize;
 349        unsigned long flags;
 350
 351        ctrl = UART_GET_CTRL(port);
 352
 353        /*
 354         * Enable the transceiver and wait for it to be ready to send data.
 355         * Clear interrupts so that this process will not be externally
 356         * interrupted in the middle (which can cause the transceiver to
 357         * drain prematurely).
 358         */
 359
 360        local_irq_save(flags);
 361
 362        UART_PUT_CTRL(port, ctrl | UART_CTRL_TE);
 363
 364        while (!UART_TX_READY(UART_GET_STATUS(port)))
 365                loop++;
 366
 367        /*
 368         * Disable the transceiver so data isn't actually sent during the
 369         * actual test.
 370         */
 371
 372        UART_PUT_CTRL(port, ctrl & ~(UART_CTRL_TE));
 373
 374        fifosize = 1;
 375        UART_PUT_CHAR(port, 0);
 376
 377        /*
 378         * So long as transmitting a character increments the tranceivier FIFO
 379         * length the FIFO must be at least that big. These bytes will
 380         * automatically drain off of the FIFO.
 381         */
 382
 383        status = UART_GET_STATUS(port);
 384        while (((status >> 20) & 0x3F) == fifosize) {
 385                fifosize++;
 386                UART_PUT_CHAR(port, 0);
 387                status = UART_GET_STATUS(port);
 388        }
 389
 390        fifosize--;
 391
 392        UART_PUT_CTRL(port, ctrl);
 393        local_irq_restore(flags);
 394
 395        if (fifosize == 0)
 396                fifosize = 1;
 397
 398        return fifosize;
 399}
 400
 401static void apbuart_flush_fifo(struct uart_port *port)
 402{
 403        int i;
 404
 405        for (i = 0; i < port->fifosize; i++)
 406                UART_GET_CHAR(port);
 407}
 408
 409
 410/* ======================================================================== */
 411/* Console driver, if enabled                                               */
 412/* ======================================================================== */
 413
 414#ifdef CONFIG_SERIAL_GRLIB_GAISLER_APBUART_CONSOLE
 415
 416static void apbuart_console_putchar(struct uart_port *port, int ch)
 417{
 418        unsigned int status;
 419        do {
 420                status = UART_GET_STATUS(port);
 421        } while (!UART_TX_READY(status));
 422        UART_PUT_CHAR(port, ch);
 423}
 424
 425static void
 426apbuart_console_write(struct console *co, const char *s, unsigned int count)
 427{
 428        struct uart_port *port = &grlib_apbuart_ports[co->index];
 429        unsigned int status, old_cr, new_cr;
 430
 431        /* First save the CR then disable the interrupts */
 432        old_cr = UART_GET_CTRL(port);
 433        new_cr = old_cr & ~(UART_CTRL_RI | UART_CTRL_TI);
 434        UART_PUT_CTRL(port, new_cr);
 435
 436        uart_console_write(port, s, count, apbuart_console_putchar);
 437
 438        /*
 439         *      Finally, wait for transmitter to become empty
 440         *      and restore the TCR
 441         */
 442        do {
 443                status = UART_GET_STATUS(port);
 444        } while (!UART_TX_READY(status));
 445        UART_PUT_CTRL(port, old_cr);
 446}
 447
 448static void __init
 449apbuart_console_get_options(struct uart_port *port, int *baud,
 450                            int *parity, int *bits)
 451{
 452        if (UART_GET_CTRL(port) & (UART_CTRL_RE | UART_CTRL_TE)) {
 453
 454                unsigned int quot, status;
 455                status = UART_GET_STATUS(port);
 456
 457                *parity = 'n';
 458                if (status & UART_CTRL_PE) {
 459                        if ((status & UART_CTRL_PS) == 0)
 460                                *parity = 'e';
 461                        else
 462                                *parity = 'o';
 463                }
 464
 465                *bits = 8;
 466                quot = UART_GET_SCAL(port) / 8;
 467                *baud = port->uartclk / (16 * (quot + 1));
 468        }
 469}
 470
 471static int __init apbuart_console_setup(struct console *co, char *options)
 472{
 473        struct uart_port *port;
 474        int baud = 38400;
 475        int bits = 8;
 476        int parity = 'n';
 477        int flow = 'n';
 478
 479        pr_debug("apbuart_console_setup co=%p, co->index=%i, options=%s\n",
 480                 co, co->index, options);
 481
 482        /*
 483         * Check whether an invalid uart number has been specified, and
 484         * if so, search for the first available port that does have
 485         * console support.
 486         */
 487        if (co->index >= grlib_apbuart_port_nr)
 488                co->index = 0;
 489
 490        port = &grlib_apbuart_ports[co->index];
 491
 492        spin_lock_init(&port->lock);
 493
 494        if (options)
 495                uart_parse_options(options, &baud, &parity, &bits, &flow);
 496        else
 497                apbuart_console_get_options(port, &baud, &parity, &bits);
 498
 499        return uart_set_options(port, co, baud, parity, bits, flow);
 500}
 501
 502static struct uart_driver grlib_apbuart_driver;
 503
 504static struct console grlib_apbuart_console = {
 505        .name = "ttyS",
 506        .write = apbuart_console_write,
 507        .device = uart_console_device,
 508        .setup = apbuart_console_setup,
 509        .flags = CON_PRINTBUFFER,
 510        .index = -1,
 511        .data = &grlib_apbuart_driver,
 512};
 513
 514
 515static int grlib_apbuart_configure(void);
 516
 517static int __init apbuart_console_init(void)
 518{
 519        if (grlib_apbuart_configure())
 520                return -ENODEV;
 521        register_console(&grlib_apbuart_console);
 522        return 0;
 523}
 524
 525console_initcall(apbuart_console_init);
 526
 527#define APBUART_CONSOLE (&grlib_apbuart_console)
 528#else
 529#define APBUART_CONSOLE NULL
 530#endif
 531
 532static struct uart_driver grlib_apbuart_driver = {
 533        .owner = THIS_MODULE,
 534        .driver_name = "serial",
 535        .dev_name = "ttyS",
 536        .major = SERIAL_APBUART_MAJOR,
 537        .minor = SERIAL_APBUART_MINOR,
 538        .nr = UART_NR,
 539        .cons = APBUART_CONSOLE,
 540};
 541
 542
 543/* ======================================================================== */
 544/* OF Platform Driver                                                       */
 545/* ======================================================================== */
 546
 547static int apbuart_probe(struct platform_device *op)
 548{
 549        int i;
 550        struct uart_port *port = NULL;
 551
 552        for (i = 0; i < grlib_apbuart_port_nr; i++) {
 553                if (op->dev.of_node == grlib_apbuart_nodes[i])
 554                        break;
 555        }
 556
 557        port = &grlib_apbuart_ports[i];
 558        port->dev = &op->dev;
 559        port->irq = op->archdata.irqs[0];
 560
 561        uart_add_one_port(&grlib_apbuart_driver, (struct uart_port *) port);
 562
 563        apbuart_flush_fifo((struct uart_port *) port);
 564
 565        printk(KERN_INFO "grlib-apbuart at 0x%llx, irq %d\n",
 566               (unsigned long long) port->mapbase, port->irq);
 567        return 0;
 568}
 569
 570static const struct of_device_id apbuart_match[] = {
 571        {
 572         .name = "GAISLER_APBUART",
 573         },
 574        {
 575         .name = "01_00c",
 576         },
 577        {},
 578};
 579MODULE_DEVICE_TABLE(of, apbuart_match);
 580
 581static struct platform_driver grlib_apbuart_of_driver = {
 582        .probe = apbuart_probe,
 583        .driver = {
 584                .name = "grlib-apbuart",
 585                .of_match_table = apbuart_match,
 586        },
 587};
 588
 589
 590static int __init grlib_apbuart_configure(void)
 591{
 592        struct device_node *np;
 593        int line = 0;
 594
 595        for_each_matching_node(np, apbuart_match) {
 596                const int *ampopts;
 597                const u32 *freq_hz;
 598                const struct amba_prom_registers *regs;
 599                struct uart_port *port;
 600                unsigned long addr;
 601
 602                ampopts = of_get_property(np, "ampopts", NULL);
 603                if (ampopts && (*ampopts == 0))
 604                        continue; /* Ignore if used by another OS instance */
 605                regs = of_get_property(np, "reg", NULL);
 606                /* Frequency of APB Bus is frequency of UART */
 607                freq_hz = of_get_property(np, "freq", NULL);
 608
 609                if (!regs || !freq_hz || (*freq_hz == 0))
 610                        continue;
 611
 612                grlib_apbuart_nodes[line] = np;
 613
 614                addr = regs->phys_addr;
 615
 616                port = &grlib_apbuart_ports[line];
 617
 618                port->mapbase = addr;
 619                port->membase = ioremap(addr, sizeof(struct grlib_apbuart_regs_map));
 620                port->irq = 0;
 621                port->iotype = UPIO_MEM;
 622                port->ops = &grlib_apbuart_ops;
 623                port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_GRLIB_GAISLER_APBUART_CONSOLE);
 624                port->flags = UPF_BOOT_AUTOCONF;
 625                port->line = line;
 626                port->uartclk = *freq_hz;
 627                port->fifosize = apbuart_scan_fifo_size((struct uart_port *) port, line);
 628                line++;
 629
 630                /* We support maximum UART_NR uarts ... */
 631                if (line == UART_NR)
 632                        break;
 633        }
 634
 635        grlib_apbuart_driver.nr = grlib_apbuart_port_nr = line;
 636        return line ? 0 : -ENODEV;
 637}
 638
 639static int __init grlib_apbuart_init(void)
 640{
 641        int ret;
 642
 643        /* Find all APBUARTS in device the tree and initialize their ports */
 644        ret = grlib_apbuart_configure();
 645        if (ret)
 646                return ret;
 647
 648        printk(KERN_INFO "Serial: GRLIB APBUART driver\n");
 649
 650        ret = uart_register_driver(&grlib_apbuart_driver);
 651
 652        if (ret) {
 653                printk(KERN_ERR "%s: uart_register_driver failed (%i)\n",
 654                       __FILE__, ret);
 655                return ret;
 656        }
 657
 658        ret = platform_driver_register(&grlib_apbuart_of_driver);
 659        if (ret) {
 660                printk(KERN_ERR
 661                       "%s: platform_driver_register failed (%i)\n",
 662                       __FILE__, ret);
 663                uart_unregister_driver(&grlib_apbuart_driver);
 664                return ret;
 665        }
 666
 667        return ret;
 668}
 669
 670static void __exit grlib_apbuart_exit(void)
 671{
 672        int i;
 673
 674        for (i = 0; i < grlib_apbuart_port_nr; i++)
 675                uart_remove_one_port(&grlib_apbuart_driver,
 676                                     &grlib_apbuart_ports[i]);
 677
 678        uart_unregister_driver(&grlib_apbuart_driver);
 679        platform_driver_unregister(&grlib_apbuart_of_driver);
 680}
 681
 682module_init(grlib_apbuart_init);
 683module_exit(grlib_apbuart_exit);
 684
 685MODULE_AUTHOR("Aeroflex Gaisler AB");
 686MODULE_DESCRIPTION("GRLIB APBUART serial driver");
 687MODULE_VERSION("2.1");
 688MODULE_LICENSE("GPL");
 689