linux/drivers/tty/serial/serial_core.c

// 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"

/*
 * 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

/*
 * Max time with active RTS before/after data is sent.
 */
#define RS485_MAX_RTS_DELAY

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)
{}

static inline struct uart_port *uart_port_ref(struct uart_state *state)
{}

static inline void uart_port_deref(struct uart_port *uport)
{}

#define uart_port_lock(state, flags)

#define uart_port_unlock(uport, flags)

static inline struct uart_port *uart_port_check(struct uart_state *state)
{}

/**
 * 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)
{}
EXPORT_SYMBOL();

static void uart_stop(struct tty_struct *tty)
{}

static void __uart_start(struct uart_state *state)
{}

static void uart_start(struct tty_struct *tty)
{}

static void
uart_update_mctrl(struct uart_port *port, unsigned int set, unsigned int clear)
{}

#define uart_set_mctrl(port, set)
#define uart_clear_mctrl(port, clear)

static void uart_port_dtr_rts(struct uart_port *uport, bool active)
{}

/* Caller holds port mutex */
static void uart_change_line_settings(struct tty_struct *tty, struct uart_state *state,
				      const struct ktermios *old_termios)
{}

static int uart_alloc_xmit_buf(struct tty_port *port)
{}

static void uart_free_xmit_buf(struct tty_port *port)
{}

/*
 * 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)
{}

static int uart_startup(struct tty_struct *tty, struct uart_state *state,
			bool init_hw)
{}

/*
 * 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)
{}

/**
 * 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
 */
void
uart_update_timeout(struct uart_port *port, unsigned int cflag,
		    unsigned int baud)
{}
EXPORT_SYMBOL();

/**
 * 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.
 *
 * If the new baud rate is invalid, try the @old termios setting. If it's still
 * invalid, we try 9600 baud. If that is also invalid 0 is returned.
 *
 * 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 int
uart_get_baud_rate(struct uart_port *port, struct ktermios *termios,
		   const struct ktermios *old, unsigned int min, unsigned int max)
{}
EXPORT_SYMBOL();

/**
 * uart_get_divisor - return uart clock divisor
 * @port: uart_port structure describing the port
 * @baud: desired baud rate
 *
 * Calculate the divisor (baud_base / baud) for the specified @baud,
 * appropriately rounded.
 *
 * If 38400 baud and custom divisor is selected, return the custom divisor
 * instead.
 *
 * Locking: caller dependent
 */
unsigned int
uart_get_divisor(struct uart_port *port, unsigned int baud)
{}
EXPORT_SYMBOL();

static int uart_put_char(struct tty_struct *tty, u8 c)
{}

static void uart_flush_chars(struct tty_struct *tty)
{}

static ssize_t uart_write(struct tty_struct *tty, const u8 *buf, size_t count)
{}

static unsigned int uart_write_room(struct tty_struct *tty)
{}

static unsigned int uart_chars_in_buffer(struct tty_struct *tty)
{}

static void uart_flush_buffer(struct tty_struct *tty)
{}

/*
 * This function performs low-level write of high-priority XON/XOFF
 * character and accounting for it.
 *
 * Requires uart_port to implement .serial_out().
 */
void uart_xchar_out(struct uart_port *uport, int offset)
{}
EXPORT_SYMBOL_GPL();

/*
 * This function is used to send a high-priority XON/XOFF character to
 * the device
 */
static void uart_send_xchar(struct tty_struct *tty, u8 ch)
{}

static void uart_throttle(struct tty_struct *tty)
{}

static void uart_unthrottle(struct tty_struct *tty)
{}

static int uart_get_info(struct tty_port *port, struct serial_struct *retinfo)
{}

static int uart_get_info_user(struct tty_struct *tty,
			 struct serial_struct *ss)
{}

static int uart_set_info(struct tty_struct *tty, struct tty_port *port,
			 struct uart_state *state,
			 struct serial_struct *new_info)
{}

static int uart_set_info_user(struct tty_struct *tty, struct serial_struct *ss)
{}

/**
 * uart_get_lsr_info - get line status register info
 * @tty: tty associated with the UART
 * @state: UART being queried
 * @value: returned modem value
 */
static int uart_get_lsr_info(struct tty_struct *tty,
			struct uart_state *state, unsigned int __user *value)
{}

static int uart_tiocmget(struct tty_struct *tty)
{}

