@@ -976,6 +976,15 @@ static irqreturn_t lpuart_int(int irq, void *dev_id)
976
976
977
977
sts = readb (sport -> port .membase + UARTSR1 );
978
978
979
+ /* SysRq, using dma, check for linebreak by framing err. */
980
+ if (sts & UARTSR1_FE && sport -> lpuart_dma_rx_use ) {
981
+ readb (sport -> port .membase + UARTDR );
982
+ uart_handle_break (& sport -> port );
983
+ /* linebreak produces some garbage, removing it */
984
+ writeb (UARTCFIFO_RXFLUSH , sport -> port .membase + UARTCFIFO );
985
+ return IRQ_HANDLED ;
986
+ }
987
+
979
988
if (sts & UARTSR1_RDRF && !sport -> lpuart_dma_rx_use )
980
989
lpuart_rxint (sport );
981
990
@@ -1004,6 +1013,37 @@ static irqreturn_t lpuart32_int(int irq, void *dev_id)
1004
1013
return IRQ_HANDLED ;
1005
1014
}
1006
1015
1016
+
1017
+ static inline void lpuart_handle_sysrq_chars (struct uart_port * port ,
1018
+ unsigned char * p , int count )
1019
+ {
1020
+ while (count -- ) {
1021
+ if (* p && uart_handle_sysrq_char (port , * p ))
1022
+ return ;
1023
+ p ++ ;
1024
+ }
1025
+ }
1026
+
1027
+ static void lpuart_handle_sysrq (struct lpuart_port * sport )
1028
+ {
1029
+ struct circ_buf * ring = & sport -> rx_ring ;
1030
+ int count ;
1031
+
1032
+ if (ring -> head < ring -> tail ) {
1033
+ count = sport -> rx_sgl .length - ring -> tail ;
1034
+ lpuart_handle_sysrq_chars (& sport -> port ,
1035
+ ring -> buf + ring -> tail , count );
1036
+ ring -> tail = 0 ;
1037
+ }
1038
+
1039
+ if (ring -> head > ring -> tail ) {
1040
+ count = ring -> head - ring -> tail ;
1041
+ lpuart_handle_sysrq_chars (& sport -> port ,
1042
+ ring -> buf + ring -> tail , count );
1043
+ ring -> tail = ring -> head ;
1044
+ }
1045
+ }
1046
+
1007
1047
static void lpuart_copy_rx_to_tty (struct lpuart_port * sport )
1008
1048
{
1009
1049
struct tty_port * port = & sport -> port .state -> port ;
@@ -1090,6 +1130,15 @@ static void lpuart_copy_rx_to_tty(struct lpuart_port *sport)
1090
1130
*/
1091
1131
ring -> head = sport -> rx_sgl .length - state .residue ;
1092
1132
BUG_ON (ring -> head > sport -> rx_sgl .length );
1133
+
1134
+ /*
1135
+ * Silent handling of keys pressed in the sysrq timeframe
1136
+ */
1137
+ if (sport -> port .sysrq ) {
1138
+ lpuart_handle_sysrq (sport );
1139
+ goto exit ;
1140
+ }
1141
+
1093
1142
/*
1094
1143
* At this point ring->head may point to the first byte right after the
1095
1144
* last byte of the dma buffer:
@@ -1121,6 +1170,7 @@ static void lpuart_copy_rx_to_tty(struct lpuart_port *sport)
1121
1170
sport -> port .icount .rx += count ;
1122
1171
}
1123
1172
1173
+ exit :
1124
1174
dma_sync_sg_for_device (chan -> device -> dev , & sport -> rx_sgl , 1 ,
1125
1175
DMA_FROM_DEVICE );
1126
1176
@@ -1557,6 +1607,7 @@ static void lpuart_tx_dma_startup(struct lpuart_port *sport)
1557
1607
static void lpuart_rx_dma_startup (struct lpuart_port * sport )
1558
1608
{
1559
1609
int ret ;
1610
+ unsigned char cr3 ;
1560
1611
1561
1612
if (!sport -> dma_rx_chan )
1562
1613
goto err ;
@@ -1573,6 +1624,12 @@ static void lpuart_rx_dma_startup(struct lpuart_port *sport)
1573
1624
sport -> lpuart_dma_rx_use = true;
1574
1625
rx_dma_timer_init (sport );
1575
1626
1627
+ if (sport -> port .has_sysrq ) {
1628
+ cr3 = readb (sport -> port .membase + UARTCR3 );
1629
+ cr3 |= UARTCR3_FEIE ;
1630
+ writeb (cr3 , sport -> port .membase + UARTCR3 );
1631
+ }
1632
+
1576
1633
return ;
1577
1634
1578
1635
err :
0 commit comments