From cb3ea80b7c84a2bb521f41af75678667dddca544 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 15 Jul 2021 15:07:59 +0100 Subject: serial: 8250: 8250_omap: make a const array static, makes object smaller Don't populate the const array k3_soc_devices on the stack but instead it static. Makes the object code smaller by 44 bytes: Before: text data bss dec hex filename 31628 5609 128 37365 91f5 drivers/tty/serial/8250/8250_omap.o After: text data bss dec hex filename 31520 5673 128 37321 91c9 drivers/tty/serial/8250/8250_omap.o Reduction of 44 bytes (gcc version 10.3.0) Signed-off-by: Colin Ian King Link: https://lore.kernel.org/r/20210715140759.27244-1-colin.king@canonical.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_omap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index 79418d4beb48..b81d1bdc7b88 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -538,7 +538,7 @@ static void omap_8250_pm(struct uart_port *port, unsigned int state, static void omap_serial_fill_features_erratas(struct uart_8250_port *up, struct omap8250_priv *priv) { - const struct soc_device_attribute k3_soc_devices[] = { + static const struct soc_device_attribute k3_soc_devices[] = { { .family = "AM65X", }, { .family = "J721E", .revision = "SR1.0" }, { /* sentinel */ } -- cgit v1.2.3-58-ga151 From 130432076f3b44dab19a5872b59fcfbb50a4ed2d Mon Sep 17 00:00:00 2001 From: Jianmin Lv Date: Thu, 15 Jul 2021 14:16:37 +0800 Subject: serial: 8250_pnp: Support configurable clock frequency ACPI-based Loongson boards need configurable rather than fixed clock frequency for serial ports. Signed-off-by: Jianmin Lv Signed-off-by: Huacai Chen Link: https://lore.kernel.org/r/20210715061637.134436-1-chenhuacai@loongson.cn Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_pnp.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/8250/8250_pnp.c b/drivers/tty/serial/8250/8250_pnp.c index de90d681b64c..98e5ee4d0d08 100644 --- a/drivers/tty/serial/8250/8250_pnp.c +++ b/drivers/tty/serial/8250/8250_pnp.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -475,6 +476,7 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) if (pnp_irq_flags(dev, 0) & IORESOURCE_IRQ_SHAREABLE) uart.port.flags |= UPF_SHARE_IRQ; uart.port.uartclk = 1843200; + device_property_read_u32(&dev->dev, "clock-frequency", &uart.port.uartclk); uart.port.dev = &dev->dev; line = serial8250_register_8250_port(&uart); -- cgit v1.2.3-58-ga151 From 8a66b31a15966ea4a206819804ae627874b90d15 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 19 Jul 2021 10:55:33 +0100 Subject: serial: 8250_bcm7271: use NULL to initialized a null pointer Pointer membase is currently being in initialized with zero rather than NULL. Fix this. Acked-by: Florian Fainelli Signed-off-by: Colin Ian King Link: https://lore.kernel.org/r/20210719095533.14017-1-colin.king@canonical.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_bcm7271.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/8250/8250_bcm7271.c b/drivers/tty/serial/8250/8250_bcm7271.c index 725a450058f8..7f656fac503f 100644 --- a/drivers/tty/serial/8250/8250_bcm7271.c +++ b/drivers/tty/serial/8250/8250_bcm7271.c @@ -941,7 +941,7 @@ static int brcmuart_probe(struct platform_device *pdev) struct clk *baud_mux_clk; struct uart_8250_port up; struct resource *irq; - void __iomem *membase = 0; + void __iomem *membase = NULL; resource_size_t mapbase = 0; u32 clk_rate = 0; int ret; -- cgit v1.2.3-58-ga151 From b1442c55ce8977aa304c9f5a078e895fac5d1d63 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 15 Jul 2021 10:30:11 +0200 Subject: serial: 8250: extend compile-test coverage Allow more drivers to be compile tested more easily, for example, when doing subsystem-wide changes. Verified on X86_64 as well as arm, powerpc and m68k with minimal configs in order to catch missing implicit build dependencies. Signed-off-by: Johan Hovold Link: https://lore.kernel.org/r/20210715083011.18887-1-johan@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/Kconfig | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index d1b3c2373fa4..71ae16de0f90 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig @@ -363,7 +363,7 @@ config SERIAL_8250_BCM2835AUX config SERIAL_8250_FSL bool depends on SERIAL_8250_CONSOLE - default PPC || ARM || ARM64 + default PPC || ARM || ARM64 || COMPILE_TEST config SERIAL_8250_DW tristate "Support for Synopsys DesignWare 8250 quirks" @@ -375,7 +375,8 @@ config SERIAL_8250_DW config SERIAL_8250_EM tristate "Support for Emma Mobile integrated serial port" - depends on SERIAL_8250 && ARM && HAVE_CLK + depends on SERIAL_8250 && HAVE_CLK + depends on ARM || COMPILE_TEST help Selecting this option will add support for the integrated serial port hardware found on the Emma Mobile line of processors. @@ -383,7 +384,8 @@ config SERIAL_8250_EM config SERIAL_8250_IOC3 tristate "SGI IOC3 8250 UART support" - depends on SGI_MFD_IOC3 && SERIAL_8250 + depends on SERIAL_8250 + depends on SGI_MFD_IOC3 || COMPILE_TEST select SERIAL_8250_EXTENDED select SERIAL_8250_SHARE_IRQ help @@ -495,7 +497,7 @@ config SERIAL_8250_MID config SERIAL_8250_PXA tristate "PXA serial port support" depends on SERIAL_8250 - depends on ARCH_PXA || ARCH_MMP + depends on ARCH_PXA || ARCH_MMP || COMPILE_TEST help If you have a machine based on an Intel XScale PXA2xx CPU you can enable its onboard serial ports by enabling this option. The option is -- cgit v1.2.3-58-ga151 From e7b91932f6223f2996560662623f1c9730fea21f Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 26 Jun 2021 06:11:21 +0200 Subject: serial: core: Report magic multiplier extra baud rates Report extra baud rates supported above the base rate for ports with the UPF_MAGIC_MULTIPLIER property, so that people have a way to find out that they can be used with their system, e.g.: Serial: 8250/16550 driver, 5 ports, IRQ sharing enabled printk: console [ttyS0] disabled serial8250.0: ttyS0 at I/O 0x3f8 (irq = 4, base_baud = 115200) is a 16550A serial8250.0: ttyS0 extra baud rates supported: 230400, 460800 printk: console [ttyS0] enabled printk: bootconsole [uart8250] disabled serial8250.0: ttyS1 at I/O 0x2f8 (irq = 3, base_baud = 115200) is a 16550A serial8250.0: ttyS1 extra baud rates supported: 230400, 460800 serial8250.0: ttyS2 at MMIO 0x1f000900 (irq = 20, base_baud = 230400) is a 16550A Otherwise there is no clear way to figure this out, as the feature is only reported as an obscure TTY flag in bit 16: $ cat /sys/class/tty/ttyS[0-2]/flags 0x10010040 0x10010040 0x90000040 $ Signed-off-by: Maciej W. Rozycki Link: https://lore.kernel.org/r/alpine.DEB.2.21.2106260334170.37803@angie.orcam.me.uk Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/serial_core.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 69092deba11f..79bd2f44d765 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -2314,6 +2314,14 @@ uart_report_port(struct uart_driver *drv, struct uart_port *port) port->dev ? ": " : "", port->name, address, port->irq, port->uartclk / 16, uart_type(port)); + + /* The magic multiplier feature is a bit obscure, so report it too. */ + if (port->flags & UPF_MAGIC_MULTIPLIER) + pr_info("%s%s%s extra baud rates supported: %d, %d", + port->dev ? dev_name(port->dev) : "", + port->dev ? ": " : "", + port->name, + port->uartclk / 8, port->uartclk / 4); } static void -- cgit v1.2.3-58-ga151 From 240e126c28df084222f0b661321e8e3ecb0d232e Mon Sep 17 00:00:00 2001 From: Zheyu Ma Date: Wed, 14 Jul 2021 05:53:23 +0000 Subject: tty: serial: jsm: hold port lock when reporting modem line changes uart_handle_dcd_change() requires a port lock to be held and will emit a warning when lockdep is enabled. Held corresponding lock to fix the following warnings. [ 132.528648] WARNING: CPU: 5 PID: 11600 at drivers/tty/serial/serial_core.c:3046 uart_handle_dcd_change+0xf4/0x120 [ 132.530482] Modules linked in: [ 132.531050] CPU: 5 PID: 11600 Comm: jsm Not tainted 5.14.0-rc1-00003-g7fef2edf7cc7-dirty #31 [ 132.535268] RIP: 0010:uart_handle_dcd_change+0xf4/0x120 [ 132.557100] Call Trace: [ 132.557562] ? __free_pages+0x83/0xb0 [ 132.558213] neo_parse_modem+0x156/0x220 [ 132.558897] neo_param+0x399/0x840 [ 132.559495] jsm_tty_open+0x12f/0x2d0 [ 132.560131] uart_startup.part.18+0x153/0x340 [ 132.560888] ? lock_is_held_type+0xe9/0x140 [ 132.561660] uart_port_activate+0x7f/0xe0 [ 132.562351] ? uart_startup.part.18+0x340/0x340 [ 132.563003] tty_port_open+0x8d/0xf0 [ 132.563523] ? uart_set_options+0x1e0/0x1e0 [ 132.564125] uart_open+0x24/0x40 [ 132.564604] tty_open+0x15c/0x630 Signed-off-by: Zheyu Ma Link: https://lore.kernel.org/r/1626242003-3809-1-git-send-email-zheyuma97@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/jsm/jsm_neo.c | 2 ++ drivers/tty/serial/jsm/jsm_tty.c | 3 +++ 2 files changed, 5 insertions(+) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/jsm/jsm_neo.c b/drivers/tty/serial/jsm/jsm_neo.c index bf0e2a4cb0ce..c6f927a76c3b 100644 --- a/drivers/tty/serial/jsm/jsm_neo.c +++ b/drivers/tty/serial/jsm/jsm_neo.c @@ -815,7 +815,9 @@ static void neo_parse_isr(struct jsm_board *brd, u32 port) /* Parse any modem signal changes */ jsm_dbg(INTR, &ch->ch_bd->pci_dev, "MOD_STAT: sending to parse_modem_sigs\n"); + spin_lock_irqsave(&ch->uart_port.lock, lock_flags); neo_parse_modem(ch, readb(&ch->ch_neo_uart->msr)); + spin_unlock_irqrestore(&ch->uart_port.lock, lock_flags); } } diff --git a/drivers/tty/serial/jsm/jsm_tty.c b/drivers/tty/serial/jsm/jsm_tty.c index 8e42a7682c63..d74cbbbf33c6 100644 --- a/drivers/tty/serial/jsm/jsm_tty.c +++ b/drivers/tty/serial/jsm/jsm_tty.c @@ -187,6 +187,7 @@ static void jsm_tty_break(struct uart_port *port, int break_state) static int jsm_tty_open(struct uart_port *port) { + unsigned long lock_flags; struct jsm_board *brd; struct jsm_channel *channel = container_of(port, struct jsm_channel, uart_port); @@ -240,6 +241,7 @@ static int jsm_tty_open(struct uart_port *port) channel->ch_cached_lsr = 0; channel->ch_stops_sent = 0; + spin_lock_irqsave(&port->lock, lock_flags); termios = &port->state->port.tty->termios; channel->ch_c_cflag = termios->c_cflag; channel->ch_c_iflag = termios->c_iflag; @@ -259,6 +261,7 @@ static int jsm_tty_open(struct uart_port *port) jsm_carrier(channel); channel->ch_open_count++; + spin_unlock_irqrestore(&port->lock, lock_flags); jsm_dbg(OPEN, &channel->ch_bd->pci_dev, "finish\n"); return 0; -- cgit v1.2.3-58-ga151 From 8d479237727ce10260bb128c2414489e1d59c103 Mon Sep 17 00:00:00 2001 From: Lino Sanfilippo Date: Thu, 1 Jul 2021 00:56:44 +0200 Subject: serial: amba-pl011: add RS485 support Add basic support for RS485: Provide a callback to configure RS485 settings. Handle the RS485 specific part in the functions pl011_rs485_tx_start() and pl011_rs485_tx_stop() which extend the generic start/stop callbacks. Beside via IOCTL from userspace RS485 can be enabled by means of the device tree property "rs485-enabled-at-boot-time". Signed-off-by: Lino Sanfilippo Link: https://lore.kernel.org/r/20210630225644.3744-1-LinoSanfilippo@gmx.de Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl011.c | 163 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 161 insertions(+), 2 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index e14f3378b8a0..d361cd84ff8c 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -265,6 +265,8 @@ struct uart_amba_port { unsigned int old_cr; /* state during shutdown */ unsigned int fixed_baud; /* vendor-set fixed baud rate */ char type[12]; + bool rs485_tx_started; + unsigned int rs485_tx_drain_interval; /* usecs */ #ifdef CONFIG_DMA_ENGINE /* DMA stuff */ bool using_tx_dma; @@ -275,6 +277,8 @@ struct uart_amba_port { #endif }; +static unsigned int pl011_tx_empty(struct uart_port *port); + static unsigned int pl011_reg_to_offset(const struct uart_amba_port *uap, unsigned int reg) { @@ -1282,6 +1286,42 @@ static inline bool pl011_dma_rx_running(struct uart_amba_port *uap) #define pl011_dma_flush_buffer NULL #endif +static void pl011_rs485_tx_stop(struct uart_amba_port *uap) +{ + struct uart_port *port = &uap->port; + int i = 0; + u32 cr; + + /* Wait until hardware tx queue is empty */ + while (!pl011_tx_empty(port)) { + if (i == port->fifosize) { + dev_warn(port->dev, + "timeout while draining hardware tx queue\n"); + break; + } + + udelay(uap->rs485_tx_drain_interval); + i++; + } + + if (port->rs485.delay_rts_after_send) + mdelay(port->rs485.delay_rts_after_send); + + cr = pl011_read(uap, REG_CR); + + if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND) + cr &= ~UART011_CR_RTS; + else + cr |= UART011_CR_RTS; + + /* Disable the transmitter and reenable the transceiver */ + cr &= ~UART011_CR_TXE; + cr |= UART011_CR_RXE; + pl011_write(cr, uap, REG_CR); + + uap->rs485_tx_started = false; +} + static void pl011_stop_tx(struct uart_port *port) { struct uart_amba_port *uap = @@ -1290,6 +1330,9 @@ static void pl011_stop_tx(struct uart_port *port) uap->im &= ~UART011_TXIM; pl011_write(uap->im, uap, REG_IMSC); pl011_dma_tx_stop(uap); + + if ((port->rs485.flags & SER_RS485_ENABLED) && uap->rs485_tx_started) + pl011_rs485_tx_stop(uap); } static bool pl011_tx_chars(struct uart_amba_port *uap, bool from_irq); @@ -1380,6 +1423,32 @@ static bool pl011_tx_char(struct uart_amba_port *uap, unsigned char c, return true; } +static void pl011_rs485_tx_start(struct uart_amba_port *uap) +{ + struct uart_port *port = &uap->port; + u32 cr; + + /* Enable transmitter */ + cr = pl011_read(uap, REG_CR); + cr |= UART011_CR_TXE; + + /* Disable receiver if half-duplex */ + if (!(port->rs485.flags & SER_RS485_RX_DURING_TX)) + cr &= ~UART011_CR_RXE; + + if (port->rs485.flags & SER_RS485_RTS_ON_SEND) + cr &= ~UART011_CR_RTS; + else + cr |= UART011_CR_RTS; + + pl011_write(cr, uap, REG_CR); + + if (port->rs485.delay_rts_before_send) + mdelay(port->rs485.delay_rts_before_send); + + uap->rs485_tx_started = true; +} + /* Returns true if tx interrupts have to be (kept) enabled */ static bool pl011_tx_chars(struct uart_amba_port *uap, bool from_irq) { @@ -1397,6 +1466,10 @@ static bool pl011_tx_chars(struct uart_amba_port *uap, bool from_irq) return false; } + if ((uap->port.rs485.flags & SER_RS485_ENABLED) && + !uap->rs485_tx_started) + pl011_rs485_tx_start(uap); + /* If we are using DMA mode, try to send some characters. */ if (pl011_dma_tx_irq(uap)) return true; @@ -1542,6 +1615,9 @@ static void pl011_set_mctrl(struct uart_port *port, unsigned int mctrl) container_of(port, struct uart_amba_port, port); unsigned int cr; + if (port->rs485.flags & SER_RS485_ENABLED) + mctrl &= ~TIOCM_RTS; + cr = pl011_read(uap, REG_CR); #define TIOCMBIT(tiocmbit, uartbit) \ @@ -1763,7 +1839,17 @@ static int pl011_startup(struct uart_port *port) /* restore RTS and DTR */ cr = uap->old_cr & (UART011_CR_RTS | UART011_CR_DTR); - cr |= UART01x_CR_UARTEN | UART011_CR_RXE | UART011_CR_TXE; + cr |= UART01x_CR_UARTEN | UART011_CR_RXE; + + if (port->rs485.flags & SER_RS485_ENABLED) { + if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND) + cr &= ~UART011_CR_RTS; + else + cr |= UART011_CR_RTS; + } else { + cr |= UART011_CR_TXE; + } + pl011_write(cr, uap, REG_CR); spin_unlock_irq(&uap->port.lock); @@ -1864,6 +1950,9 @@ static void pl011_shutdown(struct uart_port *port) pl011_dma_shutdown(uap); + if ((port->rs485.flags & SER_RS485_ENABLED) && uap->rs485_tx_started) + pl011_rs485_tx_stop(uap); + free_irq(uap->port.irq, uap); pl011_disable_uart(uap); @@ -1941,6 +2030,7 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, unsigned int lcr_h, old_cr; unsigned long flags; unsigned int baud, quot, clkdiv; + unsigned int bits; if (uap->vendor->oversampling) clkdiv = 8; @@ -1991,6 +2081,8 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, if (uap->fifosize > 1) lcr_h |= UART01x_LCRH_FEN; + bits = tty_get_frame_size(termios->c_cflag); + spin_lock_irqsave(&port->lock, flags); /* @@ -1998,11 +2090,21 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, */ uart_update_timeout(port, termios->c_cflag, baud); + /* + * Calculate the approximated time it takes to transmit one character + * with the given baud rate. We use this as the poll interval when we + * wait for the tx queue to empty. + */ + uap->rs485_tx_drain_interval = (bits * 1000 * 1000) / baud; + pl011_setup_status_masks(port, termios); if (UART_ENABLE_MS(port, termios->c_cflag)) pl011_enable_ms(port); + if (port->rs485.flags & SER_RS485_ENABLED) + termios->c_cflag &= ~CRTSCTS; + /* first, disable everything */ old_cr = pl011_read(uap, REG_CR); pl011_write(0, uap, REG_CR); @@ -2124,6 +2226,41 @@ static int pl011_verify_port(struct uart_port *port, struct serial_struct *ser) return ret; } +static int pl011_rs485_config(struct uart_port *port, + struct serial_rs485 *rs485) +{ + struct uart_amba_port *uap = + container_of(port, struct uart_amba_port, port); + + /* pick sane settings if the user hasn't */ + if (!(rs485->flags & SER_RS485_RTS_ON_SEND) == + !(rs485->flags & SER_RS485_RTS_AFTER_SEND)) { + rs485->flags |= SER_RS485_RTS_ON_SEND; + rs485->flags &= ~SER_RS485_RTS_AFTER_SEND; + } + /* clamp the delays to [0, 100ms] */ + rs485->delay_rts_before_send = min(rs485->delay_rts_before_send, 100U); + rs485->delay_rts_after_send = min(rs485->delay_rts_after_send, 100U); + memset(rs485->padding, 0, sizeof(rs485->padding)); + + if (port->rs485.flags & SER_RS485_ENABLED) + pl011_rs485_tx_stop(uap); + + /* Set new configuration */ + port->rs485 = *rs485; + + /* Make sure auto RTS is disabled */ + if (port->rs485.flags & SER_RS485_ENABLED) { + u32 cr = pl011_read(uap, REG_CR); + + cr &= ~UART011_CR_RTSEN; + pl011_write(cr, uap, REG_CR); + port->status &= ~UPSTAT_AUTORTS; + } + + return 0; +} + static const struct uart_ops amba_pl011_pops = { .tx_empty = pl011_tx_empty, .set_mctrl = pl011_set_mctrl, @@ -2588,10 +2725,28 @@ static int pl011_find_free_port(void) return -EBUSY; } +static int pl011_get_rs485_mode(struct uart_amba_port *uap) +{ + struct uart_port *port = &uap->port; + struct serial_rs485 *rs485 = &port->rs485; + int ret; + + ret = uart_get_rs485_mode(port); + if (ret) + return ret; + + /* clamp the delays to [0, 100ms] */ + rs485->delay_rts_before_send = min(rs485->delay_rts_before_send, 100U); + rs485->delay_rts_after_send = min(rs485->delay_rts_after_send, 100U); + + return 0; +} + static int pl011_setup_port(struct device *dev, struct uart_amba_port *uap, struct resource *mmiobase, int index) { void __iomem *base; + int ret; base = devm_ioremap_resource(dev, mmiobase); if (IS_ERR(base)) @@ -2608,6 +2763,10 @@ static int pl011_setup_port(struct device *dev, struct uart_amba_port *uap, uap->port.flags = UPF_BOOT_AUTOCONF; uap->port.line = index; + ret = pl011_get_rs485_mode(uap); + if (ret) + return ret; + amba_ports[index] = uap; return 0; @@ -2665,7 +2824,7 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) uap->port.iotype = vendor->access_32b ? UPIO_MEM32 : UPIO_MEM; uap->port.irq = dev->irq[0]; uap->port.ops = &amba_pl011_pops; - + uap->port.rs485_config = pl011_rs485_config; snprintf(uap->type, sizeof(uap->type), "PL011 rev%u", amba_rev(dev)); ret = pl011_setup_port(&dev->dev, uap, &dev->res, portnr); -- cgit v1.2.3-58-ga151 From b0819465be8be0c76af15436a9e6db4dab4c196e Mon Sep 17 00:00:00 2001 From: Bing Fan Date: Thu, 1 Jul 2021 09:38:32 +0800 Subject: arm pl011 serial: support multi-irq request In order to make pl011 work better, multiple interrupts are required, such as TXIM, RXIM, RTIM, error interrupt(FE/PE/BE/OE); at the same time, pl011 to GIC does not merge the interrupt lines(each serial-interrupt corresponding to different GIC hardware interrupt), so need to enable and request multiple gic interrupt numbers in the driver. Signed-off-by: Bing Fan Link: https://lore.kernel.org/r/1625103512-30182-1-git-send-email-hptsfb@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl011.c | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index d361cd84ff8c..cf6ff229e267 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -1777,11 +1777,39 @@ static void pl011_write_lcr_h(struct uart_amba_port *uap, unsigned int lcr_h) } } +static void pl011_release_irq(struct uart_amba_port *uap, unsigned int max_cnt) +{ + struct amba_device *amba_dev = container_of(uap->port.dev, struct amba_device, dev); + int i; + + for (i = 0; i < max_cnt; i++) + if (amba_dev->irq[i]) + free_irq(amba_dev->irq[i], uap); +} + static int pl011_allocate_irq(struct uart_amba_port *uap) { + int ret = 0; + int i; + unsigned int virq; + struct amba_device *amba_dev = container_of(uap->port.dev, struct amba_device, dev); + pl011_write(uap->im, uap, REG_IMSC); - return request_irq(uap->port.irq, pl011_int, IRQF_SHARED, "uart-pl011", uap); + for (i = 0; i < AMBA_NR_IRQS; i++) { + virq = amba_dev->irq[i]; + if (virq == 0) + break; + + ret = request_irq(virq, pl011_int, IRQF_SHARED, dev_name(&amba_dev->dev), uap); + if (ret) { + dev_err(uap->port.dev, "request %u interrupt failed\n", virq); + pl011_release_irq(uap, i - 1); + break; + } + } + + return ret; } /* @@ -1953,7 +1981,7 @@ static void pl011_shutdown(struct uart_port *port) if ((port->rs485.flags & SER_RS485_ENABLED) && uap->rs485_tx_started) pl011_rs485_tx_stop(uap); - free_irq(uap->port.irq, uap); + pl011_release_irq(uap, AMBA_NR_IRQS); pl011_disable_uart(uap); @@ -1983,7 +2011,7 @@ static void sbsa_uart_shutdown(struct uart_port *port) pl011_disable_interrupts(uap); - free_irq(uap->port.irq, uap); + pl011_release_irq(uap, AMBA_NR_IRQS); if (uap->port.ops->flush_buffer) uap->port.ops->flush_buffer(port); -- cgit v1.2.3-58-ga151 From 4fc2d3cd6d3a487a9fb79ebc81f7ae86a7dace7a Mon Sep 17 00:00:00 2001 From: Tamseel Shams Date: Tue, 29 Jun 2021 10:29:02 +0530 Subject: serial: samsung: use dma_ops of DMA if attached When DMA is used for TX and RX by serial driver, it should pass the DMA device pointer to DMA API instead of UART device pointer. DMA device should be used for DMA API because only the DMA device is aware of how the device connects to the memory. There might be an extra level of address translation due to a SMMU attached to the DMA device. When serial device is used for DMA API, the DMA API will have no clue of the SMMU attached to the DMA device. This patch is necessary to fix the SMMU page faults which is observed when a DMA(with SMMU enabled) is attached to UART for transfer. Acked-by: Marek Szyprowski Acked-by: Krzysztof Kozlowski Signed-off-by: Tamseel Shams Signed-off-by: Ajay Kumar Link: https://lore.kernel.org/r/20210629045902.48912-1-m.shams@samsung.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/samsung_tty.c | 46 ++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 21 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c index 9fbc61151c2e..0cf4dfe77c32 100644 --- a/drivers/tty/serial/samsung_tty.c +++ b/drivers/tty/serial/samsung_tty.c @@ -305,8 +305,9 @@ static void s3c24xx_serial_stop_tx(struct uart_port *port) dmaengine_pause(dma->tx_chan); dmaengine_tx_status(dma->tx_chan, dma->tx_cookie, &state); dmaengine_terminate_all(dma->tx_chan); - dma_sync_single_for_cpu(ourport->port.dev, - dma->tx_transfer_addr, dma->tx_size, DMA_TO_DEVICE); + dma_sync_single_for_cpu(dma->tx_chan->device->dev, + dma->tx_transfer_addr, dma->tx_size, + DMA_TO_DEVICE); async_tx_ack(dma->tx_desc); count = dma->tx_bytes_requested - state.residue; xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1); @@ -338,8 +339,9 @@ static void s3c24xx_serial_tx_dma_complete(void *args) count = dma->tx_bytes_requested - state.residue; async_tx_ack(dma->tx_desc); - dma_sync_single_for_cpu(ourport->port.dev, dma->tx_transfer_addr, - dma->tx_size, DMA_TO_DEVICE); + dma_sync_single_for_cpu(dma->tx_chan->device->dev, + dma->tx_transfer_addr, dma->tx_size, + DMA_TO_DEVICE); spin_lock_irqsave(&port->lock, flags); @@ -443,8 +445,9 @@ static int s3c24xx_serial_start_tx_dma(struct s3c24xx_uart_port *ourport, dma->tx_size = count & ~(dma_get_cache_alignment() - 1); dma->tx_transfer_addr = dma->tx_addr + xmit->tail; - dma_sync_single_for_device(ourport->port.dev, dma->tx_transfer_addr, - dma->tx_size, DMA_TO_DEVICE); + dma_sync_single_for_device(dma->tx_chan->device->dev, + dma->tx_transfer_addr, dma->tx_size, + DMA_TO_DEVICE); dma->tx_desc = dmaengine_prep_slave_single(dma->tx_chan, dma->tx_transfer_addr, dma->tx_size, @@ -515,7 +518,7 @@ static void s3c24xx_uart_copy_rx_to_tty(struct s3c24xx_uart_port *ourport, if (!count) return; - dma_sync_single_for_cpu(ourport->port.dev, dma->rx_addr, + dma_sync_single_for_cpu(dma->rx_chan->device->dev, dma->rx_addr, dma->rx_size, DMA_FROM_DEVICE); ourport->port.icount.rx += count; @@ -636,8 +639,8 @@ static void s3c64xx_start_rx_dma(struct s3c24xx_uart_port *ourport) { struct s3c24xx_uart_dma *dma = ourport->dma; - dma_sync_single_for_device(ourport->port.dev, dma->rx_addr, - dma->rx_size, DMA_FROM_DEVICE); + dma_sync_single_for_device(dma->rx_chan->device->dev, dma->rx_addr, + dma->rx_size, DMA_FROM_DEVICE); dma->rx_desc = dmaengine_prep_slave_single(dma->rx_chan, dma->rx_addr, dma->rx_size, DMA_DEV_TO_MEM, @@ -1102,18 +1105,19 @@ static int s3c24xx_serial_request_dma(struct s3c24xx_uart_port *p) goto err_release_tx; } - dma->rx_addr = dma_map_single(p->port.dev, dma->rx_buf, - dma->rx_size, DMA_FROM_DEVICE); - if (dma_mapping_error(p->port.dev, dma->rx_addr)) { + dma->rx_addr = dma_map_single(dma->rx_chan->device->dev, dma->rx_buf, + dma->rx_size, DMA_FROM_DEVICE); + if (dma_mapping_error(dma->rx_chan->device->dev, dma->rx_addr)) { reason = "DMA mapping error for RX buffer"; ret = -EIO; goto err_free_rx; } /* TX buffer */ - dma->tx_addr = dma_map_single(p->port.dev, p->port.state->xmit.buf, - UART_XMIT_SIZE, DMA_TO_DEVICE); - if (dma_mapping_error(p->port.dev, dma->tx_addr)) { + dma->tx_addr = dma_map_single(dma->tx_chan->device->dev, + p->port.state->xmit.buf, UART_XMIT_SIZE, + DMA_TO_DEVICE); + if (dma_mapping_error(dma->tx_chan->device->dev, dma->tx_addr)) { reason = "DMA mapping error for TX buffer"; ret = -EIO; goto err_unmap_rx; @@ -1122,8 +1126,8 @@ static int s3c24xx_serial_request_dma(struct s3c24xx_uart_port *p) return 0; err_unmap_rx: - dma_unmap_single(p->port.dev, dma->rx_addr, dma->rx_size, - DMA_FROM_DEVICE); + dma_unmap_single(dma->rx_chan->device->dev, dma->rx_addr, + dma->rx_size, DMA_FROM_DEVICE); err_free_rx: kfree(dma->rx_buf); err_release_tx: @@ -1142,8 +1146,8 @@ static void s3c24xx_serial_release_dma(struct s3c24xx_uart_port *p) if (dma->rx_chan) { dmaengine_terminate_all(dma->rx_chan); - dma_unmap_single(p->port.dev, dma->rx_addr, - dma->rx_size, DMA_FROM_DEVICE); + dma_unmap_single(dma->rx_chan->device->dev, dma->rx_addr, + dma->rx_size, DMA_FROM_DEVICE); kfree(dma->rx_buf); dma_release_channel(dma->rx_chan); dma->rx_chan = NULL; @@ -1151,8 +1155,8 @@ static void s3c24xx_serial_release_dma(struct s3c24xx_uart_port *p) if (dma->tx_chan) { dmaengine_terminate_all(dma->tx_chan); - dma_unmap_single(p->port.dev, dma->tx_addr, - UART_XMIT_SIZE, DMA_TO_DEVICE); + dma_unmap_single(dma->tx_chan->device->dev, dma->tx_addr, + UART_XMIT_SIZE, DMA_TO_DEVICE); dma_release_channel(dma->tx_chan); dma->tx_chan = NULL; } -- cgit v1.2.3-58-ga151 From 3b0c406124719b625b1aba431659f5cdc24a982c Mon Sep 17 00:00:00 2001 From: Igor Matheus Andrade Torrente Date: Mon, 28 Jun 2021 10:45:09 -0300 Subject: tty: Fix out-of-bound vmalloc access in imageblit This issue happens when a userspace program does an ioctl FBIOPUT_VSCREENINFO passing the fb_var_screeninfo struct containing only the fields xres, yres, and bits_per_pixel with values. If this struct is the same as the previous ioctl, the vc_resize() detects it and doesn't call the resize_screen(), leaving the fb_var_screeninfo incomplete. And this leads to the updatescrollmode() calculates a wrong value to fbcon_display->vrows, which makes the real_y() return a wrong value of y, and that value, eventually, causes the imageblit to access an out-of-bound address value. To solve this issue I made the resize_screen() be called even if the screen does not need any resizing, so it will "fix and fill" the fb_var_screeninfo independently. Cc: stable # after 5.15-rc2 is out, give it time to bake Reported-and-tested-by: syzbot+858dc7a2f7ef07c2c219@syzkaller.appspotmail.com Signed-off-by: Igor Matheus Andrade Torrente Link: https://lore.kernel.org/r/20210628134509.15895-1-igormtorrente@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/vt.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index ef981d3b7bb4..484eda1958f5 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -1219,8 +1219,25 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc, new_row_size = new_cols << 1; new_screen_size = new_row_size * new_rows; - if (new_cols == vc->vc_cols && new_rows == vc->vc_rows) - return 0; + if (new_cols == vc->vc_cols && new_rows == vc->vc_rows) { + /* + * This function is being called here to cover the case + * where the userspace calls the FBIOPUT_VSCREENINFO twice, + * passing the same fb_var_screeninfo containing the fields + * yres/xres equal to a number non-multiple of vc_font.height + * and yres_virtual/xres_virtual equal to number lesser than the + * vc_font.height and yres/xres. + * In the second call, the struct fb_var_screeninfo isn't + * being modified by the underlying driver because of the + * if above, and this causes the fbcon_display->vrows to become + * negative and it eventually leads to out-of-bound + * access by the imageblit function. + * To give the correct values to the struct and to not have + * to deal with possible errors from the code below, we call + * the resize_screen here as well. + */ + return resize_screen(vc, new_cols, new_rows, user); + } if (new_screen_size > KMALLOC_MAX_SIZE || !new_screen_size) return -EINVAL; -- cgit v1.2.3-58-ga151 From ed623dffdeebcc0acac7be6af4a301ee7169cd21 Mon Sep 17 00:00:00 2001 From: Shubhrajyoti Datta Date: Tue, 13 Jul 2021 12:18:34 +0530 Subject: tty: serial: uartlite: Disable clocks in case of errors In case the uart registration fails the clocks are left enabled. Disable the clock in case of errors. Signed-off-by: Shubhrajyoti Datta Link: https://lore.kernel.org/r/20210713064835.27978-2-shubhrajyoti.datta@xilinx.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/uartlite.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/uartlite.c b/drivers/tty/serial/uartlite.c index a5f15f22d9ef..0376c8607e89 100644 --- a/drivers/tty/serial/uartlite.c +++ b/drivers/tty/serial/uartlite.c @@ -784,6 +784,7 @@ static int ulite_probe(struct platform_device *pdev) ret = uart_register_driver(&ulite_uart_driver); if (ret < 0) { dev_err(&pdev->dev, "Failed to register driver\n"); + clk_disable_unprepare(pdata->clk); return ret; } } -- cgit v1.2.3-58-ga151 From 5bbe10a6942d668a63bfcb69c8ffdd0660db10f5 Mon Sep 17 00:00:00 2001 From: Shubhrajyoti Datta Date: Tue, 13 Jul 2021 12:18:35 +0530 Subject: tty: serial: uartlite: Add runtime pm support In the commit 07e5d4ff125a ("Revert serial-uartlite: Add runtime support") the runtime pm support was reverted to aid reverting of the other patches. This patch adds the runtime PM support back. The runtime pm calls are used to gate and enable the clocks. Signed-off-by: Shubhrajyoti Datta Link: https://lore.kernel.org/r/20210713064835.27978-3-shubhrajyoti.datta@xilinx.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/uartlite.c | 60 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 52 insertions(+), 8 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/uartlite.c b/drivers/tty/serial/uartlite.c index 0376c8607e89..047099b14cee 100644 --- a/drivers/tty/serial/uartlite.c +++ b/drivers/tty/serial/uartlite.c @@ -22,6 +22,7 @@ #include #include #include +#include #define ULITE_NAME "ttyUL" #define ULITE_MAJOR 204 @@ -54,6 +55,7 @@ #define ULITE_CONTROL_RST_TX 0x01 #define ULITE_CONTROL_RST_RX 0x02 #define ULITE_CONTROL_IE 0x10 +#define UART_AUTOSUSPEND_TIMEOUT 3000 /* ms */ /* Static pointer to console port */ #ifdef CONFIG_SERIAL_UARTLITE_CONSOLE @@ -390,12 +392,16 @@ static int ulite_verify_port(struct uart_port *port, struct serial_struct *ser) static void ulite_pm(struct uart_port *port, unsigned int state, unsigned int oldstate) { - struct uartlite_data *pdata = port->private_data; + int ret; - if (!state) - clk_enable(pdata->clk); - else - clk_disable(pdata->clk); + if (!state) { + ret = pm_runtime_get_sync(port->dev); + if (ret < 0) + dev_err(port->dev, "Failed to enable clocks\n"); + } else { + pm_runtime_mark_last_busy(port->dev); + pm_runtime_put_autosuspend(port->dev); + } } #ifdef CONFIG_CONSOLE_POLL @@ -719,11 +725,38 @@ static int __maybe_unused ulite_resume(struct device *dev) return 0; } +static int __maybe_unused ulite_runtime_suspend(struct device *dev) +{ + struct uart_port *port = dev_get_drvdata(dev); + struct uartlite_data *pdata = port->private_data; + + clk_disable(pdata->clk); + return 0; +}; + +static int __maybe_unused ulite_runtime_resume(struct device *dev) +{ + struct uart_port *port = dev_get_drvdata(dev); + struct uartlite_data *pdata = port->private_data; + int ret; + + ret = clk_enable(pdata->clk); + if (ret) { + dev_err(dev, "Cannot enable clock.\n"); + return ret; + } + return 0; +} + /* --------------------------------------------------------------------- * Platform bus binding */ -static SIMPLE_DEV_PM_OPS(ulite_pm_ops, ulite_suspend, ulite_resume); +static const struct dev_pm_ops ulite_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(ulite_suspend, ulite_resume) + SET_RUNTIME_PM_OPS(ulite_runtime_suspend, + ulite_runtime_resume, NULL) +}; #if defined(CONFIG_OF) /* Match table for of_platform binding */ @@ -779,6 +812,11 @@ static int ulite_probe(struct platform_device *pdev) return ret; } + pm_runtime_use_autosuspend(&pdev->dev); + pm_runtime_set_autosuspend_delay(&pdev->dev, UART_AUTOSUSPEND_TIMEOUT); + pm_runtime_set_active(&pdev->dev); + pm_runtime_enable(&pdev->dev); + if (!ulite_uart_driver.state) { dev_dbg(&pdev->dev, "uartlite: calling uart_register_driver()\n"); ret = uart_register_driver(&ulite_uart_driver); @@ -791,7 +829,8 @@ static int ulite_probe(struct platform_device *pdev) ret = ulite_assign(&pdev->dev, id, res->start, irq, pdata); - clk_disable(pdata->clk); + pm_runtime_mark_last_busy(&pdev->dev); + pm_runtime_put_autosuspend(&pdev->dev); return ret; } @@ -800,9 +839,14 @@ static int ulite_remove(struct platform_device *pdev) { struct uart_port *port = dev_get_drvdata(&pdev->dev); struct uartlite_data *pdata = port->private_data; + int rc; clk_disable_unprepare(pdata->clk); - return ulite_release(&pdev->dev); + rc = ulite_release(&pdev->dev); + pm_runtime_disable(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); + pm_runtime_dont_use_autosuspend(&pdev->dev); + return rc; } /* work with hotplug and coldplug */ -- cgit v1.2.3-58-ga151 From e94159dfba797539d69c14cc142baed0e3e8d53e Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 19 Jul 2021 11:24:21 +0100 Subject: tty: serial: Fix spelling mistake "Asychronous" -> "Asynchronous" There is a spelling mistake in the Kconfig text. Fix it. Signed-off-by: Colin Ian King Link: https://lore.kernel.org/r/20210719102421.14813-1-colin.king@canonical.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 24282ad99d85..e0f6d5bfdc94 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1382,7 +1382,7 @@ config SERIAL_ST_ASC select SERIAL_CORE depends on ARM || COMPILE_TEST help - This driver is for the on-chip Asychronous Serial Controller on + This driver is for the on-chip Asynchronous Serial Controller on STMicroelectronics STi SoCs. ASC is embedded in ST COMMS IP block. It supports Rx & Tx functionality. It support all industry standard baud rates. -- cgit v1.2.3-58-ga151 From 33969db7abe9e1cea524e1facb416952211e1d7d Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 13 Jul 2021 12:58:21 +0300 Subject: serial: 8250_exar: Add ->unregister_gpio() callback For the sake of reducing layering violation add ->unregister_gpio() callback and use it in the ->exit() one. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20210713095821.7834-1-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_exar.c | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c index 3ffeedc29c83..d502240bbcf2 100644 --- a/drivers/tty/serial/8250/8250_exar.c +++ b/drivers/tty/serial/8250/8250_exar.c @@ -114,6 +114,7 @@ struct exar8250; struct exar8250_platform { int (*rs485_config)(struct uart_port *, struct serial_rs485 *); int (*register_gpio)(struct pci_dev *, struct uart_8250_port *); + void (*unregister_gpio)(struct uart_8250_port *); }; /** @@ -352,9 +353,8 @@ static void setup_gpio(struct pci_dev *pcidev, u8 __iomem *p) writeb(0x00, p + UART_EXAR_MPIOOD_15_8); } -static void * -__xr17v35x_register_gpio(struct pci_dev *pcidev, - const struct software_node *node) +static struct platform_device *__xr17v35x_register_gpio(struct pci_dev *pcidev, + const struct software_node *node) { struct platform_device *pdev; @@ -374,6 +374,12 @@ __xr17v35x_register_gpio(struct pci_dev *pcidev, return pdev; } +static void __xr17v35x_unregister_gpio(struct platform_device *pdev) +{ + device_remove_software_node(&pdev->dev); + platform_device_unregister(pdev); +} + static const struct property_entry exar_gpio_properties[] = { PROPERTY_ENTRY_U32("exar,first-pin", 0), PROPERTY_ENTRY_U32("ngpios", 16), @@ -384,8 +390,7 @@ static const struct software_node exar_gpio_node = { .properties = exar_gpio_properties, }; -static int xr17v35x_register_gpio(struct pci_dev *pcidev, - struct uart_8250_port *port) +static int xr17v35x_register_gpio(struct pci_dev *pcidev, struct uart_8250_port *port) { if (pcidev->vendor == PCI_VENDOR_ID_EXAR) port->port.private_data = @@ -394,6 +399,15 @@ static int xr17v35x_register_gpio(struct pci_dev *pcidev, return 0; } +static void xr17v35x_unregister_gpio(struct uart_8250_port *port) +{ + if (!port->port.private_data) + return; + + __xr17v35x_unregister_gpio(port->port.private_data); + port->port.private_data = NULL; +} + static int generic_rs485_config(struct uart_port *port, struct serial_rs485 *rs485) { @@ -419,6 +433,7 @@ static int generic_rs485_config(struct uart_port *port, static const struct exar8250_platform exar8250_default_platform = { .register_gpio = xr17v35x_register_gpio, + .unregister_gpio = xr17v35x_unregister_gpio, .rs485_config = generic_rs485_config, }; @@ -484,6 +499,7 @@ static int iot2040_register_gpio(struct pci_dev *pcidev, static const struct exar8250_platform iot2040_platform = { .rs485_config = iot2040_rs485_config, .register_gpio = iot2040_register_gpio, + .unregister_gpio = xr17v35x_unregister_gpio, }; /* @@ -555,17 +571,11 @@ pci_xr17v35x_setup(struct exar8250 *priv, struct pci_dev *pcidev, static void pci_xr17v35x_exit(struct pci_dev *pcidev) { + const struct exar8250_platform *platform = exar_get_platform(); struct exar8250 *priv = pci_get_drvdata(pcidev); struct uart_8250_port *port = serial8250_get_port(priv->line[0]); - struct platform_device *pdev; - pdev = port->port.private_data; - if (!pdev) - return; - - device_remove_software_node(&pdev->dev); - platform_device_unregister(pdev); - port->port.private_data = NULL; + platform->unregister_gpio(port); } static inline void exar_misc_clear(struct exar8250 *priv) -- cgit v1.2.3-58-ga151 From ba998c7c3aba194f43f85bb9ce13cb4f077d3b7a Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 14 Jul 2021 11:13:04 +0200 Subject: amiserial: remove unused DBG_CNT The ugly DBG_CNT macro is unused, so remove. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210714091314.8292-1-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/amiserial.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index 5ec19c48fb7a..08987c438408 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c @@ -31,15 +31,6 @@ #undef SERIAL_DEBUG_FLOW #undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT -/* Sanity checks */ - -#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT) -#define DBG_CNT(s) printk("(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \ - tty->name, (info->tport.flags), serial_driver->refcount,info->count,tty->count,s) -#else -#define DBG_CNT(s) -#endif - /* * End of serial driver configuration section. */ -- cgit v1.2.3-58-ga151 From 1cd25475a5ebea9a82c61a9a17abea7e78dfff9f Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 14 Jul 2021 11:13:05 +0200 Subject: amiserial: remove serial_* strings Remove a print of serial_name and serial_version from the probe function, i.e. show_serial_version() from amiga_serial_probe(). The value of such a print is minimal. Aside from that, the version is artificial (copied from the serial core in 2.3.45pre2 and never increased). So inline the version into seq_printf's format string in rs_proc_show() and remove both strings completely. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210714091314.8292-2-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/amiserial.c | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index 08987c438408..b2ff5861ca78 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c @@ -40,8 +40,6 @@ #include #include #include -static char *serial_version = "4.30"; - #include #include #include @@ -91,7 +89,6 @@ struct serial_state { }; #define custom amiga_custom -static char *serial_name = "Amiga-builtin serial driver"; static struct tty_driver *serial_driver; @@ -1452,7 +1449,7 @@ static inline void line_info(struct seq_file *m, int line, static int rs_proc_show(struct seq_file *m, void *v) { - seq_printf(m, "serinfo:1.0 driver:%s\n", serial_version); + seq_printf(m, "serinfo:1.0 driver:4.30\n"); line_info(m, 0, &rs_table[0]); return 0; } @@ -1465,17 +1462,6 @@ static int rs_proc_show(struct seq_file *m, void *v) * --------------------------------------------------------------------- */ -/* - * This routine prints out the appropriate serial driver version - * number, and identifies which options were configured into this - * driver. - */ -static void show_serial_version(void) -{ - printk(KERN_INFO "%s version %s\n", serial_name, serial_version); -} - - static const struct tty_operations serial_ops = { .open = rs_open, .close = rs_close, @@ -1542,8 +1528,6 @@ static int __init amiga_serial_probe(struct platform_device *pdev) if (!serial_driver) return -ENOMEM; - show_serial_version(); - /* Initialize the tty_driver structure */ serial_driver->driver_name = "amiserial"; @@ -1628,7 +1612,6 @@ static int __exit amiga_serial_remove(struct platform_device *pdev) { struct serial_state *state = platform_get_drvdata(pdev); - /* printk("Unloading %s: version %s\n", serial_name, serial_version); */ tty_unregister_driver(serial_driver); put_tty_driver(serial_driver); tty_port_destroy(&state->tport); -- cgit v1.2.3-58-ga151 From b44206930a27e321b13a651ea176b6ccb4ce701a Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 14 Jul 2021 11:13:06 +0200 Subject: amiserial: remove stale comment The comment about interrupt routines is stale at least since commit 41c28ff1635e (kill _INLINE_) from 2006. So remove the obsolete parts and leave only "here they start...". Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210714091314.8292-3-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/amiserial.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index b2ff5861ca78..6edd2de01f39 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c @@ -179,21 +179,8 @@ static void rs_start(struct tty_struct *tty) /* * ---------------------------------------------------------------------- * - * Here starts the interrupt handling routines. All of the following - * subroutines are declared as inline and are folded into - * rs_interrupt(). They were separated out for readability's sake. + * Here start the interrupt handling routines. * - * Note: rs_interrupt() is a "fast" interrupt, which means that it - * runs with interrupts turned off. People who may want to modify - * rs_interrupt() should try to keep the interrupt handler as fast as - * possible. After you are done making modifications, it is not a bad - * idea to do: - * - * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c - * - * and look at the resulting assemble code in serial.s. - * - * - Ted Ts'o (tytso@mit.edu), 7-Mar-93 * ----------------------------------------------------------------------- */ -- cgit v1.2.3-58-ga151 From 5a7c7a6bb7065625a9802fcd712e50c2424eac6b Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 14 Jul 2021 11:13:07 +0200 Subject: amiserial: remove serial_state::xmit_fifo_size It's always 1, so define a macro for it instead. Note that the check in set_serial_info is doubled, hence remove the latter. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210714091314.8292-4-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/amiserial.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index 6edd2de01f39..0962b197e676 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c @@ -77,7 +77,6 @@ struct serial_state { unsigned long port; int baud_base; - int xmit_fifo_size; int custom_divisor; int read_status_mask; int ignore_status_mask; @@ -95,6 +94,8 @@ static struct tty_driver *serial_driver; /* number of characters left in xmit buffer before we ask for more */ #define WAKEUP_CHARS 256 +#define XMIT_FIFO_SIZE 1 + static unsigned char current_ctl_bits; static void change_speed(struct tty_struct *tty, struct serial_state *info, @@ -646,7 +647,7 @@ static void change_speed(struct tty_struct *tty, struct serial_state *info, if (!quot) quot = baud_base / 9600; info->quot = quot; - info->timeout = ((info->xmit_fifo_size*HZ*bits*quot) / baud_base); + info->timeout = (XMIT_FIFO_SIZE*HZ*bits*quot) / baud_base; info->timeout += HZ/50; /* Add .02 seconds of slop */ /* CTS flow control flag and modem status interrupts */ @@ -923,7 +924,7 @@ static int get_serial_info(struct tty_struct *tty, struct serial_struct *ss) ss->line = tty->index; ss->port = state->port; ss->flags = state->tport.flags; - ss->xmit_fifo_size = state->xmit_fifo_size; + ss->xmit_fifo_size = XMIT_FIFO_SIZE; ss->baud_base = state->baud_base; ss->close_delay = close_delay; ss->closing_wait = closing_wait; @@ -944,7 +945,7 @@ static int set_serial_info(struct tty_struct *tty, struct serial_struct *ss) change_spd = ((ss->flags ^ port->flags) & ASYNC_SPD_MASK) || ss->custom_divisor != state->custom_divisor; if (ss->irq || ss->port != state->port || - ss->xmit_fifo_size != state->xmit_fifo_size) { + ss->xmit_fifo_size != XMIT_FIFO_SIZE) { tty_unlock(tty); return -EINVAL; } @@ -958,7 +959,6 @@ static int set_serial_info(struct tty_struct *tty, struct serial_struct *ss) if ((ss->baud_base != state->baud_base) || (close_delay != port->close_delay) || (closing_wait != port->closing_wait) || - (ss->xmit_fifo_size != state->xmit_fifo_size) || ((ss->flags & ~ASYNC_USR_MASK) != (port->flags & ~ASYNC_USR_MASK))) { tty_unlock(tty); @@ -1290,9 +1290,6 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout) unsigned long orig_jiffies, char_time; int lsr; - if (info->xmit_fifo_size == 0) - return; /* Just in case.... */ - orig_jiffies = jiffies; /* @@ -1303,7 +1300,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout) * Note: we have to use pretty tight timings here to satisfy * the NIST-PCTS. */ - char_time = (info->timeout - HZ/50) / info->xmit_fifo_size; + char_time = (info->timeout - HZ/50) / XMIT_FIFO_SIZE; char_time = char_time / 5; if (char_time == 0) char_time = 1; @@ -1550,7 +1547,6 @@ static int __init amiga_serial_probe(struct platform_device *pdev) /* Hardware set up */ state->baud_base = amiga_colorclock; - state->xmit_fifo_size = 1; /* set ISRs, and then disable the rx interrupts */ error = request_irq(IRQ_AMIGA_TBE, ser_tx_int, 0, "serial TX", state); -- cgit v1.2.3-58-ga151 From 7ec3114ec78026b132eba2c7f4b1d582fad82047 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 14 Jul 2021 11:13:08 +0200 Subject: amiserial: simplify rs_open tty->port is already set when rs_open is called given we linked it by tty_port_link_device(). If it wasn't, the tty layer would WARN loudly. So it's pointless to set it in rs_open. Instead, use the value in tty->port to find out the serial_state (info). It's a fallout of commit b19e2ca77ee4 (TTY: use tty_port_link_device) which added tty_port_link_device here, but omitted to remove the tty->port assignment from rs_open. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210714091314.8292-5-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/amiserial.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index 0962b197e676..68f8cee389ec 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c @@ -1361,14 +1361,14 @@ static void rs_hangup(struct tty_struct *tty) */ static int rs_open(struct tty_struct *tty, struct file * filp) { - struct serial_state *info = rs_table + tty->index; - struct tty_port *port = &info->tport; + struct tty_port *port = tty->port; + struct serial_state *info = container_of(port, struct serial_state, + tport); int retval; port->count++; port->tty = tty; tty->driver_data = info; - tty->port = port; retval = startup(tty, info); if (retval) { -- cgit v1.2.3-58-ga151 From 5d4317abd2223eea5884f7e28d1047d5e87d4a6f Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 14 Jul 2021 11:13:09 +0200 Subject: amiserial: use memset to zero serial_state Zeroing each member of struct serial_state in probe is fragile and overly complicated. Do one memset for them all. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210714091314.8292-6-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/amiserial.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index 68f8cee389ec..558c77653e21 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c @@ -1527,13 +1527,8 @@ static int __init amiga_serial_probe(struct platform_device *pdev) tty_set_operations(serial_driver, &serial_ops); state = rs_table; + memset(state, 0, sizeof(*state)); state->port = (int)&custom.serdatr; /* Just to give it a value */ - state->custom_divisor = 0; - state->icount.cts = state->icount.dsr = - state->icount.rng = state->icount.dcd = 0; - state->icount.rx = state->icount.tx = 0; - state->icount.frame = state->icount.parity = 0; - state->icount.overrun = state->icount.brk = 0; tty_port_init(&state->tport); state->tport.ops = &amiga_port_ops; tty_port_link_device(&state->tport, serial_driver, 0); -- cgit v1.2.3-58-ga151 From 935256192996de6317e3afe5dc1b2f8d9c210afd Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 14 Jul 2021 11:13:10 +0200 Subject: amiserial: expand serial_isroot Having a macro (serial_isroot) for capable(CAP_SYS_ADMIN) does not save us from anything. It rather obfuscates the code. Hence expand serial_isroot to be explicit like every other driver is. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210714091314.8292-7-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/amiserial.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index 558c77653e21..51b51c5acf96 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c @@ -109,8 +109,6 @@ static struct serial_state rs_table[1]; #include -#define serial_isroot() (capable(CAP_SYS_ADMIN)) - /* some serial hardware definitions */ #define SDR_OVRUN (1<<15) #define SDR_RBF (1<<14) @@ -485,11 +483,11 @@ static int startup(struct tty_struct *tty, struct serial_state *info) retval = request_irq(IRQ_AMIGA_VERTB, ser_vbl_int, 0, "serial status", info); if (retval) { - if (serial_isroot()) { - set_bit(TTY_IO_ERROR, &tty->flags); - retval = 0; - } - goto errout; + if (capable(CAP_SYS_ADMIN)) { + set_bit(TTY_IO_ERROR, &tty->flags); + retval = 0; + } + goto errout; } /* enable both Rx and Tx interrupts */ @@ -955,7 +953,7 @@ static int set_serial_info(struct tty_struct *tty, struct serial_struct *ss) if (closing_wait != ASYNC_CLOSING_WAIT_NONE) closing_wait = msecs_to_jiffies(closing_wait * 10); - if (!serial_isroot()) { + if (!capable(CAP_SYS_ADMIN)) { if ((ss->baud_base != state->baud_base) || (close_delay != port->close_delay) || (closing_wait != port->closing_wait) || -- cgit v1.2.3-58-ga151 From 816807020ea68c889c35b01c38cd2f6d1da69f20 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 14 Jul 2021 11:13:11 +0200 Subject: amiserial: expand "custom" "custom" macro is a too generic name. Expand it -- that is use amiga_custom on all the locations. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210714091314.8292-8-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/amiserial.c | 86 ++++++++++++++++++++++++------------------------- 1 file changed, 42 insertions(+), 44 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index 51b51c5acf96..4658df1b5623 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c @@ -87,8 +87,6 @@ struct serial_state { int x_char; /* xon/xoff character */ }; -#define custom amiga_custom - static struct tty_driver *serial_driver; /* number of characters left in xmit buffer before we ask for more */ @@ -148,9 +146,9 @@ static void rs_stop(struct tty_struct *tty) if (info->IER & UART_IER_THRI) { info->IER &= ~UART_IER_THRI; /* disable Tx interrupt and remove any pending interrupts */ - custom.intena = IF_TBE; + amiga_custom.intena = IF_TBE; mb(); - custom.intreq = IF_TBE; + amiga_custom.intreq = IF_TBE; mb(); } local_irq_restore(flags); @@ -166,10 +164,10 @@ static void rs_start(struct tty_struct *tty) && info->xmit.buf && !(info->IER & UART_IER_THRI)) { info->IER |= UART_IER_THRI; - custom.intena = IF_SETCLR | IF_TBE; + amiga_custom.intena = IF_SETCLR | IF_TBE; mb(); /* set a pending Tx Interrupt, transmitter should restart now */ - custom.intreq = IF_SETCLR | IF_TBE; + amiga_custom.intreq = IF_SETCLR | IF_TBE; mb(); } local_irq_restore(flags); @@ -194,9 +192,9 @@ static void receive_chars(struct serial_state *info) icount = &info->icount; status = UART_LSR_DR; /* We obviously have a character! */ - serdatr = custom.serdatr; + serdatr = amiga_custom.serdatr; mb(); - custom.intreq = IF_RBF; + amiga_custom.intreq = IF_RBF; mb(); if((serdatr & 0x1ff) == 0) @@ -273,10 +271,10 @@ out: static void transmit_chars(struct serial_state *info) { - custom.intreq = IF_TBE; + amiga_custom.intreq = IF_TBE; mb(); if (info->x_char) { - custom.serdat = info->x_char | 0x100; + amiga_custom.serdat = info->x_char | 0x100; mb(); info->icount.tx++; info->x_char = 0; @@ -286,12 +284,12 @@ static void transmit_chars(struct serial_state *info) || info->tport.tty->flow.stopped || info->tport.tty->hw_stopped) { info->IER &= ~UART_IER_THRI; - custom.intena = IF_TBE; + amiga_custom.intena = IF_TBE; mb(); return; } - custom.serdat = info->xmit.buf[info->xmit.tail++] | 0x100; + amiga_custom.serdat = info->xmit.buf[info->xmit.tail++] | 0x100; mb(); info->xmit.tail = info->xmit.tail & (SERIAL_XMIT_SIZE-1); info->icount.tx++; @@ -305,7 +303,7 @@ static void transmit_chars(struct serial_state *info) printk("THRE..."); #endif if (info->xmit.head == info->xmit.tail) { - custom.intena = IF_TBE; + amiga_custom.intena = IF_TBE; mb(); info->IER &= ~UART_IER_THRI; } @@ -358,10 +356,10 @@ static void check_modem_status(struct serial_state *info) #endif port->tty->hw_stopped = 0; info->IER |= UART_IER_THRI; - custom.intena = IF_SETCLR | IF_TBE; + amiga_custom.intena = IF_SETCLR | IF_TBE; mb(); /* set a pending Tx Interrupt, transmitter should restart now */ - custom.intreq = IF_SETCLR | IF_TBE; + amiga_custom.intreq = IF_SETCLR | IF_TBE; mb(); tty_wakeup(port->tty); return; @@ -374,9 +372,9 @@ static void check_modem_status(struct serial_state *info) port->tty->hw_stopped = 1; info->IER &= ~UART_IER_THRI; /* disable Tx interrupt and remove any pending interrupts */ - custom.intena = IF_TBE; + amiga_custom.intena = IF_TBE; mb(); - custom.intreq = IF_TBE; + amiga_custom.intreq = IF_TBE; mb(); } } @@ -418,7 +416,7 @@ static irqreturn_t ser_tx_int(int irq, void *dev_id) { struct serial_state *info = dev_id; - if (custom.serdatr & SDR_TBE) { + if (amiga_custom.serdatr & SDR_TBE) { #ifdef SERIAL_DEBUG_INTR printk("ser_tx_int..."); #endif @@ -478,7 +476,7 @@ static int startup(struct tty_struct *tty, struct serial_state *info) /* Clear anything in the input buffer */ - custom.intreq = IF_RBF; + amiga_custom.intreq = IF_RBF; mb(); retval = request_irq(IRQ_AMIGA_VERTB, ser_vbl_int, 0, "serial status", info); @@ -491,7 +489,7 @@ static int startup(struct tty_struct *tty, struct serial_state *info) } /* enable both Rx and Tx interrupts */ - custom.intena = IF_SETCLR | IF_RBF | IF_TBE; + amiga_custom.intena = IF_SETCLR | IF_RBF | IF_TBE; mb(); info->IER = UART_IER_MSI; @@ -557,11 +555,11 @@ static void shutdown(struct tty_struct *tty, struct serial_state *info) } info->IER = 0; - custom.intena = IF_RBF | IF_TBE; + amiga_custom.intena = IF_RBF | IF_TBE; mb(); /* disable break condition */ - custom.adkcon = AC_UARTBRK; + amiga_custom.adkcon = AC_UARTBRK; mb(); if (C_HUPCL(tty)) @@ -705,7 +703,7 @@ static void change_speed(struct tty_struct *tty, struct serial_state *info, if(cval & UART_LCR_PARITY) serper |= (SERPER_PARENB); - custom.serper = serper; + amiga_custom.serper = serper; mb(); } @@ -749,10 +747,10 @@ static void rs_flush_chars(struct tty_struct *tty) local_irq_save(flags); info->IER |= UART_IER_THRI; - custom.intena = IF_SETCLR | IF_TBE; + amiga_custom.intena = IF_SETCLR | IF_TBE; mb(); /* set a pending Tx Interrupt, transmitter should restart now */ - custom.intreq = IF_SETCLR | IF_TBE; + amiga_custom.intreq = IF_SETCLR | IF_TBE; mb(); local_irq_restore(flags); } @@ -791,10 +789,10 @@ static int rs_write(struct tty_struct * tty, const unsigned char *buf, int count && !(info->IER & UART_IER_THRI)) { info->IER |= UART_IER_THRI; local_irq_disable(); - custom.intena = IF_SETCLR | IF_TBE; + amiga_custom.intena = IF_SETCLR | IF_TBE; mb(); /* set a pending Tx Interrupt, transmitter should restart now */ - custom.intreq = IF_SETCLR | IF_TBE; + amiga_custom.intreq = IF_SETCLR | IF_TBE; mb(); local_irq_restore(flags); } @@ -841,11 +839,11 @@ static void rs_send_xchar(struct tty_struct *tty, char ch) /* Check this ! */ local_irq_save(flags); - if(!(custom.intenar & IF_TBE)) { - custom.intena = IF_SETCLR | IF_TBE; + if(!(amiga_custom.intenar & IF_TBE)) { + amiga_custom.intena = IF_SETCLR | IF_TBE; mb(); /* set a pending Tx Interrupt, transmitter should restart now */ - custom.intreq = IF_SETCLR | IF_TBE; + amiga_custom.intreq = IF_SETCLR | IF_TBE; mb(); } local_irq_restore(flags); @@ -1016,7 +1014,7 @@ static int get_lsr_info(struct serial_state *info, unsigned int __user *value) unsigned long flags; local_irq_save(flags); - status = custom.serdatr; + status = amiga_custom.serdatr; mb(); local_irq_restore(flags); result = ((status & SDR_TSRE) ? TIOCSER_TEMT : 0); @@ -1078,9 +1076,9 @@ static int rs_break(struct tty_struct *tty, int break_state) local_irq_save(flags); if (break_state == -1) - custom.adkcon = AC_SETCLR | AC_UARTBRK; + amiga_custom.adkcon = AC_SETCLR | AC_UARTBRK; else - custom.adkcon = AC_UARTBRK; + amiga_custom.adkcon = AC_UARTBRK; mb(); local_irq_restore(flags); return 0; @@ -1257,10 +1255,10 @@ static void rs_close(struct tty_struct *tty, struct file * filp) state->read_status_mask &= ~UART_LSR_DR; if (tty_port_initialized(port)) { /* disable receive interrupts */ - custom.intena = IF_RBF; + amiga_custom.intena = IF_RBF; mb(); /* clear any pending receive interrupt */ - custom.intreq = IF_RBF; + amiga_custom.intreq = IF_RBF; mb(); /* @@ -1319,7 +1317,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout) printk("In rs_wait_until_sent(%d) check=%lu...", timeout, char_time); printk("jiff=%lu...", jiffies); #endif - while(!((lsr = custom.serdatr) & SDR_TSRE)) { + while(!((lsr = amiga_custom.serdatr) & SDR_TSRE)) { #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT printk("serdatr = %d (jiff=%lu)...", lsr, jiffies); #endif @@ -1526,7 +1524,7 @@ static int __init amiga_serial_probe(struct platform_device *pdev) state = rs_table; memset(state, 0, sizeof(*state)); - state->port = (int)&custom.serdatr; /* Just to give it a value */ + state->port = (int)&amiga_custom.serdatr; /* Just to give it a value */ tty_port_init(&state->tport); state->tport.ops = &amiga_port_ops; tty_port_link_device(&state->tport, serial_driver, 0); @@ -1554,11 +1552,11 @@ static int __init amiga_serial_probe(struct platform_device *pdev) local_irq_save(flags); /* turn off Rx and Tx interrupts */ - custom.intena = IF_RBF | IF_TBE; + amiga_custom.intena = IF_RBF | IF_TBE; mb(); /* clear any pending interrupt */ - custom.intreq = IF_RBF | IF_TBE; + amiga_custom.intreq = IF_RBF | IF_TBE; mb(); local_irq_restore(flags); @@ -1618,8 +1616,8 @@ module_platform_driver_probe(amiga_serial_driver, amiga_serial_probe); static void amiga_serial_putc(char c) { - custom.serdat = (unsigned char)c | 0x100; - while (!(custom.serdatr & 0x2000)) + amiga_custom.serdat = (unsigned char)c | 0x100; + while (!(amiga_custom.serdatr & 0x2000)) barrier(); } @@ -1632,9 +1630,9 @@ static void amiga_serial_putc(char c) static void serial_console_write(struct console *co, const char *s, unsigned count) { - unsigned short intena = custom.intenar; + unsigned short intena = amiga_custom.intenar; - custom.intena = IF_TBE; + amiga_custom.intena = IF_TBE; while (count--) { if (*s == '\n') @@ -1642,7 +1640,7 @@ static void serial_console_write(struct console *co, const char *s, amiga_serial_putc(*s++); } - custom.intena = IF_SETCLR | (intena & IF_TBE); + amiga_custom.intena = IF_SETCLR | (intena & IF_TBE); } static struct tty_driver *serial_console_device(struct console *c, int *index) -- cgit v1.2.3-58-ga151 From f3d788b4254c72d6d6f5e6fc8979f95295865e93 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 14 Jul 2021 11:13:12 +0200 Subject: amiserial: pack and sort includes The #include directives are in different places in amiserial: 1) there is no reason for that, and 2) it makes hard to judge what is included and what is not. Therefore, move all the includes to a single place and sort them. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210714091314.8292-9-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/amiserial.c | 50 ++++++++++++++++++++++--------------------------- 1 file changed, 22 insertions(+), 28 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index 4658df1b5623..0a76e70a0b96 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c @@ -22,8 +22,6 @@ * */ -#include - /* Set of debugging defines */ #undef SERIAL_DEBUG_INTR @@ -35,40 +33,38 @@ * End of serial driver configuration section. */ -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include #include #include -#include -#include +#include +#include #include -#include +#include +#include #include +#include +#include #include +#include +#include +#include #include +#include +#include +#include +#include #include -#include -#include -#include - -#include - - -#include +#include +#include +#include +#include +#include +#include #include #include +#include +#include struct serial_state { struct tty_port tport; @@ -105,8 +101,6 @@ static struct serial_state rs_table[1]; #define NR_PORTS ARRAY_SIZE(rs_table) -#include - /* some serial hardware definitions */ #define SDR_OVRUN (1<<15) #define SDR_RBF (1<<14) -- cgit v1.2.3-58-ga151 From 6cc7bda16dfd4a5d89039302cf1668f9820dfb77 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 14 Jul 2021 11:13:13 +0200 Subject: amiserial: switch rs_table to a single state amiserial deals only with a single serial, so drop the rs_table array and NR_PORTS and define a single non-array serial_state for simplicity instead. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210714091314.8292-10-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/amiserial.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index 0a76e70a0b96..dffaff5a587a 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c @@ -97,9 +97,7 @@ static void change_speed(struct tty_struct *tty, struct serial_state *info, static void rs_wait_until_sent(struct tty_struct *tty, int timeout); -static struct serial_state rs_table[1]; - -#define NR_PORTS ARRAY_SIZE(rs_table) +static struct serial_state serial_state; /* some serial hardware definitions */ #define SDR_OVRUN (1<<15) @@ -1424,7 +1422,7 @@ static inline void line_info(struct seq_file *m, int line, static int rs_proc_show(struct seq_file *m, void *v) { seq_printf(m, "serinfo:1.0 driver:4.30\n"); - line_info(m, 0, &rs_table[0]); + line_info(m, 0, &serial_state); return 0; } @@ -1494,11 +1492,11 @@ static const struct tty_port_operations amiga_port_ops = { */ static int __init amiga_serial_probe(struct platform_device *pdev) { + struct serial_state *state = &serial_state; unsigned long flags; - struct serial_state * state; int error; - serial_driver = alloc_tty_driver(NR_PORTS); + serial_driver = alloc_tty_driver(1); if (!serial_driver) return -ENOMEM; @@ -1516,7 +1514,6 @@ static int __init amiga_serial_probe(struct platform_device *pdev) serial_driver->flags = TTY_DRIVER_REAL_RAW; tty_set_operations(serial_driver, &serial_ops); - state = rs_table; memset(state, 0, sizeof(*state)); state->port = (int)&amiga_custom.serdatr; /* Just to give it a value */ tty_port_init(&state->tport); -- cgit v1.2.3-58-ga151 From 5b869a06a2790a2d1f3ee965e8f38246bfc32d24 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 14 Jul 2021 11:13:14 +0200 Subject: amiserial: remove unused state from shutdown 'state' variable is only set but never read in amiserial's shutdown. Drop it. It was like this since the driver was added to the tree as far as I can tell. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210714091314.8292-11-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/amiserial.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index dffaff5a587a..7ad103e128ac 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c @@ -517,13 +517,10 @@ errout: static void shutdown(struct tty_struct *tty, struct serial_state *info) { unsigned long flags; - struct serial_state *state; if (!tty_port_initialized(&info->tport)) return; - state = info; - #ifdef SERIAL_DEBUG_OPEN printk("Shutting down serial port %d ....\n", info->line); #endif -- cgit v1.2.3-58-ga151 From e679004dec37566f658a255157d3aed9d762a2b7 Mon Sep 17 00:00:00 2001 From: Juergen Gross Date: Wed, 7 Jul 2021 11:10:45 +0200 Subject: tty: hvc: replace BUG_ON() with negative return value Xen frontends shouldn't BUG() in case of illegal data received from their backends. So replace the BUG_ON()s when reading illegal data from the ring page with negative return values. Reviewed-by: Jan Beulich Signed-off-by: Juergen Gross Link: https://lore.kernel.org/r/20210707091045.460-1-jgross@suse.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/hvc/hvc_xen.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c index 92c9a476defc..8f143c09a169 100644 --- a/drivers/tty/hvc/hvc_xen.c +++ b/drivers/tty/hvc/hvc_xen.c @@ -86,7 +86,11 @@ static int __write_console(struct xencons_info *xencons, cons = intf->out_cons; prod = intf->out_prod; mb(); /* update queue values before going on */ - BUG_ON((prod - cons) > sizeof(intf->out)); + + if ((prod - cons) > sizeof(intf->out)) { + pr_err_once("xencons: Illegal ring page indices"); + return -EINVAL; + } while ((sent < len) && ((prod - cons) < sizeof(intf->out))) intf->out[MASK_XENCONS_IDX(prod++, intf->out)] = data[sent++]; @@ -114,7 +118,10 @@ static int domU_write_console(uint32_t vtermno, const char *data, int len) */ while (len) { int sent = __write_console(cons, data, len); - + + if (sent < 0) + return sent; + data += sent; len -= sent; @@ -138,7 +145,11 @@ static int domU_read_console(uint32_t vtermno, char *buf, int len) cons = intf->in_cons; prod = intf->in_prod; mb(); /* get pointers before reading ring */ - BUG_ON((prod - cons) > sizeof(intf->in)); + + if ((prod - cons) > sizeof(intf->in)) { + pr_err_once("xencons: Illegal ring page indices"); + return -EINVAL; + } while (cons != prod && recv < len) buf[recv++] = intf->in[MASK_XENCONS_IDX(cons++, intf->in)]; -- cgit v1.2.3-58-ga151 From d7aff291d069c4418285f3c8ee27b0ff67ce5998 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Sat, 26 Jun 2021 06:11:51 +0200 Subject: serial: 8250: Define RX trigger levels for OxSemi 950 devices Oxford Semiconductor 950 serial port devices have a 128-byte FIFO and in the enhanced (650) mode, which we select in `autoconfig_has_efr' with the ECB bit set in the EFR register, they support the receive interrupt trigger level selectable with FCR bits 7:6 from the set of 16, 32, 112, 120. This applies to the original OX16C950 discrete UART[1] as well as 950 cores embedded into more complex devices. For these devices we set the default to 112, which sets an excessively high level of 112 or 7/8 of the FIFO capacity, unlike with other port types where we choose at most 1/2 of their respective FIFO capacities. Additionally we don't make the trigger level configurable. Consequently frequent input overruns happen with high bit rates where hardware flow control cannot be used (e.g. terminal applications) even with otherwise highly-performant systems. Lower the default receive interrupt trigger level to 32 then, and make it configurable. Document the trigger levels along with other port types, including the set of 16, 32, 64, 112 for the transmit interrupt as well[2]. References: [1] "OX16C950 rev B High Performance UART with 128 byte FIFOs", Oxford Semiconductor, Inc., DS-0031, Sep 05, Table 10: "Receiver Trigger Levels", p. 22 [2] same, Table 9: "Transmit Interrupt Trigger Levels", p. 22 Signed-off-by: Maciej W. Rozycki Link: https://lore.kernel.org/r/alpine.DEB.2.21.2106260608480.37803@angie.orcam.me.uk Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_port.c | 3 ++- include/uapi/linux/serial_reg.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index 2164290cbd31..badf5c320853 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -122,7 +122,8 @@ static const struct serial8250_config uart_config[] = { .name = "16C950/954", .fifo_size = 128, .tx_loadsz = 128, - .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, + .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01, + .rxtrig_bytes = {16, 32, 112, 120}, /* UART_CAP_EFR breaks billionon CF bluetooth card. */ .flags = UART_CAP_FIFO | UART_CAP_SLEEP, }, diff --git a/include/uapi/linux/serial_reg.h b/include/uapi/linux/serial_reg.h index be07b5470f4b..f51bc8f36813 100644 --- a/include/uapi/linux/serial_reg.h +++ b/include/uapi/linux/serial_reg.h @@ -62,6 +62,7 @@ * ST16C654: 8 16 56 60 8 16 32 56 PORT_16654 * TI16C750: 1 16 32 56 xx xx xx xx PORT_16750 * TI16C752: 8 16 56 60 8 16 32 56 + * OX16C950: 16 32 112 120 16 32 64 112 PORT_16C950 * Tegra: 1 4 8 14 16 8 4 1 PORT_TEGRA */ #define UART_FCR_R_TRIG_00 0x00 -- cgit v1.2.3-58-ga151 From 0a9410b981e961a24057dceee54bb5d36309a0c4 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 21 Jul 2021 19:24:52 +0300 Subject: serial: 8250_lpss: Enable DMA on Intel Elkhart Lake PSE UARTs on Intel Elkhart Lake support DMA mode. Enable DMA on these ports. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20210721162452.48764-1-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_lpss.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/8250/8250_lpss.c b/drivers/tty/serial/8250/8250_lpss.c index 4dee8a9e0c95..848d81e3838c 100644 --- a/drivers/tty/serial/8250/8250_lpss.c +++ b/drivers/tty/serial/8250/8250_lpss.c @@ -158,6 +158,16 @@ static int byt_serial_setup(struct lpss8250 *lpss, struct uart_port *port) static int ehl_serial_setup(struct lpss8250 *lpss, struct uart_port *port) { + struct uart_8250_dma *dma = &lpss->data.dma; + struct uart_8250_port *up = up_to_u8250p(port); + + /* + * This simply makes the checks in the 8250_port to try the DMA + * channel request which in turn uses the magic of ACPI tables + * parsing (see drivers/dma/acpi-dma.c for the details) and + * matching with the registered General Purpose DMA controllers. + */ + up->dma = dma; return 0; } -- cgit v1.2.3-58-ga151 From 3d1fa055ea7298345795b982de7a5b9ec6ae238d Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 23 Jul 2021 15:59:43 +0300 Subject: serial: max310x: Use clock-names property matching to recognize EXTCLK Dennis reported that on ACPI-based systems the clock frequency isn't enough to configure device properly. We have to respect the clock source as well. To achieve this match the clock-names property against "osc" to recognize external clock connection. On DT-based system this doesn't change anything. Reported-and-tested-by: Dennis Giaya Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20210723125943.22039-1-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/max310x.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index 0c1e4df52215..c2929fefce80 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c @@ -1271,18 +1271,13 @@ static int max310x_probe(struct device *dev, const struct max310x_devtype *devty /* Always ask for fixed clock rate from a property. */ device_property_read_u32(dev, "clock-frequency", &uartclk); - s->clk = devm_clk_get_optional(dev, "osc"); + xtal = device_property_match_string(dev, "clock-names", "osc") < 0; + if (xtal) + s->clk = devm_clk_get_optional(dev, "xtal"); + else + s->clk = devm_clk_get_optional(dev, "osc"); if (IS_ERR(s->clk)) return PTR_ERR(s->clk); - if (s->clk) { - xtal = false; - } else { - s->clk = devm_clk_get_optional(dev, "xtal"); - if (IS_ERR(s->clk)) - return PTR_ERR(s->clk); - - xtal = true; - } ret = clk_prepare_enable(s->clk); if (ret) -- cgit v1.2.3-58-ga151 From 7ccbdcc4d08a6d7041e4849219bbb12ffa45db4c Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 23 Jul 2021 09:43:11 +0200 Subject: hvsi: don't panic on tty_register_driver failure The alloc_tty_driver failure is handled gracefully in hvsi_init. But tty_register_driver is not. panic is called if that one fails. So handle the failure of tty_register_driver gracefully too. This will keep at least the console functional as it was enabled earlier by console_initcall in hvsi_console_init. Instead of shooting down the whole system. This means, we disable interrupts and restore hvsi_wait back to poll_for_state(). Cc: linuxppc-dev@lists.ozlabs.org Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210723074317.32690-3-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/hvc/hvsi.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/hvc/hvsi.c b/drivers/tty/hvc/hvsi.c index bfc15279d5bc..f0bc8e780051 100644 --- a/drivers/tty/hvc/hvsi.c +++ b/drivers/tty/hvc/hvsi.c @@ -1038,7 +1038,7 @@ static const struct tty_operations hvsi_ops = { static int __init hvsi_init(void) { - int i; + int i, ret; hvsi_driver = alloc_tty_driver(hvsi_count); if (!hvsi_driver) @@ -1069,12 +1069,25 @@ static int __init hvsi_init(void) } hvsi_wait = wait_for_state; /* irqs active now */ - if (tty_register_driver(hvsi_driver)) - panic("Couldn't register hvsi console driver\n"); + ret = tty_register_driver(hvsi_driver); + if (ret) { + pr_err("Couldn't register hvsi console driver\n"); + goto err_free_irq; + } printk(KERN_DEBUG "HVSI: registered %i devices\n", hvsi_count); return 0; +err_free_irq: + hvsi_wait = poll_for_state; + for (i = 0; i < hvsi_count; i++) { + struct hvsi_struct *hp = &hvsi_ports[i]; + + free_irq(hp->virq, hp); + } + tty_driver_kref_put(hvsi_driver); + + return ret; } device_initcall(hvsi_init); -- cgit v1.2.3-58-ga151 From 0524513afe45a4a79f418c0377160b7712cab78a Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 23 Jul 2021 09:43:12 +0200 Subject: tty: don't store semi-state into tty drivers When a tty driver pointer is used as a return value of struct console's device() hook, don't store a semi-state into global variable which holds the tty driver. It could mean console::device() would return a bogus value. This is important esp. after the next patch where we switch from alloc_tty_driver to tty_alloc_driver. tty_alloc_driver returns ERR_PTR in case of error and that might have unexpected results as the code doesn't expect this. Cc: Geert Uytterhoeven Cc: "James E.J. Bottomley" Cc: Helge Deller Cc: Chris Zankel Cc: Max Filippov Cc: Laurentiu Tudor Cc: Felipe Balbi Reviewed-by: Max Filippov Acked-by: Helge Deller # parisc Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210723074317.32690-4-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- arch/m68k/emu/nfcon.c | 27 ++++++++++++++------------ arch/parisc/kernel/pdc_cons.c | 28 ++++++++++++++------------- arch/xtensa/platforms/iss/console.c | 33 +++++++++++++++++--------------- drivers/tty/amiserial.c | 35 ++++++++++++++++++---------------- drivers/tty/ehv_bytechan.c | 28 +++++++++++++++------------ drivers/tty/hvc/hvsi.c | 35 ++++++++++++++++++---------------- drivers/usb/gadget/function/u_serial.c | 32 ++++++++++++++++--------------- 7 files changed, 119 insertions(+), 99 deletions(-) (limited to 'drivers/tty') diff --git a/arch/m68k/emu/nfcon.c b/arch/m68k/emu/nfcon.c index 92636c89d65b..f393af375c90 100644 --- a/arch/m68k/emu/nfcon.c +++ b/arch/m68k/emu/nfcon.c @@ -120,35 +120,38 @@ early_param("debug", nf_debug_setup); static int __init nfcon_init(void) { + struct tty_driver *driver; int res; stderr_id = nf_get_id("NF_STDERR"); if (!stderr_id) return -ENODEV; - nfcon_tty_driver = alloc_tty_driver(1); - if (!nfcon_tty_driver) + driver = alloc_tty_driver(1); + if (!driver) return -ENOMEM; tty_port_init(&nfcon_tty_port); - nfcon_tty_driver->driver_name = "nfcon"; - nfcon_tty_driver->name = "nfcon"; - nfcon_tty_driver->type = TTY_DRIVER_TYPE_SYSTEM; - nfcon_tty_driver->subtype = SYSTEM_TYPE_TTY; - nfcon_tty_driver->init_termios = tty_std_termios; - nfcon_tty_driver->flags = TTY_DRIVER_REAL_RAW; + driver->driver_name = "nfcon"; + driver->name = "nfcon"; + driver->type = TTY_DRIVER_TYPE_SYSTEM; + driver->subtype = SYSTEM_TYPE_TTY; + driver->init_termios = tty_std_termios; + driver->flags = TTY_DRIVER_REAL_RAW; - tty_set_operations(nfcon_tty_driver, &nfcon_tty_ops); - tty_port_link_device(&nfcon_tty_port, nfcon_tty_driver, 0); - res = tty_register_driver(nfcon_tty_driver); + tty_set_operations(driver, &nfcon_tty_ops); + tty_port_link_device(&nfcon_tty_port, driver, 0); + res = tty_register_driver(driver); if (res) { pr_err("failed to register nfcon tty driver\n"); - put_tty_driver(nfcon_tty_driver); + put_tty_driver(driver); tty_port_destroy(&nfcon_tty_port); return res; } + nfcon_tty_driver = driver; + if (!(nf_console.flags & CON_ENABLED)) register_console(&nf_console); diff --git a/arch/parisc/kernel/pdc_cons.c b/arch/parisc/kernel/pdc_cons.c index 39ccad063533..650cb01203de 100644 --- a/arch/parisc/kernel/pdc_cons.c +++ b/arch/parisc/kernel/pdc_cons.c @@ -138,6 +138,7 @@ static struct tty_driver *pdc_console_tty_driver; static int __init pdc_console_tty_driver_init(void) { + struct tty_driver *driver; int err; /* Check if the console driver is still registered. @@ -160,31 +161,32 @@ static int __init pdc_console_tty_driver_init(void) printk(KERN_INFO "The PDC console driver is still registered, removing CON_BOOT flag\n"); pdc_cons.flags &= ~CON_BOOT; - pdc_console_tty_driver = alloc_tty_driver(1); - - if (!pdc_console_tty_driver) + driver = alloc_tty_driver(1); + if (!driver) return -ENOMEM; tty_port_init(&tty_port); - pdc_console_tty_driver->driver_name = "pdc_cons"; - pdc_console_tty_driver->name = "ttyB"; - pdc_console_tty_driver->major = MUX_MAJOR; - pdc_console_tty_driver->minor_start = 0; - pdc_console_tty_driver->type = TTY_DRIVER_TYPE_SYSTEM; - pdc_console_tty_driver->init_termios = tty_std_termios; - pdc_console_tty_driver->flags = TTY_DRIVER_REAL_RAW | + driver->driver_name = "pdc_cons"; + driver->name = "ttyB"; + driver->major = MUX_MAJOR; + driver->minor_start = 0; + driver->type = TTY_DRIVER_TYPE_SYSTEM; + driver->init_termios = tty_std_termios; + driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS; - tty_set_operations(pdc_console_tty_driver, &pdc_console_tty_ops); - tty_port_link_device(&tty_port, pdc_console_tty_driver, 0); + tty_set_operations(driver, &pdc_console_tty_ops); + tty_port_link_device(&tty_port, driver, 0); - err = tty_register_driver(pdc_console_tty_driver); + err = tty_register_driver(driver); if (err) { printk(KERN_ERR "Unable to register the PDC console TTY driver\n"); tty_port_destroy(&tty_port); return err; } + pdc_console_tty_driver = driver; + return 0; } device_initcall(pdc_console_tty_driver_init); diff --git a/arch/xtensa/platforms/iss/console.c b/arch/xtensa/platforms/iss/console.c index 0108504dfb45..9c3cf369b7b2 100644 --- a/arch/xtensa/platforms/iss/console.c +++ b/arch/xtensa/platforms/iss/console.c @@ -136,39 +136,42 @@ static const struct tty_operations serial_ops = { static int __init rs_init(void) { + struct tty_driver *driver; int ret; - serial_driver = alloc_tty_driver(SERIAL_MAX_NUM_LINES); - if (!serial_driver) + driver = alloc_tty_driver(SERIAL_MAX_NUM_LINES); + if (!driver) return -ENOMEM; tty_port_init(&serial_port); /* Initialize the tty_driver structure */ - serial_driver->driver_name = "iss_serial"; - serial_driver->name = "ttyS"; - serial_driver->major = TTY_MAJOR; - serial_driver->minor_start = 64; - serial_driver->type = TTY_DRIVER_TYPE_SERIAL; - serial_driver->subtype = SERIAL_TYPE_NORMAL; - serial_driver->init_termios = tty_std_termios; - serial_driver->init_termios.c_cflag = + driver->driver_name = "iss_serial"; + driver->name = "ttyS"; + driver->major = TTY_MAJOR; + driver->minor_start = 64; + driver->type = TTY_DRIVER_TYPE_SERIAL; + driver->subtype = SERIAL_TYPE_NORMAL; + driver->init_termios = tty_std_termios; + driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; - serial_driver->flags = TTY_DRIVER_REAL_RAW; + driver->flags = TTY_DRIVER_REAL_RAW; - tty_set_operations(serial_driver, &serial_ops); - tty_port_link_device(&serial_port, serial_driver, 0); + tty_set_operations(driver, &serial_ops); + tty_port_link_device(&serial_port, driver, 0); - ret = tty_register_driver(serial_driver); + ret = tty_register_driver(driver); if (ret) { pr_err("Couldn't register serial driver\n"); - tty_driver_kref_put(serial_driver); + tty_driver_kref_put(driver); tty_port_destroy(&serial_port); return ret; } + serial_driver = driver; + return 0; } diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index 7ad103e128ac..bfd3acc1ecfa 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c @@ -1490,34 +1490,35 @@ static const struct tty_port_operations amiga_port_ops = { static int __init amiga_serial_probe(struct platform_device *pdev) { struct serial_state *state = &serial_state; + struct tty_driver *driver; unsigned long flags; int error; - serial_driver = alloc_tty_driver(1); - if (!serial_driver) + driver = alloc_tty_driver(1); + if (!driver) return -ENOMEM; /* Initialize the tty_driver structure */ - serial_driver->driver_name = "amiserial"; - serial_driver->name = "ttyS"; - serial_driver->major = TTY_MAJOR; - serial_driver->minor_start = 64; - serial_driver->type = TTY_DRIVER_TYPE_SERIAL; - serial_driver->subtype = SERIAL_TYPE_NORMAL; - serial_driver->init_termios = tty_std_termios; - serial_driver->init_termios.c_cflag = + driver->driver_name = "amiserial"; + driver->name = "ttyS"; + driver->major = TTY_MAJOR; + driver->minor_start = 64; + driver->type = TTY_DRIVER_TYPE_SERIAL; + driver->subtype = SERIAL_TYPE_NORMAL; + driver->init_termios = tty_std_termios; + driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; - serial_driver->flags = TTY_DRIVER_REAL_RAW; - tty_set_operations(serial_driver, &serial_ops); + driver->flags = TTY_DRIVER_REAL_RAW; + tty_set_operations(driver, &serial_ops); memset(state, 0, sizeof(*state)); state->port = (int)&amiga_custom.serdatr; /* Just to give it a value */ tty_port_init(&state->tport); state->tport.ops = &amiga_port_ops; - tty_port_link_device(&state->tport, serial_driver, 0); + tty_port_link_device(&state->tport, driver, 0); - error = tty_register_driver(serial_driver); + error = tty_register_driver(driver); if (error) goto fail_put_tty_driver; @@ -1558,15 +1559,17 @@ static int __init amiga_serial_probe(struct platform_device *pdev) platform_set_drvdata(pdev, state); + serial_driver = driver; + return 0; fail_free_irq: free_irq(IRQ_AMIGA_TBE, state); fail_unregister: - tty_unregister_driver(serial_driver); + tty_unregister_driver(driver); fail_put_tty_driver: tty_port_destroy(&state->tport); - put_tty_driver(serial_driver); + put_tty_driver(driver); return error; } diff --git a/drivers/tty/ehv_bytechan.c b/drivers/tty/ehv_bytechan.c index 445e5ff9b36d..97ae940af478 100644 --- a/drivers/tty/ehv_bytechan.c +++ b/drivers/tty/ehv_bytechan.c @@ -751,6 +751,7 @@ static struct platform_driver ehv_bc_tty_driver = { */ static int __init ehv_bc_init(void) { + struct tty_driver *driver; struct device_node *np; unsigned int count = 0; /* Number of elements in bcs[] */ int ret; @@ -773,26 +774,28 @@ static int __init ehv_bc_init(void) if (!bcs) return -ENOMEM; - ehv_bc_driver = alloc_tty_driver(count); - if (!ehv_bc_driver) { + driver = alloc_tty_driver(count); + if (!driver) { ret = -ENOMEM; goto err_free_bcs; } - ehv_bc_driver->driver_name = "ehv-bc"; - ehv_bc_driver->name = ehv_bc_console.name; - ehv_bc_driver->type = TTY_DRIVER_TYPE_CONSOLE; - ehv_bc_driver->subtype = SYSTEM_TYPE_CONSOLE; - ehv_bc_driver->init_termios = tty_std_termios; - ehv_bc_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; - tty_set_operations(ehv_bc_driver, &ehv_bc_ops); + driver->driver_name = "ehv-bc"; + driver->name = ehv_bc_console.name; + driver->type = TTY_DRIVER_TYPE_CONSOLE; + driver->subtype = SYSTEM_TYPE_CONSOLE; + driver->init_termios = tty_std_termios; + driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; + tty_set_operations(driver, &ehv_bc_ops); - ret = tty_register_driver(ehv_bc_driver); + ret = tty_register_driver(driver); if (ret) { pr_err("ehv-bc: could not register tty driver (ret=%i)\n", ret); goto err_put_tty_driver; } + ehv_bc_driver = driver; + ret = platform_driver_register(&ehv_bc_tty_driver); if (ret) { pr_err("ehv-bc: could not register platform driver (ret=%i)\n", @@ -803,9 +806,10 @@ static int __init ehv_bc_init(void) return 0; err_deregister_tty_driver: - tty_unregister_driver(ehv_bc_driver); + ehv_bc_driver = NULL; + tty_unregister_driver(driver); err_put_tty_driver: - put_tty_driver(ehv_bc_driver); + put_tty_driver(driver); err_free_bcs: kfree(bcs); diff --git a/drivers/tty/hvc/hvsi.c b/drivers/tty/hvc/hvsi.c index f0bc8e780051..bfde7b1936a5 100644 --- a/drivers/tty/hvc/hvsi.c +++ b/drivers/tty/hvc/hvsi.c @@ -1038,29 +1038,30 @@ static const struct tty_operations hvsi_ops = { static int __init hvsi_init(void) { + struct tty_driver *driver; int i, ret; - hvsi_driver = alloc_tty_driver(hvsi_count); - if (!hvsi_driver) + driver = alloc_tty_driver(hvsi_count); + if (!driver) return -ENOMEM; - hvsi_driver->driver_name = "hvsi"; - hvsi_driver->name = "hvsi"; - hvsi_driver->major = HVSI_MAJOR; - hvsi_driver->minor_start = HVSI_MINOR; - hvsi_driver->type = TTY_DRIVER_TYPE_SYSTEM; - hvsi_driver->init_termios = tty_std_termios; - hvsi_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL; - hvsi_driver->init_termios.c_ispeed = 9600; - hvsi_driver->init_termios.c_ospeed = 9600; - hvsi_driver->flags = TTY_DRIVER_REAL_RAW; - tty_set_operations(hvsi_driver, &hvsi_ops); + driver->driver_name = "hvsi"; + driver->name = "hvsi"; + driver->major = HVSI_MAJOR; + driver->minor_start = HVSI_MINOR; + driver->type = TTY_DRIVER_TYPE_SYSTEM; + driver->init_termios = tty_std_termios; + driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL; + driver->init_termios.c_ispeed = 9600; + driver->init_termios.c_ospeed = 9600; + driver->flags = TTY_DRIVER_REAL_RAW; + tty_set_operations(driver, &hvsi_ops); for (i=0; i < hvsi_count; i++) { struct hvsi_struct *hp = &hvsi_ports[i]; int ret = 1; - tty_port_link_device(&hp->port, hvsi_driver, i); + tty_port_link_device(&hp->port, driver, i); ret = request_irq(hp->virq, hvsi_interrupt, 0, "hvsi", hp); if (ret) @@ -1069,12 +1070,14 @@ static int __init hvsi_init(void) } hvsi_wait = wait_for_state; /* irqs active now */ - ret = tty_register_driver(hvsi_driver); + ret = tty_register_driver(driver); if (ret) { pr_err("Couldn't register hvsi console driver\n"); goto err_free_irq; } + hvsi_driver = driver; + printk(KERN_DEBUG "HVSI: registered %i devices\n", hvsi_count); return 0; @@ -1085,7 +1088,7 @@ err_free_irq: free_irq(hp->virq, hp); } - tty_driver_kref_put(hvsi_driver); + tty_driver_kref_put(driver); return ret; } diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c index bffef8e47dac..c99917a07a96 100644 --- a/drivers/usb/gadget/function/u_serial.c +++ b/drivers/usb/gadget/function/u_serial.c @@ -1445,51 +1445,53 @@ EXPORT_SYMBOL_GPL(gserial_resume); static int userial_init(void) { + struct tty_driver *driver; unsigned i; int status; - gs_tty_driver = alloc_tty_driver(MAX_U_SERIAL_PORTS); - if (!gs_tty_driver) + driver = alloc_tty_driver(MAX_U_SERIAL_PORTS); + if (!driver) return -ENOMEM; - gs_tty_driver->driver_name = "g_serial"; - gs_tty_driver->name = "ttyGS"; + driver->driver_name = "g_serial"; + driver->name = "ttyGS"; /* uses dynamically assigned dev_t values */ - gs_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; - gs_tty_driver->subtype = SERIAL_TYPE_NORMAL; - gs_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; - gs_tty_driver->init_termios = tty_std_termios; + driver->type = TTY_DRIVER_TYPE_SERIAL; + driver->subtype = SERIAL_TYPE_NORMAL; + driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; + driver->init_termios = tty_std_termios; /* 9600-8-N-1 ... matches defaults expected by "usbser.sys" on * MS-Windows. Otherwise, most of these flags shouldn't affect * anything unless we were to actually hook up to a serial line. */ - gs_tty_driver->init_termios.c_cflag = + driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; - gs_tty_driver->init_termios.c_ispeed = 9600; - gs_tty_driver->init_termios.c_ospeed = 9600; + driver->init_termios.c_ispeed = 9600; + driver->init_termios.c_ospeed = 9600; - tty_set_operations(gs_tty_driver, &gs_tty_ops); + tty_set_operations(driver, &gs_tty_ops); for (i = 0; i < MAX_U_SERIAL_PORTS; i++) mutex_init(&ports[i].lock); /* export the driver ... */ - status = tty_register_driver(gs_tty_driver); + status = tty_register_driver(driver); if (status) { pr_err("%s: cannot register, err %d\n", __func__, status); goto fail; } + gs_tty_driver = driver; + pr_debug("%s: registered %d ttyGS* device%s\n", __func__, MAX_U_SERIAL_PORTS, (MAX_U_SERIAL_PORTS == 1) ? "" : "s"); return status; fail: - put_tty_driver(gs_tty_driver); - gs_tty_driver = NULL; + put_tty_driver(driver); return status; } module_init(userial_init); -- cgit v1.2.3-58-ga151 From 39b7b42be4a82f036c392abc71724b4b7752ac03 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 23 Jul 2021 09:43:13 +0200 Subject: tty: stop using alloc_tty_driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit alloc_tty_driver was deprecated by tty_alloc_driver in commit 7f0bc6a68ed9 (TTY: pass flags to alloc_tty_driver) in 2012. I never got into eliminating alloc_tty_driver until now. So we still have two functions for allocating drivers which might be confusing. So get rid of alloc_tty_driver uses to eliminate it for good in the next patch. Note we need to switch return value checking as tty_alloc_driver uses ERR_PTR. And flags are now a parameter of tty_alloc_driver. Cc: Richard Henderson (odd fixer:ALPHA PORT) Cc: Ivan Kokshaysky Cc: Matt Turner Cc: Geert Uytterhoeven Cc: "James E.J. Bottomley" Cc: Helge Deller Cc: Jeff Dike Cc: Richard Weinberger Cc: Anton Ivanov Cc: Chris Zankel Cc: Max Filippov Cc: Samuel Iglesias Gonsalvez Cc: Jens Taprogge Cc: Karsten Keil Cc: Ulf Hansson Cc: "David S. Miller" Cc: Jakub Kicinski Cc: Heiko Carstens Cc: Vasily Gorbik Cc: Christian Borntraeger Cc: Laurentiu Tudor Cc: Jiri Kosina Cc: David Sterba Cc: Shawn Guo Cc: Sascha Hauer Cc: Oliver Neukum Cc: Felipe Balbi Cc: Johan Hovold Cc: Marcel Holtmann Cc: Johan Hedberg Cc: Luiz Augusto von Dentz Acked-by: Samuel Iglesias Gonsálvez Acked-by: Max Filippov Acked-by: David Sterba Acked-by: Christian Borntraeger Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210723074317.32690-5-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- arch/alpha/kernel/srmcons.c | 6 +++--- arch/m68k/emu/nfcon.c | 7 +++---- arch/parisc/kernel/pdc_cons.c | 9 ++++----- arch/um/drivers/line.c | 11 ++++++----- arch/xtensa/platforms/iss/console.c | 7 +++---- drivers/ipack/devices/ipoctal.c | 9 ++++----- drivers/isdn/capi/capi.c | 10 ++++------ drivers/mmc/core/sdio_uart.c | 8 ++++---- drivers/net/usb/hso.c | 8 ++++---- drivers/s390/char/con3215.c | 7 +++---- drivers/s390/char/sclp_tty.c | 7 +++---- drivers/s390/char/sclp_vt220.c | 7 +++---- drivers/staging/gdm724x/gdm_tty.c | 9 ++++----- drivers/tty/amiserial.c | 7 +++---- drivers/tty/ehv_bytechan.c | 8 ++++---- drivers/tty/goldfish.c | 14 +++++++------- drivers/tty/hvc/hvc_console.c | 8 ++++---- drivers/tty/hvc/hvcs.c | 8 ++++---- drivers/tty/hvc/hvsi.c | 7 +++---- drivers/tty/ipwireless/tty.c | 8 ++++---- drivers/tty/mxser.c | 8 ++++---- drivers/tty/n_gsm.c | 9 ++++----- drivers/tty/nozomi.c | 8 ++++---- drivers/tty/serial/kgdb_nmi.c | 7 +++---- drivers/tty/serial/serial_core.c | 8 +++++--- drivers/tty/synclink_gt.c | 8 ++++---- drivers/tty/vt/vt.c | 6 +++--- drivers/usb/class/cdc-acm.c | 8 ++++---- drivers/usb/gadget/function/u_serial.c | 8 ++++---- drivers/usb/serial/usb-serial.c | 9 ++++----- net/bluetooth/rfcomm/tty.c | 8 ++++---- 31 files changed, 120 insertions(+), 132 deletions(-) (limited to 'drivers/tty') diff --git a/arch/alpha/kernel/srmcons.c b/arch/alpha/kernel/srmcons.c index fc03471a0b0f..d0a1b08d851d 100644 --- a/arch/alpha/kernel/srmcons.c +++ b/arch/alpha/kernel/srmcons.c @@ -204,9 +204,9 @@ srmcons_init(void) struct tty_driver *driver; int err; - driver = alloc_tty_driver(MAX_SRM_CONSOLE_DEVICES); - if (!driver) - return -ENOMEM; + driver = tty_alloc_driver(MAX_SRM_CONSOLE_DEVICES, 0); + if (IS_ERR(driver)) + return PTR_ERR(driver); tty_port_init(&srmcons_singleton.port); diff --git a/arch/m68k/emu/nfcon.c b/arch/m68k/emu/nfcon.c index f393af375c90..b3b64d03bad6 100644 --- a/arch/m68k/emu/nfcon.c +++ b/arch/m68k/emu/nfcon.c @@ -127,9 +127,9 @@ static int __init nfcon_init(void) if (!stderr_id) return -ENODEV; - driver = alloc_tty_driver(1); - if (!driver) - return -ENOMEM; + driver = tty_alloc_driver(1, TTY_DRIVER_REAL_RAW); + if (IS_ERR(driver)) + return PTR_ERR(driver); tty_port_init(&nfcon_tty_port); @@ -138,7 +138,6 @@ static int __init nfcon_init(void) driver->type = TTY_DRIVER_TYPE_SYSTEM; driver->subtype = SYSTEM_TYPE_TTY; driver->init_termios = tty_std_termios; - driver->flags = TTY_DRIVER_REAL_RAW; tty_set_operations(driver, &nfcon_tty_ops); tty_port_link_device(&nfcon_tty_port, driver, 0); diff --git a/arch/parisc/kernel/pdc_cons.c b/arch/parisc/kernel/pdc_cons.c index 650cb01203de..70c2a1648fc1 100644 --- a/arch/parisc/kernel/pdc_cons.c +++ b/arch/parisc/kernel/pdc_cons.c @@ -161,9 +161,10 @@ static int __init pdc_console_tty_driver_init(void) printk(KERN_INFO "The PDC console driver is still registered, removing CON_BOOT flag\n"); pdc_cons.flags &= ~CON_BOOT; - driver = alloc_tty_driver(1); - if (!driver) - return -ENOMEM; + driver = tty_alloc_driver(1, TTY_DRIVER_REAL_RAW | + TTY_DRIVER_RESET_TERMIOS); + if (IS_ERR(driver)) + return PTR_ERR(driver); tty_port_init(&tty_port); @@ -173,8 +174,6 @@ static int __init pdc_console_tty_driver_init(void) driver->minor_start = 0; driver->type = TTY_DRIVER_TYPE_SYSTEM; driver->init_termios = tty_std_termios; - driver->flags = TTY_DRIVER_REAL_RAW | - TTY_DRIVER_RESET_TERMIOS; tty_set_operations(driver, &pdc_console_tty_ops); tty_port_link_device(&tty_port, driver, 0); diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index fbc623d2cc07..0d8f4ee6335d 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -538,12 +538,14 @@ int register_lines(struct line_driver *line_driver, const struct tty_operations *ops, struct line *lines, int nlines) { - struct tty_driver *driver = alloc_tty_driver(nlines); + struct tty_driver *driver; int err; int i; - if (!driver) - return -ENOMEM; + driver = tty_alloc_driver(nlines, TTY_DRIVER_REAL_RAW | + TTY_DRIVER_DYNAMIC_DEV); + if (IS_ERR(driver)) + return PTR_ERR(driver); driver->driver_name = line_driver->name; driver->name = line_driver->device_name; @@ -551,9 +553,8 @@ int register_lines(struct line_driver *line_driver, driver->minor_start = line_driver->minor_start; driver->type = line_driver->type; driver->subtype = line_driver->subtype; - driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; driver->init_termios = tty_std_termios; - + for (i = 0; i < nlines; i++) { tty_port_init(&lines[i].port); lines[i].port.ops = &line_port_ops; diff --git a/arch/xtensa/platforms/iss/console.c b/arch/xtensa/platforms/iss/console.c index 9c3cf369b7b2..0b8a0565cdfd 100644 --- a/arch/xtensa/platforms/iss/console.c +++ b/arch/xtensa/platforms/iss/console.c @@ -139,9 +139,9 @@ static int __init rs_init(void) struct tty_driver *driver; int ret; - driver = alloc_tty_driver(SERIAL_MAX_NUM_LINES); - if (!driver) - return -ENOMEM; + driver = tty_alloc_driver(SERIAL_MAX_NUM_LINES, TTY_DRIVER_REAL_RAW); + if (IS_ERR(driver)) + return PTR_ERR(driver); tty_port_init(&serial_port); @@ -156,7 +156,6 @@ static int __init rs_init(void) driver->init_termios = tty_std_termios; driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; - driver->flags = TTY_DRIVER_REAL_RAW; tty_set_operations(driver, &serial_ops); tty_port_link_device(&serial_port, driver, 0); diff --git a/drivers/ipack/devices/ipoctal.c b/drivers/ipack/devices/ipoctal.c index 20fa02c81070..be6d11f46e62 100644 --- a/drivers/ipack/devices/ipoctal.c +++ b/drivers/ipack/devices/ipoctal.c @@ -347,10 +347,10 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, /* Register the TTY device */ /* Each IP-OCTAL channel is a TTY port */ - tty = alloc_tty_driver(NR_CHANNELS); - - if (!tty) - return -ENOMEM; + tty = tty_alloc_driver(NR_CHANNELS, TTY_DRIVER_REAL_RAW | + TTY_DRIVER_DYNAMIC_DEV); + if (IS_ERR(tty)) + return PTR_ERR(tty); /* Fill struct tty_driver with ipoctal data */ tty->owner = THIS_MODULE; @@ -362,7 +362,6 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, tty->minor_start = 0; tty->type = TTY_DRIVER_TYPE_SERIAL; tty->subtype = SERIAL_TYPE_NORMAL; - tty->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; tty->init_termios = tty_std_termios; tty->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; tty->init_termios.c_ispeed = 9600; diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index d5f9261fa879..32abf4d15450 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c @@ -1269,10 +1269,11 @@ static int __init capinc_tty_init(void) if (!capiminors) return -ENOMEM; - drv = alloc_tty_driver(capi_ttyminors); - if (!drv) { + drv = tty_alloc_driver(capi_ttyminors, TTY_DRIVER_REAL_RAW | + TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_DYNAMIC_DEV); + if (IS_ERR(drv)) { kfree(capiminors); - return -ENOMEM; + return PTR_ERR(drv); } drv->driver_name = "capi_nc"; drv->name = "capi!"; @@ -1285,9 +1286,6 @@ static int __init capinc_tty_init(void) drv->init_termios.c_oflag = OPOST | ONLCR; drv->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; drv->init_termios.c_lflag = 0; - drv->flags = - TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS | - TTY_DRIVER_DYNAMIC_DEV; tty_set_operations(drv, &capinc_ops); err = tty_register_driver(drv); diff --git a/drivers/mmc/core/sdio_uart.c b/drivers/mmc/core/sdio_uart.c index c36242b86b1d..04a57832e486 100644 --- a/drivers/mmc/core/sdio_uart.c +++ b/drivers/mmc/core/sdio_uart.c @@ -1135,9 +1135,10 @@ static int __init sdio_uart_init(void) int ret; struct tty_driver *tty_drv; - sdio_uart_tty_driver = tty_drv = alloc_tty_driver(UART_NR); - if (!tty_drv) - return -ENOMEM; + sdio_uart_tty_driver = tty_drv = tty_alloc_driver(UART_NR, + TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV); + if (IS_ERR(tty_drv)) + return PTR_ERR(tty_drv); tty_drv->driver_name = "sdio_uart"; tty_drv->name = "ttySDIO"; @@ -1145,7 +1146,6 @@ static int __init sdio_uart_init(void) tty_drv->minor_start = 0; tty_drv->type = TTY_DRIVER_TYPE_SERIAL; tty_drv->subtype = SERIAL_TYPE_NORMAL; - tty_drv->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; tty_drv->init_termios = tty_std_termios; tty_drv->init_termios.c_cflag = B4800 | CS8 | CREAD | HUPCL | CLOCAL; tty_drv->init_termios.c_ispeed = 4800; diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 63006838bdcc..6ecb6d7893a8 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -3229,9 +3229,10 @@ static int __init hso_init(void) serial_table[i] = NULL; /* allocate our driver using the proper amount of supported minors */ - tty_drv = alloc_tty_driver(HSO_SERIAL_TTY_MINORS); - if (!tty_drv) - return -ENOMEM; + tty_drv = tty_alloc_driver(HSO_SERIAL_TTY_MINORS, TTY_DRIVER_REAL_RAW | + TTY_DRIVER_DYNAMIC_DEV); + if (IS_ERR(tty_drv)) + return PTR_ERR(tty_drv); /* fill in all needed values */ tty_drv->driver_name = driver_name; @@ -3244,7 +3245,6 @@ static int __init hso_init(void) tty_drv->minor_start = 0; tty_drv->type = TTY_DRIVER_TYPE_SERIAL; tty_drv->subtype = SERIAL_TYPE_NORMAL; - tty_drv->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; tty_drv->init_termios = tty_std_termios; hso_init_termios(&tty_drv->init_termios); tty_set_operations(tty_drv, &hso_serial_ops); diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 67c0009ca545..3818a89aef5c 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c @@ -1076,9 +1076,9 @@ static int __init tty3215_init(void) if (!CONSOLE_IS_3215) return 0; - driver = alloc_tty_driver(NR_3215); - if (!driver) - return -ENOMEM; + driver = tty_alloc_driver(NR_3215, TTY_DRIVER_REAL_RAW); + if (IS_ERR(driver)) + return PTR_ERR(driver); ret = ccw_driver_register(&raw3215_ccw_driver); if (ret) { @@ -1101,7 +1101,6 @@ static int __init tty3215_init(void) driver->init_termios.c_iflag = IGNBRK | IGNPAR; driver->init_termios.c_oflag = ONLCR; driver->init_termios.c_lflag = ISIG; - driver->flags = TTY_DRIVER_REAL_RAW; tty_set_operations(driver, &tty3215_ops); ret = tty_register_driver(driver); if (ret) { diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c index 6be9de8ed37d..48790f8fb3b1 100644 --- a/drivers/s390/char/sclp_tty.c +++ b/drivers/s390/char/sclp_tty.c @@ -503,9 +503,9 @@ sclp_tty_init(void) return 0; if (!sclp.has_linemode) return 0; - driver = alloc_tty_driver(1); - if (!driver) - return -ENOMEM; + driver = tty_alloc_driver(1, TTY_DRIVER_REAL_RAW); + if (IS_ERR(driver)) + return PTR_ERR(driver); rc = sclp_rw_init(); if (rc) { @@ -548,7 +548,6 @@ sclp_tty_init(void) driver->init_termios.c_iflag = IGNBRK | IGNPAR; driver->init_termios.c_oflag = ONLCR; driver->init_termios.c_lflag = ISIG | ECHO; - driver->flags = TTY_DRIVER_REAL_RAW; tty_set_operations(driver, &sclp_ops); tty_port_link_device(&sclp_port, driver, 0); rc = tty_register_driver(driver); diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index da2496306c04..c6a7ea32aa5c 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c @@ -732,9 +732,9 @@ static int __init sclp_vt220_tty_init(void) /* Note: we're not testing for CONSOLE_IS_SCLP here to preserve * symmetry between VM and LPAR systems regarding ttyS1. */ - driver = alloc_tty_driver(1); - if (!driver) - return -ENOMEM; + driver = tty_alloc_driver(1, TTY_DRIVER_REAL_RAW); + if (IS_ERR(driver)) + return PTR_ERR(driver); rc = __sclp_vt220_init(MAX_KMEM_PAGES); if (rc) goto out_driver; @@ -746,7 +746,6 @@ static int __init sclp_vt220_tty_init(void) driver->type = TTY_DRIVER_TYPE_SYSTEM; driver->subtype = SYSTEM_TYPE_TTY; driver->init_termios = tty_std_termios; - driver->flags = TTY_DRIVER_REAL_RAW; tty_set_operations(driver, &sclp_vt220_ops); tty_port_link_device(&sclp_vt220_port, driver, 0); diff --git a/drivers/staging/gdm724x/gdm_tty.c b/drivers/staging/gdm724x/gdm_tty.c index 279de2cd9c4a..918575417264 100644 --- a/drivers/staging/gdm724x/gdm_tty.c +++ b/drivers/staging/gdm724x/gdm_tty.c @@ -281,9 +281,10 @@ int register_lte_tty_driver(void) int ret; for (i = 0; i < TTY_MAX_COUNT; i++) { - tty_driver = alloc_tty_driver(GDM_TTY_MINOR); - if (!tty_driver) - return -ENOMEM; + tty_driver = tty_alloc_driver(GDM_TTY_MINOR, + TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV); + if (IS_ERR(tty_driver)) + return PTR_ERR(tty_driver); tty_driver->owner = THIS_MODULE; tty_driver->driver_name = DRIVER_STRING[i]; @@ -291,8 +292,6 @@ int register_lte_tty_driver(void) tty_driver->major = GDM_TTY_MAJOR; tty_driver->type = TTY_DRIVER_TYPE_SERIAL; tty_driver->subtype = SERIAL_TYPE_NORMAL; - tty_driver->flags = TTY_DRIVER_REAL_RAW | - TTY_DRIVER_DYNAMIC_DEV; tty_driver->init_termios = tty_std_termios; tty_driver->init_termios.c_cflag = B9600 | CS8 | HUPCL | CLOCAL; tty_driver->init_termios.c_lflag = ISIG | ICANON | IEXTEN; diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index bfd3acc1ecfa..50f1a54ef35a 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c @@ -1494,9 +1494,9 @@ static int __init amiga_serial_probe(struct platform_device *pdev) unsigned long flags; int error; - driver = alloc_tty_driver(1); - if (!driver) - return -ENOMEM; + driver = tty_alloc_driver(1, TTY_DRIVER_REAL_RAW); + if (IS_ERR(driver)) + return PTR_ERR(driver); /* Initialize the tty_driver structure */ @@ -1509,7 +1509,6 @@ static int __init amiga_serial_probe(struct platform_device *pdev) driver->init_termios = tty_std_termios; driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; - driver->flags = TTY_DRIVER_REAL_RAW; tty_set_operations(driver, &serial_ops); memset(state, 0, sizeof(*state)); diff --git a/drivers/tty/ehv_bytechan.c b/drivers/tty/ehv_bytechan.c index 97ae940af478..f580a5de3c98 100644 --- a/drivers/tty/ehv_bytechan.c +++ b/drivers/tty/ehv_bytechan.c @@ -774,9 +774,10 @@ static int __init ehv_bc_init(void) if (!bcs) return -ENOMEM; - driver = alloc_tty_driver(count); - if (!driver) { - ret = -ENOMEM; + driver = tty_alloc_driver(count, TTY_DRIVER_REAL_RAW | + TTY_DRIVER_DYNAMIC_DEV); + if (IS_ERR(driver)) { + ret = PTR_ERR(driver); goto err_free_bcs; } @@ -785,7 +786,6 @@ static int __init ehv_bc_init(void) driver->type = TTY_DRIVER_TYPE_CONSOLE; driver->subtype = SYSTEM_TYPE_CONSOLE; driver->init_termios = tty_std_termios; - driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; tty_set_operations(driver, &ehv_bc_ops); ret = tty_register_driver(driver); diff --git a/drivers/tty/goldfish.c b/drivers/tty/goldfish.c index ccb683a6e6f5..853083fcebb8 100644 --- a/drivers/tty/goldfish.c +++ b/drivers/tty/goldfish.c @@ -253,18 +253,18 @@ static int goldfish_tty_create_driver(void) ret = -ENOMEM; goto err_alloc_goldfish_ttys_failed; } - tty = alloc_tty_driver(goldfish_tty_line_count); - if (tty == NULL) { - ret = -ENOMEM; - goto err_alloc_tty_driver_failed; + tty = tty_alloc_driver(goldfish_tty_line_count, + TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | + TTY_DRIVER_DYNAMIC_DEV); + if (IS_ERR(tty)) { + ret = PTR_ERR(tty); + goto err_tty_alloc_driver_failed; } tty->driver_name = "goldfish"; tty->name = "ttyGF"; tty->type = TTY_DRIVER_TYPE_SERIAL; tty->subtype = SERIAL_TYPE_NORMAL; tty->init_termios = tty_std_termios; - tty->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | - TTY_DRIVER_DYNAMIC_DEV; tty_set_operations(tty, &goldfish_tty_ops); ret = tty_register_driver(tty); if (ret) @@ -275,7 +275,7 @@ static int goldfish_tty_create_driver(void) err_tty_register_driver_failed: put_tty_driver(tty); -err_alloc_tty_driver_failed: +err_tty_alloc_driver_failed: kfree(goldfish_ttys); goldfish_ttys = NULL; err_alloc_goldfish_ttys_failed: diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c index 5bb8c4e44961..9215dd4bd9f0 100644 --- a/drivers/tty/hvc/hvc_console.c +++ b/drivers/tty/hvc/hvc_console.c @@ -1021,9 +1021,10 @@ static int hvc_init(void) int err; /* We need more than hvc_count adapters due to hotplug additions. */ - drv = alloc_tty_driver(HVC_ALLOC_TTY_ADAPTERS); - if (!drv) { - err = -ENOMEM; + drv = tty_alloc_driver(HVC_ALLOC_TTY_ADAPTERS, TTY_DRIVER_REAL_RAW | + TTY_DRIVER_RESET_TERMIOS); + if (IS_ERR(drv)) { + err = PTR_ERR(drv); goto out; } @@ -1033,7 +1034,6 @@ static int hvc_init(void) drv->minor_start = HVC_MINOR; drv->type = TTY_DRIVER_TYPE_SYSTEM; drv->init_termios = tty_std_termios; - drv->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS; tty_set_operations(drv, &hvc_ops); /* Always start the kthread because there can be hotplug vty adapters diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c index fe5e6b4f43de..23aebc964201 100644 --- a/drivers/tty/hvc/hvcs.c +++ b/drivers/tty/hvc/hvcs.c @@ -1445,10 +1445,11 @@ static int hvcs_initialize(void) } else num_ttys_to_alloc = hvcs_parm_num_devs; - hvcs_tty_driver = alloc_tty_driver(num_ttys_to_alloc); - if (!hvcs_tty_driver) { + hvcs_tty_driver = tty_alloc_driver(num_ttys_to_alloc, + TTY_DRIVER_REAL_RAW); + if (IS_ERR(hvcs_tty_driver)) { mutex_unlock(&hvcs_init_mutex); - return -ENOMEM; + return PTR_ERR(hvcs_tty_driver); } if (hvcs_alloc_index_list(num_ttys_to_alloc)) { @@ -1473,7 +1474,6 @@ static int hvcs_initialize(void) * throw us into a horrible recursive echo-echo-echo loop. */ hvcs_tty_driver->init_termios = hvcs_tty_termios; - hvcs_tty_driver->flags = TTY_DRIVER_REAL_RAW; tty_set_operations(hvcs_tty_driver, &hvcs_ops); diff --git a/drivers/tty/hvc/hvsi.c b/drivers/tty/hvc/hvsi.c index bfde7b1936a5..aa81f4835fef 100644 --- a/drivers/tty/hvc/hvsi.c +++ b/drivers/tty/hvc/hvsi.c @@ -1041,9 +1041,9 @@ static int __init hvsi_init(void) struct tty_driver *driver; int i, ret; - driver = alloc_tty_driver(hvsi_count); - if (!driver) - return -ENOMEM; + driver = tty_alloc_driver(hvsi_count, TTY_DRIVER_REAL_RAW); + if (IS_ERR(driver)) + return PTR_ERR(driver); driver->driver_name = "hvsi"; driver->name = "hvsi"; @@ -1054,7 +1054,6 @@ static int __init hvsi_init(void) driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL; driver->init_termios.c_ispeed = 9600; driver->init_termios.c_ospeed = 9600; - driver->flags = TTY_DRIVER_REAL_RAW; tty_set_operations(driver, &hvsi_ops); for (i=0; i < hvsi_count; i++) { diff --git a/drivers/tty/ipwireless/tty.c b/drivers/tty/ipwireless/tty.c index e3a5a5ba752c..d24404c222e0 100644 --- a/drivers/tty/ipwireless/tty.c +++ b/drivers/tty/ipwireless/tty.c @@ -564,9 +564,10 @@ int ipwireless_tty_init(void) { int result; - ipw_tty_driver = alloc_tty_driver(IPWIRELESS_PCMCIA_MINORS); - if (!ipw_tty_driver) - return -ENOMEM; + ipw_tty_driver = tty_alloc_driver(IPWIRELESS_PCMCIA_MINORS, + TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV); + if (IS_ERR(ipw_tty_driver)) + return PTR_ERR(ipw_tty_driver); ipw_tty_driver->driver_name = IPWIRELESS_PCCARD_NAME; ipw_tty_driver->name = "ttyIPWp"; @@ -574,7 +575,6 @@ int ipwireless_tty_init(void) ipw_tty_driver->minor_start = IPWIRELESS_PCMCIA_START; ipw_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; ipw_tty_driver->subtype = SERIAL_TYPE_NORMAL; - ipw_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; ipw_tty_driver->init_termios = tty_std_termios; ipw_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 900ccb2ca166..650fc6fac88e 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -1976,9 +1976,10 @@ static int __init mxser_module_init(void) { int retval; - mxvar_sdriver = alloc_tty_driver(MXSER_PORTS); - if (!mxvar_sdriver) - return -ENOMEM; + mxvar_sdriver = tty_alloc_driver(MXSER_PORTS, TTY_DRIVER_REAL_RAW | + TTY_DRIVER_DYNAMIC_DEV); + if (IS_ERR(mxvar_sdriver)) + return PTR_ERR(mxvar_sdriver); /* Initialize the tty_driver structure */ mxvar_sdriver->name = "ttyMI"; @@ -1988,7 +1989,6 @@ static int __init mxser_module_init(void) mxvar_sdriver->subtype = SERIAL_TYPE_NORMAL; mxvar_sdriver->init_termios = tty_std_termios; mxvar_sdriver->init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL; - mxvar_sdriver->flags = TTY_DRIVER_REAL_RAW|TTY_DRIVER_DYNAMIC_DEV; tty_set_operations(mxvar_sdriver, &mxser_ops); retval = tty_register_driver(mxvar_sdriver); diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index e907b7a5cab5..0308669c21c6 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -3252,10 +3252,11 @@ static int __init gsm_init(void) return status; } - gsm_tty_driver = alloc_tty_driver(256); - if (!gsm_tty_driver) { + gsm_tty_driver = tty_alloc_driver(256, TTY_DRIVER_REAL_RAW | + TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_HARDWARE_BREAK); + if (IS_ERR(gsm_tty_driver)) { pr_err("gsm_init: tty allocation failed.\n"); - status = -ENOMEM; + status = PTR_ERR(gsm_tty_driver); goto err_unreg_ldisc; } gsm_tty_driver->driver_name = "gsmtty"; @@ -3264,8 +3265,6 @@ static int __init gsm_init(void) gsm_tty_driver->minor_start = 0; gsm_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; gsm_tty_driver->subtype = SERIAL_TYPE_NORMAL; - gsm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV - | TTY_DRIVER_HARDWARE_BREAK; gsm_tty_driver->init_termios = tty_std_termios; /* Fixme */ gsm_tty_driver->init_termios.c_lflag &= ~ECHO; diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c index 0c80f25c8c3d..f3eb0aaec79b 100644 --- a/drivers/tty/nozomi.c +++ b/drivers/tty/nozomi.c @@ -1824,16 +1824,16 @@ static __init int nozomi_init(void) { int ret; - ntty_driver = alloc_tty_driver(NTTY_TTY_MAXMINORS); - if (!ntty_driver) - return -ENOMEM; + ntty_driver = tty_alloc_driver(NTTY_TTY_MAXMINORS, TTY_DRIVER_REAL_RAW | + TTY_DRIVER_DYNAMIC_DEV); + if (IS_ERR(ntty_driver)) + return PTR_ERR(ntty_driver); ntty_driver->driver_name = NOZOMI_NAME_TTY; ntty_driver->name = "noz"; ntty_driver->major = 0; ntty_driver->type = TTY_DRIVER_TYPE_SERIAL; ntty_driver->subtype = SERIAL_TYPE_NORMAL; - ntty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; ntty_driver->init_termios = tty_std_termios; ntty_driver->init_termios.c_cflag = B115200 | CS8 | CREAD | \ HUPCL | CLOCAL; diff --git a/drivers/tty/serial/kgdb_nmi.c b/drivers/tty/serial/kgdb_nmi.c index 3e7c6ee8e4b3..9209573a7e37 100644 --- a/drivers/tty/serial/kgdb_nmi.c +++ b/drivers/tty/serial/kgdb_nmi.c @@ -330,17 +330,16 @@ int kgdb_register_nmi_console(void) if (!arch_kgdb_ops.enable_nmi) return 0; - kgdb_nmi_tty_driver = alloc_tty_driver(1); - if (!kgdb_nmi_tty_driver) { + kgdb_nmi_tty_driver = tty_alloc_driver(1, TTY_DRIVER_REAL_RAW); + if (IS_ERR(kgdb_nmi_tty_driver)) { pr_err("%s: cannot allocate tty\n", __func__); - return -ENOMEM; + return PTR_ERR(kgdb_nmi_tty_driver); } kgdb_nmi_tty_driver->driver_name = "ttyNMI"; kgdb_nmi_tty_driver->name = "ttyNMI"; kgdb_nmi_tty_driver->num = 1; kgdb_nmi_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; kgdb_nmi_tty_driver->subtype = SERIAL_TYPE_NORMAL; - kgdb_nmi_tty_driver->flags = TTY_DRIVER_REAL_RAW; kgdb_nmi_tty_driver->init_termios = tty_std_termios; tty_termios_encode_baud_rate(&kgdb_nmi_tty_driver->init_termios, KGDB_NMI_BAUD, KGDB_NMI_BAUD); diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 79bd2f44d765..eb1401b61a90 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -2530,9 +2530,12 @@ int uart_register_driver(struct uart_driver *drv) if (!drv->state) goto out; - normal = alloc_tty_driver(drv->nr); - if (!normal) + normal = tty_alloc_driver(drv->nr, TTY_DRIVER_REAL_RAW | + TTY_DRIVER_DYNAMIC_DEV); + if (IS_ERR(normal)) { + retval = PTR_ERR(normal); goto out_kfree; + } drv->tty_driver = normal; @@ -2545,7 +2548,6 @@ int uart_register_driver(struct uart_driver *drv) normal->init_termios = tty_std_termios; normal->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; normal->init_termios.c_ispeed = normal->init_termios.c_ospeed = 9600; - normal->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; normal->driver_state = drv; tty_set_operations(normal, &uart_ops); diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index 5bb928b7873e..525f3a568c32 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c @@ -3689,10 +3689,11 @@ static int __init slgt_init(void) printk(KERN_INFO "%s\n", driver_name); - serial_driver = alloc_tty_driver(MAX_DEVICES); - if (!serial_driver) { + serial_driver = tty_alloc_driver(MAX_DEVICES, TTY_DRIVER_REAL_RAW | + TTY_DRIVER_DYNAMIC_DEV); + if (IS_ERR(serial_driver)) { printk("%s can't allocate tty driver\n", driver_name); - return -ENOMEM; + return PTR_ERR(serial_driver); } /* Initialize the tty_driver structure */ @@ -3708,7 +3709,6 @@ static int __init slgt_init(void) B9600 | CS8 | CREAD | HUPCL | CLOCAL; serial_driver->init_termios.c_ispeed = 9600; serial_driver->init_termios.c_ospeed = 9600; - serial_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; tty_set_operations(serial_driver, &ops); if ((rc = tty_register_driver(serial_driver)) < 0) { DBGERR(("%s can't register serial driver\n", driver_name)); diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 484eda1958f5..23230cf44b1f 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -3576,8 +3576,9 @@ int __init vty_init(const struct file_operations *console_fops) vcs_init(); - console_driver = alloc_tty_driver(MAX_NR_CONSOLES); - if (!console_driver) + console_driver = tty_alloc_driver(MAX_NR_CONSOLES, TTY_DRIVER_REAL_RAW | + TTY_DRIVER_RESET_TERMIOS); + if (IS_ERR(console_driver)) panic("Couldn't allocate console driver\n"); console_driver->name = "tty"; @@ -3588,7 +3589,6 @@ int __init vty_init(const struct file_operations *console_fops) console_driver->init_termios = tty_std_termios; if (default_utf8) console_driver->init_termios.c_iflag |= IUTF8; - console_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS; tty_set_operations(console_driver, &con_ops); if (tty_register_driver(console_driver)) panic("Couldn't register console driver\n"); diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 4895325b16a4..c19b59583d9f 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -2027,16 +2027,16 @@ static const struct tty_operations acm_ops = { static int __init acm_init(void) { int retval; - acm_tty_driver = alloc_tty_driver(ACM_TTY_MINORS); - if (!acm_tty_driver) - return -ENOMEM; + acm_tty_driver = tty_alloc_driver(ACM_TTY_MINORS, TTY_DRIVER_REAL_RAW | + TTY_DRIVER_DYNAMIC_DEV); + if (IS_ERR(acm_tty_driver)) + return PTR_ERR(acm_tty_driver); acm_tty_driver->driver_name = "acm", acm_tty_driver->name = "ttyACM", acm_tty_driver->major = ACM_TTY_MAJOR, acm_tty_driver->minor_start = 0, acm_tty_driver->type = TTY_DRIVER_TYPE_SERIAL, acm_tty_driver->subtype = SERIAL_TYPE_NORMAL, - acm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; acm_tty_driver->init_termios = tty_std_termios; acm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c index c99917a07a96..74289f68a2ab 100644 --- a/drivers/usb/gadget/function/u_serial.c +++ b/drivers/usb/gadget/function/u_serial.c @@ -1449,9 +1449,10 @@ static int userial_init(void) unsigned i; int status; - driver = alloc_tty_driver(MAX_U_SERIAL_PORTS); - if (!driver) - return -ENOMEM; + driver = tty_alloc_driver(MAX_U_SERIAL_PORTS, TTY_DRIVER_REAL_RAW | + TTY_DRIVER_DYNAMIC_DEV); + if (IS_ERR(driver)) + return PTR_ERR(driver); driver->driver_name = "g_serial"; driver->name = "ttyGS"; @@ -1459,7 +1460,6 @@ static int userial_init(void) driver->type = TTY_DRIVER_TYPE_SERIAL; driver->subtype = SERIAL_TYPE_NORMAL; - driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; driver->init_termios = tty_std_termios; /* 9600-8-N-1 ... matches defaults expected by "usbser.sys" on diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index eeb441c77207..2f7855da645f 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -1319,9 +1319,10 @@ static int __init usb_serial_init(void) { int result; - usb_serial_tty_driver = alloc_tty_driver(USB_SERIAL_TTY_MINORS); - if (!usb_serial_tty_driver) - return -ENOMEM; + usb_serial_tty_driver = tty_alloc_driver(USB_SERIAL_TTY_MINORS, + TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV); + if (IS_ERR(usb_serial_tty_driver)) + return PTR_ERR(usb_serial_tty_driver); /* Initialize our global data */ result = bus_register(&usb_serial_bus_type); @@ -1336,8 +1337,6 @@ static int __init usb_serial_init(void) usb_serial_tty_driver->minor_start = 0; usb_serial_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; usb_serial_tty_driver->subtype = SERIAL_TYPE_NORMAL; - usb_serial_tty_driver->flags = TTY_DRIVER_REAL_RAW | - TTY_DRIVER_DYNAMIC_DEV; usb_serial_tty_driver->init_termios = tty_std_termios; usb_serial_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index 4e095746e002..8ec0600cd927 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c @@ -1127,9 +1127,10 @@ int __init rfcomm_init_ttys(void) { int error; - rfcomm_tty_driver = alloc_tty_driver(RFCOMM_TTY_PORTS); - if (!rfcomm_tty_driver) - return -ENOMEM; + rfcomm_tty_driver = tty_alloc_driver(RFCOMM_TTY_PORTS, + TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV); + if (IS_ERR(rfcomm_tty_driver)) + return PTR_ERR(rfcomm_tty_driver); rfcomm_tty_driver->driver_name = "rfcomm"; rfcomm_tty_driver->name = "rfcomm"; @@ -1137,7 +1138,6 @@ int __init rfcomm_init_ttys(void) rfcomm_tty_driver->minor_start = RFCOMM_TTY_MINOR; rfcomm_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; rfcomm_tty_driver->subtype = SERIAL_TYPE_NORMAL; - rfcomm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; rfcomm_tty_driver->init_termios = tty_std_termios; rfcomm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL; rfcomm_tty_driver->init_termios.c_lflag &= ~ICANON; -- cgit v1.2.3-58-ga151 From cb9ea618ee60313d9278b2ba75f56da2531c8cac Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 23 Jul 2021 09:43:15 +0200 Subject: tty: make tty_set_operations an inline Since commit f34d7a5b7010 (tty: The big operations rework) in 2008, tty_set_operations() is a simple one-line assignment. There is no reason for this to be an exported function, hence move it to a header and make an inline from that. Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210723074317.32690-7-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 7 ------- include/linux/tty_driver.h | 8 ++++++-- 2 files changed, 6 insertions(+), 9 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 26debec26b4e..16e3fce6f88d 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -3438,13 +3438,6 @@ void tty_driver_kref_put(struct tty_driver *driver) } EXPORT_SYMBOL(tty_driver_kref_put); -void tty_set_operations(struct tty_driver *driver, - const struct tty_operations *op) -{ - driver->ops = op; -}; -EXPORT_SYMBOL(tty_set_operations); - void put_tty_driver(struct tty_driver *d) { tty_driver_kref_put(d); diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h index c7746dee58a6..6092ce9180aa 100644 --- a/include/linux/tty_driver.h +++ b/include/linux/tty_driver.h @@ -330,8 +330,6 @@ extern struct list_head tty_drivers; extern struct tty_driver *__tty_alloc_driver(unsigned int lines, struct module *owner, unsigned long flags); extern void put_tty_driver(struct tty_driver *driver); -extern void tty_set_operations(struct tty_driver *driver, - const struct tty_operations *op); extern struct tty_driver *tty_find_polling_driver(char *name, int *line); extern void tty_driver_kref_put(struct tty_driver *driver); @@ -346,6 +344,12 @@ static inline struct tty_driver *tty_driver_kref_get(struct tty_driver *d) return d; } +static inline void tty_set_operations(struct tty_driver *driver, + const struct tty_operations *op) +{ + driver->ops = op; +} + /* tty driver magic number */ #define TTY_DRIVER_MAGIC 0x5402 -- cgit v1.2.3-58-ga151 From 9f90a4ddef4e4d3aa4229f6b117d4e57231457b3 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 23 Jul 2021 09:43:16 +0200 Subject: tty: drop put_tty_driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit put_tty_driver() is an alias for tty_driver_kref_put(). There is no need for two exported identical functions, therefore switch all users of old put_tty_driver() to new tty_driver_kref_put() and remove the former for good. Cc: Richard Henderson Cc: Ivan Kokshaysky Cc: Matt Turner Cc: Geert Uytterhoeven Cc: Jeff Dike Cc: Richard Weinberger Cc: Anton Ivanov Cc: Chris Zankel Cc: Max Filippov Cc: Arnd Bergmann Cc: Greg Kroah-Hartman Cc: Samuel Iglesias Gonsalvez Cc: Jens Taprogge Cc: Karsten Keil Cc: Scott Branden Cc: Ulf Hansson Cc: "David S. Miller" Cc: Jakub Kicinski Cc: Heiko Carstens Cc: Vasily Gorbik Cc: Christian Borntraeger Cc: David Lin Cc: Johan Hovold Cc: Alex Elder Cc: Jiri Slaby Cc: Laurentiu Tudor Cc: Jiri Kosina Cc: David Sterba Cc: Shawn Guo Cc: Sascha Hauer Cc: Pengutronix Kernel Team Cc: Fabio Estevam Cc: NXP Linux Team Cc: Oliver Neukum Cc: Felipe Balbi Cc: Mathias Nyman Cc: Marcel Holtmann Cc: Johan Hedberg Cc: Luiz Augusto von Dentz Acked-by: Alex Elder Acked-by: Christian Borntraeger Acked-by: Max Filippov Acked-by: David Sterba Acked-by: Samuel Iglesias Gonsálvez Signed-off-by: Jiri Slaby Link: https://lore.kernel.org/r/20210723074317.32690-8-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- arch/alpha/kernel/srmcons.c | 2 +- arch/m68k/emu/nfcon.c | 4 ++-- arch/um/drivers/line.c | 2 +- arch/xtensa/platforms/iss/console.c | 2 +- drivers/char/pcmcia/synclink_cs.c | 4 ++-- drivers/char/ttyprintk.c | 4 ++-- drivers/ipack/devices/ipoctal.c | 4 ++-- drivers/isdn/capi/capi.c | 4 ++-- drivers/misc/bcm-vk/bcm_vk_tty.c | 8 ++++---- drivers/mmc/core/sdio_uart.c | 4 ++-- drivers/net/usb/hso.c | 4 ++-- drivers/s390/char/con3215.c | 4 ++-- drivers/s390/char/sclp_tty.c | 8 ++++---- drivers/s390/char/sclp_vt220.c | 2 +- drivers/s390/char/tty3270.c | 4 ++-- drivers/staging/fwserial/fwserial.c | 8 ++++---- drivers/staging/gdm724x/gdm_tty.c | 4 ++-- drivers/staging/greybus/uart.c | 4 ++-- drivers/tty/amiserial.c | 8 ++++---- drivers/tty/ehv_bytechan.c | 6 +++--- drivers/tty/goldfish.c | 4 ++-- drivers/tty/hvc/hvc_console.c | 2 +- drivers/tty/hvc/hvcs.c | 4 ++-- drivers/tty/ipwireless/tty.c | 4 ++-- drivers/tty/mips_ejtag_fdc.c | 2 +- drivers/tty/moxa.c | 4 ++-- drivers/tty/mxser.c | 4 ++-- drivers/tty/n_gsm.c | 4 ++-- drivers/tty/nozomi.c | 4 ++-- drivers/tty/serial/kgdb_nmi.c | 4 ++-- drivers/tty/serial/serial_core.c | 4 ++-- drivers/tty/synclink_gt.c | 4 ++-- drivers/tty/tty_io.c | 6 ------ drivers/tty/ttynull.c | 4 ++-- drivers/tty/vcc.c | 4 ++-- drivers/usb/class/cdc-acm.c | 6 +++--- drivers/usb/gadget/function/u_serial.c | 4 ++-- drivers/usb/host/xhci-dbgtty.c | 4 ++-- drivers/usb/serial/usb-serial.c | 4 ++-- include/linux/tty_driver.h | 1 - net/bluetooth/rfcomm/tty.c | 4 ++-- 41 files changed, 82 insertions(+), 89 deletions(-) (limited to 'drivers/tty') diff --git a/arch/alpha/kernel/srmcons.c b/arch/alpha/kernel/srmcons.c index d0a1b08d851d..90635ef5dafa 100644 --- a/arch/alpha/kernel/srmcons.c +++ b/arch/alpha/kernel/srmcons.c @@ -221,7 +221,7 @@ srmcons_init(void) tty_port_link_device(&srmcons_singleton.port, driver, 0); err = tty_register_driver(driver); if (err) { - put_tty_driver(driver); + tty_driver_kref_put(driver); tty_port_destroy(&srmcons_singleton.port); return err; } diff --git a/arch/m68k/emu/nfcon.c b/arch/m68k/emu/nfcon.c index b3b64d03bad6..557d60867f98 100644 --- a/arch/m68k/emu/nfcon.c +++ b/arch/m68k/emu/nfcon.c @@ -144,7 +144,7 @@ static int __init nfcon_init(void) res = tty_register_driver(driver); if (res) { pr_err("failed to register nfcon tty driver\n"); - put_tty_driver(driver); + tty_driver_kref_put(driver); tty_port_destroy(&nfcon_tty_port); return res; } @@ -161,7 +161,7 @@ static void __exit nfcon_exit(void) { unregister_console(&nf_console); tty_unregister_driver(nfcon_tty_driver); - put_tty_driver(nfcon_tty_driver); + tty_driver_kref_put(nfcon_tty_driver); tty_port_destroy(&nfcon_tty_port); } diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index 0d8f4ee6335d..8febf95da96e 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -568,7 +568,7 @@ int register_lines(struct line_driver *line_driver, if (err) { printk(KERN_ERR "register_lines : can't register %s driver\n", line_driver->name); - put_tty_driver(driver); + tty_driver_kref_put(driver); for (i = 0; i < nlines; i++) tty_port_destroy(&lines[i].port); return err; diff --git a/arch/xtensa/platforms/iss/console.c b/arch/xtensa/platforms/iss/console.c index 0b8a0565cdfd..81f988914d9a 100644 --- a/arch/xtensa/platforms/iss/console.c +++ b/arch/xtensa/platforms/iss/console.c @@ -178,7 +178,7 @@ static int __init rs_init(void) static __exit void rs_exit(void) { tty_unregister_driver(serial_driver); - put_tty_driver(serial_driver); + tty_driver_kref_put(serial_driver); tty_port_destroy(&serial_port); } diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index 6eaefea0520e..fd78d5856841 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c @@ -2841,7 +2841,7 @@ static int __init synclink_cs_init(void) err_unreg_tty: tty_unregister_driver(serial_driver); err_put_tty: - put_tty_driver(serial_driver); + tty_driver_kref_put(serial_driver); err: return rc; } @@ -2850,7 +2850,7 @@ static void __exit synclink_cs_exit(void) { pcmcia_unregister_driver(&mgslpc_driver); tty_unregister_driver(serial_driver); - put_tty_driver(serial_driver); + tty_driver_kref_put(serial_driver); } module_init(synclink_cs_init); diff --git a/drivers/char/ttyprintk.c b/drivers/char/ttyprintk.c index 230b2c9b3e3c..adf941c47506 100644 --- a/drivers/char/ttyprintk.c +++ b/drivers/char/ttyprintk.c @@ -198,7 +198,7 @@ static int __init ttyprintk_init(void) return 0; error: - put_tty_driver(ttyprintk_driver); + tty_driver_kref_put(ttyprintk_driver); tty_port_destroy(&tpk_port.port); return ret; } @@ -206,7 +206,7 @@ error: static void __exit ttyprintk_exit(void) { tty_unregister_driver(ttyprintk_driver); - put_tty_driver(ttyprintk_driver); + tty_driver_kref_put(ttyprintk_driver); tty_port_destroy(&tpk_port.port); } diff --git a/drivers/ipack/devices/ipoctal.c b/drivers/ipack/devices/ipoctal.c index be6d11f46e62..c14e65a5d38f 100644 --- a/drivers/ipack/devices/ipoctal.c +++ b/drivers/ipack/devices/ipoctal.c @@ -371,7 +371,7 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, res = tty_register_driver(tty); if (res) { dev_err(&ipoctal->dev->dev, "Can't register tty driver.\n"); - put_tty_driver(tty); + tty_driver_kref_put(tty); return res; } @@ -696,7 +696,7 @@ static void __ipoctal_remove(struct ipoctal *ipoctal) } tty_unregister_driver(ipoctal->tty_drv); - put_tty_driver(ipoctal->tty_drv); + tty_driver_kref_put(ipoctal->tty_drv); kfree(ipoctal); } diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index 32abf4d15450..0f00be62438d 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c @@ -1290,7 +1290,7 @@ static int __init capinc_tty_init(void) err = tty_register_driver(drv); if (err) { - put_tty_driver(drv); + tty_driver_kref_put(drv); kfree(capiminors); printk(KERN_ERR "Couldn't register capi_nc driver\n"); return err; @@ -1302,7 +1302,7 @@ static int __init capinc_tty_init(void) static void __exit capinc_tty_exit(void) { tty_unregister_driver(capinc_tty_driver); - put_tty_driver(capinc_tty_driver); + tty_driver_kref_put(capinc_tty_driver); kfree(capiminors); } diff --git a/drivers/misc/bcm-vk/bcm_vk_tty.c b/drivers/misc/bcm-vk/bcm_vk_tty.c index dae9eeed84a2..1b6076a89ca6 100644 --- a/drivers/misc/bcm-vk/bcm_vk_tty.c +++ b/drivers/misc/bcm-vk/bcm_vk_tty.c @@ -249,7 +249,7 @@ int bcm_vk_tty_init(struct bcm_vk *vk, char *name) tty_drv->name = kstrdup(name, GFP_KERNEL); if (!tty_drv->name) { err = -ENOMEM; - goto err_put_tty_driver; + goto err_tty_driver_kref_put; } tty_drv->type = TTY_DRIVER_TYPE_SERIAL; tty_drv->subtype = SERIAL_TYPE_NORMAL; @@ -295,8 +295,8 @@ err_kfree_tty_name: kfree(tty_drv->name); tty_drv->name = NULL; -err_put_tty_driver: - put_tty_driver(tty_drv); +err_tty_driver_kref_put: + tty_driver_kref_put(tty_drv); return err; } @@ -317,7 +317,7 @@ void bcm_vk_tty_exit(struct bcm_vk *vk) kfree(vk->tty_drv->name); vk->tty_drv->name = NULL; - put_tty_driver(vk->tty_drv); + tty_driver_kref_put(vk->tty_drv); } void bcm_vk_tty_terminate_tty_user(struct bcm_vk *vk) diff --git a/drivers/mmc/core/sdio_uart.c b/drivers/mmc/core/sdio_uart.c index 04a57832e486..04c0823e0359 100644 --- a/drivers/mmc/core/sdio_uart.c +++ b/drivers/mmc/core/sdio_uart.c @@ -1165,7 +1165,7 @@ static int __init sdio_uart_init(void) err2: tty_unregister_driver(tty_drv); err1: - put_tty_driver(tty_drv); + tty_driver_kref_put(tty_drv); return ret; } @@ -1173,7 +1173,7 @@ static void __exit sdio_uart_exit(void) { sdio_unregister_driver(&sdio_uart_driver); tty_unregister_driver(sdio_uart_tty_driver); - put_tty_driver(sdio_uart_tty_driver); + tty_driver_kref_put(sdio_uart_tty_driver); } module_init(sdio_uart_init); diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 6ecb6d7893a8..48192de045fc 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -3269,7 +3269,7 @@ static int __init hso_init(void) err_unreg_tty: tty_unregister_driver(tty_drv); err_free_tty: - put_tty_driver(tty_drv); + tty_driver_kref_put(tty_drv); return result; } @@ -3280,7 +3280,7 @@ static void __exit hso_exit(void) tty_unregister_driver(tty_drv); /* deregister the usb driver */ usb_deregister(&hso_driver); - put_tty_driver(tty_drv); + tty_driver_kref_put(tty_drv); } /* Module definitions */ diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 3818a89aef5c..f356607835d8 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c @@ -1082,7 +1082,7 @@ static int __init tty3215_init(void) ret = ccw_driver_register(&raw3215_ccw_driver); if (ret) { - put_tty_driver(driver); + tty_driver_kref_put(driver); return ret; } /* @@ -1104,7 +1104,7 @@ static int __init tty3215_init(void) tty_set_operations(driver, &tty3215_ops); ret = tty_register_driver(driver); if (ret) { - put_tty_driver(driver); + tty_driver_kref_put(driver); return ret; } tty3215_driver = driver; diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c index 48790f8fb3b1..971fbb52740b 100644 --- a/drivers/s390/char/sclp_tty.c +++ b/drivers/s390/char/sclp_tty.c @@ -509,14 +509,14 @@ sclp_tty_init(void) rc = sclp_rw_init(); if (rc) { - put_tty_driver(driver); + tty_driver_kref_put(driver); return rc; } /* Allocate pages for output buffering */ for (i = 0; i < MAX_KMEM_PAGES; i++) { page = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA); if (page == NULL) { - put_tty_driver(driver); + tty_driver_kref_put(driver); return -ENOMEM; } list_add_tail((struct list_head *) page, &sclp_tty_pages); @@ -532,7 +532,7 @@ sclp_tty_init(void) rc = sclp_register(&sclp_input_event); if (rc) { - put_tty_driver(driver); + tty_driver_kref_put(driver); return rc; } @@ -552,7 +552,7 @@ sclp_tty_init(void) tty_port_link_device(&sclp_port, driver, 0); rc = tty_register_driver(driver); if (rc) { - put_tty_driver(driver); + tty_driver_kref_put(driver); tty_port_destroy(&sclp_port); return rc; } diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index c6a7ea32aa5c..29a6a0099f83 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c @@ -763,7 +763,7 @@ out_reg: out_init: __sclp_vt220_cleanup(); out_driver: - put_tty_driver(driver); + tty_driver_kref_put(driver); return rc; } __initcall(sclp_vt220_tty_init); diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c index adc33846bf8e..5c83f71c1d0e 100644 --- a/drivers/s390/char/tty3270.c +++ b/drivers/s390/char/tty3270.c @@ -1935,7 +1935,7 @@ static int __init tty3270_init(void) tty_set_operations(driver, &tty3270_ops); ret = tty_register_driver(driver); if (ret) { - put_tty_driver(driver); + tty_driver_kref_put(driver); return ret; } tty3270_driver = driver; @@ -1952,7 +1952,7 @@ tty3270_exit(void) driver = tty3270_driver; tty3270_driver = NULL; tty_unregister_driver(driver); - put_tty_driver(driver); + tty_driver_kref_put(driver); tty3270_del_views(); } diff --git a/drivers/staging/fwserial/fwserial.c b/drivers/staging/fwserial/fwserial.c index 38a280e876c2..e8fa7f53cd5e 100644 --- a/drivers/staging/fwserial/fwserial.c +++ b/drivers/staging/fwserial/fwserial.c @@ -2852,11 +2852,11 @@ unregister_loop: tty_unregister_driver(fwloop_driver); put_loop: if (create_loop_dev) - put_tty_driver(fwloop_driver); + tty_driver_kref_put(fwloop_driver); unregister_driver: tty_unregister_driver(fwtty_driver); put_tty: - put_tty_driver(fwtty_driver); + tty_driver_kref_put(fwtty_driver); remove_debugfs: debugfs_remove_recursive(fwserial_debugfs); @@ -2871,10 +2871,10 @@ static void __exit fwserial_exit(void) kmem_cache_destroy(fwtty_txn_cache); if (create_loop_dev) { tty_unregister_driver(fwloop_driver); - put_tty_driver(fwloop_driver); + tty_driver_kref_put(fwloop_driver); } tty_unregister_driver(fwtty_driver); - put_tty_driver(fwtty_driver); + tty_driver_kref_put(fwtty_driver); debugfs_remove_recursive(fwserial_debugfs); } diff --git a/drivers/staging/gdm724x/gdm_tty.c b/drivers/staging/gdm724x/gdm_tty.c index 918575417264..04df6f9f5403 100644 --- a/drivers/staging/gdm724x/gdm_tty.c +++ b/drivers/staging/gdm724x/gdm_tty.c @@ -299,7 +299,7 @@ int register_lte_tty_driver(void) ret = tty_register_driver(tty_driver); if (ret) { - put_tty_driver(tty_driver); + tty_driver_kref_put(tty_driver); return ret; } @@ -318,7 +318,7 @@ void unregister_lte_tty_driver(void) tty_driver = gdm_driver[i]; if (tty_driver) { tty_unregister_driver(tty_driver); - put_tty_driver(tty_driver); + tty_driver_kref_put(tty_driver); } } } diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c index 73f01ed1e5b7..e6d860a9678e 100644 --- a/drivers/staging/greybus/uart.c +++ b/drivers/staging/greybus/uart.c @@ -973,7 +973,7 @@ static int gb_tty_init(void) return 0; fail_put_gb_tty: - put_tty_driver(gb_tty_driver); + tty_driver_kref_put(gb_tty_driver); fail_unregister_dev: return retval; } @@ -981,7 +981,7 @@ fail_unregister_dev: static void gb_tty_exit(void) { tty_unregister_driver(gb_tty_driver); - put_tty_driver(gb_tty_driver); + tty_driver_kref_put(gb_tty_driver); idr_destroy(&tty_minors); } diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index 50f1a54ef35a..1e60dbef676c 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c @@ -1519,7 +1519,7 @@ static int __init amiga_serial_probe(struct platform_device *pdev) error = tty_register_driver(driver); if (error) - goto fail_put_tty_driver; + goto fail_tty_driver_kref_put; printk(KERN_INFO "ttyS0 is the amiga builtin serial port\n"); @@ -1566,9 +1566,9 @@ fail_free_irq: free_irq(IRQ_AMIGA_TBE, state); fail_unregister: tty_unregister_driver(driver); -fail_put_tty_driver: +fail_tty_driver_kref_put: tty_port_destroy(&state->tport); - put_tty_driver(driver); + tty_driver_kref_put(driver); return error; } @@ -1577,7 +1577,7 @@ static int __exit amiga_serial_remove(struct platform_device *pdev) struct serial_state *state = platform_get_drvdata(pdev); tty_unregister_driver(serial_driver); - put_tty_driver(serial_driver); + tty_driver_kref_put(serial_driver); tty_port_destroy(&state->tport); free_irq(IRQ_AMIGA_TBE, state); diff --git a/drivers/tty/ehv_bytechan.c b/drivers/tty/ehv_bytechan.c index f580a5de3c98..19d32cb6af84 100644 --- a/drivers/tty/ehv_bytechan.c +++ b/drivers/tty/ehv_bytechan.c @@ -791,7 +791,7 @@ static int __init ehv_bc_init(void) ret = tty_register_driver(driver); if (ret) { pr_err("ehv-bc: could not register tty driver (ret=%i)\n", ret); - goto err_put_tty_driver; + goto err_tty_driver_kref_put; } ehv_bc_driver = driver; @@ -808,8 +808,8 @@ static int __init ehv_bc_init(void) err_deregister_tty_driver: ehv_bc_driver = NULL; tty_unregister_driver(driver); -err_put_tty_driver: - put_tty_driver(driver); +err_tty_driver_kref_put: + tty_driver_kref_put(driver); err_free_bcs: kfree(bcs); diff --git a/drivers/tty/goldfish.c b/drivers/tty/goldfish.c index 853083fcebb8..d24af649a8bb 100644 --- a/drivers/tty/goldfish.c +++ b/drivers/tty/goldfish.c @@ -274,7 +274,7 @@ static int goldfish_tty_create_driver(void) return 0; err_tty_register_driver_failed: - put_tty_driver(tty); + tty_driver_kref_put(tty); err_tty_alloc_driver_failed: kfree(goldfish_ttys); goldfish_ttys = NULL; @@ -285,7 +285,7 @@ err_alloc_goldfish_ttys_failed: static void goldfish_tty_delete_driver(void) { tty_unregister_driver(goldfish_tty_driver); - put_tty_driver(goldfish_tty_driver); + tty_driver_kref_put(goldfish_tty_driver); goldfish_tty_driver = NULL; kfree(goldfish_ttys); goldfish_ttys = NULL; diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c index 9215dd4bd9f0..7b30d5a05e2f 100644 --- a/drivers/tty/hvc/hvc_console.c +++ b/drivers/tty/hvc/hvc_console.c @@ -1063,7 +1063,7 @@ stop_thread: kthread_stop(hvc_task); hvc_task = NULL; put_tty: - put_tty_driver(drv); + tty_driver_kref_put(drv); out: return err; } diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c index 23aebc964201..245da1dfd818 100644 --- a/drivers/tty/hvc/hvcs.c +++ b/drivers/tty/hvc/hvcs.c @@ -1509,7 +1509,7 @@ buff_alloc_fail: register_fail: hvcs_free_index_list(); index_fail: - put_tty_driver(hvcs_tty_driver); + tty_driver_kref_put(hvcs_tty_driver); hvcs_tty_driver = NULL; mutex_unlock(&hvcs_init_mutex); return rc; @@ -1562,7 +1562,7 @@ static void __exit hvcs_module_exit(void) hvcs_free_index_list(); - put_tty_driver(hvcs_tty_driver); + tty_driver_kref_put(hvcs_tty_driver); printk(KERN_INFO "HVCS: driver module removed.\n"); } diff --git a/drivers/tty/ipwireless/tty.c b/drivers/tty/ipwireless/tty.c index d24404c222e0..9edd5ae17580 100644 --- a/drivers/tty/ipwireless/tty.c +++ b/drivers/tty/ipwireless/tty.c @@ -585,7 +585,7 @@ int ipwireless_tty_init(void) if (result) { printk(KERN_ERR IPWIRELESS_PCCARD_NAME ": failed to register tty driver\n"); - put_tty_driver(ipw_tty_driver); + tty_driver_kref_put(ipw_tty_driver); return result; } @@ -595,7 +595,7 @@ int ipwireless_tty_init(void) void ipwireless_tty_release(void) { tty_unregister_driver(ipw_tty_driver); - put_tty_driver(ipw_tty_driver); + tty_driver_kref_put(ipw_tty_driver); } int ipwireless_tty_is_modem(struct ipw_tty *tty) diff --git a/drivers/tty/mips_ejtag_fdc.c b/drivers/tty/mips_ejtag_fdc.c index 3b5915b94fac..02c10a968de1 100644 --- a/drivers/tty/mips_ejtag_fdc.c +++ b/drivers/tty/mips_ejtag_fdc.c @@ -1042,7 +1042,7 @@ err_destroy_ports: dport = &priv->ports[nport]; tty_port_destroy(&dport->port); } - put_tty_driver(priv->driver); + tty_driver_kref_put(priv->driver); return ret; } diff --git a/drivers/tty/moxa.c b/drivers/tty/moxa.c index 64b18177c790..776f78de0f82 100644 --- a/drivers/tty/moxa.c +++ b/drivers/tty/moxa.c @@ -1053,7 +1053,7 @@ static int __init moxa_init(void) if (tty_register_driver(moxaDriver)) { printk(KERN_ERR "can't register MOXA Smartio tty driver!\n"); - put_tty_driver(moxaDriver); + tty_driver_kref_put(moxaDriver); return -1; } @@ -1119,7 +1119,7 @@ static void __exit moxa_exit(void) del_timer_sync(&moxaTimer); tty_unregister_driver(moxaDriver); - put_tty_driver(moxaDriver); + tty_driver_kref_put(moxaDriver); } module_init(moxa_init); diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 650fc6fac88e..335e4e50d679 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -2008,7 +2008,7 @@ static int __init mxser_module_init(void) err_unr: tty_unregister_driver(mxvar_sdriver); err_put: - put_tty_driver(mxvar_sdriver); + tty_driver_kref_put(mxvar_sdriver); return retval; } @@ -2016,7 +2016,7 @@ static void __exit mxser_module_exit(void) { pci_unregister_driver(&mxser_driver); tty_unregister_driver(mxvar_sdriver); - put_tty_driver(mxvar_sdriver); + tty_driver_kref_put(mxvar_sdriver); } module_init(mxser_module_init); diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 0308669c21c6..1d92d2a84889 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -3279,7 +3279,7 @@ static int __init gsm_init(void) gsm_tty_driver->major, gsm_tty_driver->minor_start); return 0; err_put_driver: - put_tty_driver(gsm_tty_driver); + tty_driver_kref_put(gsm_tty_driver); err_unreg_ldisc: tty_unregister_ldisc(&tty_ldisc_packet); return status; @@ -3289,7 +3289,7 @@ static void __exit gsm_exit(void) { tty_unregister_ldisc(&tty_ldisc_packet); tty_unregister_driver(gsm_tty_driver); - put_tty_driver(gsm_tty_driver); + tty_driver_kref_put(gsm_tty_driver); } module_init(gsm_init); diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c index f3eb0aaec79b..0454c78deee6 100644 --- a/drivers/tty/nozomi.c +++ b/drivers/tty/nozomi.c @@ -1857,7 +1857,7 @@ static __init int nozomi_init(void) unr_tty: tty_unregister_driver(ntty_driver); free_tty: - put_tty_driver(ntty_driver); + tty_driver_kref_put(ntty_driver); return ret; } @@ -1865,7 +1865,7 @@ static __exit void nozomi_exit(void) { pci_unregister_driver(&nozomi_driver); tty_unregister_driver(ntty_driver); - put_tty_driver(ntty_driver); + tty_driver_kref_put(ntty_driver); } module_init(nozomi_init); diff --git a/drivers/tty/serial/kgdb_nmi.c b/drivers/tty/serial/kgdb_nmi.c index 9209573a7e37..55c3c9db7462 100644 --- a/drivers/tty/serial/kgdb_nmi.c +++ b/drivers/tty/serial/kgdb_nmi.c @@ -355,7 +355,7 @@ int kgdb_register_nmi_console(void) return 0; err_drv_reg: - put_tty_driver(kgdb_nmi_tty_driver); + tty_driver_kref_put(kgdb_nmi_tty_driver); return ret; } EXPORT_SYMBOL_GPL(kgdb_register_nmi_console); @@ -373,7 +373,7 @@ int kgdb_unregister_nmi_console(void) return ret; tty_unregister_driver(kgdb_nmi_tty_driver); - put_tty_driver(kgdb_nmi_tty_driver); + tty_driver_kref_put(kgdb_nmi_tty_driver); return 0; } diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index eb1401b61a90..0e2e35ab64c7 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -2568,7 +2568,7 @@ int uart_register_driver(struct uart_driver *drv) for (i = 0; i < drv->nr; i++) tty_port_destroy(&drv->state[i].port); - put_tty_driver(normal); + tty_driver_kref_put(normal); out_kfree: kfree(drv->state); out: @@ -2590,7 +2590,7 @@ void uart_unregister_driver(struct uart_driver *drv) unsigned int i; tty_unregister_driver(p); - put_tty_driver(p); + tty_driver_kref_put(p); for (i = 0; i < drv->nr; i++) tty_port_destroy(&drv->state[i].port); kfree(drv->state); diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index 525f3a568c32..c89f7de38d12 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c @@ -3650,7 +3650,7 @@ static void slgt_cleanup(void) for (info=slgt_device_list ; info != NULL ; info=info->next_device) tty_unregister_device(serial_driver, info->line); tty_unregister_driver(serial_driver); - put_tty_driver(serial_driver); + tty_driver_kref_put(serial_driver); } /* reset devices */ @@ -3712,7 +3712,7 @@ static int __init slgt_init(void) tty_set_operations(serial_driver, &ops); if ((rc = tty_register_driver(serial_driver)) < 0) { DBGERR(("%s can't register serial driver\n", driver_name)); - put_tty_driver(serial_driver); + tty_driver_kref_put(serial_driver); serial_driver = NULL; goto error; } diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 16e3fce6f88d..e8532006e960 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -3438,12 +3438,6 @@ void tty_driver_kref_put(struct tty_driver *driver) } EXPORT_SYMBOL(tty_driver_kref_put); -void put_tty_driver(struct tty_driver *d) -{ - tty_driver_kref_put(d); -} -EXPORT_SYMBOL(put_tty_driver); - /* * Called by a tty driver to register itself. */ diff --git a/drivers/tty/ttynull.c b/drivers/tty/ttynull.c index af3311a24917..1d4438472442 100644 --- a/drivers/tty/ttynull.c +++ b/drivers/tty/ttynull.c @@ -84,7 +84,7 @@ static int __init ttynull_init(void) ret = tty_register_driver(driver); if (ret < 0) { - put_tty_driver(driver); + tty_driver_kref_put(driver); tty_port_destroy(&ttynull_port); return ret; } @@ -99,7 +99,7 @@ static void __exit ttynull_exit(void) { unregister_console(&ttynull_console); tty_unregister_driver(ttynull_driver); - put_tty_driver(ttynull_driver); + tty_driver_kref_put(ttynull_driver); tty_port_destroy(&ttynull_port); } diff --git a/drivers/tty/vcc.c b/drivers/tty/vcc.c index d06bcc3b4c07..e11383ae1e7e 100644 --- a/drivers/tty/vcc.c +++ b/drivers/tty/vcc.c @@ -1028,7 +1028,7 @@ static int vcc_tty_init(void) rv = tty_register_driver(vcc_tty_driver); if (rv) { pr_err("VCC: TTY driver registration failed\n"); - put_tty_driver(vcc_tty_driver); + tty_driver_kref_put(vcc_tty_driver); vcc_tty_driver = NULL; return rv; } @@ -1041,7 +1041,7 @@ static int vcc_tty_init(void) static void vcc_tty_exit(void) { tty_unregister_driver(vcc_tty_driver); - put_tty_driver(vcc_tty_driver); + tty_driver_kref_put(vcc_tty_driver); vccdbg("VCC: TTY driver unregistered\n"); vcc_tty_driver = NULL; diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index c19b59583d9f..8bbd8e29e60d 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -2044,14 +2044,14 @@ static int __init acm_init(void) retval = tty_register_driver(acm_tty_driver); if (retval) { - put_tty_driver(acm_tty_driver); + tty_driver_kref_put(acm_tty_driver); return retval; } retval = usb_register(&acm_driver); if (retval) { tty_unregister_driver(acm_tty_driver); - put_tty_driver(acm_tty_driver); + tty_driver_kref_put(acm_tty_driver); return retval; } @@ -2064,7 +2064,7 @@ static void __exit acm_exit(void) { usb_deregister(&acm_driver); tty_unregister_driver(acm_tty_driver); - put_tty_driver(acm_tty_driver); + tty_driver_kref_put(acm_tty_driver); idr_destroy(&acm_minors); } diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c index 74289f68a2ab..72961c1beeef 100644 --- a/drivers/usb/gadget/function/u_serial.c +++ b/drivers/usb/gadget/function/u_serial.c @@ -1491,7 +1491,7 @@ static int userial_init(void) return status; fail: - put_tty_driver(driver); + tty_driver_kref_put(driver); return status; } module_init(userial_init); @@ -1499,7 +1499,7 @@ module_init(userial_init); static void userial_cleanup(void) { tty_unregister_driver(gs_tty_driver); - put_tty_driver(gs_tty_driver); + tty_driver_kref_put(gs_tty_driver); gs_tty_driver = NULL; } module_exit(userial_cleanup); diff --git a/drivers/usb/host/xhci-dbgtty.c b/drivers/usb/host/xhci-dbgtty.c index bef104511352..6e784f2fc26d 100644 --- a/drivers/usb/host/xhci-dbgtty.c +++ b/drivers/usb/host/xhci-dbgtty.c @@ -541,7 +541,7 @@ static int dbc_tty_init(void) ret = tty_register_driver(dbc_tty_driver); if (ret) { pr_err("Can't register dbc tty driver\n"); - put_tty_driver(dbc_tty_driver); + tty_driver_kref_put(dbc_tty_driver); } return ret; } @@ -550,7 +550,7 @@ static void dbc_tty_exit(void) { if (dbc_tty_driver) { tty_unregister_driver(dbc_tty_driver); - put_tty_driver(dbc_tty_driver); + tty_driver_kref_put(dbc_tty_driver); dbc_tty_driver = NULL; } } diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 2f7855da645f..090a78c948f2 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -1366,7 +1366,7 @@ exit_reg_driver: exit_bus: pr_err("%s - returning with error %d\n", __func__, result); - put_tty_driver(usb_serial_tty_driver); + tty_driver_kref_put(usb_serial_tty_driver); return result; } @@ -1378,7 +1378,7 @@ static void __exit usb_serial_exit(void) usb_serial_generic_deregister(); tty_unregister_driver(usb_serial_tty_driver); - put_tty_driver(usb_serial_tty_driver); + tty_driver_kref_put(usb_serial_tty_driver); bus_unregister(&usb_serial_bus_type); idr_destroy(&serial_minors); } diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h index 6092ce9180aa..c20431d8def8 100644 --- a/include/linux/tty_driver.h +++ b/include/linux/tty_driver.h @@ -329,7 +329,6 @@ extern struct list_head tty_drivers; extern struct tty_driver *__tty_alloc_driver(unsigned int lines, struct module *owner, unsigned long flags); -extern void put_tty_driver(struct tty_driver *driver); extern struct tty_driver *tty_find_polling_driver(char *name, int *line); extern void tty_driver_kref_put(struct tty_driver *driver); diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index 8ec0600cd927..ebd78fdbd6e8 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c @@ -1146,7 +1146,7 @@ int __init rfcomm_init_ttys(void) error = tty_register_driver(rfcomm_tty_driver); if (error) { BT_ERR("Can't register RFCOMM TTY driver"); - put_tty_driver(rfcomm_tty_driver); + tty_driver_kref_put(rfcomm_tty_driver); return error; } @@ -1158,5 +1158,5 @@ int __init rfcomm_init_ttys(void) void rfcomm_cleanup_ttys(void) { tty_unregister_driver(rfcomm_tty_driver); - put_tty_driver(rfcomm_tty_driver); + tty_driver_kref_put(rfcomm_tty_driver); } -- cgit v1.2.3-58-ga151 From 3a96e97ab4e835078e6f27b7e1c0947814df3841 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 26 Jul 2021 15:07:17 +0200 Subject: serial: 8250_pci: make setup_port() parameters explicitly unsigned The bar and offset parameters to setup_port() are used in pointer math, and while it would be very difficult to get them to wrap as a negative number, just be "safe" and make them unsigned so that static checkers do not trip over them unintentionally. Cc: Jiri Slaby Reported-by: Jordy Zomer Link: https://lore.kernel.org/r/20210726130717.2052096-1-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 75827b608fdb..fe64f77a9789 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -87,7 +87,7 @@ static void moan_device(const char *str, struct pci_dev *dev) static int setup_port(struct serial_private *priv, struct uart_8250_port *port, - int bar, int offset, int regshift) + u8 bar, unsigned int offset, int regshift) { struct pci_dev *dev = priv->dev; -- cgit v1.2.3-58-ga151 From c92bbbfe21efaa4344871bd2fb5a7649c0b07b84 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 26 Jul 2021 15:43:21 +0200 Subject: vt: keyboard: treat kbd_table as an array all the time. The keyboard.c code seems to like to treat the kbd_table as both an array, and as a base to do some pointer math off of. As they really are the same thing, and compilers are smart enough not to make a difference anymore, just be explicit and always use this as an array to make the code more obvious for all to read. Cc: Jiri Slaby Cc: Andy Shevchenko Cc: Jordy Zomer Link: https://lore.kernel.org/r/20210726134322.2274919-1-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/keyboard.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c index 4b0d69042ceb..e81c940a2ea1 100644 --- a/drivers/tty/vt/keyboard.c +++ b/drivers/tty/vt/keyboard.c @@ -1173,7 +1173,7 @@ static inline unsigned char getleds(void) */ int vt_get_leds(int console, int flag) { - struct kbd_struct *kb = kbd_table + console; + struct kbd_struct *kb = &kbd_table[console]; int ret; unsigned long flags; @@ -1195,7 +1195,7 @@ EXPORT_SYMBOL_GPL(vt_get_leds); */ void vt_set_led_state(int console, int leds) { - struct kbd_struct *kb = kbd_table + console; + struct kbd_struct *kb = &kbd_table[console]; setledstate(kb, leds); } @@ -1214,7 +1214,7 @@ void vt_set_led_state(int console, int leds) */ void vt_kbd_con_start(int console) { - struct kbd_struct *kb = kbd_table + console; + struct kbd_struct *kb = &kbd_table[console]; unsigned long flags; spin_lock_irqsave(&led_lock, flags); clr_vc_kbd_led(kb, VC_SCROLLOCK); @@ -1231,7 +1231,7 @@ void vt_kbd_con_start(int console) */ void vt_kbd_con_stop(int console) { - struct kbd_struct *kb = kbd_table + console; + struct kbd_struct *kb = &kbd_table[console]; unsigned long flags; spin_lock_irqsave(&led_lock, flags); set_vc_kbd_led(kb, VC_SCROLLOCK); @@ -1377,7 +1377,7 @@ static void kbd_rawcode(unsigned char data) { struct vc_data *vc = vc_cons[fg_console].d; - kbd = kbd_table + vc->vc_num; + kbd = &kbd_table[vc->vc_num]; if (kbd->kbdmode == VC_RAW) put_queue(vc, data); } @@ -1400,7 +1400,7 @@ static void kbd_keycode(unsigned int keycode, int down, bool hw_raw) tty->driver_data = vc; } - kbd = kbd_table + vc->vc_num; + kbd = &kbd_table[vc->vc_num]; #ifdef CONFIG_SPARC if (keycode == KEY_STOP) @@ -1827,7 +1827,7 @@ int vt_do_diacrit(unsigned int cmd, void __user *udp, int perm) */ int vt_do_kdskbmode(int console, unsigned int arg) { - struct kbd_struct *kb = kbd_table + console; + struct kbd_struct *kb = &kbd_table[console]; int ret = 0; unsigned long flags; @@ -1867,7 +1867,7 @@ int vt_do_kdskbmode(int console, unsigned int arg) */ int vt_do_kdskbmeta(int console, unsigned int arg) { - struct kbd_struct *kb = kbd_table + console; + struct kbd_struct *kb = &kbd_table[console]; int ret = 0; unsigned long flags; @@ -2010,7 +2010,7 @@ out: int vt_do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm, int console) { - struct kbd_struct *kb = kbd_table + console; + struct kbd_struct *kb = &kbd_table[console]; struct kbentry kbe; if (copy_from_user(&kbe, user_kbe, sizeof(struct kbentry))) @@ -2099,7 +2099,7 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm) int vt_do_kdskled(int console, int cmd, unsigned long arg, int perm) { - struct kbd_struct *kb = kbd_table + console; + struct kbd_struct *kb = &kbd_table[console]; unsigned long flags; unsigned char ucval; @@ -2141,7 +2141,7 @@ int vt_do_kdskled(int console, int cmd, unsigned long arg, int perm) int vt_do_kdgkbmode(int console) { - struct kbd_struct *kb = kbd_table + console; + struct kbd_struct *kb = &kbd_table[console]; /* This is a spot read so needs no locking */ switch (kb->kbdmode) { case VC_RAW: @@ -2165,7 +2165,7 @@ int vt_do_kdgkbmode(int console) */ int vt_do_kdgkbmeta(int console) { - struct kbd_struct *kb = kbd_table + console; + struct kbd_struct *kb = &kbd_table[console]; /* Again a spot read so no locking */ return vc_kbd_mode(kb, VC_META) ? K_ESCPREFIX : K_METABIT; } @@ -2206,7 +2206,7 @@ int vt_get_shift_state(void) */ void vt_reset_keyboard(int console) { - struct kbd_struct *kb = kbd_table + console; + struct kbd_struct *kb = &kbd_table[console]; unsigned long flags; spin_lock_irqsave(&kbd_event_lock, flags); @@ -2236,7 +2236,7 @@ void vt_reset_keyboard(int console) int vt_get_kbd_mode_bit(int console, int bit) { - struct kbd_struct *kb = kbd_table + console; + struct kbd_struct *kb = &kbd_table[console]; return vc_kbd_mode(kb, bit); } @@ -2251,7 +2251,7 @@ int vt_get_kbd_mode_bit(int console, int bit) void vt_set_kbd_mode_bit(int console, int bit) { - struct kbd_struct *kb = kbd_table + console; + struct kbd_struct *kb = &kbd_table[console]; unsigned long flags; spin_lock_irqsave(&kbd_event_lock, flags); @@ -2270,7 +2270,7 @@ void vt_set_kbd_mode_bit(int console, int bit) void vt_clr_kbd_mode_bit(int console, int bit) { - struct kbd_struct *kb = kbd_table + console; + struct kbd_struct *kb = &kbd_table[console]; unsigned long flags; spin_lock_irqsave(&kbd_event_lock, flags); -- cgit v1.2.3-58-ga151 From 3df15d6f37246d2f12f53d915c41d806289d3d46 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 26 Jul 2021 15:43:22 +0200 Subject: vt: keyboard.c: make console an unsigned int The console variable is used everywhere in some fun pointer path and array indexes and for some reason isn't always declared as unsigned. This plays havoc with some static analysis tools so mark the variable as unsigned so we "know" we can not wrap the arrays backwards here. Cc: Jiri Slaby Cc: Andy Shevchenko Reported-by: Jordy Zomer Link: https://lore.kernel.org/r/20210726134322.2274919-2-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/keyboard.c | 30 +++++++++++++++--------------- include/linux/vt_kern.h | 30 +++++++++++++++--------------- 2 files changed, 30 insertions(+), 30 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c index e81c940a2ea1..c7fbbcdcc346 100644 --- a/drivers/tty/vt/keyboard.c +++ b/drivers/tty/vt/keyboard.c @@ -1171,7 +1171,7 @@ static inline unsigned char getleds(void) * * Check the status of a keyboard led flag and report it back */ -int vt_get_leds(int console, int flag) +int vt_get_leds(unsigned int console, int flag) { struct kbd_struct *kb = &kbd_table[console]; int ret; @@ -1193,7 +1193,7 @@ EXPORT_SYMBOL_GPL(vt_get_leds); * Set the LEDs on a console. This is a wrapper for the VT layer * so that we can keep kbd knowledge internal */ -void vt_set_led_state(int console, int leds) +void vt_set_led_state(unsigned int console, int leds) { struct kbd_struct *kb = &kbd_table[console]; setledstate(kb, leds); @@ -1212,7 +1212,7 @@ void vt_set_led_state(int console, int leds) * don't hold the lock. We probably need to split out an LED lock * but not during an -rc release! */ -void vt_kbd_con_start(int console) +void vt_kbd_con_start(unsigned int console) { struct kbd_struct *kb = &kbd_table[console]; unsigned long flags; @@ -1229,7 +1229,7 @@ void vt_kbd_con_start(int console) * Handle console stop. This is a wrapper for the VT layer * so that we can keep kbd knowledge internal */ -void vt_kbd_con_stop(int console) +void vt_kbd_con_stop(unsigned int console) { struct kbd_struct *kb = &kbd_table[console]; unsigned long flags; @@ -1825,7 +1825,7 @@ int vt_do_diacrit(unsigned int cmd, void __user *udp, int perm) * Update the keyboard mode bits while holding the correct locks. * Return 0 for success or an error code. */ -int vt_do_kdskbmode(int console, unsigned int arg) +int vt_do_kdskbmode(unsigned int console, unsigned int arg) { struct kbd_struct *kb = &kbd_table[console]; int ret = 0; @@ -1865,7 +1865,7 @@ int vt_do_kdskbmode(int console, unsigned int arg) * Update the keyboard meta bits while holding the correct locks. * Return 0 for success or an error code. */ -int vt_do_kdskbmeta(int console, unsigned int arg) +int vt_do_kdskbmeta(unsigned int console, unsigned int arg) { struct kbd_struct *kb = &kbd_table[console]; int ret = 0; @@ -2008,7 +2008,7 @@ out: } int vt_do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm, - int console) + unsigned int console) { struct kbd_struct *kb = &kbd_table[console]; struct kbentry kbe; @@ -2097,7 +2097,7 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm) return ret; } -int vt_do_kdskled(int console, int cmd, unsigned long arg, int perm) +int vt_do_kdskled(unsigned int console, int cmd, unsigned long arg, int perm) { struct kbd_struct *kb = &kbd_table[console]; unsigned long flags; @@ -2139,7 +2139,7 @@ int vt_do_kdskled(int console, int cmd, unsigned long arg, int perm) return -ENOIOCTLCMD; } -int vt_do_kdgkbmode(int console) +int vt_do_kdgkbmode(unsigned int console) { struct kbd_struct *kb = &kbd_table[console]; /* This is a spot read so needs no locking */ @@ -2163,7 +2163,7 @@ int vt_do_kdgkbmode(int console) * * Report the meta flag status of this console */ -int vt_do_kdgkbmeta(int console) +int vt_do_kdgkbmeta(unsigned int console) { struct kbd_struct *kb = &kbd_table[console]; /* Again a spot read so no locking */ @@ -2176,7 +2176,7 @@ int vt_do_kdgkbmeta(int console) * * Restore the unicode console state to its default */ -void vt_reset_unicode(int console) +void vt_reset_unicode(unsigned int console) { unsigned long flags; @@ -2204,7 +2204,7 @@ int vt_get_shift_state(void) * Reset the keyboard bits for a console as part of a general console * reset event */ -void vt_reset_keyboard(int console) +void vt_reset_keyboard(unsigned int console) { struct kbd_struct *kb = &kbd_table[console]; unsigned long flags; @@ -2234,7 +2234,7 @@ void vt_reset_keyboard(int console) * caller must be sure that there are no synchronization needs */ -int vt_get_kbd_mode_bit(int console, int bit) +int vt_get_kbd_mode_bit(unsigned int console, int bit) { struct kbd_struct *kb = &kbd_table[console]; return vc_kbd_mode(kb, bit); @@ -2249,7 +2249,7 @@ int vt_get_kbd_mode_bit(int console, int bit) * caller must be sure that there are no synchronization needs */ -void vt_set_kbd_mode_bit(int console, int bit) +void vt_set_kbd_mode_bit(unsigned int console, int bit) { struct kbd_struct *kb = &kbd_table[console]; unsigned long flags; @@ -2268,7 +2268,7 @@ void vt_set_kbd_mode_bit(int console, int bit) * caller must be sure that there are no synchronization needs */ -void vt_clr_kbd_mode_bit(int console, int bit) +void vt_clr_kbd_mode_bit(unsigned int console, int bit) { struct kbd_struct *kb = &kbd_table[console]; unsigned long flags; diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h index 0da94a6dee15..b5ab452fca5b 100644 --- a/include/linux/vt_kern.h +++ b/include/linux/vt_kern.h @@ -148,26 +148,26 @@ void hide_boot_cursor(bool hide); /* keyboard provided interfaces */ int vt_do_diacrit(unsigned int cmd, void __user *up, int eperm); -int vt_do_kdskbmode(int console, unsigned int arg); -int vt_do_kdskbmeta(int console, unsigned int arg); +int vt_do_kdskbmode(unsigned int console, unsigned int arg); +int vt_do_kdskbmeta(unsigned int console, unsigned int arg); int vt_do_kbkeycode_ioctl(int cmd, struct kbkeycode __user *user_kbkc, int perm); int vt_do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm, - int console); + unsigned int console); int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm); -int vt_do_kdskled(int console, int cmd, unsigned long arg, int perm); -int vt_do_kdgkbmode(int console); -int vt_do_kdgkbmeta(int console); -void vt_reset_unicode(int console); +int vt_do_kdskled(unsigned int console, int cmd, unsigned long arg, int perm); +int vt_do_kdgkbmode(unsigned int console); +int vt_do_kdgkbmeta(unsigned int console); +void vt_reset_unicode(unsigned int console); int vt_get_shift_state(void); -void vt_reset_keyboard(int console); -int vt_get_leds(int console, int flag); -int vt_get_kbd_mode_bit(int console, int bit); -void vt_set_kbd_mode_bit(int console, int bit); -void vt_clr_kbd_mode_bit(int console, int bit); -void vt_set_led_state(int console, int leds); -void vt_kbd_con_start(int console); -void vt_kbd_con_stop(int console); +void vt_reset_keyboard(unsigned int console); +int vt_get_leds(unsigned int console, int flag); +int vt_get_kbd_mode_bit(unsigned int console, int bit); +void vt_set_kbd_mode_bit(unsigned int console, int bit); +void vt_clr_kbd_mode_bit(unsigned int console, int bit); +void vt_set_led_state(unsigned int console, int leds); +void vt_kbd_con_start(unsigned int console); +void vt_kbd_con_stop(unsigned int console); void vc_scrolldelta_helper(struct vc_data *c, int lines, unsigned int rolled_over, void *_base, unsigned int size); -- cgit v1.2.3-58-ga151 From 33e5571ebdec49cb87e8cbba730cf046dfb44e80 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Tue, 27 Jul 2021 13:31:48 +0300 Subject: serial: omap: Disable PM runtime autoidle to remove pm_runtime_irq_safe() We want to remove the use of pm_runtime_irq_safe() from serial drivers to allow making PM runtime handling generic. Let's simplify things by disabling PM runtime autoidle for omap-serial as this driver has been deprecated for years because of the 8250_omap driver. There are still some omap-serial users that seem to hang on to it for some unknown rs485 reasons it seems. But presumably those folks do not need PM runtime autoidle with omap-serial, and hopefully can just move to using 8250_omap driver instead. For 8250_omap driver, we will eventually move to use generic serial layer PM based on patches done by Andy Shevchenko to remove pm_runtime_irq_safe() usage. Cc: Andy Shevchenko Cc: Dario Binacchi Cc: Vignesh Raghavendra Reviewed-by: Andy Shevchenko Signed-off-by: Tony Lindgren Link: https://lore.kernel.org/r/20210727103149.51175-1-tony@atomide.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/omap-serial.c | 75 ++-------------------------------------- 1 file changed, 2 insertions(+), 73 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 9e81b09ba08e..0862941862c8 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -276,11 +276,8 @@ static void serial_omap_enable_ms(struct uart_port *port) dev_dbg(up->port.dev, "serial_omap_enable_ms+%d\n", up->port.line); - pm_runtime_get_sync(up->dev); up->ier |= UART_IER_MSI; serial_out(up, UART_IER, up->ier); - pm_runtime_mark_last_busy(up->dev); - pm_runtime_put_autosuspend(up->dev); } static void serial_omap_stop_tx(struct uart_port *port) @@ -288,8 +285,6 @@ static void serial_omap_stop_tx(struct uart_port *port) struct uart_omap_port *up = to_uart_omap_port(port); int res; - pm_runtime_get_sync(up->dev); - /* Handle RS-485 */ if (port->rs485.flags & SER_RS485_ENABLED) { if (up->scr & OMAP_UART_SCR_TX_EMPTY) { @@ -330,21 +325,15 @@ static void serial_omap_stop_tx(struct uart_port *port) up->ier &= ~UART_IER_THRI; serial_out(up, UART_IER, up->ier); } - - pm_runtime_mark_last_busy(up->dev); - pm_runtime_put_autosuspend(up->dev); } static void serial_omap_stop_rx(struct uart_port *port) { struct uart_omap_port *up = to_uart_omap_port(port); - pm_runtime_get_sync(up->dev); up->ier &= ~(UART_IER_RLSI | UART_IER_RDI); up->port.read_status_mask &= ~UART_LSR_DR; serial_out(up, UART_IER, up->ier); - pm_runtime_mark_last_busy(up->dev); - pm_runtime_put_autosuspend(up->dev); } static void transmit_chars(struct uart_omap_port *up, unsigned int lsr) @@ -399,8 +388,6 @@ static void serial_omap_start_tx(struct uart_port *port) struct uart_omap_port *up = to_uart_omap_port(port); int res; - pm_runtime_get_sync(up->dev); - /* Handle RS-485 */ if (port->rs485.flags & SER_RS485_ENABLED) { /* Fire THR interrupts when FIFO is below trigger level */ @@ -421,8 +408,6 @@ static void serial_omap_start_tx(struct uart_port *port) up->rs485_tx_filter_count = 0; serial_omap_enable_ier_thri(up); - pm_runtime_mark_last_busy(up->dev); - pm_runtime_put_autosuspend(up->dev); } static void serial_omap_throttle(struct uart_port *port) @@ -430,13 +415,10 @@ static void serial_omap_throttle(struct uart_port *port) struct uart_omap_port *up = to_uart_omap_port(port); unsigned long flags; - pm_runtime_get_sync(up->dev); spin_lock_irqsave(&up->port.lock, flags); up->ier &= ~(UART_IER_RLSI | UART_IER_RDI); serial_out(up, UART_IER, up->ier); spin_unlock_irqrestore(&up->port.lock, flags); - pm_runtime_mark_last_busy(up->dev); - pm_runtime_put_autosuspend(up->dev); } static void serial_omap_unthrottle(struct uart_port *port) @@ -444,13 +426,10 @@ static void serial_omap_unthrottle(struct uart_port *port) struct uart_omap_port *up = to_uart_omap_port(port); unsigned long flags; - pm_runtime_get_sync(up->dev); spin_lock_irqsave(&up->port.lock, flags); up->ier |= UART_IER_RLSI | UART_IER_RDI; serial_out(up, UART_IER, up->ier); spin_unlock_irqrestore(&up->port.lock, flags); - pm_runtime_mark_last_busy(up->dev); - pm_runtime_put_autosuspend(up->dev); } static unsigned int check_modem_status(struct uart_omap_port *up) @@ -576,7 +555,6 @@ static irqreturn_t serial_omap_irq(int irq, void *dev_id) int max_count = 256; spin_lock(&up->port.lock); - pm_runtime_get_sync(up->dev); do { iir = serial_in(up, UART_IIR); @@ -616,8 +594,6 @@ static irqreturn_t serial_omap_irq(int irq, void *dev_id) tty_flip_buffer_push(&up->port.state->port); - pm_runtime_mark_last_busy(up->dev); - pm_runtime_put_autosuspend(up->dev); up->port_activity = jiffies; return ret; @@ -629,13 +605,11 @@ static unsigned int serial_omap_tx_empty(struct uart_port *port) unsigned long flags; unsigned int ret = 0; - pm_runtime_get_sync(up->dev); dev_dbg(up->port.dev, "serial_omap_tx_empty+%d\n", up->port.line); spin_lock_irqsave(&up->port.lock, flags); ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0; spin_unlock_irqrestore(&up->port.lock, flags); - pm_runtime_mark_last_busy(up->dev); - pm_runtime_put_autosuspend(up->dev); + return ret; } @@ -645,10 +619,7 @@ static unsigned int serial_omap_get_mctrl(struct uart_port *port) unsigned int status; unsigned int ret = 0; - pm_runtime_get_sync(up->dev); status = check_modem_status(up); - pm_runtime_mark_last_busy(up->dev); - pm_runtime_put_autosuspend(up->dev); dev_dbg(up->port.dev, "serial_omap_get_mctrl+%d\n", up->port.line); @@ -680,7 +651,6 @@ static void serial_omap_set_mctrl(struct uart_port *port, unsigned int mctrl) if (mctrl & TIOCM_LOOP) mcr |= UART_MCR_LOOP; - pm_runtime_get_sync(up->dev); old_mcr = serial_in(up, UART_MCR); old_mcr &= ~(UART_MCR_LOOP | UART_MCR_OUT2 | UART_MCR_OUT1 | UART_MCR_DTR | UART_MCR_RTS); @@ -696,9 +666,6 @@ static void serial_omap_set_mctrl(struct uart_port *port, unsigned int mctrl) up->efr &= ~UART_EFR_RTS; serial_out(up, UART_EFR, up->efr); serial_out(up, UART_LCR, lcr); - - pm_runtime_mark_last_busy(up->dev); - pm_runtime_put_autosuspend(up->dev); } static void serial_omap_break_ctl(struct uart_port *port, int break_state) @@ -707,7 +674,6 @@ static void serial_omap_break_ctl(struct uart_port *port, int break_state) unsigned long flags; dev_dbg(up->port.dev, "serial_omap_break_ctl+%d\n", up->port.line); - pm_runtime_get_sync(up->dev); spin_lock_irqsave(&up->port.lock, flags); if (break_state == -1) up->lcr |= UART_LCR_SBC; @@ -715,8 +681,6 @@ static void serial_omap_break_ctl(struct uart_port *port, int break_state) up->lcr &= ~UART_LCR_SBC; serial_out(up, UART_LCR, up->lcr); spin_unlock_irqrestore(&up->port.lock, flags); - pm_runtime_mark_last_busy(up->dev); - pm_runtime_put_autosuspend(up->dev); } static int serial_omap_startup(struct uart_port *port) @@ -788,8 +752,6 @@ static int serial_omap_startup(struct uart_port *port) serial_out(up, UART_OMAP_WER, up->wer); - pm_runtime_mark_last_busy(up->dev); - pm_runtime_put_autosuspend(up->dev); up->port_activity = jiffies; return 0; } @@ -801,7 +763,6 @@ static void serial_omap_shutdown(struct uart_port *port) dev_dbg(up->port.dev, "serial_omap_shutdown+%d\n", up->port.line); - pm_runtime_get_sync(up->dev); /* * Disable interrupts from this port */ @@ -825,8 +786,7 @@ static void serial_omap_shutdown(struct uart_port *port) if (serial_in(up, UART_LSR) & UART_LSR_DR) (void) serial_in(up, UART_RX); - pm_runtime_mark_last_busy(up->dev); - pm_runtime_put_autosuspend(up->dev); + pm_runtime_put_sync(up->dev); free_irq(up->port.irq, up); dev_pm_clear_wake_irq(up->dev); } @@ -896,7 +856,6 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, * Ok, we're now changing the port state. Do it with * interrupts disabled. */ - pm_runtime_get_sync(up->dev); spin_lock_irqsave(&up->port.lock, flags); /* @@ -1096,8 +1055,6 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, serial_omap_set_mctrl(&up->port, up->port.mctrl); spin_unlock_irqrestore(&up->port.lock, flags); - pm_runtime_mark_last_busy(up->dev); - pm_runtime_put_autosuspend(up->dev); dev_dbg(up->port.dev, "serial_omap_set_termios+%d\n", up->port.line); } @@ -1110,7 +1067,6 @@ serial_omap_pm(struct uart_port *port, unsigned int state, dev_dbg(up->port.dev, "serial_omap_pm+%d\n", up->port.line); - pm_runtime_get_sync(up->dev); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); efr = serial_in(up, UART_EFR); serial_out(up, UART_EFR, efr | UART_EFR_ECB); @@ -1120,9 +1076,6 @@ serial_omap_pm(struct uart_port *port, unsigned int state, serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); serial_out(up, UART_EFR, efr); serial_out(up, UART_LCR, 0); - - pm_runtime_mark_last_busy(up->dev); - pm_runtime_put_autosuspend(up->dev); } static void serial_omap_release_port(struct uart_port *port) @@ -1202,11 +1155,8 @@ static void serial_omap_poll_put_char(struct uart_port *port, unsigned char ch) { struct uart_omap_port *up = to_uart_omap_port(port); - pm_runtime_get_sync(up->dev); wait_for_xmitr(up); serial_out(up, UART_TX, ch); - pm_runtime_mark_last_busy(up->dev); - pm_runtime_put_autosuspend(up->dev); } static int serial_omap_poll_get_char(struct uart_port *port) @@ -1214,7 +1164,6 @@ static int serial_omap_poll_get_char(struct uart_port *port) struct uart_omap_port *up = to_uart_omap_port(port); unsigned int status; - pm_runtime_get_sync(up->dev); status = serial_in(up, UART_LSR); if (!(status & UART_LSR_DR)) { status = NO_POLL_CHAR; @@ -1224,9 +1173,6 @@ static int serial_omap_poll_get_char(struct uart_port *port) status = serial_in(up, UART_RX); out: - pm_runtime_mark_last_busy(up->dev); - pm_runtime_put_autosuspend(up->dev); - return status; } @@ -1309,8 +1255,6 @@ serial_omap_console_write(struct console *co, const char *s, unsigned int ier; int locked = 1; - pm_runtime_get_sync(up->dev); - local_irq_save(flags); if (up->port.sysrq) locked = 0; @@ -1343,8 +1287,6 @@ serial_omap_console_write(struct console *co, const char *s, if (up->msr_saved_flags) check_modem_status(up); - pm_runtime_mark_last_busy(up->dev); - pm_runtime_put_autosuspend(up->dev); if (locked) spin_unlock(&up->port.lock); local_irq_restore(flags); @@ -1403,8 +1345,6 @@ serial_omap_config_rs485(struct uart_port *port, struct serial_rs485 *rs485) unsigned int mode; int val; - pm_runtime_get_sync(up->dev); - /* Disable interrupts from this port */ mode = up->ier; up->ier = 0; @@ -1438,9 +1378,6 @@ serial_omap_config_rs485(struct uart_port *port, struct serial_rs485 *rs485) serial_out(up, UART_OMAP_SCR, up->scr); } - pm_runtime_mark_last_busy(up->dev); - pm_runtime_put_autosuspend(up->dev); - return 0; } @@ -1737,11 +1674,7 @@ static int serial_omap_probe(struct platform_device *pdev) omap_up_info->autosuspend_timeout = -1; device_init_wakeup(up->dev, true); - pm_runtime_use_autosuspend(&pdev->dev); - pm_runtime_set_autosuspend_delay(&pdev->dev, - omap_up_info->autosuspend_timeout); - pm_runtime_irq_safe(&pdev->dev); pm_runtime_enable(&pdev->dev); pm_runtime_get_sync(&pdev->dev); @@ -1755,12 +1688,9 @@ static int serial_omap_probe(struct platform_device *pdev) if (ret != 0) goto err_add_port; - pm_runtime_mark_last_busy(up->dev); - pm_runtime_put_autosuspend(up->dev); return 0; err_add_port: - pm_runtime_dont_use_autosuspend(&pdev->dev); pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); cpu_latency_qos_remove_request(&up->pm_qos_request); @@ -1778,7 +1708,6 @@ static int serial_omap_remove(struct platform_device *dev) uart_remove_one_port(&serial_omap_reg, &up->port); - pm_runtime_dont_use_autosuspend(up->dev); pm_runtime_put_sync(up->dev); pm_runtime_disable(up->dev); cpu_latency_qos_remove_request(&up->pm_qos_request); -- cgit v1.2.3-58-ga151 From 6c44eb5905f6cc731b36c4170f703f81e477f039 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Tue, 27 Jul 2021 13:31:49 +0300 Subject: serial: omap: Only allow if 8250_omap is not selected For years we've been carrying legacy omap-serial in addition to 8250_omap driver and 8250_omap should be used instead. Let's finally start planning on removing omap-serial by first not building it if 8250_omap is selected to save some memory. The defconfigs have switched over to using 8250_omap, and we have a fixup in place for the the serial console since commit 00648d0282dc ("tty: serial: 8250: omap: add ttySx console if the user didn't"). So people updating their systems without omap-serial will see boot time warnings on what is going on. Cc: Andy Shevchenko Cc: Dario Binacchi Cc: Vignesh Raghavendra Signed-off-by: Tony Lindgren Link: https://lore.kernel.org/r/20210727103149.51175-2-tony@atomide.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index e0f6d5bfdc94..131a6a587acd 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -959,7 +959,7 @@ config SERIAL_VT8500_CONSOLE config SERIAL_OMAP tristate "OMAP serial port support" - depends on ARCH_OMAP2PLUS || COMPILE_TEST + depends on (ARCH_OMAP2PLUS && !SERIAL_8250_OMAP) || COMPILE_TEST select SERIAL_CORE help If you have a machine based on an Texas Instruments OMAP CPU you -- cgit v1.2.3-58-ga151 From 1fe0e1fa3209ad8e9124147775bd27b1d9f04bd4 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Tue, 27 Jul 2021 13:35:33 +0300 Subject: serial: 8250_omap: Handle optional overrun-throttle-ms property Handle optional overrun-throttle-ms property as done for 8250_fsl in commit 6d7f677a2afa ("serial: 8250: Rate limit serial port rx interrupts during input overruns"). This can be used to rate limit the UART interrupts on noisy lines that end up producing messages like the following: ttyS ttyS2: 4 input overrun(s) At least on droid4, the multiplexed USB and UART port is left to UART mode by the bootloader for a debug console, and if a USB charger is connected on boot, we get noise on the UART until the PMIC related drivers for PHY and charger are loaded. With this patch and overrun-throttle-ms = <500> we avoid the extra rx interrupts. Cc: Carl Philipp Klemm Cc: Merlijn Wajer Cc: Pavel Machek Cc: Sebastian Reichel Cc: Vignesh Raghavendra Signed-off-by: Tony Lindgren Link: https://lore.kernel.org/r/20210727103533.51547-2-tony@atomide.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_omap.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index b81d1bdc7b88..891fd8345e25 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -617,7 +617,7 @@ static irqreturn_t omap8250_irq(int irq, void *dev_id) struct uart_port *port = dev_id; struct omap8250_priv *priv = port->private_data; struct uart_8250_port *up = up_to_u8250p(port); - unsigned int iir; + unsigned int iir, lsr; int ret; #ifdef CONFIG_SERIAL_8250_DMA @@ -628,6 +628,7 @@ static irqreturn_t omap8250_irq(int irq, void *dev_id) #endif serial8250_rpm_get(up); + lsr = serial_port_in(port, UART_LSR); iir = serial_port_in(port, UART_IIR); ret = serial8250_handle_irq(port, iir); @@ -642,6 +643,24 @@ static irqreturn_t omap8250_irq(int irq, void *dev_id) serial_port_in(port, UART_RX); } + /* Stop processing interrupts on input overrun */ + if ((lsr & UART_LSR_OE) && up->overrun_backoff_time_ms > 0) { + unsigned long delay; + + up->ier = port->serial_in(port, UART_IER); + if (up->ier & (UART_IER_RLSI | UART_IER_RDI)) { + port->ops->stop_rx(port); + } else { + /* Keep restarting the timer until + * the input overrun subsides. + */ + cancel_delayed_work(&up->overrun_backoff); + } + + delay = msecs_to_jiffies(up->overrun_backoff_time_ms); + schedule_delayed_work(&up->overrun_backoff, delay); + } + serial8250_rpm_put(up); return IRQ_RETVAL(ret); @@ -1353,6 +1372,10 @@ static int omap8250_probe(struct platform_device *pdev) } } + if (of_property_read_u32(np, "overrun-throttle-ms", + &up.overrun_backoff_time_ms) != 0) + up.overrun_backoff_time_ms = 0; + priv->wakeirq = irq_of_parse_and_map(np, 1); pdata = of_device_get_match_data(&pdev->dev); -- cgit v1.2.3-58-ga151 From 217b04c67b6bca03a484bf8cad44596a34a9de4c Mon Sep 17 00:00:00 2001 From: Tang Bin Date: Wed, 11 Aug 2021 18:51:36 +0800 Subject: serial: stm32: fix the conditional expression writing In the function stm32_usart_init_port, intent of the code maybe when irq returns a value of zero, the return should be '-ENODEV'. But the conditional expression '? :' maybe clerical error, it should be '?:' to make '-ENODEV' work. But in fact, as the example in platform.c is * int irq = platform_get_irq(pdev, 0); * if (irq < 0) * return irq; So the return value of zero is unnecessary to check, at last remove the unnecessary '?: -ENODEV'. Co-developed-by: Zhang Shengju Signed-off-by: Zhang Shengju Signed-off-by: Tang Bin Link: https://lore.kernel.org/r/20210811105136.25392-1-tangbin@cmss.chinamobile.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/stm32-usart.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c index ef793b3b4591..090822cd1604 100644 --- a/drivers/tty/serial/stm32-usart.c +++ b/drivers/tty/serial/stm32-usart.c @@ -1034,8 +1034,8 @@ static int stm32_usart_init_port(struct stm32_port *stm32port, int ret, irq; irq = platform_get_irq(pdev, 0); - if (irq <= 0) - return irq ? : -ENODEV; + if (irq < 0) + return irq; port->iotype = UPIO_MEM; port->flags = UPF_BOOT_AUTOCONF; -- cgit v1.2.3-58-ga151 From 0a732d7dfb44da367405b23a54b305d0979e02c1 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 6 Aug 2021 14:17:35 +0300 Subject: serdev: Split and export serdev_acpi_get_uart_resource() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The same as for I²C Serial Bus resource split and export serdev_acpi_get_uart_resource(). We have already a few users one of which is converted here. Rationale of this is to consolidate parsing UART Serial Bus resource in one place as it's done, e.g., for I²C Serial Bus. Reviewed-by: Hans de Goede Acked-by: Hans de Goede Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20210806111736.66591-1-andriy.shevchenko@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serdev/core.c | 36 +++++++++++++++++++++++++++++------- include/linux/serdev.h | 14 ++++++++++++++ 2 files changed, 43 insertions(+), 7 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c index 9cdfcfe07e87..6b997aa25f74 100644 --- a/drivers/tty/serdev/core.c +++ b/drivers/tty/serdev/core.c @@ -564,23 +564,45 @@ struct acpi_serdev_lookup { int index; }; +/** + * serdev_acpi_get_uart_resource - Gets UARTSerialBus resource if type matches + * @ares: ACPI resource + * @uart: Pointer to UARTSerialBus resource will be returned here + * + * Checks if the given ACPI resource is of type UARTSerialBus. + * In this case, returns a pointer to it to the caller. + * + * Return: True if resource type is of UARTSerialBus, otherwise false. + */ +bool serdev_acpi_get_uart_resource(struct acpi_resource *ares, + struct acpi_resource_uart_serialbus **uart) +{ + struct acpi_resource_uart_serialbus *sb; + + if (ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS) + return false; + + sb = &ares->data.uart_serial_bus; + if (sb->type != ACPI_RESOURCE_SERIAL_TYPE_UART) + return false; + + *uart = sb; + return true; +} +EXPORT_SYMBOL_GPL(serdev_acpi_get_uart_resource); + static int acpi_serdev_parse_resource(struct acpi_resource *ares, void *data) { struct acpi_serdev_lookup *lookup = data; struct acpi_resource_uart_serialbus *sb; acpi_status status; - if (ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS) - return 1; - - if (ares->data.common_serial_bus.type != ACPI_RESOURCE_SERIAL_TYPE_UART) + if (!serdev_acpi_get_uart_resource(ares, &sb)) return 1; if (lookup->index != -1 && lookup->n++ != lookup->index) return 1; - sb = &ares->data.uart_serial_bus; - status = acpi_get_handle(lookup->device_handle, sb->resource_source.string_ptr, &lookup->controller_handle); @@ -588,7 +610,7 @@ static int acpi_serdev_parse_resource(struct acpi_resource *ares, void *data) return 1; /* - * NOTE: Ideally, we would also want to retreive other properties here, + * NOTE: Ideally, we would also want to retrieve other properties here, * once setting them before opening the device is supported by serdev. */ diff --git a/include/linux/serdev.h b/include/linux/serdev.h index 9f14f9c12ec4..3368c261ab62 100644 --- a/include/linux/serdev.h +++ b/include/linux/serdev.h @@ -327,4 +327,18 @@ static inline int serdev_tty_port_unregister(struct tty_port *port) } #endif /* CONFIG_SERIAL_DEV_CTRL_TTYPORT */ +struct acpi_resource; +struct acpi_resource_uart_serialbus; + +#ifdef CONFIG_ACPI +bool serdev_acpi_get_uart_resource(struct acpi_resource *ares, + struct acpi_resource_uart_serialbus **uart); +#else +static inline bool serdev_acpi_get_uart_resource(struct acpi_resource *ares, + struct acpi_resource_uart_serialbus **uart) +{ + return false; +} +#endif /* CONFIG_ACPI */ + #endif /*_LINUX_SERDEV_H */ -- cgit v1.2.3-58-ga151 From 920792aa44ffb255c66d5295d71cc747d038cc98 Mon Sep 17 00:00:00 2001 From: Sam Protsenko Date: Wed, 11 Aug 2021 14:48:24 +0300 Subject: tty: serial: samsung: Init USI to keep clocks running UART block is a part of USI (Universal Serial Interface) IP-core in Samsung SoCs since Exynos9810 (e.g. in Exynos850). USI allows one to enable one of three types of serial interface: UART, SPI or I2C. That's possible because USI shares almost all internal circuits within each protocol. USI also provides some additional registers so it's possible to configure it. One USI register called USI_OPTION has reset value of 0x0. Because of this the clock gating behavior is controlled by hardware (HWACG = Hardware Auto Clock Gating), which simply means the serial won't work after reset as is. In order to make it work, USI_OPTION[2:1] bits must be set to 0b01, so that HWACG is controlled manually (by software). Bits meaning: - CLKREQ_ON = 1: clock is continuously provided to IP - CLKSTOP_ON = 0: drive IP_CLKREQ to High (needs to be set along with CLKREQ_ON = 1) USI is not present on older chips, like s3c2410, s3c2412, s3c2440, s3c6400, s5pv210, exynos5433, exynos4210. So the new boolean field '.has_usi' was added to struct s3c24xx_uart_info. USI registers will be only actually accessed when '.has_usi' field is set to "1". This feature is needed for further serial enablement on Exynos850, but some other new Exynos chips (like Exynos9810) may benefit from this feature as well. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Sam Protsenko Link: https://lore.kernel.org/r/20210811114827.27322-5-semen.protsenko@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/samsung_tty.c | 32 +++++++++++++++++++++++++++++++- include/linux/serial_s3c.h | 9 +++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c index 0cf4dfe77c32..857afcd5fe2d 100644 --- a/drivers/tty/serial/samsung_tty.c +++ b/drivers/tty/serial/samsung_tty.c @@ -65,6 +65,7 @@ enum s3c24xx_port_type { struct s3c24xx_uart_info { char *name; enum s3c24xx_port_type type; + unsigned int has_usi; unsigned int port_type; unsigned int fifosize; unsigned long rx_fifomask; @@ -1356,6 +1357,28 @@ static int apple_s5l_serial_startup(struct uart_port *port) return ret; } +static void exynos_usi_init(struct uart_port *port) +{ + struct s3c24xx_uart_port *ourport = to_ourport(port); + struct s3c24xx_uart_info *info = ourport->info; + unsigned int val; + + if (!info->has_usi) + return; + + /* Clear the software reset of USI block (it's set at startup) */ + val = rd_regl(port, USI_CON); + val &= ~USI_CON_RESET_MASK; + wr_regl(port, USI_CON, val); + udelay(1); + + /* Continuously provide the clock to USI IP w/o gating (for Rx mode) */ + val = rd_regl(port, USI_OPTION); + val &= ~USI_OPTION_HWACG_MASK; + val |= USI_OPTION_HWACG_CLKREQ_ON; + wr_regl(port, USI_OPTION, val); +} + /* power power management control */ static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level, @@ -1383,6 +1406,7 @@ static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level, if (!IS_ERR(ourport->baudclk)) clk_prepare_enable(ourport->baudclk); + exynos_usi_init(port); break; default: dev_err(port->dev, "s3c24xx_serial: unknown pm %d\n", level); @@ -2106,6 +2130,8 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, if (ret) pr_warn("uart: failed to enable baudclk\n"); + exynos_usi_init(port); + /* Keep all interrupts masked and cleared */ switch (ourport->info->type) { case TYPE_S3C6400: @@ -2754,10 +2780,11 @@ static struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = { #endif #if defined(CONFIG_ARCH_EXYNOS) -#define EXYNOS_COMMON_SERIAL_DRV_DATA \ +#define EXYNOS_COMMON_SERIAL_DRV_DATA_USI(_has_usi) \ .info = &(struct s3c24xx_uart_info) { \ .name = "Samsung Exynos UART", \ .type = TYPE_S3C6400, \ + .has_usi = _has_usi, \ .port_type = PORT_S3C6400, \ .has_divslot = 1, \ .rx_fifomask = S5PV210_UFSTAT_RXMASK, \ @@ -2777,6 +2804,9 @@ static struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = { .has_fracval = 1, \ } \ +#define EXYNOS_COMMON_SERIAL_DRV_DATA \ + EXYNOS_COMMON_SERIAL_DRV_DATA_USI(0) + static struct s3c24xx_serial_drv_data exynos4210_serial_drv_data = { EXYNOS_COMMON_SERIAL_DRV_DATA, .fifosize = { 256, 64, 16, 16 }, diff --git a/include/linux/serial_s3c.h b/include/linux/serial_s3c.h index f6c3323fc4c5..cf0de4a86640 100644 --- a/include/linux/serial_s3c.h +++ b/include/linux/serial_s3c.h @@ -27,6 +27,15 @@ #define S3C2410_UERSTAT (0x14) #define S3C2410_UFSTAT (0x18) #define S3C2410_UMSTAT (0x1C) +#define USI_CON (0xC4) +#define USI_OPTION (0xC8) + +#define USI_CON_RESET (1<<0) +#define USI_CON_RESET_MASK (1<<0) + +#define USI_OPTION_HWACG_CLKREQ_ON (1<<1) +#define USI_OPTION_HWACG_CLKSTOP_ON (1<<2) +#define USI_OPTION_HWACG_MASK (3<<1) #define S3C2410_LCON_CFGMASK ((0xF<<3)|(0x3)) -- cgit v1.2.3-58-ga151 From f63299b3972d07c3c436fc13949d05d8dcf5e41c Mon Sep 17 00:00:00 2001 From: Sam Protsenko Date: Wed, 11 Aug 2021 14:48:25 +0300 Subject: tty: serial: samsung: Fix driver data macros style Make checkpatch happy by fixing this error: ERROR: Macros with complex values should be enclosed in parentheses Although this change is made to keep macros consistent with consequent patches (adding driver data for new SoC), it's intentionally added as a separate patch to ease possible porting efforts in future. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Sam Protsenko Link: https://lore.kernel.org/r/20210811114827.27322-6-semen.protsenko@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/samsung_tty.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c index 857afcd5fe2d..c3ab2ff91862 100644 --- a/drivers/tty/serial/samsung_tty.c +++ b/drivers/tty/serial/samsung_tty.c @@ -2820,8 +2820,8 @@ static struct s3c24xx_serial_drv_data exynos5433_serial_drv_data = { #define EXYNOS4210_SERIAL_DRV_DATA ((kernel_ulong_t)&exynos4210_serial_drv_data) #define EXYNOS5433_SERIAL_DRV_DATA ((kernel_ulong_t)&exynos5433_serial_drv_data) #else -#define EXYNOS4210_SERIAL_DRV_DATA (kernel_ulong_t)NULL -#define EXYNOS5433_SERIAL_DRV_DATA (kernel_ulong_t)NULL +#define EXYNOS4210_SERIAL_DRV_DATA ((kernel_ulong_t)NULL) +#define EXYNOS5433_SERIAL_DRV_DATA ((kernel_ulong_t)NULL) #endif #ifdef CONFIG_ARCH_APPLE -- cgit v1.2.3-58-ga151 From 9a4d22f7955ee365f7829859f599a01b3ffd850b Mon Sep 17 00:00:00 2001 From: Sam Protsenko Date: Wed, 11 Aug 2021 14:48:26 +0300 Subject: tty: serial: samsung: Add Exynos850 SoC data Add serial driver data for Exynos850 SoC. This driver data is basically reusing EXYNOS_COMMON_SERIAL_DRV_DATA, which is common for all Exynos chips, but also enables USI init, which was added in previous commit: "tty: serial: samsung: Init USI to keep clocks running". Reviewed-by: Krzysztof Kozlowski Signed-off-by: Sam Protsenko Link: https://lore.kernel.org/r/20210811114827.27322-7-semen.protsenko@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/samsung_tty.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c index c3ab2ff91862..e2f49863e9c2 100644 --- a/drivers/tty/serial/samsung_tty.c +++ b/drivers/tty/serial/samsung_tty.c @@ -2817,11 +2817,19 @@ static struct s3c24xx_serial_drv_data exynos5433_serial_drv_data = { .fifosize = { 64, 256, 16, 256 }, }; +static struct s3c24xx_serial_drv_data exynos850_serial_drv_data = { + EXYNOS_COMMON_SERIAL_DRV_DATA_USI(1), + .fifosize = { 256, 64, 64, 64 }, +}; + #define EXYNOS4210_SERIAL_DRV_DATA ((kernel_ulong_t)&exynos4210_serial_drv_data) #define EXYNOS5433_SERIAL_DRV_DATA ((kernel_ulong_t)&exynos5433_serial_drv_data) +#define EXYNOS850_SERIAL_DRV_DATA ((kernel_ulong_t)&exynos850_serial_drv_data) + #else #define EXYNOS4210_SERIAL_DRV_DATA ((kernel_ulong_t)NULL) #define EXYNOS5433_SERIAL_DRV_DATA ((kernel_ulong_t)NULL) +#define EXYNOS850_SERIAL_DRV_DATA ((kernel_ulong_t)NULL) #endif #ifdef CONFIG_ARCH_APPLE @@ -2877,6 +2885,9 @@ static const struct platform_device_id s3c24xx_serial_driver_ids[] = { }, { .name = "s5l-uart", .driver_data = S5L_SERIAL_DRV_DATA, + }, { + .name = "exynos850-uart", + .driver_data = EXYNOS850_SERIAL_DRV_DATA, }, { }, }; @@ -2900,6 +2911,8 @@ static const struct of_device_id s3c24xx_uart_dt_match[] = { .data = (void *)EXYNOS5433_SERIAL_DRV_DATA }, { .compatible = "apple,s5l-uart", .data = (void *)S5L_SERIAL_DRV_DATA }, + { .compatible = "samsung,exynos850-uart", + .data = (void *)EXYNOS850_SERIAL_DRV_DATA }, {}, }; MODULE_DEVICE_TABLE(of, s3c24xx_uart_dt_match); -- cgit v1.2.3-58-ga151 From 94560f6156fed8ddb0dfc93620382fadf02d90d0 Mon Sep 17 00:00:00 2001 From: Qian Cai Date: Fri, 13 Aug 2021 12:31:35 -0400 Subject: Revert "arm pl011 serial: support multi-irq request" This reverts commit b0819465be8be0c76af15436a9e6db4dab4c196e which results in amba_device-specific code being called from sbsa_uart_startup() and sbsa_uart_shutdown(). Signed-off-by: Qian Cai Link: https://lore.kernel.org/r/20210813163135.205-1-quic_qiancai@quicinc.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl011.c | 34 +++------------------------------- 1 file changed, 3 insertions(+), 31 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index cf6ff229e267..d361cd84ff8c 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -1777,39 +1777,11 @@ static void pl011_write_lcr_h(struct uart_amba_port *uap, unsigned int lcr_h) } } -static void pl011_release_irq(struct uart_amba_port *uap, unsigned int max_cnt) -{ - struct amba_device *amba_dev = container_of(uap->port.dev, struct amba_device, dev); - int i; - - for (i = 0; i < max_cnt; i++) - if (amba_dev->irq[i]) - free_irq(amba_dev->irq[i], uap); -} - static int pl011_allocate_irq(struct uart_amba_port *uap) { - int ret = 0; - int i; - unsigned int virq; - struct amba_device *amba_dev = container_of(uap->port.dev, struct amba_device, dev); - pl011_write(uap->im, uap, REG_IMSC); - for (i = 0; i < AMBA_NR_IRQS; i++) { - virq = amba_dev->irq[i]; - if (virq == 0) - break; - - ret = request_irq(virq, pl011_int, IRQF_SHARED, dev_name(&amba_dev->dev), uap); - if (ret) { - dev_err(uap->port.dev, "request %u interrupt failed\n", virq); - pl011_release_irq(uap, i - 1); - break; - } - } - - return ret; + return request_irq(uap->port.irq, pl011_int, IRQF_SHARED, "uart-pl011", uap); } /* @@ -1981,7 +1953,7 @@ static void pl011_shutdown(struct uart_port *port) if ((port->rs485.flags & SER_RS485_ENABLED) && uap->rs485_tx_started) pl011_rs485_tx_stop(uap); - pl011_release_irq(uap, AMBA_NR_IRQS); + free_irq(uap->port.irq, uap); pl011_disable_uart(uap); @@ -2011,7 +1983,7 @@ static void sbsa_uart_shutdown(struct uart_port *port) pl011_disable_interrupts(uap); - pl011_release_irq(uap, AMBA_NR_IRQS); + free_irq(uap->port.irq, uap); if (uap->port.ops->flush_buffer) uap->port.ops->flush_buffer(port); -- cgit v1.2.3-58-ga151 From 59bd4eedf118a0404631038ece6f6a436b98c256 Mon Sep 17 00:00:00 2001 From: Tang Bin Date: Sat, 14 Aug 2021 20:49:51 +0800 Subject: serial: stm32: use the defined variable to simplify code Use the defined variable 'dev' to make the code cleaner. Signed-off-by: Zhang Shengju Signed-off-by: Tang Bin Link: https://lore.kernel.org/r/20210814124951.30084-1-tangbin@cmss.chinamobile.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/stm32-usart.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c index 090822cd1604..99f9038dda5d 100644 --- a/drivers/tty/serial/stm32-usart.c +++ b/drivers/tty/serial/stm32-usart.c @@ -1177,7 +1177,7 @@ static int stm32_usart_of_dma_rx_probe(struct stm32_port *stm32port, if (uart_console(port)) return -ENODEV; - stm32port->rx_buf = dma_alloc_coherent(&pdev->dev, RX_BUF_L, + stm32port->rx_buf = dma_alloc_coherent(dev, RX_BUF_L, &stm32port->rx_dma_buf, GFP_KERNEL); if (!stm32port->rx_buf) @@ -1243,7 +1243,7 @@ static int stm32_usart_of_dma_tx_probe(struct stm32_port *stm32port, stm32port->tx_dma_busy = false; - stm32port->tx_buf = dma_alloc_coherent(&pdev->dev, TX_BUF_L, + stm32port->tx_buf = dma_alloc_coherent(dev, TX_BUF_L, &stm32port->tx_dma_buf, GFP_KERNEL); if (!stm32port->tx_buf) -- cgit v1.2.3-58-ga151 From 3d881e32e295decbc86f5d920bedae929be5bfb0 Mon Sep 17 00:00:00 2001 From: Tang Bin Date: Sat, 14 Aug 2021 21:14:18 +0800 Subject: serial: stm32: use devm_platform_get_and_ioremap_resource() Use devm_platform_get_and_ioremap_resource() to simplify code. Signed-off-by: Zhang Shengju Signed-off-by: Tang Bin Link: https://lore.kernel.org/r/20210814131418.13608-1-tangbin@cmss.chinamobile.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/stm32-usart.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c index 99f9038dda5d..8f032e77b954 100644 --- a/drivers/tty/serial/stm32-usart.c +++ b/drivers/tty/serial/stm32-usart.c @@ -1064,8 +1064,7 @@ static int stm32_usart_init_port(struct stm32_port *stm32port, &stm32port->txftcfg); } - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - port->membase = devm_ioremap_resource(&pdev->dev, res); + port->membase = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(port->membase)) return PTR_ERR(port->membase); port->mapbase = res->start; -- cgit v1.2.3-58-ga151 From 87b8061bad9bd4b549b2daf36ffbaa57be2789a2 Mon Sep 17 00:00:00 2001 From: Ulrich Hecht Date: Mon, 16 Aug 2021 18:22:01 +0200 Subject: serial: sh-sci: fix break handling for sysrq This fixes two issues that cause the sysrq sequence to be inadvertently aborted on SCIF serial consoles: - a NUL character remains in the RX queue after a break has been detected, which is then passed on to uart_handle_sysrq_char() - the break interrupt is handled twice on controllers with multiplexed ERI and BRI interrupts Signed-off-by: Ulrich Hecht Link: https://lore.kernel.org/r/20210816162201.28801-1-uli+renesas@fpond.eu Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 07eb56294371..89ee43061d3a 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1758,6 +1758,10 @@ static irqreturn_t sci_br_interrupt(int irq, void *ptr) /* Handle BREAKs */ sci_handle_breaks(port); + + /* drop invalid character received before break was detected */ + serial_port_in(port, SCxRDR); + sci_clear_SCxSR(port, SCxSR_BREAK_CLEAR(port)); return IRQ_HANDLED; @@ -1837,7 +1841,8 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) ret = sci_er_interrupt(irq, ptr); /* Break Interrupt */ - if ((ssr_status & SCxSR_BRK(port)) && err_enabled) + if (s->irqs[SCIx_ERI_IRQ] != s->irqs[SCIx_BRI_IRQ] && + (ssr_status & SCxSR_BRK(port)) && err_enabled) ret = sci_br_interrupt(irq, ptr); /* Overrun Interrupt */ -- cgit v1.2.3-58-ga151 From 1143637f00cd8205c43bad702b2aff57c01913f8 Mon Sep 17 00:00:00 2001 From: Changbin Du Date: Sat, 14 Aug 2021 08:50:33 +0800 Subject: tty: replace in_irq() with in_hardirq() Replace the obsolete and ambiguos macro in_irq() with new macro in_hardirq(). Reviewed-by: Jiri Slaby Signed-off-by: Changbin Du Link: https://lore.kernel.org/r/20210814005033.2381-1-changbin.du@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/sysrq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index 6628792431dc..c911196ac893 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c @@ -258,7 +258,7 @@ static void sysrq_handle_showallcpus(int key) if (!trigger_all_cpu_backtrace()) { struct pt_regs *regs = NULL; - if (in_irq()) + if (in_hardirq()) regs = get_irq_regs(); if (regs) { pr_info("CPU%d:\n", smp_processor_id()); @@ -280,7 +280,7 @@ static void sysrq_handle_showregs(int key) { struct pt_regs *regs = NULL; - if (in_irq()) + if (in_hardirq()) regs = get_irq_regs(); if (regs) show_regs(regs); -- cgit v1.2.3-58-ga151 From 88c1d2478ec8a420cf60a3c25503e37b34fea5aa Mon Sep 17 00:00:00 2001 From: Fugang Duan Date: Tue, 17 Aug 2021 18:02:03 +0800 Subject: tty: serial: fsl_lpuart: check dma_tx_in_progress in tx dma callback There have a corner case that tx DMA .callback() is coming after .flush_buffer(), then .callback() should check dma_tx_in_progress flag and return in directly. Signed-off-by: Fugang Duan Signed-off-by: Vipul Kumar Signed-off-by: Sherry Sun Link: https://lore.kernel.org/r/20210817100203.21300-1-sherry.sun@nxp.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/fsl_lpuart.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index f0e5da77ed6d..31d715c4787a 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -479,6 +479,10 @@ static void lpuart_dma_tx_complete(void *arg) unsigned long flags; spin_lock_irqsave(&sport->port.lock, flags); + if (!sport->dma_tx_in_progress) { + spin_unlock_irqrestore(&sport->port.lock, flags); + return; + } dma_unmap_sg(chan->device->dev, sgl, sport->dma_tx_nents, DMA_TO_DEVICE); -- cgit v1.2.3-58-ga151 From 322003b907d6c74d16154091bca492a2b2829ac0 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 25 Aug 2021 10:24:05 +0300 Subject: tty: moxa: use semi-colons instead of commas This code works but it's cleaner to use a semi-colon to end a statement instead of a comma. Acked-by: Jiri Slaby Signed-off-by: Dan Carpenter Link: https://lore.kernel.org/r/20210825072405.GA13013@kili Signed-off-by: Greg Kroah-Hartman --- drivers/tty/moxa.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/moxa.c b/drivers/tty/moxa.c index 776f78de0f82..bf17e90858b8 100644 --- a/drivers/tty/moxa.c +++ b/drivers/tty/moxa.c @@ -2034,10 +2034,10 @@ static int moxa_get_serial_info(struct tty_struct *tty, if (!info) return -ENODEV; mutex_lock(&info->port.mutex); - ss->type = info->type, - ss->line = info->port.tty->index, - ss->flags = info->port.flags, - ss->baud_base = 921600, + ss->type = info->type; + ss->line = info->port.tty->index; + ss->flags = info->port.flags; + ss->baud_base = 921600; ss->close_delay = jiffies_to_msecs(info->port.close_delay) / 10; mutex_unlock(&info->port.mutex); return 0; -- cgit v1.2.3-58-ga151 From 2285c496392979c9ac9d84e19a313ee9212d9b62 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 25 Aug 2021 10:24:35 +0300 Subject: mxser: use semi-colons instead of commas This code works, but it's cleaner to use semi-colons at the end of a statement instead of a comma. Acked-by: Jiri Slaby Signed-off-by: Dan Carpenter Link: https://lore.kernel.org/r/20210825072435.GB13013@kili Signed-off-by: Greg Kroah-Hartman --- drivers/tty/mxser.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 335e4e50d679..1216f3985e18 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -1039,12 +1039,12 @@ static int mxser_get_serial_info(struct tty_struct *tty, if (closing_wait != ASYNC_CLOSING_WAIT_NONE) closing_wait = jiffies_to_msecs(closing_wait) / 10; - ss->type = info->type, - ss->line = tty->index, - ss->port = info->ioaddr, - ss->irq = info->board->irq, - ss->flags = info->port.flags, - ss->baud_base = MXSER_BAUD_BASE, + ss->type = info->type; + ss->line = tty->index; + ss->port = info->ioaddr; + ss->irq = info->board->irq; + ss->flags = info->port.flags; + ss->baud_base = MXSER_BAUD_BASE; ss->close_delay = close_delay; ss->closing_wait = closing_wait; ss->custom_divisor = MXSER_CUSTOM_DIVISOR, -- cgit v1.2.3-58-ga151 From d5c38948448abc2bb6b36dbf85a554bf4748885e Mon Sep 17 00:00:00 2001 From: Andy Duan Date: Thu, 19 Aug 2021 10:10:33 +0800 Subject: tty: serial: fsl_lpuart: fix the wrong mapbase value Register offset needs to be applied on mapbase also. dma_tx/rx_request use the physical address of UARTDATA. Register offset is currently only applied to membase (the corresponding virtual addr) but not on mapbase. Fixes: 24b1e5f0e83c ("tty: serial: lpuart: add imx7ulp support") Reviewed-by: Leonard Crestez Signed-off-by: Adriana Reus Signed-off-by: Sherry Sun Signed-off-by: Andy Duan Link: https://lore.kernel.org/r/20210819021033.32606-1-sherry.sun@nxp.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/fsl_lpuart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 31d715c4787a..117e011aff5f 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -2615,7 +2615,7 @@ static int lpuart_probe(struct platform_device *pdev) return PTR_ERR(sport->port.membase); sport->port.membase += sdata->reg_off; - sport->port.mapbase = res->start; + sport->port.mapbase = res->start + sdata->reg_off; sport->port.dev = &pdev->dev; sport->port.type = PORT_LPUART; sport->devtype = sdata->devtype; -- cgit v1.2.3-58-ga151 From 48422152a8f1c290f74d8fb16ec6c77a1263834c Mon Sep 17 00:00:00 2001 From: Fugang Duan Date: Mon, 23 Aug 2021 16:17:33 +0800 Subject: tty: serial: fsl_lpuart: enable two stop bits for lpuart32 Add two stop bits support. User can run the command to enable two stop bits for test: stty cstopb -F /dev/ttyLPx Signed-off-by: Fugang Duan Signed-off-by: Sherry Sun Link: https://lore.kernel.org/r/20210823081733.31941-1-sherry.sun@nxp.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/fsl_lpuart.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 117e011aff5f..55097e068908 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -2049,11 +2049,12 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios, { struct lpuart_port *sport = container_of(port, struct lpuart_port, port); unsigned long flags; - unsigned long ctrl, old_ctrl, modem; + unsigned long ctrl, old_ctrl, bd, modem; unsigned int baud; unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8; ctrl = old_ctrl = lpuart32_read(&sport->port, UARTCTRL); + bd = lpuart32_read(&sport->port, UARTBAUD); modem = lpuart32_read(&sport->port, UARTMODIR); /* * only support CS8 and CS7, and for CS7 must enable PE. @@ -2097,7 +2098,9 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios, } if (termios->c_cflag & CSTOPB) - termios->c_cflag &= ~CSTOPB; + bd |= UARTBAUD_SBNS; + else + bd &= ~UARTBAUD_SBNS; /* parity must be enabled when CS7 to match 8-bits format */ if ((termios->c_cflag & CSIZE) == CS7) @@ -2167,6 +2170,7 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios, lpuart32_write(&sport->port, old_ctrl & ~(UARTCTRL_TE | UARTCTRL_RE), UARTCTRL); + lpuart32_write(&sport->port, bd, UARTBAUD); lpuart32_serial_setbrg(sport, baud); lpuart32_write(&sport->port, modem, UARTMODIR); lpuart32_write(&sport->port, ctrl, UARTCTRL); -- cgit v1.2.3-58-ga151 From bd5305dcabbc208560521bc0617f0a82715e41c9 Mon Sep 17 00:00:00 2001 From: Fugang Duan Date: Mon, 23 Aug 2021 17:18:01 +0800 Subject: tty: serial: fsl_lpuart: do software reset for imx7ulp and imx8qxp Do software reset for communication port on imx7ulp and imx8qxp after the port is registered if the UART controller support the feature. Do partition reset with LPUART's power on, LPUART registers will keep the previous status, like on i.MX8QXP platform, which is not expected action, so need to set the RST bit of GLOBAL register to reset all uart internal logic and registers. Currently, only i.MX7ULP and i.MX8QXP LPUART controllers include global register that support the software reset. Signed-off-by: Fugang Duan Signed-off-by: Sherry Sun Link: https://lore.kernel.org/r/20210823091801.17447-1-sherry.sun@nxp.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/fsl_lpuart.c | 48 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 55097e068908..b1e7190ae483 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -109,6 +110,11 @@ #define UARTSFIFO_TXOF 0x02 #define UARTSFIFO_RXUF 0x01 +/* 32-bit global registers only for i.MX7ULP/i.MX8x + * Used to reset all internal logic and registers, except the Global Register. + */ +#define UART_GLOBAL 0x8 + /* 32-bit register definition */ #define UARTBAUD 0x00 #define UARTSTAT 0x04 @@ -219,6 +225,10 @@ #define UARTWATER_TXWATER_OFF 0 #define UARTWATER_RXWATER_OFF 16 +#define UART_GLOBAL_RST 0x2 +#define GLOBAL_RST_MIN_US 20 +#define GLOBAL_RST_MAX_US 40 + /* Rx DMA timeout in ms, which is used to calculate Rx ring buffer size */ #define DMA_RX_TIMEOUT (10) @@ -320,6 +330,11 @@ static inline bool is_layerscape_lpuart(struct lpuart_port *sport) sport->devtype == LS1028A_LPUART); } +static inline bool is_imx7ulp_lpuart(struct lpuart_port *sport) +{ + return sport->devtype == IMX7ULP_LPUART; +} + static inline bool is_imx8qxp_lpuart(struct lpuart_port *sport) { return sport->devtype == IMX8QXP_LPUART; @@ -383,6 +398,33 @@ static unsigned int lpuart_get_baud_clk_rate(struct lpuart_port *sport) #define lpuart_enable_clks(x) __lpuart_enable_clks(x, true) #define lpuart_disable_clks(x) __lpuart_enable_clks(x, false) +static int lpuart_global_reset(struct lpuart_port *sport) +{ + struct uart_port *port = &sport->port; + void __iomem *global_addr; + int ret; + + if (uart_console(port)) + return 0; + + ret = clk_prepare_enable(sport->ipg_clk); + if (ret) { + dev_err(sport->port.dev, "failed to enable uart ipg clk: %d\n", ret); + return ret; + } + + if (is_imx7ulp_lpuart(sport) || is_imx8qxp_lpuart(sport)) { + global_addr = port->membase + UART_GLOBAL - IMX_REG_OFF; + writel(UART_GLOBAL_RST, global_addr); + usleep_range(GLOBAL_RST_MIN_US, GLOBAL_RST_MAX_US); + writel(0, global_addr); + usleep_range(GLOBAL_RST_MIN_US, GLOBAL_RST_MAX_US); + } + + clk_disable_unprepare(sport->ipg_clk); + return 0; +} + static void lpuart_stop_tx(struct uart_port *port) { unsigned char temp; @@ -2699,6 +2741,10 @@ static int lpuart_probe(struct platform_device *pdev) if (ret) goto failed_attach_port; + ret = lpuart_global_reset(sport); + if (ret) + goto failed_reset; + ret = uart_get_rs485_mode(&sport->port); if (ret) goto failed_get_rs485; @@ -2715,6 +2761,8 @@ static int lpuart_probe(struct platform_device *pdev) return 0; failed_get_rs485: +failed_reset: + uart_remove_one_port(&lpuart_reg, &sport->port); failed_attach_port: failed_irq_request: lpuart_disable_clks(sport); -- cgit v1.2.3-58-ga151 From fa934fc1a8679f0704dddaefb6946c3da26c58a5 Mon Sep 17 00:00:00 2001 From: Tang Bin Date: Mon, 23 Aug 2021 19:07:54 +0800 Subject: tty: serial: linflexuart: Remove redundant check to simplify the code In the function uart_add_one_port(), it can return zero or non-zero, so remove redundant check to simplify the code. Signed-off-by: Zhang Shengju Signed-off-by: Tang Bin Link: https://lore.kernel.org/r/20210823110754.11232-1-tangbin@cmss.chinamobile.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/fsl_linflexuart.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/fsl_linflexuart.c b/drivers/tty/serial/fsl_linflexuart.c index d87048073abe..283757264608 100644 --- a/drivers/tty/serial/fsl_linflexuart.c +++ b/drivers/tty/serial/fsl_linflexuart.c @@ -861,11 +861,7 @@ static int linflex_probe(struct platform_device *pdev) platform_set_drvdata(pdev, sport); - ret = uart_add_one_port(&linflex_reg, sport); - if (ret) - return ret; - - return 0; + return uart_add_one_port(&linflex_reg, sport); } static int linflex_remove(struct platform_device *pdev) -- cgit v1.2.3-58-ga151 From 618bf2b04bd6a903a9ebf0edb8d1700ba9a1a6da Mon Sep 17 00:00:00 2001 From: Tang Bin Date: Sun, 22 Aug 2021 11:28:04 +0800 Subject: serial: 8250_ingenic: Use of_device_get_match_data Retrieve OF match data, it's better and cleaner to use 'of_device_get_match_data' over 'of_match_device'. Acked-by: Paul Cercueil Signed-off-by: Zhang Shengju Signed-off-by: Tang Bin Link: https://lore.kernel.org/r/20210822032806.3256-2-tangbin@cmss.chinamobile.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_ingenic.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/8250/8250_ingenic.c b/drivers/tty/serial/8250/8250_ingenic.c index 988bf6bcce42..65402d05eff9 100644 --- a/drivers/tty/serial/8250/8250_ingenic.c +++ b/drivers/tty/serial/8250/8250_ingenic.c @@ -209,16 +209,14 @@ static int ingenic_uart_probe(struct platform_device *pdev) struct uart_8250_port uart = {}; struct ingenic_uart_data *data; const struct ingenic_uart_config *cdata; - const struct of_device_id *match; struct resource *regs; int irq, err, line; - match = of_match_device(of_match, &pdev->dev); - if (!match) { + cdata = of_device_get_match_data(&pdev->dev); + if (!cdata) { dev_err(&pdev->dev, "Error: No device match found\n"); return -ENODEV; } - cdata = match->data; irq = platform_get_irq(pdev, 0); if (irq < 0) -- cgit v1.2.3-58-ga151 From a6a65f9ee0937d02e8084ee1ed305e38aae848e6 Mon Sep 17 00:00:00 2001 From: Tang Bin Date: Sun, 22 Aug 2021 11:28:05 +0800 Subject: serial: tegra: Use of_device_get_match_data Retrieve OF match data, it's better and cleaner to use 'of_device_get_match_data' over 'of_match_device'. Signed-off-by: Zhang Shengju Signed-off-by: Tang Bin Link: https://lore.kernel.org/r/20210822032806.3256-3-tangbin@cmss.chinamobile.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/serial-tegra.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c index eba5b9ecba34..45e2e4109acd 100644 --- a/drivers/tty/serial/serial-tegra.c +++ b/drivers/tty/serial/serial-tegra.c @@ -1568,14 +1568,12 @@ static int tegra_uart_probe(struct platform_device *pdev) struct resource *resource; int ret; const struct tegra_uart_chip_data *cdata; - const struct of_device_id *match; - match = of_match_device(tegra_uart_of_match, &pdev->dev); - if (!match) { + cdata = of_device_get_match_data(&pdev->dev); + if (!cdata) { dev_err(&pdev->dev, "Error: No device match found\n"); return -ENODEV; } - cdata = match->data; tup = devm_kzalloc(&pdev->dev, sizeof(*tup), GFP_KERNEL); if (!tup) { -- cgit v1.2.3-58-ga151 From 74d2fb7e708433b7397d9647ea7ec1cbcb0ae379 Mon Sep 17 00:00:00 2001 From: Tang Bin Date: Sun, 22 Aug 2021 11:28:06 +0800 Subject: serial: vt8500: Use of_device_get_match_data Retrieve OF match data, it's better and cleaner to use 'of_device_get_match_data' over 'of_match_device'. Signed-off-by: Zhang Shengju Signed-off-by: Tang Bin Link: https://lore.kernel.org/r/20210822032806.3256-4-tangbin@cmss.chinamobile.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/vt8500_serial.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/vt8500_serial.c b/drivers/tty/serial/vt8500_serial.c index c5edd56ff830..e15b2bf69904 100644 --- a/drivers/tty/serial/vt8500_serial.c +++ b/drivers/tty/serial/vt8500_serial.c @@ -623,17 +623,14 @@ static int vt8500_serial_probe(struct platform_device *pdev) struct vt8500_port *vt8500_port; struct resource *mmres, *irqres; struct device_node *np = pdev->dev.of_node; - const struct of_device_id *match; const unsigned int *flags; int ret; int port; - match = of_match_device(wmt_dt_ids, &pdev->dev); - if (!match) + flags = of_device_get_match_data(&pdev->dev); + if (!flags) return -EINVAL; - flags = match->data; - mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0); irqres = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!mmres || !irqres) -- cgit v1.2.3-58-ga151 From bb2853a6a421a052268eee00fd5d3f6b3504b2b1 Mon Sep 17 00:00:00 2001 From: Nguyen Dinh Phi Date: Mon, 23 Aug 2021 08:06:41 +0800 Subject: tty: Fix data race between tiocsti() and flush_to_ldisc() The ops->receive_buf() may be accessed concurrently from these two functions. If the driver flushes data to the line discipline receive_buf() method while tiocsti() is waiting for the ops->receive_buf() to finish its work, the data race will happen. For example: tty_ioctl |tty_ldisc_receive_buf ->tioctsi | ->tty_port_default_receive_buf | ->tty_ldisc_receive_buf ->hci_uart_tty_receive | ->hci_uart_tty_receive ->h4_recv | ->h4_recv In this case, the h4 receive buffer will be overwritten by the latecomer, and we will lost the data. Hence, change tioctsi() function to use the exclusive lock interface from tty_buffer to avoid the data race. Reported-by: syzbot+97388eb9d31b997fe1d0@syzkaller.appspotmail.com Reviewed-by: Jiri Slaby Signed-off-by: Nguyen Dinh Phi Link: https://lore.kernel.org/r/20210823000641.2082292-1-phind.uet@gmail.com Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index e8532006e960..6616d4a0d41d 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -2290,8 +2290,6 @@ static int tty_fasync(int fd, struct file *filp, int on) * Locking: * Called functions take tty_ldiscs_lock * current->signal->tty check is safe without locks - * - * FIXME: may race normal receive processing */ static int tiocsti(struct tty_struct *tty, char __user *p) @@ -2307,8 +2305,10 @@ static int tiocsti(struct tty_struct *tty, char __user *p) ld = tty_ldisc_ref_wait(tty); if (!ld) return -EIO; + tty_buffer_lock_exclusive(tty->port); if (ld->ops->receive_buf) ld->ops->receive_buf(tty, &ch, &mbz, 1); + tty_buffer_unlock_exclusive(tty->port); tty_ldisc_deref(ld); return 0; } -- cgit v1.2.3-58-ga151 From 3620a89b7d27138c716e5cf537a0bf6606a3a1b3 Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Thu, 26 Aug 2021 15:43:23 -0400 Subject: tty: serial: uartlite: Use constants in early_uartlite_putc Use the constants defined at the beginning of this file instead of integer literals when accessing registers. This makes this code easier to read, and obviates the need for some explanatory comments. Signed-off-by: Sean Anderson Link: https://lore.kernel.org/r/20210826194323.3209227-1-sean.anderson@seco.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/uartlite.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/uartlite.c b/drivers/tty/serial/uartlite.c index 047099b14cee..a1b9264498e2 100644 --- a/drivers/tty/serial/uartlite.c +++ b/drivers/tty/serial/uartlite.c @@ -561,16 +561,15 @@ static void early_uartlite_putc(struct uart_port *port, int c) * This limit is pretty arbitrary, unless we are at about 10 baud * we'll never timeout on a working UART. */ - unsigned retries = 1000000; - /* read status bit - 0x8 offset */ - while (--retries && (readl(port->membase + 8) & (1 << 3))) + + while (--retries && + (readl(port->membase + ULITE_STATUS) & ULITE_STATUS_TXFULL)) ; /* Only attempt the iowrite if we didn't timeout */ - /* write to TX_FIFO - 0x4 offset */ if (retries) - writel(c & 0xff, port->membase + 4); + writel(c & 0xff, port->membase + ULITE_TX); } static void early_uartlite_write(struct console *console, -- cgit v1.2.3-58-ga151 From 2e5f3a69b6fcd52a64ce3d746c6ee8390b6cabe8 Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Thu, 26 Aug 2021 15:25:49 -0400 Subject: tty: serial: uartlite: Use read_poll_timeout for a polling loop read_poll_timeout was recently introduced, and can be used to simplify our console polling loop. This results in a slight reduction in code. early_uartlite_putc can't get the same treatment, because it can be called before udelay is set up. Signed-off-by: Sean Anderson Link: https://lore.kernel.org/r/20210826192549.3203071-1-sean.anderson@seco.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/uartlite.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/uartlite.c b/drivers/tty/serial/uartlite.c index a1b9264498e2..dfc1ba4e1572 100644 --- a/drivers/tty/serial/uartlite.c +++ b/drivers/tty/serial/uartlite.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -454,24 +455,15 @@ static const struct uart_ops ulite_ops = { static void ulite_console_wait_tx(struct uart_port *port) { u8 val; - unsigned long timeout; /* * Spin waiting for TX fifo to have space available. * When using the Microblaze Debug Module this can take up to 1s */ - timeout = jiffies + msecs_to_jiffies(1000); - while (1) { - val = uart_in32(ULITE_STATUS, port); - if ((val & ULITE_STATUS_TXFULL) == 0) - break; - if (time_after(jiffies, timeout)) { - dev_warn(port->dev, - "timeout waiting for TX buffer empty\n"); - break; - } - cpu_relax(); - } + if (read_poll_timeout_atomic(uart_in32, val, !(val & ULITE_STATUS_TXFULL), + 0, 1000000, false, ULITE_STATUS, port)) + dev_warn(port->dev, + "timeout waiting for TX buffer empty\n"); } static void ulite_console_putchar(struct uart_port *port, int ch) -- cgit v1.2.3-58-ga151