[Feature][T106_eSDK]update from T106-V2.01.01.02P56U06.AP.15.05_CAP.15.05 to T106-V2.01.01.02P56U06.AP.15.11_CAP.15.11.01

Only Configure: No
Affected branch: master
Affected module: unknow
Is it affected on both ZXIC and MTK: only ZXIC
Self-test: Yes
Doc Update: No

Change-Id: If8f21262a363af23493123574902bf038b8ff297
diff --git a/upstream/linux-5.10/drivers/net/zvnet/zvnet_dev.c b/upstream/linux-5.10/drivers/net/zvnet/zvnet_dev.c
index bea60e1..2a8fcc3 100755
--- a/upstream/linux-5.10/drivers/net/zvnet/zvnet_dev.c
+++ b/upstream/linux-5.10/drivers/net/zvnet/zvnet_dev.c
@@ -72,6 +72,10 @@
 module_param(g_wrap_num, int, 0644);

 unsigned int g_wrap_timeout = 10;

 module_param(g_wrap_timeout, int, 0644);

+/*jb.qi add for debug network package on 20240806 start*/

+unsigned int g_trace_limit = 0;

+module_param(g_trace_limit, int, 0644);

+/*jb.qi add for debug network package on 20240806 end*/

 #endif

 

 /*******************************************************************************

@@ -143,7 +147,19 @@
 		}

 	}

 }

+/*jb.qi add for debug network package on 20240806 start*/

+void zvnet_dump_packet(unsigned char * data, int len, int limit_len)

+{

+    int i = 0;

 

+    for(i = 0; i < len && i < limit_len; i=i+16)

+    {

+        printk("0x%04x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",i,

+            *(data+i),*(data+i+1),*(data+i+2),*(data+i+3),*(data+i+4),*(data+i+5),*(data+i+6),*(data+i+7),

+            *(data+i+8),*(data+i+9),*(data+i+10),*(data+i+11),*(data+i+12),*(data+i+13),*(data+i+14),*(data+i+15));

+    }

+}

+/*jb.qi add for debug network package on 20240806 end*/

 int zvnet_get_index_by_netdev(struct net_device *net)

 {

     int i;

@@ -288,6 +304,13 @@
 	/* make sure we initialize shinfo sequentially */

 	skb_reset_network_header(skb);

 	skb_set_kcov_handle(skb, kcov_common_handle());

+	/*jb.qi add for debug network package on 20240806 start*/

+	if(unlikely(g_trace_limit > 0)){

+        	printk("-%s-dump_packet-start-%d\n", skb->dev->name, skb->len);

+        	zvnet_dump_packet(skb->data, skb->len, g_trace_limit);

+        	printk("-%s-dump_packet-end-\n", skb->dev->name);

+        }

+	/*jb.qi add for debug network package on 20240806 end*/

 	return skb;

 }

 

