[T106][ZXW-31]Submit the patch for dual-core P43 version to add UART1 console switching function.

Change-Id: Ie05094fa3486a2964d514c4254f92c8f344c2b16
diff --git a/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/include/mach/spinlock.h b/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/include/mach/spinlock.h
index c24480b..15c1875 100644
--- a/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/include/mach/spinlock.h
+++ b/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/include/mach/spinlock.h
@@ -244,5 +244,6 @@
  * Others:

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

  void  reg_spin_unlock(void);

+ int  soft_spin_lock_printf(emsf_lock_id sfid);

 #endif/*_SYS_H*/

 

diff --git a/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/spinlock.c b/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/spinlock.c
index 6aaf63c..e99382e 100644
--- a/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/spinlock.c
+++ b/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/spinlock.c
@@ -24,7 +24,7 @@
 #include <linux/cdev.h>

 #include <linux/fs.h>

 #include <linux/uaccess.h>

-

+#include <linux/delay.h>

 #define	USE_HW_SPINLOCK				1

 

 #if USE_HW_SPINLOCK

@@ -206,6 +206,33 @@
     //zspinlock_debug("cpu %d releases %d software lock!/n",SELF_CORE_ID,sfid);

 

 }

+#ifdef _USE_CAP_SYS

+int  soft_spin_lock_printf(emsf_lock_id sfid)

+{

+	static unsigned long lock_count = 0;

+softlock_loop:

+   	while(softlock_desc[sfid]->owner != SELF_CORE_ID && softlock_desc[sfid]->used)

+   	{

+   		ndelay(1);

+   		lock_count++;

+		if(lock_count >= 5000)

+		{

+			lock_count = 0;

+			return -1;

+		}

+   	}

+	_hw_spin_lock(SOFTLOCK_HWLOCK);

+	if(softlock_desc[sfid]->owner != SELF_CORE_ID && softlock_desc[sfid]->used)

+   	{

+	      _hw_spin_unlock(SOFTLOCK_HWLOCK);

+		goto softlock_loop;

+   	}

+    softlock_desc[sfid]->used ++;

+    softlock_desc[sfid]->owner = SELF_CORE_ID;

+    _hw_spin_unlock(SOFTLOCK_HWLOCK);

+	return 0;

+}

+#endif

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

  * Function: soft_spin_unlock

  * Description:Óësoft_spin_lock¶ÔÓ¦µÄÊÍ·ÅÈí¼þËø½Ó¿Ú¡£

diff --git a/ap/os/linux/linux-3.4.x/drivers/tty/serial/serial_core.c b/ap/os/linux/linux-3.4.x/drivers/tty/serial/serial_core.c
index 9fc2007..3b70883 100644
--- a/ap/os/linux/linux-3.4.x/drivers/tty/serial/serial_core.c
+++ b/ap/os/linux/linux-3.4.x/drivers/tty/serial/serial_core.c
@@ -582,7 +582,13 @@
 		ret += c;
 	}
 	raw_spin_unlock_irqrestore(&port->lock, flags);
-
+	#ifdef _USE_VEHICLE_DC
+	if(pdev->id == DEBUG_CONSOLE){
+		if(CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE) == 0){
+			ret  = count;
+		}
+	}
+#endif
 	uart_start(tty);
 	return ret;
 }
diff --git a/ap/os/linux/linux-3.4.x/drivers/tty/serial/zx29_uart.c b/ap/os/linux/linux-3.4.x/drivers/tty/serial/zx29_uart.c
index ba4a761..2dfa903 100755
--- a/ap/os/linux/linux-3.4.x/drivers/tty/serial/zx29_uart.c
+++ b/ap/os/linux/linux-3.4.x/drivers/tty/serial/zx29_uart.c
@@ -50,7 +50,9 @@
 
 #include "zx29_uart.h"
 #include <linux/soc/zte/pm/drv_idle.h>
+#include <linux/soc/zte/rpm/rpmsg.h>
 #include <mach/pcu.h>
+#include "../arch/arm/mach-zx297520v3/include/mach/spinlock.h"
 //#define DEBUG_UART
 
 #ifdef DEBUG_UART
@@ -208,7 +210,10 @@
 
 #define	zx29_MAXPORTS	ARRAY_SIZE(zx29_uart_ports)
 
-
+#ifdef _USE_CAP_SYS
+static void zx29_uart_console_putc(struct uart_port *port, const char c);
+static void zx29_uart_console_putc_printf(struct uart_port *port, int c);
+#endif
 
 void uart_mod_timer(struct zx29_uart_port *zup, unsigned long *flags)
 {
@@ -232,8 +237,8 @@
  * 1:  able console input, can input commands
  */
 static ssize_t console_input_store(struct device *_dev,
-				 struct device_attribute *attr,
-				 const char *buf, size_t count)
+				struct device_attribute *attr,
+				const char *buf, size_t count)
 {
     uint32_t  flag = 0;
 	flag = simple_strtoul(buf, NULL, 16);
@@ -255,8 +260,8 @@
 }
 
 static ssize_t ctsrts_input_store(struct device *_dev,
-				 struct device_attribute *attr,
-				 const char *buf, size_t count)
+				struct device_attribute *attr,
+				const char *buf, size_t count)
 {
     uint32_t  flag = 0;
 	struct platform_device *pdev = container_of(_dev, struct platform_device, dev);
@@ -280,8 +285,8 @@
 }
 
 static ssize_t wakeup_enable_store(struct device *_dev,
-				 struct device_attribute *attr,
-				 const char *buf, size_t count)
+				struct device_attribute *attr,
+				const char *buf, size_t count)
 {
     uint32_t  flag = 0;
 	struct platform_device *pdev = container_of(_dev, struct platform_device, dev);
@@ -312,6 +317,146 @@
 }
 DEVICE_ATTR(statics, S_IRUGO | S_IWUSR, statics_show, NULL);
 
+#ifdef _USE_CAP_SYS
+#define ICP_CORE_ID_PS 2
+#define ICP_CORE_ID_CAP CAP_ID
+#define ICP_CHANNEL_CONSOLE_UART channel_7
+#define ICP_MSG_LEN_CONSOLE_UART 2
+#define ICP_BUFFERSIZE_CONSOLE_TOGGLE 16
+#define SYMB_PS_CORE_ID ICP_CORE_ID_PS
+#define SYMB_CAP_CORE_ID ICP_CORE_ID_CAP
+#define SYMB_WHAT_CORE_ID 3
+#define ENABLE_CURRENT_CONSOLE_UART 1
+#define DISABLE_CURRENT_CONSOLE_UART 0
+#define ENABLE_TOGGLE 1
+#define DISABLE_TOGGLE 0
+unsigned char g_core_id_occupy_uart = 0;
+unsigned char g_ps_uart_toggle = 0;
+static irqreturn_t zx29_uart_interrupt(int irq, void *dev_id);
+static void restart_current_cons_uart(void)
+{
+	struct zx29_uart_port *zup = &zx29_uart_ports[DEBUG_CONSOLE];	
+	struct uart_port *port = &zup->port;
+	enable_irq(port->irq);
+	g_core_id_occupy_uart = SYMB_PS_CORE_ID;
+	spin_lock(&zup->port.lock);
+	tasklet_schedule(&zup->write_wakeup);
+	spin_unlock(&zup->port.lock);
+}
+static void forbid_current_cons_uart(void)
+{
+	struct zx29_uart_port *zup = &zx29_uart_ports[DEBUG_CONSOLE];	
+	struct uart_port *port = &zup->port;
+	disable_irq(port->irq);
+	g_core_id_occupy_uart = SYMB_CAP_CORE_ID;
+}
+static void process_cap2ps_rpmsg(char *arr)
+{
+	if((arr[0] == SYMB_PS_CORE_ID) && (arr[1] == ENABLE_CURRENT_CONSOLE_UART)){
+		restart_current_cons_uart();
+	}else if((arr[0] == SYMB_PS_CORE_ID) && (arr[1] == DISABLE_CURRENT_CONSOLE_UART)){
+		g_core_id_occupy_uart = SYMB_CAP_CORE_ID;
+		printk("current console uart not enable.\n");
+	}else{
+		printk("%s error!!\n",__func__);
+	}
+}
+static void icp_callback_cap2ps(void *buf, unsigned int len)
+{
+	char *arr_cap2ps;
+	if (len==0){
+		printk("%s empty.\n", __func__);
+		return ;
+	}	
+	arr_cap2ps = (char *)buf;
+	process_cap2ps_rpmsg(arr_cap2ps);
+}
+static void echo_to_change_ohter_uart(uint32_t val)
+{
+	int ret;
+	if(val > ENABLE_TOGGLE)
+	{
+		printk("echo para error!!!\n");
+		return;
+	}
+	char arr[2] = {0};
+	arr[0] = SYMB_CAP_CORE_ID;
+	arr[1] = val;
+    T_ZDrvRpMsg_Msg icp_msg;
+    icp_msg.actorID = CAP_ID;
+    icp_msg.chID 	= ICP_CHANNEL_CONSOLE_UART;
+    icp_msg.flag 	= RPMSG_WRITE_INT;		/* 1- means send an icp interrupt> */
+    icp_msg.buf 	= arr;
+    icp_msg.len 	= ICP_MSG_LEN_CONSOLE_UART;	
+	ret = zDrvRpMsg_Write_Cap(&icp_msg);
+	if(ret == ICP_MSG_LEN_CONSOLE_UART){
+		if(val == ENABLE_TOGGLE)
+			g_core_id_occupy_uart = 1;
+		else if(val == DISABLE_TOGGLE)
+			g_core_id_occupy_uart = 0;	
+	}else
+		printk("zDrvRpMsg_Write_Cap fail.\n");
+}
+static ssize_t console_uart_toggle_show(struct device *_dev,
+				struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "\n console_uart_toggle_show %d. \n", g_ps_uart_toggle);
+}
+static ssize_t console_uart_toggle_store(struct device *_dev,
+				struct device_attribute *attr,
+				const char *buf, size_t count)
+{
+    uint32_t  flag = 0;
+	flag = simple_strtoul(buf, NULL, 16);
+	if(flag == ENABLE_TOGGLE){
+		g_ps_uart_toggle = 1;
+		echo_to_change_ohter_uart(flag);
+		forbid_current_cons_uart();
+	}else if(flag == DISABLE_TOGGLE){
+		g_ps_uart_toggle = 0;
+	}
+	return count;
+}
+DEVICE_ATTR(console_uart_toggle, S_IRUGO | S_IWUSR, console_uart_toggle_show,
+	    console_uart_toggle_store);
+static void notify_occupy_uart_coreid_to_other(void)
+{
+	char arr[2] = {0};
+	arr[0] = SYMB_WHAT_CORE_ID;
+	arr[1] = g_core_id_occupy_uart;
+    T_ZDrvRpMsg_Msg icp_msg;
+    icp_msg.actorID = CAP_ID;
+    icp_msg.chID 	= ICP_CHANNEL_CONSOLE_UART;
+    icp_msg.flag 	= RPMSG_WRITE_INT;		/* 1- means send an icp interrupt> */
+    icp_msg.buf 	= arr;
+    icp_msg.len 	= ICP_MSG_LEN_CONSOLE_UART;	
+	zDrvRpMsg_Write_Cap(&icp_msg);
+}
+static ssize_t coreid_occupy_uart_show(struct device *_dev,
+				struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "\n core %d occupy cons uart now! \n",g_core_id_occupy_uart);
+}
+static ssize_t coreid_occupy_uart_store(struct device *_dev,
+				struct device_attribute *attr,
+				const char *buf, size_t count)
+{
+    uint32_t  flag = 0;
+	flag = simple_strtoul(buf, NULL, 16);
+	g_core_id_occupy_uart = flag;
+	if(flag == SYMB_PS_CORE_ID){
+		g_ps_uart_toggle = 0;
+		notify_occupy_uart_coreid_to_other();
+	}else if(SYMB_CAP_CORE_ID){
+		g_ps_uart_toggle = 1;
+		notify_occupy_uart_coreid_to_other();
+		forbid_current_cons_uart();
+	}
+	return count;
+}
+DEVICE_ATTR(coreid_occupy_uart, S_IRUGO | S_IWUSR, coreid_occupy_uart_show,
+	    coreid_occupy_uart_store);
+#endif
 
 #if CONFIG_SERIAL_ZX29_DMA
 static inline bool zx29_dma_tx_start(struct zx29_uart_port *zup);
