[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/arch/arm/mm/fault.c b/ap/os/linux/linux-3.4.x/arch/arm/mm/fault.c
index 7d6902f..73f76ac 100755
--- a/ap/os/linux/linux-3.4.x/arch/arm/mm/fault.c
+++ b/ap/os/linux/linux-3.4.x/arch/arm/mm/fault.c
@@ -21,12 +21,12 @@
 #ifdef CONFIG_MMU
 #ifdef CONFIG_KPROBES
 static inline int notify_page_fault(struct pt_regs*regs,unsigned int fsr){int 
-ret=(0x476+8165-0x245b);if(!user_mode(regs)){preempt_disable();if(kprobe_running
-()&&kprobe_fault_handler(regs,fsr))ret=(0x1a75+1842-0x21a6);preempt_enable();}
-return ret;}
+ret=(0x10cf+4777-0x2378);if(!user_mode(regs)){preempt_disable();if(
+kprobe_running()&&kprobe_fault_handler(regs,fsr))ret=(0x2526+92-0x2581);
+preempt_enable();}return ret;}
 #else
 static inline int notify_page_fault(struct pt_regs*regs,unsigned int fsr){return
-(0xc63+4795-0x1f1e);}
+(0x68+5818-0x1722);}
 #endif
 void show_pte(struct mm_struct*mm,unsigned long addr){pgd_t*pgd;if(!mm)mm=&
 init_mm;printk(KERN_ALERT"\x70\x67\x64\x20\x3d\x20\x25\x70" "\n",mm->pgd);pgd=
@@ -34,10 +34,10 @@
 "\x5b\x25\x30\x38\x6c\x78\x5d\x20\x2a\x70\x67\x64\x3d\x25\x30\x38\x6c\x6c\x78",
 addr,(long long)pgd_val(*pgd));do{pud_t*pud;pmd_t*pmd;pte_t*pte;if(pgd_none(*pgd
 ))break;if(pgd_bad(*pgd)){printk("\x28\x62\x61\x64\x29");break;}pud=pud_offset(
-pgd,addr);if(PTRS_PER_PUD!=(0x4fd+4800-0x17bc))printk(
+pgd,addr);if(PTRS_PER_PUD!=(0xa93+6427-0x23ad))printk(
 "\x2c\x20\x2a\x70\x75\x64\x3d\x25\x30\x38\x6c\x6c\x78",(long long)pud_val(*pud))
 ;if(pud_none(*pud))break;if(pud_bad(*pud)){printk("\x28\x62\x61\x64\x29");break;
-}pmd=pmd_offset(pud,addr);if(PTRS_PER_PMD!=(0x1460+2716-0x1efb))printk(
+}pmd=pmd_offset(pud,addr);if(PTRS_PER_PMD!=(0x102d+1714-0x16de))printk(
 "\x2c\x20\x2a\x70\x6d\x64\x3d\x25\x30\x38\x6c\x6c\x78",(long long)pmd_val(*pmd))
 ;if(pmd_none(*pmd))break;if(pmd_bad(*pmd)){printk("\x28\x62\x61\x64\x29");break;
 }if(PageHighMem(pfn_to_page(pmd_val(*pmd)>>PAGE_SHIFT)))break;pte=pte_offset_map
@@ -47,18 +47,18 @@
 printk("\x2c\x20\x2a\x70\x70\x74\x65\x3d\x25\x30\x38\x6c\x6c\x78",(long long)
 pte_val(pte[PTE_HWTABLE_PTRS]));
 #endif
-pte_unmap(pte);}while((0x8d9+7646-0x26b7));printk("\n");}
+pte_unmap(pte);}while((0xadb+4004-0x1a7f));printk("\n");}
 #else					
 void show_pte(struct mm_struct*mm,unsigned long addr){}
 #endif					
 static void __do_kernel_fault(struct mm_struct*mm,unsigned long addr,unsigned 
 int fsr,struct pt_regs*regs){if(fixup_exception(regs))return;bust_spinlocks(
-(0xa24+203-0xaee));printk(KERN_ALERT
+(0x693+5051-0x1a4d));printk(KERN_ALERT
 "\x55\x6e\x61\x62\x6c\x65\x20\x74\x6f\x20\x68\x61\x6e\x64\x6c\x65\x20\x6b\x65\x72\x6e\x65\x6c\x20\x25\x73\x20\x61\x74\x20\x76\x69\x72\x74\x75\x61\x6c\x20\x61\x64\x64\x72\x65\x73\x73\x20\x25\x30\x38\x6c\x78" "\n"
 ,(addr<PAGE_SIZE)?
 "\x4e\x55\x4c\x4c\x20\x70\x6f\x69\x6e\x74\x65\x72\x20\x64\x65\x72\x65\x66\x65\x72\x65\x6e\x63\x65"
 :"\x70\x61\x67\x69\x6e\x67\x20\x72\x65\x71\x75\x65\x73\x74",addr);show_pte(mm,
-addr);die("\x4f\x6f\x70\x73",regs,fsr);bust_spinlocks((0x11bc+2271-0x1a9b));
+addr);die("\x4f\x6f\x70\x73",regs,fsr);bust_spinlocks((0x19a0+1715-0x2053));
 do_exit(SIGKILL);}static void __do_user_fault(struct task_struct*tsk,unsigned 
 long addr,unsigned int fsr,unsigned int sig,int code,struct pt_regs*regs){struct
  siginfo si;
@@ -69,7 +69,7 @@
 ,tsk->comm,sig,addr,fsr);show_pte(tsk->mm,addr);show_regs(regs);}
 #endif
 tsk->thread.address=addr;tsk->thread.error_code=fsr;tsk->thread.trap_no=
-(0x114b+3538-0x1f0f);si.si_signo=sig;si.si_errno=(0x19d2+357-0x1b37);si.si_code=
+(0x1884+305-0x19a7);si.si_signo=sig;si.si_errno=(0x184c+3084-0x2458);si.si_code=
 code;si.si_addr=(void __user*)addr;force_sig_info(sig,&si,tsk);}void do_bad_area
 (unsigned long addr,unsigned int fsr,struct pt_regs*regs){struct task_struct*tsk
 =current;struct mm_struct*mm=tsk->active_mm;if(user_mode(regs))__do_user_fault(
@@ -91,9 +91,9 @@
 static int __kprobes do_page_fault(unsigned long addr,unsigned int fsr,struct 
 pt_regs*regs){struct task_struct*tsk;struct mm_struct*mm;int fault,sig,code;int 
 write=fsr&FSR_WRITE;unsigned int flags=FAULT_FLAG_ALLOW_RETRY|
-FAULT_FLAG_KILLABLE|(write?FAULT_FLAG_WRITE:(0xb6b+52-0xb9f));if(
-notify_page_fault(regs,fsr))return(0x1975+3197-0x25f2);tsk=current;mm=tsk->mm;if
-(interrupts_enabled(regs))local_irq_enable();if(!mm||pagefault_disabled())goto 
+FAULT_FLAG_KILLABLE|(write?FAULT_FLAG_WRITE:(0x27b+5387-0x1786));if(
+notify_page_fault(regs,fsr))return(0x412+4514-0x15b4);tsk=current;mm=tsk->mm;if(
+interrupts_enabled(regs))local_irq_enable();if(!mm||pagefault_disabled())goto 
 no_context;if(!down_read_trylock(&mm->mmap_sem)){if(!user_mode(regs)&&!
 search_exception_tables(regs->ARM_pc))goto no_context;retry:down_read(&mm->
 mmap_sem);}else{might_sleep();
@@ -101,23 +101,23 @@
 if(!user_mode(regs)&&!search_exception_tables(regs->ARM_pc))goto no_context;
 #endif
 }fault=__do_page_fault(mm,addr,fsr,flags,tsk);if((fault&VM_FAULT_RETRY)&&
-fatal_signal_pending(current))return(0x2e3+4659-0x1516);perf_sw_event(
-PERF_COUNT_SW_PAGE_FAULTS,(0x1997+704-0x1c56),regs,addr);if(!(fault&
+fatal_signal_pending(current))return(0xd4d+1889-0x14ae);perf_sw_event(
+PERF_COUNT_SW_PAGE_FAULTS,(0x173b+2031-0x1f29),regs,addr);if(!(fault&
 VM_FAULT_ERROR)&&flags&FAULT_FLAG_ALLOW_RETRY){if(fault&VM_FAULT_MAJOR){tsk->
-maj_flt++;perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ,(0x9b5+2609-0x13e5),regs,
+maj_flt++;perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ,(0x289+5023-0x1627),regs,
 addr);}else{tsk->min_flt++;perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN,
-(0x5d5+5222-0x1a3a),regs,addr);}if(fault&VM_FAULT_RETRY){flags&=~
+(0xfec+801-0x130c),regs,addr);}if(fault&VM_FAULT_RETRY){flags&=~
 FAULT_FLAG_ALLOW_RETRY;goto retry;}}up_read(&mm->mmap_sem);if(likely(!(fault&(
-VM_FAULT_ERROR|VM_FAULT_BADMAP|VM_FAULT_BADACCESS))))return(0x4b8+6712-0x1ef0);
-if(fault&VM_FAULT_OOM){pagefault_out_of_memory();return(0x11c+2508-0xae8);}if(!
+VM_FAULT_ERROR|VM_FAULT_BADMAP|VM_FAULT_BADACCESS))))return(0x1547+4065-0x2528);
+if(fault&VM_FAULT_OOM){pagefault_out_of_memory();return(0xb6a+5412-0x208e);}if(!
 user_mode(regs))goto no_context;if(fault&VM_FAULT_SIGBUS){sig=SIGBUS;code=
 BUS_ADRERR;}else{sig=SIGSEGV;code=fault==VM_FAULT_BADACCESS?SEGV_ACCERR:
 SEGV_MAPERR;}__do_user_fault(tsk,addr,fsr,sig,code,regs);return
