di: TL1 enable lmv_lock_win_en cause crash [1/1]
authorzhiwei.yuan <zhiwei.yuan@amlogic.com>
Thu, 28 Feb 2019 07:30:09 +0000 (15:30 +0800)
committerJianxin Pan <jianxin.pan@amlogic.com>
Fri, 1 Mar 2019 13:30:26 +0000 (05:30 -0800)
PD#SWPL-4999

Problem:
use vmalloc in interrupt context

Solution:
move di_map to cma allocate function(kernel thread)

Verify:
verified by t962x2_x301

Change-Id: I8cf8d9caf9703ba039b32da98d2382a4c875de30
Signed-off-by: zhiwei.yuan <zhiwei.yuan@amlogic.com>
drivers/amlogic/media/deinterlace/deinterlace.c
drivers/amlogic/media/deinterlace/deinterlace.h
drivers/amlogic/media/deinterlace/deinterlace_hw.c
drivers/amlogic/media/deinterlace/deinterlace_hw.h

index d9ef4cf..5e793b8 100644 (file)
@@ -1878,6 +1878,7 @@ static unsigned int di_cma_alloc(struct di_dev_s *devp)
        unsigned int start_time, end_time, delta_time;
        struct di_buf_s *buf_p = NULL;
        int itmp, alloc_cnt = 0;
+       u8 *tmp;
 
        start_time = jiffies_to_msecs(jiffies);
        queue_for_each_entry(buf_p, ptmp, QUEUE_LOCAL_FREE, list) {
@@ -1923,6 +1924,18 @@ static unsigned int di_cma_alloc(struct di_dev_s *devp)
                                        di_pre_stru.mtn_size +
                                        di_pre_stru.count_size +
                                        di_pre_stru.mv_size;
+                                       tmp = di_vmap(buf_p->mcinfo_adr,
+                                               di_pre_stru.mcinfo_size,
+                                               &buf_p->bflg_vmap);
+
+                                       if (buf_p->bflg_vmap == true)
+                                               buf_p->mcinfo_vaddr =
+                                                       (unsigned short *)tmp;
+                                       else {
+                                               buf_p->mcinfo_vaddr = NULL;
+                                               pr_err("DI: %s vmap fail\n",
+                                                       __func__);
+                                       }
                        }
                }
        }
@@ -1987,6 +2000,12 @@ static void di_cma_release(struct di_dev_s *devp)
                }
                if ((ii >= USED_LOCAL_BUF_MAX) &&
                        (buf_p->pages != NULL)) {
+
+                       if (buf_p->bflg_vmap == true) {
+                               di_unmap_phyaddr((u8 *)buf_p->mcinfo_vaddr);
+                               buf_p->bflg_vmap = false;
+                       }
+
                        if (dma_release_from_contiguous(&(devp->pdev->dev),
                                        buf_p->pages,
                                        devp->buffer_size >> PAGE_SHIFT)) {
@@ -2049,6 +2068,7 @@ static int di_init_buf(int width, int height, unsigned char prog_flag)
        unsigned int mv_canvas_width = width, canvas_align_width = 32;
        unsigned long di_post_mem = 0, nrds_mem = 0;
        struct di_buf_s *keep_buf = di_post_stru.keep_buf;
+       u8 *tmp;
 
        if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A))
                canvas_align_width = 64;
@@ -2177,6 +2197,18 @@ static int di_init_buf(int width, int height, unsigned char prog_flag)
                                                de_devp->mem_start +
                                                di_buf_size * i + nr_size +
                                                mtn_size + count_size + mv_size;
+                                       tmp = di_vmap(di_buf->mcinfo_adr,
+                                               di_pre_stru.mcinfo_size,
+                                               &di_buf->bflg_vmap);
+
+                                       if (di_buf->bflg_vmap == true)
+                                               di_buf->mcinfo_vaddr =
+                                                       (unsigned short *)tmp;
+                                       else {
+                                               di_buf->mcinfo_vaddr = NULL;
+                                               pr_err("DI: %s vmap fail\n",
+                                                       __func__);
+                                       }
                                }
                                di_buf->canvas_config_flag = 2;
                        }