@@ -479,14 +624,46 @@
 	unsigned int reg_bak[10] = {0};
 	struct circ_buf *xmit = &zup->port.state->xmit;
 	int count = 0;	
-#if 0
-	if(uart_console(port) && !g_console_open_flag){
+
+
+#ifdef _USE_VEHICLE_DC
+	if((port->line == DEBUG_CONSOLE))
+	{
+		if(g_core_id_occupy_uart == SYMB_CAP_CORE_ID){
+		#if 1
+			count = uart_circ_chars_pending(xmit);
+			while(count-- > 0) 
+			{
+				xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+				if (uart_circ_empty(xmit))
+					break;
+			}
+		#endif
+			return;
+		}
 		count = uart_circ_chars_pending(xmit);
-		xmit->tail = xmit->head;
-		zup->port.icount.tx += count;
+		while(count-- > 0) 
+		{
+			zx29_uart_console_putc_printf(&zup->port, xmit->buf[xmit->tail]);
+			xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+			zup->port.icount.tx++;
+			if (uart_circ_empty(xmit)){
+				break;
+			}
+		}
+
+		if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+		{
+			spin_lock(&zup->port.lock);
+			tasklet_schedule(&zup->write_wakeup);
+			spin_unlock(&zup->port.lock);
+			return;
+		}
 		return;
 	}
+else
 #endif
+{
 	if(!(UART_GET_RIS(port)&UART_TXIS) && (UART_GET_FR(port) & UART_FR_TXFE))
 	{
 		if(!(UART_GET_RIS(port)&UART_TXIS))	
@@ -505,10 +682,11 @@
 		}
 
 	}
+	}
 #if CONFIG_SERIAL_ZX29_DMA	 
 	if(!uart_console(port))