@@ -451,7 +474,7 @@
 	}

 		

 	if(unlikely(skb_headroom(skb) < NET_SKB_PAD || skb->next//|| skb->capHead

-		|| skb->fclone || skb->cloned || (skb_shinfo(skb)->nr_frags) 

+		|| skb->fclone || skb->cloned || (skb_shinfo(skb)->nr_frags) || skb->sk || (skb->indev == NULL) 

 		|| (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY) || (skb_has_frag_list(skb)))){

 		int ret_len = skb->len;

 

diff --git a/upstream/linux-5.10/drivers/spi/spi-zx29.c b/upstream/linux-5.10/drivers/spi/spi-zx29.c
index d570db1..fd49fd6 100755
--- a/upstream/linux-5.10/drivers/spi/spi-zx29.c
+++ b/upstream/linux-5.10/drivers/spi/spi-zx29.c
@@ -158,8 +158,6 @@
 #define SPI_INTR_EN_MASK_TX_EMPTY_IE  		(0x1UL << 3)
 #define SPI_INTR_EN_MASK_RX_THRES_IE  		(0x1UL << 4)
 #define SPI_INTR_EN_MASK_TX_THRES_IE  		(0x1UL << 5)
-//yu.dong@20240617 [T106BUG-641] SPI packet loss problem, add kernel buffer scheme.
-#define SPI_INTR_EN_MASK_MST_EOT_IE  		(0x1UL << 6)
 
 /*
  * SPI Interrupt Status Register OR Interrupt Clear Register - SPI_INTR_SR_SCLR
@@ -1984,24 +1982,25 @@
 	return ret;
 }
 
+/* yu.dong@20240715 [T106BUG-641] SPI packet loss problem, merged into ZXW patch start */
 /* yu.dong@20240617 [T106BUG-641] SPI packet loss problem, add kernel buffer scheme start */
-#define SPI_SLVAE_RX_BUFF_SIZE        4096
-#define SPI_SLVAE_RX_MAX_PACK_NUM     15
-#define SPI_SLVAE_RX_PACK_LEN         146
-#define SPI_SLVAE_RX_LIST_BUFF_LEN    (SPI_SLVAE_RX_MAX_PACK_NUM*SPI_SLVAE_RX_PACK_LEN)
-static dma_channel_def slave_rx_conf[SPI_SLVAE_RX_MAX_PACK_NUM] = {0};
+#define SPI_SLAVE_RX_BUFF_SIZE        4096
+#define SPI_SLAVE_RX_MAX_PACK_NUM     15
+#define SPI_SLAVE_RX_PACK_LEN         146
+#define SPI_SLAVE_RX_LIST_BUFF_LEN    (SPI_SLAVE_RX_MAX_PACK_NUM*SPI_SLAVE_RX_PACK_LEN)
+static dma_channel_def slave_rx_conf[SPI_SLAVE_RX_MAX_PACK_NUM] = {0};
 //yu.dong@20240617 [T106BUG-641] SPI packet loss issue, increase kernel buffer and read all cached data away, no data loss.
 #define SPI_MAGIC 0x55555555
 static bool rxbuf_is_free_space(struct spi_device *spi)
 {
 	if (spi->recv_pos < spi->rd_pos) {
-        if ((spi->rd_pos - spi->recv_pos) > SPI_SLVAE_RX_PACK_LEN)
+        if ((spi->rd_pos - spi->recv_pos) > SPI_SLAVE_RX_PACK_LEN)
 			return 1;
 		else
 			return 0;
 	}
 	else {
-		if ((SPI_SLVAE_RX_BUFF_SIZE - spi->recv_pos + spi->rd_pos ) > SPI_SLVAE_RX_PACK_LEN)
+		if ((SPI_SLAVE_RX_BUFF_SIZE - spi->recv_pos + spi->rd_pos ) > SPI_SLAVE_RX_PACK_LEN)
 			return 1;
 		else
 			return 0;
@@ -2018,26 +2017,26 @@
 
 	zx29spi = spi_master_get_devdata(spi->master);
 	zx29spi->spi_poll_cnt++;
-	end = *(volatile unsigned int *)(spi->cyc_buf +spi->cyc_index * SPI_SLVAE_RX_PACK_LEN + SPI_SLVAE_RX_PACK_LEN - 4);
-	while((end != SPI_MAGIC) && index < SPI_SLVAE_RX_MAX_PACK_NUM) {
+	end = *(volatile unsigned int *)(spi->cyc_buf +spi->cyc_index * SPI_SLAVE_RX_PACK_LEN + SPI_SLAVE_RX_PACK_LEN - 4);
+	while((end != SPI_MAGIC) && index < SPI_SLAVE_RX_MAX_PACK_NUM) {
 		if(!rxbuf_is_free_space(spi)) {
 			printk("rx_buff not enough space!!!!!");
 			zx29spi->spi_dma_cnt++;
 			break;
 		}else {
-			if((spi->recv_pos + SPI_SLVAE_RX_PACK_LEN) <= SPI_SLVAE_RX_BUFF_SIZE) {
-				memcpy(spi->rx_buf + spi->recv_pos,spi->cyc_buf + spi->cyc_index * SPI_SLVAE_RX_PACK_LEN,SPI_SLVAE_RX_PACK_LEN);
+			if((spi->recv_pos + SPI_SLAVE_RX_PACK_LEN) <= SPI_SLAVE_RX_BUFF_SIZE) {
+				memcpy(spi->rx_buf + spi->recv_pos,spi->cyc_buf + spi->cyc_index * SPI_SLAVE_RX_PACK_LEN,SPI_SLAVE_RX_PACK_LEN);
 			}else {
-				memcpy(spi->rx_buf + spi->recv_pos,spi->cyc_buf + spi->cyc_index * SPI_SLVAE_RX_PACK_LEN,SPI_SLVAE_RX_BUFF_SIZE - spi->recv_pos);
-				memcpy(spi->rx_buf,spi->cyc_buf + spi->cyc_index * SPI_SLVAE_RX_PACK_LEN + (SPI_SLVAE_RX_BUFF_SIZE - spi->recv_pos),SPI_SLVAE_RX_PACK_LEN-(SPI_SLVAE_RX_BUFF_SIZE-spi->recv_pos));
+				memcpy(spi->rx_buf + spi->recv_pos,spi->cyc_buf + spi->cyc_index * SPI_SLAVE_RX_PACK_LEN,SPI_SLAVE_RX_BUFF_SIZE - spi->recv_pos);
+				memcpy(spi->rx_buf,spi->cyc_buf + spi->cyc_index * SPI_SLAVE_RX_PACK_LEN + (SPI_SLAVE_RX_BUFF_SIZE - spi->recv_pos),SPI_SLAVE_RX_PACK_LEN-(SPI_SLAVE_RX_BUFF_SIZE-spi->recv_pos));
 			}
-			*(volatile unsigned int *)(spi->cyc_buf +spi->cyc_index * SPI_SLVAE_RX_PACK_LEN + SPI_SLVAE_RX_PACK_LEN - 4) = SPI_MAGIC;
-			spi->recv_pos = (spi->recv_pos + SPI_SLVAE_RX_PACK_LEN)%SPI_SLVAE_RX_BUFF_SIZE;
-			spi->cyc_index = (spi->cyc_index + 1)%SPI_SLVAE_RX_MAX_PACK_NUM;
+			*(volatile unsigned int *)(spi->cyc_buf +spi->cyc_index * SPI_SLAVE_RX_PACK_LEN + SPI_SLAVE_RX_PACK_LEN - 4) = SPI_MAGIC;
+			spi->recv_pos = (spi->recv_pos + SPI_SLAVE_RX_PACK_LEN)%SPI_SLAVE_RX_BUFF_SIZE;
+			spi->cyc_index = (spi->cyc_index + 1)%SPI_SLAVE_RX_MAX_PACK_NUM;
 
 			zx29spi->spi_dma_cnt++;
 			index++;
-			end = *(volatile unsigned int *)(spi->cyc_buf +spi->cyc_index * SPI_SLVAE_RX_PACK_LEN + SPI_SLVAE_RX_PACK_LEN - 4);
+			end = *(volatile unsigned int *)(spi->cyc_buf +spi->cyc_index * SPI_SLAVE_RX_PACK_LEN + SPI_SLAVE_RX_PACK_LEN - 4);
 		}
 
 		if(spi->is_rd_waiting == true && spi->recv_done == 0) {
@@ -2045,7 +2044,7 @@
 			spi->recv_done = 1;
 		}
 	}
-	if((end != SPI_MAGIC) && index == SPI_SLVAE_RX_MAX_PACK_NUM)
+	if((end != SPI_MAGIC) && index == SPI_SLAVE_RX_MAX_PACK_NUM)
 		printk("cyc_buf be covered!!!!!");
 	return;
 }
@@ -2056,7 +2055,7 @@
 	struct chip_data *chip = NULL;
 	struct dma_chan *rxchan = NULL;
 	struct dma_async_tx_descriptor *rxdesc;
-	unsigned short transfer_len = SPI_SLVAE_RX_PACK_LEN;
+	unsigned short transfer_len = SPI_SLAVE_RX_PACK_LEN;
 	int i;
 
 	chip = zx29spi->cur_chip = spi->controller_state;
@@ -2079,7 +2078,7 @@
 	 * not trigger on 2 elements this needs explicit mapping rather than
 	 * calculation.
 	 */
-	for(i = 0;i < SPI_SLVAE_RX_MAX_PACK_NUM;i++) {
+	for(i = 0;i < SPI_SLAVE_RX_MAX_PACK_NUM;i++) {
 		switch (zx29spi->rx_lev_trig) {
 		case SPI_RX_1_OR_MORE_ELEM:
 			slave_rx_conf[i].dma_control.src_burst_len = DMA_BURST_LEN_1;
@@ -2144,7 +2143,7 @@
 
 	/* Submit and fire RX and TX with TX last so we're ready to read! */
 	if (spi->rx_dma) {
-		rxdesc = rxchan->device->device_prep_dma_cyclic(rxchan,NULL,SPI_SLVAE_RX_MAX_PACK_NUM * SPI_SLVAE_RX_PACK_LEN, SPI_SLVAE_RX_PACK_LEN,0,0);
+		rxdesc = rxchan->device->device_prep_dma_cyclic(rxchan,NULL,SPI_SLAVE_RX_MAX_PACK_NUM * SPI_SLAVE_RX_PACK_LEN, SPI_SLAVE_RX_PACK_LEN,0,0);
 		if (!rxdesc) {
 			printk(KERN_INFO "!!ERROR DESC !!![%s][%d]\n",__func__,__LINE__);
 			dmaengine_terminate_all(rxchan);
@@ -2170,14 +2169,13 @@
 	printk("zx29_slave_rd_start...\r\n");
 
 	zx29spi = spi_master_get_devdata(spi->master);
-	dev = &zx29spi->pdev->dev;
 	if (!zx29spi)
 		return -EINVAL;
-
+	dev = &zx29spi->pdev->dev;
 	spi->cyc_index = 0;
 	spi->rd_pos = spi->recv_pos = 0;
 
-	spi->cyc_buf = dma_alloc_coherent(dev, SPI_SLVAE_RX_BUFF_SIZE, &spi->rx_dma, GFP_KERNEL);
+	spi->cyc_buf = dma_alloc_coherent(dev, SPI_SLAVE_RX_BUFF_SIZE, &spi->rx_dma, GFP_KERNEL);
 	if (dma_mapping_error(dev, spi->rx_dma)) {
 		dev_err(dev, "dma_map_single spi rx failed\n");
 		return -ENOMEM;
@@ -2203,10 +2201,9 @@
 	struct dma_chan *rxchan = NULL;
 
 	zx29spi = spi_master_get_devdata(spi->master);
-	dev = &zx29spi->pdev->dev;
 	if (!zx29spi)
 		return -EINVAL;
-
+	dev = &zx29spi->pdev->dev;
 	chip = zx29spi->cur_chip= spi->controller_state;
 	writel(chip->fifo_ctrl, (SPI_FIFO_CTRL_OFFSET+zx29spi->virtbase));
 	rxchan = zx29spi->dma_rx_channel;
@@ -2217,7 +2214,7 @@
 	}
 
 	if(spi->cyc_buf != NULL && spi->rx_dma) {
-		dma_free_coherent(dev, SPI_SLVAE_RX_BUFF_SIZE, spi->cyc_buf, spi->rx_dma);
+		dma_free_coherent(dev, SPI_SLAVE_RX_BUFF_SIZE, spi->cyc_buf, spi->rx_dma);
 		spi->cyc_buf = NULL;
 	}
 
@@ -2230,6 +2227,7 @@
 	return status;
 }
 /* yu.dong@20240617 [T106BUG-641] SPI packet loss problem, add kernel buffer scheme end */
+/* yu.dong@20240715 [T106BUG-641] SPI packet loss problem, merged into ZXW patch end*/
 
 static int zx29_prepare_transfer_hardware(struct spi_master *master)
 {
@@ -2343,7 +2341,7 @@
 	.iface = SPI_INTERFACE_MOTOROLA_SPI,
 	.hierarchy = SPI_MASTER,
 	.slave_tx_disable = DO_NOT_DRIVE_TX,
-	.rx_lev_trig = SPI_RX_4_OR_MORE_ELEM,
+	.rx_lev_trig = SPI_RX_8_OR_MORE_ELEM,
 	.tx_lev_trig = SPI_TX_4_OR_MORE_EMPTY_LOC,
 //	.ctrl_len = SSP_BITS_8,
 //	.wait_state = SSP_MWIRE_WAIT_ZERO,
@@ -2611,7 +2609,10 @@
 	ktime_t k_time_start = 0;
 	ktime_t k_time_end = 0;
 	ktime_t diff_ns = 0;
-        /* yu.dong@20240617 [T106BUG-641] SPI packet loss problem, add kernel buffer scheme start */
+    /* yu.dong@20240715 [T106BUG-641] SPI packet loss problem, merged into ZXW patch start */
+    /* yu.dong@20240617 [T106BUG-641] SPI packet loss problem, add kernel buffer scheme start */
+	if(false == zx29spi->master->slave)
+		pm_stay_awake(&zx29spi->pdev->dev);
 	regval = readl((SPI_COM_CTRL_OFFSET+zx29spi->virtbase)) & (~SPI_COM_CTRL_MASK_SSPE);
 	writel(regval, (SPI_COM_CTRL_OFFSET+zx29spi->virtbase));
 	
@@ -2635,7 +2636,10 @@
 	if(diff_ns >= 10000000) {
 		dev_info(&zx29spi->pdev->dev, " zx29_setup_to_regs failed! diff_ns=%lld \n",diff_ns);
 	}
-	
+
+	if(false == zx29spi->master->slave)
+		pm_relax(&zx29spi->pdev->dev);
+    /* yu.dong@20240715 [T106BUG-641] SPI packet loss problem, merged into ZXW patch end */
 }
 /**
  * zx29_setup - setup function registered to SPI master framework
@@ -2821,7 +2825,10 @@
 		zx29_setup_to_regs(chip,zx29spi);
 	}
 
-        //yu.dong@20240617 [T106BUG-641] SPI packet loss problem, add kernel buffer scheme.
+	if(zx29spi->mode == ZX29_SSP_MASTER_TYPE) {
+		if(spi->setup_immediately == 1)
+			zx29_setup_to_regs(chip,zx29spi);
+	}
 
 	return status;
  err_config_params:
diff --git a/upstream/linux-5.10/drivers/spi/spidev.c b/upstream/linux-5.10/drivers/spi/spidev.c
index 1522a21..2a7cdbc 100755
--- a/upstream/linux-5.10/drivers/spi/spidev.c
+++ b/upstream/linux-5.10/drivers/spi/spidev.c
@@ -217,48 +217,30 @@
 		return -EMSGSIZE;
 
 	spidev = filp->private_data;
+    /* yu.dong@20240715 [T106BUG-641] SPI packet loss problem, merged into ZXW patch start */
+	if(spidev->spi->master->slave) {
+		#ifdef SPI_SLAVE_FOR_YK
+		size_t total = 0;
 
+		if (spidev->spi->rd_pos == spidev->spi->recv_pos) {
 
-
-	#ifdef SPI_SLAVE_FOR_YK
-	size_t total = 0;
-
-	if (spidev->spi->rd_pos == spidev->spi->recv_pos) {
-
-		status = 0;
-		spidev->spi->is_rd_waiting = true;
-		if(0 != wait_event_freezable(spidev->spi->rd_wait, spidev->spi->recv_done)) {
-			if(spidev->spi->controller->spi_slave_rd_stop)
-				spidev->spi->controller->spi_slave_rd_stop(spidev->spi);
-			spidev->spi->is_rd_waiting = false;
-			return 	status;
-		}else {
-			spidev->spi->recv_done = false;
-			spidev->spi->is_rd_waiting = false;
+			status = 0;
+			spidev->spi->is_rd_waiting = true;
+			if(0 != wait_event_freezable(spidev->spi->rd_wait, spidev->spi->recv_done)) {
+				if(spidev->spi->controller->spi_slave_rd_stop)
+					spidev->spi->controller->spi_slave_rd_stop(spidev->spi);
+				spidev->spi->is_rd_waiting = false;
+				return 	status;
+			}else {
+				spidev->spi->recv_done = false;
+				spidev->spi->is_rd_waiting = false;
+			}
 		}
-	}
-	mutex_lock(&spidev->buf_lock);
-	if(spidev->spi->rd_pos < spidev->spi->recv_pos) {
+		mutex_lock(&spidev->buf_lock);
+		if(spidev->spi->rd_pos < spidev->spi->recv_pos) {
 
-		total = spidev->spi->recv_pos - spidev->spi->rd_pos;
-		status = (total > count) ? count : total;
-	
-		missing = copy_to_user(buf, spidev->rx_buffer+spidev->spi->rd_pos, status);
-		if (missing == status) {
-			status = -EFAULT;
-		}
-		else {
-			status = status - missing;
-			spidev->spi->rd_pos += status;
-		}
-
-	}else if(spidev->spi->rd_pos > spidev->spi->recv_pos) {
-
-		total = bufsiz - (spidev->spi->rd_pos - spidev->spi->recv_pos);
-		status = (total > count) ? count : total;
-
-		if((spidev->spi->rd_pos + status) <= bufsiz) {
-
+			total = spidev->spi->recv_pos - spidev->spi->rd_pos;
+			status = (total > count) ? count : total;
 			missing = copy_to_user(buf, spidev->rx_buffer+spidev->spi->rd_pos, status);
 			if (missing == status) {
 				status = -EFAULT;
@@ -266,48 +248,81 @@
 			else {
 				status = status - missing;
 				spidev->spi->rd_pos += status;
-				spidev->spi->rd_pos = spidev->spi->rd_pos%bufsiz;
-			}
-		}else {
-
-			unsigned long first,rest;
-
-			first = bufsiz - spidev->spi->rd_pos;
-			missing = copy_to_user(buf, spidev->rx_buffer+spidev->spi->rd_pos, first);
-			if (missing == first) {
-				status = -EFAULT;
-			} else {
-				status = status - missing;
 			}
 
-			rest = status-first;
-			missing = copy_to_user(buf+first, spidev->rx_buffer, rest);
-			if (missing == rest) {
-				status = -EFAULT;
-			} else {
-				status = status - missing;
+		}else if(spidev->spi->rd_pos > spidev->spi->recv_pos) {
+
+			total = bufsiz - (spidev->spi->rd_pos - spidev->spi->recv_pos);
+			status = (total > count) ? count : total;
+
+			if((spidev->spi->rd_pos + status) <= bufsiz) {
+
+				missing = copy_to_user(buf, spidev->rx_buffer+spidev->spi->rd_pos, status);
+				if (missing == status) {
+					status = -EFAULT;
+				}
+				else {
+					status = status - missing;
+					spidev->spi->rd_pos += status;
+					spidev->spi->rd_pos = spidev->spi->rd_pos%bufsiz;
+				}
+			}else {
+
+				unsigned long first,rest;
+
+				first = bufsiz - spidev->spi->rd_pos;
+				missing = copy_to_user(buf, spidev->rx_buffer+spidev->spi->rd_pos, first);
+				if (missing == first) {
+					status = -EFAULT;
+				} else {
+					status = status - missing;
+				}
+
+				rest = status-first;
+				missing = copy_to_user(buf+first, spidev->rx_buffer, rest);
+				if (missing == rest) {
+					status = -EFAULT;
+				} else {
+					status = status - missing;
+				}
+				spidev->spi->rd_pos = rest;
 			}
-			spidev->spi->rd_pos = rest;
 		}
-	}
-	#else
-	mutex_lock(&spidev->buf_lock);
-	if(spidev->rd_from_rx_buffer) 
-		status = count;
-	else 
-		status = spidev_sync_read(spidev, count);
-	
-	if (status > 0) {
-
-		missing = copy_to_user(buf, spidev->rx_buffer, status);
-		if (missing == status)
-			status = -EFAULT;
+		#else
+		mutex_lock(&spidev->buf_lock);
+		if(spidev->rd_from_rx_buffer)
+			status = count;
 		else
-			status = status - missing;
-	}
-	#endif
-	mutex_unlock(&spidev->buf_lock);
+			status = spidev_sync_read(spidev, count);
 
+		if (status > 0) {
+
+			missing = copy_to_user(buf, spidev->rx_buffer, status);
+			if (missing == status)
+				status = -EFAULT;
+			else
+				status = status - missing;
+		}
+		#endif
+		mutex_unlock(&spidev->buf_lock);
+    }else {
+		mutex_lock(&spidev->buf_lock);
+
+		if(spidev->rd_from_rx_buffer) 
+			status = count;
+		else
+			status = spidev_sync_read(spidev, count);
+
+		if(status > 0) {
+			missing = copy_to_user(buf, spidev->rx_buffer, status);
+			if (missing == status)
+				status = -EFAULT;
+			else
+				status = status - missing;
+		}
+		mutex_unlock(&spidev->buf_lock);
+	}
+    /* yu.dong@20240715 [T106BUG-641] SPI packet loss problem, merged into ZXW patch end */
 	return status;
 }
 /* yu.dong@20240617 [T106BUG-641] SPI packet loss problem, add kernel buffer scheme end*/
@@ -783,15 +798,19 @@
 		}
 	}
 
-        /* yu.dong@20240617 [T106BUG-641] SPI packet loss problem, add kernel buffer scheme start */
-	#ifdef SPI_SLAVE_FOR_YK
-	if(spidev->rx_buffer) {
-		spidev->spi->rx_buf = spidev->rx_buffer;
-		if(spidev->spi->controller->spi_slave_rd_start)
-			spidev->spi->controller->spi_slave_rd_start(spidev->spi);
-	}
-	#endif
-        /* yu.dong@20240617 [T106BUG-641] SPI packet loss problem, add kernel buffer scheme end */
+    /* yu.dong@20240715 [T106BUG-641] SPI packet loss problem, merged into ZXW patch start */
+    /* yu.dong@20240617 [T106BUG-641] SPI packet loss problem, add kernel buffer scheme start */
+	if(spidev->spi->master->slave) {
+		#ifdef SPI_SLAVE_FOR_YK
+		if(spidev->rx_buffer) {
+			spidev->spi->rx_buf = spidev->rx_buffer;
+			if(spidev->spi->controller->spi_slave_rd_start)
+				spidev->spi->controller->spi_slave_rd_start(spidev->spi);
+		}
+		#endif
+    }
+    /* yu.dong@20240617 [T106BUG-641] SPI packet loss problem, add kernel buffer scheme end */
+    /* yu.dong@20240715 [T106BUG-641] SPI packet loss problem, merged into ZXW patch end */
 	spidev->users++;
 	filp->private_data = spidev;
 	stream_open(inode, filp);
@@ -838,14 +857,18 @@
 		spi = spi_dev_get(spidev->spi);
 		spin_unlock_irq(&spidev->spi_lock);
 
-                /* yu.dong@20240617 [T106BUG-641] SPI packet loss problem, add kernel buffer scheme start */
-		#ifdef SPI_SLAVE_FOR_YK
-		if(spidev->rx_buffer) {
-			if(spi->controller->spi_slave_rd_stop)
-				spi->controller->spi_slave_rd_stop(spi);
-		}
-		#endif

-                /* yu.dong@20240617 [T106BUG-641] SPI packet loss problem, add kernel buffer scheme end */
+        /* yu.dong@20240715 [T106BUG-641] SPI packet loss problem, merged into ZXW patch start */
+        /* yu.dong@20240617 [T106BUG-641] SPI packet loss problem, add kernel buffer scheme start */
+        if(spidev->spi->master->slave) {
+			#ifdef SPI_SLAVE_FOR_YK
+			if(spidev->rx_buffer) {
+				if(spi->controller->spi_slave_rd_stop)
+					spi->controller->spi_slave_rd_stop(spi);
+			}
+			#endif
+        }
+        /* yu.dong@20240617 [T106BUG-641] SPI packet loss problem, add kernel buffer scheme end */
+        /* yu.dong@20240715 [T106BUG-641] SPI packet loss problem, merged into ZXW patch end*/
 		if(spi && spi->master->slave) 
 			pm_relax(&spi->dev);
 		kfree(spidev->tx_buffer);
@@ -2257,7 +2280,14 @@
 		dev_info(&spi->dev,"trans_gap_num = 0x%x",val);
 	}
 
-	// yu.dong@20240617 [T106BUG-641] SPI packet loss problem, add kernel buffer scheme.
+	if (device_property_read_u32(&spi->dev, "setup-immediately",&val)) {
+		spi->setup_immediately = 0;
+		dev_err(&spi->dev,"setup-immediately get failed");
+	}
+	else {
+		spi->setup_immediately = val;
+		dev_info(&spi->dev,"setup-immediately = 0x%x",val);
+	}
 
 	/* If we can allocate a minor number, hook up this device.
 	 * Reusing minors is fine so long as udev or mdev is working.
diff --git a/upstream/linux-5.10/drivers/tty/serial/zx29_uart.c b/upstream/linux-5.10/drivers/tty/serial/zx29_uart.c
index 60629b6..b29437a 100755
--- a/upstream/linux-5.10/drivers/tty/serial/zx29_uart.c
+++ b/upstream/linux-5.10/drivers/tty/serial/zx29_uart.c
@@ -124,6 +124,7 @@
 	bool			queued;
 	atomic_t		count;
 };
+#define UART_DEBUG_RECORDER_BYTE 0
 #define UART_DMA_CYCLE_RX_CONFIG_COUNT 5
 struct zx29_dma_cycle_data{
 	int id;
@@ -140,8 +141,13 @@
 	int cnt_th;
 	struct zx29_sgbuf sgbuf[UART_DMA_CYCLE_RX_CONFIG_COUNT];
 	dma_channel_def rxdef[UART_DMA_CYCLE_RX_CONFIG_COUNT];
+	bool enter_throttle;
+	bool from_unthrottle;
+	bool used;
+	unsigned int cnt_throttle;
+	unsigned int cnt_unthrottle;
 };
-struct zx29_dma_cycle_data uart_dma_cycle[5];
+struct zx29_dma_cycle_data uart_dma_cycle[6];
 #endif
 
 
@@ -279,27 +285,29 @@
 	unsigned int ris;
 }uart_static;
 #define STATIC_UART_ID  0
-uart_static g_uart_static[256] = {0};
-int g_uart_static_cnt = 0;
-void test_uart_static(int uart_id, char *buf, int cnt, int steps)
+#define UART_STATIC_COUNT 512
+#define UART_STATIC_NUM 4
+uart_static g_uart_static[UART_STATIC_NUM][UART_STATIC_COUNT] = {0};
+int g_uart_static_cnt[UART_STATIC_NUM] = {0};
+void test_uart_static(int uart_id, char *buf, unsigned int cnt, int steps)
 {
-	if(uart_id != STATIC_UART_ID)
-		return;
+	//if(uart_id != STATIC_UART_ID)
+	//	return;
 	if(buf){
 		if(cnt >= 16){
-			strncpy(g_uart_static[g_uart_static_cnt].head, buf, 16);
+			memcpy(g_uart_static[uart_id][g_uart_static_cnt[uart_id]].head, buf, 16);
 		}else{
-			memcpy(g_uart_static[g_uart_static_cnt].head, buf, cnt);
+			memcpy(g_uart_static[uart_id][g_uart_static_cnt[uart_id]].head, buf, cnt);
 		}
 	}
-	g_uart_static[g_uart_static_cnt].cnt = cnt;
-	g_uart_static[g_uart_static_cnt].s_time = local_clock();
-	g_uart_static[g_uart_static_cnt].func_step = steps;	
-	g_uart_static[g_uart_static_cnt].fr = UART_GET_FR(&zx29_uart_ports[uart_id].port);	
-	g_uart_static[g_uart_static_cnt].ris = UART_GET_RIS(&zx29_uart_ports[uart_id].port);
+	g_uart_static[uart_id][g_uart_static_cnt[uart_id]].cnt = cnt;
+	g_uart_static[uart_id][g_uart_static_cnt[uart_id]].s_time = local_clock();
+	g_uart_static[uart_id][g_uart_static_cnt[uart_id]].func_step = steps;	
+	g_uart_static[uart_id][g_uart_static_cnt[uart_id]].fr = UART_GET_FR(&zx29_uart_ports[uart_id].port);	
+	g_uart_static[uart_id][g_uart_static_cnt[uart_id]].ris = UART_GET_RIS(&zx29_uart_ports[uart_id].port);
 
-	if(++g_uart_static_cnt >= 256)
-		g_uart_static_cnt = 0;
+	if(++g_uart_static_cnt[uart_id] >= UART_STATIC_COUNT)
+		g_uart_static_cnt[uart_id] = 0;
 }
 
 
@@ -975,6 +983,19 @@
 }
 
 #if CONFIG_SERIAL_ZX29_DMA
+#if UART_DEBUG_RECORDER_BYTE
+#define UART_DRIVER_DEBUG_COUNT (4*1024*1024)
+u32 cnt_uart_driver_debug = 0;
+u8 uart_driver_debug[UART_DRIVER_DEBUG_COUNT]={};
+void uart_debug(char *debug_buf, u32 count){
+	if(cnt_uart_driver_debug > (UART_DRIVER_DEBUG_COUNT-1)){
+		cnt_uart_driver_debug = 0;
+	}else{
+		memcpy(uart_driver_debug+cnt_uart_driver_debug,debug_buf,count);
+		cnt_uart_driver_debug = cnt_uart_driver_debug+count;
+	}	
+}
+#endif
 int dma_complete_thread_use_dma_cyclic(void *ptr)
 {
 	unsigned long flags;
@@ -986,8 +1007,14 @@
 	int uart_id = zup->port.line;
 	while(down_interruptible(&zup->sema_cyclic) == 0)
 	{	
+		if(uart_dma_cycle[zup->port.line].cnt_callback > 0)
+			uart_id = zup->port.line;
+		else if(uart_dma_cycle[zup->port.line+3].cnt_callback > 0)
+			uart_id = zup->port.line + 3;
+		
 		if(zup->port_close || !uart_dma_cycle[uart_id].sgbuf[uart_dma_cycle[uart_id].flg_enter_th].dma_addr)
 			break;
+		
 		spin_lock_irqsave(&zup->port.lock, flags);
 		uart_dma_cycle[uart_id].cnt_th_total++;
 		uart_dma_cycle[uart_id].cnt_th++;
@@ -1005,6 +1032,10 @@
 		spin_unlock_irqrestore(&zup->port.lock, flags);
 		dma_count = tty_insert_flip_string(&zup->port.state->port,
 						   zup->sg2tty->buf, pending);
+		test_uart_static(zup->port.line, zup->sg2tty->buf, uart_dma_cycle[zup->port.line].used, 27);
+#if UART_DEBUG_RECORDER_BYTE
+		uart_debug(zup->sg2tty->buf, pending);
+#endif
 		tty_flip_buffer_push(&zup->port.state->port);
 		spin_lock_irqsave(&zup->port.lock, flags);		
 		dma_sync_sg_for_device(dev, &zup->sg2tty->sg, 1, DMA_FROM_DEVICE);
@@ -1591,6 +1622,10 @@
 		printk("[%s][%d]\n",__func__,__LINE__);
 		return -EIO;
 	}
+	
+	if(uart_dma_cycle[zup->port.line].used)
+		uart_id = uart_id + 3;
+	
 	dmaengine_slave_config(rxchan, (struct dma_slave_config*)&uart_dma_cycle[uart_id].rxdef);
 	desc = rxchan->device->device_prep_dma_cyclic(rxchan,NULL,(ZX29_DMA_BUFFER_SIZE *5) , ZX29_DMA_BUFFER_SIZE,0,0);
 	if (!desc) {
@@ -1607,6 +1642,14 @@
 	zup->dmacr |= UART_RXDMAE;
 	UART_PUT_DMACR(&zup->port, zup->dmacr);
 	uart_dma_cycle[uart_id].flg_enter_th = 0;
+	if(uart_dma_cycle[zup->port.line].used){
+		uart_dma_cycle[zup->port.line].used = false;
+		uart_dma_cycle[zup->port.line+3].used = true;
+	}else{
+		uart_dma_cycle[zup->port.line].used = true;
+		uart_dma_cycle[zup->port.line+3].used = false;		
+	}
+
 	zup->dmarx.running = true;
 	zup->dmarx.used = true;
 	zup->imr &= ~(UART_RXIM | UART_RTIM);
@@ -1692,6 +1735,8 @@
 	unsigned int ris_status;
 	int uart_id = zup->port.line;
 	spin_lock_irqsave(&zup->port.lock, flags);
+	if(!uart_dma_cycle[zup->port.line].used)
+		uart_id = uart_id + 3;
 	uart_dma_cycle[uart_id].cnt_callback_total++;
 	uart_dma_cycle[uart_id].cnt_callback++;
 	ris_status = UART_GET_RIS(&zup->port);
@@ -2050,6 +2095,9 @@
 		dma_count = tty_insert_flip_string(&zup->port.state->port,
 						   sgbuf->buf, pending);
 		test_uart_static(zup->port.line, sgbuf->buf, pending, 6);
+#if UART_DEBUG_RECORDER_BYTE
+		uart_debug(sgbuf->buf, pending);
+#endif
 		spin_lock_irqsave(&zup->port.lock, *flags);	 	
 		dma_sync_sg_for_device(dev, &sgbuf->sg, 1, DMA_FROM_DEVICE);
 		zup->port.icount.rx += dma_count;
@@ -2061,6 +2109,10 @@
 		spin_unlock_irqrestore(&zup->port.lock, *flags);
 			fifo_count = tty_insert_flip_string(&zup->port.state->port,
 							   fifo_buf, fifo_len);
+			test_uart_static(zup->port.line, fifo_buf, fifo_len, 50);
+#if UART_DEBUG_RECORDER_BYTE
+			uart_debug(fifo_buf, fifo_len);
+#endif
 			fifo_buf[0] = '\0';
 			fifo_buf[1] = '\0';
 			fifo_buf[2] = '\0';
@@ -2070,6 +2122,7 @@
 	if(((pending) && (pending != 4096)) || (fifo_len > 0)){
 		spin_unlock(&zup->port.lock);
 		tty_flip_buffer_push(&zup->port.state->port);
+		test_uart_static(zup->port.line, NULL, (fifo_count+dma_count), 51);
 		spin_lock(&zup->port.lock);	
 	}
 }
@@ -2647,40 +2700,53 @@
 	unsigned long flags;
 	struct zx29_sgbuf *sgbuf = NULL;
 	int uart_id = zup->port.line;
+
+	
 	if(!zx29_dma_rx_running(zup))
 		return HRTIMER_NORESTART;
-	if(uart_dma_cycle[uart_id].cnt_callback > 0){
+	raw_spin_lock_irqsave(&zup->port.lock, flags);	
+	
+	if((uart_dma_cycle[zup->port.line].cnt_callback > 0) || (uart_dma_cycle[zup->port.line+3].cnt_callback > 0)){
+		test_uart_static(zup->port.line, NULL, uart_dma_cycle[zup->port.line].used, 46);
+		raw_spin_unlock_irqrestore(&zup->port.lock, flags);
 		return HRTIMER_NORESTART;
 	}
 	
-	spin_lock_irqsave(&zup->port.lock, flags);	
+	if(!uart_dma_cycle[zup->port.line].used)
+		uart_id = uart_id + 3;
+			
 	sgbuf = &uart_dma_cycle[uart_id].sgbuf[uart_dma_cycle[uart_id].flg_enter_th];
 	if(zup->port_close || (sgbuf == NULL)){
-		spin_unlock_irqrestore(&zup->port.lock, flags);
-		return HRTIMER_RESTART;
+		raw_spin_unlock_irqrestore(&zup->port.lock, flags);
+		return HRTIMER_NORESTART;
 	}
 	if(zup->sema_cyclic.count > 0){
 		printk("uart has th not deal.\n");
-		spin_unlock_irqrestore(&zup->port.lock, flags);
+		//test_uart_static(zup->port.line, NULL, uart_id, 11);
+		raw_spin_unlock_irqrestore(&zup->port.lock, flags);
+		hrtimer_forward_now(&zup->rx_dma_hrtimer, g_hr_interval);
 		return HRTIMER_RESTART;
 	}
+	
 	if((zup->sg2tty)){//dma not complete now, later check again
 		printk("dmath_cyclic not end.\n");
-		spin_unlock_irqrestore(&zup->port.lock, flags);
+		raw_spin_unlock_irqrestore(&zup->port.lock, flags);
 		test_uart_static(zup->port.line, NULL, 0, 14);
 		hrtimer_forward_now(&zup->rx_dma_hrtimer, g_hr_interval);
 		return HRTIMER_RESTART;
 	}
-	if(zup->enter_suspend){
-		spin_unlock_irqrestore(&zup->port.lock, flags);
+	if(zup->enter_suspend || uart_dma_cycle[uart_id].enter_throttle){
+		raw_spin_unlock_irqrestore(&zup->port.lock, flags);
 		test_uart_static(zup->port.line, NULL, 0, 15);
 		hrtimer_forward_now(&zup->rx_dma_hrtimer, g_hr_interval);
 		return HRTIMER_RESTART;
 	}
 	dma_peripheral_id rx_id = uart_get_rx_dma_peripheral_id(zup);
 	pending = sgbuf->sg.length - zx29_dma_get_transfer_num(rx_id);
-	if(((pending == zup->pre_pending) && pending) || uart_dma_cycle[uart_id].from_resume){
+	if(((pending == zup->pre_pending) && pending) || uart_dma_cycle[uart_id].from_resume 
+		|| uart_dma_cycle[uart_id].from_unthrottle){
 		uart_dma_cycle[uart_id].from_resume = 0;
+		uart_dma_cycle[uart_id].from_unthrottle = false;
 #if 0
 	if(uart_dma_cycle[uart_id].flg_enter_th == 0)
 		uart_dma_cycle[uart_id].flg_enter_to = 4;
@@ -2723,24 +2789,28 @@
 		zup->dmacr &= ~UART_RXDMAE;
 		UART_PUT_DMACR(&zup->port,zup->dmacr);
 		dmaengine_terminate_all(rxchan);
-		test_uart_static(zup->port.line, NULL, 0, 60);
 		zup->dmarx.running = false;
 		zup->dmarx.used = false;
+		tmp_len = sgbuf->sg.length - zx29_dma_get_transfer_num(rx_id);
+		if(tmp_len != pending){
+			pending = tmp_len;
+			//test_uart_static(zup->port.line, NULL, tmp_len, 48);
+		}
 		wmb();		
 		int i = 0;
 		for(i= 0;i < 3;i++){
 			fr = UART_GET_FR(&zup->port);
 			if((fr & UART_FR_RXFE) == 0){
-				g_fifo_residue_buf[uart_id][i] = UART_GET_CHAR(&zup->port) |	UART_DUMMY_DR_RX;
-				g_fifo_residue_all[uart_id][g_fifo_cnt[uart_id]++] = g_fifo_residue_buf[uart_id][i];
-				if(g_fifo_cnt[uart_id] >= 20)	g_fifo_cnt[uart_id] = 0;
+				g_fifo_residue_buf[zup->port.line][i] = UART_GET_CHAR(&zup->port) |	UART_DUMMY_DR_RX;
+				g_fifo_residue_all[zup->port.line][g_fifo_cnt[zup->port.line]++] = g_fifo_residue_buf[zup->port.line][i];
+				if(g_fifo_cnt[zup->port.line] >= 20)	g_fifo_cnt[zup->port.line] = 0;
 			}	
 			else
 				break;
 		}	
 		if(i){
-			g_fifo_residue_all[uart_id][g_fifo_cnt[uart_id]++]=i;
-			if(g_fifo_cnt[uart_id] >= 20)	g_fifo_cnt[uart_id] = 0;
+			g_fifo_residue_all[zup->port.line][g_fifo_cnt[zup->port.line]++]=i;
+			if(g_fifo_cnt[zup->port.line] >= 20)	g_fifo_cnt[zup->port.line] = 0;
 		}
 		if (zx29_dma_rx_trigger_dma_use_dma_cyclic(zup)) {
 			printk("rx_dma_chars RXDMA start fail\n");
@@ -2748,20 +2818,21 @@
 			UART_PUT_IMSC(&zup->port,zup->imr);
 		}else{
 			hrtimer_forward_now(&zup->rx_dma_hrtimer, g_hr_interval);
+			test_uart_static(zup->port.line, NULL, (pending+i), 49);
 			zup->pre_pending = 0;
 			zup->dmarx.used = true;
 			zup->work_state = true;
 		}
 		if((pending && (pending != 4096)) || (i > 0)){
-			zx29_uart_deal_dma_fifo_rx_chars_cyclic(zup, pending, sgbuf, &flags, g_fifo_residue_buf[uart_id],i);
+			zx29_uart_deal_dma_fifo_rx_chars_cyclic(zup, pending, sgbuf, &flags, g_fifo_residue_buf[zup->port.line],i);
 		}	
 		uart_dma_cycle[uart_id].cnt_th = 0;
 		uart_dma_cycle[uart_id].cnt_callback=0;
 deal_end:		
-		spin_unlock_irqrestore(&zup->port.lock, flags);
+		raw_spin_unlock_irqrestore(&zup->port.lock, flags);
 		return HRTIMER_RESTART;
 	}else{
-		spin_unlock_irqrestore(&zup->port.lock, flags);
+		raw_spin_unlock_irqrestore(&zup->port.lock, flags);
 		zup->pre_pending = pending;
 		hrtimer_forward_now(&zup->rx_dma_hrtimer, g_hr_interval);
 		test_uart_static(zup->port.line, NULL, zup->pre_pending, 22);
@@ -3005,14 +3076,34 @@
 			}
 			return -1;
 		}
+		
+		ret = zx29_sgbuf_init(zup->dmarx.chan, &uart_dma_cycle[uart_id+3].sgbuf[i],DMA_FROM_DEVICE);
+		if(ret){
+			printk( "init uart_dma_cycle sgbuf failed,uart: %d,ret:%d\n", (zup->port.line+3), ret);
+			for(j=0;j<i;j++){
+				zx29_sgbuf_free(zup->dmarx.chan, &uart_dma_cycle[uart_id+3].sgbuf[j],DMA_FROM_DEVICE);
+			}
+			return -1;
+		}
 	}
 	for(i=0;i<UART_DMA_CYCLE_RX_CONFIG_COUNT;i++){
-		if(zup->port.line == UART0)
+		if(zup->port.line == UART0){
 			uart_dma_cycle[uart_id].rxdef[i].src_addr	= ZX_UART0_BASE+zx29_UART_DR;
-		else if(zup->port.line == UART1)
+			uart_dma_cycle[uart_id].used = false;
+			uart_dma_cycle[uart_id+3].rxdef[i].src_addr	= ZX_UART0_BASE+zx29_UART_DR;
+			uart_dma_cycle[uart_id+3].used = false;
+		}	
+		else if(zup->port.line == UART1){
 			uart_dma_cycle[uart_id].rxdef[i].src_addr	= ZX_UART1_BASE+zx29_UART_DR;
-		else{
+			uart_dma_cycle[uart_id].used = false;
+			uart_dma_cycle[uart_id+3].rxdef[i].src_addr	= ZX_UART1_BASE+zx29_UART_DR;
+			uart_dma_cycle[uart_id+3].used = false;			
+		}
+		else if(zup->port.line == UART2){
 			uart_dma_cycle[uart_id].rxdef[i].src_addr	= ZX_UART2_BASE+zx29_UART_DR;
+			uart_dma_cycle[uart_id].used = false;
+			uart_dma_cycle[uart_id+3].rxdef[i].src_addr	= ZX_UART2_BASE+zx29_UART_DR;
+			uart_dma_cycle[uart_id+3].used = false;	
 		}
 		uart_dma_cycle[uart_id].rxdef[i].dest_addr = (unsigned int)(uart_dma_cycle[uart_id].sgbuf[i].dma_addr);
 		uart_dma_cycle[uart_id].rxdef[i].dma_control.tran_mode = TRAN_PERI_TO_MEM;
@@ -3022,7 +3113,18 @@
 		uart_dma_cycle[uart_id].rxdef[i].dma_control.dest_burst_size = DMA_BURST_SIZE_8BIT;
 		uart_dma_cycle[uart_id].rxdef[i].dma_control.dest_burst_len	= DMA_BURST_LEN_4;
 		uart_dma_cycle[uart_id].rxdef[i].dma_control.irq_mode		= DMA_ALL_IRQ_ENABLE;
-		uart_dma_cycle[uart_id].rxdef[i].link_addr		= 1;	
+		uart_dma_cycle[uart_id].rxdef[i].link_addr		= 1;
+
+		uart_dma_cycle[uart_id+3].rxdef[i].dest_addr = (unsigned int)(uart_dma_cycle[uart_id+3].sgbuf[i].dma_addr);
+		uart_dma_cycle[uart_id+3].rxdef[i].dma_control.tran_mode = TRAN_PERI_TO_MEM;
+		uart_dma_cycle[uart_id+3].rxdef[i].dma_control.src_burst_len	= DMA_BURST_LEN_4;
+		uart_dma_cycle[uart_id+3].rxdef[i].count		= ZX29_DMA_BUFFER_SIZE;
+		uart_dma_cycle[uart_id+3].rxdef[i].dma_control.src_burst_size = DMA_BURST_SIZE_8BIT;
+		uart_dma_cycle[uart_id+3].rxdef[i].dma_control.dest_burst_size = DMA_BURST_SIZE_8BIT;
+		uart_dma_cycle[uart_id+3].rxdef[i].dma_control.dest_burst_len = DMA_BURST_LEN_4;
+		uart_dma_cycle[uart_id+3].rxdef[i].dma_control.irq_mode		= DMA_ALL_IRQ_ENABLE;
+		uart_dma_cycle[uart_id+3].rxdef[i].link_addr		= 1;
+
 	}	
 	return 0;
 }
@@ -3032,8 +3134,10 @@
 	int uart_id = zup->port.line;
 	for(i=0;i<UART_DMA_CYCLE_RX_CONFIG_COUNT;i++){
 		zx29_sgbuf_free(zup->dmarx.chan, &uart_dma_cycle[uart_id].sgbuf[i],DMA_FROM_DEVICE);
+		zx29_sgbuf_free(zup->dmarx.chan, &uart_dma_cycle[uart_id+3].sgbuf[i],DMA_FROM_DEVICE);
 	}
 	memset(uart_dma_cycle[uart_id].rxdef, 0, sizeof(uart_dma_cycle[uart_id].rxdef));
+	memset(uart_dma_cycle[uart_id+3].rxdef, 0, sizeof(uart_dma_cycle[uart_id+3].rxdef));
 }
 static void uart_dma_startup(struct zx29_uart_port *zup)
 {
@@ -3461,6 +3565,9 @@
 	//struct zx29_uart_platdata *pdata = pdev->dev.platform_data;
 #if CONFIG_SERIAL_ZX29_DMA
 	zup->port_close = true;
+	if(zup->uart_power_mode)
+		up(&zup->sema_cyclic);
+	else
 	up(&zup->sema);
 #endif
 	int ret;
@@ -3762,11 +3869,25 @@
 	UART_PUT_CHAR(port, ch);
 }
 #endif /* CONFIG_CONSOLE_POLL */
+extern int tty_buffer_space_avail(struct tty_port *port);
 static void zx29_uart_throttle_rx(struct uart_port *port)
 {
+	test_uart_static(port->line, NULL, 0, 80);
 	unsigned long flags;
+	int uart_id = port->line;
+
 	struct zx29_uart_port *zup = container_of(port, struct zx29_uart_port, port);
 	dma_peripheral_id rx_id = uart_get_rx_dma_peripheral_id(zup);
+	spin_lock_irqsave(&port->lock, flags);
+	if(!uart_dma_cycle[port->line].used)
+		uart_id = uart_id + 3;
+	if(!tty_buffer_space_avail(&port->state->port)){
+		zx29_dma_stop(DMA_CH_UART0_RX);
+		uart_dma_cycle[uart_id].enter_throttle = true;
+		uart_dma_cycle[uart_id].cnt_throttle++;
+	}	
+	spin_unlock_irqrestore(&port->lock, flags);
+	#if 0
 	while(zx29_dma_get_transfer_num(rx_id) != 4096)
 		msleep(1);
 	spin_lock_irqsave(&port->lock, flags);
@@ -3775,24 +3896,35 @@
 	zx29_dma_stop(rx_id);
 	zup->dmarx.running = false;
 	zup->dmarx.used = false;
+	uart_dma_cycle[port->line].enter_throttle = true; 
 	spin_unlock_irqrestore(&port->lock, flags);
+	#endif
 }
 static void zx29_uart_unthrottle_rx(struct uart_port *port)
 {
+	test_uart_static(port->line, NULL, 0, 81);
 	struct zx29_uart_port *zup = container_of(port, struct zx29_uart_port, port);
 	unsigned long flags;
+	int uart_id = port->line;
 	spin_lock_irqsave(&port->lock, flags);
-	if (zx29_dma_rx_trigger_dma(zup)) {
+	if(!uart_dma_cycle[port->line].used)
+		uart_id = uart_id + 3;
+	uart_dma_cycle[uart_id].enter_throttle = false;
+	uart_dma_cycle[uart_id].from_unthrottle = true;
+	uart_dma_cycle[uart_id].cnt_unthrottle++;
+	#if 0
+	if (zx29_dma_rx_trigger_dma_use_dma_cyclic(zup)) {
 		printk("rx_dma_chars RXDMA start fail\n");
 		zup->imr |= (UART_RTIM|UART_RXIM);
 		UART_PUT_IMSC(&zup->port,zup->imr);
 	}else{
-		uart_mod_timer(zup, &flags);
+		hrtimer_forward_now(&zup->rx_dma_hrtimer, g_hr_interval);
 		zup->pre_pending = 0;
 		zup->dmarx.used = true;
 		zup->work_state = true;
 		UART_PUT_ICR(&zup->port,(UART_RTIS|UART_RXIS));
 	}
+	#endif
 	spin_unlock_irqrestore(&port->lock, flags);
 }
 
@@ -3839,9 +3971,7 @@
 	unsigned int offset=(unsigned int)(pdev->id);
 	struct device_node *np = pdev->dev.of_node;
 	unsigned int baud, ibrd, fbrd;
-    /*cz.li add for uart1 2 change baudrate to 4M on 2023/8/15 start*/
-	unsigned int max_bus_clk;
-    /*cz.li add for uart1 2 change baudrate to 4M on 2023/8/15 end*/
+
 	struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	//struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);	
 
@@ -3865,12 +3995,6 @@
 		printk("failed to get zx29_port->wclk: %d\n", ret);
 		return ret;
 	}
-   /*cz.li add for uart1 2 change baudrate to 4M on 2023/8/15 start*/
-	if(0 == pdev->id || 2 == pdev->id){
-		device_property_read_u32(&pdev->dev, "uart-max-bus-freq", &max_bus_clk);
-		clk_set_rate(zx29_port->wclk, max_bus_clk);
-	}
-   /*cz.li add for uart1 2 change baudrate to 4M on 2023/8/15 end*/
 	if(offset == 0){
 	clk_set_rate(zx29_port->wclk, 104 * 1000000);
 	}
@@ -3900,11 +4024,6 @@
 	//here is temple def	
 	if(port->uartclk == 0){
 		printk("---zx29_init_ports,  uartclk hard set to 26M\n");
-        /*cz.li add for uart1 2 change baudrate to 4M on 2023/8/15 start*/
-		if(0 == pdev->id || 2 == pdev->id)
-			port->uartclk = 104000000;
-		else
-        /*cz.li add for uart1 2 change baudrate to 4M on 2023/8/15 end*/
 		port->uartclk = 26000000;
 	}
 	printk("---zx29_init_ports, line:%d, irq:%d, membase:%08x, uartclk:%d\n", port->line, port->irq, port->membase, port->uartclk);
@@ -4196,6 +4315,8 @@
 	if (!zup)
 		return -EINVAL;
 	int uart_id = zup->port.line;
+	if(!uart_dma_cycle[zup->port.line].used)
+		uart_id = uart_id + 3;
 	if(zup->port.line == UART1)
 		return 0;
 #if 1