-(0xeb8+5181-0x22f5);no_context:__do_kernel_fault(mm,addr,fsr,regs);return
-(0x109f+233-0x1188);}
+(0x1548+205-0x1615);no_context:__do_kernel_fault(mm,addr,fsr,regs);return
+(0x44c+6307-0x1cef);}
 #else					
 static int do_page_fault(unsigned long addr,unsigned int fsr,struct pt_regs*regs
-){return(0xfd5+28-0xff1);}
+){return(0xefa+4246-0x1f90);}
 #endif					
 #ifdef CONFIG_MMU
 static int __kprobes do_translation_fault(unsigned long addr,unsigned int fsr,
@@ -130,21 +130,21 @@
 bad_area;if(!pud_present(*pud))set_pud(pud,*pud_k);pmd=pmd_offset(pud,addr);
 pmd_k=pmd_offset(pud_k,addr);
 #ifdef CONFIG_ARM_LPAE
-index=(0x275+8084-0x2209);
+index=(0x1d5+278-0x2eb);
 #else
-index=(addr>>SECTION_SHIFT)&(0x24f+8817-0x24bf);
+index=(addr>>SECTION_SHIFT)&(0x14fa+1753-0x1bd2);
 #endif
 if(pmd_none(pmd_k[index]))goto bad_area;copy_pmd(pmd,pmd_k);return
-(0xac5+2445-0x1452);bad_area:do_bad_area(addr,fsr,regs);return(0x45a+1734-0xb20)
-;}
+(0xc0c+6216-0x2454);bad_area:do_bad_area(addr,fsr,regs);return
+(0x193a+2083-0x215d);}
 #else					
 static int do_translation_fault(unsigned long addr,unsigned int fsr,struct 
-pt_regs*regs){return(0x629+3872-0x1549);}
+pt_regs*regs){return(0x751+3133-0x138e);}
 #endif					
 static int do_sect_fault(unsigned long addr,unsigned int fsr,struct pt_regs*regs
 ){if(interrupts_enabled(regs))local_irq_enable();do_bad_area(addr,fsr,regs);
-return(0x5e9+6240-0x1e49);}static int do_bad(unsigned long addr,unsigned int fsr
-,struct pt_regs*regs){return(0x178b+717-0x1a57);}struct fsr_info{int(*fn)(
+return(0x36d+6227-0x1bc0);}static int do_bad(unsigned long addr,unsigned int fsr
+,struct pt_regs*regs){return(0x90a+6430-0x2227);}struct fsr_info{int(*fn)(
 unsigned long addr,unsigned int fsr,struct pt_regs*regs);int sig;int code;const 
 char*name;};
 #ifdef CONFIG_ARM_LPAE
@@ -153,21 +153,21 @@
 #include "fsr-2level.c"
 #endif
 void __init hook_fault_code(int nr,int(*fn)(unsigned long,unsigned int,struct 
-pt_regs*),int sig,int code,const char*name){if(nr<(0xb92+569-0xdcb)||nr>=
+pt_regs*),int sig,int code,const char*name){if(nr<(0x10e4+4307-0x21b7)||nr>=
 ARRAY_SIZE(fsr_info))BUG();fsr_info[nr].fn=fn;fsr_info[nr].sig=sig;fsr_info[nr].
 code=code;fsr_info[nr].name=name;}
 #ifdef CONFIG_MODEM_CODE_IS_MAPPING
 static DECLARE_RWSEM(shrinker_rwsem);atomic_t _code_page_count=ATOMIC_INIT(
-(0x265+3892-0x1199));struct addr_info{struct list_head node;unsigned long vaddr;
+(0xaba+2616-0x14f2));struct addr_info{struct list_head node;unsigned long vaddr;
 unsigned long kaddr;unsigned long page_index;};enum modem_access_technology{GSM=
-(0x151b+2288-0x1e0b),UTRAN=(0x6bf+4679-0x1905),LTE=(0x5a4+2420-0xf16),COM=
-(0x1892+2343-0x21b6),NR_MODEM_ACCESS=(0x23f+6560-0x1bdb)};struct list_head 
+(0x858+1778-0xf4a),UTRAN=(0x7bb+6127-0x1fa9),LTE=(0x758+1563-0xd71),COM=
+(0x2022+1256-0x2507),NR_MODEM_ACCESS=(0x468+7954-0x2376)};struct list_head 
 modem_page_list[NR_MODEM_ACCESS]={LIST_HEAD_INIT(modem_page_list[
-(0x11e3+1572-0x1807)]),LIST_HEAD_INIT(modem_page_list[(0x12d7+3686-0x213c)]),
-LIST_HEAD_INIT(modem_page_list[(0x4b+6599-0x1a10)]),LIST_HEAD_INIT(
-modem_page_list[(0x624+6859-0x20ec)]),};unsigned int page_used[
-(0xe05+3499-0x1b88)];struct completion page_completion[(0x180b+3415-0x253a)*
-(0x1635+1312-0x1b35)];static void unmap_pte_range(pmd_t*pmd,unsigned long addr,
+(0x7b1+7792-0x2621)]),LIST_HEAD_INIT(modem_page_list[(0xf8+8818-0x2369)]),
+LIST_HEAD_INIT(modem_page_list[(0x1365+1369-0x18bc)]),LIST_HEAD_INIT(
+modem_page_list[(0x730+7892-0x2601)]),};unsigned int page_used[
+(0x7c9+3414-0x14f7)];struct completion page_completion[(0x58a+6492-0x1ebe)*
+(0xaf1+881-0xe42)];static void unmap_pte_range(pmd_t*pmd,unsigned long addr,
 unsigned long end){pte_t*pte;pte=pte_offset_kernel(pmd,addr);do{pte_t ptent=
 ptep_get_and_clear(&init_mm,addr,pte);WARN_ON(!pte_none(ptent)&&!pte_present(
 ptent));}while(pte++,addr+=PAGE_SIZE,addr!=end);}static void unmap_pmd_range(
@@ -181,124 +181,125 @@
 addr,unsigned long end){pgd_t*pgd;unsigned long next;BUG_ON(addr>=end);pgd=
 pgd_offset_k(addr);do{next=pgd_addr_end(addr,end);if(pgd_none_or_clear_bad(pgd))
 continue;unmap_pud_range(pgd,addr,next);}while(pgd++,addr=next,addr!=end);}void 
