@@ -324,8 +324,10 @@ struct sc16is7xx_one {
324324 u8 line ;
325325 struct kthread_work tx_work ;
326326 struct kthread_work reg_work ;
327+ struct kthread_delayed_work ms_work ;
327328 struct sc16is7xx_one_config config ;
328329 bool irda_mode ;
330+ unsigned int old_mctrl ;
329331};
330332
331333struct sc16is7xx_port {
@@ -705,12 +707,56 @@ static void sc16is7xx_handle_tx(struct uart_port *port)
705707 spin_unlock_irqrestore (& port -> lock , flags );
706708}
707709
710+ static unsigned int sc16is7xx_get_hwmctrl (struct uart_port * port )
711+ {
712+ u8 msr = sc16is7xx_port_read (port , SC16IS7XX_MSR_REG );
713+ unsigned int mctrl = 0 ;
714+
715+ mctrl |= (msr & SC16IS7XX_MSR_CTS_BIT ) ? TIOCM_CTS : 0 ;
716+ mctrl |= (msr & SC16IS7XX_MSR_DSR_BIT ) ? TIOCM_DSR : 0 ;
717+ mctrl |= (msr & SC16IS7XX_MSR_CD_BIT ) ? TIOCM_CAR : 0 ;
718+ mctrl |= (msr & SC16IS7XX_MSR_RI_BIT ) ? TIOCM_RNG : 0 ;
719+ return mctrl ;
720+ }
721+
722+ static void sc16is7xx_update_mlines (struct sc16is7xx_one * one )
723+ {
724+ struct uart_port * port = & one -> port ;
725+ struct sc16is7xx_port * s = dev_get_drvdata (port -> dev );
726+ unsigned long flags ;
727+ unsigned int status , changed ;
728+
729+ lockdep_assert_held_once (& s -> efr_lock );
730+
731+ status = sc16is7xx_get_hwmctrl (port );
732+ changed = status ^ one -> old_mctrl ;
733+
734+ if (changed == 0 )
735+ return ;
736+
737+ one -> old_mctrl = status ;
738+
739+ spin_lock_irqsave (& port -> lock , flags );
740+ if ((changed & TIOCM_RNG ) && (status & TIOCM_RNG ))
741+ port -> icount .rng ++ ;
742+ if (changed & TIOCM_DSR )
743+ port -> icount .dsr ++ ;
744+ if (changed & TIOCM_CAR )
745+ uart_handle_dcd_change (port , status & TIOCM_CAR );
746+ if (changed & TIOCM_CTS )
747+ uart_handle_cts_change (port , status & TIOCM_CTS );
748+
749+ wake_up_interruptible (& port -> state -> port .delta_msr_wait );
750+ spin_unlock_irqrestore (& port -> lock , flags );
751+ }
752+
708753static bool sc16is7xx_port_irq (struct sc16is7xx_port * s , int portno )
709754{
710755 struct uart_port * port = & s -> p [portno ].port ;
711756
712757 do {
713758 unsigned int iir , rxlen ;
759+ struct sc16is7xx_one * one = to_sc16is7xx_one (port , port );
714760
715761 iir = sc16is7xx_port_read (port , SC16IS7XX_IIR_REG );
716762 if (iir & SC16IS7XX_IIR_NO_INT_BIT )
@@ -727,6 +773,11 @@ static bool sc16is7xx_port_irq(struct sc16is7xx_port *s, int portno)
727773 if (rxlen )
728774 sc16is7xx_handle_rx (port , rxlen , iir );
729775 break ;
776+ /* CTSRTS interrupt comes only when CTS goes inactive */
777+ case SC16IS7XX_IIR_CTSRTS_SRC :
778+ case SC16IS7XX_IIR_MSI_SRC :
779+ sc16is7xx_update_mlines (one );
780+ break ;
730781 case SC16IS7XX_IIR_THRI_SRC :
731782 sc16is7xx_handle_tx (port );
732783 break ;
@@ -874,6 +925,30 @@ static void sc16is7xx_stop_rx(struct uart_port *port)
874925 sc16is7xx_ier_clear (port , SC16IS7XX_IER_RDI_BIT );
875926}
876927
928+ static void sc16is7xx_ms_proc (struct kthread_work * ws )
929+ {
930+ struct sc16is7xx_one * one = to_sc16is7xx_one (ws , ms_work .work );
931+ struct sc16is7xx_port * s = dev_get_drvdata (one -> port .dev );
932+
933+ if (one -> port .state ) {
934+ mutex_lock (& s -> efr_lock );
935+ sc16is7xx_update_mlines (one );
936+ mutex_unlock (& s -> efr_lock );
937+
938+ kthread_queue_delayed_work (& s -> kworker , & one -> ms_work , HZ );
939+ }
940+ }
941+
942+ static void sc16is7xx_enable_ms (struct uart_port * port )
943+ {
944+ struct sc16is7xx_one * one = to_sc16is7xx_one (port , port );
945+ struct sc16is7xx_port * s = dev_get_drvdata (port -> dev );
946+
947+ lockdep_assert_held_once (& port -> lock );
948+
949+ kthread_queue_delayed_work (& s -> kworker , & one -> ms_work , 0 );
950+ }
951+
877952static void sc16is7xx_start_tx (struct uart_port * port )
878953{
879954 struct sc16is7xx_port * s = dev_get_drvdata (port -> dev );
@@ -893,10 +968,10 @@ static unsigned int sc16is7xx_tx_empty(struct uart_port *port)
893968
894969static unsigned int sc16is7xx_get_mctrl (struct uart_port * port )
895970{
896- /* DCD and DSR are not wired and CTS/RTS is handled automatically
897- * so just indicate DSR and CAR asserted
898- */
899- return TIOCM_DSR | TIOCM_CAR ;
971+ struct sc16is7xx_one * one = to_sc16is7xx_one ( port , port );
972+
973+ /* Called with port lock taken so we can only return cached value */
974+ return one -> old_mctrl ;
900975}
901976
902977static void sc16is7xx_set_mctrl (struct uart_port * port , unsigned int mctrl )
@@ -920,8 +995,12 @@ static void sc16is7xx_set_termios(struct uart_port *port,
920995 struct ktermios * old )
921996{
922997 struct sc16is7xx_port * s = dev_get_drvdata (port -> dev );
998+ struct sc16is7xx_one * one = to_sc16is7xx_one (port , port );
923999 unsigned int lcr , flow = 0 ;
9241000 int baud ;
1001+ unsigned long flags ;
1002+
1003+ kthread_cancel_delayed_work_sync (& one -> ms_work );
9251004
9261005 /* Mask termios capabilities we don't support */
9271006 termios -> c_cflag &= ~CMSPAR ;
@@ -1010,8 +1089,15 @@ static void sc16is7xx_set_termios(struct uart_port *port,
10101089 /* Setup baudrate generator */
10111090 baud = sc16is7xx_set_baud (port , baud );
10121091
1092+ spin_lock_irqsave (& port -> lock , flags );
1093+
10131094 /* Update timeout according to new baud rate */
10141095 uart_update_timeout (port , termios -> c_cflag , baud );
1096+
1097+ if (UART_ENABLE_MS (port , termios -> c_cflag ))
1098+ sc16is7xx_enable_ms (port );
1099+
1100+ spin_unlock_irqrestore (& port -> lock , flags );
10151101}
10161102
10171103static int sc16is7xx_config_rs485 (struct uart_port * port ,
@@ -1052,6 +1138,7 @@ static int sc16is7xx_startup(struct uart_port *port)
10521138 struct sc16is7xx_one * one = to_sc16is7xx_one (port , port );
10531139 struct sc16is7xx_port * s = dev_get_drvdata (port -> dev );
10541140 unsigned int val ;
1141+ unsigned long flags ;
10551142
10561143 sc16is7xx_power (port , 1 );
10571144
@@ -1102,16 +1189,25 @@ static int sc16is7xx_startup(struct uart_port *port)
11021189 SC16IS7XX_EFCR_TXDISABLE_BIT ,
11031190 0 );
11041191
1105- /* Enable RX interrupt */
1106- val = SC16IS7XX_IER_RDI_BIT ;
1192+ /* Enable RX, CTS change and modem lines interrupts */
1193+ val = SC16IS7XX_IER_RDI_BIT | SC16IS7XX_IER_CTSI_BIT |
1194+ SC16IS7XX_IER_MSI_BIT ;
11071195 sc16is7xx_port_write (port , SC16IS7XX_IER_REG , val );
11081196
1197+ /* Enable modem status polling */
1198+ spin_lock_irqsave (& port -> lock , flags );
1199+ sc16is7xx_enable_ms (port );
1200+ spin_unlock_irqrestore (& port -> lock , flags );
1201+
11091202 return 0 ;
11101203}
11111204
11121205static void sc16is7xx_shutdown (struct uart_port * port )
11131206{
11141207 struct sc16is7xx_port * s = dev_get_drvdata (port -> dev );
1208+ struct sc16is7xx_one * one = to_sc16is7xx_one (port , port );
1209+
1210+ kthread_cancel_delayed_work_sync (& one -> ms_work );
11151211
11161212 /* Disable all interrupts */
11171213 sc16is7xx_port_write (port , SC16IS7XX_IER_REG , 0 );
@@ -1175,6 +1271,7 @@ static const struct uart_ops sc16is7xx_ops = {
11751271 .stop_tx = sc16is7xx_stop_tx ,
11761272 .start_tx = sc16is7xx_start_tx ,
11771273 .stop_rx = sc16is7xx_stop_rx ,
1274+ .enable_ms = sc16is7xx_enable_ms ,
11781275 .break_ctl = sc16is7xx_break_ctl ,
11791276 .startup = sc16is7xx_startup ,
11801277 .shutdown = sc16is7xx_shutdown ,
@@ -1341,7 +1438,9 @@ static int sc16is7xx_probe(struct device *dev,
13411438 s -> p [i ].port .uartclk = freq ;
13421439 s -> p [i ].port .rs485_config = sc16is7xx_config_rs485 ;
13431440 s -> p [i ].port .ops = & sc16is7xx_ops ;
1441+ s -> p [i ].old_mctrl = 0 ;
13441442 s -> p [i ].port .line = sc16is7xx_alloc_line ();
1443+
13451444 if (s -> p [i ].port .line >= SC16IS7XX_MAX_DEVS ) {
13461445 ret = - ENOMEM ;
13471446 goto out_ports ;
@@ -1353,9 +1452,17 @@ static int sc16is7xx_probe(struct device *dev,
13531452 sc16is7xx_port_write (& s -> p [i ].port , SC16IS7XX_EFCR_REG ,
13541453 SC16IS7XX_EFCR_RXDISABLE_BIT |
13551454 SC16IS7XX_EFCR_TXDISABLE_BIT );
1455+
1456+ /* Use GPIO lines as modem status registers */
1457+ if (devtype -> has_mctrl )
1458+ sc16is7xx_port_write (& s -> p [i ].port ,
1459+ SC16IS7XX_IOCONTROL_REG ,
1460+ SC16IS7XX_IOCONTROL_MODEM_BIT );
1461+
13561462 /* Initialize kthread work structs */
13571463 kthread_init_work (& s -> p [i ].tx_work , sc16is7xx_tx_proc );
13581464 kthread_init_work (& s -> p [i ].reg_work , sc16is7xx_reg_proc );
1465+ kthread_init_delayed_work (& s -> p [i ].ms_work , sc16is7xx_ms_proc );
13591466 /* Register port */
13601467 uart_add_one_port (& sc16is7xx_uart , & s -> p [i ].port );
13611468
@@ -1439,6 +1546,7 @@ static void sc16is7xx_remove(struct device *dev)
14391546#endif
14401547
14411548 for (i = 0 ; i < s -> devtype -> nr_uart ; i ++ ) {
1549+ kthread_cancel_delayed_work_sync (& s -> p [i ].ms_work );
14421550 uart_remove_one_port (& sc16is7xx_uart , & s -> p [i ].port );
14431551 clear_bit (s -> p [i ].port .line , & sc16is7xx_lines );
14441552 sc16is7xx_power (& s -> p [i ].port , 0 );
0 commit comments