From 2d398c6e5c3560c3dd172b724099ea7055af0136 Mon Sep 17 00:00:00 2001 From: Pengcheng Chen Date: Sat, 2 Feb 2019 15:42:04 +0800 Subject: [PATCH] gdc: unmap gdc dma_buf after gdc process stop [2/2] PD#SWPL-4839 Problem: have risk of unmap gdc dma_buf Solution: unmap gdc dma_buf after gdc process stop Verify: verify by w400 Change-Id: If86ac881fd85a5c4b3583567c9748e87149c1d78 Signed-off-by: Pengcheng Chen --- drivers/amlogic/media/gdc/app/gdc_dmabuf.c | 1 - drivers/amlogic/media/gdc/app/gdc_module.c | 75 +++++++++++-------- .../amlogic/media/gdc/inc/gdc/gdc_config.h | 10 ++- 3 files changed, 54 insertions(+), 32 deletions(-) diff --git a/drivers/amlogic/media/gdc/app/gdc_dmabuf.c b/drivers/amlogic/media/gdc/app/gdc_dmabuf.c index 1ade0e4b7567..390874a22dab 100644 --- a/drivers/amlogic/media/gdc/app/gdc_dmabuf.c +++ b/drivers/amlogic/media/gdc/app/gdc_dmabuf.c @@ -552,7 +552,6 @@ int gdc_dma_buffer_get_phys(struct aml_dma_cfg *cfg, unsigned long *addr) *addr = PFN_PHYS(page_to_pfn(page)); ret = 0; } - gdc_dma_buffer_unmap(cfg); return ret; } diff --git a/drivers/amlogic/media/gdc/app/gdc_module.c b/drivers/amlogic/media/gdc/app/gdc_module.c index e0f1dade368f..e698bafb1f66 100644 --- a/drivers/amlogic/media/gdc/app/gdc_module.c +++ b/drivers/amlogic/media/gdc/app/gdc_module.c @@ -520,7 +520,7 @@ static long gdc_process_input_dma_info(struct mgdc_fh_s *fh, { long ret = -1; unsigned long addr; - struct aml_dma_cfg cfg; + struct aml_dma_cfg *cfg = NULL; struct gdc_cmd_s *gdc_cmd = &fh->gdc_cmd; struct gdc_config_s *gc = &gdc_cmd->gdc_config; @@ -532,10 +532,12 @@ static long gdc_process_input_dma_info(struct mgdc_fh_s *fh, switch (gc->format) { case NV12: if (gs_ex->input_buffer.plane_number == 1) { - cfg.fd = gs_ex->input_buffer.y_base_fd; - cfg.dev = &fh->gdev->pdev->dev; - cfg.dir = DMA_TO_DEVICE; - ret = gdc_dma_buffer_get_phys(&cfg, &addr); + cfg = &fh->dma_cfg.input_cfg_plane1; + cfg->fd = gs_ex->input_buffer.y_base_fd; + cfg->dev = &fh->gdev->pdev->dev; + cfg->dir = DMA_TO_DEVICE; + + ret = gdc_dma_buffer_get_phys(cfg, &addr); if (ret < 0) { gdc_log(LOG_ERR, "dma import input fd %d failed\n", @@ -550,10 +552,11 @@ static long gdc_process_input_dma_info(struct mgdc_fh_s *fh, gdc_log(LOG_INFO, "1 plane get input addr=%x\n", gdc_cmd->y_base_addr); } else if (gs_ex->input_buffer.plane_number == 2) { - cfg.fd = gs_ex->input_buffer.y_base_fd; - cfg.dev = &fh->gdev->pdev->dev; - cfg.dir = DMA_TO_DEVICE; - ret = gdc_dma_buffer_get_phys(&cfg, &addr); + cfg = &fh->dma_cfg.input_cfg_plane1; + cfg->fd = gs_ex->input_buffer.y_base_fd; + cfg->dev = &fh->gdev->pdev->dev; + cfg->dir = DMA_TO_DEVICE; + ret = gdc_dma_buffer_get_phys(cfg, &addr); if (ret < 0) { gdc_log(LOG_ERR, "dma import input fd %d failed\n", @@ -561,11 +564,11 @@ static long gdc_process_input_dma_info(struct mgdc_fh_s *fh, return -EINVAL; } gdc_cmd->y_base_addr = addr; - - cfg.fd = gs_ex->input_buffer.uv_base_fd; - cfg.dev = &fh->gdev->pdev->dev; - cfg.dir = DMA_TO_DEVICE; - ret = gdc_dma_buffer_get_phys(&cfg, &addr); + cfg = &fh->dma_cfg.input_cfg_plane2; + cfg->fd = gs_ex->input_buffer.uv_base_fd; + cfg->dev = &fh->gdev->pdev->dev; + cfg->dir = DMA_TO_DEVICE; + ret = gdc_dma_buffer_get_phys(cfg, &addr); if (ret < 0) { gdc_log(LOG_ERR, "dma import input fd %d failed\n", @@ -580,10 +583,11 @@ static long gdc_process_input_dma_info(struct mgdc_fh_s *fh, } break; case Y_GREY: - cfg.fd = gs_ex->input_buffer.y_base_fd; - cfg.dev = &(fh->gdev->pdev->dev); - cfg.dir = DMA_TO_DEVICE; - ret = gdc_dma_buffer_get_phys(&cfg, &addr); + cfg = &fh->dma_cfg.input_cfg_plane1; + cfg->fd = gs_ex->input_buffer.y_base_fd; + cfg->dev = &(fh->gdev->pdev->dev); + cfg->dir = DMA_TO_DEVICE; + ret = gdc_dma_buffer_get_phys(cfg, &addr); if (ret < 0) { gdc_log(LOG_ERR, "dma import input fd %d failed\n", @@ -606,7 +610,7 @@ static long gdc_process_ex_info(struct mgdc_fh_s *fh, long ret; unsigned long addr = 0; size_t len; - struct aml_dma_cfg cfg; + struct aml_dma_cfg *cfg = NULL; struct gdc_cmd_s *gdc_cmd = &fh->gdc_cmd; if (fh == NULL || gs_ex == NULL) { @@ -628,10 +632,11 @@ static long gdc_process_ex_info(struct mgdc_fh_s *fh, } } else if (gs_ex->output_buffer.mem_alloc_type == AML_GDC_MEM_DMABUF) { /* dma alloc */ - cfg.fd = gs_ex->output_buffer.y_base_fd; - cfg.dev = &(gdc_manager.gdc_dev->pdev->dev); - cfg.dir = DMA_FROM_DEVICE; - ret = gdc_dma_buffer_get_phys(&cfg, &addr); + cfg = &fh->dma_cfg.output_cfg; + cfg->fd = gs_ex->output_buffer.y_base_fd; + cfg->dev = &(gdc_manager.gdc_dev->pdev->dev); + cfg->dir = DMA_FROM_DEVICE; + ret = gdc_dma_buffer_get_phys(cfg, &addr); if (ret < 0) { gdc_log(LOG_ERR, "dma import out fd %d failed\n", gs_ex->output_buffer.y_base_fd); @@ -655,10 +660,11 @@ static long gdc_process_ex_info(struct mgdc_fh_s *fh, } } else if (gs_ex->config_buffer.mem_alloc_type == AML_GDC_MEM_DMABUF) { /* dma alloc */ - cfg.fd = gs_ex->config_buffer.y_base_fd; - cfg.dev = &(gdc_manager.gdc_dev->pdev->dev); - cfg.dir = DMA_TO_DEVICE; - ret = gdc_dma_buffer_get_phys(&cfg, &addr); + cfg = &fh->dma_cfg.config_cfg; + cfg->fd = gs_ex->config_buffer.y_base_fd; + cfg->dev = &(gdc_manager.gdc_dev->pdev->dev); + cfg->dir = DMA_TO_DEVICE; + ret = gdc_dma_buffer_get_phys(cfg, &addr); if (ret < 0) { gdc_log(LOG_ERR, "dma import config fd %d failed\n", gs_ex->config_buffer.shared_fd); @@ -690,10 +696,10 @@ static long gdc_process_ex_info(struct mgdc_fh_s *fh, gdc_log(LOG_INFO, "%s, input addr=%x\n", __func__, fh->gdc_cmd.y_base_addr); mutex_lock(&fh->gdev->d_mutext); - #if 1 + if (gs_ex->config_buffer.mem_alloc_type == AML_GDC_MEM_DMABUF) gdc_buffer_dma_flush(gs_ex->config_buffer.shared_fd); - #endif + ret = gdc_run(gdc_cmd); if (ret < 0) gdc_log(LOG_ERR, "gdc process failed ret = %ld\n", ret); @@ -704,11 +710,20 @@ static long gdc_process_ex_info(struct mgdc_fh_s *fh, gdc_log(LOG_ERR, "gdc timeout\n"); gdc_stop(gdc_cmd); + mutex_unlock(&fh->gdev->d_mutext); #if 0 if (gs_ex->output_buffer.mem_alloc_type == AML_GDC_MEM_DMABUF) gdc_buffer_cache_flush(gs_ex->output_buffer.shared_fd); #endif - mutex_unlock(&fh->gdev->d_mutext); + if (gs_ex->input_buffer.mem_alloc_type == AML_GDC_MEM_DMABUF) { + gdc_dma_buffer_unmap(&fh->dma_cfg.input_cfg_plane1); + if (gs_ex->input_buffer.plane_number == 2) + gdc_dma_buffer_unmap(&fh->dma_cfg.input_cfg_plane2); + } + if (gs_ex->config_buffer.mem_alloc_type == AML_GDC_MEM_DMABUF) + gdc_dma_buffer_unmap(&fh->dma_cfg.config_cfg); + if (gs_ex->output_buffer.mem_alloc_type == AML_GDC_MEM_DMABUF) + gdc_dma_buffer_unmap(&fh->dma_cfg.output_cfg); return 0; } diff --git a/drivers/amlogic/media/gdc/inc/gdc/gdc_config.h b/drivers/amlogic/media/gdc/inc/gdc/gdc_config.h index 9cab803561fe..dbf7300dea08 100644 --- a/drivers/amlogic/media/gdc/inc/gdc/gdc_config.h +++ b/drivers/amlogic/media/gdc/inc/gdc/gdc_config.h @@ -25,7 +25,7 @@ #include #include "system_gdc_io.h" #include "gdc_api.h" - +#include "gdc_dmabuf.h" struct gdc_cmd_s; struct gdc_manager_s { @@ -45,6 +45,13 @@ struct meson_gdc_dev_t { struct miscdevice misc_dev; }; +struct gdc_dma_cfg_t { + struct aml_dma_cfg input_cfg_plane1; + struct aml_dma_cfg input_cfg_plane2; + struct aml_dma_cfg config_cfg; + struct aml_dma_cfg output_cfg; +}; + struct mgdc_fh_s { struct list_head list; wait_queue_head_t irq_queue; @@ -64,6 +71,7 @@ struct mgdc_fh_s { unsigned long c_len; struct gdc_dma_cfg y_dma_cfg; struct gdc_dma_cfg uv_dma_cfg; + struct gdc_dma_cfg_t dma_cfg; }; irqreturn_t interrupt_handler_next(int irq, void *param);