static int
uart_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear)
{}

static int uart_break_ctl(struct tty_struct *tty, int break_state)
{}

static int uart_do_autoconfig(struct tty_struct *tty, struct uart_state *state)
{}

static void uart_enable_ms(struct uart_port *uport)
{}

/*
 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
 * - mask passed in arg for lines of interest
 *   (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
 * Caller should use TIOCGICOUNT to see which one it was
 *
 * FIXME: This wants extracting into a common all driver implementation
 * of TIOCMWAIT using tty_port.
 */
static int uart_wait_modem_status(struct uart_state *state, unsigned long arg)
{}

/*
 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
 * Return: write counters to the user passed counter struct
 * NB: both 1->0 and 0->1 transitions are counted except for
 *     RI where only 0->1 is counted.
 */
static int uart_get_icount(struct tty_struct *tty,
			  struct serial_icounter_struct *icount)
{}

#define SER_RS485_LEGACY_FLAGS

static int uart_check_rs485_flags(struct uart_port *port, struct serial_rs485 *rs485)
{}

static void uart_sanitize_serial_rs485_delays(struct uart_port *port,
					      struct serial_rs485 *rs485)
{}

static void uart_sanitize_serial_rs485(struct uart_port *port, struct serial_rs485 *rs485)
{}

static void uart_set_rs485_termination(struct uart_port *port,
				       const struct serial_rs485 *rs485)
{}

static void uart_set_rs485_rx_during_tx(struct uart_port *port,
					const struct serial_rs485 *rs485)
{}

static int uart_rs485_config(struct uart_port *port)
{}

static int uart_get_rs485_config(struct uart_port *port,
			 struct serial_rs485 __user *rs485)
{}

static int uart_set_rs485_config(struct tty_struct *tty, struct uart_port *port,
			 struct serial_rs485 __user *rs485_user)
{}

static int uart_get_iso7816_config(struct uart_port *port,
				   struct serial_iso7816 __user *iso7816)
{}

static int uart_set_iso7816_config(struct uart_port *port,
				   struct serial_iso7816 __user *iso7816_user)
{}

/*
 * Called via sys_ioctl.  We can use spin_lock_irq() here.
 */
static int
uart_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg)
{}

static void uart_set_ldisc(struct tty_struct *tty)
{}

static void uart_set_termios(struct tty_struct *tty,
			     const struct ktermios *old_termios)
{}

/*
 * Calls to uart_close() are serialised via the tty_lock in
 *   drivers/tty/tty_io.c:tty_release()
 *   drivers/tty/tty_io.c:do_tty_hangup()
 */
static void uart_close(struct tty_struct *tty, struct file *filp)
{}

static void uart_tty_port_shutdown(struct tty_port *port)
{}

static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
{}

/*
 * Calls to uart_hangup() are serialised by the tty_lock in
 *   drivers/tty/tty_io.c:do_tty_hangup()
 * This runs from a workqueue and can sleep for a _short_ time only.
 */
static void uart_hangup(struct tty_struct *tty)
{}

/* uport == NULL if uart_port has already been removed */
static void uart_port_shutdown(struct tty_port *port)
{}

static bool uart_carrier_raised(struct tty_port *port)
{}

static void uart_dtr_rts(struct tty_port *port, bool active)
{}

static int uart_install(struct tty_driver *driver, struct tty_struct *tty)
{}

/*
 * Calls to uart_open are serialised by the tty_lock in
 *   drivers/tty/tty_io.c:tty_open()
 * Note that if this fails, then uart_close() _will_ be called.
 *
 * In time, we want to scrap the "opening nonpresent ports"
 * behaviour and implement an alternative way for setserial
 * to set base addresses/ports/types.  This will allow us to
 * get rid of a certain amount of extra tests.
 */
static int uart_open(struct tty_struct *tty, struct file *filp)
{}

static int uart_port_activate(struct tty_port *port, struct tty_struct *tty)
{}

static const char *uart_type(struct uart_port *port)
{}

#ifdef CONFIG_PROC_FS

static void uart_line_info(struct seq_file *m, struct uart_driver *drv, int i)
{}

static int uart_proc_show(struct seq_file *m, void *v)
{}
#endif

static void uart_port_spin_lock_init(struct uart_port *port)
{}

