[Feature][ZXW-179]merge P52U02 version

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: I4fa8f86757e71388ae88400914dae8b50cd00338
diff --git a/ap/os/linux/linux-3.4.x/drivers/mtd/mtdadapter.c b/ap/os/linux/linux-3.4.x/drivers/mtd/mtdadapter.c
old mode 100644
new mode 100755
index c7b418a..1cc4218
--- a/ap/os/linux/linux-3.4.x/drivers/mtd/mtdadapter.c
+++ b/ap/os/linux/linux-3.4.x/drivers/mtd/mtdadapter.c
@@ -19,6 +19,7 @@
 #include <linux/kernel.h> 
 #include <linux/mtd/mtd.h>
 #include <linux/module.h>
+#include <linux/soc/zte/otp/otp_zx.h>
 
 #define READ_ZLOADER_FLAG_SIZE 0x800
 #define WRITE_ZLOADER_FLAG_SIZE 0x3000
@@ -26,6 +27,8 @@
 
 extern struct mtd_info *mtd_fota;
 extern int g_zload_read_only_flag;
+extern char *nor_cmdline;
+unsigned char nor_flag = 0;
 
 #ifndef USE_CPPS_KO
 extern unsigned int zOss_NvItemRead(unsigned int NvItemID, unsigned char *NvItemData, unsigned int NvItemLen);
@@ -212,23 +215,59 @@
     if( buffer == NULL )
         return -1;
 
-    if(mtd_read(mtd_fota,0,READ_ZLOADER_FLAG_SIZE,&retlen,buffer))/* BOOTFLAGÔÚnandµÄµÚ20~27×Ö½Ú */
-    {
-        kfree(buffer);
-        return 1;
-    }
-	memcpy(&value, buffer+2, 1); 
-	bootflag = value;
-   
-    if( bootflag == 0x5a)
-    {
-        bootflag = 1;
-    }
+	if(nor_cmdline != NULL)
+	{
+		if (!strcmp(nor_cmdline, "1"))
+		{
+		    nor_flag = 1;
+			printk("----------EnhancedSecurity---------\n");
+		}
+	}
+	if(1 == nor_flag)
+	{
+#ifndef CONFIG_SPI_ZXIC_NOR
+
+		if(nor_read(0, 256, buffer))
+	    {
+	        kfree(buffer);
+	        return 1;
+	    }
+		memcpy(&value, buffer+2, 1); 
+		bootflag = value;
+	   
+	    if( bootflag == 0x5a)
+	    {
+	        bootflag = 1;
+	    }
+		else
+		{
+	        bootflag = 0;
+		}
+	    kfree(buffer);
+#endif
+	}
 	else
 	{
-        bootflag = 0;
-	}
-    kfree(buffer);
+		if(mtd_read(mtd_fota,0,READ_ZLOADER_FLAG_SIZE,&retlen,buffer))/* BOOTFLAGÔÚnandµÄµÚ20~27×Ö½Ú */
+	    {
+	        kfree(buffer);
+	        return 1;
+	    }
+		memcpy(&value, buffer+2, 1); 
+		bootflag = value;
+	   
+	    if( bootflag == 0x5a)
+	    {
+	        bootflag = 1;
+	    }
+		else
+		{
+	        bootflag = 0;
+		}
+	    kfree(buffer);
+
+	}  
+    
 
 	return bootflag;
 }
@@ -246,38 +285,87 @@
 	int bootflag = 0;
 	int retlen = 0;
     struct erase_info ei;
-	
-    unsigned char *buffer = kzalloc(WRITE_ZLOADER_FLAG_SIZE,GFP_KERNEL);
 
-    if( buffer == NULL )
-        return -1;
-
-    if(mtd_read(mtd_fota,0,WRITE_ZLOADER_FLAG_SIZE,&retlen,buffer))/* BOOTFLAGÔÚnandµÄµÚ20~27×Ö½Ú */
-    {
-        kfree(buffer);
-        return -1;
-    }
-	if(flag == 0 )
+	if(nor_cmdline != NULL)
 	{
-	    bootflag = 0x00;
-        memset(&value, bootflag, 1);
+		if (!strcmp(nor_cmdline, "1"))
+		{
+		    nor_flag = 1;
+			printk("----------EnhancedSecurity---------\n");
+		}else{
+			printk("----------normal---------\n");
+		}
+	}else{
+	    printk("----------nor cmdline is null!---------\n");
 	}
