@@ -315,7 +315,8 @@ struct sc16is7xx_devtype {
315315
316316struct sc16is7xx_one_config {
317317 unsigned int flags ;
318- u8 ier_clear ;
318+ u8 ier_mask ;
319+ u8 ier_val ;
319320};
320321
321322struct sc16is7xx_one {
@@ -349,6 +350,9 @@ static struct uart_driver sc16is7xx_uart = {
349350 .nr = SC16IS7XX_MAX_DEVS ,
350351};
351352
353+ static void sc16is7xx_ier_set (struct uart_port * port , u8 bit );
354+ static void sc16is7xx_stop_tx (struct uart_port * port );
355+
352356#define to_sc16is7xx_port (p ,e ) ((container_of((p), struct sc16is7xx_port, e)))
353357#define to_sc16is7xx_one (p ,e ) ((container_of((p), struct sc16is7xx_one, e)))
354358
@@ -651,6 +655,7 @@ static void sc16is7xx_handle_tx(struct uart_port *port)
651655 struct sc16is7xx_port * s = dev_get_drvdata (port -> dev );
652656 struct circ_buf * xmit = & port -> state -> xmit ;
653657 unsigned int txlen , to_send , i ;
658+ unsigned long flags ;
654659
655660 if (unlikely (port -> x_char )) {
656661 sc16is7xx_port_write (port , SC16IS7XX_THR_REG , port -> x_char );
@@ -659,8 +664,12 @@ static void sc16is7xx_handle_tx(struct uart_port *port)
659664 return ;
660665 }
661666
662- if (uart_circ_empty (xmit ) || uart_tx_stopped (port ))
667+ if (uart_circ_empty (xmit ) || uart_tx_stopped (port )) {
668+ spin_lock_irqsave (& port -> lock , flags );
669+ sc16is7xx_stop_tx (port );
670+ spin_unlock_irqrestore (& port -> lock , flags );
663671 return ;
672+ }
664673
665674 /* Get length of data pending in circular buffer */
666675 to_send = uart_circ_chars_pending (xmit );
@@ -687,8 +696,13 @@ static void sc16is7xx_handle_tx(struct uart_port *port)
687696 sc16is7xx_fifo_write (port , to_send );
688697 }
689698
699+ spin_lock_irqsave (& port -> lock , flags );
690700 if (uart_circ_chars_pending (xmit ) < WAKEUP_CHARS )
691701 uart_write_wakeup (port );
702+
703+ if (uart_circ_empty (xmit ))
704+ sc16is7xx_stop_tx (port );
705+ spin_unlock_irqrestore (& port -> lock , flags );
692706}
693707
694708static bool sc16is7xx_port_irq (struct sc16is7xx_port * s , int portno )
@@ -751,6 +765,7 @@ static void sc16is7xx_tx_proc(struct kthread_work *ws)
751765{
752766 struct uart_port * port = & (to_sc16is7xx_one (ws , tx_work )-> port );
753767 struct sc16is7xx_port * s = dev_get_drvdata (port -> dev );
768+ unsigned long flags ;
754769
755770 if ((port -> rs485 .flags & SER_RS485_ENABLED ) &&
756771 (port -> rs485 .delay_rts_before_send > 0 ))
@@ -759,6 +774,10 @@ static void sc16is7xx_tx_proc(struct kthread_work *ws)
759774 mutex_lock (& s -> efr_lock );
760775 sc16is7xx_handle_tx (port );
761776 mutex_unlock (& s -> efr_lock );
777+
778+ spin_lock_irqsave (& port -> lock , flags );
779+ sc16is7xx_ier_set (port , SC16IS7XX_IER_THRI_BIT );
780+ spin_unlock_irqrestore (& port -> lock , flags );
762781}
763782
764783static void sc16is7xx_reconf_rs485 (struct uart_port * port )
@@ -813,7 +832,7 @@ static void sc16is7xx_reg_proc(struct kthread_work *ws)
813832
814833 if (config .flags & SC16IS7XX_RECONF_IER )
815834 sc16is7xx_port_update (& one -> port , SC16IS7XX_IER_REG ,
816- config .ier_clear , 0 );
835+ config .ier_mask , config . ier_val );
817836
818837 if (config .flags & SC16IS7XX_RECONF_RS485 )
819838 sc16is7xx_reconf_rs485 (& one -> port );
@@ -824,8 +843,24 @@ static void sc16is7xx_ier_clear(struct uart_port *port, u8 bit)
824843 struct sc16is7xx_port * s = dev_get_drvdata (port -> dev );
825844 struct sc16is7xx_one * one = to_sc16is7xx_one (port , port );
826845
846+ lockdep_assert_held_once (& port -> lock );
847+
848+ one -> config .flags |= SC16IS7XX_RECONF_IER ;
849+ one -> config .ier_mask |= bit ;
850+ one -> config .ier_val &= ~bit ;
851+ kthread_queue_work (& s -> kworker , & one -> reg_work );
852+ }
853+
854+ static void sc16is7xx_ier_set (struct uart_port * port , u8 bit )
855+ {
856+ struct sc16is7xx_port * s = dev_get_drvdata (port -> dev );
857+ struct sc16is7xx_one * one = to_sc16is7xx_one (port , port );
858+
859+ lockdep_assert_held_once (& port -> lock );
860+
827861 one -> config .flags |= SC16IS7XX_RECONF_IER ;
828- one -> config .ier_clear |= bit ;
862+ one -> config .ier_mask |= bit ;
863+ one -> config .ier_val |= bit ;
829864 kthread_queue_work (& s -> kworker , & one -> reg_work );
830865}
831866
@@ -1067,8 +1102,8 @@ static int sc16is7xx_startup(struct uart_port *port)
10671102 SC16IS7XX_EFCR_TXDISABLE_BIT ,
10681103 0 );
10691104
1070- /* Enable RX, TX interrupts */
1071- val = SC16IS7XX_IER_RDI_BIT | SC16IS7XX_IER_THRI_BIT ;
1105+ /* Enable RX interrupt */
1106+ val = SC16IS7XX_IER_RDI_BIT ;
10721107 sc16is7xx_port_write (port , SC16IS7XX_IER_REG , val );
10731108
10741109 return 0 ;
0 commit comments