-shrink_modem_mem(unsigned int access_type){int i=(0x1c8a+1686-0x2320);unsigned 
+shrink_modem_mem(unsigned int access_type){int i=(0xf1a+3533-0x1ce7);unsigned 
 long vaddr;struct addr_info*addr,*tmp_addr;struct list_head tmp_page_list;for(i=
-(0x1e9d+520-0x20a5);i<NR_MODEM_ACCESS;i++){if(i==access_type)continue;down_write
+(0x56c+6679-0x1f83);i<NR_MODEM_ACCESS;i++){if(i==access_type)continue;down_write
 (&shrinker_rwsem);list_replace_init(&modem_page_list[i],&tmp_page_list);up_write
 (&shrinker_rwsem);list_for_each_entry_safe(addr,tmp_addr,&tmp_page_list,node){
 list_del_init(&addr->node);page_completion[addr->page_index].done=
-(0x151f+3520-0x22df);page_used[addr->page_index/BITS_PER_LONG]&=~(
-(0x11d5+4290-0x2296)<<(addr->page_index%BITS_PER_LONG));vaddr=addr->vaddr&
-PAGE_MASK;if(vaddr<cpps_global_var.cpko_text_start||vaddr>cpps_global_var.
-modem_text_end){panic(
+(0x580+4899-0x18a3);page_used[addr->page_index/BITS_PER_LONG]&=~(
+(0x9f5+898-0xd76)<<(addr->page_index%BITS_PER_LONG));vaddr=addr->vaddr&PAGE_MASK
+;if(vaddr<cpps_global_var.cpko_text_start||vaddr>cpps_global_var.modem_text_end)
+{panic(
 "\x61\x64\x64\x72\x5f\x69\x6e\x66\x6f\x3a\x20\x25\x30\x38\x78\x20\x69\x73\x20\x20\x64\x65\x73\x74\x72\x6f\x79"
 ,addr);}flush_cache_vunmap(vaddr,vaddr+PAGE_SIZE);unmap_page_range(vaddr,vaddr+
 PAGE_SIZE);flush_tlb_kernel_range(vaddr,vaddr+PAGE_SIZE);
 #ifdef CONFIG_DEBUG_RODATA
 unsigned int flags;local_irq_save(flags);set_memory_rw(addr->kaddr,
-(0x2378+489-0x2560));local_irq_restore(flags);
+(0x17e1+476-0x19bc));local_irq_restore(flags);
 #endif
 free_page(addr->kaddr);kfree(addr);atomic_dec(&_code_page_count);};}}
 EXPORT_SYMBOL(shrink_modem_mem);phys_addr_t virt_is_mapping(unsigned long addr){
 pgd_t*pgd;pmd_t*pmd;pte_t*ptep,pte;unsigned long pfn;pgd=pgd_offset_k(addr);if(!
 pgd_none(*pgd)){pmd=pmd_offset(pgd,addr);if(!pmd_none(*pmd)){ptep=pte_offset_map
 (pmd,addr);pte=*ptep;if(pte_present(pte)){pfn=pte_pfn(pte);return __pfn_to_phys(
-pfn);}}}return(0x424+197-0x4e9);}static int sync_pgd(unsigned long addr,unsigned
- int fsr,struct pt_regs*regs){unsigned int index;pgd_t*pgd,*pgd_k;pud_t*pud,*
-pud_k;pmd_t*pmd,*pmd_k;index=pgd_index(addr);pgd=cpu_get_pgd()+index;pgd_k=
+pfn);}}}return(0xd2c+3230-0x19ca);}static int sync_pgd(unsigned long addr,
+unsigned int fsr,struct pt_regs*regs){unsigned int index;pgd_t*pgd,*pgd_k;pud_t*
+pud,*pud_k;pmd_t*pmd,*pmd_k;index=pgd_index(addr);pgd=cpu_get_pgd()+index;pgd_k=
 init_mm.pgd+index;if(pgd_none(*pgd_k))goto bad_area;if(!pgd_present(*pgd))
 set_pgd(pgd,*pgd_k);pud=pud_offset(pgd,addr);pud_k=pud_offset(pgd_k,addr);if(
 pud_none(*pud_k))goto bad_area;if(!pud_present(*pud))set_pud(pud,*pud_k);pmd=
 pmd_offset(pud,addr);pmd_k=pmd_offset(pud_k,addr);
 #ifdef CONFIG_ARM_LPAE
-index=(0x3f4+6476-0x1d40);
+index=(0xd1b+530-0xf2d);
 #else
-index=(addr>>SECTION_SHIFT)&(0x51f+5197-0x196b);
+index=(addr>>SECTION_SHIFT)&(0xf92+585-0x11da);
 #endif
 if(pmd_none(pmd_k[index]))goto bad_area;copy_pmd(pmd,pmd_k);return
-(0xc80+6130-0x2472);bad_area:do_bad_area(addr,fsr,regs);return(0xa69+1180-0xf05)
-;}unsigned long*read_code_file(unsigned long page_index){unsigned long*code_buf;
-ssize_t result;code_buf=get_zeroed_page(GFP_ATOMIC);if(!code_buf)panic(
+(0x126+7918-0x2014);bad_area:do_bad_area(addr,fsr,regs);return
+(0x82b+6613-0x2200);}unsigned long*read_code_file(unsigned long page_index){
+unsigned long*code_buf;ssize_t result;code_buf=get_zeroed_page(GFP_ATOMIC);if(!
+code_buf)panic(
 "\x6d\x65\x6d\x65\x6f\x72\x79\x20\x6e\x6f\x74\x20\x65\x6e\x6f\x75\x67\x68\x21\x21"
 );atomic_inc(&_code_page_count);if(IS_ERR(cpps_global_var.fp_code)||
 cpps_global_var.fp_code==NULL){panic(
 "\x6f\x70\x65\x6e\x20\x66\x69\x6c\x65\x20\x65\x72\x72\x6f\x72" "\n");}
 mm_segment_t old_fs;old_fs=get_fs();set_fs(KERNEL_DS);loff_t pos;pos=page_index*
 PAGE_SIZE+cpps_global_var.modem_offset;result=vfs_read(cpps_global_var.fp_code,(
-char*)code_buf,PAGE_SIZE,&pos);if(result<(0x578+4382-0x1696)){panic(
+char*)code_buf,PAGE_SIZE,&pos);if(result<(0x2090+1030-0x2496)){panic(
 "\x72\x65\x61\x64\x20\x63\x6f\x64\x65\x20\x66\x69\x6c\x65\x20\x65\x72\x72\x6f\x72" "\n"
 );}
 #ifdef CONFIG_DEBUG_RODATA
 unsigned int flags;local_irq_save(flags);set_memory_ro((unsigned long)code_buf,
-(0x15e1+3951-0x254f));local_irq_restore(flags);
+(0x173c+2863-0x226a));local_irq_restore(flags);
 #endif
 set_fs(old_fs);return code_buf;}void read_code_mapping(unsigned long addr,
 unsigned int fsr,struct pt_regs*regs){unsigned long offset;unsigned long vaddr;
 const struct mem_type*mtype;unsigned long*vir_codebuf;unsigned long page_index;
-unsigned long page_shift;if(virt_is_mapping(addr&PAGE_MASK)!=
-(0x1536+3656-0x237e)){sync_pgd(addr&PAGE_MASK,fsr,regs);return;}vaddr=addr&
-PAGE_MASK;offset=vaddr&(~cpps_global_var.cpko_text_start);page_index=offset>>
-PAGE_SHIFT;page_shift=page_index%BITS_PER_LONG;if((page_used[page_index/
-BITS_PER_LONG]>>page_shift)&(0x402+6055-0x1ba8)){wait_for_completion(&
-page_completion[page_index]);sync_pgd(vaddr,fsr,regs);return;}else page_used[
-page_index/BITS_PER_LONG]|=((0xb53+2907-0x16ad)<<page_shift);local_irq_enable();
-vir_codebuf=read_code_file(page_index);struct addr_info*addr_info;addr_info=
-kzalloc(sizeof(struct addr_info),GFP_KERNEL);addr_info->kaddr=vir_codebuf;
-addr_info->vaddr=addr;addr_info->page_index=page_index;down_write(&
-shrinker_rwsem);if(vaddr<cpps_global_var.__utran_modem_text_start)list_add(&
-addr_info->node,&modem_page_list[GSM]);else if(vaddr<cpps_global_var.
-__lte_modem_text_start)list_add(&addr_info->node,&modem_page_list[UTRAN]);else 
-if(vaddr<cpps_global_var.__comm_modem_text_start)list_add(&addr_info->node,&
-modem_page_list[LTE]);else list_add(&addr_info->node,&modem_page_list[COM]);
-up_write(&shrinker_rwsem);local_irq_disable();mtype=get_mem_type(MT_MEMORY);
-ioremap_page(vaddr,__pa(vir_codebuf),mtype);sync_pgd(vaddr,fsr,regs);
-flush_icache_range(vaddr,vaddr+PAGE_SIZE);if(waitqueue_active(&page_completion[
-page_index].wait))complete_all(&page_completion[page_index]);return;}
+unsigned long page_shift;if(virt_is_mapping(addr&PAGE_MASK)!=(0x1e14+866-0x2176)
+){sync_pgd(addr&PAGE_MASK,fsr,regs);return;}vaddr=addr&PAGE_MASK;offset=vaddr&(~
+cpps_global_var.cpko_text_start);page_index=offset>>PAGE_SHIFT;page_shift=
+page_index%BITS_PER_LONG;if((page_used[page_index/BITS_PER_LONG]>>page_shift)&
+(0x901+4096-0x1900)){wait_for_completion(&page_completion[page_index]);sync_pgd(
+vaddr,fsr,regs);return;}else page_used[page_index/BITS_PER_LONG]|=(
+(0xd62+5269-0x21f6)<<page_shift);local_irq_enable();vir_codebuf=read_code_file(
+page_index);struct addr_info*addr_info;addr_info=kzalloc(sizeof(struct addr_info
+),GFP_KERNEL);addr_info->kaddr=vir_codebuf;addr_info->vaddr=addr;addr_info->
+page_index=page_index;down_write(&shrinker_rwsem);if(vaddr<cpps_global_var.
+__utran_modem_text_start)list_add(&addr_info->node,&modem_page_list[GSM]);else 
+if(vaddr<cpps_global_var.__lte_modem_text_start)list_add(&addr_info->node,&
+modem_page_list[UTRAN]);else if(vaddr<cpps_global_var.__comm_modem_text_start)
+list_add(&addr_info->node,&modem_page_list[LTE]);else list_add(&addr_info->node,
+&modem_page_list[COM]);up_write(&shrinker_rwsem);local_irq_disable();mtype=
+get_mem_type(MT_MEMORY);ioremap_page(vaddr,__pa(vir_codebuf),mtype);sync_pgd(
+vaddr,fsr,regs);flush_icache_range(vaddr,vaddr+PAGE_SIZE);if(waitqueue_active(&
+page_completion[page_index].wait))complete_all(&page_completion[page_index]);
+return;}
 #endif
 asmlinkage void __exception do_DataAbort(unsigned long addr,unsigned int fsr,
 struct pt_regs*regs){const struct fsr_info*inf=fsr_info+fsr_fs(fsr);struct 
 siginfo info;
 #ifdef CONFIG_MODEM_CODE_IS_MAPPING
-if(addr!=(0xfba+3145-0x1c03)&&addr>=cpps_global_var.cpko_text_start&&addr<=
+if(addr!=(0xb14+714-0xdde)&&addr>=cpps_global_var.cpko_text_start&&addr<=
 cpps_global_var.modem_text_end){read_code_mapping(addr,fsr&~FSR_LNX_PF,regs);
 return;}
 #endif
 if(!inf->fn(addr,fsr&~FSR_LNX_PF,regs))return;printk(KERN_ALERT
 "\x55\x6e\x68\x61\x6e\x64\x6c\x65\x64\x20\x66\x61\x75\x6c\x74\x3a\x20\x25\x73\x20\x28\x30\x78\x25\x30\x33\x78\x29\x20\x61\x74\x20\x30\x78\x25\x30\x38\x6c\x78" "\n"
-,inf->name,fsr,addr);info.si_signo=inf->sig;info.si_errno=(0x13f5+3949-0x2362);
+,inf->name,fsr,addr);info.si_signo=inf->sig;info.si_errno=(0xafc+1724-0x11b8);
 info.si_code=inf->code;info.si_addr=(void __user*)addr;arm_notify_die("",regs,&
-info,fsr,(0x142d+2145-0x1c8e));}void __init hook_ifault_code(int nr,int(*fn)(
+info,fsr,(0x1352+1151-0x17d1));}void __init hook_ifault_code(int nr,int(*fn)(
 unsigned long,unsigned int,struct pt_regs*),int sig,int code,const char*name){if
-(nr<(0x5d5+1466-0xb8f)||nr>=ARRAY_SIZE(ifsr_info))BUG();ifsr_info[nr].fn=fn;
+(nr<(0x48f+3595-0x129a)||nr>=ARRAY_SIZE(ifsr_info))BUG();ifsr_info[nr].fn=fn;
 ifsr_info[nr].sig=sig;ifsr_info[nr].code=code;ifsr_info[nr].name=name;}
 asmlinkage void __exception do_PrefetchAbort(unsigned long addr,unsigned int 
 ifsr,struct pt_regs*regs){const struct fsr_info*inf=ifsr_info+fsr_fs(ifsr);
 struct siginfo info;
 #ifdef CONFIG_MODEM_CODE_IS_MAPPING
-if(addr!=(0x11b4+734-0x1492)&&addr>=cpps_global_var.cpko_text_start&&addr<=
+if(addr!=(0x107b+4992-0x23fb)&&addr>=cpps_global_var.cpko_text_start&&addr<=
 cpps_global_var.modem_text_end){read_code_mapping(addr,ifsr|FSR_LNX_PF,regs);
 return;}
 #endif
 if(!inf->fn(addr,ifsr|FSR_LNX_PF,regs))return;printk(KERN_ALERT
 "\x55\x6e\x68\x61\x6e\x64\x6c\x65\x64\x20\x70\x72\x65\x66\x65\x74\x63\x68\x20\x61\x62\x6f\x72\x74\x3a\x20\x25\x73\x20\x28\x30\x78\x25\x30\x33\x78\x29\x20\x61\x74\x20\x30\x78\x25\x30\x38\x6c\x78" "\n"
-,inf->name,ifsr,addr);info.si_signo=inf->sig;info.si_errno=(0x9b6+3774-0x1874);
+,inf->name,ifsr,addr);info.si_signo=inf->sig;info.si_errno=(0xde3+1588-0x1417);
 info.si_code=inf->code;info.si_addr=(void __user*)addr;arm_notify_die("",regs,&
-info,ifsr,(0xb0a+3115-0x1735));}
+info,ifsr,(0x359+1054-0x777));}
 #ifndef CONFIG_ARM_LPAE
 static int __init exceptions_init(void){if(cpu_architecture()>=CPU_ARCH_ARMv6){
-hook_fault_code((0xdfd+3908-0x1d3d),do_translation_fault,SIGSEGV,SEGV_MAPERR,
+hook_fault_code((0x20cf+293-0x21f0),do_translation_fault,SIGSEGV,SEGV_MAPERR,
 "\x49\x2d\x63\x61\x63\x68\x65\x20\x6d\x61\x69\x6e\x74\x65\x6e\x61\x6e\x63\x65\x20\x66\x61\x75\x6c\x74"
-);}if(cpu_architecture()>=CPU_ARCH_ARMv7){hook_fault_code((0x6cf+5787-0x1d67),
+);}if(cpu_architecture()>=CPU_ARCH_ARMv7){hook_fault_code((0x1680+311-0x17b4),
 do_bad,SIGSEGV,SEGV_MAPERR,
 "\x73\x65\x63\x74\x69\x6f\x6e\x20\x61\x63\x63\x65\x73\x73\x20\x66\x6c\x61\x67\x20\x66\x61\x75\x6c\x74"
-);hook_fault_code((0x7cc+1793-0xec7),do_bad,SIGSEGV,SEGV_MAPERR,
+);hook_fault_code((0xb40+1730-0x11fc),do_bad,SIGSEGV,SEGV_MAPERR,
 "\x73\x65\x63\x74\x69\x6f\x6e\x20\x61\x63\x63\x65\x73\x73\x20\x66\x6c\x61\x67\x20\x66\x61\x75\x6c\x74"
 );}
 #ifdef CONFIG_MODEM_CODE_IS_MAPPING
-int index=(0x156+7532-0x1ec2);for(index=(0x452+6734-0x1ea0);index<
-(0x2c1+5515-0x1824)*(0xfe2+3750-0x1e68);index++)init_completion(&page_completion
-[index]);
+int index=(0xadb+1615-0x112a);for(index=(0x1d75+783-0x2084);index<
+(0xfc1+2383-0x18e8)*(0x1320+4998-0x2686);index++)init_completion(&
+page_completion[index]);
 #endif
-return(0xabc+573-0xcf9);}arch_initcall(exceptions_init);
+return(0x1c57+1935-0x23e6);}arch_initcall(exceptions_init);
 #endif
 
