Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * timbuart.c timberdale FPGA UART driver
0004  * Copyright (c) 2009 Intel Corporation
0005  */
0006 
0007 /* Supports:
0008  * Timberdale FPGA UART
0009  */
0010 
0011 #include <linux/pci.h>
0012 #include <linux/interrupt.h>
0013 #include <linux/serial_core.h>
0014 #include <linux/tty.h>
0015 #include <linux/tty_flip.h>
0016 #include <linux/kernel.h>
0017 #include <linux/platform_device.h>
0018 #include <linux/ioport.h>
0019 #include <linux/slab.h>
0020 #include <linux/module.h>
0021 
0022 #include "timbuart.h"
0023 
0024 struct timbuart_port {
0025     struct uart_port    port;
0026     struct tasklet_struct   tasklet;
0027     int         usedma;
0028     u32         last_ier;
0029     struct platform_device  *dev;
0030 };
0031 
0032 static int baudrates[] = {9600, 19200, 38400, 57600, 115200, 230400, 460800,
0033     921600, 1843200, 3250000};
0034 
0035 static void timbuart_mctrl_check(struct uart_port *port, u32 isr, u32 *ier);
0036 
0037 static irqreturn_t timbuart_handleinterrupt(int irq, void *devid);
0038 
0039 static void timbuart_stop_rx(struct uart_port *port)
0040 {
0041     /* spin lock held by upper layer, disable all RX interrupts */
0042     u32 ier = ioread32(port->membase + TIMBUART_IER) & ~RXFLAGS;
0043     iowrite32(ier, port->membase + TIMBUART_IER);
0044 }
0045 
0046 static void timbuart_stop_tx(struct uart_port *port)
0047 {
0048     /* spinlock held by upper layer, disable TX interrupt */
0049     u32 ier = ioread32(port->membase + TIMBUART_IER) & ~TXBAE;
0050     iowrite32(ier, port->membase + TIMBUART_IER);
0051 }
0052 
0053 static void timbuart_start_tx(struct uart_port *port)
0054 {
0055     struct timbuart_port *uart =
0056         container_of(port, struct timbuart_port, port);
0057 
0058     /* do not transfer anything here -> fire off the tasklet */
0059     tasklet_schedule(&uart->tasklet);
0060 }
0061 
0062 static unsigned int timbuart_tx_empty(struct uart_port *port)
0063 {
0064     u32 isr = ioread32(port->membase + TIMBUART_ISR);
0065 
0066     return (isr & TXBE) ? TIOCSER_TEMT : 0;
0067 }
0068 
0069 static void timbuart_flush_buffer(struct uart_port *port)
0070 {
0071     if (!timbuart_tx_empty(port)) {
0072         u8 ctl = ioread8(port->membase + TIMBUART_CTRL) |
0073             TIMBUART_CTRL_FLSHTX;
0074 
0075         iowrite8(ctl, port->membase + TIMBUART_CTRL);
0076         iowrite32(TXBF, port->membase + TIMBUART_ISR);
0077     }
0078 }
0079 
0080 static void timbuart_rx_chars(struct uart_port *port)
0081 {
0082     struct tty_port *tport = &port->state->port;
0083 
0084     while (ioread32(port->membase + TIMBUART_ISR) & RXDP) {
0085         u8 ch = ioread8(port->membase + TIMBUART_RXFIFO);
0086         port->icount.rx++;
0087         tty_insert_flip_char(tport, ch, TTY_NORMAL);
0088     }
0089 
0090     tty_flip_buffer_push(tport);
0091 
0092     dev_dbg(port->dev, "%s - total read %d bytes\n",
0093         __func__, port->icount.rx);
0094 }
0095 
0096 static void timbuart_tx_chars(struct uart_port *port)
0097 {
0098     struct circ_buf *xmit = &port->state->xmit;
0099 
0100     while (!(ioread32(port->membase + TIMBUART_ISR) & TXBF) &&
0101         !uart_circ_empty(xmit)) {
0102         iowrite8(xmit->buf[xmit->tail],
0103             port->membase + TIMBUART_TXFIFO);
0104         xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
0105         port->icount.tx++;
0106     }
0107 
0108     dev_dbg(port->dev,
0109         "%s - total written %d bytes, CTL: %x, RTS: %x, baud: %x\n",
0110          __func__,
0111         port->icount.tx,
0112         ioread8(port->membase + TIMBUART_CTRL),
0113         port->mctrl & TIOCM_RTS,
0114         ioread8(port->membase + TIMBUART_BAUDRATE));
0115 }
0116 
0117 static void timbuart_handle_tx_port(struct uart_port *port, u32 isr, u32 *ier)
0118 {
0119     struct timbuart_port *uart =
0120         container_of(port, struct timbuart_port, port);
0121     struct circ_buf *xmit = &port->state->xmit;
0122 
0123     if (uart_circ_empty(xmit) || uart_tx_stopped(port))
0124         return;
0125 
0126     if (port->x_char)
0127         return;
0128 
0129     if (isr & TXFLAGS) {
0130         timbuart_tx_chars(port);
0131         /* clear all TX interrupts */
0132         iowrite32(TXFLAGS, port->membase + TIMBUART_ISR);
0133 
0134         if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
0135             uart_write_wakeup(port);
0136     } else
0137         /* Re-enable any tx interrupt */
0138         *ier |= uart->last_ier & TXFLAGS;
0139 
0140     /* enable interrupts if there are chars in the transmit buffer,
0141      * Or if we delivered some bytes and want the almost empty interrupt
0142      * we wake up the upper layer later when we got the interrupt
0143      * to give it some time to go out...
0144      */
0145     if (!uart_circ_empty(xmit))
0146         *ier |= TXBAE;
0147 
0148     dev_dbg(port->dev, "%s - leaving\n", __func__);
0149 }
0150 
0151 static void timbuart_handle_rx_port(struct uart_port *port, u32 isr, u32 *ier)
0152 {
0153     if (isr & RXFLAGS) {
0154         /* Some RX status is set */
0155         if (isr & RXBF) {
0156             u8 ctl = ioread8(port->membase + TIMBUART_CTRL) |
0157                 TIMBUART_CTRL_FLSHRX;
0158             iowrite8(ctl, port->membase + TIMBUART_CTRL);
0159             port->icount.overrun++;
0160         } else if (isr & (RXDP))
0161             timbuart_rx_chars(port);
0162 
0163         /* ack all RX interrupts */
0164         iowrite32(RXFLAGS, port->membase + TIMBUART_ISR);
0165     }
0166 
0167     /* always have the RX interrupts enabled */
0168     *ier |= RXBAF | RXBF | RXTT;
0169 
0170     dev_dbg(port->dev, "%s - leaving\n", __func__);
0171 }
0172 
0173 static void timbuart_tasklet(struct tasklet_struct *t)
0174 {
0175     struct timbuart_port *uart = from_tasklet(uart, t, tasklet);
0176     u32 isr, ier = 0;
0177 
0178     spin_lock(&uart->port.lock);
0179 
0180     isr = ioread32(uart->port.membase + TIMBUART_ISR);
0181     dev_dbg(uart->port.dev, "%s ISR: %x\n", __func__, isr);
0182 
0183     if (!uart->usedma)
0184         timbuart_handle_tx_port(&uart->port, isr, &ier);
0185 
0186     timbuart_mctrl_check(&uart->port, isr, &ier);
0187 
0188     if (!uart->usedma)
0189         timbuart_handle_rx_port(&uart->port, isr, &ier);
0190 
0191     iowrite32(ier, uart->port.membase + TIMBUART_IER);
0192 
0193     spin_unlock(&uart->port.lock);
0194     dev_dbg(uart->port.dev, "%s leaving\n", __func__);
0195 }
0196 
0197 static unsigned int timbuart_get_mctrl(struct uart_port *port)
0198 {
0199     u8 cts = ioread8(port->membase + TIMBUART_CTRL);
0200     dev_dbg(port->dev, "%s - cts %x\n", __func__, cts);
0201 
0202     if (cts & TIMBUART_CTRL_CTS)
0203         return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
0204     else
0205         return TIOCM_DSR | TIOCM_CAR;
0206 }
0207 
0208 static void timbuart_set_mctrl(struct uart_port *port, unsigned int mctrl)
0209 {
0210     dev_dbg(port->dev, "%s - %x\n", __func__, mctrl);
0211 
0212     if (mctrl & TIOCM_RTS)
0213         iowrite8(TIMBUART_CTRL_RTS, port->membase + TIMBUART_CTRL);
0214     else
0215         iowrite8(0, port->membase + TIMBUART_CTRL);
0216 }
0217 
0218 static void timbuart_mctrl_check(struct uart_port *port, u32 isr, u32 *ier)
0219 {
0220     unsigned int cts;
0221 
0222     if (isr & CTS_DELTA) {
0223         /* ack */
0224         iowrite32(CTS_DELTA, port->membase + TIMBUART_ISR);
0225         cts = timbuart_get_mctrl(port);
0226         uart_handle_cts_change(port, cts & TIOCM_CTS);
0227         wake_up_interruptible(&port->state->port.delta_msr_wait);
0228     }
0229 
0230     *ier |= CTS_DELTA;
0231 }
0232 
0233 static void timbuart_break_ctl(struct uart_port *port, int ctl)
0234 {
0235     /* N/A */
0236 }
0237 
0238 static int timbuart_startup(struct uart_port *port)
0239 {
0240     struct timbuart_port *uart =
0241         container_of(port, struct timbuart_port, port);
0242 
0243     dev_dbg(port->dev, "%s\n", __func__);
0244 
0245     iowrite8(TIMBUART_CTRL_FLSHRX, port->membase + TIMBUART_CTRL);
0246     iowrite32(0x1ff, port->membase + TIMBUART_ISR);
0247     /* Enable all but TX interrupts */
0248     iowrite32(RXBAF | RXBF | RXTT | CTS_DELTA,
0249         port->membase + TIMBUART_IER);
0250 
0251     return request_irq(port->irq, timbuart_handleinterrupt, IRQF_SHARED,
0252         "timb-uart", uart);
0253 }
0254 
0255 static void timbuart_shutdown(struct uart_port *port)
0256 {
0257     struct timbuart_port *uart =
0258         container_of(port, struct timbuart_port, port);
0259     dev_dbg(port->dev, "%s\n", __func__);
0260     free_irq(port->irq, uart);
0261     iowrite32(0, port->membase + TIMBUART_IER);
0262 
0263     timbuart_flush_buffer(port);
0264 }
0265 
0266 static int get_bindex(int baud)
0267 {
0268     int i;
0269 
0270     for (i = 0; i < ARRAY_SIZE(baudrates); i++)
0271         if (baud <= baudrates[i])
0272             return i;
0273 
0274     return -1;
0275 }
0276 
0277 static void timbuart_set_termios(struct uart_port *port,
0278     struct ktermios *termios,
0279     struct ktermios *old)
0280 {
0281     unsigned int baud;
0282     short bindex;
0283     unsigned long flags;
0284 
0285     baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16);
0286     bindex = get_bindex(baud);
0287     dev_dbg(port->dev, "%s - bindex %d\n", __func__, bindex);
0288 
0289     if (bindex < 0)
0290         bindex = 0;
0291     baud = baudrates[bindex];
0292 
0293     /* The serial layer calls into this once with old = NULL when setting
0294        up initially */
0295     if (old)
0296         tty_termios_copy_hw(termios, old);
0297     tty_termios_encode_baud_rate(termios, baud, baud);
0298 
0299     spin_lock_irqsave(&port->lock, flags);
0300     iowrite8((u8)bindex, port->membase + TIMBUART_BAUDRATE);
0301     uart_update_timeout(port, termios->c_cflag, baud);
0302     spin_unlock_irqrestore(&port->lock, flags);
0303 }
0304 
0305 static const char *timbuart_type(struct uart_port *port)
0306 {
0307     return port->type == PORT_UNKNOWN ? "timbuart" : NULL;
0308 }
0309 
0310 /* We do not request/release mappings of the registers here,
0311  * currently it's done in the proble function.
0312  */
0313 static void timbuart_release_port(struct uart_port *port)
0314 {
0315     struct platform_device *pdev = to_platform_device(port->dev);
0316     int size =
0317         resource_size(platform_get_resource(pdev, IORESOURCE_MEM, 0));
0318 
0319     if (port->flags & UPF_IOREMAP) {
0320         iounmap(port->membase);
0321         port->membase = NULL;
0322     }
0323 
0324     release_mem_region(port->mapbase, size);
0325 }
0326 
0327 static int timbuart_request_port(struct uart_port *port)
0328 {
0329     struct platform_device *pdev = to_platform_device(port->dev);
0330     int size =
0331         resource_size(platform_get_resource(pdev, IORESOURCE_MEM, 0));
0332 
0333     if (!request_mem_region(port->mapbase, size, "timb-uart"))
0334         return -EBUSY;
0335 
0336     if (port->flags & UPF_IOREMAP) {
0337         port->membase = ioremap(port->mapbase, size);
0338         if (port->membase == NULL) {
0339             release_mem_region(port->mapbase, size);
0340             return -ENOMEM;
0341         }
0342     }
0343 
0344     return 0;
0345 }
0346 
0347 static irqreturn_t timbuart_handleinterrupt(int irq, void *devid)
0348 {
0349     struct timbuart_port *uart = (struct timbuart_port *)devid;
0350 
0351     if (ioread8(uart->port.membase + TIMBUART_IPR)) {
0352         uart->last_ier = ioread32(uart->port.membase + TIMBUART_IER);
0353 
0354         /* disable interrupts, the tasklet enables them again */
0355         iowrite32(0, uart->port.membase + TIMBUART_IER);
0356 
0357         /* fire off bottom half */
0358         tasklet_schedule(&uart->tasklet);
0359 
0360         return IRQ_HANDLED;
0361     } else
0362         return IRQ_NONE;
0363 }
0364 
0365 /*
0366  * Configure/autoconfigure the port.
0367  */
0368 static void timbuart_config_port(struct uart_port *port, int flags)
0369 {
0370     if (flags & UART_CONFIG_TYPE) {
0371         port->type = PORT_TIMBUART;
0372         timbuart_request_port(port);
0373     }
0374 }
0375 
0376 static int timbuart_verify_port(struct uart_port *port,
0377     struct serial_struct *ser)
0378 {
0379     /* we don't want the core code to modify any port params */
0380     return -EINVAL;
0381 }
0382 
0383 static const struct uart_ops timbuart_ops = {
0384     .tx_empty = timbuart_tx_empty,
0385     .set_mctrl = timbuart_set_mctrl,
0386     .get_mctrl = timbuart_get_mctrl,
0387     .stop_tx = timbuart_stop_tx,
0388     .start_tx = timbuart_start_tx,
0389     .flush_buffer = timbuart_flush_buffer,
0390     .stop_rx = timbuart_stop_rx,
0391     .break_ctl = timbuart_break_ctl,
0392     .startup = timbuart_startup,
0393     .shutdown = timbuart_shutdown,
0394     .set_termios = timbuart_set_termios,
0395     .type = timbuart_type,
0396     .release_port = timbuart_release_port,
0397     .request_port = timbuart_request_port,
0398     .config_port = timbuart_config_port,
0399     .verify_port = timbuart_verify_port
0400 };
0401 
0402 static struct uart_driver timbuart_driver = {
0403     .owner = THIS_MODULE,
0404     .driver_name = "timberdale_uart",
0405     .dev_name = "ttyTU",
0406     .major = TIMBUART_MAJOR,
0407     .minor = TIMBUART_MINOR,
0408     .nr = 1
0409 };
0410 
0411 static int timbuart_probe(struct platform_device *dev)
0412 {
0413     int err, irq;
0414     struct timbuart_port *uart;
0415     struct resource *iomem;
0416 
0417     dev_dbg(&dev->dev, "%s\n", __func__);
0418 
0419     uart = kzalloc(sizeof(*uart), GFP_KERNEL);
0420     if (!uart) {
0421         err = -EINVAL;
0422         goto err_mem;
0423     }
0424 
0425     uart->usedma = 0;
0426 
0427     uart->port.uartclk = 3250000 * 16;
0428     uart->port.fifosize  = TIMBUART_FIFO_SIZE;
0429     uart->port.regshift  = 2;
0430     uart->port.iotype  = UPIO_MEM;
0431     uart->port.ops = &timbuart_ops;
0432     uart->port.irq = 0;
0433     uart->port.flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP;
0434     uart->port.line  = 0;
0435     uart->port.dev  = &dev->dev;
0436 
0437     iomem = platform_get_resource(dev, IORESOURCE_MEM, 0);
0438     if (!iomem) {
0439         err = -ENOMEM;
0440         goto err_register;
0441     }
0442     uart->port.mapbase = iomem->start;
0443     uart->port.membase = NULL;
0444 
0445     irq = platform_get_irq(dev, 0);
0446     if (irq < 0) {
0447         err = -EINVAL;
0448         goto err_register;
0449     }
0450     uart->port.irq = irq;
0451 
0452     tasklet_setup(&uart->tasklet, timbuart_tasklet);
0453 
0454     err = uart_register_driver(&timbuart_driver);
0455     if (err)
0456         goto err_register;
0457 
0458     err = uart_add_one_port(&timbuart_driver, &uart->port);
0459     if (err)
0460         goto err_add_port;
0461 
0462     platform_set_drvdata(dev, uart);
0463 
0464     return 0;
0465 
0466 err_add_port:
0467     uart_unregister_driver(&timbuart_driver);
0468 err_register:
0469     kfree(uart);
0470 err_mem:
0471     printk(KERN_ERR "timberdale: Failed to register Timberdale UART: %d\n",
0472         err);
0473 
0474     return err;
0475 }
0476 
0477 static int timbuart_remove(struct platform_device *dev)
0478 {
0479     struct timbuart_port *uart = platform_get_drvdata(dev);
0480 
0481     tasklet_kill(&uart->tasklet);
0482     uart_remove_one_port(&timbuart_driver, &uart->port);
0483     uart_unregister_driver(&timbuart_driver);
0484     kfree(uart);
0485 
0486     return 0;
0487 }
0488 
0489 static struct platform_driver timbuart_platform_driver = {
0490     .driver = {
0491         .name   = "timb-uart",
0492     },
0493     .probe      = timbuart_probe,
0494     .remove     = timbuart_remove,
0495 };
0496 
0497 module_platform_driver(timbuart_platform_driver);
0498 
0499 MODULE_DESCRIPTION("Timberdale UART driver");
0500 MODULE_LICENSE("GPL v2");
0501 MODULE_ALIAS("platform:timb-uart");
0502