#if defined(CONFIG_SERIAL_CORE_CONSOLE) || defined(CONFIG_CONSOLE_POLL)
/**
 * uart_console_write - write a console message to a serial port
 * @port: the port to write the message
 * @s: array of characters
 * @count: number of characters in string to write
 * @putchar: function to write character to port
 */
void uart_console_write(struct uart_port *port, const char *s,
			unsigned int count,
			void (*putchar)(struct uart_port *, unsigned char))
{}
EXPORT_SYMBOL_GPL();

/**
 * uart_get_console - get uart port for console
 * @ports: ports to search in
 * @nr: number of @ports
 * @co: console to search for
 * Returns: uart_port for the console @co
 *
 * Check whether an invalid uart number has been specified (as @co->index), and
 * if so, search for the first available port that does have console support.
 */
struct uart_port * __init
uart_get_console(struct uart_port *ports, int nr, struct console *co)
{}

/**
 * uart_parse_earlycon - Parse earlycon options
 * @p:	     ptr to 2nd field (ie., just beyond '<name>,')
 * @iotype:  ptr for decoded iotype (out)
 * @addr:    ptr for decoded mapbase/iobase (out)
 * @options: ptr for <options> field; %NULL if not present (out)
 *
 * Decodes earlycon kernel command line parameters of the form:
 *  * earlycon=<name>,io|mmio|mmio16|mmio32|mmio32be|mmio32native,<addr>,<options>
 *  * console=<name>,io|mmio|mmio16|mmio32|mmio32be|mmio32native,<addr>,<options>
 *
 * The optional form:
 *  * earlycon=<name>,0x<addr>,<options>
 *  * console=<name>,0x<addr>,<options>
 *
 * is also accepted; the returned @iotype will be %UPIO_MEM.
 *
 * Returns: 0 on success or -%EINVAL on failure
 */
int uart_parse_earlycon(char *p, unsigned char *iotype, resource_size_t *addr,
			char **options)
{}
EXPORT_SYMBOL_GPL();

/**
 * uart_parse_options - Parse serial port baud/parity/bits/flow control.
 * @options: pointer to option string
 * @baud: pointer to an 'int' variable for the baud rate.
 * @parity: pointer to an 'int' variable for the parity.
 * @bits: pointer to an 'int' variable for the number of data bits.
 * @flow: pointer to an 'int' variable for the flow control character.
 *
 * uart_parse_options() decodes a string containing the serial console
 * options. The format of the string is <baud><parity><bits><flow>,
 * eg: 115200n8r
 */
void
uart_parse_options(const char *options, int *baud, int *parity,
		   int *bits, int *flow)
{}
EXPORT_SYMBOL_GPL();

/**
 * uart_set_options - setup the serial console parameters
 * @port: pointer to the serial ports uart_port structure
 * @co: console pointer
 * @baud: baud rate
 * @parity: parity character - 'n' (none), 'o' (odd), 'e' (even)
 * @bits: number of data bits
 * @flow: flow control character - 'r' (rts)
 *
 * Locking: Caller must hold console_list_lock in order to serialize
 * early initialization of the serial-console lock.
 */
int
uart_set_options(struct uart_port *port, struct console *co,
		 int baud, int parity, int bits, int flow)
{}
EXPORT_SYMBOL_GPL();
#endif /* CONFIG_SERIAL_CORE_CONSOLE */

/**
 * uart_change_pm - set power state of the port
 *
 * @state: port descriptor
 * @pm_state: new state
 *
 * Locking: port->mutex has to be held
 */
static void uart_change_pm(struct uart_state *state,
			   enum uart_pm_state pm_state)
{}

struct uart_match {};

static int serial_match_port(struct device *dev, void *data)
{}

int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport)
{}
EXPORT_SYMBOL();

int uart_resume_port(struct uart_driver *drv, struct uart_port *uport)
{}
EXPORT_SYMBOL();

static inline void
uart_report_port(struct uart_driver *drv, struct uart_port *port)
{}

static void
uart_configure_port(struct uart_driver *drv, struct uart_state *state,
		    struct uart_port *port)
{}

#ifdef CONFIG_CONSOLE_POLL

static int uart_poll_init(struct tty_driver *driver, int line, char *options)
{}

static int uart_poll_get_char(struct tty_driver *driver, int line)
{}

static void uart_poll_put_char(struct tty_driver *driver, int line, char ch)
{}
#endif

