drivers/tty/serial/xilinx_uartps.c

Source file repositories/reference/linux-study-clean/drivers/tty/serial/xilinx_uartps.c

File Facts

System
Linux kernel
Corpus path
drivers/tty/serial/xilinx_uartps.c
Extension
.c
Size
55857 bytes
Lines
1925
Domain
Driver Families
Bucket
drivers/tty
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct cdns_uart {
	struct uart_port	*port;
	struct clk		*uartclk;
	struct clk		*pclk;
	unsigned int		baud;
	struct notifier_block	clk_rate_change_nb;
	u32			quirks;
	bool cts_override;
	struct gpio_desc	*gpiod_rts;
	bool			rs485_tx_started;
	struct hrtimer		tx_timer;
	struct reset_control	*rstc;
};
struct cdns_platform_data {
	u32 quirks;
};

static struct serial_rs485 cdns_rs485_supported = {
	.flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND |
		 SER_RS485_RTS_AFTER_SEND,
	.delay_rts_before_send = 1,
	.delay_rts_after_send = 1,
};

#define to_cdns_uart(_nb) container_of(_nb, struct cdns_uart, \
		clk_rate_change_nb)

/**
 * cdns_uart_handle_rx - Handle the received bytes along with Rx errors.
 * @dev_id: Id of the UART port
 * @isrstatus: The interrupt status register value as read
 * Return: None
 */
static void cdns_uart_handle_rx(void *dev_id, unsigned int isrstatus)
{
	struct uart_port *port = (struct uart_port *)dev_id;
	struct cdns_uart *cdns_uart = port->private_data;
	unsigned int data;
	unsigned int rxbs_status = 0;
	unsigned int status_mask;
	unsigned int framerrprocessed = 0;
	char status = TTY_NORMAL;
	bool is_rxbs_support;

	is_rxbs_support = cdns_uart->quirks & CDNS_UART_RXBS_SUPPORT;

	while ((readl(port->membase + CDNS_UART_SR) &
		CDNS_UART_SR_RXEMPTY) != CDNS_UART_SR_RXEMPTY) {
		if (is_rxbs_support)
			rxbs_status = readl(port->membase + CDNS_UART_RXBS);
		data = readl(port->membase + CDNS_UART_FIFO);
		port->icount.rx++;
		/*
		 * There is no hardware break detection in Zynq, so we interpret
		 * framing error with all-zeros data as a break sequence.
		 * Most of the time, there's another non-zero byte at the
		 * end of the sequence.
		 */
		if (!is_rxbs_support && (isrstatus & CDNS_UART_IXR_FRAMING)) {
			if (!data) {
				port->read_status_mask |= CDNS_UART_IXR_BRK;
				framerrprocessed = 1;
				continue;
			}
		}
		if (is_rxbs_support && (rxbs_status & CDNS_UART_RXBS_BRK)) {
			port->icount.brk++;
			status = TTY_BREAK;
			if (uart_handle_break(port))
				continue;
		}

		isrstatus &= port->read_status_mask;
		isrstatus &= ~port->ignore_status_mask;
		status_mask = port->read_status_mask;
		status_mask &= ~port->ignore_status_mask;

		if (data &&
		    (port->read_status_mask & CDNS_UART_IXR_BRK)) {
			port->read_status_mask &= ~CDNS_UART_IXR_BRK;
			port->icount.brk++;
			if (uart_handle_break(port))
				continue;
		}

		if (uart_prepare_sysrq_char(port, data))
			continue;

		if (is_rxbs_support) {
			if ((rxbs_status & CDNS_UART_RXBS_PARITY)

Annotation

Implementation Notes