summaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/serial')
-rw-r--r--drivers/tty/serial/8250/8250_dw.c33
-rw-r--r--drivers/tty/serial/8250/8250_exar.c34
-rw-r--r--drivers/tty/serial/8250/8250_ingenic.c17
-rw-r--r--drivers/tty/serial/8250/8250_of.c5
-rw-r--r--drivers/tty/serial/8250/8250_omap.c2
-rw-r--r--drivers/tty/serial/8250/8250_port.c26
-rw-r--r--drivers/tty/serial/8250/8250_uniphier.c5
-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.c93
-rw-r--r--drivers/tty/serial/jsm/jsm_neo.c6
-rw-r--r--drivers/tty/serial/jsm/jsm_tty.c6
-rw-r--r--drivers/tty/serial/max310x.c267
-rw-r--r--drivers/tty/serial/meson_uart.c31
-rw-r--r--drivers/tty/serial/mxs-auart.c11
-rw-r--r--drivers/tty/serial/omap-serial.c18
-rw-r--r--drivers/tty/serial/serial_core.c35
-rw-r--r--drivers/tty/serial/stm32-usart.h2
21 files changed, 365 insertions, 270 deletions
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
index 5bb0c42c88dd..cd1b94a0f451 100644
--- a/drivers/tty/serial/8250/8250_dw.c
+++ b/drivers/tty/serial/8250/8250_dw.c
@@ -252,31 +252,25 @@ static void dw8250_set_termios(struct uart_port *p, struct ktermios *termios,
struct ktermios *old)
{
unsigned int baud = tty_termios_baud_rate(termios);
- unsigned int target_rate, min_rate, max_rate;
struct dw8250_data *d = p->private_data;
long rate;
- int i, ret;
+ int ret;
if (IS_ERR(d->clk) || !old)
goto out;
- /* Find a clk rate within +/-1.6% of an integer multiple of baudx16 */
- target_rate = baud * 16;
- min_rate = target_rate - (target_rate >> 6);
- max_rate = target_rate + (target_rate >> 6);
-
- for (i = 1; i <= UART_DIV_MAX; i++) {
- rate = clk_round_rate(d->clk, i * target_rate);
- if (rate >= i * min_rate && rate <= i * max_rate)
- break;
- }
- if (i <= UART_DIV_MAX) {
- clk_disable_unprepare(d->clk);
+ clk_disable_unprepare(d->clk);
+ rate = clk_round_rate(d->clk, baud * 16);
+ if (rate < 0)
+ ret = rate;
+ else if (rate == 0)
+ ret = -ENOENT;
+ else
ret = clk_set_rate(d->clk, rate);
- clk_prepare_enable(d->clk);
- if (!ret)
- p->uartclk = rate;
- }
+ clk_prepare_enable(d->clk);
+
+ if (!ret)
+ p->uartclk = rate;
out:
p->status &= ~UPSTAT_AUTOCTS;
@@ -515,7 +509,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_exar.c b/drivers/tty/serial/8250/8250_exar.c
index a402878c9f30..38af306ca0e8 100644
--- a/drivers/tty/serial/8250/8250_exar.c
+++ b/drivers/tty/serial/8250/8250_exar.c
@@ -34,6 +34,7 @@
#define PCI_DEVICE_ID_EXAR_XR17V4358 0x4358
#define PCI_DEVICE_ID_EXAR_XR17V8358 0x8358
+#define UART_EXAR_INT0 0x80
#define UART_EXAR_8XMODE 0x88 /* 8X sampling rate select */
#define UART_EXAR_FCTR 0x08 /* Feature Control Register */
@@ -121,6 +122,7 @@ struct exar8250_board {
struct exar8250 {
unsigned int nr;
struct exar8250_board *board;
+ void __iomem *virt;
int line[0];
};
@@ -131,12 +133,9 @@ static int default_setup(struct exar8250 *priv, struct pci_dev *pcidev,
const struct exar8250_board *board = priv->board;
unsigned int bar = 0;
- if (!pcim_iomap_table(pcidev)[bar] && !pcim_iomap(pcidev, bar, 0))
- return -ENOMEM;
-
port->port.iotype = UPIO_MEM;
port->port.mapbase = pci_resource_start(pcidev, bar) + offset;
- port->port.membase = pcim_iomap_table(pcidev)[bar] + offset;
+ port->port.membase = priv->virt + offset;
port->port.regshift = board->reg_shift;
return 0;
@@ -420,6 +419,25 @@ static void pci_xr17v35x_exit(struct pci_dev *pcidev)
port->port.private_data = NULL;
}
+/*
+ * These Exar UARTs have an extra interrupt indicator that could fire for a
+ * few interrupts that are not presented/cleared through IIR. One of which is
+ * a wakeup interrupt when coming out of sleep. These interrupts are only
+ * cleared by reading global INT0 or INT1 registers as interrupts are
+ * associated with channel 0. The INT[3:0] registers _are_ accessible from each
+ * channel's address space, but for the sake of bus efficiency we register a
+ * dedicated handler at the PCI device level to handle them.
+ */
+static irqreturn_t exar_misc_handler(int irq, void *data)
+{
+ struct exar8250 *priv = data;
+
+ /* Clear all PCI interrupts by reading INT0. No effect on IIR */
+ ioread8(priv->virt + UART_EXAR_INT0);
+
+ return IRQ_HANDLED;
+}
+
static int
exar_pci_probe(struct pci_dev *pcidev, const struct pci_device_id *ent)
{
@@ -448,6 +466,9 @@ exar_pci_probe(struct pci_dev *pcidev, const struct pci_device_id *ent)
return -ENOMEM;
priv->board = board;
+ priv->virt = pcim_iomap(pcidev, bar, 0);
+ if (!priv->virt)
+ return -ENOMEM;
pci_set_master(pcidev);
@@ -461,6 +482,11 @@ exar_pci_probe(struct pci_dev *pcidev, const struct pci_device_id *ent)
uart.port.irq = pci_irq_vector(pcidev, 0);
uart.port.dev = &pcidev->dev;
+ rc = devm_request_irq(&pcidev->dev, uart.port.irq, exar_misc_handler,
+ IRQF_SHARED, "exar_uart", priv);
+ if (rc)
+ return rc;
+
for (i = 0; i < nr_ports && i < maxnr; i++) {
rc = board->setup(priv, pcidev, &uart, i);
if (rc) {
diff --git a/drivers/tty/serial/8250/8250_ingenic.c b/drivers/tty/serial/8250/8250_ingenic.c
index 6af84900870e..15a8c8dfa92b 100644
--- a/drivers/tty/serial/8250/8250_ingenic.c
+++ b/drivers/tty/serial/8250/8250_ingenic.c
@@ -91,14 +91,22 @@ static int __init ingenic_early_console_setup(struct earlycon_device *dev,
const char *opt)
{
struct uart_port *port = &dev->port;
- unsigned int baud, divisor;
+ unsigned int divisor;
+ int baud = 115200;
if (!dev->port.membase)
return -ENODEV;
+ if (opt) {
+ unsigned int parity, bits, flow; /* unused for now */
+
+ uart_parse_options(opt, &baud, &parity, &bits, &flow);
+ }
+
ingenic_early_console_setup_clock(dev);
- baud = dev->baud ?: 115200;
+ if (dev->baud)
+ baud = dev->baud;
divisor = DIV_ROUND_CLOSEST(port->uartclk, 16 * baud);
early_out(port, UART_IER, 0);
@@ -125,6 +133,10 @@ EARLYCON_DECLARE(jz4740_uart, ingenic_early_console_setup);
OF_EARLYCON_DECLARE(jz4740_uart, "ingenic,jz4740-uart",
ingenic_early_console_setup);
+EARLYCON_DECLARE(jz4770_uart, ingenic_early_console_setup);
+OF_EARLYCON_DECLARE(jz4770_uart, "ingenic,jz4770-uart",
+ ingenic_early_console_setup);
+
EARLYCON_DECLARE(jz4775_uart, ingenic_early_console_setup);
OF_EARLYCON_DECLARE(jz4775_uart, "ingenic,jz4775-uart",
ingenic_early_console_setup);
@@ -319,6 +331,7 @@ static const struct ingenic_uart_config jz4780_uart_config = {
static const struct of_device_id of_match[] = {
{ .compatible = "ingenic,jz4740-uart", .data = &jz4740_uart_config },
{ .compatible = "ingenic,jz4760-uart", .data = &jz4760_uart_config },
+ { .compatible = "ingenic,jz4770-uart", .data = &jz4760_uart_config },
{ .compatible = "ingenic,jz4775-uart", .data = &jz4760_uart_config },
{ .compatible = "ingenic,jz4780-uart", .data = &jz4780_uart_config },
{ /* sentinel */ }
diff --git a/drivers/tty/serial/8250/8250_of.c b/drivers/tty/serial/8250/8250_of.c
index 1e67a7e4a5fd..160b8906d9b9 100644
--- a/drivers/tty/serial/8250/8250_of.c
+++ b/drivers/tty/serial/8250/8250_of.c
@@ -136,8 +136,11 @@ static int of_platform_serial_setup(struct platform_device *ofdev,
}
info->rst = devm_reset_control_get_optional_shared(&ofdev->dev, NULL);
- if (IS_ERR(info->rst))
+ if (IS_ERR(info->rst)) {
+ ret = PTR_ERR(info->rst);
goto err_dispose;
+ }
+
ret = reset_control_deassert(info->rst);
if (ret)
goto err_dispose;
diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c
index bd40ba402410..57f6eba47f44 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/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index 11434551ac0a..1328c7e70108 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -441,7 +441,6 @@ static void io_serial_out(struct uart_port *p, int offset, int value)
}
static int serial8250_default_handle_irq(struct uart_port *port);
-static int exar_handle_irq(struct uart_port *port);
static void set_io_from_upio(struct uart_port *p)
{
@@ -1884,26 +1883,6 @@ static int serial8250_default_handle_irq(struct uart_port *port)
}
/*
- * These Exar UARTs have an extra interrupt indicator that could
- * fire for a few unimplemented interrupts. One of which is a
- * wakeup event when coming out of sleep. Put this here just
- * to be on the safe side that these interrupts don't go unhandled.
- */
-static int exar_handle_irq(struct uart_port *port)
-{
- unsigned int iir = serial_port_in(port, UART_IIR);
- int ret = 0;
-
- if (((port->type == PORT_XR17V35X) || (port->type == PORT_XR17D15X)) &&
- serial_port_in(port, UART_EXAR_INT0) != 0)
- ret = 1;
-
- ret |= serial8250_handle_irq(port, iir);
-
- return ret;
-}
-
-/*
* Newer 16550 compatible parts such as the SC16C650 & Altera 16550 Soft IP
* have a programmable TX threshold that triggers the THRE interrupt in
* the IIR register. In this case, the THRE interrupt indicates the FIFO
@@ -3067,11 +3046,6 @@ static void serial8250_config_port(struct uart_port *port, int flags)
if (port->type == PORT_UNKNOWN)
serial8250_release_std_resource(up);
- /* Fixme: probably not the best place for this */
- if ((port->type == PORT_XR17V35X) ||
- (port->type == PORT_XR17D15X))
- port->handle_irq = exar_handle_irq;
-
register_dev_spec_attr_grp(up);
up->fcr = uart_config[up->port.type].fcr;
}
diff --git a/drivers/tty/serial/8250/8250_uniphier.c b/drivers/tty/serial/8250/8250_uniphier.c
index 45ef506293ae..28d88ccf5a0c 100644
--- a/drivers/tty/serial/8250/8250_uniphier.c
+++ b/drivers/tty/serial/8250/8250_uniphier.c
@@ -250,12 +250,13 @@ static int uniphier_uart_probe(struct platform_device *pdev)
up.dl_read = uniphier_serial_dl_read;
up.dl_write = uniphier_serial_dl_write;
- priv->line = serial8250_register_8250_port(&up);
- if (priv->line < 0) {
+ ret = serial8250_register_8250_port(&up);
+ if (ret < 0) {
dev_err(dev, "failed to register 8250 port\n");
clk_disable_unprepare(priv->clk);
return ret;
}
+ priv->line = ret;
platform_set_drvdata(pdev, priv);
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
index a5c0ef1e7695..16b1496e6105 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 b788fee54249..3682fd3e960c 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 04af8de8617e..4b40a5b449ee 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 efa25611ca0c..df46a9e88c34 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 1c4d3f387138..8cf112f2efc3 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 e4b3d9123a03..1d7ca382bc12 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 |
@@ -2232,29 +2219,28 @@ static void serial_imx_enable_wakeup(struct imx_port *sport, bool on)
unsigned int val;
val = readl(sport->port.membase + UCR3);
- if (on)
+ if (on) {
+ writel(USR1_AWAKE, sport->port.membase + USR1);
val |= UCR3_AWAKEN;
+ }
else
val &= ~UCR3_AWAKEN;
writel(val, sport->port.membase + UCR3);
- val = readl(sport->port.membase + UCR1);
- if (on)
- val |= UCR1_RTSDEN;
- else
- val &= ~UCR1_RTSDEN;
- writel(val, sport->port.membase + UCR1);
+ if (sport->have_rtscts) {
+ val = readl(sport->port.membase + UCR1);
+ if (on)
+ val |= UCR1_RTSDEN;
+ else
+ val &= ~UCR1_RTSDEN;
+ writel(val, sport->port.membase + UCR1);
+ }
}
static int imx_serial_port_suspend_noirq(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct imx_port *sport = platform_get_drvdata(pdev);
- int ret;
-
- ret = clk_enable(sport->clk_ipg);
- if (ret)
- return ret;
serial_imx_save_context(sport);
@@ -2275,8 +2261,6 @@ static int imx_serial_port_resume_noirq(struct device *dev)
serial_imx_restore_context(sport);
- clk_disable(sport->clk_ipg);
-
return 0;
}
@@ -2284,15 +2268,19 @@ static int imx_serial_port_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct imx_port *sport = platform_get_drvdata(pdev);
-
- /* enable wakeup from i.MX UART */
- serial_imx_enable_wakeup(sport, true);
+ int ret;
uart_suspend_port(&imx_reg, &sport->port);
disable_irq(sport->port.irq);
- /* Needed to enable clock in suspend_noirq */
- return clk_prepare(sport->clk_ipg);
+ ret = clk_prepare_enable(sport->clk_ipg);
+ if (ret)
+ return ret;
+
+ /* enable wakeup from i.MX UART */
+ serial_imx_enable_wakeup(sport, true);
+
+ return 0;
}
static int imx_serial_port_resume(struct device *dev)
@@ -2306,7 +2294,7 @@ static int imx_serial_port_resume(struct device *dev)
uart_resume_port(&imx_reg, &sport->port);
enable_irq(sport->port.irq);
- clk_unprepare(sport->clk_ipg);
+ clk_disable_unprepare(sport->clk_ipg);
return 0;
}
@@ -2318,8 +2306,7 @@ static int imx_serial_port_freeze(struct device *dev)
uart_suspend_port(&imx_reg, &sport->port);
- /* Needed to enable clock in suspend_noirq */
- return clk_prepare(sport->clk_ipg);
+ return clk_prepare_enable(sport->clk_ipg);
}
static int imx_serial_port_thaw(struct device *dev)
@@ -2329,7 +2316,7 @@ static int imx_serial_port_thaw(struct device *dev)
uart_resume_port(&imx_reg, &sport->port);
- clk_unprepare(sport->clk_ipg);
+ clk_disable_unprepare(sport->clk_ipg);
return 0;
}
diff --git a/drivers/tty/serial/jsm/jsm_neo.c b/drivers/tty/serial/jsm/jsm_neo.c
index 4718560b8fdc..bf0e2a4cb0ce 100644
--- a/drivers/tty/serial/jsm/jsm_neo.c
+++ b/drivers/tty/serial/jsm/jsm_neo.c
@@ -282,9 +282,6 @@ static void neo_copy_data_from_uart_to_queue(struct jsm_channel *ch)
u16 head;
u16 tail;
- if (!ch)
- return;
-
/* cache head and tail of queue */
head = ch->ch_r_head & RQUEUEMASK;
tail = ch->ch_r_tail & RQUEUEMASK;
@@ -1175,6 +1172,9 @@ static irqreturn_t neo_intr(int irq, void *voidbrd)
continue;
ch = brd->channels[port];
+ if (!ch)
+ continue;
+
neo_copy_data_from_uart_to_queue(ch);
/* Call our tty layer to enforce queue flow control if needed. */
diff --git a/drivers/tty/serial/jsm/jsm_tty.c b/drivers/tty/serial/jsm/jsm_tty.c
index 469927d37b41..b6bd6e15e07b 100644
--- a/drivers/tty/serial/jsm/jsm_tty.c
+++ b/drivers/tty/serial/jsm/jsm_tty.c
@@ -523,9 +523,6 @@ void jsm_input(struct jsm_channel *ch)
jsm_dbg(READ, &ch->ch_bd->pci_dev, "start\n");
- if (!ch)
- return;
-
port = &ch->uart_port.state->port;
tp = port->tty;
@@ -648,11 +645,8 @@ static void jsm_carrier(struct jsm_channel *ch)
int phys_carrier = 0;
jsm_dbg(CARR, &ch->ch_bd->pci_dev, "start\n");
- if (!ch)
- return;
bd = ch->ch_bd;
-
if (!bd)
return;
diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c
index ecb6513a6505..39f635812077 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);
+ }
+
+ } 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;
+ }
+
+ 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 (sts & port->ignore_status_mask)
- continue;
+ if (uart_handle_sysrq_char(port, ch))
+ continue;
- uart_insert_char(port, sts, MAX310X_LSR_RXOVR_BIT, ch, flag);
+ 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;
@@ -1086,10 +1159,31 @@ static int max310x_gpio_direction_output(struct gpio_chip *chip,
return 0;
}
+
+static int max310x_gpio_set_config(struct gpio_chip *chip, unsigned int offset,
+ unsigned long config)
+{
+ struct max310x_port *s = gpiochip_get_data(chip);
+ struct uart_port *port = &s->p[offset / 4].port;
+
+ switch (pinconf_to_config_param(config)) {
+ case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+ max310x_port_update(port, MAX310X_GPIOCFG_REG,
+ 1 << ((offset % 4) + 4),
+ 1 << ((offset % 4) + 4));
+ return 0;
+ case PIN_CONFIG_DRIVE_PUSH_PULL:
+ max310x_port_update(port, MAX310X_GPIOCFG_REG,
+ 1 << ((offset % 4) + 4), 0);
+ return 0;
+ default:
+ return -ENOTSUPP;
+ }
+}
#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 +1263,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 +1314,27 @@ 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.set_config = max310x_gpio_set_config;
+ 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 +1388,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 +1399,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 +1421,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 daafe60175da..8a842591b37c 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 efb4fd3784ed..079dc47aa142 100644
--- a/drivers/tty/serial/mxs-auart.c
+++ b/drivers/tty/serial/mxs-auart.c
@@ -40,7 +40,6 @@
#include <asm/cacheflush.h>
-#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/err.h>
#include <linux/irq.h>
@@ -1597,7 +1596,7 @@ static int mxs_auart_init_gpios(struct mxs_auart_port *s, struct device *dev)
for (i = 0; i < UART_GPIO_MAX; i++) {
gpiod = mctrl_gpio_to_gpiod(s->gpios, i);
- if (gpiod && (gpiod_get_direction(gpiod) == GPIOF_DIR_IN))
+ if (gpiod && (gpiod_get_direction(gpiod) == 1))
s->gpio_irq[i] = gpiod_to_irq(gpiod);
else
s->gpio_irq[i] = -EINVAL;
@@ -1721,7 +1720,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 +1734,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 53d59e9b944a..6420ae581a80 100644
--- a/drivers/tty/serial/omap-serial.c
+++ b/drivers/tty/serial/omap-serial.c
@@ -1602,7 +1602,6 @@ static int serial_omap_probe_rs485(struct uart_omap_port *up,
struct device_node *np)
{
struct serial_rs485 *rs485conf = &up->port.rs485;
- enum of_gpio_flags flags;
int ret;
rs485conf->flags = 0;
@@ -1611,19 +1610,24 @@ 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);
+ up->rts_gpio = of_get_named_gpio(np, "rts-gpio", 0);
if (gpio_is_valid(up->rts_gpio)) {
ret = devm_gpio_request(up->dev, up->rts_gpio, "omap-serial");
if (ret < 0)
return ret;
- ret = gpio_direction_output(up->rts_gpio,
- flags & SER_RS485_RTS_AFTER_SEND);
+ ret = rs485conf->flags & SER_RS485_RTS_AFTER_SEND ? 1 : 0;
+ ret = gpio_direction_output(up->rts_gpio, ret);
if (ret < 0)
return ret;
} else if (up->rts_gpio == -EPROBE_DEFER) {
@@ -1632,8 +1636,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 854995e1cae7..c8dde56b532b 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -974,6 +974,8 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port,
}
} else {
retval = uart_startup(tty, state, 1);
+ if (retval == 0)
+ tty_port_set_initialized(port, true);
if (retval > 0)
retval = 0;
}
@@ -1955,9 +1957,10 @@ EXPORT_SYMBOL_GPL(uart_parse_earlycon);
* eg: 115200n8r
*/
void
-uart_parse_options(char *options, int *baud, int *parity, int *bits, int *flow)
+uart_parse_options(const char *options, int *baud, int *parity,
+ int *bits, int *flow)
{
- char *s = options;
+ const char *s = options;
*baud = simple_strtoul(s, NULL, 10);
while (*s >= '0' && *s <= '9')
@@ -3013,19 +3016,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 +3039,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 8a5ff54d0f42..2294d0f05872 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 */
OpenPOWER on IntegriCloud