3633 lines · 92.6 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0+/* *  Driver core for serial ports * *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. * *  Copyright 1999 ARM Limited *  Copyright (C) 2000-2001 Deep Blue Solutions Ltd. */#include <linux/module.h>#include <linux/tty.h>#include <linux/tty_flip.h>#include <linux/slab.h>#include <linux/sched/signal.h>#include <linux/init.h>#include <linux/console.h>#include <linux/gpio/consumer.h>#include <linux/kernel.h>#include <linux/of.h>#include <linux/pm_runtime.h>#include <linux/proc_fs.h>#include <linux/seq_file.h>#include <linux/device.h>#include <linux/serial.h> /* for serial_state and serial_icounter_struct */#include <linux/serial_core.h>#include <linux/sysrq.h>#include <linux/delay.h>#include <linux/mutex.h>#include <linux/math64.h>#include <linux/security.h> #include <linux/irq.h>#include <linux/uaccess.h> #include "serial_base.h"#include "8250/8250.h" /* For hub6_match_port() */ /* * This is used to lock changes in serial line configuration. */static DEFINE_MUTEX(port_mutex); /* * lockdep: port->lock is initialized in two places, but we *          want only one lock-class: */static struct lock_class_key port_lock_key; #define HIGH_BITS_OFFSET	((sizeof(long)-sizeof(int))*8) /* * Max time with active RTS before/after data is sent. */#define RS485_MAX_RTS_DELAY	100 /* msecs */ static void uart_change_pm(struct uart_state *state,			   enum uart_pm_state pm_state); static void uart_port_shutdown(struct tty_port *port); static int uart_dcd_enabled(struct uart_port *uport){	return !!(uport->status & UPSTAT_DCD_ENABLE);} static inline struct uart_port *uart_port_ref(struct uart_state *state){	if (atomic_add_unless(&state->refcount, 1, 0))		return state->uart_port;	return NULL;} static inline void uart_port_deref(struct uart_port *uport){	if (atomic_dec_and_test(&uport->state->refcount))		wake_up(&uport->state->remove_wait);} static inline struct uart_port *uart_port_ref_lock(struct uart_state *state, unsigned long *flags){	struct uart_port *uport = uart_port_ref(state); 	if (uport)		uart_port_lock_irqsave(uport, flags); 	return uport;} static inline void uart_port_unlock_deref(struct uart_port *uport, unsigned long flags){	if (uport) {		uart_port_unlock_irqrestore(uport, flags);		uart_port_deref(uport);	}} static inline struct uart_port *uart_port_check(struct uart_state *state){	lockdep_assert_held(&state->port.mutex);	return state->uart_port;} /** * uart_write_wakeup - schedule write processing * @port: port to be processed * * This routine is used by the interrupt handler to schedule processing in the * software interrupt portion of the driver. A driver is expected to call this * function when the number of characters in the transmit buffer have dropped * below a threshold. * * Locking: @port->lock should be held */void uart_write_wakeup(struct uart_port *port){	struct uart_state *state = port->state;	/*	 * This means you called this function _after_ the port was	 * closed.  No cookie for you.	 */	BUG_ON(!state);	tty_port_tty_wakeup(&state->port);}EXPORT_SYMBOL(uart_write_wakeup); static void uart_stop(struct tty_struct *tty){	struct uart_state *state = tty->driver_data;	struct uart_port *port;	unsigned long flags; 	port = uart_port_ref_lock(state, &flags);	if (port)		port->ops->stop_tx(port);	uart_port_unlock_deref(port, flags);} static void __uart_start(struct uart_state *state){	struct uart_port *port = state->uart_port;	struct serial_port_device *port_dev;	int err; 	if (!port || port->flags & UPF_DEAD || uart_tx_stopped(port))		return; 	port_dev = port->port_dev; 	/* Increment the runtime PM usage count for the active check below */	err = pm_runtime_get(&port_dev->dev);	if (err < 0 && err != -EINPROGRESS) {		pm_runtime_put_noidle(&port_dev->dev);		return;	} 	/*	 * Start TX if enabled, and kick runtime PM. If the device is not	 * enabled, serial_port_runtime_resume() calls start_tx() again	 * after enabling the device.	 */	if (!pm_runtime_enabled(port->dev) || pm_runtime_active(&port_dev->dev))		port->ops->start_tx(port);	pm_runtime_mark_last_busy(&port_dev->dev);	pm_runtime_put_autosuspend(&port_dev->dev);} static void uart_start(struct tty_struct *tty){	struct uart_state *state = tty->driver_data;	struct uart_port *port;	unsigned long flags; 	port = uart_port_ref_lock(state, &flags);	__uart_start(state);	uart_port_unlock_deref(port, flags);} static voiduart_update_mctrl(struct uart_port *port, unsigned int set, unsigned int clear){	unsigned int old; 	guard(uart_port_lock_irqsave)(port);	old = port->mctrl;	port->mctrl = (old & ~clear) | set;	if (old != port->mctrl && !(port->rs485.flags & SER_RS485_ENABLED))		port->ops->set_mctrl(port, port->mctrl);} #define uart_set_mctrl(port, set)	uart_update_mctrl(port, set, 0)#define uart_clear_mctrl(port, clear)	uart_update_mctrl(port, 0, clear) static void uart_port_dtr_rts(struct uart_port *uport, bool active){	if (active)		uart_set_mctrl(uport, TIOCM_DTR | TIOCM_RTS);	else		uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS);} /* Caller holds port mutex */static void uart_change_line_settings(struct tty_struct *tty, struct uart_state *state,				      const struct ktermios *old_termios){	struct uart_port *uport = uart_port_check(state);	struct ktermios *termios;	bool old_hw_stopped; 	/*	 * If we have no tty, termios, or the port does not exist,	 * then we can't set the parameters for this port.	 */	if (!tty || uport->type == PORT_UNKNOWN)		return; 	termios = &tty->termios;	uport->ops->set_termios(uport, termios, old_termios); 	/*	 * Set modem status enables based on termios cflag	 */	guard(uart_port_lock_irq)(uport);	if (termios->c_cflag & CRTSCTS)		uport->status |= UPSTAT_CTS_ENABLE;	else		uport->status &= ~UPSTAT_CTS_ENABLE; 	if (termios->c_cflag & CLOCAL)		uport->status &= ~UPSTAT_DCD_ENABLE;	else		uport->status |= UPSTAT_DCD_ENABLE; 	/* reset sw-assisted CTS flow control based on (possibly) new mode */	old_hw_stopped = uport->hw_stopped;	uport->hw_stopped = uart_softcts_mode(uport) &&			    !(uport->ops->get_mctrl(uport) & TIOCM_CTS);	if (uport->hw_stopped != old_hw_stopped) {		if (!old_hw_stopped)			uport->ops->stop_tx(uport);		else			__uart_start(state);	}} static int uart_alloc_xmit_buf(struct tty_port *port){	struct uart_state *state = container_of(port, struct uart_state, port);	struct uart_port *uport;	unsigned long flags;	unsigned long page; 	/*	 * Initialise and allocate the transmit and temporary	 * buffer.	 */	page = get_zeroed_page(GFP_KERNEL);	if (!page)		return -ENOMEM; 	uport = uart_port_ref_lock(state, &flags);	if (!state->port.xmit_buf) {		state->port.xmit_buf = (unsigned char *)page;		kfifo_init(&state->port.xmit_fifo, state->port.xmit_buf,				PAGE_SIZE);		uart_port_unlock_deref(uport, flags);	} else {		uart_port_unlock_deref(uport, flags);		/*		 * Do not free() the page under the port lock, see		 * uart_free_xmit_buf().		 */		free_page(page);	} 	return 0;} static void uart_free_xmit_buf(struct tty_port *port){	struct uart_state *state = container_of(port, struct uart_state, port);	struct uart_port *uport;	unsigned long flags;	char *xmit_buf; 	/*	 * Do not free() the transmit buffer page under the port lock since	 * this can create various circular locking scenarios. For instance,	 * console driver may need to allocate/free a debug object, which	 * can end up in printk() recursion.	 */	uport = uart_port_ref_lock(state, &flags);	xmit_buf = port->xmit_buf;	port->xmit_buf = NULL;	INIT_KFIFO(port->xmit_fifo);	uart_port_unlock_deref(uport, flags); 	free_page((unsigned long)xmit_buf);} /* * Startup the port.  This will be called once per open.  All calls * will be serialised by the per-port mutex. */static int uart_port_startup(struct tty_struct *tty, struct uart_state *state,			     bool init_hw){	struct uart_port *uport = uart_port_check(state);	int retval; 	if (uport->type == PORT_UNKNOWN)		return 1; 	/*	 * Make sure the device is in D0 state.	 */	uart_change_pm(state, UART_PM_STATE_ON); 	retval = uart_alloc_xmit_buf(&state->port);	if (retval)		return retval; 	retval = uport->ops->startup(uport);	if (retval == 0) {		if (uart_console(uport) && uport->cons->cflag) {			tty->termios.c_cflag = uport->cons->cflag;			tty->termios.c_ispeed = uport->cons->ispeed;			tty->termios.c_ospeed = uport->cons->ospeed;			uport->cons->cflag = 0;			uport->cons->ispeed = 0;			uport->cons->ospeed = 0;		}		/*		 * Initialise the hardware port settings.		 */		uart_change_line_settings(tty, state, NULL); 		/*		 * Setup the RTS and DTR signals once the		 * port is open and ready to respond.		 */		if (init_hw && C_BAUD(tty))			uart_port_dtr_rts(uport, true);	} 	/*	 * This is to allow setserial on this port. People may want to set	 * port/irq/type and then reconfigure the port properly if it failed	 * now.	 */	if (retval && capable(CAP_SYS_ADMIN))		return 1; 	return retval;} static int uart_startup(struct tty_struct *tty, struct uart_state *state,			bool init_hw){	struct tty_port *port = &state->port;	struct uart_port *uport;	int retval; 	if (tty_port_initialized(port))		goto out_base_port_startup; 	retval = uart_port_startup(tty, state, init_hw);	if (retval) {		set_bit(TTY_IO_ERROR, &tty->flags);		return retval;	} out_base_port_startup:	uport = uart_port_check(state);	if (!uport)		return -EIO; 	serial_base_port_startup(uport); 	return 0;} /* * This routine will shutdown a serial port; interrupts are disabled, and * DTR is dropped if the hangup on close termio flag is on.  Calls to * uart_shutdown are serialised by the per-port semaphore. * * uport == NULL if uart_port has already been removed */static void uart_shutdown(struct tty_struct *tty, struct uart_state *state){	struct uart_port *uport = uart_port_check(state);	struct tty_port *port = &state->port; 	/*	 * Set the TTY IO error marker	 */	if (tty)		set_bit(TTY_IO_ERROR, &tty->flags); 	if (uport)		serial_base_port_shutdown(uport); 	if (tty_port_initialized(port)) {		tty_port_set_initialized(port, false); 		/*		 * Turn off DTR and RTS early.		 */		if (uport) {			if (uart_console(uport) && tty) {				uport->cons->cflag = tty->termios.c_cflag;				uport->cons->ispeed = tty->termios.c_ispeed;				uport->cons->ospeed = tty->termios.c_ospeed;			} 			if (!tty || C_HUPCL(tty))				uart_port_dtr_rts(uport, false);		} 		uart_port_shutdown(port);	} 	/*	 * It's possible for shutdown to be called after suspend if we get	 * a DCD drop (hangup) at just the right time.  Clear suspended bit so	 * we don't try to resume a port that has been shutdown.	 */	tty_port_set_suspended(port, false); 	uart_free_xmit_buf(port);} /** * uart_update_timeout - update per-port frame timing information * @port: uart_port structure describing the port * @cflag: termios cflag value * @baud: speed of the port * * Set the @port frame timing information from which the FIFO timeout value is * derived. The @cflag value should reflect the actual hardware settings as * number of bits, parity, stop bits and baud rate is taken into account here. * * Locking: caller is expected to take @port->lock */voiduart_update_timeout(struct uart_port *port, unsigned int cflag,		    unsigned int baud){	u64 temp = tty_get_frame_size(cflag); 	temp *= NSEC_PER_SEC;	port->frame_time = (unsigned int)DIV64_U64_ROUND_UP(temp, baud);}EXPORT_SYMBOL(uart_update_timeout); /** * uart_get_baud_rate - return baud rate for a particular port * @port: uart_port structure describing the port in question. * @termios: desired termios settings * @old: old termios (or %NULL) * @min: minimum acceptable baud rate * @max: maximum acceptable baud rate * * Decode the termios structure into a numeric baud rate, taking account of the * magic 38400 baud rate (with spd_* flags), and mapping the %B0 rate to 9600 * baud or min argument, whichever is greater. * * If the new baud rate is invalid, try the @old termios setting. If it's still * invalid, clip to the nearest chip supported rate. * * The @termios structure is updated to reflect the baud rate we're actually * going to be using. Don't do this for the case where B0 is requested ("hang * up"). * * Locking: caller dependent */unsigned intuart_get_baud_rate(struct uart_port *port, struct ktermios *termios,		   const struct ktermios *old, unsigned int min, unsigned int max){	unsigned int try;	unsigned int baud;	unsigned int altbaud;	upf_t flags = port->flags & UPF_SPD_MASK; 	switch (flags) {	case UPF_SPD_HI:		altbaud = 57600;		break;	case UPF_SPD_VHI:		altbaud = 115200;		break;	case UPF_SPD_SHI:		altbaud = 230400;		break;	case UPF_SPD_WARP:		altbaud = 460800;		break;	default:		altbaud = 38400;

Lines 1–500 of 3633.