Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5ede4a5c authored by Soren Brinkmann's avatar Soren Brinkmann Committed by Greg Kroah-Hartman
Browse files

tty: xuartps: Move RX path into helper function



Move RX-related IRQ handling into a helper function.
Fixes a problem where every char received after a parity or frame error
in the current isr will also be tagged as a parity or frame error.

Signed-off-by: default avatarSoren Brinkmann <soren.brinkmann@xilinx.com>
Reviewed-by: default avatarPeter Hurley <peter@hurleysoftware.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent a19eda0f
Loading
Loading
Loading
Loading
+28 −22
Original line number Diff line number Diff line
@@ -172,28 +172,8 @@ struct cdns_uart {
#define to_cdns_uart(_nb) container_of(_nb, struct cdns_uart, \
		clk_rate_change_nb);

/**
 * cdns_uart_isr - Interrupt handler
 * @irq: Irq number
 * @dev_id: Id of the port
 *
 * Return: IRQHANDLED
 */
static irqreturn_t cdns_uart_isr(int irq, void *dev_id)
static void cdns_uart_handle_rx(struct uart_port *port, unsigned int isrstatus)
{
	struct uart_port *port = (struct uart_port *)dev_id;
	unsigned long flags;
	unsigned int isrstatus, numbytes;
	unsigned int data;
	char status = TTY_NORMAL;

	spin_lock_irqsave(&port->lock, flags);

	/* Read the interrupt status register to determine which
	 * interrupt(s) is/are active.
	 */
	isrstatus = readl(port->membase + CDNS_UART_ISR_OFFSET);

	/*
	 * There is no hardware break detection, so we interpret framing
	 * error with all-zeros data as a break sequence. Most of the time,
@@ -223,6 +203,9 @@ static irqreturn_t cdns_uart_isr(int irq, void *dev_id)
		/* Receive Timeout Interrupt */
		while (!(readl(port->membase + CDNS_UART_SR_OFFSET) &
					CDNS_UART_SR_RXEMPTY)) {
			u32 data;
			char status = TTY_NORMAL;

			data = readl(port->membase + CDNS_UART_FIFO_OFFSET);

			/* Non-NULL byte after BREAK is garbage (99%) */
@@ -267,6 +250,29 @@ static irqreturn_t cdns_uart_isr(int irq, void *dev_id)
		}
		tty_flip_buffer_push(&port->state->port);
	}
}

/**
 * cdns_uart_isr - Interrupt handler
 * @irq: Irq number
 * @dev_id: Id of the port
 *
 * Return: IRQHANDLED
 */
static irqreturn_t cdns_uart_isr(int irq, void *dev_id)
{
	struct uart_port *port = (struct uart_port *)dev_id;
	unsigned long flags;
	unsigned int isrstatus, numbytes;

	spin_lock_irqsave(&port->lock, flags);

	/* Read the interrupt status register to determine which
	 * interrupt(s) is/are active.
	 */
	isrstatus = readl(port->membase + CDNS_UART_ISR_OFFSET);

	cdns_uart_handle_rx(port, isrstatus);

	/* Dispatch an appropriate handler */
	if ((isrstatus & CDNS_UART_IXR_TXEMPTY) == CDNS_UART_IXR_TXEMPTY) {