static const struct tty_operations uart_ops =;

static const struct tty_port_operations uart_port_ops =;

/**
 * uart_register_driver - register a driver with the uart core layer
 * @drv: low level driver structure
 *
 * Register a uart driver with the core driver. We in turn register with the
 * tty layer, and initialise the core driver per-port state.
 *
 * We have a proc file in /proc/tty/driver which is named after the normal
 * driver.
 *
 * @drv->port should be %NULL, and the per-port structures should be registered
 * using uart_add_one_port() after this call has succeeded.
 *
 * Locking: none, Interrupts: enabled
 */
int uart_register_driver(struct uart_driver *drv)
{}
EXPORT_SYMBOL();

/**
 * uart_unregister_driver - remove a driver from the uart core layer
 * @drv: low level driver structure
 *
 * Remove all references to a driver from the core driver. The low level
 * driver must have removed all its ports via the uart_remove_one_port() if it
 * registered them with uart_add_one_port(). (I.e. @drv->port is %NULL.)
 *
 * Locking: none, Interrupts: enabled
 */
void uart_unregister_driver(struct uart_driver *drv)
{}
EXPORT_SYMBOL();

struct tty_driver *uart_console_device(struct console *co, int *index)
{}
EXPORT_SYMBOL_GPL();

static ssize_t uartclk_show(struct device *dev,
	struct device_attribute *attr, char *buf)
{}

static ssize_t type_show(struct device *dev,
	struct device_attribute *attr, char *buf)
{}

static ssize_t line_show(struct device *dev,
	struct device_attribute *attr, char *buf)
{}

static ssize_t port_show(struct device *dev,
	struct device_attribute *attr, char *buf)
{}

static ssize_t irq_show(struct device *dev,
	struct device_attribute *attr, char *buf)
{}

static ssize_t flags_show(struct device *dev,
	struct device_attribute *attr, char *buf)
{}

static ssize_t xmit_fifo_size_show(struct device *dev,
	struct device_attribute *attr, char *buf)
{}

static ssize_t close_delay_show(struct device *dev,
	struct device_attribute *attr, char *buf)
{}

static ssize_t closing_wait_show(struct device *dev,
	struct device_attribute *attr, char *buf)
{}

static ssize_t custom_divisor_show(struct device *dev,
	struct device_attribute *attr, char *buf)
{}

static ssize_t io_type_show(struct device *dev,
	struct device_attribute *attr, char *buf)
{}

static ssize_t iomem_base_show(struct device *dev,
	struct device_attribute *attr, char *buf)
{}

static ssize_t iomem_reg_shift_show(struct device *dev,
	struct device_attribute *attr, char *buf)
{}

static ssize_t console_show(struct device *dev,
	struct device_attribute *attr, char *buf)
{}

static ssize_t console_store(struct device *dev,
	struct device_attribute *attr, const char *buf, size_t count)
{}

static DEVICE_ATTR_RO(uartclk);
static DEVICE_ATTR_RO(type);
static DEVICE_ATTR_RO(line);
static DEVICE_ATTR_RO(port);
static DEVICE_ATTR_RO(irq);
static DEVICE_ATTR_RO(flags);
static DEVICE_ATTR_RO(xmit_fifo_size);
static DEVICE_ATTR_RO(close_delay);
static DEVICE_ATTR_RO(closing_wait);
static DEVICE_ATTR_RO(custom_divisor);
static DEVICE_ATTR_RO(io_type);
static DEVICE_ATTR_RO(iomem_base);
static DEVICE_ATTR_RO(iomem_reg_shift);
static DEVICE_ATTR_RW(console);

static struct attribute *tty_dev_attrs[] =;

static const struct attribute_group tty_dev_attr_group =;

/**
 * serial_core_add_one_port - attach a driver-defined port structure
 * @drv: pointer to the uart low level driver structure for this port
 * @uport: uart port structure to use for this port.
 *
 * Context: task context, might sleep
 *
 * This allows the driver @drv to register its own uart_port structure with the
 * core driver. The main purpose is to allow the low level uart drivers to
 * expand uart_port, rather than having yet more levels of structures.
 * Caller must hold port_mutex.
 */
static int serial_core_add_one_port(struct uart_driver *drv, struct uart_port *uport)
{}