-    else
-    {
-        bootflag = 0x5a;
-        memset(&value, bootflag, 1);
-    }
+
+	if(1 == nor_flag)
+	{
+#ifndef CONFIG_SPI_ZXIC_NOR
+
+	    unsigned char *buffer = kmalloc(0x10000, GFP_KERNEL);
+
+	    if( buffer == NULL )
+	        return -1;
 	
-    memcpy(buffer+2, &value, 1);
-    memset(&ei, 0, sizeof(struct erase_info));
-    ei.mtd  = mtd_fota;
-    ei.addr = 0;
-    ei.len  = mtd_fota->erasesize;
-	g_zload_read_only_flag = 1;
-    ret = mtd_erase(mtd_fota, &ei);                  /*²Á³ýµÚÒ»¿é*/
-	ret = mtd_write(mtd_fota,0,WRITE_ZLOADER_FLAG_SIZE,&retlen,buffer);
-	g_zload_read_only_flag = 0;
-    kfree(buffer);
+	    if(nor_read(0,0x10000,buffer))
+		{
+			kfree(buffer);
+			return -1;
+		}
+		if(flag == 0 )
+		{
+			bootflag = 0x00;
+			memset(&value, bootflag, 1);
+		}
+		else
+		{
+			bootflag = 0x5a;
+			memset(&value, bootflag, 1);
+		}
+
+		memcpy(buffer+2, &value, 1);
+
+		ret = nor_erase(0);
+		ret = nor_write(0,0x10000,buffer);
+		kfree(buffer);
+#endif
+	}
+	else
+	{
+	    unsigned char *buffer = kzalloc(WRITE_ZLOADER_FLAG_SIZE,GFP_KERNEL);
+
+	    if( buffer == NULL )
+	        return -1;
+
+	    if(mtd_read(mtd_fota,0,WRITE_ZLOADER_FLAG_SIZE,&retlen,buffer))/* BOOTFLAGÔÚnandµÄµÚ20~27×Ö½Ú */
+	    {
+	        kfree(buffer);
+	        return -1;
+	    }
+		if(flag == 0 )
+		{
+		    bootflag = 0x00;
+	        memset(&value, bootflag, 1);
+		}
+	    else
+	    {
+	        bootflag = 0x5a;
+	        memset(&value, bootflag, 1);
+	    }
+		
+	    memcpy(buffer+2, &value, 1);
+	    memset(&ei, 0, sizeof(struct erase_info));
+	    ei.mtd  = mtd_fota;
+	    ei.addr = 0;
+	    ei.len  = mtd_fota->erasesize;
+		g_zload_read_only_flag = 1;
+	    ret = mtd_erase(mtd_fota, &ei);                  /*²Á³ýµÚÒ»¿é*/
+		ret = mtd_write(mtd_fota,0,WRITE_ZLOADER_FLAG_SIZE,&retlen,buffer);
+		g_zload_read_only_flag = 0;
+	    kfree(buffer);
+
+	}   
 
     return 0;
 
diff --git a/ap/os/linux/linux-3.4.x/drivers/mtd/nand/nand_base.c b/ap/os/linux/linux-3.4.x/drivers/mtd/nand/nand_base.c
index d259c4c..edb5c5a 100755
--- a/ap/os/linux/linux-3.4.x/drivers/mtd/nand/nand_base.c
+++ b/ap/os/linux/linux-3.4.x/drivers/mtd/nand/nand_base.c
@@ -114,6 +114,8 @@
 
 extern struct cmdline_mtd_partition *partitions;
 
