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

Commit ceca629e authored by Sascha Hauer's avatar Sascha Hauer Committed by Russell King
Browse files

[ARM] 2971/1: i.MX uart handle rts irq



Patch from Sascha Hauer

handle rts interrupt

Signed-off-by: default avatarGiancarlo Formicuccia <giancarlo.formicuccia@gmail.com>
Signed-off-by: default avatarSascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 9f693d7b
Loading
Loading
Loading
Loading
+33 −6
Original line number Diff line number Diff line
@@ -73,7 +73,7 @@ struct imx_port {
	struct uart_port	port;
	struct timer_list	timer;
	unsigned int		old_status;
	int txirq,rxirq;
	int txirq,rxirq,rtsirq;
};

/*
@@ -181,6 +181,22 @@ static void imx_start_tx(struct uart_port *port)
		imx_transmit_buffer(sport);
}

static irqreturn_t imx_rtsint(int irq, void *dev_id, struct pt_regs *regs)
{
	struct imx_port *sport = (struct imx_port *)dev_id;
	unsigned int val = USR1((u32)sport->port.membase)&USR1_RTSS;
	unsigned long flags;

	spin_lock_irqsave(&sport->port.lock, flags);

	USR1((u32)sport->port.membase) = USR1_RTSD;
	uart_handle_cts_change(&sport->port, !!val);
	wake_up_interruptible(&sport->port.info->delta_msr_wait);

	spin_unlock_irqrestore(&sport->port.lock, flags);
	return IRQ_HANDLED;
}

static irqreturn_t imx_txint(int irq, void *dev_id, struct pt_regs *regs)
{
	struct imx_port *sport = (struct imx_port *)dev_id;
@@ -386,15 +402,21 @@ static int imx_startup(struct uart_port *port)
	if (retval) goto error_out1;

	retval = request_irq(sport->txirq, imx_txint, 0,
			     "imx-uart", sport);
			     DRIVER_NAME, sport);
	if (retval) goto error_out2;

	retval = request_irq(sport->rtsirq, imx_rtsint, 0,
			     DRIVER_NAME, sport);
	if (retval) goto error_out3;
	set_irq_type(sport->rtsirq, IRQT_BOTHEDGE);

	/*
	 * Finally, clear and enable interrupts
	 */

	USR1((u32)sport->port.membase) = USR1_RTSD;
	UCR1((u32)sport->port.membase) |=
	                 (UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_UARTEN);
	                 (UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN);

	UCR2((u32)sport->port.membase) |= (UCR2_RXEN | UCR2_TXEN);
	/*
@@ -406,6 +428,8 @@ static int imx_startup(struct uart_port *port)

	return 0;

error_out3:
	free_irq(sport->txirq, sport);
error_out2:
	free_irq(sport->rxirq, sport);
error_out1:
@@ -424,6 +448,7 @@ static void imx_shutdown(struct uart_port *port)
	/*
	 * Free the interrupts
	 */
	free_irq(sport->rtsirq, sport);
	free_irq(sport->txirq, sport);
	free_irq(sport->rxirq, sport);

@@ -432,7 +457,7 @@ static void imx_shutdown(struct uart_port *port)
	 */

	UCR1((u32)sport->port.membase) &=
	                 ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_UARTEN);
	                 ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN);
}

static void
@@ -522,7 +547,7 @@ imx_set_termios(struct uart_port *port, struct termios *termios,
	 * disable interrupts and drain transmitter
	 */
	old_ucr1 = UCR1((u32)sport->port.membase);
	UCR1((u32)sport->port.membase) &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN);
	UCR1((u32)sport->port.membase) &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN);

	while ( !(USR2((u32)sport->port.membase) & USR2_TXDC))
		barrier();
@@ -643,6 +668,7 @@ static struct imx_port imx_ports[] = {
	{
	.txirq  = UART1_MINT_TX,
	.rxirq  = UART1_MINT_RX,
	.rtsirq = UART1_MINT_RTS,
	.port	= {
		.type		= PORT_IMX,
		.iotype		= SERIAL_IO_MEM,
@@ -658,6 +684,7 @@ static struct imx_port imx_ports[] = {
	}, {
	.txirq  = UART2_MINT_TX,
	.rxirq  = UART2_MINT_RX,
	.rtsirq = UART2_MINT_RTS,
	.port	= {
		.type		= PORT_IMX,
		.iotype		= SERIAL_IO_MEM,
@@ -737,7 +764,7 @@ imx_console_write(struct console *co, const char *s, unsigned int count)

	UCR1((u32)sport->port.membase) =
	                   (old_ucr1 | UCR1_UARTCLKEN | UCR1_UARTEN)
	                   & ~(UCR1_TXMPTYEN | UCR1_RRDYEN);
	                   & ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN);
	UCR2((u32)sport->port.membase) = old_ucr2 | UCR2_TXEN;

	/*