diff options
55 files changed, 3039 insertions, 313 deletions
diff --git a/Documentation/devicetree/bindings/dma/8250_mtk_dma.txt b/Documentation/devicetree/bindings/dma/8250_mtk_dma.txt new file mode 100644 index 000000000000..3fe0961bcf64 --- /dev/null +++ b/Documentation/devicetree/bindings/dma/8250_mtk_dma.txt @@ -0,0 +1,33 @@ +* Mediatek UART APDMA Controller + +Required properties: +- compatible should contain: + * "mediatek,mt2712-uart-dma" for MT2712 compatible APDMA + * "mediatek,mt6577-uart-dma" for MT6577 and all of the above + +- reg: The base address of the APDMA register bank. + +- interrupts: A single interrupt specifier. + +- clocks : Must contain an entry for each entry in clock-names. + See ../clocks/clock-bindings.txt for details. +- clock-names: The APDMA clock for register accesses + +Examples: + + apdma: dma-controller@11000380 { + compatible = "mediatek,mt2712-uart-dma"; + reg = <0 0x11000380 0 0x400>; + interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_LOW>, + <GIC_SPI 64 IRQ_TYPE_LEVEL_LOW>, + <GIC_SPI 65 IRQ_TYPE_LEVEL_LOW>, + <GIC_SPI 66 IRQ_TYPE_LEVEL_LOW>, + <GIC_SPI 67 IRQ_TYPE_LEVEL_LOW>, + <GIC_SPI 68 IRQ_TYPE_LEVEL_LOW>, + <GIC_SPI 69 IRQ_TYPE_LEVEL_LOW>, + <GIC_SPI 70 IRQ_TYPE_LEVEL_LOW>; + clocks = <&pericfg CLK_PERI_AP_DMA>; + clock-names = "apdma"; + #dma-cells = <1>; + }; + diff --git a/Documentation/devicetree/bindings/serial/8250.txt b/Documentation/devicetree/bindings/serial/8250.txt index aeb6db4e35c3..da50321da34d 100644 --- a/Documentation/devicetree/bindings/serial/8250.txt +++ b/Documentation/devicetree/bindings/serial/8250.txt @@ -51,6 +51,7 @@ Optional properties: - tx-threshold: Specify the TX FIFO low water indication for parts with programmable TX FIFO thresholds. - resets : phandle + reset specifier pairs +- overrun-throttle-ms : how long to pause uart rx when input overrun is encountered. Note: * fsl,ns16550: diff --git a/Documentation/devicetree/bindings/serial/fsl-lpuart.txt b/Documentation/devicetree/bindings/serial/fsl-lpuart.txt index 6bd3f2e93d61..21483ba820bc 100644 --- a/Documentation/devicetree/bindings/serial/fsl-lpuart.txt +++ b/Documentation/devicetree/bindings/serial/fsl-lpuart.txt @@ -8,6 +8,8 @@ Required properties: on LS1021A SoC with 32-bit big-endian register organization - "fsl,imx7ulp-lpuart" for lpuart compatible with the one integrated on i.MX7ULP SoC with 32-bit little-endian register organization + - "fsl,imx8qxp-lpuart" for lpuart compatible with the one integrated + on i.MX8QXP SoC with 32-bit little-endian register organization - reg : Address and length of the register set for the device - interrupts : Should contain uart interrupt - clocks : phandle + clock specifier pairs, one for each entry in clock-names diff --git a/Documentation/devicetree/bindings/serial/lantiq_asc.txt b/Documentation/devicetree/bindings/serial/lantiq_asc.txt index 3acbd309ab9d..40e81a5818f6 100644 --- a/Documentation/devicetree/bindings/serial/lantiq_asc.txt +++ b/Documentation/devicetree/bindings/serial/lantiq_asc.txt @@ -6,8 +6,23 @@ Required properties: - interrupts: the 3 (tx rx err) interrupt numbers. The interrupt specifier depends on the interrupt-parent interrupt controller. +Optional properties: +- clocks: Should contain frequency clock and gate clock +- clock-names: Should be "freq" and "asc" + Example: +asc0: serial@16600000 { + compatible = "lantiq,asc"; + reg = <0x16600000 0x100000>; + interrupt-parent = <&gic>; + interrupts = <GIC_SHARED 103 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SHARED 105 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SHARED 106 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cgu CLK_SSX4>, <&cgu GCLK_UART>; + clock-names = "freq", "asc"; +}; + asc1: serial@e100c00 { compatible = "lantiq,asc"; reg = <0xE100C00 0x400>; diff --git a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt index e52e16c6bc57..20232ad05d89 100644 --- a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt +++ b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt @@ -24,6 +24,10 @@ Required properties: - "renesas,hscif-r8a7745" for R8A7745 (RZ/G1E) HSCIF compatible UART. - "renesas,scif-r8a77470" for R8A77470 (RZ/G1C) SCIF compatible UART. - "renesas,hscif-r8a77470" for R8A77470 (RZ/G1C) HSCIF compatible UART. + - "renesas,scif-r8a774a1" for R8A774A1 (RZ/G2M) SCIF compatible UART. + - "renesas,hscif-r8a774a1" for R8A774A1 (RZ/G2M) HSCIF compatible UART. + - "renesas,scif-r8a774c0" for R8A774C0 (RZ/G2E) SCIF compatible UART. + - "renesas,hscif-r8a774c0" for R8A774C0 (RZ/G2E) HSCIF compatible UART. - "renesas,scif-r8a7778" for R8A7778 (R-Car M1) SCIF compatible UART. - "renesas,scif-r8a7779" for R8A7779 (R-Car H1) SCIF compatible UART. - "renesas,scif-r8a7790" for R8A7790 (R-Car H2) SCIF compatible UART. @@ -61,13 +65,13 @@ Required properties: - "renesas,scifa-sh73a0" for SH73A0 (SH-Mobile AG5) SCIFA compatible UART. - "renesas,scifb-sh73a0" for SH73A0 (SH-Mobile AG5) SCIFB compatible UART. - "renesas,rcar-gen1-scif" for R-Car Gen1 SCIF compatible UART, - - "renesas,rcar-gen2-scif" for R-Car Gen2 SCIF compatible UART, - - "renesas,rcar-gen3-scif" for R-Car Gen3 SCIF compatible UART, - - "renesas,rcar-gen2-scifa" for R-Car Gen2 SCIFA compatible UART, - - "renesas,rcar-gen2-scifb" for R-Car Gen2 SCIFB compatible UART, + - "renesas,rcar-gen2-scif" for R-Car Gen2 and RZ/G1 SCIF compatible UART, + - "renesas,rcar-gen3-scif" for R-Car Gen3 and RZ/G2 SCIF compatible UART, + - "renesas,rcar-gen2-scifa" for R-Car Gen2 and RZ/G1 SCIFA compatible UART, + - "renesas,rcar-gen2-scifb" for R-Car Gen2 and RZ/G1 SCIFB compatible UART, - "renesas,rcar-gen1-hscif" for R-Car Gen1 HSCIF compatible UART, - - "renesas,rcar-gen2-hscif" for R-Car Gen2 HSCIF compatible UART, - - "renesas,rcar-gen3-hscif" for R-Car Gen3 HSCIF compatible UART, + - "renesas,rcar-gen2-hscif" for R-Car Gen2 and RZ/G1 HSCIF compatible UART, + - "renesas,rcar-gen3-hscif" for R-Car Gen3 and RZ/G2 HSCIF compatible UART, - "renesas,scif" for generic SCIF compatible UART. - "renesas,scifa" for generic SCIFA compatible UART. - "renesas,scifb" for generic SCIFB compatible UART. diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 9d03b2ff5df6..2e2ffe7010aa 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -66,6 +66,14 @@ config TTY_PRINTK If unsure, say N. +config TTY_PRINTK_LEVEL + depends on TTY_PRINTK + int "ttyprintk log level (1-7)" + range 1 7 + default "6" + help + Printk log level to use for ttyprintk messages. + config PRINTER tristate "Parallel printer support" depends on PARPORT diff --git a/drivers/char/ttyprintk.c b/drivers/char/ttyprintk.c index 67549ce88cc9..88808dbba486 100644 --- a/drivers/char/ttyprintk.c +++ b/drivers/char/ttyprintk.c @@ -37,6 +37,8 @@ static struct ttyprintk_port tpk_port; */ #define TPK_STR_SIZE 508 /* should be bigger then max expected line length */ #define TPK_MAX_ROOM 4096 /* we could assume 4K for instance */ +#define TPK_PREFIX KERN_SOH __stringify(CONFIG_TTY_PRINTK_LEVEL) + static int tpk_curr; static char tpk_buffer[TPK_STR_SIZE + 4]; @@ -45,7 +47,7 @@ static void tpk_flush(void) { if (tpk_curr > 0) { tpk_buffer[tpk_curr] = '\0'; - pr_info("[U] %s\n", tpk_buffer); + printk(TPK_PREFIX "[U] %s\n", tpk_buffer); tpk_curr = 0; } } diff --git a/drivers/gnss/serial.c b/drivers/gnss/serial.c index 31e891f00175..def64b36d994 100644 --- a/drivers/gnss/serial.c +++ b/drivers/gnss/serial.c @@ -65,7 +65,7 @@ static int gnss_serial_write_raw(struct gnss_device *gdev, /* write is only buffered synchronously */ ret = serdev_device_write(serdev, buf, count, MAX_SCHEDULE_TIMEOUT); - if (ret < 0) + if (ret < 0 || ret < count) return ret; /* FIXME: determine if interrupted? */ diff --git a/drivers/gnss/sirf.c b/drivers/gnss/sirf.c index 2c22836d3ffd..226f6e6fe01b 100644 --- a/drivers/gnss/sirf.c +++ b/drivers/gnss/sirf.c @@ -85,7 +85,7 @@ static int sirf_write_raw(struct gnss_device *gdev, const unsigned char *buf, /* write is only buffered synchronously */ ret = serdev_device_write(serdev, buf, count, MAX_SCHEDULE_TIMEOUT); - if (ret < 0) + if (ret < 0 || ret < count) return ret; /* FIXME: determine if interrupted? */ diff --git a/drivers/tty/hvc/hvc_opal.c b/drivers/tty/hvc/hvc_opal.c index 77baf895108f..c66412566efc 100644 --- a/drivers/tty/hvc/hvc_opal.c +++ b/drivers/tty/hvc/hvc_opal.c @@ -353,7 +353,7 @@ void __init hvc_opal_init_early(void) if (!opal) return; for_each_child_of_node(opal, np) { - if (!strcmp(np->name, "serial")) { + if (of_node_name_eq(np, "serial")) { stdout_node = np; break; } diff --git a/drivers/tty/hvc/hvc_vio.c b/drivers/tty/hvc/hvc_vio.c index 59eaa620bf13..6de6d4a1a221 100644 --- a/drivers/tty/hvc/hvc_vio.c +++ b/drivers/tty/hvc/hvc_vio.c @@ -371,20 +371,11 @@ device_initcall(hvc_vio_init); /* after drivers/tty/hvc/hvc_console.c */ void __init hvc_vio_init_early(void) { const __be32 *termno; - const char *name; const struct hv_ops *ops; /* find the boot console from /chosen/stdout */ - if (!of_stdout) - return; - name = of_get_property(of_stdout, "name", NULL); - if (!name) { - printk(KERN_WARNING "stdout node missing 'name' property!\n"); - return; - } - /* Check if it's a virtual terminal */ - if (strncmp(name, "vty", 3) != 0) + if (!of_node_name_prefix(of_stdout, "vty")) return; termno = of_get_property(of_stdout, "reg", NULL); if (termno == NULL) diff --git a/drivers/tty/n_hdlc.c b/drivers/tty/n_hdlc.c index dabb391909aa..99460af61b77 100644 --- a/drivers/tty/n_hdlc.c +++ b/drivers/tty/n_hdlc.c @@ -612,7 +612,7 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file, } /* no data */ - if (file->f_flags & O_NONBLOCK) { + if (tty_io_nonblock(tty, file)) { ret = -EAGAIN; break; } @@ -679,7 +679,7 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file, if (tbuf) break; - if (file->f_flags & O_NONBLOCK) { + if (tty_io_nonblock(tty, file)) { error = -EAGAIN; break; } diff --git a/drivers/tty/n_r3964.c b/drivers/tty/n_r3964.c index 749a608c40b0..f75696f0ee2d 100644 --- a/drivers/tty/n_r3964.c +++ b/drivers/tty/n_r3964.c @@ -1085,7 +1085,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file, pMsg = remove_msg(pInfo, pClient); if (pMsg == NULL) { /* no messages available. */ - if (file->f_flags & O_NONBLOCK) { + if (tty_io_nonblock(tty, file)) { ret = -EAGAIN; goto unlock; } diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 3ad460219fd6..5dc9686697cf 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1702,7 +1702,7 @@ n_tty_receive_buf_common(struct tty_struct *tty, const unsigned char *cp, down_read(&tty->termios_rwsem); - while (1) { + do { /* * When PARMRK is set, each input char may take up to 3 chars * in the read buf; reduce the buffer space avail by 3x @@ -1744,7 +1744,7 @@ n_tty_receive_buf_common(struct tty_struct *tty, const unsigned char *cp, fp += n; count -= n; rcvd += n; - } + } while (!test_bit(TTY_LDISC_CHANGING, &tty->flags)); tty->receive_room = room; @@ -2211,7 +2211,7 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, break; if (!timeout) break; - if (file->f_flags & O_NONBLOCK) { + if (tty_io_nonblock(tty, file)) { retval = -EAGAIN; break; } @@ -2365,7 +2365,7 @@ static ssize_t n_tty_write(struct tty_struct *tty, struct file *file, } if (!nr) break; - if (file->f_flags & O_NONBLOCK) { + if (tty_io_nonblock(tty, file)) { retval = -EAGAIN; break; } diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c index 9db93f500b4e..a0ac16ee6575 100644 --- a/drivers/tty/serdev/core.c +++ b/drivers/tty/serdev/core.c @@ -15,6 +15,7 @@ #include <linux/of_device.h> #include <linux/pm_domain.h> #include <linux/pm_runtime.h> +#include <linux/sched.h> #include <linux/serdev.h> #include <linux/slab.h> @@ -216,6 +217,21 @@ void serdev_device_write_wakeup(struct serdev_device *serdev) } EXPORT_SYMBOL_GPL(serdev_device_write_wakeup); +/** + * serdev_device_write_buf() - write data asynchronously + * @serdev: serdev device + * @buf: data to be written + * @count: number of bytes to write + * + * Write data to the device asynchronously. + * + * Note that any accepted data has only been buffered by the controller; use + * serdev_device_wait_until_sent() to make sure the controller write buffer + * has actually been emptied. + * + * Return: The number of bytes written (less than count if not enough room in + * the write buffer), or a negative errno on errors. + */ int serdev_device_write_buf(struct serdev_device *serdev, const unsigned char *buf, size_t count) { @@ -228,17 +244,42 @@ int serdev_device_write_buf(struct serdev_device *serdev, } EXPORT_SYMBOL_GPL(serdev_device_write_buf); +/** + * serdev_device_write() - write data synchronously + * @serdev: serdev device + * @buf: data to be written + * @count: number of bytes to write + * @timeout: timeout in jiffies, or 0 to wait indefinitely + * + * Write data to the device synchronously by repeatedly calling + * serdev_device_write() until the controller has accepted all data (unless + * interrupted by a timeout or a signal). + * + * Note that any accepted data has only been buffered by the controller; use + * serdev_device_wait_until_sent() to make sure the controller write buffer + * has actually been emptied. + * + * Note that this function depends on serdev_device_write_wakeup() being + * called in the serdev driver write_wakeup() callback. + * + * Return: The number of bytes written (less than count if interrupted), + * -ETIMEDOUT or -ERESTARTSYS if interrupted before any bytes were written, or + * a negative errno on errors. + */ int serdev_device_write(struct serdev_device *serdev, const unsigned char *buf, size_t count, - unsigned long timeout) + long timeout) { struct serdev_controller *ctrl = serdev->ctrl; + int written = 0; int ret; - if (!ctrl || !ctrl->ops->write_buf || - (timeout && !serdev->ops->write_wakeup)) + if (!ctrl || !ctrl->ops->write_buf || !serdev->ops->write_wakeup) return -EINVAL; + if (timeout == 0) + timeout = MAX_SCHEDULE_TIMEOUT; + mutex_lock(&serdev->write_lock); do { reinit_completion(&serdev->write_comp); @@ -247,14 +288,29 @@ int serdev_device_write(struct serdev_device *serdev, if (ret < 0) break; + written += ret; buf += ret; count -= ret; - } while (count && - (timeout = wait_for_completion_timeout(&serdev->write_comp, - timeout))); + if (count == 0) + break; + + timeout = wait_for_completion_interruptible_timeout(&serdev->write_comp, + timeout); + } while (timeout > 0); mutex_unlock(&serdev->write_lock); - return ret < 0 ? ret : (count ? -ETIMEDOUT : 0); + + if (ret < 0) + return ret; + + if (timeout <= 0 && written == 0) { + if (timeout == -ERESTARTSYS) + return -ERESTARTSYS; + else + return -ETIMEDOUT; + } + + return written; } EXPORT_SYMBOL_GPL(serdev_device_write); diff --git a/drivers/tty/serial/8250/8250_aspeed_vuart.c b/drivers/tty/serial/8250/8250_aspeed_vuart.c index 435bec40dee6..0438d9a905ce 100644 --- a/drivers/tty/serial/8250/8250_aspeed_vuart.c +++ b/drivers/tty/serial/8250/8250_aspeed_vuart.c @@ -5,6 +5,10 @@ * Copyright (C) 2016 Jeremy Kerr <jk@ozlabs.org>, IBM Corp. * Copyright (C) 2006 Arnd Bergmann <arnd@arndb.de>, IBM Corp. */ +#if defined(CONFIG_SERIAL_8250_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) +#define SUPPORT_SYSRQ +#endif + #include <linux/device.h> #include <linux/module.h> #include <linux/of_address.h> @@ -293,7 +297,7 @@ static int aspeed_vuart_handle_irq(struct uart_port *port) if (lsr & UART_LSR_THRE) serial8250_tx_chars(up); - spin_unlock_irqrestore(&port->lock, flags); + uart_unlock_and_check_sysrq(port, flags); return 1; } diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 94f3e1c64490..189ab1212d9a 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -942,6 +942,21 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port * return NULL; } +static void serial_8250_overrun_backoff_work(struct work_struct *work) +{ + struct uart_8250_port *up = + container_of(to_delayed_work(work), struct uart_8250_port, + overrun_backoff); + struct uart_port *port = &up->port; + unsigned long flags; + + spin_lock_irqsave(&port->lock, flags); + up->ier |= UART_IER_RLSI | UART_IER_RDI; + up->port.read_status_mask |= UART_LSR_DR; + serial_out(up, UART_IER, up->ier); + spin_unlock_irqrestore(&port->lock, flags); +} + /** * serial8250_register_8250_port - register a serial port * @up: serial port template @@ -1056,6 +1071,16 @@ int serial8250_register_8250_port(struct uart_8250_port *up) ret = 0; } } + + /* Initialise interrupt backoff work if required */ + if (up->overrun_backoff_time_ms > 0) { + uart->overrun_backoff_time_ms = up->overrun_backoff_time_ms; + INIT_DELAYED_WORK(&uart->overrun_backoff, + serial_8250_overrun_backoff_work); + } else { + uart->overrun_backoff_time_ms = 0; + } + mutex_unlock(&serial_mutex); return ret; diff --git a/drivers/tty/serial/8250/8250_fsl.c b/drivers/tty/serial/8250/8250_fsl.c index 6640a4c7ddd1..aa0e216d5ead 100644 --- a/drivers/tty/serial/8250/8250_fsl.c +++ b/drivers/tty/serial/8250/8250_fsl.c @@ -1,4 +1,8 @@ // SPDX-License-Identifier: GPL-2.0 +#if defined(CONFIG_SERIAL_8250_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) +#define SUPPORT_SYSRQ +#endif + #include <linux/serial_reg.h> #include <linux/serial_8250.h> @@ -45,8 +49,29 @@ int fsl8250_handle_irq(struct uart_port *port) lsr = orig_lsr = up->port.serial_in(&up->port, UART_LSR); - if (lsr & (UART_LSR_DR | UART_LSR_BI)) + /* Process incoming characters first */ + if ((lsr & (UART_LSR_DR | UART_LSR_BI)) && + (up->ier & (UART_IER_RLSI | UART_IER_RDI))) { lsr = serial8250_rx_chars(up, lsr); + } + + /* Stop processing interrupts on input overrun */ + if ((orig_lsr & UART_LSR_OE) && (up->overrun_backoff_time_ms > 0)) { + unsigned long delay; + + up->ier = port->serial_in(port, UART_IER); + if (up->ier & (UART_IER_RLSI | UART_IER_RDI)) { + port->ops->stop_rx(port); + } else { + /* Keep restarting the timer until + * the input overrun subsides. + */ + cancel_delayed_work(&up->overrun_backoff); + } + + delay = msecs_to_jiffies(up->overrun_backoff_time_ms); + schedule_delayed_work(&up->overrun_backoff, delay); + } serial8250_modem_status(up); @@ -54,7 +79,7 @@ int fsl8250_handle_irq(struct uart_port *port) serial8250_tx_chars(up); up->lsr_saved_flags = orig_lsr; - spin_unlock_irqrestore(&up->port.lock, flags); + uart_unlock_and_check_sysrq(&up->port, flags); return 1; } EXPORT_SYMBOL_GPL(fsl8250_handle_irq); diff --git a/drivers/tty/serial/8250/8250_mtk.c b/drivers/tty/serial/8250/8250_mtk.c index c3f933d10295..e2c407656fa6 100644 --- a/drivers/tty/serial/8250/8250_mtk.c +++ b/drivers/tty/serial/8250/8250_mtk.c @@ -14,6 +14,10 @@ #include <linux/pm_runtime.h> #include <linux/serial_8250.h> #include <linux/serial_reg.h> +#include <linux/console.h> +#include <linux/dma-mapping.h> +#include <linux/tty.h> +#include <linux/tty_flip.h> #include "8250.h" @@ -22,12 +26,172 @@ #define UART_MTK_SAMPLE_POINT 0x0b /* Sample point register */ #define MTK_UART_RATE_FIX 0x0d /* UART Rate Fix Register */ +#define MTK_UART_DMA_EN 0x13 /* DMA Enable register */ +#define MTK_UART_DMA_EN_TX 0x2 +#define MTK_UART_DMA_EN_RX 0x5 + +#define MTK_UART_TX_SIZE UART_XMIT_SIZE +#define MTK_UART_RX_SIZE 0x8000 +#define MTK_UART_TX_TRIGGER 1 +#define MTK_UART_RX_TRIGGER MTK_UART_RX_SIZE + +#ifdef CONFIG_SERIAL_8250_DMA +enum dma_rx_status { + DMA_RX_START = 0, + DMA_RX_RUNNING = 1, + DMA_RX_SHUTDOWN = 2, +}; +#endif + struct mtk8250_data { int line; + unsigned int rx_pos; struct clk *uart_clk; struct clk *bus_clk; + struct uart_8250_dma *dma; +#ifdef CONFIG_SERIAL_8250_DMA + enum dma_rx_status rx_status; +#endif }; |
