diff options
Diffstat (limited to 'drivers/tty/serial')
26 files changed, 226 insertions, 130 deletions
diff --git a/drivers/tty/serial/8250/8250_em.c b/drivers/tty/serial/8250/8250_em.c index 2a76e22d2ec0..db88dee3a399 100644 --- a/drivers/tty/serial/8250/8250_em.c +++ b/drivers/tty/serial/8250/8250_em.c @@ -78,14 +78,18 @@ static void serial8250_em_serial_dl_write(struct uart_8250_port *up, int value) static int serial8250_em_probe(struct platform_device *pdev) { - struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); - struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); struct serial8250_em_priv *priv; struct uart_8250_port up; - int ret; + struct resource *regs; + int irq, ret; - if (!regs || !irq) { - dev_err(&pdev->dev, "missing registers or irq\n"); + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!regs) { + dev_err(&pdev->dev, "missing registers\n"); return -EINVAL; } @@ -101,7 +105,7 @@ static int serial8250_em_probe(struct platform_device *pdev) memset(&up, 0, sizeof(up)); up.port.mapbase = regs->start; - up.port.irq = irq->start; + up.port.irq = irq; up.port.type = PORT_UNKNOWN; up.port.flags = UPF_BOOT_AUTOCONF | UPF_FIXED_PORT | UPF_IOREMAP; up.port.dev = &pdev->dev; diff --git a/drivers/tty/serial/8250/8250_ingenic.c b/drivers/tty/serial/8250/8250_ingenic.c index 424c07c5f629..dde766fa465f 100644 --- a/drivers/tty/serial/8250/8250_ingenic.c +++ b/drivers/tty/serial/8250/8250_ingenic.c @@ -207,12 +207,11 @@ static unsigned int ingenic_uart_serial_in(struct uart_port *p, int offset) static int ingenic_uart_probe(struct platform_device *pdev) { struct uart_8250_port uart = {}; - struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); - struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); struct ingenic_uart_data *data; const struct ingenic_uart_config *cdata; const struct of_device_id *match; - int err, line; + struct resource *regs; + int irq, err, line; match = of_match_device(of_match, &pdev->dev); if (!match) { @@ -221,8 +220,13 @@ static int ingenic_uart_probe(struct platform_device *pdev) } cdata = match->data; - if (!regs || !irq) { - dev_err(&pdev->dev, "no registers/irq defined\n"); + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!regs) { + dev_err(&pdev->dev, "no registers defined\n"); return -EINVAL; } @@ -238,7 +242,7 @@ static int ingenic_uart_probe(struct platform_device *pdev) uart.port.regshift = 2; uart.port.serial_out = ingenic_uart_serial_out; uart.port.serial_in = ingenic_uart_serial_in; - uart.port.irq = irq->start; + uart.port.irq = irq; uart.port.dev = &pdev->dev; uart.port.fifosize = cdata->fifosize; uart.tx_loadsz = cdata->tx_loadsz; diff --git a/drivers/tty/serial/8250/8250_men_mcb.c b/drivers/tty/serial/8250/8250_men_mcb.c index e985f344b2dd..737c4c31e8a0 100644 --- a/drivers/tty/serial/8250/8250_men_mcb.c +++ b/drivers/tty/serial/8250/8250_men_mcb.c @@ -51,7 +51,7 @@ static u32 men_lookup_uartclk(struct mcb_device *mdev) return clkval; } -static unsigned int get_num_ports(struct mcb_device *mdev, +static int get_num_ports(struct mcb_device *mdev, void __iomem *membase) { switch (mdev->id) { @@ -140,7 +140,7 @@ static void serial_8250_men_mcb_remove(struct mcb_device *mdev) return; num_ports = get_num_ports(mdev, data[0].uart.port.membase); - if (num_ports < 0 || num_ports > 4) { + if (num_ports <= 0 || num_ports > 4) { dev_err(&mdev->dev, "error retrieving number of ports!\n"); return; } diff --git a/drivers/tty/serial/8250/8250_mtk.c b/drivers/tty/serial/8250/8250_mtk.c index 98b8a3e30733..7b0dec14c8b8 100644 --- a/drivers/tty/serial/8250/8250_mtk.c +++ b/drivers/tty/serial/8250/8250_mtk.c @@ -512,13 +512,17 @@ static int mtk8250_probe_of(struct platform_device *pdev, struct uart_port *p, static int mtk8250_probe(struct platform_device *pdev) { struct uart_8250_port uart = {}; - struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); - struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); struct mtk8250_data *data; - int err; + struct resource *regs; + int irq, err; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; - if (!regs || !irq) { - dev_err(&pdev->dev, "no registers/irq defined\n"); + regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!regs) { + dev_err(&pdev->dev, "no registers defined\n"); return -EINVAL; } @@ -542,7 +546,7 @@ static int mtk8250_probe(struct platform_device *pdev) spin_lock_init(&uart.port.lock); uart.port.mapbase = regs->start; - uart.port.irq = irq->start; + uart.port.irq = irq; uart.port.pm = mtk8250_do_pm; uart.port.type = PORT_16550; uart.port.flags = UPF_BOOT_AUTOCONF | UPF_FIXED_PORT; diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index 16cfb887c5a3..562087df7d33 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -1209,17 +1209,21 @@ MODULE_DEVICE_TABLE(of, omap8250_dt_ids); static int omap8250_probe(struct platform_device *pdev) { - struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); - struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); struct device_node *np = pdev->dev.of_node; struct omap8250_priv *priv; const struct omap8250_platdata *pdata; struct uart_8250_port up; - int ret; + struct resource *regs; void __iomem *membase; + int irq, ret; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; - if (!regs || !irq) { - dev_err(&pdev->dev, "missing registers or irq\n"); + regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!regs) { + dev_err(&pdev->dev, "missing registers\n"); return -EINVAL; } @@ -1236,7 +1240,7 @@ static int omap8250_probe(struct platform_device *pdev) up.port.dev = &pdev->dev; up.port.mapbase = regs->start; up.port.membase = membase; - up.port.irq = irq->start; + up.port.irq = irq; /* * It claims to be 16C750 compatible however it is a little different. * It has EFR and has no FCR7_64byte bit. The AFE (which it claims to diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index 1632f7d25acc..d64ca77d9cfa 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -16,6 +16,7 @@ #include <linux/ioport.h> #include <linux/init.h> #include <linux/console.h> +#include <linux/gpio/consumer.h> #include <linux/sysrq.h> #include <linux/delay.h> #include <linux/platform_device.h> diff --git a/drivers/tty/serial/8250/8250_pxa.c b/drivers/tty/serial/8250/8250_pxa.c index 11612d174716..33ca98bfa5b3 100644 --- a/drivers/tty/serial/8250/8250_pxa.c +++ b/drivers/tty/serial/8250/8250_pxa.c @@ -18,7 +18,6 @@ #include <linux/serial_core.h> #include <linux/serial_reg.h> #include <linux/of.h> -#include <linux/of_irq.h> #include <linux/of_platform.h> #include <linux/platform_device.h> #include <linux/slab.h> @@ -93,12 +92,15 @@ static int serial_pxa_probe(struct platform_device *pdev) { struct uart_8250_port uart = {}; struct pxa8250_data *data; - struct resource *mmres, *irqres; - int ret; + struct resource *mmres; + int irq, ret; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0); - irqres = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!mmres || !irqres) + if (!mmres) return -ENODEV; data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); @@ -121,7 +123,7 @@ static int serial_pxa_probe(struct platform_device *pdev) uart.port.iotype = UPIO_MEM32; uart.port.mapbase = mmres->start; uart.port.regshift = 2; - uart.port.irq = irqres->start; + uart.port.irq = irq; uart.port.fifosize = 64; uart.port.flags = UPF_IOREMAP | UPF_SKIP_TEST | UPF_FIXED_TYPE; uart.port.dev = &pdev->dev; diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index d2ae033aea40..603137da4736 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig @@ -222,7 +222,7 @@ config SERIAL_8250_MANY_PORTS Say Y here if you have dumb serial boards other than the four standard COM 1/2/3/4 ports. This may happen if you have an AST FourPort, Accent Async, Boca (read the Boca mini-HOWTO, available - from <http://www.tldp.org/docs.html#howto>), or other custom + from <https://www.tldp.org/docs.html#howto>), or other custom serial port hardware which acts similar to standard serial port hardware. If you only use the standard COM 1/2/3/4 ports, you can say N here to save some memory. You can also say Y if you have an @@ -266,7 +266,7 @@ config SERIAL_8250_BOCA depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS help Say Y here if you have a Boca serial board. Please read the Boca - mini-HOWTO, available from <http://www.tldp.org/docs.html#howto> + mini-HOWTO, available from <https://www.tldp.org/docs.html#howto> To compile this driver as a module, choose M here: the module will be called 8250_boca. diff --git a/drivers/tty/serial/altera_jtaguart.c b/drivers/tty/serial/altera_jtaguart.c index c90e503d6b57..d0ca9cf29b62 100644 --- a/drivers/tty/serial/altera_jtaguart.c +++ b/drivers/tty/serial/altera_jtaguart.c @@ -27,7 +27,7 @@ /* * Altera JTAG UART register definitions according to the Altera JTAG UART - * datasheet: http://www.altera.com/literature/hb/nios2/n2cpu_nii51009.pdf + * datasheet: https://www.altera.com/literature/hb/nios2/n2cpu_nii51009.pdf */ #define ALTERA_JTAGUART_SIZE 8 diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 8efd7c2a34fe..c010f639298d 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -2607,7 +2607,6 @@ static int pl011_setup_port(struct device *dev, struct uart_amba_port *uap, uap->port.has_sysrq = IS_ENABLED(CONFIG_SERIAL_AMBA_PL011_CONSOLE); uap->port.flags = UPF_BOOT_AUTOCONF; uap->port.line = index; - spin_lock_init(&uap->port.lock); amba_ports[index] = uap; diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 90298c403042..7ca642249224 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -1925,6 +1925,9 @@ static void __lpuart32_serial_setbrg(struct uart_port *port, tmp_sbr++; } + if (tmp_sbr > UARTBAUD_SBR_MASK) + continue; + if (tmp_diff <= baud_diff) { baud_diff = tmp_diff; osr = tmp_osr; diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 1265e8d86d8a..ba4e35229b36 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -20,6 +20,7 @@ #include <linux/serial.h> #include <linux/clk.h> #include <linux/delay.h> +#include <linux/ktime.h> #include <linux/pinctrl/consumer.h> #include <linux/rational.h> #include <linux/slab.h> @@ -188,6 +189,13 @@ struct imx_uart_data { enum imx_uart_type devtype; }; +enum imx_tx_state { + OFF, + WAIT_AFTER_RTS, + SEND, + WAIT_AFTER_SEND, +}; + struct imx_port { struct uart_port port; struct timer_list timer; @@ -224,6 +232,10 @@ struct imx_port { unsigned int dma_tx_nents; unsigned int saved_reg[10]; bool context_saved; + + enum imx_tx_state tx_state; + struct hrtimer trigger_start_tx; + struct hrtimer trigger_stop_tx; }; struct imx_port_ucrs { @@ -400,6 +412,15 @@ static void imx_uart_rts_inactive(struct imx_port *sport, u32 *ucr2) mctrl_gpio_set(sport->gpios, sport->port.mctrl); } +static void start_hrtimer_ms(struct hrtimer *hrt, unsigned long msec) +{ + long sec = msec / MSEC_PER_SEC; + long nsec = (msec % MSEC_PER_SEC) * 1000000; + ktime_t t = ktime_set(sec, nsec); + + hrtimer_start(hrt, t, HRTIMER_MODE_REL); +} + /* called with port.lock taken and irqs off */ static void imx_uart_start_rx(struct uart_port *port) { @@ -427,7 +448,10 @@ static void imx_uart_start_rx(struct uart_port *port) static void imx_uart_stop_tx(struct uart_port *port) { struct imx_port *sport = (struct imx_port *)port; - u32 ucr1; + u32 ucr1, ucr4, usr2; + + if (sport->tx_state == OFF) + return; /* * We are maybe in the SMP context, so if the DMA TX thread is running @@ -439,21 +463,44 @@ static void imx_uart_stop_tx(struct uart_port *port) ucr1 = imx_uart_readl(sport, UCR1); imx_uart_writel(sport, ucr1 & ~UCR1_TRDYEN, UCR1); - /* in rs485 mode disable transmitter if shifter is empty */ - if (port->rs485.flags & SER_RS485_ENABLED && - imx_uart_readl(sport, USR2) & USR2_TXDC) { - u32 ucr2 = imx_uart_readl(sport, UCR2), ucr4; - if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND) - imx_uart_rts_active(sport, &ucr2); - else - imx_uart_rts_inactive(sport, &ucr2); - imx_uart_writel(sport, ucr2, UCR2); + usr2 = imx_uart_readl(sport, USR2); + if (!(usr2 & USR2_TXDC)) { + /* The shifter is still busy, so retry once TC triggers */ + return; + } - imx_uart_start_rx(port); + ucr4 = imx_uart_readl(sport, UCR4); + ucr4 &= ~UCR4_TCEN; + imx_uart_writel(sport, ucr4, UCR4); - ucr4 = imx_uart_readl(sport, UCR4); - ucr4 &= ~UCR4_TCEN; - imx_uart_writel(sport, ucr4, UCR4); + /* in rs485 mode disable transmitter */ + if (port->rs485.flags & SER_RS485_ENABLED) { + if (sport->tx_state == SEND) { + sport->tx_state = WAIT_AFTER_SEND; + start_hrtimer_ms(&sport->trigger_stop_tx, + port->rs485.delay_rts_after_send); + return; + } + + if (sport->tx_state == WAIT_AFTER_RTS || + sport->tx_state == WAIT_AFTER_SEND) { + u32 ucr2; + + hrtimer_try_to_cancel(&sport->trigger_start_tx); + + ucr2 = imx_uart_readl(sport, UCR2); + if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND) + imx_uart_rts_active(sport, &ucr2); + else + imx_uart_rts_inactive(sport, &ucr2); + imx_uart_writel(sport, ucr2, UCR2); + + imx_uart_start_rx(port); + + sport->tx_state = OFF; + } + } else { + sport->tx_state = OFF; } } @@ -651,28 +698,50 @@ static void imx_uart_start_tx(struct uart_port *port) if (!sport->port.x_char && uart_circ_empty(&port->state->xmit)) return; + /* + * We cannot simply do nothing here if sport->tx_state == SEND already + * because UCR1_TXMPTYEN might already have been cleared in + * imx_uart_stop_tx(), but tx_state is still SEND. + */ + if (port->rs485.flags & SER_RS485_ENABLED) { - u32 ucr2; + if (sport->tx_state == OFF) { + u32 ucr2 = imx_uart_readl(sport, UCR2); + if (port->rs485.flags & SER_RS485_RTS_ON_SEND) + imx_uart_rts_active(sport, &ucr2); + else + imx_uart_rts_inactive(sport, &ucr2); + imx_uart_writel(sport, ucr2, UCR2); - ucr2 = imx_uart_readl(sport, UCR2); - if (port->rs485.flags & SER_RS485_RTS_ON_SEND) - imx_uart_rts_active(sport, &ucr2); - else - imx_uart_rts_inactive(sport, &ucr2); - imx_uart_writel(sport, ucr2, UCR2); + if (!(port->rs485.flags & SER_RS485_RX_DURING_TX)) + imx_uart_stop_rx(port); - if (!(port->rs485.flags & SER_RS485_RX_DURING_TX)) - imx_uart_stop_rx(port); + sport->tx_state = WAIT_AFTER_RTS; + start_hrtimer_ms(&sport->trigger_start_tx, + port->rs485.delay_rts_before_send); + return; + } - /* - * Enable transmitter and shifter empty irq only if DMA is off. - * In the DMA case this is done in the tx-callback. - */ - if (!sport->dma_is_enabled) { - u32 ucr4 = imx_uart_readl(sport, UCR4); - ucr4 |= UCR4_TCEN; - imx_uart_writel(sport, ucr4, UCR4); + if (sport->tx_state == WAIT_AFTER_SEND + || sport->tx_state == WAIT_AFTER_RTS) { + + hrtimer_try_to_cancel(&sport->trigger_stop_tx); + + /* + * Enable transmitter and shifter empty irq only if DMA + * is off. In the DMA case this is done in the + * tx-callback. + */ + if (!sport->dma_is_enabled) { + u32 ucr4 = imx_uart_readl(sport, UCR4); + ucr4 |= UCR4_TCEN; + imx_uart_writel(sport, ucr4, UCR4); + } + + sport->tx_state = SEND; } + } else { + sport->tx_state = SEND; } if (!sport->dma_is_enabled) { @@ -1630,7 +1699,6 @@ imx_uart_set_termios(struct uart_port *port, struct ktermios *termios, if (termios->c_cflag & CRTSCTS) ucr2 &= ~UCR2_IRTS; - if (termios->c_cflag & CSTOPB) ucr2 |= UCR2_STPB; if (termios->c_cflag & PARENB) { @@ -1857,10 +1925,6 @@ static int imx_uart_rs485_config(struct uart_port *port, struct imx_port *sport = (struct imx_port *)port; u32 ucr2; - /* unimplemented */ - rs485conf->delay_rts_before_send = 0; - rs485conf->delay_rts_after_send = 0; - /* RTS is required to control the transmitter */ if (!sport->have_rtscts && !sport->have_rtsgpio) rs485conf->flags &= ~SER_RS485_ENABLED; @@ -2223,6 +2287,32 @@ static void imx_uart_probe_pdata(struct imx_port *sport, sport->have_rtscts = 1; } +static enum hrtimer_restart imx_trigger_start_tx(struct hrtimer *t) +{ + struct imx_port *sport = container_of(t, struct imx_port, trigger_start_tx); + unsigned long flags; + + spin_lock_irqsave(&sport->port.lock, flags); + if (sport->tx_state == WAIT_AFTER_RTS) + imx_uart_start_tx(&sport->port); + spin_unlock_irqrestore(&sport->port.lock, flags); + + return HRTIMER_NORESTART; +} + +static enum hrtimer_restart imx_trigger_stop_tx(struct hrtimer *t) +{ + struct imx_port *sport = container_of(t, struct imx_port, trigger_stop_tx); + unsigned long flags; + + spin_lock_irqsave(&sport->port.lock, flags); + if (sport->tx_state == WAIT_AFTER_SEND) + imx_uart_stop_tx(&sport->port); + spin_unlock_irqrestore(&sport->port.lock, flags); + + return HRTIMER_NORESTART; +} + static int imx_uart_probe(struct platform_device *pdev) { struct imx_port *sport; @@ -2369,6 +2459,11 @@ static int imx_uart_probe(struct platform_device *pdev) clk_disable_unprepare(sport->clk_ipg); + hrtimer_init(&sport->trigger_start_tx, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + hrtimer_init(&sport->trigger_stop_tx, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + sport->trigger_start_tx.function = imx_trigger_start_tx; + sport->trigger_stop_tx.function = imx_trigger_stop_tx; + /* * Allocate the IRQ(s) i.MX1 has three interrupts whereas later * chips only have one interrupt. @@ -2406,9 +2501,6 @@ static int imx_uart_probe(struct platform_device *pdev) } } - /* We need to initialize lock even for non-registered console */ - spin_lock_init(&sport->port.lock); - imx_uart_ports[sport->port.line] = sport; platform_set_drvdata(pdev, sport); diff --git a/drivers/tty/serial/jsm/jsm_driver.c b/drivers/tty/serial/jsm/jsm_driver.c index 592e51d8944e..cd30da0ef083 100644 --- a/drivers/tty/serial/jsm/jsm_driver.c +++ b/drivers/tty/serial/jsm/jsm_driver.c @@ -16,7 +16,7 @@ #include "jsm.h" -MODULE_AUTHOR("Digi International, http://www.digi.com"); +MODULE_AUTHOR("Digi International, https://www.digi.com"); MODULE_DESCRIPTION("Driver for the Digi International Neo and Classic PCI based product line"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("jsm"); diff --git a/drivers/tty/serial/kgdboc.c b/drivers/tty/serial/kgdboc.c index 84ffede27f23..49d0c7f2b29b 100644 --- a/drivers/tty/serial/kgdboc.c +++ b/drivers/tty/serial/kgdboc.c @@ -538,7 +538,8 @@ static int __init kgdboc_earlycon_init(char *opt) if (!con) { /* - * Both earlycon and kgdboc_earlycon are initialized during * early parameter parsing. We cannot guarantee earlycon gets + * Both earlycon and kgdboc_earlycon are initialized during + * early parameter parsing. We cannot guarantee earlycon gets * in first and, in any case, on ACPI systems earlycon may * defer its own initialization (usually to somewhere within * setup_arch() ). To cope with either of these situations diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c index 60a9c53fa7cb..87f005e5d2af 100644 --- a/drivers/tty/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c @@ -696,6 +696,7 @@ static void msm_enable_ms(struct uart_port *port) } static void msm_handle_rx_dm(struct uart_port *port, unsigned int misr) + __must_hold(&port->lock) { struct tty_port *tport = &port->state->port; unsigned int sr; @@ -771,6 +772,7 @@ static void msm_handle_rx_dm(struct uart_port *port, unsigned int misr) } static void msm_handle_rx(struct uart_port *port) + __must_hold(&port->lock) { struct tty_port *tport = &port->state->port; unsigned int sr; diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index 40fa7a27722d..67aca8cb9cd4 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -1857,41 +1857,24 @@ static void pch_uart_pci_remove(struct pci_dev *pdev) kfree(priv); return; } -#ifdef CONFIG_PM -static int pch_uart_pci_suspend(struct pci_dev *pdev, pm_message_t state) + +static int __maybe_unused pch_uart_pci_suspend(struct device *dev) { - struct eg20t_port *priv = pci_get_drvdata(pdev); + struct eg20t_port *priv = dev_get_drvdata(dev); uart_suspend_port(&pch_uart_driver, &priv->port); - pci_save_state(pdev); - pci_set_power_state(pdev, pci_choose_state(pdev, state)); return 0; } -static int pch_uart_pci_resume(struct pci_dev *pdev) +static int __maybe_unused pch_uart_pci_resume(struct device *dev) { - struct eg20t_port *priv = pci_get_drvdata(pdev); - int ret; - - pci_set_power_state(pdev, PCI_D0); - pci_restore_state(pdev); - - ret = pci_enable_device(pdev); - if (ret) { - dev_err(&pdev->dev, - "%s-pci_enable_device failed(ret=%d) ", __func__, ret); - return ret; - } + struct eg20t_port *priv = dev_get_drvdata(dev); uart_resume_port(&pch_uart_driver, &priv->port); return 0; } -#else -#define pch_uart_pci_suspend NULL -#define pch_uart_pci_resume NULL -#endif static const struct pci_device_id pch_uart_pci_id[] = { {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8811), @@ -1945,13 +1928,16 @@ probe_error: return ret; } +static SIMPLE_DEV_PM_OPS(pch_uart_pci_pm_ops, + pch_uart_pci_suspend, + pch_uart_pci_resume); + static struct pci_driver pch_uart_pci_driver = { .name = "pch_uart", .id_table = pch_uart_pci_id, .probe = pch_uart_pci_probe, .remove = pch_uart_pci_remove, - .suspend = pch_uart_pci_suspend, - .resume = pch_uart_pci_resume, + .driver.pm = &pch_uart_pci_pm_ops, }; static int __init pch_uart_module_init(void) diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c index ba65a3bbd72a..96e7aa479961 100644 --- a/drivers/tty/serial/pmac_zilog.c +++ b/drivers/tty/serial/pmac_zilog.c @@ -213,6 +213,7 @@ static void pmz_interrupt_control(struct uart_pmac_port *uap, int enable) } static bool pmz_receive_chars(struct uart_pmac_port *uap) + __must_hold(&uap->port.lock) { struct tty_port *port; unsigned char ch, r1, drop, flag; diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c index 457c0bf8cbf8..1ed3d354e16d 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -718,7 +718,7 @@ static void qcom_geni_serial_handle_tx(struct uart_port *uport, bool done, u8 buf[sizeof(u32)]; int c; - memset(buf, 0, ARRAY_SIZE(buf)); + memset(buf, 0, sizeof(buf)); tx_bytes = min_t(size_t, remaining, port->tx_bytes_pw); for (c = 0; c < tx_bytes ; c++) { diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c index d913d9b2762a..8ed3482d2e1e 100644 --- a/drivers/tty/serial/samsung_tty.c +++ b/drivers/tty/serial/samsung_tty.c @@ -6,7 +6,7 @@ * http://armlinux.simtec.co.uk/ */ -/* Hote on 2410 error handling +/* Note on 2410 error handling * * The s3c2410 manual has a love/hate affair with the contents of the * UERSTAT register in the UART blocks, and keeps marking some of the @@ -327,7 +327,6 @@ static void s3c24xx_serial_tx_dma_complete(void *args) unsigned long flags; int count; - dmaengine_tx_status(dma->tx_chan, dma->tx_cookie, &state); count = dma->tx_bytes_requested - state.residue; async_tx_ack(dma->tx_desc); @@ -409,7 +408,6 @@ static int s3c24xx_serial_start_tx_dma(struct s3c24xx_uart_port *ourport, struct circ_buf *xmit = &port->state->xmit; struct s3c24xx_uart_dma *dma = ourport->dma; - if (ourport->tx_mode != S3C24XX_TX_DMA) enable_tx_dma(ourport); @@ -816,7 +814,6 @@ static irqreturn_t s3c24xx_serial_rx_chars_pio(void *dev_id) return IRQ_HANDLED; } - static irqreturn_t s3c24xx_serial_rx_chars(int irq, void *dev_id) { struct s3c24xx_uart_port *ourport = dev_id; @@ -842,8 +839,8 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id) count >= ourport->min_dma_size) { int align = dma_get_cache_alignment() - (xmit->tail & (dma_get_cache_alignment() - 1)); - if (count-align >= ourport->min_dma_size) { - dma_count = count-align; + if (count - align >= ourport->min_dma_size) { + dma_count = count - align; count = align; } } @@ -1589,7 +1586,6 @@ s3c24xx_serial_verify_port(struct uart_port *port, struct serial_struct *ser) return 0; } - #ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE static struct console s3c24xx_serial_console; @@ -1672,7 +1668,6 @@ s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS] = { } }, #if CONFIG_SERIAL_SAMSUNG_UARTS > 2 - [2] = { .port = { .lock = __PORT_LOCK_UNLOCKED(2), @@ -1728,7 +1723,6 @@ static void s3c24xx_serial_resetport(struct uart_port *port, udelay(1); } - #ifdef CONFIG_ARM_S3C24XX_CPUFREQ static int s3c24xx_serial_cpufreq_transition(struct notifier_block *nb, @@ -1903,9 +1897,9 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, port->mapbase = res->start; ret = platform_get_irq(platdev, 0); - if (ret < 0) + if (ret < 0) { port->irq = 0; - else { + } else { port->irq = ret; ourport->rx_irq = ret; ourport->tx_irq = ret + 1; @@ -1977,8 +1971,8 @@ static const struct of_device_id s3c24xx_uart_dt_match[]; static int probe_index; -static inline struct s3c24xx_serial_drv_data *s3c24xx_get_driver_data( - struct platform_device *pdev) +static inline struct s3c24xx_serial_drv_data * +s3c24xx_get_driver_data(struct platform_device *pdev) { #ifdef CONFIG_OF if (pdev->dev.of_node) { @@ -2329,7 +2323,6 @@ s3c24xx_serial_get_options(struct uart_port *port, int *baud, *baud = rate / (16 * (ubrdiv + 1)); dev_dbg(port->dev, "calculated baud %d\n", *baud); } - } static int __init @@ -2696,6 +2689,7 @@ static int __init s3c2410_early_console_setup(struct earlycon_device *device, device->port.private_data = &s3c2410_early_console_data; return samsung_early_console_setup(device, opt); } + OF_EARLYCON_DECLARE(s3c2410, "samsung,s3c2410-uart", s3c2410_early_console_setup); @@ -2710,6 +2704,7 @@ static int __init s3c2440_early_console_setup(struct earlycon_device *device, device->port.private_data = &s3c2440_early_console_data; return samsung_early_console_setup(device, opt); } + OF_EARLYCON_DECLARE(s3c2412, "samsung,s3c2412-uart", s3c2440_early_console_setup); OF_EARLYCON_DECLARE(s3c2440, "samsung,s3c2440-uart", @@ -2728,6 +2723,7 @@ static int __init s5pv210_early_console_setup(struct earlycon_device *device, device->port.private_data = &s5pv210_early_console_data; return samsung_early_console_setup(device, opt); } + OF_EARLYCON_DECLARE(s5pv210, "samsung,s5pv210-uart", s5pv210_early_console_setup); OF_EARLYCON_DECLARE(exynos4210, "samsung,exynos4210-uart", diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c index 04d1b0807e66..b87914ae6da8 100644 --- a/drivers/tty/serial/serial-tegra.c +++ b/drivers/tty/serial/serial-tegra.c @@ -439,16 +439,16 @@ static char tegra_uart_decode_rx_error(struct tegra_uart_port *tup, /* Overrrun error */ flag = TTY_OVERRUN; tup->uport.icount.overrun++; - dev_err(tup->uport.dev, "Got overrun errors\n"); + dev_dbg(tup->uport.dev, "Got overrun errors\n"); } else if (lsr & UART_LSR_PE) { /* Parity error */ flag = TTY_PARITY; tup->uport.icount.parity++; - dev_err(tup->uport.dev, "Got Parity errors\n"); + dev_dbg(tup->uport.dev, "Got Parity errors\n"); } else if (lsr & UART_LSR_FE) { flag = TTY_FRAME; tup->uport.icount.frame++; - dev_err(tup->uport.dev, "Got frame errors\n"); + dev_dbg(tup->uport.dev, "Got frame errors\n"); } else if (lsr & UART_LSR_BI) { /* * Break error diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 5f3daabdc916..3403dd790517 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -14,6 +14,7 @@ #include <linux/sched/signal.h> #include <linux/init.h> #include <linux/console.h> +#include <linux/gpio/consumer.h> #include <linux/of.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> @@ -1120,7 +1121,7 @@ out: return ret; } -static int uart_do_autoconfig(struct tty_struct *tty,struct uart_state *state) +static int uart_do_autoconfig(struct tty_struct *tty, struct uart_state *state) { struct tty_port *port = &state->port; struct uart_port *uport; @@ -1523,6 +1524,7 @@ static void uart_set_termios(struct tty_struct *tty, /* Handle transition away from B0 status */ else if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) { unsigned int mask = TIOCM_DTR; + if (!(cflag & CRTSCTS) || !tty_throttled(tty)) mask |= TIOCM_RTS; uart_set_mctrl(uport, mask); @@ -2279,6 +2281,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) if (console_suspend_enabled || !uart_console(uport)) { /* Protected by port mutex for now */ struct tty_struct *tty = port->tty; + ret = ops->startup(uport); if (ret == 0) { if (tty) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 204bb68ce3ca..e1179e74a2b8 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -3301,9 +3301,6 @@ static int sci_probe_single(struct platform_device *dev, sciport->port.flags |= UPF_HARD_FLOW; } - if (sci_uart_driver.cons->index == sciport->port.line) - spin_lock_init(&sciport->port.lock); - ret = uart_add_one_port(&sci_uart_driver, &sciport->port); if (ret) { sci_cleanup_single(sciport); diff --git a/drivers/tty/serial/sifive.c b/drivers/tty/serial/sifive.c index 0b5110dad051..13eadcb8aec4 100644 --- a/drivers/tty/serial/sifive.c +++ b/drivers/tty/serial/sifive.c @@ -883,7 +883,6 @@ console_initcall(sifive_console_init); static void __ssp_add_console_port(struct sifive_serial_port *ssp) { - spin_lock_init(&ssp->port.lock); sifive_serial_console_ports[ssp->port.line] = ssp; } diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c index 8602ff357321..d1c5e536a167 100644 --- a/drivers/tty/serial/stm32-usart.c +++ b/drivers/tty/serial/stm32-usart.c @@ -1033,8 +1033,9 @@ static struct stm32_port *stm32_of_get_stm32_port(struct platform_device *pdev) if (WARN_ON(id >= STM32_MAX_PORTS)) return NULL; - stm32_ports[id].hw_flow_control = of_property_read_bool(np, - "st,hw-flow-ctrl"); + stm32_ports[id].hw_flow_control = + of_property_read_bool (np, "st,hw-flow-ctrl") /*deprecated*/ || + of_property_read_bool (np, "uart-has-rtscts"); stm32_ports[id].port.line = id; stm32_ports[id].cr1_irq = USART_CR1_RXNEIE; stm32_ports[id].cr3_irq = 0; diff --git a/drivers/tty/serial/sunhv.c b/drivers/tty/serial/sunhv.c index e35073e93a5b..eafada8fb6fa 100644 --- a/drivers/tty/serial/sunhv.c +++ b/drivers/tty/serial/sunhv.c @@ -567,9 +567,6 @@ static int hv_probe(struct platform_device *op) sunserial_console_match(&sunhv_console, op->dev.of_node, &sunhv_reg, port->line, false); - /* We need to initialize lock even for non-registered console */ - spin_lock_init(&port->lock); - err = uart_add_one_port(&sunhv_reg, port); if (err) goto out_unregister_driver; diff --git a/drivers/tty/serial/uartlite.c b/drivers/tty/serial/uartlite.c index 7dbd0c471d92..09379db613d8 100644 --- a/drivers/tty/serial/uartlite.c +++ b/drivers/tty/serial/uartlite.c @@ -32,7 +32,7 @@ * Register definitions * * For register details see datasheet: - * http://www.xilinx.com/support/documentation/ip_documentation/opb_uartlite.pdf + * https://www.xilinx.com/support/documentation/ip_documentation/opb_uartlite.pdf */ #define ULITE_RX 0x00 |