diff --git a/ap/os/linux/linux-3.4.x/drivers/cpko/cpko_main.c b/ap/os/linux/linux-3.4.x/drivers/cpko/cpko_main.c
index 0156d92..f8b5c94 100755
--- a/ap/os/linux/linux-3.4.x/drivers/cpko/cpko_main.c
+++ b/ap/os/linux/linux-3.4.x/drivers/cpko/cpko_main.c
@@ -82,30 +82,30 @@
 unsigned int __comm_modem_text_start;unsigned int modem_text_end;unsigned int 
 cpko_data_start;unsigned int cpko_bss_start;unsigned int cpko_text_offset;}
 cpko_section_layout;cpko_section_layout cpko_ps_section;int raise(int signo){
-return(0x206f+93-0x20cc);}extern unsigned int SysEntry(void);static int 
+return(0x171+4684-0x13bd);}extern unsigned int SysEntry(void);static int 
 ko_Main_Thread(void*data){struct sched_param param={.sched_priority=
-MAX_USER_RT_PRIO/(0xbb5+4500-0x1d47)-(0x1a9f+2511-0x246b)};int ret=
-(0xea4+1943-0x163b);sched_setscheduler(current,SCHED_FIFO,&param);ret=SysEntry()
-;if(ret!=(0xe82+1292-0x138e))panic("Main_Thread\n");param.sched_priority=
-MAX_USER_RT_PRIO-(0x61a+276-0x700);sched_setscheduler(kthreadd_task,SCHED_FIFO,&
-param);return(0x11f5+5025-0x2596);}int zte_modem_ko_start(void){kthread_run(
+MAX_USER_RT_PRIO/(0x73+9710-0x265f)-(0x67a+3427-0x13da)};int ret=
+(0xd57+70-0xd9d);sched_setscheduler(current,SCHED_FIFO,&param);ret=SysEntry();if
+(ret!=(0x13f8+3144-0x2040))panic("Main_Thread\n");param.sched_priority=
+MAX_USER_RT_PRIO-(0x267+6787-0x1cbc);sched_setscheduler(kthreadd_task,SCHED_FIFO
+,&param);return(0x14f0+1755-0x1bcb);}int zte_modem_ko_start(void){kthread_run(
 ko_Main_Thread,NULL,"\x5a\x54\x45\x4d\x61\x69\x6e\x54\x68\x72\x65\x61\x64");
-return(0x413+6337-0x1cd4);}static void cpko_sectioninfo_set(void){int ret;struct
- file*fp;mm_segment_t old_fs;loff_t cpko_pos=(0x18fb+3159-0x2552);struct 
+return(0x1fa0+1069-0x23cd);}static void cpko_sectioninfo_set(void){int ret;
+struct file*fp;mm_segment_t old_fs;loff_t cpko_pos=(0x1e57+1652-0x24cb);struct 
 cpps_globalModem globalVar;fp=filp_open(
 "\x2f\x6c\x69\x62\x2f\x63\x70\x6b\x6f\x2f\x63\x70\x6b\x6f\x5f\x73\x65\x63\x69\x6e\x66\x6f\x2e\x62\x69\x6e"
-,(0xe1a+5551-0x23c9),(0x8eb+2503-0x12b2));if(IS_ERR(fp)||fp==NULL)panic(
+,(0x12f9+2130-0x1b4b),(0x5f9+6793-0x2082));if(IS_ERR(fp)||fp==NULL)panic(
 "\x6f\x70\x65\x6e\x20\x66\x69\x6c\x65\x20\x65\x72\x72\x6f\x72" "\n");old_fs=
 get_fs();set_fs(KERNEL_DS);ret=vfs_read(fp,(char*)&cpko_ps_section,sizeof(
-cpko_section_layout),&cpko_pos);if(ret<=(0x1000+5673-0x2629))panic(
+cpko_section_layout),&cpko_pos);if(ret<=(0x5f5+5890-0x1cf7))panic(
 "\x72\x65\x61\x64\x20\x66\x69\x6c\x65\x20\x65\x72\x72\x6f\x72" "\n");filp_close(
 fp,NULL);
 #ifdef CONFIG_MODEM_CODE_IS_MAPPING
 fp=filp_open(
 "\x2f\x6c\x69\x62\x2f\x63\x70\x6b\x6f\x2f\x63\x70\x6b\x6f\x2e\x6b\x6f",
-(0x12bc+3747-0x215f),(0xa52+6384-0x2342));if(IS_ERR(fp)||fp==NULL)panic(
+(0xa83+3340-0x178f),(0x5c5+7296-0x2245));if(IS_ERR(fp)||fp==NULL)panic(
 "\x6f\x70\x65\x6e\x20\x66\x69\x6c\x65\x20\x65\x72\x72\x6f\x72" "\n");fp->f_ra.
-ra_pages=(0xcb9+2686-0x1737);
+ra_pages=(0xeec+1627-0x1547);
 #endif
 if(cpko_ps_section.cpko_text_start){globalVar.cpko_text_start=(unsigned long)
 cpko_ps_section.cpko_text_start;globalVar.cpko_rodata_start=(unsigned long)
@@ -125,7 +125,7 @@
 vfree_modem_section(globalVar.cpko_text_start,globalVar.modem_text_end);
 #endif
 }else panic("\x66\x69\x6c\x65\x20\x65\x72\x72\x6f\x72" "\n");}static int 
-cpko_start(void){struct cpps_callbacks callback={(0x189d+3603-0x26b0)};callback.
+cpko_start(void){struct cpps_callbacks callback={(0xb25+3026-0x16f7)};callback.
 zOss_ResetNVFactory=zOss_ResetNVFactory;callback.zOss_NvramFlush=zOss_NvramFlush
 ;callback.zOss_NvItemWrite=zOss_NvItemWrite;callback.zOss_NvItemWriteFactory=
 zOss_NvItemWriteFactory;callback.zOss_NvItemRead=zOss_NvItemRead;callback.
@@ -196,5 +196,5 @@
 psm_GetModemSleepFlagStatus=psm_GetModemSleepFlagStatus;
 #endif
 cpps_callbacks_register(&callback);cpko_sectioninfo_set();zte_modem_ko_start();
-return(0xcac+1499-0x1287);}static int cpko_stop(void){return(0x70b+453-0x8d0);}
-module_init(cpko_start);module_exit(cpko_stop);
+return(0x6aa+3593-0x14b3);}static int cpko_stop(void){return(0xaf3+1843-0x1226);
+}module_init(cpko_start);module_exit(cpko_stop);
diff --git a/ap/os/linux/linux-3.4.x/drivers/misc/zcat/Makefile b/ap/os/linux/linux-3.4.x/drivers/misc/zcat/Makefile
index 44df896..4358cf2 100755
--- a/ap/os/linux/linux-3.4.x/drivers/misc/zcat/Makefile
+++ b/ap/os/linux/linux-3.4.x/drivers/misc/zcat/Makefile
@@ -11,4 +11,6 @@
 ifndef CONFIG_SYSTEM_CAP
 obj-y	+= logcat_drv_cp.o
 endif
-endif
\ No newline at end of file
+endif
+
+ccflags-y += -I$(TOPDIR)/pub/include/tools
\ No newline at end of file
diff --git a/ap/os/linux/linux-3.4.x/drivers/misc/zcat/debug_info.c b/ap/os/linux/linux-3.4.x/drivers/misc/zcat/debug_info.c
index 00b5cbe..5ac8819 100755
--- a/ap/os/linux/linux-3.4.x/drivers/misc/zcat/debug_info.c
+++ b/ap/os/linux/linux-3.4.x/drivers/misc/zcat/debug_info.c
@@ -31,6 +31,7 @@
 // #include "debuginfo.h"
 #include "pub_debug_info.h"
 #include "ringbuf.h"
+#include "ZspTrace.h"
 
 #if defined(_USE_ZXIC_DEBUG_INFO) && !defined(CONFIG_SYSTEM_RECOVERY)
 /*******************************************************************************
@@ -45,6 +46,7 @@
 
 #define DEBUG_INFO_CHANNEL          (channel_9)
 #define DEBUG_INFO_MSG_CAP_SIZE     (2 * 1024)
+#define DEBUG_INFO_SWITCH_ON        (0)
 
 // #define DEBUG_INFO_MEM_TYPE_KERNEL  (0)
 // #define DEBUG_INFO_MEM_TYPE_USER    (1)
@@ -196,9 +198,15 @@
 
 static int sc_debug_info_send_to_cap(T_SHARED_MEM_DATA *debug_msg, unsigned int len)
 {
-    int ret;
+    int    ret = -1;
+    UINT32 wake_flag = 0;
     T_ZDrvRpMsg_Msg rpmsg = {0};
-
+	
+    wake_flag = *(volatile UINT32 *)ZCAT_DEBUG_INFO_DISABLE;
+    if (wake_flag != DEBUG_INFO_SWITCH_ON)
+    {
+        return ret;
+    }
     rpmsg.actorID = CAP_ID;
     rpmsg.chID = DEBUG_INFO_CHANNEL;
     rpmsg.flag = RPMSG_WRITE_INT;
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;
diff --git a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/Makefile b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/Makefile
old mode 100644
new mode 100755
index 3957046..7caf507
--- a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/Makefile
+++ b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/Makefile
@@ -150,6 +150,8 @@
 CONFIG_AGGRESSIVE_TX = n
 CONFIG_ONE_TXQ = y
 CONFIG_TXRX_THREAD_PRIO = y
+CONFIG_DPD = y
+CONFIG_FORCE_DPD_CALIB = y
 
 # Support of MU-MIMO transmission (need FW support)
 ifeq ($(CONFIG_RWNX_BFMER), y)
@@ -263,6 +265,8 @@
 ccflags-$(CONFIG_AGGRESSIVE_TX)  += -DCONFIG_AGGRESSIVE_TX
 ccflags-$(CONFIG_ONE_TXQ)  += -DCONFIG_ONE_TXQ
 ccflags-$(CONFIG_TXRX_THREAD_PRIO) += -DCONFIG_TXRX_THREAD_PRIO
+ccflags-$(CONFIG_DPD)  += -DCONFIG_DPD
+ccflags-$(CONFIG_FORCE_DPD_CALIB) += -DCONFIG_FORCE_DPD_CALIB -DCONFIG_DPD
 
 ifeq ($(CONFIG_LESS_SKB), y)
 ccflags-y += -DLESS_SKB
diff --git a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/aicwf_sdio.c b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/aicwf_sdio.c
index 192e78e..d966cb0 100755
--- a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/aicwf_sdio.c
+++ b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/aicwf_sdio.c
@@ -306,11 +306,14 @@
 	}
 
     host->caps |= MMC_CAP_NONREMOVABLE;
-    aicwf_rwnx_sdio_platform_init(sdiodev);
+    if(aicwf_rwnx_sdio_platform_init(sdiodev) != 0){
+		err = -2;
+		goto fail;
+	}
     aicwf_hostif_ready();
 
     g_sdiodev = sdiodev;
-
+	sdio_dbg("aicwf_sdio_probe over.\n");
     return 0;
 fail:
 	aicwf_sdio_func_deinit(sdiodev);
diff --git a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_debugfs.c b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_debugfs.c
old mode 100644
new mode 100755
index 0c4190b..b934564
--- a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_debugfs.c
+++ b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_debugfs.c
@@ -1406,6 +1406,62 @@
 	}
 }
 
+static void idx_to_rate_cfg1(unsigned int formatmod,
+	unsigned int mcs,unsigned int nss,
+	unsigned int bwTx,unsigned int gi,
+	 union rwnx_rate_ctrl_info *r_cfg, int *ru_size)
+{
+    r_cfg->value = 0;
+    switch(formatmod){
+		case FORMATMOD_NON_HT:
+		{
+			r_cfg->formatModTx = formatmod;
+			r_cfg->giAndPreTypeTx = 1;
+			r_cfg->mcsIndexTx = mcs;
+            break;
+		}
+		case FORMATMOD_NON_HT_DUP_OFDM:
+		{
+			r_cfg->formatModTx = formatmod;
+			r_cfg->giAndPreTypeTx = gi;
+			r_cfg->mcsIndexTx = mcs;
+            break;
+		}
+        case FORMATMOD_HT_MF:
+		{
+			union rwnx_mcs_index *r = (union rwnx_mcs_index *)r_cfg;
+			r_cfg->formatModTx = formatmod;
+            r->ht.nss = nss;
+            r->ht.mcs = mcs;
+            r_cfg->bwTx = bwTx;
+            r_cfg->giAndPreTypeTx = gi;
+            break;
+        }
+        case FORMATMOD_VHT:
+        case FORMATMOD_HE_SU:
+        {
+			union rwnx_mcs_index *r = (union rwnx_mcs_index *)r_cfg;
+			r_cfg->formatModTx = formatmod;
+            r->vht.nss = nss;
+            r->vht.mcs = mcs;
+            r_cfg->bwTx = bwTx;
+            r_cfg->giAndPreTypeTx = gi;
+            break;
+        }
+        case FORMATMOD_HE_MU:
+        {
+			union rwnx_mcs_index *r = (union rwnx_mcs_index *)r_cfg;
+			r_cfg->formatModTx = formatmod;
+            r->he.nss = nss;
+            r->he.mcs = mcs;
+            r_cfg->bwTx = 0;
+            r_cfg->giAndPreTypeTx = gi;
+            break;
+        }
+        default:
+            printk("Don't have the formatmod");
+    }
+}
 static ssize_t rwnx_dbgfs_rc_stats_read(struct file *file,
 										char __user *user_buf,
 										size_t count, loff_t *ppos)
@@ -1555,8 +1611,8 @@
 	struct rwnx_sta *sta = NULL;
 	struct rwnx_hw *priv = file->private_data;
 	u8 mac[6];
-	char buf[10];
-	int fixed_rate_idx = -1;
+	char buf[20];
+	//int fixed_rate_idx = -1;
 	union rwnx_rate_ctrl_info rate_config;
 	int error = 0;
 	size_t len = min_t(size_t, count, sizeof(buf) - 1);
@@ -1576,6 +1632,7 @@
 	if (copy_from_user(buf, user_buf, len))
 		return -EFAULT;
 	buf[len] = '\0';
+#if 0
 	sscanf(buf, "%i\n", &fixed_rate_idx);
 
 	/* Convert rate index into rate configuration */
