Skip to content

Commit cb1a609

Browse files
Uwe Kleine-Königgregkh
authored andcommitted
serial: imx: implement rts delaying for rs485
This adds support for delays between assertion of RTS (which is supposed to enable the rs485 transmitter) and sending as well as between the last send char and deassertionof RTS. Signed-off-by: Uwe Kleine-König <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 23a98b6 commit cb1a609

File tree

1 file changed

+121
-36
lines changed

1 file changed

+121
-36
lines changed

drivers/tty/serial/imx.c

Lines changed: 121 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,13 @@ struct imx_uart_data {
188188
enum imx_uart_type devtype;
189189
};
190190

191+
enum imx_tx_state {
192+
OFF,
193+
WAIT_AFTER_RTS,
194+
SEND,
195+
WAIT_AFTER_SEND,
196+
};
197+
191198
struct imx_port {
192199
struct uart_port port;
193200
struct timer_list timer;
@@ -224,6 +231,11 @@ struct imx_port {
224231
unsigned int dma_tx_nents;
225232
unsigned int saved_reg[10];
226233
bool context_saved;
234+
235+
enum imx_tx_state tx_state;
236+
unsigned long tx_state_next_change;
237+
struct timer_list trigger_start_tx;
238+
struct timer_list trigger_stop_tx;
227239
};
228240

229241
struct imx_port_ucrs {
@@ -427,7 +439,10 @@ static void imx_uart_start_rx(struct uart_port *port)
427439
static void imx_uart_stop_tx(struct uart_port *port)
428440
{
429441
struct imx_port *sport = (struct imx_port *)port;
430-
u32 ucr1;
442+
u32 ucr1, ucr4, usr2;
443+
444+
if (sport->tx_state == OFF)
445+
return;
431446

432447
/*
433448
* We are maybe in the SMP context, so if the DMA TX thread is running
@@ -439,21 +454,46 @@ static void imx_uart_stop_tx(struct uart_port *port)
439454
ucr1 = imx_uart_readl(sport, UCR1);
440455
imx_uart_writel(sport, ucr1 & ~UCR1_TRDYEN, UCR1);
441456

442-
/* in rs485 mode disable transmitter if shifter is empty */
443-
if (port->rs485.flags & SER_RS485_ENABLED &&
444-
imx_uart_readl(sport, USR2) & USR2_TXDC) {
445-
u32 ucr2 = imx_uart_readl(sport, UCR2), ucr4;
446-
if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND)
447-
imx_uart_rts_active(sport, &ucr2);
448-
else
449-
imx_uart_rts_inactive(sport, &ucr2);
450-
imx_uart_writel(sport, ucr2, UCR2);
457+
usr2 = imx_uart_readl(sport, USR2);
458+
if (!(usr2 & USR2_TXDC)) {
459+
/* The shifter is still busy, so retry once TC triggers */
460+
return;
461+
}
451462

452-
imx_uart_start_rx(port);
463+
ucr4 = imx_uart_readl(sport, UCR4);
464+
ucr4 &= ~UCR4_TCEN;
465+
imx_uart_writel(sport, ucr4, UCR4);
453466

454-
ucr4 = imx_uart_readl(sport, UCR4);
455-
ucr4 &= ~UCR4_TCEN;
456-
imx_uart_writel(sport, ucr4, UCR4);
467+
/* in rs485 mode disable transmitter */
468+
if (port->rs485.flags & SER_RS485_ENABLED) {
469+
if (sport->tx_state == SEND) {
470+
sport->tx_state = WAIT_AFTER_SEND;
471+
sport->tx_state_next_change =
472+
jiffies + DIV_ROUND_UP(port->rs485.delay_rts_after_send * HZ, 1000);
473+
}
474+
475+
if (sport->tx_state == WAIT_AFTER_RTS ||
476+
(sport->tx_state == WAIT_AFTER_SEND &&
477+
time_after_eq(jiffies, sport->tx_state_next_change))) {
478+
u32 ucr2;
479+
480+
del_timer(&sport->trigger_start_tx);
481+
482+
ucr2 = imx_uart_readl(sport, UCR2);
483+
if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND)
484+
imx_uart_rts_active(sport, &ucr2);
485+
else
486+
imx_uart_rts_inactive(sport, &ucr2);
487+
imx_uart_writel(sport, ucr2, UCR2);
488+
489+
imx_uart_start_rx(port);
490+
491+
sport->tx_state = OFF;
492+
} else if (sport->tx_state == WAIT_AFTER_SEND) {
493+
mod_timer(&sport->trigger_stop_tx, sport->tx_state_next_change);
494+
}
495+
} else {
496+
sport->tx_state = OFF;
457497
}
458498
}
459499

@@ -651,28 +691,53 @@ static void imx_uart_start_tx(struct uart_port *port)
651691
if (!sport->port.x_char && uart_circ_empty(&port->state->xmit))
652692
return;
653693

694+
/*
695+
* We cannot simply do nothing here if sport->tx_state == SEND already
696+
* because UCR1_TXMPTYEN might already have been cleared in
697+
* imx_uart_stop_tx(), but tx_state is still SEND.
698+
*/
699+
654700
if (port->rs485.flags & SER_RS485_ENABLED) {
655-
u32 ucr2;
701+
if (sport->tx_state == OFF) {
702+
u32 ucr2 = imx_uart_readl(sport, UCR2);
703+
if (port->rs485.flags & SER_RS485_RTS_ON_SEND)
704+
imx_uart_rts_active(sport, &ucr2);
705+
else
706+
imx_uart_rts_inactive(sport, &ucr2);
707+
imx_uart_writel(sport, ucr2, UCR2);
656708

657-
ucr2 = imx_uart_readl(sport, UCR2);
658-
if (port->rs485.flags & SER_RS485_RTS_ON_SEND)
659-
imx_uart_rts_active(sport, &ucr2);
660-
else
661-
imx_uart_rts_inactive(sport, &ucr2);
662-
imx_uart_writel(sport, ucr2, UCR2);
709+
if (!(port->rs485.flags & SER_RS485_RX_DURING_TX))
710+
imx_uart_stop_rx(port);
663711

664-
if (!(port->rs485.flags & SER_RS485_RX_DURING_TX))
665-
imx_uart_stop_rx(port);
712+
sport->tx_state = WAIT_AFTER_RTS;
713+
sport->tx_state_next_change =
714+
jiffies + DIV_ROUND_UP(port->rs485.delay_rts_before_send * HZ, 1000);
715+
}
666716

667-
/*
668-
* Enable transmitter and shifter empty irq only if DMA is off.
669-
* In the DMA case this is done in the tx-callback.
670-
*/
671-
if (!sport->dma_is_enabled) {
672-
u32 ucr4 = imx_uart_readl(sport, UCR4);
673-
ucr4 |= UCR4_TCEN;
674-
imx_uart_writel(sport, ucr4, UCR4);
717+
if (sport->tx_state == WAIT_AFTER_SEND ||
718+
(sport->tx_state == WAIT_AFTER_RTS &&
719+
time_after_eq(jiffies, sport->tx_state_next_change))) {
720+
721+
del_timer(&sport->trigger_stop_tx);
722+
/*
723+
* Enable transmitter and shifter empty irq only if DMA
724+
* is off. In the DMA case this is done in the
725+
* tx-callback.
726+
*/
727+
if (!sport->dma_is_enabled) {
728+
u32 ucr4 = imx_uart_readl(sport, UCR4);
729+
ucr4 |= UCR4_TCEN;
730+
imx_uart_writel(sport, ucr4, UCR4);
731+
}
732+
733+
sport->tx_state = SEND;
734+
735+
} else if (sport->tx_state == WAIT_AFTER_RTS) {
736+
mod_timer(&sport->trigger_start_tx, sport->tx_state_next_change);
737+
return;
675738
}
739+
} else {
740+
sport->tx_state = SEND;
676741
}
677742

678743
if (!sport->dma_is_enabled) {
@@ -1630,7 +1695,6 @@ imx_uart_set_termios(struct uart_port *port, struct ktermios *termios,
16301695

16311696
if (termios->c_cflag & CRTSCTS)
16321697
ucr2 &= ~UCR2_IRTS;
1633-
16341698
if (termios->c_cflag & CSTOPB)
16351699
ucr2 |= UCR2_STPB;
16361700
if (termios->c_cflag & PARENB) {
@@ -1857,10 +1921,6 @@ static int imx_uart_rs485_config(struct uart_port *port,
18571921
struct imx_port *sport = (struct imx_port *)port;
18581922
u32 ucr2;
18591923

1860-
/* unimplemented */
1861-
rs485conf->delay_rts_before_send = 0;
1862-
rs485conf->delay_rts_after_send = 0;
1863-
18641924
/* RTS is required to control the transmitter */
18651925
if (!sport->have_rtscts && !sport->have_rtsgpio)
18661926
rs485conf->flags &= ~SER_RS485_ENABLED;
@@ -2223,6 +2283,28 @@ static void imx_uart_probe_pdata(struct imx_port *sport,
22232283
sport->have_rtscts = 1;
22242284
}
22252285

2286+
static void imx_trigger_start_tx(struct timer_list *t)
2287+
{
2288+
struct imx_port *sport = from_timer(sport, t, trigger_start_tx);
2289+
unsigned long flags;
2290+
2291+
spin_lock_irqsave(&sport->port.lock, flags);
2292+
if (sport->tx_state == WAIT_AFTER_RTS)
2293+
imx_uart_start_tx(&sport->port);
2294+
spin_unlock_irqrestore(&sport->port.lock, flags);
2295+
}
2296+
2297+
static void imx_trigger_stop_tx(struct timer_list *t)
2298+
{
2299+
struct imx_port *sport = from_timer(sport, t, trigger_stop_tx);
2300+
unsigned long flags;
2301+
2302+
spin_lock_irqsave(&sport->port.lock, flags);
2303+
if (sport->tx_state == WAIT_AFTER_SEND)
2304+
imx_uart_stop_tx(&sport->port);
2305+
spin_unlock_irqrestore(&sport->port.lock, flags);
2306+
}
2307+
22262308
static int imx_uart_probe(struct platform_device *pdev)
22272309
{
22282310
struct imx_port *sport;
@@ -2369,6 +2451,9 @@ static int imx_uart_probe(struct platform_device *pdev)
23692451

23702452
clk_disable_unprepare(sport->clk_ipg);
23712453

2454+
timer_setup(&sport->trigger_start_tx, imx_trigger_start_tx, 0);
2455+
timer_setup(&sport->trigger_stop_tx, imx_trigger_stop_tx, 0);
2456+
23722457
/*
23732458
* Allocate the IRQ(s) i.MX1 has three interrupts whereas later
23742459
* chips only have one interrupt.

0 commit comments

Comments
 (0)