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