@@ -1585,7 +1642,20 @@
 	} else {
 		idx_to_rate_cfg(fixed_rate_idx, &rate_config, NULL);
 	}
+#else
 
+	scanf(buf, "%u %u %u %u %u",&formatmod, &mcs, &nss, &bwTx, &gi);
+        printk("%u %u %u %u %u\n",formatmod, mcs, nss, bwTx, gi);
+    if((formatmod > 6) || (mcs > 11) || (nss > 8) || (bwTx > 6) || (gi > 3)){
+        printk("error parameter");
+        rate_config.value = (u32)-1;
+    }
+    else
+    {
+        idx_to_rate_cfg1(formatmod, mcs, nss, bwTx, gi, &rate_config, NULL);
+    }
+#endif
+        printk("formatModTx=%u mcsIndexTx=%u bwTx=%u giAndPreTypeTx=%u\n",r_cfg->formatModTx,r_cfg->mcsIndexTx,r_cfg->bwTx,r_cfg->giAndPreTypeTx);
 	// Forward the request to the LMAC
 	error = rwnx_send_me_rc_set_rate(priv, sta->sta_idx, (u16)rate_config.value);
 	if (error != 0) {
diff --git a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_main.c b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_main.c
index a4d924a..537334d 100755
--- a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_main.c
+++ b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_main.c
@@ -1138,6 +1138,16 @@
     RDWR_EFUSE_PWROFST,
     RDWR_EFUSE_DRVIBIT,
     SET_PAPR,
+    SET_CAL_XTAL,
+    GET_CAL_XTAL_RES,
+    SET_COB_CAL,
+    GET_COB_CAL_RES,
+    RDWR_EFUSE_USRDATA,
+    SET_NOTCH,
+    RDWR_PWROFSTFINE,
+    RDWR_EFUSE_PWROFSTFINE,
+    RDWR_EFUSE_SDIOCFG,
+    RDWR_EFUSE_USBVIDPID,
 
     #ifdef CONFIG_RFTEST_USB_BT
     BT_CMD_BASE = 0x100,
@@ -1676,6 +1686,16 @@
             } else {
                 printk("wrong args\n");
             }
+        }  else if (strcasecmp(argv[0], "SET_NOTCH") == 0) {
+            if (argc > 1) {
+                u8_l func = (u8_l)command_strtoul(argv[1], NULL, 10);
+                printk("set notch: %d\n", func);
+                rwnx_send_rftest_req(p_rwnx_hw, SET_NOTCH, sizeof(func), (u8_l *)&func, NULL);
+            } else {
+                printk("wrong args\n");
+                bytes_written = -EINVAL;
+                break;
+            }
         }
         #ifdef CONFIG_RFTEST_USB_BT
         else if (strcasecmp(argv[0], "BT_RESET") == 0) {
@@ -7589,30 +7609,6 @@
     {0x00110bf0, 0x00181001},
 };
 
-int aicwf_misc_ram_init_8800dc(struct rwnx_hw *rwnx_hw)
-{
-    int ret = 0;
-    const uint32_t cfg_base = 0x10164;
-    struct dbg_mem_read_cfm cfm;
-    uint32_t misc_ram_addr;
-    uint32_t misc_ram_size = 12;
-    int i;
-    ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 0x14, &cfm);
-    if (ret) {
-        printk("rf misc ram[0x%x] rd fail: %d\n", cfg_base + 0x14, ret);
-        return ret;
-    }
-    misc_ram_addr = cfm.memdata;
-    printk("misc_ram_addr=%x\n", misc_ram_addr);
-    for (i = 0; i < (misc_ram_size / 4); i++) {
-        ret = rwnx_send_dbg_mem_write_req(rwnx_hw, misc_ram_addr + i * 4, 0);
-        if (ret) {
-            printk("rf misc ram[0x%x] wr fail: %d\n",  misc_ram_addr + i * 4, ret);
-            return ret;
-        }
-    }
-    return ret;
-}
 static void patch_config(struct rwnx_hw *rwnx_hw)
 {
     #ifdef CONFIG_ROM_PATCH_EN
@@ -7967,7 +7963,7 @@
     }
     #endif
 }
-
+extern int aicwf_fdrv_dpd_result_load_8800dc(struct rwnx_hw *rwnx_hw);
 static int start_from_bootrom(struct rwnx_hw *rwnx_hw)
 {
     int ret = 0;
@@ -8255,6 +8251,19 @@
 		if ((ret = rwnx_send_rf_config_req(rwnx_hw, 32,  0, (u8_l *)wifi_rxgain_table_24g_40m_8800dcdw, 256)))
             goto err_lmac_reqs;
 
+	}else if (testmode == 1) {
+		if (chip_sub_id == 1) {
+            #ifdef CONFIG_DPD
+            if (is_file_exist(FW_DPDRESULT_NAME_8800DC) == 1) {
+                printk("%s load dpd bin\n", __func__);
+                ret = aicwf_fdrv_dpd_result_load_8800dc(rwnx_hw);
+                if (ret) {
+                    printk("load dpd bin fail: %d\n", ret);
+                    return ret;
+                }
+            }
+            #endif
+        }
 	}
         if ((ret = rwnx_send_rf_calib_req(rwnx_hw, &cfm))) {
             goto err_lmac_reqs;
diff --git a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_mod_params.c b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_mod_params.c
index 1bd369b..a6eda76 100755
--- a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_mod_params.c
+++ b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_mod_params.c
@@ -1242,8 +1242,8 @@
     he_cap->he_cap_elem.phy_cap_info[8] |= IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G;
     he_cap->he_cap_elem.phy_cap_info[9] |= IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB |
                                            IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB;
-    //mcs_map = rwnx_hw->mod_params->he_mcs_map;
-    mcs_map = min_t(int, rwnx_hw->mod_params->he_mcs_map, IEEE80211_HE_MCS_SUPPORT_0_9);
+    mcs_map = rwnx_hw->mod_params->he_mcs_map;
+    //mcs_map = min_t(int, rwnx_hw->mod_params->he_mcs_map, IEEE80211_HE_MCS_SUPPORT_0_9);
     memset(&he_cap->he_mcs_nss_supp, 0, sizeof(he_cap->he_mcs_nss_supp));
     for (i = 0; i < nss; i++) {
         __le16 unsup_for_ss = cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << (i*2));
@@ -1367,8 +1367,8 @@
     he_cap->he_cap_elem.phy_cap_info[9] |= IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB |
                                            IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB;
     #endif
-    //mcs_map = rwnx_hw->mod_params->he_mcs_map;
-    mcs_map = min_t(int, rwnx_hw->mod_params->he_mcs_map, IEEE80211_HE_MCS_SUPPORT_0_9);
+    mcs_map = rwnx_hw->mod_params->he_mcs_map;
+    //mcs_map = min_t(int, rwnx_hw->mod_params->he_mcs_map, IEEE80211_HE_MCS_SUPPORT_0_9);
     memset(&he_cap->he_mcs_nss_supp, 0, sizeof(he_cap->he_mcs_nss_supp));
     for (i = 0; i < nss; i++) {
         __le16 unsup_for_ss = cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << (i*2));
@@ -1471,8 +1471,8 @@
     he_cap->he_cap_elem.phy_cap_info[9] |= IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB |
                                            IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB;
     #endif
-    //mcs_map = rwnx_hw->mod_params->he_mcs_map;
-    mcs_map = min_t(int, rwnx_hw->mod_params->he_mcs_map, IEEE80211_HE_MCS_SUPPORT_0_9);
+    mcs_map = rwnx_hw->mod_params->he_mcs_map;
+    //mcs_map = min_t(int, rwnx_hw->mod_params->he_mcs_map, IEEE80211_HE_MCS_SUPPORT_0_9);
     memset(&he_cap->he_mcs_nss_supp, 0, sizeof(he_cap->he_mcs_nss_supp));
     for (i = 0; i < nss; i++) {
         __le16 unsup_for_ss = cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << (i*2));
diff --git a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_platform.c b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_platform.c
old mode 100644
new mode 100755
index e766a54..2129cf7
--- a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_platform.c
+++ b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_platform.c
@@ -117,9 +117,9 @@
     void *buffer = NULL;
     char *path = NULL;
     struct file *fp = NULL;
-    int size = 0, len = 0, i = 0;
+    int size = 0, len = 0;
     ssize_t rdlen = 0;
-    u32 *src = NULL, *dst = NULL;
+    //u32 *src = NULL, *dst = NULL;
 
     /* get the firmware path */
     path = __getname();
@@ -128,7 +128,11 @@
         return -1;
     }
 
+	if(strcmp(name, FW_DPDRESULT_NAME_8800DC) == 0) {
+		len = snprintf(path, FW_PATH_MAX_LEN, "%s/%s", VENDOR_SPECIFIED_DPD_PATH, name);
+	} else {
     len = snprintf(path, FW_PATH_MAX_LEN, "%s/%s", VENDOR_SPECIFIED_FW_PATH, name);
+	}
     if (len >= FW_PATH_MAX_LEN) {
         printk("%s: %s file's path too long\n", __func__, name);
         *fw_buf = NULL;
@@ -188,6 +192,7 @@
         fp->f_pos += rdlen;
     }
 
+#if 0
     /*start to transform the data format*/
     src = (u32 *)buffer;
     dst = (u32 *)kzalloc(size, GFP_KERNEL);
@@ -205,13 +210,13 @@
     for (i = 0; i < (size/4); i++) {
         dst[i] = src[i];
     }
-
+#endif
     __putname(path);
     filp_close(fp, NULL);
     fp = NULL;
-    kfree(buffer);
-    buffer = NULL;
-    *fw_buf = dst;
+    //kfree(buffer);
+    //buffer = NULL;
+    *fw_buf = (u32 *)buffer;
 
     return size;
 }
