diff options
| author | Mark Brown <broonie@kernel.org> | 2020-08-25 11:01:46 +0100 | 
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2020-08-25 11:01:46 +0100 | 
| commit | 3bec5b6aae830355e786e204b20a7cea38c3a8ed (patch) | |
| tree | fd597b87faf55ceb2a207ee94f4feca6276696db /include/linux/serial_core.h | |
| parent | a577f3456c0a2fac3dee037c483753e6e68f3e49 (diff) | |
| parent | d012a7190fc1fd72ed48911e77ca97ba4521bccd (diff) | |
Merge tag 'v5.9-rc2' into regulator-5.9
Linux 5.9-rc2
Diffstat (limited to 'include/linux/serial_core.h')
| -rw-r--r-- | include/linux/serial_core.h | 104 | 
1 files changed, 99 insertions, 5 deletions
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 9fd550e7946a..01fc4d9c9c54 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -10,7 +10,6 @@  #include <linux/bitops.h>  #include <linux/compiler.h>  #include <linux/console.h> -#include <linux/gpio/consumer.h>  #include <linux/interrupt.h>  #include <linux/circ_buf.h>  #include <linux/spinlock.h> @@ -30,6 +29,7 @@  struct uart_port;  struct serial_struct;  struct device; +struct gpio_desc;  /*   * This structure describes all the operations that can be done on the @@ -462,10 +462,104 @@ extern void uart_handle_cts_change(struct uart_port *uport,  extern void uart_insert_char(struct uart_port *port, unsigned int status,  		 unsigned int overrun, unsigned int ch, unsigned int flag); -extern int uart_handle_sysrq_char(struct uart_port *port, unsigned int ch); -extern int uart_prepare_sysrq_char(struct uart_port *port, unsigned int ch); -extern void uart_unlock_and_check_sysrq(struct uart_port *port, unsigned long flags); -extern int uart_handle_break(struct uart_port *port); +#ifdef CONFIG_MAGIC_SYSRQ_SERIAL +#define SYSRQ_TIMEOUT	(HZ * 5) + +bool uart_try_toggle_sysrq(struct uart_port *port, unsigned int ch); + +static inline int uart_handle_sysrq_char(struct uart_port *port, unsigned int ch) +{ +	if (!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; +} + +static inline int uart_prepare_sysrq_char(struct uart_port *port, unsigned int ch) +{ +	if (!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; +} + +static inline void uart_unlock_and_check_sysrq(struct uart_port *port, unsigned long irqflags) +{ +	int sysrq_ch; + +	if (!port->has_sysrq) { +		spin_unlock_irqrestore(&port->lock, irqflags); +		return; +	} + +	sysrq_ch = port->sysrq_ch; +	port->sysrq_ch = 0; + +	spin_unlock_irqrestore(&port->lock, irqflags); + +	if (sysrq_ch) +		handle_sysrq(sysrq_ch); +} +#else	/* CONFIG_MAGIC_SYSRQ_SERIAL */ +static inline int uart_handle_sysrq_char(struct uart_port *port, unsigned int ch) +{ +	return 0; +} +static inline int uart_prepare_sysrq_char(struct uart_port *port, unsigned int ch) +{ +	return 0; +} +static inline void uart_unlock_and_check_sysrq(struct uart_port *port, unsigned long irqflags) +{ +	spin_unlock_irqrestore(&port->lock, irqflags); +} +#endif	/* CONFIG_MAGIC_SYSRQ_SERIAL */ + +/* + * We do the SysRQ and SAK checking like this... + */ +static inline int uart_handle_break(struct uart_port *port) +{ +	struct uart_state *state = port->state; + +	if (port->handle_break) +		port->handle_break(port); + +#ifdef CONFIG_MAGIC_SYSRQ_SERIAL +	if (port->has_sysrq && uart_console(port)) { +		if (!port->sysrq) { +			port->sysrq = jiffies + SYSRQ_TIMEOUT; +			return 1; +		} +		port->sysrq = 0; +	} +#endif +	if (port->flags & UPF_SAK) +		do_SAK(state->port.tty); +	return 0; +}  /*   *	UART_ENABLE_MS - determine if port should enable modem status irqs  | 