-	 { 
-		 if (!zx29_dma_tx_start(zup))
+	{ 
+		if (!zx29_dma_tx_start(zup))
 		   	{
 				zup->imr |= UART_TXIM;
 				UART_PUT_IMSC(port, zup->imr);
@@ -609,7 +787,7 @@
 		      //printk("yanming dma_complete_thread, dma2tty:%d\n", dma_count);			
 			if (dma_count < pending)
 				dev_info(zup->port.dev,
-					 "couldn't insert all characters (TTY is full?)\n");
+					"couldn't insert all characters (TTY is full?)\n");
 			
 
 		}
@@ -839,7 +1017,7 @@
 #if CONFIG_SERIAL_ZX29_DMA
 	/* If we are using DMA mode, try to send some characters. */
 	if(!uart_console(&(zup->port)))
-	 { 
+	{ 
 		if (zx29_dma_tx_irq(zup))
 			return;
 	}
@@ -894,10 +1072,10 @@
 		return false;
 
 	/*
-	 * If we already have a TX buffer queued, but received a
-	 * TX interrupt, it will be because we've just sent an X-char.
-	 * Ensure the TX DMA is enabled and the TX IRQ is disabled.
-	 */
+	* If we already have a TX buffer queued, but received a
+	* TX interrupt, it will be because we've just sent an X-char.
+	* Ensure the TX DMA is enabled and the TX IRQ is disabled.
+	*/
 	if (zup->dmatx.queued) {
 		zup->dmacr |= UART_TXDMAE;
 		UART_PUT_DMACR(&zup->port, zup->dmacr);
@@ -907,9 +1085,9 @@
 	}
 
 	/*
-	 * We don't have a TX buffer queued, so try to queue one.
-	 * If we successfully queued a buffer, mask the TX IRQ.
-	 */
+	* We don't have a TX buffer queued, so try to queue one.
+	* If we successfully queued a buffer, mask the TX IRQ.
+	*/
 	if (zx29_uart_dma_tx_chars(zup) > 0) {
 		zup->imr &= ~UART_TXIM;
 		UART_PUT_IMSC(&zup->port,zup->imr);
@@ -968,19 +1146,19 @@
 	}
 
 	/*
-	 * We have an X-char to send.  Disable DMA to prevent it loading
-	 * the TX fifo, and then see if we can stuff it into the FIFO.
-	 */
+	* We have an X-char to send.  Disable DMA to prevent it loading
+	* the TX fifo, and then see if we can stuff it into the FIFO.
+	*/
 	dmacr = zup->dmacr;
 	zup->dmacr &= ~UART_TXDMAE;
 	UART_PUT_DMACR(&zup->port, zup->dmacr);
 
 	if (UART_GET_FR(&zup->port) & UART_FR_TXFF) {
 		/*
-		 * No space in the FIFO, so enable the transmit interrupt
-		 * so we know when there is space.  Note that once we've
-		 * loaded the character, we should just re-enable DMA.
-		 */
+		* No space in the FIFO, so enable the transmit interrupt
+		* so we know when there is space.  Note that once we've
+		* loaded the character, we should just re-enable DMA.
+		*/
 		return false;
 	}
 
@@ -1055,10 +1233,10 @@
 	dmaengine_slave_config(zup->dmarx.chan, (struct dma_slave_config*)&zup->dmarx.rx_def[zup->dmarx.rx_index]);
 	desc = zup->dmarx.chan->device->device_prep_interleaved_dma(zup->dmarx.chan,NULL,0);
 	/*
-	 * If the DMA engine is busy and cannot prepare a
-	 * channel, no big deal, the driver will fall back
-	 * to interrupt mode as a result of this error code.
-	 */
+	* If the DMA engine is busy and cannot prepare a
+	* channel, no big deal, the driver will fall back
+	* to interrupt mode as a result of this error code.
+	*/
 	if (!desc) {
 		printk(KERN_INFO "!!ERROR DESC !!![%s][%d]Port:[%d]\n",__func__,__LINE__,zup->port.line);
 		zup->dmarx.running = false;
@@ -1164,17 +1342,17 @@
 	int ret;
 	unsigned long flags;
 	/*
-	 * This completion interrupt occurs typically when the
-	 * RX buffer is totally stuffed but no timeout has yet
-	 * occurred. When that happens, we just want the RX
-	 * routine to flush out the secondary DMA buffer while
-	 * we immediately trigger the next DMA job.
-	 */
+	* This completion interrupt occurs typically when the
+	* RX buffer is totally stuffed but no timeout has yet
+	* occurred. When that happens, we just want the RX
+	* routine to flush out the secondary DMA buffer while
+	* we immediately trigger the next DMA job.
+	*/
 	raw_spin_lock_irqsave(&zup->port.lock, flags);
 	/*
-	 * Rx data can be taken by the UART interrupts during
-	 * the DMA irq handler. So we check the residue here.
-	 */
+	* Rx data can be taken by the UART interrupts during
+	* the DMA irq handler. So we check the residue here.
+	*/
 	rxchan->device->device_tx_status(rxchan, dmarx->cookie, &state);
 	
 
@@ -1197,10 +1375,10 @@
 	raw_spin_unlock_irqrestore(&zup->port.lock, flags);
 #endif	
 	/*
-	 * Do this check after we picked the DMA chars so we don't
-	 * get some IRQ immediately from RX.
-	 */
-	 /*
+	* Do this check after we picked the DMA chars so we don't
+	* get some IRQ immediately from RX.
+	*/
+	/*
 	if (ret) {
 		dev_dbg(zup->port.dev, "could not retrigger RX DMA job "
 			"fall back to interrupt mode\n");
@@ -1218,7 +1396,7 @@
 	zup->dmacr &= ~UART_RXDMAE;
 	UART_PUT_DMACR(&zup->port,zup->dmacr);
 	zx29_dma_stop(rx_id);
-	 zup->curr_sg = NULL;
+	zup->curr_sg = NULL;
 }
 
 static void zx29_dma_remove(struct zx29_uart_port *zup)
@@ -1229,8 +1407,6 @@
 	if (zup->dmarx.chan)
 		dma_release_channel(zup->dmarx.chan);
 }
-
-
 static void zx29_dma_shutdown(struct zx29_uart_port *zup)
 {
 	unsigned long flags;
@@ -1246,7 +1422,7 @@
 	zup->dmacr &= ~(UART_DMAONERR | UART_RXDMAE | UART_TXDMAE);
 	UART_PUT_DMACR(&zup->port,zup->dmacr);
 	zx29_dma_stop(rx_id);
-	 zup->curr_sg = NULL;
+	zup->curr_sg = NULL;
 	raw_spin_unlock_irqrestore(&zup->port.lock, flags);
 	if (zup->using_tx_dma) {
 		/* In theory, this should already be done by zx29_dma_flush_buffer */
@@ -1325,14 +1501,14 @@
 	UART_PUT_DMACR(&zup->port,zup->dmacr);
 
 	/*
-	 * If TX DMA was disabled, it means that we've stopped the DMA for
-	 * some reason (eg, XOFF received, or we want to send an X-char.)
-	 *
-	 * Note: we need to be careful here of a potential race between DMA
-	 * and the rest of the driver - if the driver disables TX DMA while
-	 * a TX buffer completing, we must update the tx queued status to
-	 * get further refills (hence we check dmacr).
-	 */
+	* If TX DMA was disabled, it means that we've stopped the DMA for
+	* some reason (eg, XOFF received, or we want to send an X-char.)
+	*
+	* Note: we need to be careful here of a potential race between DMA
+	* and the rest of the driver - if the driver disables TX DMA while
+	* a TX buffer completing, we must update the tx queued status to
+	* get further refills (hence we check dmacr).
+	*/
 	if (!(dmacr & UART_TXDMAE) || uart_tx_stopped(&zup->port) ||
 	    uart_circ_empty(&zup->port.state->xmit)) {
 		zup->dmatx.queued = false;
@@ -1347,9 +1523,9 @@
 
 	if (zx29_uart_dma_tx_chars(zup) <= 0) {
 		/*
-		 * We didn't queue a DMA buffer for some reason, but we
-		 * have data pending to be sent.  Re-enable the TX IRQ.
-		 */
+		* We didn't queue a DMA buffer for some reason, but we
+		* have data pending to be sent.  Re-enable the TX IRQ.
+		*/
 		zup->imr |= UART_TXIM;
 		UART_PUT_IMSC(&zup->port, zup->imr);
 	}
@@ -1366,11 +1542,11 @@
 	unsigned int count;
 
 	/*
-	 * Try to avoid the overhead involved in using DMA if the
-	 * transaction fits in the first half of the FIFO, by using
-	 * the standard interrupt handling.  This ensures that we
-	 * issue a uart_write_wakeup() at the appropriate time.
-	 */
+	* Try to avoid the overhead involved in using DMA if the
+	* transaction fits in the first half of the FIFO, by using
+	* the standard interrupt handling.  This ensures that we
+	* issue a uart_write_wakeup() at the appropriate time.
+	*/
  
 	count = uart_circ_chars_pending(xmit);
 	if (count < (16 >> 1)) {
@@ -1385,9 +1561,9 @@
 	}
 */
 	/*
-	 * Bodge: don't send the last character by DMA, as this
-	 * will prevent XON from notifying us to restart DMA.
-	 */
+	* Bodge: don't send the last character by DMA, as this
+	* will prevent XON from notifying us to restart DMA.
+	*/
 	//count -= 1;
 
 	/* Else proceed to copy the TX chars to the DMA buffer and fire DMA */
@@ -1424,9 +1600,9 @@
 	dma_unmap_sg(dma_dev->dev, &dmatx->sg, 1, DMA_TO_DEVICE);
 	zup->dmatx.queued = false;
 	/*
-	 * If DMA cannot be used right now, we complete this
-	 * transaction via IRQ and let the TTY layer retry.
-	 */
+	* If DMA cannot be used right now, we complete this
+	* transaction via IRQ and let the TTY layer retry.
+	*/
 	dev_dbg(zup->port.dev, "TX DMA busy\n");
 	return -EBUSY;
 	}	
@@ -1440,9 +1616,9 @@
 	zup->dmatx.queued = true;
 
 	/*
-	 * Now we know that DMA will fire, so advance the ring buffer
-	 * with the stuff we just dispatched.
-	 */
+	* Now we know that DMA will fire, so advance the ring buffer
+	* with the stuff we just dispatched.
+	*/
 	xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1);
 	zup->port.icount.tx += count;
 
@@ -1475,10 +1651,10 @@
 		dma_sync_sg_for_cpu(dev, &sgbuf->sg, 1, DMA_FROM_DEVICE);
 
 		/*
-		 * First take all chars in the DMA pipe, then look in the FIFO.
-		 * Note that tty_insert_flip_buf() tries to take as many chars
-		 * as it can.
-		 */
+		* First take all chars in the DMA pipe, then look in the FIFO.
+		* Note that tty_insert_flip_buf() tries to take as many chars
+		* as it can.
+		*/
 	
 	raw_spin_unlock_irqrestore(&zup->port.lock, *flags);
 	
@@ -1495,28 +1671,28 @@
 		    //  printk("yanming uart_dma_rx_chars, dma2tty:%d\n", dma_count);			
 		if (dma_count < pending)
 			dev_info(zup->port.dev,
-				 "couldn't insert all characters (TTY is full?)\n");
+				"couldn't insert all characters (TTY is full?)\n");
 	}
 
 	/*
-	 * Only continue with trying to read the FIFO if all DMA chars have
-	 * been taken first.
-	 */
+	* Only continue with trying to read the FIFO if all DMA chars have
+	* been taken first.
+	*/
 	//if (dma_count == pending && readfifo) {
 	if ((pending > 0) && readfifo) {
 		/* Clear any error flags */
 		//UART_PUT_ICR(&zup->port,UART_OEIC | UART_BEIC | UART_PEIC | UART_FEIC);
 		/*
-		 * If we read all the DMA'd characters, and we had an
-		 * incomplete buffer, that could be due to an rx error, or
-		 * maybe we just timed out. Read any pending chars and check
-		 * the error status.
-		 *
-		 * Error conditions will only occur in the FIFO, these will
-		 * trigger an immediate interrupt and stop the DMA job, so we
-		 * will always find the error in the FIFO, never in the DMA
-		 * buffer.
-		 */
+		* If we read all the DMA'd characters, and we had an
+		* incomplete buffer, that could be due to an rx error, or
+		* maybe we just timed out. Read any pending chars and check
+		* the error status.
+		*
+		* Error conditions will only occur in the FIFO, these will
+		* trigger an immediate interrupt and stop the DMA job, so we
+		* will always find the error in the FIFO, never in the DMA
+		* buffer.
+		*/
 		fifotaken = zx29_uart_fifo_to_tty(zup);
 			//if(zup->port.line == 0)
 		     // printk("yanming uart_dma_rx_chars, fifo2tty:%d\n", fifotaken);			
@@ -1559,10 +1735,10 @@
 
 	if(zx29_dma_rx_running(zup)){
 		/*
-		 * Pause the transfer so we can trust the current counter,
-		 * do this before we pause the block, else we may
-		 * overflow the FIFO.
-		 */
+		* Pause the transfer so we can trust the current counter,
+		* do this before we pause the block, else we may
+		* overflow the FIFO.
+		*/
 	//	if(zx29_dma_stop(rx_id))
 		//	printk( "uart%d unable to pause DMA transfer\n", zup->port.line);
 		zup->dmacr &= ~UART_RXDMAE;
@@ -1581,9 +1757,9 @@
 	
 	dmarx->use_buf_b = !dmarx->use_buf_b;
 		/*
-		 * This will take the chars we have so far and insert
-		 * into the framework.
-		 */
+		* This will take the chars we have so far and insert
+		* into the framework.
+		*/
 			zx29_uart_dma_rx_chars(zup, pending, sgbuf, false, flags);
 	}
 
@@ -1706,10 +1882,10 @@
 
 	if(zx29_dma_rx_running(zup)){
 		/*
-		 * Pause the transfer so we can trust the current counter,
-		 * do this before we pause the block, else we may
-		 * overflow the FIFO.
-		 */
+		* Pause the transfer so we can trust the current counter,
+		* do this before we pause the block, else we may
+		* overflow the FIFO.
+		*/
 		 
 		zup->dmacr &= ~UART_RXDMAE;
 		UART_PUT_DMACR(&zup->port,zup->dmacr);
@@ -2121,7 +2297,7 @@
 		dev_err(zup->port.dev, "failed to init DMA %s: %d\n",
 			"RX buffer B", ret);
 		zx29_sgbuf_free(zup->dmarx.chan, &zup->dmarx.sgbuf_a,
-				 DMA_FROM_DEVICE);
+				DMA_FROM_DEVICE);
 		goto skip_rx;
 	}
 
