Commit 7531ee31 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'tty-5.8-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty into master

Pull tty/serial driver fixes from Greg KH:
 :Here are some small tty and serial driver fixes for 5.8-rc6.

  The largest set of patches in here is a revert of the sysrq changes
  that went into 5.8-rc1 but turned out to cause a noticable overhead
  and cpu usage.

  Other than that, there's a few small serial driver fixes to resolve
  reported issues, and finally resolving the spinlock init problem on
  many serial driver consoles.

  All of these have been in linux-next for a while with no reported
  issues"

* tag 'tty-5.8-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty:
  serial: core: Initialise spin lock before use in uart_configure_port()
  serial: mxs-auart: add missed iounmap() in probe failure and remove
  serial: sh-sci: Initialize spinlock for uart console
  Revert "tty: xilinx_uartps: Fix missing id assignment to the console"
  serial: core: drop redundant sysrq checks
  serial: core: fix sysrq overhead regression
  Revert "serial: core: Refactor uart_unlock_and_check_sysrq()"
  tty/serial: fix serial_core.c kernel-doc warnings
  tty: serial: cpm_uart: Fix behaviour for non existing GPIOs
parents 7e8d2f6d f743061a
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -1215,7 +1215,12 @@ static int cpm_uart_init_port(struct device_node *np,

		pinfo->gpios[i] = NULL;

		gpiod = devm_gpiod_get_index(dev, NULL, i, GPIOD_ASIS);
		gpiod = devm_gpiod_get_index_optional(dev, NULL, i, GPIOD_ASIS);

		if (IS_ERR(gpiod)) {
			ret = PTR_ERR(gpiod);
			goto out_irq;
		}

		if (gpiod) {
			if (i == GPIO_RTS || i == GPIO_DTR)
@@ -1237,6 +1242,8 @@ static int cpm_uart_init_port(struct device_node *np,

	return cpm_uart_request_port(&pinfo->port);

out_irq:
	irq_dispose_mapping(pinfo->port.irq);
out_pram:
	cpm_uart_unmap_pram(pinfo, pram);
out_mem:
+8 −4
Original line number Diff line number Diff line
@@ -1698,21 +1698,21 @@ static int mxs_auart_probe(struct platform_device *pdev)
	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		ret = irq;
		goto out_disable_clks;
		goto out_iounmap;
	}

	s->port.irq = irq;
	ret = devm_request_irq(&pdev->dev, irq, mxs_auart_irq_handle, 0,
			       dev_name(&pdev->dev), s);
	if (ret)
		goto out_disable_clks;
		goto out_iounmap;

	platform_set_drvdata(pdev, s);

	ret = mxs_auart_init_gpios(s, &pdev->dev);
	if (ret) {
		dev_err(&pdev->dev, "Failed to initialize GPIOs.\n");
		goto out_disable_clks;
		goto out_iounmap;
	}

	/*
@@ -1720,7 +1720,7 @@ static int mxs_auart_probe(struct platform_device *pdev)
	 */
	ret = mxs_auart_request_gpio_irq(s);
	if (ret)
		goto out_disable_clks;
		goto out_iounmap;

	auart_port[s->port.line] = s;

@@ -1746,6 +1746,9 @@ out_free_qpio_irq:
	mxs_auart_free_gpio_irq(s);
	auart_port[pdev->id] = NULL;

out_iounmap:
	iounmap(s->port.membase);

out_disable_clks:
	if (is_asm9260_auart(s)) {
		clk_disable_unprepare(s->clk);
@@ -1761,6 +1764,7 @@ static int mxs_auart_remove(struct platform_device *pdev)
	uart_remove_one_port(&auart_driver, &s->port);
	auart_port[pdev->id] = NULL;
	mxs_auart_free_gpio_irq(s);
	iounmap(s->port.membase);
	if (is_asm9260_auart(s)) {
		clk_disable_unprepare(s->clk);
		clk_disable_unprepare(s->clk_ahb);
+17 −98
Original line number Diff line number Diff line
@@ -41,8 +41,6 @@ static struct lock_class_key port_lock_key;

#define HIGH_BITS_OFFSET	((sizeof(long)-sizeof(int))*8)

#define SYSRQ_TIMEOUT	(HZ * 5)

static void uart_change_speed(struct tty_struct *tty, struct uart_state *state,
					struct ktermios *old_termios);
static void uart_wait_until_sent(struct tty_struct *tty, int timeout);
@@ -1916,6 +1914,12 @@ static inline bool uart_console_enabled(struct uart_port *port)
	return uart_console(port) && (port->cons->flags & CON_ENABLED);
}

static void __uart_port_spin_lock_init(struct uart_port *port)
{
	spin_lock_init(&port->lock);
	lockdep_set_class(&port->lock, &port_lock_key);
}

/*
 * Ensure that the serial console lock is initialised early.
 * If this port is a console, then the spinlock is already initialised.
@@ -1925,8 +1929,7 @@ static inline void uart_port_spin_lock_init(struct uart_port *port)
	if (uart_console(port))
		return;

	spin_lock_init(&port->lock);
	lockdep_set_class(&port->lock, &port_lock_key);
	__uart_port_spin_lock_init(port);
}

#if defined(CONFIG_SERIAL_CORE_CONSOLE) || defined(CONFIG_CONSOLE_POLL)
@@ -2372,6 +2375,13 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state,
		/* Power up port for set_mctrl() */
		uart_change_pm(state, UART_PM_STATE_ON);

		/*
		 * If this driver supports console, and it hasn't been
		 * successfully registered yet, initialise spin lock for it.
		 */
		if (port->cons && !(port->cons->flags & CON_ENABLED))
			__uart_port_spin_lock_init(port);

		/*
		 * Ensure that the modem control lines are de-activated.
		 * keep the DTR setting that is set in uart_set_options()
@@ -3163,7 +3173,7 @@ static DECLARE_WORK(sysrq_enable_work, uart_sysrq_on);
 *	Returns false if @ch is out of enabling sequence and should be
 *	handled some other way, true if @ch was consumed.
 */
static bool uart_try_toggle_sysrq(struct uart_port *port, unsigned int ch)
bool uart_try_toggle_sysrq(struct uart_port *port, unsigned int ch)
{
	int sysrq_toggle_seq_len = strlen(sysrq_toggle_seq);

@@ -3186,99 +3196,9 @@ static bool uart_try_toggle_sysrq(struct uart_port *port, unsigned int ch)
	port->sysrq = 0;
	return true;
}
#else
static inline bool uart_try_toggle_sysrq(struct uart_port *port, unsigned int ch)
{
	return false;
}
EXPORT_SYMBOL_GPL(uart_try_toggle_sysrq);
#endif

int uart_handle_sysrq_char(struct uart_port *port, unsigned int ch)
{
	if (!IS_ENABLED(CONFIG_MAGIC_SYSRQ_SERIAL))
		return 0;

	if (!port->has_sysrq || !port->sysrq)
		return 0;

	if (ch && time_before(jiffies, port->sysrq)) {
		if (sysrq_mask()) {
			handle_sysrq(ch);
			port->sysrq = 0;
			return 1;
		}
		if (uart_try_toggle_sysrq(port, ch))
			return 1;
	}
	port->sysrq = 0;

	return 0;
}
EXPORT_SYMBOL_GPL(uart_handle_sysrq_char);

int uart_prepare_sysrq_char(struct uart_port *port, unsigned int ch)
{
	if (!IS_ENABLED(CONFIG_MAGIC_SYSRQ_SERIAL))
		return 0;

	if (!port->has_sysrq || !port->sysrq)
		return 0;

	if (ch && time_before(jiffies, port->sysrq)) {
		if (sysrq_mask()) {
			port->sysrq_ch = ch;
			port->sysrq = 0;
			return 1;
		}
		if (uart_try_toggle_sysrq(port, ch))
			return 1;
	}
	port->sysrq = 0;

	return 0;
}
EXPORT_SYMBOL_GPL(uart_prepare_sysrq_char);

void uart_unlock_and_check_sysrq(struct uart_port *port, unsigned long flags)
__releases(&port->lock)
{
	if (port->has_sysrq) {
		int sysrq_ch = port->sysrq_ch;

		port->sysrq_ch = 0;
		spin_unlock_irqrestore(&port->lock, flags);
		if (sysrq_ch)
			handle_sysrq(sysrq_ch);
	} else {
		spin_unlock_irqrestore(&port->lock, flags);
	}
}
EXPORT_SYMBOL_GPL(uart_unlock_and_check_sysrq);

/*
 * We do the SysRQ and SAK checking like this...
 */
int uart_handle_break(struct uart_port *port)
{
	struct uart_state *state = port->state;

	if (port->handle_break)
		port->handle_break(port);

	if (port->has_sysrq && uart_console(port)) {
		if (!port->sysrq) {
			port->sysrq = jiffies + SYSRQ_TIMEOUT;
			return 1;
		}
		port->sysrq = 0;
	}

	if (port->flags & UPF_SAK)
		do_SAK(state->port.tty);
	return 0;
}
EXPORT_SYMBOL_GPL(uart_handle_break);

EXPORT_SYMBOL(uart_write_wakeup);
EXPORT_SYMBOL(uart_register_driver);
EXPORT_SYMBOL(uart_unregister_driver);
@@ -3289,8 +3209,7 @@ EXPORT_SYMBOL(uart_remove_one_port);

/**
 * uart_get_rs485_mode() - retrieve rs485 properties for given uart
 * @dev: uart device
 * @rs485conf: output parameter
 * @port: uart device's target port
 *
 * This function implements the device tree binding described in
 * Documentation/devicetree/bindings/serial/rs485.txt.
+3 −0
Original line number Diff line number Diff line
@@ -3301,6 +3301,9 @@ static int sci_probe_single(struct platform_device *dev,
		sciport->port.flags |= UPF_HARD_FLOW;
	}

	if (sci_uart_driver.cons->index == sciport->port.line)
		spin_lock_init(&sciport->port.lock);

	ret = uart_add_one_port(&sci_uart_driver, &sciport->port);
	if (ret) {
		sci_cleanup_single(sciport);
+0 −1
Original line number Diff line number Diff line
@@ -1465,7 +1465,6 @@ static int cdns_uart_probe(struct platform_device *pdev)
		cdns_uart_uart_driver.nr = CDNS_UART_NR_PORTS;
#ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
		cdns_uart_uart_driver.cons = &cdns_uart_console;
		cdns_uart_console.index = id;
#endif

		rc = uart_register_driver(&cdns_uart_uart_driver);
Loading