@@ -4272,8 +4304,7 @@ static irqreturn_t de_irq(int irq, void *dev_instance)
                                is_meson_txhd_cpu())
                                mc_pre_mv_irq();
                        calc_lmv_base_mcinfo((di_pre_stru.cur_height>>1),
-                               di_pre_stru.di_wr_buf->mcinfo_adr,
-                               di_pre_stru.mcinfo_size);
+                               di_pre_stru.di_wr_buf->mcinfo_vaddr);
                }
                nr_process_in_irq();
                if ((data32&0x200) && de_devp->nrds_enable)
index 0e38fdd..9aa19e2 100644 (file)
@@ -117,6 +117,8 @@ struct di_buf_s {
        int cnt_canvas_idx;
        unsigned long mcinfo_adr;
        int mcinfo_canvas_idx;
+       unsigned short *mcinfo_vaddr;
+       bool bflg_vmap;
        unsigned long mcvec_adr;
        int mcvec_canvas_idx;
        struct mcinfo_pre_s {
index 14827c7..0b1bf38 100644 (file)
@@ -314,28 +314,25 @@ static struct mcinfo_lmv_s lines_mv[540];
 static short offset_lmv = 100;
 module_param_named(offset_lmv, offset_lmv, short, 0644);
 
-void calc_lmv_base_mcinfo(unsigned int vf_height, unsigned long mcinfo_adr,
-                                       unsigned int mcinfo_size)
+void calc_lmv_base_mcinfo(unsigned int vf_height, unsigned short *mcinfo_vadr)
 {
        unsigned short i, top_str, bot_str, top_end, bot_end, j = 0;
-       unsigned short *mcinfo_vadr = NULL, lck_num;
+       unsigned short lck_num;
        unsigned short flg_m1 = 0, flg_i = 0, nLmvLckSt = 0;
        unsigned short lmv_lckstext[3] = {0, 0, 0}, nLmvLckEd;
        unsigned short lmv_lckedext[3] = {0, 0, 0}, nLmvLckNum;
-       bool bflg_vmap = false;
-       u8 *tmp;
+       //bool bflg_vmap = false;
 
        //mcinfo_vadr = (unsigned short *)phys_to_virt(mcinfo_adr);
 
        if (!lmv_lock_win_en)
                return;
 
-       tmp = di_vmap(mcinfo_adr, mcinfo_size, &bflg_vmap);
-       if (tmp == NULL) {
+       //tmp = di_vmap(mcinfo_adr, mcinfo_size, &bflg_vmap);
+       if (mcinfo_vadr == NULL) {
                di_print("err:di_vmap failed\n");
                return;
        }
-       mcinfo_vadr = (unsigned short *)tmp;
 
        for (i = 0; i < (vf_height>>1); i++) {
                lmvs_init(&lines_mv[i], *(mcinfo_vadr+i));
@@ -349,8 +346,8 @@ void calc_lmv_base_mcinfo(unsigned int vf_height, unsigned long mcinfo_adr,
                                pr_info("\n");
                }
        }
-       if (bflg_vmap)
-               di_unmap_phyaddr(tmp);
+       //if (bflg_vmap)
+               //di_unmap_phyaddr(tmp);
 
        pr_mcinfo_cnt ? pr_mcinfo_cnt-- : (pr_mcinfo_cnt = 0);
        top_str = 0;
index d6b44d5..dbaa344 100644 (file)
@@ -165,8 +165,7 @@ void enable_di_post_mif(enum gate_mode_e mode);
 void di_hw_uninit(void);
 void combing_pd22_window_config(unsigned int width, unsigned int height);
 void calc_lmv_init(void);
-void calc_lmv_base_mcinfo(unsigned int vf_height, unsigned long mcinfo_adr,
-                                               unsigned int mcinfo_size);
+void calc_lmv_base_mcinfo(unsigned int vf_height, unsigned short *mcinfo_vadr);
 void init_field_mode(unsigned short height);
 void film_mode_win_config(unsigned int width, unsigned int height);
 void pulldown_vof_win_config(struct pulldown_detected_s *wins);