@@ -2215,9 +2391,9 @@
 	port->icount.overrun = port->icount.parity = port->icount.rng = 0;
 	port->icount.rx = port->icount.tx = 0;
 	/* 
-	 *enable uart clock 
-	 *if uart is used for console, don't need do these, these was done before
-	 */
+	*enable uart clock 
+	*if uart is used for console, don't need do these, these was done before
+	*/
 	if (DEBUG_CONSOLE != pdev->id) {	
 	    /*  config uart apb_clk   */
 		clk_prepare_enable(zup->busclk);
@@ -2291,7 +2467,7 @@
 				pcu_int_clear(PCU_UART0_RXD_INT); 
 				ret = request_irq(zup->irq, zx29_uart_rxd_irq,
 			      		IRQF_ONESHOT , "uart_rxd_irq",
-			    		 zup);
+			    		zup);
 				printk(KERN_INFO"zx29_uart_startup, retval:%d\n",ret);
 				irq_set_irq_wake(zup->irq,1);
 #ifdef CONFIG_CPU_IDLE	
@@ -2398,10 +2574,10 @@
 	UART_PUT_CR(port, control);
 
 	/*
-	 * Finally, enable interrupts, only timeouts when using DMA
-	 * if initial RX DMA job failed, start in interrupt mode
-	 * as well.
-	 */
+	* Finally, enable interrupts, only timeouts when using DMA
+	* if initial RX DMA job failed, start in interrupt mode
+	* as well.
+	*/
 	raw_spin_lock_irqsave(&zup->port.lock, flags);
 	/* Clear out any spuriously appearing RX interrupts */
 	UART_PUT_ICR(port, (UART_RTIS | UART_RXIS));
@@ -2626,8 +2802,8 @@
 	raw_spin_lock_irqsave(&port->lock, flags);
 
 	/*
-	 * Update the per-port timeout.
-	 */
+	* Update the per-port timeout.
+	*/
 	uart_update_timeout(port, termios->c_cflag, baud);
 
 	port->read_status_mask = UART_DR_OE | 255;
@@ -2637,24 +2813,24 @@
 		port->read_status_mask |= UART_DR_BE;
 
 	/*
-	 * Characters to ignore
-	 */
+	* Characters to ignore
+	*/
 	port->ignore_status_mask = 0;
 	if (termios->c_iflag & IGNPAR)
 		port->ignore_status_mask |= UART_DR_FE | UART_DR_PE;
 	if (termios->c_iflag & IGNBRK) {
 		port->ignore_status_mask |= UART_DR_BE;
 		/*
-		 * If we're ignoring parity and break indicators,
-		 * ignore overruns too (for real raw support).
-		 */
+		* If we're ignoring parity and break indicators,
+		* ignore overruns too (for real raw support).
+		*/
 		if (termios->c_iflag & IGNPAR)
 			port->ignore_status_mask |= UART_DR_OE;
 	}
 
 	/*
-	 * Ignore all characters if CREAD is not set.
-	 */
+	* Ignore all characters if CREAD is not set.
+	*/
 	if ((termios->c_cflag & CREAD) == 0)
 		port->ignore_status_mask |= UART_DUMMY_DR_RX;
 
@@ -2677,10 +2853,10 @@
 	}
 
 	/*
-	 * ----------v----------v----------v----------v-----
-	 * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L
-	 * ----------^----------^----------^----------^-----
-	 */
+	* ----------v----------v----------v----------v-----
+	* NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L
+	* ----------^----------^----------^----------^-----
+	*/
 	UART_PUT_LCRH(port, lcr_h);
 	UART_PUT_CR(port, old_cr);
 
@@ -2862,7 +3038,7 @@
         * just configure clock, 
         * actually pin configuration is needed, but now gpio driver is not OK
         * use bootloader default configuration
