summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/serial/fsl-imx-uart.txt4
-rw-r--r--Documentation/devicetree/bindings/serial/fsl-lpuart.txt3
-rw-r--r--Documentation/devicetree/bindings/serial/maxim,max310x.txt18
-rw-r--r--Documentation/devicetree/bindings/serial/mvebu-uart.txt50
-rw-r--r--Documentation/devicetree/bindings/serial/omap_serial.txt1
-rw-r--r--Documentation/devicetree/bindings/serial/rs485.txt1
-rw-r--r--Documentation/driver-model/devres.txt3
-rw-r--r--drivers/tty/Kconfig6
-rw-r--r--drivers/tty/goldfish.c2
-rw-r--r--drivers/tty/isicom.c6
-rw-r--r--drivers/tty/moxa.c17
-rw-r--r--drivers/tty/moxa.h2
-rw-r--r--drivers/tty/n_gsm.c2
-rw-r--r--drivers/tty/serdev/core.c31
-rw-r--r--drivers/tty/serdev/serdev-ttyport.c8
-rw-r--r--drivers/tty/serial/8250/8250_dw.c3
-rw-r--r--drivers/tty/serial/8250/8250_omap.c2
-rw-r--r--drivers/tty/serial/8250/Kconfig1
-rw-r--r--drivers/tty/serial/Kconfig14
-rw-r--r--drivers/tty/serial/amba-pl011.c12
-rw-r--r--drivers/tty/serial/atmel_serial.c2
-rw-r--r--drivers/tty/serial/fsl_lpuart.c15
-rw-r--r--drivers/tty/serial/imx.c47
-rw-r--r--drivers/tty/serial/max310x.c245
-rw-r--r--drivers/tty/serial/meson_uart.c31
-rw-r--r--drivers/tty/serial/mxs-auart.c8
-rw-r--r--drivers/tty/serial/omap-serial.c11
-rw-r--r--drivers/tty/serial/serial_core.c28
-rw-r--r--drivers/tty/serial/stm32-usart.h2
-rw-r--r--drivers/tty/tty_io.c2
-rw-r--r--drivers/tty/vt/selection.c6
-rw-r--r--include/linux/serdev.h7
-rw-r--r--include/linux/serial_core.h6
33 files changed, 379 insertions, 217 deletions
diff --git a/Documentation/devicetree/bindings/serial/fsl-imx-uart.txt b/Documentation/devicetree/bindings/serial/fsl-imx-uart.txt
index 860a955..afcfbc3 100644
--- a/Documentation/devicetree/bindings/serial/fsl-imx-uart.txt
+++ b/Documentation/devicetree/bindings/serial/fsl-imx-uart.txt
@@ -6,10 +6,10 @@ Required properties:
- interrupts : Should contain uart interrupt
Optional properties:
-- fsl,irda-mode : Indicate the uart supports irda mode
- fsl,dte-mode : Indicate the uart works in DTE mode. The uart works
in DCE mode by default.
-- rs485-rts-delay, rs485-rx-during-tx, linux,rs485-enabled-at-boot-time: see rs485.txt
+- rs485-rts-delay, rs485-rts-active-low, rs485-rx-during-tx,
+ linux,rs485-enabled-at-boot-time: see rs485.txt
Please check Documentation/devicetree/bindings/serial/serial.txt
for the complete list of generic properties.
diff --git a/Documentation/devicetree/bindings/serial/fsl-lpuart.txt b/Documentation/devicetree/bindings/serial/fsl-lpuart.txt
index 59567b5..6bd3f2e 100644
--- a/Documentation/devicetree/bindings/serial/fsl-lpuart.txt
+++ b/Documentation/devicetree/bindings/serial/fsl-lpuart.txt
@@ -16,7 +16,8 @@ Required properties:
Optional properties:
- dmas: A list of two dma specifiers, one for each entry in dma-names.
- dma-names: should contain "tx" and "rx".
-- rs485-rts-delay, rs485-rx-during-tx, linux,rs485-enabled-at-boot-time: see rs485.txt
+- rs485-rts-delay, rs485-rts-active-low, rs485-rx-during-tx,
+ linux,rs485-enabled-at-boot-time: see rs485.txt
Note: Optional properties for DMA support. Write them both or both not.
diff --git a/Documentation/devicetree/bindings/serial/maxim,max310x.txt b/Documentation/devicetree/bindings/serial/maxim,max310x.txt
index 83a919c..823f77d 100644
--- a/Documentation/devicetree/bindings/serial/maxim,max310x.txt
+++ b/Documentation/devicetree/bindings/serial/maxim,max310x.txt
@@ -24,13 +24,27 @@ Optional properties:
1 = active low.
Example:
+
+/ {
+ clocks {
+ spi_uart_clk: osc_max14830 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <3686400>;
+ };
+
+ };
+};
+
+&spi0 {
max14830: max14830@0 {
compatible = "maxim,max14830";
reg = <0>;
- clocks = <&clk20m>;
+ clocks = <&spi_uart_clk>;
clock-names = "osc";
interrupt-parent = <&gpio3>;
- interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
+ interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
gpio-controller;
#gpio-cells = <2>;
};
+};
diff --git a/Documentation/devicetree/bindings/serial/mvebu-uart.txt b/Documentation/devicetree/bindings/serial/mvebu-uart.txt
index d37fabe..2ae2fee 100644
--- a/Documentation/devicetree/bindings/serial/mvebu-uart.txt
+++ b/Documentation/devicetree/bindings/serial/mvebu-uart.txt
@@ -1,13 +1,53 @@
-* Marvell UART : Non standard UART used in some of Marvell EBU SoCs (e.g., Armada-3700)
+* Marvell UART : Non standard UART used in some of Marvell EBU SoCs
+ e.g., Armada-3700.
Required properties:
-- compatible: "marvell,armada-3700-uart"
+- compatible:
+ - "marvell,armada-3700-uart" for the standard variant of the UART
+ (32 bytes FIFO, no DMA, level interrupts, 8-bit access to the
+ FIFO, baudrate limited to 230400).
+ - "marvell,armada-3700-uart-ext" for the extended variant of the
+ UART (128 bytes FIFO, DMA, front interrupts, 8-bit or 32-bit
+ accesses to the FIFO, baudrate unlimited by the dividers).
- reg: offset and length of the register set for the device.
-- interrupts: device interrupt
+- clocks: UART reference clock used to derive the baudrate. If no clock
+ is provided (possible only with the "marvell,armada-3700-uart"
+ compatible string for backward compatibility), it will only work
+ if the baudrate was initialized by the bootloader and no baudrate
+ change will then be possible.
+- interrupts:
+ - Must contain three elements for the standard variant of the IP
+ (marvell,armada-3700-uart): "uart-sum", "uart-tx" and "uart-rx",
+ respectively the UART sum interrupt, the UART TX interrupt and
+ UART RX interrupt. A corresponding interrupt-names property must
+ be defined.
+ - Must contain two elements for the extended variant of the IP
+ (marvell,armada-3700-uart-ext): "uart-tx" and "uart-rx",
+ respectively the UART TX interrupt and the UART RX interrupt. A
+ corresponding interrupts-names property must be defined.
+ - For backward compatibility reasons, a single element interrupts
+ property is also supported for the standard variant of the IP,
+ containing only the UART sum interrupt. This form is deprecated
+ and should no longer be used.
Example:
- serial@12000 {
+ uart0: serial@12000 {
compatible = "marvell,armada-3700-uart";
reg = <0x12000 0x200>;
- interrupts = <43>;
+ clocks = <&xtalclk>;
+ interrupts =
+ <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "uart-sum", "uart-tx", "uart-rx";
+ };
+
+ uart1: serial@12200 {
+ compatible = "marvell,armada-3700-uart-ext";
+ reg = <0x12200 0x30>;
+ clocks = <&xtalclk>;
+ interrupts =
+ <GIC_SPI 30 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 31 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "uart-tx", "uart-rx";
};
diff --git a/Documentation/devicetree/bindings/serial/omap_serial.txt b/Documentation/devicetree/bindings/serial/omap_serial.txt
index 43eac67..4b0f05a 100644
--- a/Documentation/devicetree/bindings/serial/omap_serial.txt
+++ b/Documentation/devicetree/bindings/serial/omap_serial.txt
@@ -20,6 +20,7 @@ Optional properties:
node and a DMA channel number.
- dma-names : "rx" for receive channel, "tx" for transmit channel.
- rs485-rts-delay, rs485-rx-during-tx, linux,rs485-enabled-at-boot-time: see rs485.txt
+- rs485-rts-active-high: drive RTS high when sending (default is low).
Example:
diff --git a/Documentation/devicetree/bindings/serial/rs485.txt b/Documentation/devicetree/bindings/serial/rs485.txt
index b841593..b7c29f7 100644
--- a/Documentation/devicetree/bindings/serial/rs485.txt
+++ b/Documentation/devicetree/bindings/serial/rs485.txt
@@ -12,6 +12,7 @@ Optional properties:
* b is the delay between end of data sent and rts signal in milliseconds
it corresponds to the delay after sending data and actual release of the line.
If this property is not specified, <0 0> is assumed.
+- rs485-rts-active-low: drive RTS low when sending (default is high).
- linux,rs485-enabled-at-boot-time: empty property telling to enable the rs485
feature at boot time. It can be disabled later with proper ioctl.
- rs485-rx-during-tx: empty property that enables the receiving of data even
diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt
index c180045..7c1bb3d 100644
--- a/Documentation/driver-model/devres.txt
+++ b/Documentation/driver-model/devres.txt
@@ -384,6 +384,9 @@ RESET
devm_reset_control_get()
devm_reset_controller_register()
+SERDEV
+ devm_serdev_device_open()
+
SLAVE DMA ENGINE
devm_acpi_dma_controller_register()
diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig
index cc2b4d9..b811442 100644
--- a/drivers/tty/Kconfig
+++ b/drivers/tty/Kconfig
@@ -394,10 +394,14 @@ config GOLDFISH_TTY
depends on GOLDFISH
select SERIAL_CORE
select SERIAL_CORE_CONSOLE
- select SERIAL_EARLYCON
help
Console and system TTY driver for the Goldfish virtual platform.
+config GOLDFISH_TTY_EARLY_CONSOLE
+ bool
+ default y if GOLDFISH_TTY=y
+ select SERIAL_EARLYCON
+
config DA_TTY
bool "DA TTY"
depends on METAG_DA
diff --git a/drivers/tty/goldfish.c b/drivers/tty/goldfish.c
index 7f657bb..1c1bd0a 100644
--- a/drivers/tty/goldfish.c
+++ b/drivers/tty/goldfish.c
@@ -433,6 +433,7 @@ static int goldfish_tty_remove(struct platform_device *pdev)
return 0;
}
+#ifdef CONFIG_GOLDFISH_TTY_EARLY_CONSOLE
static void gf_early_console_putchar(struct uart_port *port, int ch)
{
__raw_writel(ch, port->membase);
@@ -456,6 +457,7 @@ static int __init gf_earlycon_setup(struct earlycon_device *device,
}
OF_EARLYCON_DECLARE(early_gf_tty, "google,goldfish-tty", gf_earlycon_setup);
+#endif
static const struct of_device_id goldfish_tty_of_match[] = {
{ .compatible = "google,goldfish-tty", },
diff --git a/drivers/tty/isicom.c b/drivers/tty/isicom.c
index 015686f..bdd3027 100644
--- a/drivers/tty/isicom.c
+++ b/drivers/tty/isicom.c
@@ -219,13 +219,9 @@ static struct isi_port isi_ports[PORT_COUNT];
static int WaitTillCardIsFree(unsigned long base)
{
unsigned int count = 0;
- unsigned int a = in_atomic(); /* do we run under spinlock? */
while (!(inw(base + 0xe) & 0x1) && count++ < 100)
- if (a)
- mdelay(1);
- else
- msleep(1);
+ mdelay(1);
return !(inw(base + 0xe) & 0x1);
}
diff --git a/drivers/tty/moxa.c b/drivers/tty/moxa.c
index 68cbc03..250a19f 100644
--- a/drivers/tty/moxa.c
+++ b/drivers/tty/moxa.c
@@ -1487,8 +1487,6 @@ static void moxa_set_tty_param(struct tty_struct *tty, struct ktermios *old_term
if (ts->c_iflag & IXANY)
xany = 1;
- /* Clear the features we don't support */
- ts->c_cflag &= ~CMSPAR;
MoxaPortFlowCtrl(ch, rts, cts, txflow, rxflow, xany);
baud = MoxaPortSetTermio(ch, ts, tty_get_baud_rate(tty));
if (baud == -1)
@@ -1781,10 +1779,17 @@ static int MoxaPortSetTermio(struct moxa_port *port, struct ktermios *termio,
mode |= MX_STOP1;
if (termio->c_cflag & PARENB) {
- if (termio->c_cflag & PARODD)
- mode |= MX_PARODD;
- else
- mode |= MX_PAREVEN;
+ if (termio->c_cflag & PARODD) {
+ if (termio->c_cflag & CMSPAR)
+ mode |= MX_PARMARK;
+ else
+ mode |= MX_PARODD;
+ } else {
+ if (termio->c_cflag & CMSPAR)
+ mode |= MX_PARSPACE;
+ else
+ mode |= MX_PAREVEN;
+ }
} else
mode |= MX_PARNONE;
diff --git a/drivers/tty/moxa.h b/drivers/tty/moxa.h
index 8ce89fd..563d2dc 100644
--- a/drivers/tty/moxa.h
+++ b/drivers/tty/moxa.h
@@ -301,5 +301,7 @@
#define MX_PARNONE 0x00
#define MX_PAREVEN 0x40
#define MX_PARODD 0xC0
+#define MX_PARMARK 0xA0
+#define MX_PARSPACE 0x20
#endif
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
index 5131bdc..48e791d 100644
--- a/drivers/tty/n_gsm.c
+++ b/drivers/tty/n_gsm.c
@@ -2955,7 +2955,6 @@ static int gsmtty_open(struct tty_struct *tty, struct file *filp)
static void gsmtty_close(struct tty_struct *tty, struct file *filp)
{
struct gsm_dlci *dlci = tty->driver_data;
- struct gsm_mux *gsm;
if (dlci == NULL)
return;
@@ -2964,7 +2963,6 @@ static void gsmtty_close(struct tty_struct *tty, struct file *filp)
mutex_lock(&dlci->mutex);
gsm_destroy_network(dlci);
mutex_unlock(&dlci->mutex);
- gsm = dlci->gsm;
if (tty_port_close_start(&dlci->port, tty, filp) == 0)
return;
gsm_dlci_begin_close(dlci);
diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c
index 1bef398..28133db 100644
--- a/drivers/tty/serdev/core.c
+++ b/drivers/tty/serdev/core.c
@@ -132,6 +132,33 @@ void serdev_device_close(struct serdev_device *serdev)
}
EXPORT_SYMBOL_GPL(serdev_device_close);
+static void devm_serdev_device_release(struct device *dev, void *dr)
+{
+ serdev_device_close(*(struct serdev_device **)dr);
+}
+
+int devm_serdev_device_open(struct device *dev, struct serdev_device *serdev)
+{
+ struct serdev_device **dr;
+ int ret;
+
+ dr = devres_alloc(devm_serdev_device_release, sizeof(*dr), GFP_KERNEL);
+ if (!dr)
+ return -ENOMEM;
+
+ ret = serdev_device_open(serdev);
+ if (ret) {
+ devres_free(dr);
+ return ret;
+ }
+
+ *dr = serdev;
+ devres_add(dev, dr);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(devm_serdev_device_open);
+
void serdev_device_write_wakeup(struct serdev_device *serdev)
{
complete(&serdev->write_comp);
@@ -268,8 +295,8 @@ static int serdev_drv_probe(struct device *dev)
static int serdev_drv_remove(struct device *dev)
{
const struct serdev_device_driver *sdrv = to_serdev_device_driver(dev->driver);
-
- sdrv->remove(to_serdev_device(dev));
+ if (sdrv->remove)
+ sdrv->remove(to_serdev_device(dev));
return 0;
}
diff --git a/drivers/tty/serdev/serdev-ttyport.c b/drivers/tty/serdev/serdev-ttyport.c
index 247788a..a5abb05 100644
--- a/drivers/tty/serdev/serdev-ttyport.c
+++ b/drivers/tty/serdev/serdev-ttyport.c
@@ -59,7 +59,8 @@ static void ttyport_write_wakeup(struct tty_port *port)
test_bit(SERPORT_ACTIVE, &serport->flags))
serdev_controller_write_wakeup(ctrl);
- wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
+ /* Wake up any tty_wait_until_sent() */
+ wake_up_interruptible(&tty->write_wait);
tty_kref_put(tty);
}
@@ -122,6 +123,8 @@ static int ttyport_open(struct serdev_controller *ctrl)
if (ret)
goto err_close;
+ tty_unlock(serport->tty);
+
/* Bring the UART into a known 8 bits no parity hw fc state */
ktermios = tty->termios;
ktermios.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP |
@@ -131,11 +134,12 @@ static int ttyport_open(struct serdev_controller *ctrl)
ktermios.c_cflag &= ~(CSIZE | PARENB);
ktermios.c_cflag |= CS8;
ktermios.c_cflag |= CRTSCTS;
+ /* Hangups are not supported so make sure to ignore carrier detect. */
+ ktermios.c_cflag |= CLOCAL;
tty_set_termios(tty, &ktermios);
set_bit(SERPORT_ACTIVE, &serport->flags);
- tty_unlock(serport->tty);
return 0;
err_close:
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
index 5bb0c42..bda75d3 100644
--- a/drivers/tty/serial/8250/8250_dw.c
+++ b/drivers/tty/serial/8250/8250_dw.c
@@ -515,7 +515,8 @@ static int dw8250_probe(struct platform_device *pdev)
/* If no clock rate is defined, fail. */
if (!p->uartclk) {
dev_err(dev, "clock rate not defined\n");
- return -EINVAL;
+ err = -EINVAL;
+ goto err_clk;
}
data->pclk = devm_clk_get(dev, "apb_pclk");
diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c
index bd40ba4..57f6eba 100644
--- a/drivers/tty/serial/8250/8250_omap.c
+++ b/drivers/tty/serial/8250/8250_omap.c
@@ -414,7 +414,7 @@ static void omap_8250_set_termios(struct uart_port *port,
/* Up to here it was mostly serial8250_do_set_termios() */
/*
- * We enable TRIG_GRANU for RX and TX and additionaly we set
+ * We enable TRIG_GRANU for RX and TX and additionally we set
* SCR_TX_EMPTY bit. The result is the following:
* - RX_TRIGGER amount of bytes in the FIFO will cause an interrupt.
* - less than RX_TRIGGER number of bytes will also cause an interrupt
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
index a5c0ef1..16b1496 100644
--- a/drivers/tty/serial/8250/Kconfig
+++ b/drivers/tty/serial/8250/Kconfig
@@ -5,6 +5,7 @@
config SERIAL_8250
tristate "8250/16550 and compatible serial support"
+ depends on !S390
select SERIAL_CORE
---help---
This selects whether you want to include the driver for the standard
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index b788fee..3682fd3 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -761,24 +761,30 @@ config SERIAL_SH_SCI
select SERIAL_MCTRL_GPIO if GPIOLIB
config SERIAL_SH_SCI_NR_UARTS
- int "Maximum number of SCI(F) serial ports"
+ int "Maximum number of SCI(F) serial ports" if EXPERT
depends on SERIAL_SH_SCI
+ default "3" if H8300
+ default "10" if SUPERH
+ default "18" if ARCH_RENESAS
default "2"
config SERIAL_SH_SCI_CONSOLE
- bool "Support for console on SuperH SCI(F)"
+ bool "Support for console on SuperH SCI(F)" if EXPERT
depends on SERIAL_SH_SCI=y
select SERIAL_CORE_CONSOLE
+ default y
config SERIAL_SH_SCI_EARLYCON
- bool "Support for early console on SuperH SCI(F)"
+ bool "Support for early console on SuperH SCI(F)" if EXPERT
depends on SERIAL_SH_SCI=y
select SERIAL_CORE_CONSOLE
select SERIAL_EARLYCON
+ default ARCH_RENESAS || H8300
config SERIAL_SH_SCI_DMA
- bool "DMA support"
+ bool "DMA support" if EXPERT
depends on SERIAL_SH_SCI && DMA_ENGINE
+ default ARCH_RENESAS
config SERIAL_PNX8XXX
bool "Enable PNX8XXX SoCs' UART Support"
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index 04af8de..4b40a5b 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -314,10 +314,9 @@ static void pl011_write(unsigned int val, const struct uart_amba_port *uap,
static int pl011_fifo_to_tty(struct uart_amba_port *uap)
{
u16 status;
- unsigned int ch, flag, max_count = 256;
- int fifotaken = 0;
+ unsigned int ch, flag, fifotaken;
- while (max_count--) {
+ for (fifotaken = 0; fifotaken != 256; fifotaken++) {
status = pl011_read(uap, REG_FR);
if (status & UART01x_FR_RXFE)
break;
@@ -326,7 +325,6 @@ static int pl011_fifo_to_tty(struct uart_amba_port *uap)
ch = pl011_read(uap, REG_DR) | UART_DUMMY_DR_RX;
flag = TTY_NORMAL;
uap->port.icount.rx++;
- fifotaken++;
if (unlikely(ch & UART_DR_ERROR)) {
if (ch & UART011_DR_BE) {
@@ -1482,12 +1480,10 @@ static irqreturn_t pl011_int(int irq, void *dev_id)
struct uart_amba_port *uap = dev_id;
unsigned long flags;
unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT;
- u16 imsc;
int handled = 0;
spin_lock_irqsave(&uap->port.lock, flags);
- imsc = pl011_read(uap, REG_IMSC);
- status = pl011_read(uap, REG_RIS) & imsc;
+ status = pl011_read(uap, REG_RIS) & uap->im;
if (status) {
do {
check_apply_cts_event_workaround(uap);
@@ -1511,7 +1507,7 @@ static irqreturn_t pl011_int(int irq, void *dev_id)
if (pass_counter-- == 0)
break;
- status = pl011_read(uap, REG_RIS) & imsc;
+ status = pl011_read(uap, REG_RIS) & uap->im;
} while (status != 0);
handled = 1;
}
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
index efa2561..df46a9e 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -2345,7 +2345,7 @@ static int atmel_init_port(struct atmel_uart_port *atmel_port,
atmel_init_property(atmel_port, pdev);
atmel_set_ops(port);
- of_get_rs485_mode(pdev->dev.of_node, &port->rs485);
+ uart_get_rs485_mode(&pdev->dev, &port->rs485);
port->iotype = UPIO_MEM;
port->flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP;
diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 1c4d3f3..8cf112f 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -2206,23 +2206,16 @@ static int lpuart_probe(struct platform_device *pdev)
if (ret)
goto failed_attach_port;
- of_get_rs485_mode(np, &sport->port.rs485);
+ uart_get_rs485_mode(&pdev->dev, &sport->port.rs485);
- if (sport->port.rs485.flags & SER_RS485_RX_DURING_TX) {
+ if (sport->port.rs485.flags & SER_RS485_RX_DURING_TX)
dev_err(&pdev->dev, "driver doesn't support RX during TX\n");
- return -ENOSYS;
- }
if (sport->port.rs485.delay_rts_before_send ||
- sport->port.rs485.delay_rts_after_send) {
+ sport->port.rs485.delay_rts_after_send)
dev_err(&pdev->dev, "driver doesn't support RTS delays\n");
- return -ENOSYS;
- }
- if (sport->port.rs485.flags & SER_RS485_ENABLED) {
- sport->port.rs485.flags |= SER_RS485_RTS_ON_SEND;
- writeb(UARTMODEM_TXRTSE, sport->port.membase + UARTMODEM);
- }
+ lpuart_config_rs485(&sport->port, &sport->port.rs485);
sport->dma_tx_chan = dma_request_slave_channel(sport->port.dev, "tx");
if (!sport->dma_tx_chan)
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index e4b3d91..c2b29fd 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -703,25 +703,6 @@ out:
return IRQ_HANDLED;
}
-static void imx_disable_rx_int(struct imx_port *sport)
-{
- unsigned long temp;
-
- /* disable the receiver ready and aging timer interrupts */
- temp = readl(sport->port.membase + UCR1);
- temp &= ~(UCR1_RRDYEN);
- writel(temp, sport->port.membase + UCR1);
-
- temp = readl(sport->port.membase + UCR2);
- temp &= ~(UCR2_ATEN);
- writel(temp, sport->port.membase + UCR2);
-
- /* disable the rx errors interrupts */
- temp = readl(sport->port.membase + UCR4);
- temp &= ~UCR4_OREN;
- writel(temp, sport->port.membase + UCR4);
-}
-
static void clear_rx_errors(struct imx_port *sport);
/*
@@ -1252,18 +1233,21 @@ static int imx_startup(struct uart_port *port)
if (sport->dma_is_inited && !sport->dma_is_enabled)
imx_enable_dma(sport);
- temp = readl(sport->port.membase + UCR1);
- temp |= UCR1_RRDYEN | UCR1_UARTEN;
+ temp = readl(sport->port.membase + UCR1) & ~UCR1_RRDYEN;
+ if (!sport->dma_is_enabled)
+ temp |= UCR1_RRDYEN;
+ temp |= UCR1_UARTEN;
if (sport->have_rtscts)
temp |= UCR1_RTSDEN;
writel(temp, sport->port.membase + UCR1);
- temp = readl(sport->port.membase + UCR4);
- temp |= UCR4_OREN;
+ temp = readl(sport->port.membase + UCR4) & ~UCR4_OREN;
+ if (!sport->dma_is_enabled)
+ temp |= UCR4_OREN;
writel(temp, sport->port.membase + UCR4);
- temp = readl(sport->port.membase + UCR2);
+ temp = readl(sport->port.membase + UCR2) & ~UCR2_ATEN;
temp |= (UCR2_RXEN | UCR2_TXEN);
if (!sport->have_rtscts)
temp |= UCR2_IRTS;
@@ -1297,10 +1281,8 @@ static int imx_startup(struct uart_port *port)
* In our iMX53 the average delay for the first reception dropped from
* approximately 35000 microseconds to 1000 microseconds.
*/
- if (sport->dma_is_enabled) {
- imx_disable_rx_int(sport);
+ if (sport->dma_is_enabled)
start_rx_dma(sport);
- }
spin_unlock_irqrestore(&sport->port.lock, flags);
@@ -2017,8 +1999,6 @@ static int serial_imx_probe_dt(struct imx_port *sport,
if (of_get_property(np, "rts-gpios", NULL))
sport->have_rtsgpio = 1;
- of_get_rs485_mode(np, &sport->port.rs485);
-
return 0;
}
#else
@@ -2080,7 +2060,6 @@ static int serial_imx_probe(struct platform_device *pdev)
sport->port.fifosize = 32;
sport->port.ops = &imx_pops;
sport->port.rs485_config = imx_rs485_config;
- sport->port.rs485.flags |= SER_RS485_RTS_ON_SEND;
sport->port.flags = UPF_BOOT_AUTOCONF;
timer_setup(&sport->timer, imx_timeout, 0);
@@ -2111,6 +2090,14 @@ static int serial_imx_probe(struct platform_device *pdev)
return ret;
}
+ uart_get_rs485_mode(&pdev->dev, &sport->port.rs485);
+
+ if (sport->port.rs485.flags & SER_RS485_ENABLED &&
+ (!sport->have_rtscts || !sport->have_rtsgpio))
+ dev_err(&pdev->dev, "no RTS control, disabling rs485\n");
+
+ imx_rs485_config(&sport->port, &sport->port.rs485);
+
/* Disable interrupts before requesting them */
reg = readl_relaxed(sport->port.membase + UCR1);
reg &= ~(UCR1_ADEN | UCR1_TRDYEN | UCR1_IDEN | UCR1_RRDYEN |
diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c
index ecb6513..97576ff 100644
--- a/drivers/tty/serial/max310x.c
+++ b/drivers/tty/serial/max310x.c
@@ -233,6 +233,7 @@
/* Misc definitions */
#define MAX310X_FIFO_SIZE (128)
#define MAX310x_REV_MASK (0xf8)
+#define MAX310X_WRITE_BIT 0x80
/* MAX3107 specific */
#define MAX3107_REV_ID (0xa0)
@@ -593,57 +594,118 @@ static int max310x_set_ref_clk(struct max310x_port *s, unsigned long freq,
return (int)bestfreq;
}
-static void max310x_handle_rx(struct uart_port *port, unsigned int rxlen)
+static void max310x_batch_write(struct uart_port *port, u8 *txbuf, unsigned int len)
{
- unsigned int sts, ch, flag;
+ u8 header[] = { (port->iobase + MAX310X_THR_REG) | MAX310X_WRITE_BIT };
+ struct spi_transfer xfer[] = {
+ {
+ .tx_buf = &header,
+ .len = sizeof(header),
+ }, {
+ .tx_buf = txbuf,
+ .len = len,
+ }
+ };
+ spi_sync_transfer(to_spi_device(port->dev), xfer, ARRAY_SIZE(xfer));
+}
- if (unlikely(rxlen >= port->fifosize)) {
- dev_warn_ratelimited(port->dev, "Possible RX FIFO overrun\n");
- port->icount.buf_overrun++;
- /* Ensure sanity of RX level */
- rxlen = port->fifosize;
- }
+static void max310x_batch_read(struct uart_port *port, u8 *rxbuf, unsigned int len)
+{
+ u8 header[] = { port->iobase + MAX310X_RHR_REG };
+ struct spi_transfer xfer[] = {
+ {
+ .tx_buf = &header,
+ .len = sizeof(header),
+ }, {
+ .rx_buf = rxbuf,
+ .len = len,
+ }
+ };
+ spi_sync_transfer(to_spi_device(port->dev), xfer, ARRAY_SIZE(xfer));
+}
- while (rxlen--) {
- ch = max310x_port_read(port, MAX310X_RHR_REG);
- sts = max310x_port_read(port, MAX310X_LSR_IRQSTS_REG);
+static void max310x_handle_rx(struct uart_port *port, unsigned int rxlen)
+{
+ unsigned int sts, ch, flag, i;
+ u8 buf[MAX310X_FIFO_SIZE];
+
+ if (port->read_status_mask == MAX310X_LSR_RXOVR_BIT) {
+ /* We are just reading, happily ignoring any error conditions.
+ * Break condition, parity checking, framing errors -- they
+ * are all ignored. That means that we can do a batch-read.
+ *
+ * There is a small opportunity for race if the RX FIFO
+ * overruns while we're reading the buffer; the datasheets says
+ * that the LSR register applies to the "current" character.
+ * That's also the reason why we cannot do batched reads when
+ * asked to check the individual statuses.
+ * */
- sts &= MAX310X_LSR_RXPAR_BIT | MAX310X_LSR_FRERR_BIT |
- MAX310X_LSR_RXOVR_BIT | MAX310X_LSR_RXBRK_BIT;
+ sts = max310x_port_read(port, MAX310X_LSR_IRQSTS_REG);
+ max310x_batch_read(port, buf, rxlen);
- port->icount.rx++;
+ port->icount.rx += rxlen;
flag = TTY_NORMAL;
+ sts &= port->read_status_mask;
- if (unlikely(sts)) {
- if (sts & MAX310X_LSR_RXBRK_BIT) {
- port->icount.brk++;
- if (uart_handle_break(port))
- continue;
- } else if (sts & MAX310X_LSR_RXPAR_BIT)
- port->icount.parity++;
- else if (sts & MAX310X_LSR_FRERR_BIT)
- port->icount.frame++;
- else if (sts & MAX310X_LSR_RXOVR_BIT)
- port->icount.overrun++;
-
- sts &= port->read_status_mask;
- if (sts & MAX310X_LSR_RXBRK_BIT)
- flag = TTY_BREAK;
- else if (sts & MAX310X_LSR_RXPAR_BIT)
- flag = TTY_PARITY;
- else if (sts & MAX310X_LSR_FRERR_BIT)
- flag = TTY_FRAME;
- else if (sts & MAX310X_LSR_RXOVR_BIT)
- flag = TTY_OVERRUN;
+ if (sts & MAX310X_LSR_RXOVR_BIT) {
+ dev_warn_ratelimited(port->dev, "Hardware RX FIFO overrun\n");
+ port->icount.overrun++;
}
- if (uart_handle_sysrq_char(port, ch))
- continue;
+ for (i = 0; i < rxlen; ++i) {
+ uart_insert_char(port, sts, MAX310X_LSR_RXOVR_BIT, buf[i], flag);
+ }
- if (sts & port->ignore_status_mask)
- continue;
+ } else {
+ if (unlikely(rxlen >= port->fifosize)) {
+ dev_warn_ratelimited(port->dev, "Possible RX FIFO overrun\n");
+ port->icount.buf_overrun++;
+ /* Ensure sanity of RX level */
+ rxlen = port->fifosize;
+ }
- uart_insert_char(port, sts, MAX310X_LSR_RXOVR_BIT, ch, flag);
+ while (rxlen--) {
+ ch = max310x_port_read(port, MAX310X_RHR_REG);
+ sts = max310x_port_read(port, MAX310X_LSR_IRQSTS_REG);
+
+ sts &= MAX310X_LSR_RXPAR_BIT | MAX310X_LSR_FRERR_BIT |
+ MAX310X_LSR_RXOVR_BIT | MAX310X_LSR_RXBRK_BIT;
+
+ port->icount.rx++;
+ flag = TTY_NORMAL;
+
+ if (unlikely(sts)) {
+ if (sts & MAX310X_LSR_RXBRK_BIT) {
+ port->icount.brk++;
+ if (uart_handle_break(port))
+ continue;
+ } else if (sts & MAX310X_LSR_RXPAR_BIT)
+ port->icount.parity++;
+ else if (sts & MAX310X_LSR_FRERR_BIT)
+ port->icount.frame++;
+ else if (sts & MAX310X_LSR_RXOVR_BIT)
+ port->icount.overrun++;
+
+ sts &= port->read_status_mask;
+ if (sts & MAX310X_LSR_RXBRK_BIT)
+ flag = TTY_BREAK;
+ else if (sts & MAX310X_LSR_RXPAR_BIT)
+ flag = TTY_PARITY;
+ else if (sts & MAX310X_LSR_FRERR_BIT)
+ flag = TTY_FRAME;
+ else if (sts & MAX310X_LSR_RXOVR_BIT)
+ flag = TTY_OVERRUN;
+ }
+
+ if (uart_handle_sysrq_char(port, ch))
+ continue;
+
+ if (sts & port->ignore_status_mask)
+ continue;
+
+ uart_insert_char(port, sts, MAX310X_LSR_RXOVR_BIT, ch, flag);
+ }
}
tty_flip_buffer_push(&port->state->port);
@@ -652,7 +714,7 @@ static void max310x_handle_rx(struct uart_port *port, unsigned int rxlen)
static void max310x_handle_tx(struct uart_port *port)
{
struct circ_buf *xmit = &port->state->xmit;
- unsigned int txlen, to_send;
+ unsigned int txlen, to_send, until_end;
if (unlikely(port->x_char)) {
max310x_port_write(port, MAX310X_THR_REG, port->x_char);
@@ -666,28 +728,43 @@ static void max310x_handle_tx(struct uart_port *port)
/* Get length of data pending in circular buffer */
to_send = uart_circ_chars_pending(xmit);
+ until_end = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
if (likely(to_send)) {
/* Limit to size of TX FIFO */
txlen = max310x_port_read(port, MAX310X_TXFIFOLVL_REG);
txlen = port->fifosize - txlen;
to_send = (to_send > txlen) ? txlen : to_send;
+ if (until_end < to_send) {
+ /* It's a circ buffer -- wrap around.
+ * We could do that in one SPI transaction, but meh. */
+ max310x_batch_write(port, xmit->buf + xmit->tail, until_end);
+ max310x_batch_write(port, xmit->buf, to_send - until_end);
+ } else {
+ max310x_batch_write(port, xmit->buf + xmit->tail, to_send);
+ }
+
/* Add data to send */
port->icount.tx += to_send;
- while (to_send--) {
- max310x_port_write(port, MAX310X_THR_REG,
- xmit->buf[xmit->tail]);
- xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
- }
+ xmit->tail = (xmit->tail + to_send) & (UART_XMIT_SIZE - 1);
}
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
uart_write_wakeup(port);
}
-static void max310x_port_irq(struct max310x_port *s, int portno)
+static void max310x_start_tx(struct uart_port *port)
+{
+ struct max310x_one *one = container_of(port, struct max310x_one, port);
+
+ if (!work_pending(&one->tx_work))
+ schedule_work(&one->tx_work);
+}
+
+static irqreturn_t max310x_port_irq(struct max310x_port *s, int portno)
{
struct uart_port *port = &s->p[portno].port;
+ irqreturn_t res = IRQ_NONE;
do {
unsigned int ists, lsr, rxlen;
@@ -698,6 +775,8 @@ static void max310x_port_irq(struct max310x_port *s, int portno)
if (!ists && !rxlen)
break;
+ res = IRQ_HANDLED;
+
if (ists & MAX310X_IRQ_CTS_BIT) {
lsr = max310x_port_read(port, MAX310X_LSR_IRQSTS_REG);
uart_handle_cts_change(port,
@@ -705,17 +784,16 @@ static void max310x_port_irq(struct max310x_port *s, int portno)
}
if (rxlen)
max310x_handle_rx(port, rxlen);
- if (ists & MAX310X_IRQ_TXEMPTY_BIT) {
- mutex_lock(&s->mutex);
- max310x_handle_tx(port);
- mutex_unlock(&s->mutex);
- }
+ if (ists & MAX310X_IRQ_TXEMPTY_BIT)
+ max310x_start_tx(port);
} while (1);
+ return res;
}
static irqreturn_t max310x_ist(int irq, void *dev_id)
{
struct max310x_port *s = (struct max310x_port *)dev_id;
+ bool handled = false;
if (s->devtype->nr > 1) {
do {
@@ -726,12 +804,15 @@ static irqreturn_t max310x_ist(int irq, void *dev_id)
val = ((1 << s->devtype->nr) - 1) & ~val;
if (!val)
break;
- max310x_port_irq(s, fls(val) - 1);
+ if (max310x_port_irq(s, fls(val) - 1) == IRQ_HANDLED)
+ handled = true;
} while (1);
- } else
- max310x_port_irq(s, 0);
+ } else {
+ if (max310x_port_irq(s, 0) == IRQ_HANDLED)
+ handled = true;
+ }
- return IRQ_HANDLED;
+ return IRQ_RETVAL(handled);
}
static void max310x_wq_proc(struct work_struct *ws)
@@ -744,14 +825,6 @@ static void max310x_wq_proc(struct work_struct *ws)
mutex_unlock(&s->mutex);
}
-static void max310x_start_tx(struct uart_port *port)
-{
- struct max310x_one *one = container_of(port, struct max310x_one, port);
-
- if (!work_pending(&one->tx_work))
- schedule_work(&one->tx_work);
-}
-
static unsigned int max310x_tx_empty(struct uart_port *port)
{
unsigned int lvl, sts;
@@ -1089,7 +1162,7 @@ static int max310x_gpio_direction_output(struct gpio_chip *chip,
#endif
static int max310x_probe(struct device *dev, struct max310x_devtype *devtype,
- struct regmap *regmap, int irq, unsigned long flags)
+ struct regmap *regmap, int irq)
{
int i, ret, fmin, fmax, freq, uartclk;
struct clk *clk_osc, *clk_xtal;
@@ -1169,23 +1242,6 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype,
uartclk = max310x_set_ref_clk(s, freq, xtal);
dev_dbg(dev, "Reference clock set to %i Hz\n", uartclk);
-#ifdef CONFIG_GPIOLIB
- /* Setup GPIO cotroller */
- s->gpio.owner = THIS_MODULE;
- s->gpio.parent = dev;
- s->gpio.label = dev_name(dev);
- s->gpio.direction_input = max310x_gpio_direction_input;
- s->gpio.get = max310x_gpio_get;
- s->gpio.direction_output= max310x_gpio_direction_output;
- s->gpio.set = max310x_gpio_set;
- s->gpio.base = -1;
- s->gpio.ngpio = devtype->nr * 4;
- s->gpio.can_sleep = 1;
- ret = devm_gpiochip_add_data(dev, &s->gpio, s);
- if (ret)
- goto out_clk;
-#endif
-
mutex_init(&s->mutex);
for (i = 0; i < devtype->nr; i++) {
@@ -1237,9 +1293,26 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype,
devtype->power(&s->p[i].port, 0);
}
+#ifdef CONFIG_GPIOLIB
+ /* Setup GPIO cotroller */
+ s->gpio.owner = THIS_MODULE;
+ s->gpio.parent = dev;
+ s->gpio.label = dev_name(dev);
+ s->gpio.direction_input = max310x_gpio_direction_input;
+ s->gpio.get = max310x_gpio_get;
+ s->gpio.direction_output= max310x_gpio_direction_output;
+ s->gpio.set = max310x_gpio_set;
+ s->gpio.base = -1;
+ s->gpio.ngpio = devtype->nr * 4;
+ s->gpio.can_sleep = 1;
+ ret = devm_gpiochip_add_data(dev, &s->gpio, s);
+ if (ret)
+ goto out_uart;
+#endif
+
/* Setup interrupt */
ret = devm_request_threaded_irq(dev, irq, NULL, max310x_ist,
- IRQF_ONESHOT | flags, dev_name(dev), s);
+ IRQF_ONESHOT | IRQF_SHARED, dev_name(dev), s);
if (!ret)
return 0;
@@ -1293,7 +1366,7 @@ MODULE_DEVICE_TABLE(of, max310x_dt_ids);
static struct regmap_config regcfg = {
.reg_bits = 8,
.val_bits = 8,
- .write_flag_mask = 0x80,
+ .write_flag_mask = MAX310X_WRITE_BIT,
.cache_type = REGCACHE_RBTREE,
.writeable_reg = max310x_reg_writeable,
.volatile_reg = max310x_reg_volatile,
@@ -1304,7 +1377,6 @@ static struct regmap_config regcfg = {
static int max310x_spi_probe(struct spi_device *spi)
{
struct max310x_devtype *devtype;
- unsigned long flags = 0;
struct regmap *regmap;
int ret;
@@ -1327,11 +1399,10 @@ static int max310x_spi_probe(struct spi_device *spi)
devtype = (struct max310x_devtype *)id_entry->driver_data;
}
- flags = IRQF_TRIGGER_FALLING;
regcfg.max_register = devtype->nr * 0x20 - 1;
regmap = devm_regmap_init_spi(spi, &regcfg);
- return max310x_probe(&spi->dev, devtype, regmap, spi->irq, flags);
+ return max310x_probe(&spi->dev, devtype, regmap, spi->irq);
}
static int max310x_spi_remove(struct spi_device *spi)
diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index daafe60..8a84259 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -34,9 +34,15 @@
/* AML_UART_CONTROL bits */
#define AML_UART_TX_EN BIT(12)
#define AML_UART_RX_EN BIT(13)
+#define AML_UART_TWO_WIRE_EN BIT(15)
+#define AML_UART_STOP_BIT_LEN_MASK (0x03 << 16)
+#define AML_UART_STOP_BIT_1SB (0x00 << 16)
+#define AML_UART_STOP_BIT_2SB (0x01 << 16)
+#define AML_UART_PARITY_TYPE BIT(18)
+#define AML_UART_PARITY_EN BIT(19)
#define AML_UART_TX_RST BIT(22)
#define AML_UART_RX_RST BIT(23)
-#define AML_UART_CLR_ERR BIT(24)
+#define AML_UART_CLEAR_ERR BIT(24)
#define AML_UART_RX_INT_EN BIT(27)
#define AML_UART_TX_INT_EN BIT(28)
#define AML_UART_DATA_LEN_MASK (0x03 << 20)
@@ -57,15 +63,6 @@
AML_UART_FRAME_ERR | \
AML_UART_TX_FIFO_WERR)
-/* AML_UART_CONTROL bits */
-#define AML_UART_TWO_WIRE_EN BIT(15)
-#define AML_UART_PARITY_TYPE BIT(18)
-#define AML_UART_PARITY_EN BIT(19)
-#define AML_UART_CLEAR_ERR BIT(24)
-#define AML_UART_STOP_BIN_LEN_MASK (0x03 << 16)
-#define AML_UART_STOP_BIN_1SB (0x00 << 16)
-#define AML_UART_STOP_BIN_2SB (0x01 << 16)
-
/* AML_UART_MISC bits */
#define AML_UART_XMIT_IRQ(c) (((c) & 0xff) << 8)
#define AML_UART_RECV_IRQ(c) ((c) & 0xff)
@@ -263,10 +260,10 @@ static void meson_uart_reset(struct uart_port *port)
u32 val;
val = readl(port->membase + AML_UART_CONTROL);
- val |= (AML_UART_RX_RST | AML_UART_TX_RST | AML_UART_CLR_ERR);
+ val |= (AML_UART_RX_RST | AML_UART_TX_RST | AML_UART_CLEAR_ERR);
writel(val, port->membase + AML_UART_CONTROL);
- val &= ~(AML_UART_RX_RST | AML_UART_TX_RST | AML_UART_CLR_ERR);
+ val &= ~(AML_UART_RX_RST | AML_UART_TX_RST | AML_UART_CLEAR_ERR);
writel(val, port->membase + AML_UART_CONTROL);
}
@@ -276,9 +273,9 @@ static int meson_uart_startup(struct uart_port *port)
int ret = 0;
val = readl(port->membase + AML_UART_CONTROL);
- val |= AML_UART_CLR_ERR;
+ val |= AML_UART_CLEAR_ERR;
writel(val, port->membase + AML_UART_CONTROL);
- val &= ~AML_UART_CLR_ERR;
+ val &= ~AML_UART_CLEAR_ERR;
writel(val, port->membase + AML_UART_CONTROL);
val |= (AML_UART_RX_EN | AML_UART_TX_EN);
@@ -354,11 +351,11 @@ static void meson_uart_set_termios(struct uart_port *port,
else
val &= ~AML_UART_PARITY_TYPE;
- val &= ~AML_UART_STOP_BIN_LEN_MASK;
+ val &= ~AML_UART_STOP_BIT_LEN_MASK;
if (cflags & CSTOPB)
- val |= AML_UART_STOP_BIN_2SB;
+ val |= AML_UART_STOP_BIT_2SB;
else
- val |= AML_UART_STOP_BIN_1SB;
+ val |= AML_UART_STOP_BIT_1SB;
if (cflags & CRTSCTS)
val &= ~AML_UART_TWO_WIRE_EN;
diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c
index efb4fd3..5b47040 100644
--- a/drivers/tty/serial/mxs-auart.c
+++ b/drivers/tty/serial/mxs-auart.c
@@ -1721,7 +1721,7 @@ static int mxs_auart_probe(struct platform_device *pdev)
ret = uart_add_one_port(&auart_driver, &s->port);
if (ret)
- goto out_free_gpio_irq;
+ goto out_disable_clks_free_qpio_irq;
/* ASM9260 don't have version reg */
if (is_asm9260_auart(s)) {
@@ -1735,7 +1735,11 @@ static int mxs_auart_probe(struct platform_device *pdev)
return 0;
-out_free_gpio_irq:
+out_disable_clks_free_qpio_irq:
+ if (s->clk)
+ clk_disable_unprepare(s->clk_ahb);
+ if (s->clk_ahb)
+ clk_disable_unprepare(s->clk_ahb);
mxs_auart_free_gpio_irq(s);
auart_port[pdev->id] = NULL;
return ret;
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
index 53d59e9..56e6833 100644
--- a/drivers/tty/serial/omap-serial.c
+++ b/drivers/tty/serial/omap-serial.c
@@ -1611,10 +1611,15 @@ static int serial_omap_probe_rs485(struct uart_omap_port *up,
if (!np)
return 0;
- if (of_property_read_bool(np, "rs485-rts-active-high"))
+ uart_get_rs485_mode(up->dev, rs485conf);
+
+ if (of_property_read_bool(np, "rs485-rts-active-high")) {
rs485conf->flags |= SER_RS485_RTS_ON_SEND;
- else
+ rs485conf->flags &= ~SER_RS485_RTS_AFTER_SEND;
+ } else {
+ rs485conf->flags &= ~SER_RS485_RTS_ON_SEND;
rs485conf->flags |= SER_RS485_RTS_AFTER_SEND;
+ }
/* check for tx enable gpio */
up->rts_gpio = of_get_named_gpio_flags(np, "rts-gpio", 0, &flags);
@@ -1632,8 +1637,6 @@ static int serial_omap_probe_rs485(struct uart_omap_port *up,
up->rts_gpio = -EINVAL;
}
- of_get_rs485_mode(np, rs485conf);
-
return 0;
}
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 854995e..f57969d 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -3013,19 +3013,20 @@ EXPORT_SYMBOL(uart_add_one_port);
EXPORT_SYMBOL(uart_remove_one_port);
/**
- * of_get_rs485_mode() - Implement parsing rs485 properties
- * @np: uart node
+ * uart_get_rs485_mode() - retrieve rs485 properties for given uart
+ * @dev: uart device
* @rs485conf: output parameter
*
* This function implements the device tree binding described in
* Documentation/devicetree/bindings/serial/rs485.txt.
*/
-void of_get_rs485_mode(struct device_node *np, struct serial_rs485 *rs485conf)
+void uart_get_rs485_mode(struct device *dev, struct serial_rs485 *rs485conf)
{
u32 rs485_delay[2];
int ret;
- ret = of_property_read_u32_array(np, "rs485-rts-delay", rs485_delay, 2);
+ ret = device_property_read_u32_array(dev, "rs485-rts-delay",
+ rs485_delay, 2);
if (!ret) {
rs485conf->delay_rts_before_send = rs485_delay[0];
rs485conf->delay_rts_after_send = rs485_delay[1];
@@ -3035,18 +3036,25 @@ void of_get_rs485_mode(struct device_node *np, struct serial_rs485 *rs485conf)
}
/*
- * clear full-duplex and enabled flags to get to a defined state with
- * the two following properties.
+ * Clear full-duplex and enabled flags, set RTS polarity to active high
+ * to get to a defined state with the following properties:
*/
- rs485conf->flags &= ~(SER_RS485_RX_DURING_TX | SER_RS485_ENABLED);
+ rs485conf->flags &= ~(SER_RS485_RX_DURING_TX | SER_RS485_ENABLED |
+ SER_RS485_RTS_AFTER_SEND);
+ rs485conf->flags |= SER_RS485_RTS_ON_SEND;
- if (of_property_read_bool(np, "rs485-rx-during-tx"))
+ if (device_property_read_bool(dev, "rs485-rx-during-tx"))
rs485conf->flags |= SER_RS485_RX_DURING_TX;
- if (of_property_read_bool(np, "linux,rs485-enabled-at-boot-time"))
+ if (device_property_read_bool(dev, "linux,rs485-enabled-at-boot-time"))
rs485conf->flags |= SER_RS485_ENABLED;
+
+ if (device_property_read_bool(dev, "rs485-rts-active-low")) {
+ rs485conf->flags &= ~SER_RS485_RTS_ON_SEND;
+ rs485conf->flags |= SER_RS485_RTS_AFTER_SEND;
+ }
}
-EXPORT_SYMBOL_GPL(of_get_rs485_mode);
+EXPORT_SYMBOL_GPL(uart_get_rs485_mode);
MODULE_DESCRIPTION("Serial driver core");
MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/stm32-usart.h b/drivers/tty/serial/stm32-usart.h
index 8a5ff54..2294d0f 100644
--- a/drivers/tty/serial/stm32-usart.h
+++ b/drivers/tty/serial/stm32-usart.h
@@ -236,7 +236,7 @@ struct stm32_usart_info stm32h7_info = {
#define USART_ICR_CMCF BIT(17) /* F7 */
#define USART_ICR_WUCF BIT(20) /* H7 */
-#define STM32_SERIAL_NAME "ttyS"
+#define STM32_SERIAL_NAME "ttySTM"
#define STM32_MAX_PORTS 8
#define RX_BUF_L 200 /* dma rx buffer length */
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index dc60aee..a6ca634 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -1476,6 +1476,8 @@ static void release_tty(struct tty_struct *tty, int idx)
if (tty->link)
tty->link->port->itty = NULL;
tty_buffer_cancel_work(tty->port);
+ if (tty->link)
+ tty_buffer_cancel_work(tty->link->port);
tty_kref_put(tty->link);
tty_kref_put(tty);
diff --git a/drivers/tty/vt/selection.c b/drivers/tty/vt/selection.c
index af4da95..7851383 100644
--- a/drivers/tty/vt/selection.c
+++ b/drivers/tty/vt/selection.c
@@ -186,11 +186,7 @@ int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *t
}
if (ps > pe) /* make sel_start <= sel_end */
- {
- int tmp = ps;
- ps = pe;
- pe = tmp;
- }
+ swap(ps, pe);
if (sel_cons != vc_cons[fg_console].d) {
clear_selection();
diff --git a/include/linux/serdev.h b/include/linux/serdev.h
index d609e6d..48d8ce2 100644
--- a/include/linux/serdev.h
+++ b/include/linux/serdev.h
@@ -27,8 +27,10 @@ struct serdev_device;
/**
* struct serdev_device_ops - Callback operations for a serdev device
- * @receive_buf: Function called with data received from device.
- * @write_wakeup: Function called when ready to transmit more data.
+ * @receive_buf: Function called with data received from device;
+ * returns number of bytes accepted; may sleep.
+ * @write_wakeup: Function called when ready to transmit more data; must
+ * not sleep.
*/
struct serdev_device_ops {
int (*receive_buf)(struct serdev_device *, const unsigned char *, size_t);
@@ -193,6 +195,7 @@ static inline int serdev_controller_receive_buf(struct serdev_controller *ctrl,
int serdev_device_open(struct serdev_device *);
void serdev_device_close(struct serdev_device *);
+int devm_serdev_device_open(struct device *, struct serdev_device *);
unsigned int serdev_device_set_baudrate(struct serdev_device *, unsigned int);
void serdev_device_set_flow_control(struct serdev_device *, bool);
int serdev_device_write_buf(struct serdev_device *, const unsigned char *, size_t);
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 37b044e..b60b225 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -501,9 +501,5 @@ static inline int uart_handle_break(struct uart_port *port)
(cflag) & CRTSCTS || \
!((cflag) & CLOCAL))
-/*
- * Common device tree parsing helpers
- */
-void of_get_rs485_mode(struct device_node *np, struct serial_rs485 *rs485conf);
-
+void uart_get_rs485_mode(struct device *dev, struct serial_rs485 *rs485conf);
#endif /* LINUX_SERIAL_CORE_H */
OpenPOWER on IntegriCloud