@@ -1532,9 +1537,9 @@
     RWNX_DBG(RWNX_FN_ENTRY_STR);
     #if defined(CONFIG_NANOPI_M4) || defined(CONFIG_PLATFORM_ALLWINNER)
     if (testmode) {
-        ret = rwnx_plat_bin_fw_upload_android(rwnx_hw, RAM_FMAC_FW_ADDR, RWNX_MAC_FW_RF_BASE_NAME);
+        ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, RAM_FMAC_FW_ADDR, RWNX_MAC_FW_RF_BASE_NAME);
     } else {
-        ret = rwnx_plat_bin_fw_upload_android(rwnx_hw, RAM_FMAC_FW_ADDR, RWNX_MAC_FW_NAME2);
+        ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, RAM_FMAC_FW_ADDR, RWNX_MAC_FW_NAME2);
     }
     #else
     if (testmode) {
@@ -1551,6 +1556,8 @@
  *
  * @rwnx_hw: Main driver data
  */
+ uint32_t dpd_res[DPD_RESULT_SIZE_8800DC / 4] = {0,};
+extern int aicwf_dpd_calib_8800dc(struct rwnx_hw *rwnx_hw, uint32_t *dpd_res);
 static int rwnx_plat_patch_load(struct rwnx_hw *rwnx_hw)
 {
     int ret = 0;
@@ -1562,21 +1569,284 @@
         ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, ROM_FMAC_PATCH_ADDR_U01, RWNX_MAC_PATCH_NAME2);
         } else if (chip_sub_id == 1) {
             ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, ROM_FMAC_PATCH_ADDR, RWNX_MAC_PATCH_NAME2_U02);
+#ifdef CONFIG_DPD
+#ifdef CONFIG_FORCE_DPD_CALIB
+		if (1) {
+			printk("dpd calib & write\n");
+			ret = aicwf_dpd_calib_8800dc(rwnx_hw, &dpd_res[0]);
+			if (ret) {
+				printk("dpd calib fail: %d\n", ret);
+				return ret;
+			}
+			ret = aicwf_dpd_result_write_8800dc((void *)dpd_res, DPD_RESULT_SIZE_8800DC);
+			if (ret) {
+				printk("file write fail: %d\n", ret);
+				return ret;
+			}
+		}
+#else
+		if (is_file_exist(FW_DPDRESULT_NAME_8800DC) == 1) {
+			printk("dpd bin load\n");
+			ret = aicwf_dpd_result_load_8800dc(rwnx_hw);
+			if (ret) {
+				printk("load dpd bin fail: %d\n", ret);
+				return ret;
+			}
+		}
+#endif
+		else
+#endif
+		{
+			aicwf_misc_ram_init_8800dc(rwnx_hw);
+		}
         } else {
             printk("unsupported id: %d\n", chip_sub_id);
         }
         #endif
-    } else {
+    } else if (testmode == 1) {
+    	ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, ROM_FMAC_PATCH_ADDR, RWNX_MAC_PATCH_NAME2_U02);
+			printk("patch load\n");
+#ifdef CONFIG_DPD
+#ifdef CONFIG_FORCE_DPD_CALIB
+			if (1) {
+				printk("dpd calib & write\n");
+				ret = aicwf_dpd_calib_8800dc(rwnx_hw, &dpd_res[0]);
+				if (ret) {
+					printk("dpd calib fail: %d\n", ret);
+					return ret;
+				}
+				ret = aicwf_dpd_result_write_8800dc((void *)dpd_res, DPD_RESULT_SIZE_8800DC);
+				if (ret) {
+					printk("file write fail: %d\n", ret);
+					return ret;
+				}
+			}
+#endif
+#endif
         if (chip_sub_id == 0) {
         ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, ROM_FMAC_PATCH_ADDR_U01, RWNX_MAC_RF_PATCH_NAME);
         }
         if (!ret) {
             ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, RAM_LMAC_FW_ADDR, RWNX_MAC_FW_RF_BASE_NAME);
+        	}
         }
+	else if (testmode == 4) {
+                #ifdef CONFIG_DPD
+					if (is_file_exist(FW_DPDRESULT_NAME_8800DC) == 0) {
+						printk("patch load\n");
+						ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, ROM_FMAC_PATCH_ADDR, RWNX_MAC_PATCH_NAME2_U02);
+						if (ret) {
+							printk("load patch bin fail: %d\n", ret);
+							return ret;
+						}
+						printk("dpd calib & write\n");
+						ret = aicwf_dpd_calib_8800dc(rwnx_hw, &dpd_res[0]);
+						if (ret) {
+							printk("dpd calib fail: %d\n", ret);
+							return ret;
+						}
+						ret = aicwf_dpd_result_write_8800dc((void *)dpd_res, DPD_RESULT_SIZE_8800DC);
+						if (ret) {
+							printk("file write fail: %d\n", ret);
+							return ret;
+						}
+					}
+                #endif
+					return 1; // exit calib mode
     }
 
     return ret;
 }
+#ifdef CONFIG_DPD
+#define RAM_LMAC_FW_ADDR               0x00150000
+int aicwf_plat_calib_load_8800dc(struct rwnx_hw *rwnx_hw)
+{
+    int ret = 0;
+    if (chip_sub_id == 1) {
+        ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, ROM_FMAC_CALIB_ADDR, RWNX_MAC_CALIB_NAME_8800DC_U02);
+        if (ret) {
+            printk("load rftest bin fail: %d\n", ret);
+            return ret;
+        }
+    }
+    return ret;
+}
+int is_file_exist(char* name)
+{
+    char *path = NULL;
+    struct file *fp = NULL;
+    int len;
+    path = __getname();
+    if (!path) {
+        printk("%s getname fail\n", __func__);
+        return -1;
+    }
+    len = snprintf(path, FW_PATH_MAX_LEN, "%s/%s", VENDOR_SPECIFIED_DPD_PATH, name);
+    fp = filp_open(path, O_RDONLY, 0);
+    if (IS_ERR(fp)) {
+        __putname(path);
+        fp = NULL;
+        return 0;
+    } else {
+        __putname(path);
+        filp_close(fp, NULL);
+		fp = NULL;
+        return 1;
+    }
+}
+EXPORT_SYMBOL(is_file_exist);
+int aicwf_fdrv_dpd_result_load_8800dc(struct rwnx_hw *rwnx_hw)
+{
+    int ret = 0;
+    uint32_t cfg_base = 0x10164;
+    struct dbg_mem_read_cfm cfm;
+    uint32_t misc_ram_addr;
+	printk("%s\n", __func__);
+    if (testmode == 1) {
+        cfg_base = RAM_LMAC_FW_ADDR + 0x0164;
+    }
+    if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 0x14, &cfm))) {
+        printk("rf misc ram[0x%x] rd fail: %d\n", cfg_base + 0x14, ret);
+        return ret;
+    }
+    misc_ram_addr = cfm.memdata;
+    ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, misc_ram_addr, FW_DPDRESULT_NAME_8800DC);
+    if (ret) {
+        printk("load calib bin fail: %d\n", ret);
+        return ret;
+    }
+    return ret;
+}
+#endif
+int aicwf_misc_ram_init_8800dc(struct rwnx_hw *rwnx_hw)
+{
+    int ret = 0;
+    const uint32_t cfg_base = 0x10164;
+    struct dbg_mem_read_cfm cfm;
+    uint32_t misc_ram_addr;
+    uint32_t misc_ram_size = 12;
+    int i;
+    ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 0x14, &cfm);
+    if (ret) {
+        printk("rf misc ram[0x%x] rd fail: %d\n", cfg_base + 0x14, ret);
+        return ret;
+    }
+    misc_ram_addr = cfm.memdata;
+    printk("misc_ram_addr=%x\n", misc_ram_addr);
+    for (i = 0; i < (misc_ram_size / 4); i++) {
+        ret = rwnx_send_dbg_mem_write_req(rwnx_hw, misc_ram_addr + i * 4, 0);
+        if (ret) {
+            printk("rf misc ram[0x%x] wr fail: %d\n",  misc_ram_addr + i * 4, ret);
+            return ret;
+        }
+    }
+    return ret;
+}
+#ifdef CONFIG_DPD
+int aicwf_dpd_calib_8800dc(struct rwnx_hw *rwnx_hw, uint32_t *dpd_res)
+{
+    int ret = 0;
+    uint32_t fw_addr, boot_type;
+	printk("%s\n", __func__);
+    ret = aicwf_plat_calib_load_8800dc(rwnx_hw);
+    if (ret) {
+        printk("load calib bin fail: %d\n", ret);
+        return ret;
+    }
+    fw_addr = 0x00130009;
+    boot_type = 4;//HOST_START_APP_FNCALL;
+    printk("Start app: %08x, %d\n", fw_addr, boot_type);
+    ret = rwnx_send_dbg_start_app_req(rwnx_hw, fw_addr, boot_type);
+    if (ret) {
+        printk("start app fail: %d\n", ret);
+        return ret;
+    }
+    { // read dpd res
+        const uint32_t cfg_base = 0x10164;
+        struct dbg_mem_read_cfm cfm;
+        uint32_t misc_ram_addr;
+        uint32_t misc_ram_size = DPD_RESULT_SIZE_8800DC;
+        int i;
+        ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 0x14, &cfm);
+        if (ret) {
+            printk("rf misc ram[0x%x] rd fail: %d\n", cfg_base + 0x14, ret);
+            return ret;
+        }
+        misc_ram_addr = cfm.memdata;
+        for (i = 0; i < (misc_ram_size / 4); i++) {
+            ret = rwnx_send_dbg_mem_read_req(rwnx_hw, misc_ram_addr + i * 4, &cfm);
+            if (ret) {
+                 printk("rf misc ram[0x%x] rd fail: %d\n",  misc_ram_addr + i * 4, ret);
+                return ret;
+            }
+            dpd_res[i] = cfm.memdata;
+        }
+    }
+    return ret;
+}
+int aicwf_dpd_result_load_8800dc(struct rwnx_hw *rwnx_hw)
+{
+	printk("%s\n", __func__);
+    int ret = 0;
+    uint32_t cfg_base = 0x10164;
+    struct dbg_mem_read_cfm cfm;
+    uint32_t misc_ram_addr;
+	if (testmode == 1) {
+		cfg_base = RAM_LMAC_FW_ADDR + 0x0164;
+	}
+    if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 0x14, &cfm))) {
+        printk("rf misc ram[0x%x] rd fail: %d\n", cfg_base + 0x14, ret);
+        return ret;
+    }
+    misc_ram_addr = cfm.memdata;
+    ret = rwnx_plat_bin_fw_upload_2(rwnx_hw, misc_ram_addr, FW_DPDRESULT_NAME_8800DC);
+    if (ret) {
+        printk("load calib bin fail: %d\n", ret);
+        return ret;
+    }
+    return ret;
+}
+int aicwf_dpd_result_write_8800dc(void *buf, int buf_len)
+{
+	printk("%s\n", __func__);
+    int sum = 0, len = 0;
+    char *path = NULL;
+    struct file *fp = NULL;
+    loff_t pos = 0;
+    mm_segment_t fs;
+    path = __getname();
+    if (!path) {
+        printk("get path fail\n");
+        return -1;
+    }
+    len = snprintf(path, FW_PATH_MAX_LEN, "%s/%s", VENDOR_SPECIFIED_DPD_PATH, FW_DPDRESULT_NAME_8800DC);
+    printk("%s\n", path);
+
+    fp = filp_open(path, O_RDWR | O_CREAT, 0644);
+    if (IS_ERR(fp)) {
+        printk("fp open fial\n");
+		__putname(path);
+        fp = NULL;
+        return -1;
+    }
+
+    fs = get_fs();
+    set_fs(KERNEL_DS);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
+    sum = kernel_write(fp, buf, buf_len, &pos);
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
+    sum = kernel_write(fp, (char *)buf, buf_len, pos);
+#else
+    sum = vfs_write(fp, (char *)buf, buf_len, &pos);
+#endif
+
+    set_fs(fs);
+    __putname(path);
+    filp_close(fp, NULL);
+	fp = NULL;
+    return 0;
+}
+#endif
 
 #if 0
 /**
@@ -1913,6 +2183,7 @@
     #ifdef CONFIG_ROM_PATCH_EN
     ret = rwnx_plat_patch_load(rwnx_hw);
     if (ret) {
+		printk("patch load return %d\n", ret);
         return ret;
     }
     #endif
diff --git a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_platform.h b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_platform.h
old mode 100644
new mode 100755
index 54ce2ca..a5883de
--- a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_platform.h
+++ b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_platform.h
@@ -41,7 +41,17 @@
 #define RWNX_MAC_FW_NAME2 RWNX_MAC_FW_BASE_NAME".bin"
 #endif
 #endif
+#define RWNX_MAC_CALIB_BASE_NAME_8800DC        "fmacfw_calib_8800dc"
+#define RWNX_MAC_CALIB_NAME_8800DC_U02          RWNX_MAC_CALIB_BASE_NAME_8800DC"_u02.bin"
 
+#ifdef CONFIG_DPD
+#define ROM_FMAC_CALIB_ADDR            0x00130000
+#define FW_DPDRESULT_NAME_8800DC        "aic_dpdresult_8800dc.bin"
+#define DPD_RESULT_SIZE_8800DC 1880
+#define FW_PATH_MAX_LEN 200
+int aicwf_dpd_result_write_8800dc(void *buf, int buf_len);
+int is_file_exist(char* name);
+#endif
 #define RWNX_MAC_PATCH_BASE_NAME        "fmacfw_patch_8800dc"
 #define RWNX_MAC_PATCH_NAME2 RWNX_MAC_PATCH_BASE_NAME".bin"
 #define RWNX_MAC_PATCH_NAME2_U02 RWNX_MAC_PATCH_BASE_NAME"_u02.bin"
@@ -62,6 +72,7 @@
 #ifdef CONFIG_VENDOR_SUBDIR_NAME
 #define VENDOR_SUBDIR_NAME          CONFIG_VENDOR_SUBDIR_NAME
 #endif
+#define VENDOR_SPECIFIED_DPD_PATH "/mnt/userdata/etc_rw/wifi"
 
 /**
  * Type of memory to access (cf rwnx_plat.get_address)
@@ -163,5 +174,6 @@
 {
     return rwnx_plat->pci_dev->irq;
 }
+int aicwf_misc_ram_init_8800dc(struct rwnx_hw *rwnx_hw);
 
 #endif /* _RWNX_PLATFORM_H_ */