-	 */
+	*/
     if(DEBUG_CONSOLE == pdev->id){
 		/*  config uart apb_clk   */
 		clk_prepare_enable(zx29_port->busclk);
@@ -2876,6 +3052,7 @@
 
 #ifdef CONFIG_SERIAL_ZX29_UART_CONSOLE
 
+#ifndef _USE_CAP_SYS
 /****************************************************************************/
 static void zx29_uart_console_putc(struct uart_port *port, const char c)
 {
@@ -2884,6 +3061,28 @@
 	UART_PUT_CHAR(port, c);
 }
 
+#else
+static void zx29_uart_console_putc(struct uart_port *port, const char c)
+{
+	if(g_core_id_occupy_uart == SYMB_CAP_CORE_ID)
+		return;
+	soft_spin_lock(UART_SFLOCK);
+	while (UART_GET_FR(port) & UART_FR_TXFF)
+		barrier();
+	UART_PUT_CHAR(port, c);
+	soft_spin_unlock(UART_SFLOCK);
+}
+static void zx29_uart_console_putc_printf(struct uart_port *port, int c)
+{
+	int ret;
+	ret = soft_spin_lock_printf(UART_SFLOCK);
+	while (UART_GET_FR(port) & UART_FR_TXFF)
+		barrier();
+	UART_PUT_CHAR(port, c);
+	if(!ret)
+		soft_spin_unlock(UART_SFLOCK);
+}
+#endif
 
 /****************************************************************************/
 static void zx29_uart_console_write(struct console *co, const char *s, unsigned int count)
@@ -2908,7 +3107,7 @@
  * try to determine the current setup.
  ****************************************************************************/
 static void __init zx29_console_get_options(struct uart_port *port, int *baud,
-						 int *parity, int *bits)
+						int *parity, int *bits)
 {
 	if (UART_GET_CR(port) & UART_CR_UARTEN) {
 		unsigned int lcr_h, ibrd, fbrd;
@@ -3059,12 +3258,21 @@
 #endif
 		return ret;
 		}
-	 sema_init(&port->sema, 0);
+	sema_init(&port->sema, 0);
 	/*platform_set_drvdata(pdev, port);*/
 	
 	if(pdev->id == DEBUG_CONSOLE){
 		g_console_open_flag = pdata->uart_input_enable ? pdata->uart_input_enable : 0;
 		error = device_create_file(&pdev->dev, &dev_attr_console_input);
+#ifdef _USE_CAP_SYS
+		error = device_create_file(&pdev->dev, &dev_attr_console_uart_toggle);
+		error = device_create_file(&pdev->dev, &dev_attr_coreid_occupy_uart);
+		int ret;
+		ret = zDrvRpMsg_CreateChannel_Cap(CAP_ID, ICP_CHANNEL_CONSOLE_UART, ICP_BUFFERSIZE_CONSOLE_TOGGLE);
+		if(ret)
+			printk("linux3 request icp channel for uart fail %d.\n", ret);
+		zDrvRpMsg_RegCallBack_Cap(CAP_ID, ICP_CHANNEL_CONSOLE_UART, icp_callback_cap2ps);
+#endif
 	}
 	
 	if(pdev->id != DEBUG_CONSOLE){
@@ -3091,7 +3299,7 @@
 #endif
 	int i;
 	if(pdev->id == DEBUG_CONSOLE){		
-		 device_remove_file(&pdev->dev, &dev_attr_console_input);
+		device_remove_file(&pdev->dev, &dev_attr_console_input);
 	}
 	
 	if(pdev->id != DEBUG_CONSOLE){
@@ -3153,4 +3361,3 @@
 
 module_init(zx29_uart_init);
 module_exit(zx29_uart_exit);
-
diff --git a/ap/project/zx297520v3/prj_vehicle_dc/fs/normal/rootfs/etc/rc b/ap/project/zx297520v3/prj_vehicle_dc/fs/normal/rootfs/etc/rc
index 4c3d0c8..724d26d 100755
--- a/ap/project/zx297520v3/prj_vehicle_dc/fs/normal/rootfs/etc/rc
+++ b/ap/project/zx297520v3/prj_vehicle_dc/fs/normal/rootfs/etc/rc
@@ -262,3 +262,13 @@
 rm -rf /etc_rw/udhcpd*.pid
 sh /sbin/rm_dev.sh
 echo 2000 > /proc/sys/net/nf_conntrack_max
+# read nv for which core to occupy uart console
+coreid_uart_cons=$(nv get uart_console_coreid)
+if [[ $coreid_uart_cons == "1" ]]; then
+echo 1 > /sys/devices/platform/zx29_uart.1/coreid_occupy_uart
+cat /sys/devices/platform/zx29_uart.1/coreid_occupy_uart
+fi
+if [[ $coreid_uart_cons == "2" ]]; then
+echo 2 > /sys/devices/platform/zx29_uart.1/coreid_occupy_uart
+cat /sys/devices/platform/zx29_uart.1/coreid_occupy_uart
+fi
diff --git a/cap/zx297520v3/sources/meta-zxic-custom/recipes-core/images/files/zx297520v3/vehicle_dc/fs/normal/rootfs/etc/init.d/enter_amt.sh b/cap/zx297520v3/sources/meta-zxic-custom/recipes-core/images/files/zx297520v3/vehicle_dc/fs/normal/rootfs/etc/init.d/enter_amt.sh
index 30f7d5d..01d0f74 100755
--- a/cap/zx297520v3/sources/meta-zxic-custom/recipes-core/images/files/zx297520v3/vehicle_dc/fs/normal/rootfs/etc/init.d/enter_amt.sh
+++ b/cap/zx297520v3/sources/meta-zxic-custom/recipes-core/images/files/zx297520v3/vehicle_dc/fs/normal/rootfs/etc/init.d/enter_amt.sh
@@ -23,6 +23,7 @@
 	/etc/init.d/mdev start
 	sh /etc/init.d/fscheck.sh
 	/etc/init.d/nvserver start
+	/etc/init.d/nv-rpc-daemon start
 	nv set ver_mode=0
 	/etc/init.d/zxic_usbCfgMng start
 	sh /etc/init.d/zcatlog_config.sh
diff --git a/cap/zx297520v3/sources/meta-zxic-custom/recipes-core/images/files/zx297520v3/vehicle_dc/fs/normal/rootfs/etc_ro/default/default_parameter_user b/cap/zx297520v3/sources/meta-zxic-custom/recipes-core/images/files/zx297520v3/vehicle_dc/fs/normal/rootfs/etc_ro/default/default_parameter_user
index 2d770b3..9942191 100755
--- a/cap/zx297520v3/sources/meta-zxic-custom/recipes-core/images/files/zx297520v3/vehicle_dc/fs/normal/rootfs/etc_ro/default/default_parameter_user
+++ b/cap/zx297520v3/sources/meta-zxic-custom/recipes-core/images/files/zx297520v3/vehicle_dc/fs/normal/rootfs/etc_ro/default/default_parameter_user
@@ -444,6 +444,7 @@
 uart_ctstrs_enable=
 uart_softcontrol_enable=
 uart_wakeup_enable=1
+uart_console_coreid=1
 special_cmd_list=$MYNETREAD
 ##为入网入库芯片认证版本添加 begin
 atcmd_stream1=AT+ZSET="w_instrument",1
diff --git a/cap/zx297520v3/sources/meta-zxic/recipes-kernel/linux/files/zx297520v3/linux-5_10-vehicle_dc-normal-defconfig b/cap/zx297520v3/sources/meta-zxic/recipes-kernel/linux/files/zx297520v3/linux-5_10-vehicle_dc-normal-defconfig
index 0d0de0e..f2fdb7a 100755
--- a/cap/zx297520v3/sources/meta-zxic/recipes-kernel/linux/files/zx297520v3/linux-5_10-vehicle_dc-normal-defconfig
+++ b/cap/zx297520v3/sources/meta-zxic/recipes-kernel/linux/files/zx297520v3/linux-5_10-vehicle_dc-normal-defconfig
@@ -1527,7 +1527,7 @@
 # CONFIG_SERIAL_SPRD is not set
 CONFIG_SERIAL_ZX29_UART=y
 CONFIG_SERIAL_ZX29_UART_CONSOLE=y
-CONFIG_UART_CONSOLE_ID=0
+CONFIG_UART_CONSOLE_ID=1
 # end of Serial drivers
 
 CONFIG_SERIAL_NONSTANDARD=y
diff --git a/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/arch/arm/boot/dts/zx297520v3-vehicle_dc.dts b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/arch/arm/boot/dts/zx297520v3-vehicle_dc.dts
index b11ed95..6e185f1 100755
--- a/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/arch/arm/boot/dts/zx297520v3-vehicle_dc.dts
+++ b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/arch/arm/boot/dts/zx297520v3-vehicle_dc.dts
@@ -50,7 +50,7 @@
 	compatible = "zte,zx297520v3-vehicle-dc", "zte,zx297520v3";
 
 	chosen {
-		bootargs = "console=ttyS0,921600n8 earlycon rdinit=/sbin/init ubi.block=0,vol_rootfs root=/dev/ubiblock0_0 rootfstype=squashfs ubi.mtd=caprootfs ";
+		bootargs = "console=ttyS1,921600n8 earlycon rdinit=/sbin/init ubi.block=0,vol_rootfs root=/dev/ubiblock0_0 rootfstype=squashfs ubi.mtd=caprootfs ";
 	};
 
 	memory {
diff --git a/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/arch/arm/boot/dts/zx297520v3.dtsi b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/arch/arm/boot/dts/zx297520v3.dtsi
index 761e056..4ea7090 100644
--- a/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/arch/arm/boot/dts/zx297520v3.dtsi
+++ b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/arch/arm/boot/dts/zx297520v3.dtsi
@@ -312,7 +312,7 @@
 			interrupts = <GIC_SPI UART0_MIX_INT IRQ_TYPE_LEVEL_HIGH>; 
 			clocks = <&clkc UART0_WCLK>, <&clkc UART0_PCLK>;
 			clock-names = "uartclk", "apb_pclk";
-			status = "okay";
+			status = "disabled";
 		};
 
 		soc_uart1: uart@1408000 {
@@ -322,7 +322,7 @@
 			interrupts = <GIC_SPI UART1_MIX_INT IRQ_TYPE_LEVEL_HIGH>; 
 			clocks = <&clkc UART1_WCLK>, <&clkc UART1_PCLK>;
 			clock-names = "uartclk", "apb_pclk";
-			status = "disabled";
+			status = "okay";
 		};
 		soc_uart2: uart@140D000 {
 			compatible = "zxic,zx29-uart";
diff --git a/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/drivers/soc/zte/spinlock/spinlock-zx297520v3.c b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/drivers/soc/zte/spinlock/spinlock-zx297520v3.c
index dc252ea..99d3fb7 100644
--- a/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/drivers/soc/zte/spinlock/spinlock-zx297520v3.c
+++ b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/drivers/soc/zte/spinlock/spinlock-zx297520v3.c
@@ -210,6 +210,33 @@
     //zspinlock_debug("cpu %d releases %d software lock!/n",SELF_CORE_ID,sfid);

 

 }

+#if 1

+int  soft_spin_lock_printf(emsf_lock_id sfid)

+{

+	static unsigned long lock_count = 0;

+softlock_loop:

+   	while(softlock_desc[sfid]->owner != SELF_CORE_ID && softlock_desc[sfid]->used)

+   	{

+   		ndelay(1);

+   		lock_count++;

+		if(lock_count >= 5000)

+		{

+			lock_count = 0;

+			return -1;

+		}

+   	}

+	_hw_spin_lock(SOFTLOCK_HWLOCK);

+	if(softlock_desc[sfid]->owner != SELF_CORE_ID && softlock_desc[sfid]->used)

+   	{

+	      _hw_spin_unlock(SOFTLOCK_HWLOCK);

+		goto softlock_loop;

+   	}

+    softlock_desc[sfid]->used ++;

+    softlock_desc[sfid]->owner = SELF_CORE_ID;

+    _hw_spin_unlock(SOFTLOCK_HWLOCK);

+	return 0;

+}

+#endif

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

  * Function: soft_spin_unlock

  * Description:Óësoft_spin_lock¶ÔÓ¦µÄÊÍ·ÅÈí¼þËø½Ó¿Ú¡£

diff --git a/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/drivers/tty/serial/zx29_uart.c b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/drivers/tty/serial/zx29_uart.c
index 542f78c..3a832b9 100755
--- a/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/drivers/tty/serial/zx29_uart.c
+++ b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/drivers/tty/serial/zx29_uart.c
@@ -35,6 +35,7 @@
 #include <linux/device.h>
 #include <linux/ioport.h>
 #include <linux/sched/clock.h>
+#include <linux/soc/zte/spinlock.h>
 
 #if 0
 #include <mach/gpio_def.h>
@@ -54,6 +55,7 @@
 //#include "../../dma/zte/zx298501_dma.h"
 
 #include "zx29_uart.h"
+#include <linux/soc/zte/rpmsg.h>
 //#include <linux/soc/zte/pm/drv_idle.h>
 //#include <mach/pcu.h>
 //#define DEBUG_UART
@@ -260,14 +262,15 @@
 //
 //    return false;
 //}
-
+static void zx29_uart_console_putc(struct uart_port *port, int c);
 void zx29_uart_putc(struct uart_port *port, int c);
+static void zx29_uart_console_putc_printf(struct uart_port *port, int c);
  
 #if CONFIG_SERIAL_ZX29_DMA
 void uart_mod_timer(struct zx29_uart_port *zup, unsigned long *flags)
 {
-	 unsigned long t_delay = 0;
-	 t_delay =  msecs_to_jiffies(RX_DMA_TIMEOUT);
+	unsigned long t_delay = 0;
+	t_delay =  msecs_to_jiffies(RX_DMA_TIMEOUT);
 	spin_unlock_irqrestore(&zup->port.lock, *flags);
 	//printk("uart_mod_timer, delay %d jiffies\n", t_delay);
 	mod_timer(&(zup->rx_dma_timer), jiffies + t_delay);
@@ -290,8 +293,8 @@
  * 1:  able console input, can input commands
  */
 static ssize_t console_input_store(struct device *_dev,
-				 struct device_attribute *attr,
-				 const char *buf, size_t count)
+				struct device_attribute *attr,
+				const char *buf, size_t count)
 {
     uint32_t  flag = 0;
 	flag = simple_strtoul(buf, NULL, 16);
@@ -318,8 +321,8 @@
 }
 
 static ssize_t ctsrts_input_store(struct device *_dev,
-				 struct device_attribute *attr,
-				 const char *buf, size_t count)
+				struct device_attribute *attr,
+				const char *buf, size_t count)
 {
     uint32_t  flag = 0;
 	struct platform_device *pdev = container_of(_dev, struct platform_device, dev);
@@ -346,8 +349,8 @@
 }
 
 static ssize_t wakeup_enable_store(struct device *_dev,
-				 struct device_attribute *attr,
-				 const char *buf, size_t count)
+				struct device_attribute *attr,
+				const char *buf, size_t count)
 {
     uint32_t  flag = 0;
 	struct platform_device *pdev = container_of(_dev, struct platform_device, dev);
@@ -381,6 +384,151 @@
 		);
 }
 DEVICE_ATTR(statics, S_IRUGO, statics_show, NULL);