+extern struct mutex otpMutex;
+
 extern  void denali_set_intr_modes(struct denali_nand_info *denali,
 					uint16_t INT_ENABLE);
 static int nand_get_device(struct nand_chip *chip, struct mtd_info *mtd,
@@ -1729,6 +1731,8 @@
 	int ret;
 	
 	nand_get_device(chip, mtd, FL_READING);
+	mutex_lock(&otpMutex);
+	
 	/*ops.len = len;
 	ops.datbuf = buf;
 	ops.oobbuf = NULL;
@@ -1741,6 +1745,8 @@
 	
 	//*retlen = ops.retlen;
 	*retlen = chip->ops.retlen;
+
+	mutex_unlock(&otpMutex);
 	nand_release_device(mtd);
 	return ret;
 }
@@ -2011,6 +2017,7 @@
 		return -EINVAL;
 	}
 	nand_get_device(chip, mtd, FL_READING);
+	mutex_lock(&otpMutex);
 
 	switch (ops->mode) {
 	case MTD_OPS_PLACE_OOB:
@@ -2027,6 +2034,7 @@
 	else
 		ret = nand_do_read_ops(mtd, from, ops);
 out:
+	mutex_unlock(&otpMutex);
 	nand_release_device(mtd);
 	return ret;
 }
@@ -2473,12 +2481,14 @@
 	int ret;
 		
 	nand_get_device(chip, mtd, FL_WRITING);
+	mutex_lock(&otpMutex);
 	ops.len = len;
 	ops.datbuf = (uint8_t *)buf;
 	ops.oobbuf = NULL;
 	ops.mode = 0;
 	ret = nand_do_write_ops(mtd, to, &ops);
 	*retlen = ops.retlen;
+	mutex_unlock(&otpMutex);
 	nand_release_device(mtd);
 		
 	return ret;
@@ -2596,6 +2606,7 @@
 	}
 
 	nand_get_device(chip, mtd, FL_WRITING);
+	mutex_lock(&otpMutex);
 
 	switch (ops->mode) {
 	case MTD_OPS_PLACE_OOB:
@@ -2612,6 +2623,7 @@
 	else
 		ret = nand_do_write_ops(mtd, to, ops);
 out:
+	mutex_unlock(&otpMutex);
 	nand_release_device(mtd);	
 	return ret;
 }
@@ -2695,6 +2707,7 @@
 
 	/* Grab the lock and see if the device is available */
 	nand_get_device(chip, mtd, FL_ERASING);
+	mutex_lock(&otpMutex);
 
 	/* Shift to get first page */
 	page = (int)(instr->addr >> chip->page_shift);
@@ -2804,6 +2817,7 @@
 	ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
 
 	/* Deselect and wake up anyone waiting on the device */
+	mutex_unlock(&otpMutex);
 	nand_release_device(mtd);
 
 	/* Do call back function */
diff --git a/ap/os/linux/linux-3.4.x/drivers/mtd/nand/spi_nand.c b/ap/os/linux/linux-3.4.x/drivers/mtd/nand/spi_nand.c
index e1ac821..0cc1f5b 100755
--- a/ap/os/linux/linux-3.4.x/drivers/mtd/nand/spi_nand.c
+++ b/ap/os/linux/linux-3.4.x/drivers/mtd/nand/spi_nand.c
@@ -670,6 +670,7 @@
 {
     int ret = 0;
     uint32_t ecc = 0;
+	uint8_t feature = (ECC_EN|QE);
     struct spi_nand_info *spi_nand = mtd_to_spi_nand(mtd);
 	struct spi_nand_ctrl_ops *ctrl = spi_nand->ctrl;
 	int real_page; 
@@ -685,6 +686,15 @@
         
     }
 
+	/*check ecc enable*/
+	/*
+	ctrl->get_feature(REG_FEATURE, &feature);
+	if(!(feature & ECC_EN))
+	{
+		printk("[SPI-NAND] read page 0x%x while ecc is disable!,feature is 0x%x\n",page,feature);
+		//BUG_ON(1);
+	}*/
+
 	real_page = spi_nand_get_real_page(mtd, page);
 
     ret = ctrl->read_page_to_cache(real_page);
@@ -700,11 +710,13 @@
         printk("[SPI-NAND][spi_nand_check_ecc]\n");
         
     }
-    if ( ecc != 0 )
+	
+    if ( ecc != 0 && (chip->ops.mode != MTD_OPS_RAW))
     {
 		g_cur_ecc_page_addr = real_page*mtd->writesize;
 #ifdef __ECC_CHECK_SUPPORT__
 		mtd->ecc_stats.failed++;
+        printk("ecc_stats.failed++\n");
 #endif
     }
 	if((spi_nand->para->planes == 2) && (((real_page >> 6)%2) != 0))
diff --git a/ap/os/linux/linux-3.4.x/drivers/mtd/nand/zxic_spifc.c b/ap/os/linux/linux-3.4.x/drivers/mtd/nand/zxic_spifc.c
index 16c0efe..e6034ef 100755
--- a/ap/os/linux/linux-3.4.x/drivers/mtd/nand/zxic_spifc.c
+++ b/ap/os/linux/linux-3.4.x/drivers/mtd/nand/zxic_spifc.c
@@ -55,6 +55,8 @@
 static uint32_t spi_fc_wait_cmd_end(void);
 int winbond_dev_id2 = 0;
 unsigned char g_nor_flag = 0;
+struct mutex otpMutex;
+
 /* SPI NAND FLASH COMMAND FORMAT TYPE */
 /********************************************************************************
   [Instruction]                 |--write enable
@@ -923,6 +925,10 @@
             continue;   /* ´«Êäʧ°Ü£¬½áÊø±¾´ÎÑ­»·²¢ÖØ´« */
         }
 
+		if(g_nor_flag == 1)
+			gpio_set_value(86,GPIO_HIGH);//spp
+		
+
         ret = spi_fc_read_fifo(len,value);     /* ¶ÁÈ¡Êý¾Ý */
 		
         if ( ret != SUCCESS )
@@ -930,9 +936,6 @@
             //spi_fc_disable();
             continue;   /* ´«Êäʧ°Ü£¬½áÊø±¾´ÎÑ­»·²¢ÖØ´« */
         }
-
-		if(g_nor_flag == 1)
-			gpio_set_value(86,GPIO_HIGH);//spp
 		
         break;
     }
@@ -1869,8 +1872,11 @@
 		}
 	}
 
+
 	pr_info("----------spi_nand_probe-----------\n");
 
+	mutex_init(&otpMutex);
+
 	spifc = kzalloc(sizeof(*spifc), GFP_KERNEL);
 	if (!spifc)
 		return -ENOMEM;