@@ -226,7 +226,8 @@ struct eg20t_port {
226226 struct pch_dma_slave param_rx ;
227227 struct dma_chan * chan_tx ;
228228 struct dma_chan * chan_rx ;
229- struct scatterlist sg_tx ;
229+ struct scatterlist * sg_tx_p ;
230+ int nent ;
230231 struct scatterlist sg_rx ;
231232 int tx_dma_use ;
232233 void * rx_buf_virt ;
@@ -595,30 +596,42 @@ static void pch_dma_rx_complete(void *arg)
595596 struct eg20t_port * priv = arg ;
596597 struct uart_port * port = & priv -> port ;
597598 struct tty_struct * tty = tty_port_tty_get (& port -> state -> port );
599+ int count ;
598600
599601 if (!tty ) {
600602 pr_debug ("%s:tty is busy now" , __func__ );
601603 return ;
602604 }
603605
604- if (dma_push_rx (priv , priv -> trigger_level ))
606+ dma_sync_sg_for_cpu (port -> dev , & priv -> sg_rx , 1 , DMA_FROM_DEVICE );
607+ count = dma_push_rx (priv , priv -> trigger_level );
608+ if (count )
605609 tty_flip_buffer_push (tty );
606-
607610 tty_kref_put (tty );
611+ async_tx_ack (priv -> desc_rx );
612+ pch_uart_hal_enable_interrupt (priv , PCH_UART_HAL_RX_INT );
608613}
609614
610615static void pch_dma_tx_complete (void * arg )
611616{
612617 struct eg20t_port * priv = arg ;
613618 struct uart_port * port = & priv -> port ;
614619 struct circ_buf * xmit = & port -> state -> xmit ;
620+ struct scatterlist * sg = priv -> sg_tx_p ;
621+ int i ;
615622
616- xmit -> tail += sg_dma_len (& priv -> sg_tx );
623+ for (i = 0 ; i < priv -> nent ; i ++ , sg ++ ) {
624+ xmit -> tail += sg_dma_len (sg );
625+ port -> icount .tx += sg_dma_len (sg );
626+ }
617627 xmit -> tail &= UART_XMIT_SIZE - 1 ;
618- port -> icount .tx += sg_dma_len (& priv -> sg_tx );
619-
620628 async_tx_ack (priv -> desc_tx );
629+ dma_unmap_sg (port -> dev , sg , priv -> nent , DMA_TO_DEVICE );
621630 priv -> tx_dma_use = 0 ;
631+ priv -> nent = 0 ;
632+ kfree (priv -> sg_tx_p );
633+ if (uart_circ_chars_pending (xmit ))
634+ pch_uart_hal_enable_interrupt (priv , PCH_UART_HAL_TX_INT );
622635}
623636
624637static int pop_tx (struct eg20t_port * priv , unsigned char * buf , int size )
@@ -682,7 +695,7 @@ static int dma_handle_rx(struct eg20t_port *priv)
682695
683696 sg_init_table (& priv -> sg_rx , 1 ); /* Initialize SG table */
684697
685- sg_dma_len (sg ) = priv -> fifo_size ;
698+ sg_dma_len (sg ) = priv -> trigger_level ;
686699
687700 sg_set_page (& priv -> sg_rx , virt_to_page (priv -> rx_buf_virt ),
688701 sg_dma_len (sg ), (unsigned long )priv -> rx_buf_virt &
@@ -692,7 +705,8 @@ static int dma_handle_rx(struct eg20t_port *priv)
692705
693706 desc = priv -> chan_rx -> device -> device_prep_slave_sg (priv -> chan_rx ,
694707 sg , 1 , DMA_FROM_DEVICE ,
695- DMA_PREP_INTERRUPT );
708+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK );
709+
696710 if (!desc )
697711 return 0 ;
698712
@@ -731,6 +745,9 @@ static unsigned int handle_tx(struct eg20t_port *priv)
731745 fifo_size -- ;
732746 }
733747 size = min (xmit -> head - xmit -> tail , fifo_size );
748+ if (size < 0 )
749+ size = fifo_size ;
750+
734751 tx_size = pop_tx (priv , xmit -> buf , size );
735752 if (tx_size > 0 ) {
736753 ret = pch_uart_hal_write (priv , xmit -> buf , tx_size );
@@ -740,8 +757,10 @@ static unsigned int handle_tx(struct eg20t_port *priv)
740757
741758 priv -> tx_empty = tx_empty ;
742759
743- if (tx_empty )
760+ if (tx_empty ) {
744761 pch_uart_hal_disable_interrupt (priv , PCH_UART_HAL_TX_INT );
762+ uart_write_wakeup (port );
763+ }
745764
746765 return PCH_UART_HANDLED_TX_INT ;
747766}
@@ -750,11 +769,16 @@ static unsigned int dma_handle_tx(struct eg20t_port *priv)
750769{
751770 struct uart_port * port = & priv -> port ;
752771 struct circ_buf * xmit = & port -> state -> xmit ;
753- struct scatterlist * sg = & priv -> sg_tx ;
772+ struct scatterlist * sg ;
754773 int nent ;
755774 int fifo_size ;
756775 int tx_empty ;
757776 struct dma_async_tx_descriptor * desc ;
777+ int num ;
778+ int i ;
779+ int bytes ;
780+ int size ;
781+ int rem ;
758782
759783 if (!priv -> start_tx ) {
760784 pr_info ("%s:Tx isn't started. (%lu)\n" , __func__ , jiffies );
@@ -772,37 +796,68 @@ static unsigned int dma_handle_tx(struct eg20t_port *priv)
772796 fifo_size -- ;
773797 }
774798
775- pch_uart_hal_disable_interrupt (priv , PCH_UART_HAL_TX_INT );
799+ bytes = min ((int )CIRC_CNT (xmit -> head , xmit -> tail ,
800+ UART_XMIT_SIZE ), CIRC_CNT_TO_END (xmit -> head ,
801+ xmit -> tail , UART_XMIT_SIZE ));
802+ if (!bytes ) {
803+ pch_uart_hal_disable_interrupt (priv , PCH_UART_HAL_TX_INT );
804+ uart_write_wakeup (port );
805+ return 0 ;
806+ }
807+
808+ if (bytes > fifo_size ) {
809+ num = bytes / fifo_size + 1 ;
810+ size = fifo_size ;
811+ rem = bytes % fifo_size ;
812+ } else {
813+ num = 1 ;
814+ size = bytes ;
815+ rem = bytes ;
816+ }
776817
777818 priv -> tx_dma_use = 1 ;
778819
779- sg_init_table (& priv -> sg_tx , 1 ); /* Initialize SG table */
820+ priv -> sg_tx_p = kzalloc (sizeof (struct scatterlist )* num , GFP_ATOMIC );
821+
822+ sg_init_table (priv -> sg_tx_p , num ); /* Initialize SG table */
823+ sg = priv -> sg_tx_p ;
780824
781- sg_set_page (& priv -> sg_tx , virt_to_page (xmit -> buf ),
782- UART_XMIT_SIZE , (int )xmit -> buf & ~PAGE_MASK );
825+ for (i = 0 ; i < num ; i ++ , sg ++ ) {
826+ if (i == (num - 1 ))
827+ sg_set_page (sg , virt_to_page (xmit -> buf ),
828+ rem , fifo_size * i );
829+ else
830+ sg_set_page (sg , virt_to_page (xmit -> buf ),
831+ size , fifo_size * i );
832+ }
783833
784- nent = dma_map_sg (port -> dev , & priv -> sg_tx , 1 , DMA_TO_DEVICE );
834+ sg = priv -> sg_tx_p ;
835+ nent = dma_map_sg (port -> dev , sg , num , DMA_TO_DEVICE );
785836 if (!nent ) {
786837 pr_err ("%s:dma_map_sg Failed\n" , __func__ );
787838 return 0 ;
788839 }
789-
790- sg -> offset = xmit -> tail & (UART_XMIT_SIZE - 1 );
791- sg_dma_address (sg ) = (sg_dma_address (sg ) & ~(UART_XMIT_SIZE - 1 )) +
792- sg -> offset ;
793- sg_dma_len (sg ) = min ((int )CIRC_CNT (xmit -> head , xmit -> tail ,
794- UART_XMIT_SIZE ), CIRC_CNT_TO_END (xmit -> head ,
795- xmit -> tail , UART_XMIT_SIZE ));
840+ priv -> nent = nent ;
841+
842+ for (i = 0 ; i < nent ; i ++ , sg ++ ) {
843+ sg -> offset = (xmit -> tail & (UART_XMIT_SIZE - 1 )) +
844+ fifo_size * i ;
845+ sg_dma_address (sg ) = (sg_dma_address (sg ) &
846+ ~(UART_XMIT_SIZE - 1 )) + sg -> offset ;
847+ if (i == (nent - 1 ))
848+ sg_dma_len (sg ) = rem ;
849+ else
850+ sg_dma_len (sg ) = size ;
851+ }
796852
797853 desc = priv -> chan_tx -> device -> device_prep_slave_sg (priv -> chan_tx ,
798- sg , nent , DMA_TO_DEVICE , DMA_PREP_INTERRUPT | DMA_CTRL_ACK );
854+ priv -> sg_tx_p , nent , DMA_TO_DEVICE ,
855+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK );
799856 if (!desc ) {
800857 pr_err ("%s:device_prep_slave_sg Failed\n" , __func__ );
801858 return 0 ;
802859 }
803-
804- dma_sync_sg_for_device (port -> dev , sg , 1 , DMA_TO_DEVICE );
805-
860+ dma_sync_sg_for_device (port -> dev , priv -> sg_tx_p , nent , DMA_TO_DEVICE );
806861 priv -> desc_tx = desc ;
807862 desc -> callback = pch_dma_tx_complete ;
808863 desc -> callback_param = priv ;
@@ -857,10 +912,16 @@ static irqreturn_t pch_uart_interrupt(int irq, void *dev_id)
857912 }
858913 break ;
859914 case PCH_UART_IID_RDR : /* Received Data Ready */
860- if (priv -> use_dma )
915+ if (priv -> use_dma ) {
916+ pch_uart_hal_disable_interrupt (priv ,
917+ PCH_UART_HAL_RX_INT );
861918 ret = dma_handle_rx (priv );
862- else
919+ if (!ret )
920+ pch_uart_hal_enable_interrupt (priv ,
921+ PCH_UART_HAL_RX_INT );
922+ } else {
863923 ret = handle_rx (priv );
924+ }
864925 break ;
865926 case PCH_UART_IID_RDR_TO : /* Received Data Ready
866927 (FIFO Timeout) */
0 commit comments