+#define VEHICLE_USE_ONE_UART_LOG 1
+#if VEHICLE_USE_ONE_UART_LOG
+#define ICP_CORE_ID_PS CORE_PS0
+#define ICP_CORE_ID_CAP 1
+#define ICP_CHANNEL_CONSOLE_UART 7
+#define ICP_MSG_LEN_CONSOLE_UART 2
+#define ICP_BUFFERSIZE_CONSOLE_TOGGLE 16
+#define SYMB_PS_CORE_ID ICP_CORE_ID_PS
+#define SYMB_CAP_CORE_ID ICP_CORE_ID_CAP
+#define SYMB_WHAT_CORE_ID 3
+#define ENABLE_CURRENT_CONSOLE_UART 1
+#define DISABLE_CURRENT_CONSOLE_UART 0
+#define ENABLE_TOGGLE 1
+#define DISABLE_TOGGLE 0
+unsigned char g_core_id_occupy_uart = 0;
+unsigned char g_cap_uart_toggle = 0;
+static irqreturn_t zx29_uart_interrupt(int irq, void *dev_id);
+static void restart_current_cons_uart(void)
+{
+	struct zx29_uart_port *zup = &zx29_uart_ports[DEBUG_CONSOLE];	
+	struct uart_port *port = &zup->port;
+	enable_irq(port->irq);
+	g_core_id_occupy_uart = SYMB_CAP_CORE_ID;
+	spin_lock(&zup->port.lock);
+	tasklet_schedule(&zup->write_wakeup);
+	spin_unlock(&zup->port.lock);
+}
+static void forbid_current_cons_uart(void)
+{
+	struct zx29_uart_port *zup = &zx29_uart_ports[DEBUG_CONSOLE];	
+	struct uart_port *port = &zup->port;
+	disable_irq(port->irq);
+	g_core_id_occupy_uart = SYMB_PS_CORE_ID;
+}
+static void process_ps2cap_rpmsg(char *arr)
+{
+	if((arr[0] == SYMB_CAP_CORE_ID) && (arr[1] == ENABLE_CURRENT_CONSOLE_UART)){
+		restart_current_cons_uart();
+	}else if((arr[0] == SYMB_CAP_CORE_ID) && (arr[1] == DISABLE_CURRENT_CONSOLE_UART)){
+		printk("current console uart not enable.\n");
+		g_core_id_occupy_uart = SYMB_CAP_CORE_ID;
+	}else if((arr[0] == SYMB_WHAT_CORE_ID) && (arr[1] == SYMB_PS_CORE_ID)){
+		g_core_id_occupy_uart = SYMB_PS_CORE_ID;
+		forbid_current_cons_uart();
+	}else if((arr[0] == SYMB_WHAT_CORE_ID) && (arr[1] == SYMB_CAP_CORE_ID)){
+		g_core_id_occupy_uart = SYMB_CAP_CORE_ID;
+	}
+	else{
+		printk("%s error!!\n",__func__);
+	}
+}
+static void icp_callback_ps2cap(void *buf, unsigned int len)
+{
+	char *arr_ps2cap;
+	if (len==0){
+		printk("%s empty.\n", __func__);
+		return ;
+	}	
+	arr_ps2cap = (char *)buf;
+	process_ps2cap_rpmsg(arr_ps2cap);
+}
+static void echo_to_change_ohter_uart(uint32_t val)
+{
+	int ret;
+	if(val > ENABLE_TOGGLE)
+	{
+		printk("echo para error!!!\n");
+		return;
+	}
+	char arr[2] = {0};
+	arr[0] = SYMB_PS_CORE_ID;
+	arr[1] = val;
+    T_RpMsg_Msg icp_msg;
+    icp_msg.coreID = CORE_PS0;
+    icp_msg.chID 	= ICP_CHANNEL_CONSOLE_UART;
+    icp_msg.flag 	= RPMSG_WRITE_INT;		/* 1- means send an icp interrupt> */
+    icp_msg.buf 	= arr;
+    icp_msg.len 	= ICP_MSG_LEN_CONSOLE_UART;	
+	ret = rpmsgWrite(&icp_msg);
+	if(ret == 0){
+		if(val == ENABLE_TOGGLE)
+			g_core_id_occupy_uart = SYMB_PS_CORE_ID;
+		else if(val == DISABLE_TOGGLE)
+			g_core_id_occupy_uart = SYMB_CAP_CORE_ID;	
+	}else
+		printk("echo_to_change_ohter_uart fail.\n");
+}
+static ssize_t console_uart_toggle_show(struct device *_dev,
+				struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "\n console_uart_toggle_show %d. \n", g_cap_uart_toggle);
+}
+static ssize_t console_uart_toggle_store(struct device *_dev,
+				struct device_attribute *attr,
+				const char *buf, size_t count)
+{
+    uint32_t  flag = 0;
+	flag = simple_strtoul(buf, NULL, 16);
+	if(flag == ENABLE_TOGGLE){
+		g_cap_uart_toggle = 1;
+		forbid_current_cons_uart();
+		echo_to_change_ohter_uart(flag);
+	}else if(flag == DISABLE_TOGGLE){
+		g_cap_uart_toggle = 0;
+		g_core_id_occupy_uart = SYMB_CAP_CORE_ID;
+	}
+	return count;
+}
+DEVICE_ATTR(console_uart_toggle, S_IRUGO | S_IWUSR, console_uart_toggle_show,
+	    console_uart_toggle_store);
+static void notify_occupy_uart_coreid_to_other(void)
+{
+	char arr[2] = {0};
+	arr[0] = SYMB_WHAT_CORE_ID;
+	arr[1] = g_core_id_occupy_uart;
+    T_RpMsg_Msg icp_msg;
+    icp_msg.coreID = CORE_AP;
+    icp_msg.chID 	= ICP_CHANNEL_CONSOLE_UART;
+    icp_msg.flag 	= RPMSG_WRITE_INT;		/* 1- means send an icp interrupt> */
+    icp_msg.buf 	= arr;
+    icp_msg.len 	= ICP_MSG_LEN_CONSOLE_UART;	
+	rpmsgWrite(&icp_msg);
+}
+static ssize_t coreid_occupy_uart_show(struct device *_dev,
+				struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "\n core %d occupy cons uart now! \n",g_core_id_occupy_uart);
+}
+static ssize_t coreid_occupy_uart_store(struct device *_dev,
+				struct device_attribute *attr,
+				const char *buf, size_t count)
+{
+    uint32_t  flag = 0;
+	flag = simple_strtoul(buf, NULL, 16);
+	g_core_id_occupy_uart = flag;
+	if(flag == SYMB_CAP_CORE_ID){
+		g_cap_uart_toggle = 0;
+	}else if(SYMB_PS_CORE_ID){
+		g_cap_uart_toggle = 1;
+	}
+	return count;
+}
+DEVICE_ATTR(coreid_occupy_uart, S_IRUGO | S_IWUSR, coreid_occupy_uart_show,
+	    coreid_occupy_uart_store);
+#endif
 
 
 #if CONFIG_SERIAL_ZX29_DMA
@@ -547,7 +695,44 @@
 	unsigned int reg_bak[10] = {0};
 	struct circ_buf *xmit = &zup->port.state->xmit;
 	int count = 0;	
+#if VEHICLE_USE_ONE_UART_LOG
+	if((port->line == DEBUG_CONSOLE))
+	{
+		if(g_core_id_occupy_uart == SYMB_PS_CORE_ID){
+			#if 1
+			count = uart_circ_chars_pending(xmit);		
+			while(count-- > 0) 
+			{
+				xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+				if (uart_circ_empty(xmit))
+					break;	
+			}
+			#endif
+			return;
+		}
+		count = uart_circ_chars_pending(xmit);		
+		while(count-- > 0) 
+		{
+			zx29_uart_console_putc_printf(&zup->port, xmit->buf[xmit->tail]);
+			xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+			zup->port.icount.tx++;
+			if (uart_circ_empty(xmit)){
+				break;
+			}
+		}
 	
+		if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+		{
+			spin_lock(&zup->port.lock);
+			tasklet_schedule(&zup->write_wakeup);
+			spin_unlock(&zup->port.lock);
+			return;
+		}
+		return;
+	}
+else
+#endif
+{
 	if(!(UART_GET_RIS(port)&UART_TXIS) && (UART_GET_FR(port) & UART_FR_TXFE))
 	{
 		if(!(UART_GET_RIS(port)&UART_TXIS))	
@@ -566,10 +751,11 @@
 		}
 
 	}
+	}
 #if CONFIG_SERIAL_ZX29_DMA	 
 	if(!uart_console(port))