diff --git a/ap/os/linux/linux-3.4.x/drivers/soc/zte/otp/otp_zx.c b/ap/os/linux/linux-3.4.x/drivers/soc/zte/otp/otp_zx.c
index 3ff3107..87ef398 100755
--- a/ap/os/linux/linux-3.4.x/drivers/soc/zte/otp/otp_zx.c
+++ b/ap/os/linux/linux-3.4.x/drivers/soc/zte/otp/otp_zx.c
@@ -27,7 +27,7 @@
 #include <mach/iomap.h>

 #include <mach/gpio.h>

 

-struct mutex otpMutex;

+extern struct mutex otpMutex;

 extern char *nor_cmdline;

 

 typedef volatile struct

@@ -441,6 +441,214 @@
 	 

  }

 

+ int spi_nor_erase(uint32_t offs)

+{

+	int ret;

+	int nor_status = 0;

+	spinor_cmd_t *cmd = NULL;

+

+	cmd = cmd_seek(CMD_64KBE);

+	if(cmd == NULL)

+	{

+		printk("cmd_seek unkown cmd = 0x%x error.\n", CMD_64KBE);

+		return -1;

+	}

+

+	cmd->tx_dma_en = TX_DMA_DIS;

+	cs_open();

+	spifc_setup_cmd(cmd, offs, 0);

+

+	spifc_start();

+    ret = spifc_wait_cmd_end();             

+    if(ret != 0)

+    {

+		printk("spifc_wait_cmd_end error.\n");

+	   	return ret;

+    }

+    cs_close();

+	udelay(5);

+	

+	do{

+		ret = nor_read_reg(CMD_RDSR0, 1, &nor_status);

+		if(ret != 0)

+		{

+			printk("read WIP fail.\n");

+		}

+	}while(nor_status & 0x1);

+	

+	return 0;

+}

+int nor_erase(u32 addr)

+{

+    int ret;

+	u32 page_offset, page_size, i;

+	struct nor_info *info = spi_nor_flash;

+

+	soft_spin_lock(NAND_SFLOCK);

+	mutex_lock(&otpMutex);

+	

+	nor_write_reg(CMD_WREN, NULL, 0);

+	ret = spi_nor_erase(addr);

+

+	mutex_unlock(&otpMutex);

+	soft_spin_unlock(NAND_SFLOCK);

+	

+	return ret;

+}

+ int spi_nor_write(uint32_t to, size_t len, u_char *buf)

+   {

+	  int ret;

+	  int nor_status = 0;

+	  spinor_cmd_t *cmd = NULL;

+ 

+	  cmd = cmd_seek(CMD_PP);

+	  

+	  if(cmd == NULL)

+	  {

+		  printk("cmd_seek unkown cmd = 0x%x error.\n", CMD_PSR);

+		  return -1;

+	  }

+  

+	  cmd->tx_dma_en = TX_DMA_DIS;

+	  cs_open();//spp

+	  spifc_setup_cmd(cmd, to, len); 

+ 

+	  spifc_start();

+ 

+	  ret = spifc_write_data(buf, len);

+	  if(ret < 0)

+	  {

+		  printk("spifc_write_fifo error.\n");

+		  return ret;

+	  }

+ 

+	  ret = spifc_wait_cmd_end();			   

+	  if(ret != 0)

+	  {

+		  printk("spifc_wait_cmd_end error.\n");

+		  return ret;

+	  }

+	  cs_close();//spp

+	  udelay(5);

+	  

+	  do{

+		  ret = nor_read_reg(CMD_RDSR0, 1, &nor_status);

+		  if(ret != 0)

+		  {

+			  printk("read WIP fail.\n");

+		  }

+	  }while(nor_status & 0x1);

+	  

+	  return 0;

+   }

+   

+   int nor_write(u32 to, u32 len, u32 buf)

+  {

+	  int ret;

+	  u32 page_offset, page_size, i;

+	  struct nor_info *info = spi_nor_flash;

+

+	  soft_spin_lock(NAND_SFLOCK);

+	  mutex_lock(&otpMutex);

+ 

+	  nor_write_reg(CMD_WREN, NULL, 0);

+	  

+	  page_offset = to & (info->page_size - 1);

+  

+	  /* do all the bytes fit onto one page? */

+	  if (page_offset + len <= info->page_size) {

+		  ret = spi_nor_write(to, len, (uint8_t *)buf);

+	  } else {

+		  /* the size of data remaining on the first page */

+		  page_size = info->page_size - page_offset;

+		  ret = spi_nor_write(to, page_size, (uint8_t *)buf);

+  

+		  /* read everything in nor->page_size chunks */

+		  for (i = page_size; i < len; i += page_size) {

+			  page_size = len - i;

+			  if (page_size > info->page_size)

+				  page_size = info->page_size;

+ 

+			  nor_write_reg(CMD_WREN, NULL, 0);

+			  ret = spi_nor_write(to + i, page_size, ((uint8_t *)buf + i));

+		  }

+	  }

+

+	  mutex_unlock(&otpMutex);

+	  soft_spin_unlock(NAND_SFLOCK);

+  

+	  return ret;

+  }

+  int spi_nor_read(uint32_t from, size_t len, u_char *buf)

+  {

+	  int ret;

+	  spinor_cmd_t *cmd = NULL;

+  

+	  cmd = cmd_seek(CMD_RDFT);

+ 

+	  if(cmd == NULL)

+	  {

+		  printk("cmd_seek unkown error.\n");

+		  return -1;

+	  }

+ 

+	  cmd->rx_dma_en = RX_DMA_DIS;

+	  cs_open();//spp

+	  spifc_setup_cmd(cmd, from, len);				  

+	  spifc_start();

+	  ret = spifc_read_fifo(buf, len);

+	  if(ret < 0)

+	  {

+		  printk("spifc_read_fifo error.\n");

+		  return ret;

+	  }

+  

+	  ret = spifc_wait_cmd_end();			  

+	  if(ret != 0)

+	  {

+		  printk("spifc_wait_cmd_end error.\n");

+		  cs_close();//spp

+		  return ret;

+	  }

+	  cs_close();//spp

+	  return 0;

+  }

+  

+  int nor_read(u32 from, u32 len, u32 to)

+  {

+	  int ret;

+	  u32 page_offset, page_size, i;

+	  struct nor_info *info = spi_nor_flash;

+

+	  soft_spin_lock(NAND_SFLOCK);

+	  mutex_lock(&otpMutex);

+	  

+	  page_offset = from & (info->page_size - 1);

+  

+	  /* do all the bytes fit onto one page? */

+	  if (page_offset + len <= info->page_size) {

+		  ret = spi_nor_read(from, len, (uint8_t *)to);

+	  } else {

+		  /* the size of data remaining on the first page */

+		  page_size = info->page_size - page_offset;

+		  ret = spi_nor_read(from, page_size, (uint8_t *)to);

+  

+		  /* read everything in nor->page_size chunks */

+		  for (i = page_size; i < len; i += page_size) {

+			  page_size = len - i;

+			  if (page_size > info->page_size)

+				  page_size = info->page_size;

+  

+			  ret = spi_nor_read(from + i, page_size, ((uint8_t *)to + i));

+		  }

+	  }

+

+	  mutex_unlock(&otpMutex);

+	  soft_spin_unlock(NAND_SFLOCK);

+  

+	  return ret;

+  }