/**
 * serial_core_remove_one_port - detach a driver defined port structure
 * @drv: pointer to the uart low level driver structure for this port
 * @uport: uart port structure for this port
 *
 * Context: task context, might sleep
 *
 * This unhooks (and hangs up) the specified port structure from the core
 * driver. No further calls will be made to the low-level code for this port.
 * Caller must hold port_mutex.
 */
static void serial_core_remove_one_port(struct uart_driver *drv,
					struct uart_port *uport)
{}

/**
 * uart_match_port - are the two ports equivalent?
 * @port1: first port
 * @port2: second port
 *
 * This utility function can be used to determine whether two uart_port
 * structures describe the same port.
 */
bool uart_match_port(const struct uart_port *port1,
		const struct uart_port *port2)
{}
EXPORT_SYMBOL();

static struct serial_ctrl_device *
serial_core_get_ctrl_dev(struct serial_port_device *port_dev)
{}

/*
 * Find a registered serial core controller device if one exists. Returns
 * the first device matching the ctrl_id. Caller must hold port_mutex.
 */
static struct serial_ctrl_device *serial_core_ctrl_find(struct uart_driver *drv,
							struct device *phys_dev,
							int ctrl_id)
{}

static struct serial_ctrl_device *serial_core_ctrl_device_add(struct uart_port *port)
{}

static int serial_core_port_device_add(struct serial_ctrl_device *ctrl_dev,
				       struct uart_port *port)
{}

/*
 * Initialize a serial core port device, and a controller device if needed.
 */
int serial_core_register_port(struct uart_driver *drv, struct uart_port *port)
{}

/*
 * Removes a serial core port device, and the related serial core controller
 * device if the last instance.
 */
void serial_core_unregister_port(struct uart_driver *drv, struct uart_port *port)
{}

/**
 * uart_handle_dcd_change - handle a change of carrier detect state
 * @uport: uart_port structure for the open port
 * @active: new carrier detect status
 *
 * Caller must hold uport->lock.
 */
void uart_handle_dcd_change(struct uart_port *uport, bool active)
{}
EXPORT_SYMBOL_GPL();

/**
 * uart_handle_cts_change - handle a change of clear-to-send state
 * @uport: uart_port structure for the open port
 * @active: new clear-to-send status
 *
 * Caller must hold uport->lock.
 */
void uart_handle_cts_change(struct uart_port *uport, bool active)
{}
EXPORT_SYMBOL_GPL();

/**
 * uart_insert_char - push a char to the uart layer
 *
 * User is responsible to call tty_flip_buffer_push when they are done with
 * insertion.
 *
 * @port: corresponding port
 * @status: state of the serial port RX buffer (LSR for 8250)
 * @overrun: mask of overrun bits in @status
 * @ch: character to push
 * @flag: flag for the character (see TTY_NORMAL and friends)
 */
void uart_insert_char(struct uart_port *port, unsigned int status,
		      unsigned int overrun, u8 ch, u8 flag)
{}
EXPORT_SYMBOL_GPL();

#ifdef CONFIG_MAGIC_SYSRQ_SERIAL
static const u8 sysrq_toggle_seq[] =;

static void uart_sysrq_on(struct work_struct *w)
{}
static DECLARE_WORK(sysrq_enable_work, uart_sysrq_on);

/**
 * uart_try_toggle_sysrq - Enables SysRq from serial line
 * @port: uart_port structure where char(s) after BREAK met
 * @ch: new character in the sequence after received BREAK
 *
 * Enables magic SysRq when the required sequence is met on port
 * (see CONFIG_MAGIC_SYSRQ_SERIAL_SEQUENCE).
 *
 * Returns: %false if @ch is out of enabling sequence and should be
 * handled some other way, %true if @ch was consumed.
 */
bool uart_try_toggle_sysrq(struct uart_port *port, u8 ch)
{}
EXPORT_SYMBOL_GPL();
#endif

/**
 * uart_get_rs485_mode() - retrieve rs485 properties for given uart
 * @port: uart device's target port
 *
 * This function implements the device tree binding described in
 * Documentation/devicetree/bindings/serial/rs485.txt.
 */
int uart_get_rs485_mode(struct uart_port *port)
{}
EXPORT_SYMBOL_GPL();

/* Compile-time assertions for serial_rs485 layout */
static_assert();
static_assert();
static_assert();

MODULE_DESCRIPTION();
MODULE_LICENSE();