-	 { 
-		 if (!zx29_dma_tx_start(zup))
+	{ 
+		if (!zx29_dma_tx_start(zup))
 		   	{
 				zup->imr |= UART_TXIM;
 				UART_PUT_IMSC(port, zup->imr);
@@ -671,7 +857,7 @@
 		      //printk("yanming dma_complete_thread, dma2tty:%d\n", dma_count);			
 			if (dma_count < pending)
 				dev_info(zup->port.dev,
-					 "couldn't insert all characters (TTY is full?)\n");
+					"couldn't insert all characters (TTY is full?)\n");
 			
 
 		}
@@ -910,7 +1096,7 @@
 #if CONFIG_SERIAL_ZX29_DMA
 	/* If we are using DMA mode, try to send some characters. */
 	if(!uart_console(&(zup->port)))
-	 { 
+	{ 
 		if (zx29_dma_tx_irq(zup))
 			return;
 	}
@@ -974,10 +1160,10 @@
 		return false;
 
 	/*
-	 * If we already have a TX buffer queued, but received a
-	 * TX interrupt, it will be because we've just sent an X-char.
-	 * Ensure the TX DMA is enabled and the TX IRQ is disabled.
-	 */
+	* If we already have a TX buffer queued, but received a
+	* TX interrupt, it will be because we've just sent an X-char.
+	* Ensure the TX DMA is enabled and the TX IRQ is disabled.
+	*/
 	if (zup->dmatx.queued) {
 		zup->dmacr |= UART_TXDMAE;
 		UART_PUT_DMACR(&zup->port, zup->dmacr);
@@ -987,9 +1173,9 @@
 	}
 
 	/*
-	 * We don't have a TX buffer queued, so try to queue one.
-	 * If we successfully queued a buffer, mask the TX IRQ.
-	 */
+	* We don't have a TX buffer queued, so try to queue one.
+	* If we successfully queued a buffer, mask the TX IRQ.
+	*/
 	if (zx29_uart_dma_tx_chars(zup) > 0) {
 		zup->imr &= ~UART_TXIM;
 		UART_PUT_IMSC(&zup->port,zup->imr);
@@ -1048,19 +1234,19 @@
 	}
 
 	/*
-	 * We have an X-char to send.  Disable DMA to prevent it loading
-	 * the TX fifo, and then see if we can stuff it into the FIFO.
-	 */
+	* We have an X-char to send.  Disable DMA to prevent it loading
+	* the TX fifo, and then see if we can stuff it into the FIFO.
+	*/
 	dmacr = zup->dmacr;
 	zup->dmacr &= ~UART_TXDMAE;
 	UART_PUT_DMACR(&zup->port, zup->dmacr);
 
 	if (UART_GET_FR(&zup->port) & UART_FR_TXFF) {
 		/*
-		 * No space in the FIFO, so enable the transmit interrupt
-		 * so we know when there is space.  Note that once we've
-		 * loaded the character, we should just re-enable DMA.
-		 */
+		* No space in the FIFO, so enable the transmit interrupt
+		* so we know when there is space.  Note that once we've
+		* loaded the character, we should just re-enable DMA.
+		*/
 		return false;
 	}
 
@@ -1136,10 +1322,10 @@
 
 
 	/*
-	 * If the DMA engine is busy and cannot prepare a
-	 * channel, no big deal, the driver will fall back
-	 * to interrupt mode as a result of this error code.
-	 */
+	* If the DMA engine is busy and cannot prepare a
+	* channel, no big deal, the driver will fall back
+	* to interrupt mode as a result of this error code.
+	*/
 	if (!desc) {
 		printk(KERN_INFO "!!ERROR DESC !!![%s][%d]Port:[%d]\n",__func__,__LINE__,zup->port.line);
 		zup->dmarx.running = false;
@@ -1229,7 +1415,7 @@
 	zup->dmacr &= ~UART_RXDMAE;
 	UART_PUT_DMACR(&zup->port,zup->dmacr);
 	zx29_dma_stop(rx_id);
-	 zup->curr_sg = NULL;
+	zup->curr_sg = NULL;
 }
 
 static void zx29_dma_remove(struct zx29_uart_port *zup)
@@ -1259,7 +1445,7 @@
 	zup->dmacr &= ~(UART_DMAONERR | UART_RXDMAE | UART_TXDMAE);
 	UART_PUT_DMACR(&zup->port,zup->dmacr);
 	zx29_dma_stop(rx_id);
-	 zup->curr_sg = NULL;
+	zup->curr_sg = NULL;
 	spin_unlock_irqrestore(&zup->port.lock, flags);
 	if (zup->using_tx_dma) {
 		/* In theory, this should already be done by zx29_dma_flush_buffer */
@@ -1339,14 +1525,14 @@
 	UART_PUT_DMACR(&zup->port,zup->dmacr);
 
 	/*
-	 * If TX DMA was disabled, it means that we've stopped the DMA for
-	 * some reason (eg, XOFF received, or we want to send an X-char.)
-	 *
-	 * Note: we need to be careful here of a potential race between DMA
-	 * and the rest of the driver - if the driver disables TX DMA while
-	 * a TX buffer completing, we must update the tx queued status to
-	 * get further refills (hence we check dmacr).
-	 */
+	* If TX DMA was disabled, it means that we've stopped the DMA for
+	* some reason (eg, XOFF received, or we want to send an X-char.)
+	*
+	* Note: we need to be careful here of a potential race between DMA
+	* and the rest of the driver - if the driver disables TX DMA while
+	* a TX buffer completing, we must update the tx queued status to
+	* get further refills (hence we check dmacr).
+	*/
 	if (!(dmacr & UART_TXDMAE) || uart_tx_stopped(&zup->port) ||
 	    uart_circ_empty(&zup->port.state->xmit)) {
 		zup->dmatx.queued = false;
@@ -1361,9 +1547,9 @@
 
 	if (zx29_uart_dma_tx_chars(zup) <= 0) {
 		/*
-		 * We didn't queue a DMA buffer for some reason, but we
-		 * have data pending to be sent.  Re-enable the TX IRQ.
-		 */
+		* We didn't queue a DMA buffer for some reason, but we
+		* have data pending to be sent.  Re-enable the TX IRQ.
+		*/
 		zup->imr |= UART_TXIM;
 		UART_PUT_IMSC(&zup->port, zup->imr);
 	}
@@ -1380,11 +1566,11 @@
 	unsigned int count;
 
 	/*
-	 * Try to avoid the overhead involved in using DMA if the
-	 * transaction fits in the first half of the FIFO, by using
-	 * the standard interrupt handling.  This ensures that we
-	 * issue a uart_write_wakeup() at the appropriate time.
-	 */
+	* Try to avoid the overhead involved in using DMA if the
+	* transaction fits in the first half of the FIFO, by using
+	* the standard interrupt handling.  This ensures that we
+	* issue a uart_write_wakeup() at the appropriate time.
+	*/
  
 	count = uart_circ_chars_pending(xmit);
 	if (count < (16 >> 1)) {
@@ -1426,9 +1612,9 @@
 		dma_unmap_sg(dma_dev->dev, &dmatx->sg, 1, DMA_TO_DEVICE);
 		zup->dmatx.queued = false;
 		/*
-		 * If DMA cannot be used right now, we complete this
-		 * transaction via IRQ and let the TTY layer retry.
-		 */
+		* If DMA cannot be used right now, we complete this
+		* transaction via IRQ and let the TTY layer retry.
+		*/
 		dev_dbg(zup->port.dev, "TX DMA busy\n");
 		return -EBUSY;
 	}	
@@ -1442,9 +1628,9 @@
 	zup->dmatx.queued = true;
 
 	/*
-	 * Now we know that DMA will fire, so advance the ring buffer
-	 * with the stuff we just dispatched.
-	 */
+	* Now we know that DMA will fire, so advance the ring buffer
+	* with the stuff we just dispatched.
+	*/
 	xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1);
 	zup->port.icount.tx += count;
 
@@ -1477,10 +1663,10 @@
 		dma_sync_sg_for_cpu(dev, &sgbuf->sg, 1, DMA_FROM_DEVICE);
 
 		/*
-		 * First take all chars in the DMA pipe, then look in the FIFO.
-		 * Note that tty_insert_flip_buf() tries to take as many chars
-		 * as it can.
-		 */
+		* First take all chars in the DMA pipe, then look in the FIFO.
+		* Note that tty_insert_flip_buf() tries to take as many chars
+		* as it can.
+		*/
 	
 	spin_unlock_irqrestore(&zup->port.lock, *flags);
 	
@@ -1495,28 +1681,28 @@
 		zup->port.icount.rx += dma_count;
 		if (dma_count < pending)
 			dev_info(zup->port.dev,
-				 "couldn't insert all characters (TTY is full?)\n");
+				"couldn't insert all characters (TTY is full?)\n");
 	}
 
 	/*
-	 * Only continue with trying to read the FIFO if all DMA chars have
-	 * been taken first.
-	 */
+	* Only continue with trying to read the FIFO if all DMA chars have
+	* been taken first.
+	*/
 	//if (dma_count == pending && readfifo) {
 	if ((pending > 0) && readfifo) {
 		/* Clear any error flags */
 		//UART_PUT_ICR(&zup->port,UART_OEIC | UART_BEIC | UART_PEIC | UART_FEIC);
 		/*
-		 * If we read all the DMA'd characters, and we had an
-		 * incomplete buffer, that could be due to an rx error, or
-		 * maybe we just timed out. Read any pending chars and check
-		 * the error status.
-		 *
-		 * Error conditions will only occur in the FIFO, these will
-		 * trigger an immediate interrupt and stop the DMA job, so we
-		 * will always find the error in the FIFO, never in the DMA
-		 * buffer.
-		 */
+		* If we read all the DMA'd characters, and we had an
+		* incomplete buffer, that could be due to an rx error, or
+		* maybe we just timed out. Read any pending chars and check
+		* the error status.
+		*
+		* Error conditions will only occur in the FIFO, these will
+		* trigger an immediate interrupt and stop the DMA job, so we
+		* will always find the error in the FIFO, never in the DMA
+		* buffer.
+		*/
 		test_uart_static(zup->port.line, NULL, 0, 7);
 		fifotaken = zx29_uart_fifo_to_tty(zup);
 	}
@@ -1558,10 +1744,10 @@
 
 	if(zx29_dma_rx_running(zup)){
 		/*
-		 * Pause the transfer so we can trust the current counter,
-		 * do this before we pause the block, else we may
-		 * overflow the FIFO.
-		 */
+		* Pause the transfer so we can trust the current counter,
+		* do this before we pause the block, else we may
+		* overflow the FIFO.
+		*/
 	//	if(zx29_dma_stop(rx_id))
 		//	printk( "uart%d unable to pause DMA transfer\n", zup->port.line);
 		//rxchan->device->device_tx_status(rxchan, dmarx->cookie, &state);
@@ -1583,9 +1769,9 @@
 	
 	dmarx->use_buf_b = !dmarx->use_buf_b;
 		/*
-		 * This will take the chars we have so far and insert
-		 * into the framework.
-		 */
+		* This will take the chars we have so far and insert
+		* into the framework.
+		*/
 			zx29_uart_dma_rx_chars(zup, pending, sgbuf, false, flags);
 	}
 
@@ -1633,8 +1819,6 @@
 	//tty_flip_buffer_push(tty);
 	//spin_lock(&zup->port.lock);
 }