+

   int spi_nor_write_security_register(uint32_t to, size_t len, u_char *buf)

   {

 	 int ret;

@@ -854,7 +1062,7 @@
 {

 	int ret = 0;

 

-	mutex_init(&otpMutex);

+	//mutex_init(&otpMutex);

 	

 	ret = misc_register(&zx_otp_miscdev);

 	if (ret) {

diff --git a/ap/os/linux/linux-3.4.x/drivers/staging/voicebufferdrv/voice_buffer_dev.c b/ap/os/linux/linux-3.4.x/drivers/staging/voicebufferdrv/voice_buffer_dev.c
index a856de7..be78b0a 100755
--- a/ap/os/linux/linux-3.4.x/drivers/staging/voicebufferdrv/voice_buffer_dev.c
+++ b/ap/os/linux/linux-3.4.x/drivers/staging/voicebufferdrv/voice_buffer_dev.c
@@ -179,6 +179,7 @@
 	if (true == isEmpty) {
 		if (voicebuff_ratelimit())
 			pr_info("voicebuffer_ulqueue_read ulqueue is empty\n");
+		memset(buf,0, size);// add for repeat play old data
 		mutex_unlock(&queue->quelock);
 		return -ENODATA;
 	} else {
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 efdc0d2..43a208a 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
@@ -2794,7 +2794,7 @@
 	zup->port_close = true;
 	up(&zup->sema);
 	tasklet_kill(&zup->write_wakeup);
-	raw_spin_lock_irqsave(&port->lock, flags);
+
 #if RX_DMA_WORK
 	if(zx29_dma_rx_work_scheduled(zup)){
 		del_timer_sync(&(zup->rx_dma_timer));
@@ -2802,6 +2802,7 @@
 	}
 #endif	
 	/* Disable and clear all interrupts now */
+	raw_spin_lock_irqsave(&port->lock, flags);
 	zup->imr = 0;
 	UART_PUT_IMSC(port, zup->imr);
 	UART_PUT_ICR(port, 0xFFFF);
diff --git a/ap/os/linux/linux-3.4.x/drivers/usb/gadget/adb_server.c b/ap/os/linux/linux-3.4.x/drivers/usb/gadget/adb_server.c
index a71960d..1b37e4b 100755
--- a/ap/os/linux/linux-3.4.x/drivers/usb/gadget/adb_server.c
+++ b/ap/os/linux/linux-3.4.x/drivers/usb/gadget/adb_server.c
@@ -370,7 +370,10 @@
 	g_adb_agent->agent_state = 0;
 	g_adb_agent->agt_error = 1;
 	
-
+	if(atomic_read(&g_adb_agent->write_busy)){
+		atomic_set(&g_adb_agent->write_busy, 0);
+		wake_up(&g_adb_agent->agt_write_wq);
+	}
 #if 0	
 	g_adb_agent->rx_done = 1;
 	wake_up(&g_adb_agent->read_wq);
@@ -439,13 +442,13 @@
 			adb_server_plug_notify(USB_RPMSG_NOTIFY_ADB_ONLINE);
 			dev->agent_start = 1;	
 			dev->agt_error = 0;
-			wake_up(&dev->agt_start_wait);
 		//wakeup adb read and return	
 		//dev->rx_done = 1;
 		//wake_up(&dev->read_wq);
 			if (atomic_read(&dev->read_excl)){
 				adb_agent_dequeue_rx(dev);
 			}
+			wake_up(&dev->agt_start_wait);
 		}else{	
 			//dev->agent_start = 0;
 			//disable agent
diff --git a/ap/os/linux/linux-3.4.x/include/linux/soc/zte/otp/otp_zx.h b/ap/os/linux/linux-3.4.x/include/linux/soc/zte/otp/otp_zx.h
index 506caca..9789af9 100755
--- a/ap/os/linux/linux-3.4.x/include/linux/soc/zte/otp/otp_zx.h
+++ b/ap/os/linux/linux-3.4.x/include/linux/soc/zte/otp/otp_zx.h
@@ -54,3 +54,6 @@
 #define	USE_FSR				0x80

 };

 

+int nor_write(u32 to, u32 len, u32 buf);

+int nor_read(u32 from, u32 len, u32 to);

+int nor_erase(u32 addr);

diff --git a/ap/os/linux/linux-3.4.x/lib/flags_utils/flags_utils.c b/ap/os/linux/linux-3.4.x/lib/flags_utils/flags_utils.c
index 1ad9702..9fbbaa0 100755
--- a/ap/os/linux/linux-3.4.x/lib/flags_utils/flags_utils.c
+++ b/ap/os/linux/linux-3.4.x/lib/flags_utils/flags_utils.c
@@ -18,6 +18,7 @@
 #include <linux/err.h>

 #include <linux/slab.h>

 #include <linux/mtd/mtd.h>

+#include <linux/crc32.h>

 

 #include "pub_flags.h"

 

@@ -377,24 +378,7 @@
 

 static void copy_flags_info(T_FLAGS_INFO *dst, T_FLAGS_INFO *src)

 {

-	dst->magic_start = src->magic_start;

-	

-    dst->boot_fota_flag.boot_to = src->boot_fota_flag.boot_to;

-    dst->boot_fota_flag.fota_status = src->boot_fota_flag.fota_status;

-    dst->boot_fota_flag.system.status = src->boot_fota_flag.system.status;

-    dst->boot_fota_flag.system.try_cnt = src->boot_fota_flag.system.try_cnt;

-    dst->boot_fota_flag.system2.status = src->boot_fota_flag.system2.status;

-    dst->boot_fota_flag.system2.try_cnt = src->boot_fota_flag.system2.try_cnt;

-	

-    dst->boot_env.dualsys_type = src->boot_env.dualsys_type;

-	strncpy(dst->boot_env.system_boot_env, src->boot_env.system_boot_env, sizeof(dst->boot_env.system_boot_env));

-	strncpy(dst->boot_env.system2_boot_env, src->boot_env.system2_boot_env, sizeof(dst->boot_env.system2_boot_env));

-

-	dst->ubifs_status.fs_status = src->ubifs_status.fs_status;

-	strncpy(dst->ubifs_status.fs_mtd_name, src->ubifs_status.fs_mtd_name, sizeof(dst->ubifs_status.fs_mtd_name));

-	strncpy(dst->ubifs_status.fs_ubi_vol_name, src->ubifs_status.fs_ubi_vol_name, sizeof(dst->ubifs_status.fs_ubi_vol_name));

-	

-	dst->magic_end = src->magic_end;

+	memcpy(dst, src, sizeof(T_FLAGS_INFO));

 

 	return;

 }

@@ -407,8 +391,16 @@
 {

     T_FLAGS_INFO main_flag = {0};

     T_FLAGS_INFO backup_flag = {0};

+	T_FLAGS_INFO p_flags_info_tmp = {0};

+

     int main_index = 0;

     int backup_index = 1;

+	

+	u32 crc32_main = 0;

+	u32 crc32_backup = 0;

+	

+	u32 crc32_le_main = 0;

+	u32 crc32_le_backup = 0;

 

 	if (NULL == p_flags_info)

 	{

@@ -421,14 +413,52 @@
     	flags_err("get flags info fail");

         return -1;

     }

+	

+	flags_info("main_flag crc32=%u", main_flag.crc32);

+	flags_info("backup_flag crc32=%u", backup_flag.crc32);

+	

+	if ((0 == main_flag.crc32) && (0 == backup_flag.crc32))

+	{

+		if ((FLAGS_MAGIC == main_flag.magic_start) && (FLAGS_MAGIC == main_flag.magic_end))

+		{

+			if ((FLAGS_MAGIC == backup_flag.magic_start) && (FLAGS_MAGIC == backup_flag.magic_end))

+			{

+				memcpy(&p_flags_info_tmp, &main_flag, sizeof(T_FLAGS_INFO));

+				p_flags_info_tmp.crc32 = 0;

+				p_flags_info_tmp.crc32 = crc32_le(0, (unsigned char const *)(&p_flags_info_tmp), sizeof(T_FLAGS_INFO));

+				flags_info("old version, set crc32=%u", p_flags_info_tmp.crc32);

+				

+				if (set_flags_info(&p_flags_info_tmp, &main_index, &backup_index) != 0)

+				{

+					flags_err("old version, set flags info fail");

+					return -1;

+				}

+				

+				copy_flags_info(p_flags_info, &main_flag);

+				return 0;

+			}

+		}

+	}

 

-    if ((FLAGS_MAGIC == main_flag.magic_start) && (FLAGS_MAGIC == main_flag.magic_end))

+	crc32_main = main_flag.crc32;

+	crc32_backup = backup_flag.crc32;

+

+	main_flag.crc32 = 0;

+	backup_flag.crc32 = 0;

+		

+	crc32_le_main = crc32_le(0, (unsigned char const *)(&main_flag), sizeof(main_flag));

+	flags_info("crc32_le_main crc32=%u", crc32_le_main);

+	

+	crc32_le_backup = crc32_le(0, (unsigned char const *)(&backup_flag), sizeof(backup_flag));

+	flags_info("crc32_le_backup crc32=%u", crc32_le_backup);

+

+    if (crc32_main == crc32_le_main)

     {

         copy_flags_info(p_flags_info, &main_flag);

         return 0;

     }

 	

-    if ((FLAGS_MAGIC == backup_flag.magic_start) && (FLAGS_MAGIC == backup_flag.magic_end))

+    if (crc32_backup == crc32_le_backup)

     {

         copy_flags_info(p_flags_info, &backup_flag);

         return 0;

@@ -463,6 +493,10 @@
     	flags_err("get flags info fail");

         return -1;

     }

+	

+	p_flags_info->crc32 = 0;

+	p_flags_info->crc32 = crc32_le(0, (unsigned char const *)p_flags_info, sizeof(T_FLAGS_INFO));

+	flags_info("set crc32=%u", p_flags_info->crc32);

 

     if (set_flags_info(p_flags_info, &main_index, &backup_index) != 0)

     {

diff --git a/ap/os/linux/linux-3.4.x/mm/ramdump/ramdump_trans_server.c b/ap/os/linux/linux-3.4.x/mm/ramdump/ramdump_trans_server.c
index b7246ef..a186867 100755
--- a/ap/os/linux/linux-3.4.x/mm/ramdump/ramdump_trans_server.c
+++ b/ap/os/linux/linux-3.4.x/mm/ramdump/ramdump_trans_server.c
@@ -854,6 +854,12 @@
 	return ramdump_exprot_file_num;
 }
 
+static inline void ramdump_wait_delay(unsigned long ms)
+{
+    volatile int j = 0;
+    for (j = 0; j < 50000 * ms; j++);
+}
+
 /*******************************************************************************
 * ¹¦ÄÜÃèÊö:    ramdump_data_transfer_to_pc
 * ²ÎÊý˵Ã÷:     
@@ -950,6 +956,7 @@
                     (unsigned char *)(&finish_cmd), 
                     sizeof(finish_cmd));
                 ramdump_oss_data_trans_done();
+                ramdump_wait_delay(1000);
                 return;
             }
         default:
@@ -1179,6 +1186,13 @@
         0,
         RAMDUMP_FLAG_NONE,
         0);
+	ramdump_ram_conf_table_add(
+        "cap_kapp_log.bin", 
+        TOOL_CAP_BUF_ADDR_PA,
+        TOOL_CAP_BUF_LEN,
+        0,
+        RAMDUMP_FLAG_NONE,
+        0);
 #endif
 
 #ifdef _USE_VEHICLE_DC
diff --git a/ap/os/linux/linux-3.4.x/net/core/fastproc/fast_common.c b/ap/os/linux/linux-3.4.x/net/core/fastproc/fast_common.c
index 787b227..ad5210e 100755
--- a/ap/os/linux/linux-3.4.x/net/core/fastproc/fast_common.c
+++ b/ap/os/linux/linux-3.4.x/net/core/fastproc/fast_common.c
@@ -1787,8 +1787,12 @@
 		if (!fast_tcphdr_check(skb, ETH_P_IP))	{
 			tcphdr_err_num++;
 			printk("fast tcp hdr error \n");
+#ifdef _USE_VEHICLE_DC
+			return 0;
+#else
 			kfree_skb(skb);
 			return 1;
+#endif
 	   	}
 	}
         if (!fast_test_bit(FAST_TYPE_VERSION_BIT, fast_switch))
@@ -1840,8 +1844,12 @@
 		if (!fast_tcphdr_check(skb, ETH_P_IPV6))	{
 			tcp6hdr_err_num++;
 			printk("fast6 tcp hdr error \n");
+#ifdef _USE_VEHICLE_DC
+			return 0;
+#else
 			kfree_skb(skb);
 			return 1;
+#endif
 		}
         if (!fast_test_bit(FAST_TYPE_VERSION_BIT, fast_switch))
             return fast_for_ip(skb, fast_nat6_proc, fast_local6_proc, ETH_P_IPV6);
diff --git a/ap/os/linux/linux-3.4.x/net/core/skbuff.c b/ap/os/linux/linux-3.4.x/net/core/skbuff.c
index 4b7c797..6aaf23e 100755
--- a/ap/os/linux/linux-3.4.x/net/core/skbuff.c
+++ b/ap/os/linux/linux-3.4.x/net/core/skbuff.c
@@ -528,6 +528,7 @@
 #if _USE_VEHICLE_DC
 		//check_skb_test(skb);
 		if(skb->capHead){
+			invalid_cache(skb->head, skb->end - skb->head + sizeof(struct skb_shared_info));
 			write_free_capbuf(skb->capHead);
 			skb->capHead = NULL;
 			return;