-
-
 /****************************************************************************/
 static void zx29_uart_rx_timeout_chars(struct zx29_uart_port *zup, unsigned long *flags)
 {
@@ -1687,10 +1871,10 @@
 
 	if(zx29_dma_rx_running(zup)){
 		/*
-		 * Pause the transfer so we can trust the current counter,
-		 * do this before we pause the block, else we may
-		 * overflow the FIFO.
-		 */
+		* Pause the transfer so we can trust the current counter,
+		* do this before we pause the block, else we may
+		* overflow the FIFO.
+		*/
 		zup->dmacr &= ~UART_RXDMAE;
 		UART_PUT_DMACR(&zup->port,zup->dmacr);
 		zx29_dma_stop(rx_id);
@@ -2130,7 +2314,7 @@
 	if (ret) {
 		printk( "failed to init DMA uart: %d RX buffer B ,ret:%d\n", zup->port.line, ret);
 		zx29_sgbuf_free(zup->dmarx.chan, &zup->dmarx.sgbuf_a,
-				 DMA_FROM_DEVICE);
+				DMA_FROM_DEVICE);
 		goto skip_rx;
 	}
 
@@ -2213,9 +2397,9 @@
 	port->icount.overrun = port->icount.parity = port->icount.rng = 0;
 	port->icount.rx = port->icount.tx = 0;
 	/* 
-	 *enable uart clock 
-	 *if uart is used for console, don't need do these, these was done before
-	 */
+	*enable uart clock 
+	*if uart is used for console, don't need do these, these was done before
+	*/
 	if (DEBUG_CONSOLE != port->line) {	
 	    /*  config uart apb_clk   */
 		clk_prepare_enable(zup->busclk);
@@ -2290,7 +2474,7 @@
 				pcu_int_clear(PCU_UART0_RXD_INT); 
 				ret = request_irq(zup->irq, zx29_uart_rxd_irq,
 			      		IRQF_ONESHOT , "uart_rxd_irq",
-			    		 zup);
+			    		zup);
 				printk(KERN_INFO"zx29_uart_startup, retval:%d\n",ret);
 				irq_set_irq_wake(zup->irq,1);
 #ifdef CONFIG_CPU_IDLE	
@@ -2398,10 +2582,10 @@
 	UART_PUT_CR(port, control);
 
 	/*
-	 * Finally, enable interrupts, only timeouts when using DMA
-	 * if initial RX DMA job failed, start in interrupt mode
-	 * as well.
-	 */
+	* Finally, enable interrupts, only timeouts when using DMA
+	* if initial RX DMA job failed, start in interrupt mode
+	* as well.
+	*/
 	spin_lock_irqsave(&zup->port.lock, flags);
 	/* Clear out any spuriously appearing RX interrupts */
 	UART_PUT_ICR(port, (UART_RTIS | UART_RXIS));
@@ -2568,8 +2752,8 @@
 	spin_lock_irqsave(&port->lock, flags);
 
 	/*
-	 * Update the per-port timeout.
-	 */
+	* Update the per-port timeout.
+	*/
 	uart_update_timeout(port, termios->c_cflag, baud);
 
 	port->read_status_mask = UART_DR_OE | 255;
@@ -2579,24 +2763,24 @@
 		port->read_status_mask |= UART_DR_BE;
 
 	/*
-	 * Characters to ignore
-	 */
+	* Characters to ignore
+	*/
 	port->ignore_status_mask = 0;
 	if (termios->c_iflag & IGNPAR)
 		port->ignore_status_mask |= UART_DR_FE | UART_DR_PE;
 	if (termios->c_iflag & IGNBRK) {
 		port->ignore_status_mask |= UART_DR_BE;
 		/*
-		 * If we're ignoring parity and break indicators,
-		 * ignore overruns too (for real raw support).
-		 */
+		* If we're ignoring parity and break indicators,
+		* ignore overruns too (for real raw support).
+		*/
 		if (termios->c_iflag & IGNPAR)
 			port->ignore_status_mask |= UART_DR_OE;
 	}
 
 	/*
-	 * Ignore all characters if CREAD is not set.
-	 */
+	* Ignore all characters if CREAD is not set.
+	*/
 	if ((termios->c_cflag & CREAD) == 0)
 		port->ignore_status_mask |= UART_DUMMY_DR_RX;
 
@@ -2619,10 +2803,10 @@
 	}
 
 	/*
-	 * ----------v----------v----------v----------v-----
-	 * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L
-	 * ----------^----------^----------^----------^-----
-	 */
+	* ----------v----------v----------v----------v-----
+	* NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L
+	* ----------^----------^----------^----------^-----
+	*/
 	UART_PUT_LCRH(port, lcr_h);
 	UART_PUT_CR(port, old_cr);
 
@@ -2805,7 +2989,7 @@
         * just configure clock, 
         * actually pin configuration is needed, but now gpio driver is not OK
         * use bootloader default configuration
-	 */
+	*/
     if(DEBUG_CONSOLE == pdev->id){
 		/*  config uart apb_clk   */
 		clk_prepare_enable(zx29_port->busclk);
@@ -2819,6 +3003,28 @@
 
 #ifdef CONFIG_SERIAL_ZX29_UART_CONSOLE
 
+#if VEHICLE_USE_ONE_UART_LOG
+static void zx29_uart_console_putc(struct uart_port *port, int c)
+{
+	if(g_core_id_occupy_uart == SYMB_PS_CORE_ID)
+		return;
+	soft_spin_lock(UART_SFLOCK);
+	while (UART_GET_FR(port) & UART_FR_TXFF)
+		barrier();
+	UART_PUT_CHAR(port, c);
+	soft_spin_unlock(UART_SFLOCK);
+}
+static void zx29_uart_console_putc_printf(struct uart_port *port, int c)
+{
+	int ret;
+	ret = soft_spin_lock_printf(UART_SFLOCK);
+	while (UART_GET_FR(port) & UART_FR_TXFF)
+		barrier();
+	UART_PUT_CHAR(port, c);
+	if(!ret)
+		soft_spin_unlock(UART_SFLOCK);
+}
+#else
 /****************************************************************************/
 static void zx29_uart_console_putc(struct uart_port *port, int c)
 {
@@ -2826,6 +3032,7 @@
 		barrier();
 	UART_PUT_CHAR(port, c);
 }
+#endif
 
 
 /****************************************************************************/
@@ -2848,7 +3055,7 @@
  * try to determine the current setup.
  ****************************************************************************/
 static void __init zx29_console_get_options(struct uart_port *port, int *baud,
-						 int *parity, int *bits)
+						int *parity, int *bits)
 {
 	if (UART_GET_CR(port) & UART_CR_UARTEN) {
 		unsigned int lcr_h, ibrd, fbrd;
@@ -3022,7 +3229,7 @@
 {
 	int ret=0;	
 	int error;
-	 char    wakelock_name[20];
+	char    wakelock_name[20];
 	struct device_node *np = pdev->dev.of_node;
 	ret = of_alias_get_id(np, "uart");
 
@@ -3066,7 +3273,7 @@
 		return ret;
 	}
 #if CONFIG_SERIAL_ZX29_DMA
-	 sema_init(&port->sema, 0);
+	sema_init(&port->sema, 0);
 #endif
 
 	/*platform_set_drvdata(pdev, port);*/
@@ -3074,6 +3281,16 @@
 	if(pdev->id == DEBUG_CONSOLE){
 		//g_console_open_flag = pdata->uart_input_enable ? pdata->uart_input_enable : 0;
 		error = device_create_file(&pdev->dev, &dev_attr_console_input);
+#if VEHICLE_USE_ONE_UART_LOG
+		error = device_create_file(&pdev->dev, &dev_attr_console_uart_toggle);
+		error = device_create_file(&pdev->dev, &dev_attr_coreid_occupy_uart);
+		int ret;
+		ret = rpmsgCreateChannel(CORE_PS0, ICP_CHANNEL_CONSOLE_UART, ICP_BUFFERSIZE_CONSOLE_TOGGLE);
+		if(ret){
+			printk("linux5 request icp channel for uart fail %d.\n",ret);
+		}
+		rpmsgRegCallBack(CORE_PS0, ICP_CHANNEL_CONSOLE_UART, icp_callback_ps2cap);
+#endif
 	}
 	
 	if(pdev->id != DEBUG_CONSOLE){
@@ -3101,7 +3318,7 @@
 #endif
 	int i;
 	if(pdev->id == DEBUG_CONSOLE){		
-		 device_remove_file(&pdev->dev, &dev_attr_console_input);
+		device_remove_file(&pdev->dev, &dev_attr_console_input);
 	}
 	
 	if(pdev->id != DEBUG_CONSOLE){
@@ -3173,4 +3390,3 @@
 //subsys_initcall(zx29_uart_init);
 module_init(zx29_uart_init);
 module_exit(zx29_uart_exit);
-
diff --git a/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/include/linux/soc/zte/spinlock.h b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/include/linux/soc/zte/spinlock.h
index c2c49c1..ec20d83 100644
--- a/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/include/linux/soc/zte/spinlock.h
+++ b/cap/zx297520v3/zxic_code/zxic_source/linux-5.10/include/linux/soc/zte/spinlock.h
@@ -105,6 +105,6 @@
 void  soft_spin_unlock_psm(emsf_lock_id sfid);

 

 void zx_spinlock_init(void __iomem *spinlock_base);

-

+int  soft_spin_lock_printf(emsf_lock_id sfid);

 #endif/* _SPINLOCK_H */