From 436d4c489eaeca3c785c916dd71ad4d2fd187339 Mon Sep 17 00:00:00 2001 From: "dalong.zhang" Date: Thu, 22 Dec 2016 11:26:08 +0800 Subject: [PATCH] camera: rockchip: camsys driver v0.0x21.9 Change-Id: I371f3bfc1e6276407bb9481f4a7897d4955903ba Signed-off-by: dalong.zhang --- .../media/video/rk_camsys/camsys_internal.h | 7 +- drivers/media/video/rk_camsys/camsys_marvin.c | 67 +++++++++++++++++-- 2 files changed, 69 insertions(+), 5 deletions(-) diff --git a/drivers/media/video/rk_camsys/camsys_internal.h b/drivers/media/video/rk_camsys/camsys_internal.h index 4b73fddad5ca..11efb236005f 100644 --- a/drivers/media/video/rk_camsys/camsys_internal.h +++ b/drivers/media/video/rk_camsys/camsys_internal.h @@ -146,8 +146,13 @@ * 1) remove memset function wrong called code. *v0.0x21.8: * 1) flash module exist risk, fix up it. +*v0.0x21.9: + 1) fix drm iommu crash. + if process cameraserver was died during streaming, iommu resource + was not released correctly. when cameraserver was recovered and + streaming again, iommu resource may be conflicted. */ -#define CAMSYS_DRIVER_VERSION KERNEL_VERSION(0, 0x21, 8) +#define CAMSYS_DRIVER_VERSION KERNEL_VERSION(0, 0x21, 9) #define CAMSYS_PLATFORM_DRV_NAME "RockChip-CamSys" #define CAMSYS_PLATFORM_MARVIN_NAME "Platform_MarvinDev" diff --git a/drivers/media/video/rk_camsys/camsys_marvin.c b/drivers/media/video/rk_camsys/camsys_marvin.c index 4321bddb87c2..e3e236f0e085 100755 --- a/drivers/media/video/rk_camsys/camsys_marvin.c +++ b/drivers/media/video/rk_camsys/camsys_marvin.c @@ -393,13 +393,43 @@ static int camsys_mrv_drm_iommu_cb(void *ptr, camsys_sysctrl_t *devctl) dev = &camsys_dev->pdev->dev; iommu = (camsys_iommu_t *)(devctl->rev); - index = camsys_dev->dma_buf_cnt; if (devctl->on) { - if (index == 0) { + /*ummap mapped fd first*/ + int cur_mapped_cnt = camsys_dev->dma_buf_cnt; + + for (index = 0; index < cur_mapped_cnt; index++) { + if (camsys_dev->dma_buf[index].fd == iommu->map_fd) + break; + } + if (index != cur_mapped_cnt) { + attach = camsys_dev->dma_buf[index].attach; + dma_buf = camsys_dev->dma_buf[index].dma_buf; + sgt = camsys_dev->dma_buf[index].sgt; + dma_buf_unmap_attachment + (attach, + sgt, + DMA_BIDIRECTIONAL); + dma_buf_detach(dma_buf, attach); + dma_buf_put(dma_buf); + if (camsys_dev->dma_buf_cnt == 1) + camsys_drm_dma_detach_device(camsys_dev); + camsys_dev->dma_buf_cnt--; + camsys_dev->dma_buf[index].fd = -1; + } + /*get a free slot*/ + for (index = 0; index < CAMSYS_DMA_BUF_MAX_NUM; index++) + if (camsys_dev->dma_buf[index].fd == -1) + break; + + if (index == CAMSYS_DMA_BUF_MAX_NUM) + return -ENOMEM; + + if (camsys_dev->dma_buf_cnt == 0) { ret = camsys_drm_dma_attach_device(camsys_dev); if (ret) return ret; } + dma_buf = dma_buf_get(iommu->map_fd); if (IS_ERR(dma_buf)) return PTR_ERR(dma_buf); @@ -423,10 +453,25 @@ static int camsys_mrv_drm_iommu_cb(void *ptr, camsys_sysctrl_t *devctl) iommu->linear_addr = dma_addr; iommu->len = sg_dma_len(sgt->sgl); camsys_dev->dma_buf_cnt++; + camsys_trace + ( + 1, + "%s:iommu map dma_addr 0x%lx,attach %p," + "dma_buf %p,sgt %p,fd %d,buf_cnt %d", + __func__, + (unsigned long)dma_addr, + attach, + dma_buf, + sgt, + iommu->map_fd, + camsys_dev->dma_buf_cnt); } else { - if ((camsys_dev->dma_buf_cnt == 0) || (index < 0) || - (index >= CAMSYS_DMA_BUF_MAX_NUM)) + if ( + (camsys_dev->dma_buf_cnt == 0) || + (index < 0) || + (index >= CAMSYS_DMA_BUF_MAX_NUM)) return -EINVAL; + for (index = 0; index < camsys_dev->dma_buf_cnt; index++) { if (camsys_dev->dma_buf[index].fd == iommu->map_fd) break; @@ -438,6 +483,16 @@ static int camsys_mrv_drm_iommu_cb(void *ptr, camsys_sysctrl_t *devctl) attach = camsys_dev->dma_buf[index].attach; dma_buf = camsys_dev->dma_buf[index].dma_buf; sgt = camsys_dev->dma_buf[index].sgt; + camsys_trace + ( + 1, + "%s:iommu map ,attach %p," + "dma_buf %p,sgt %p,index %d", + __func__, + attach, + dma_buf, + sgt, + index); dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL); dma_buf_detach(dma_buf, attach); dma_buf_put(dma_buf); @@ -445,6 +500,7 @@ static int camsys_mrv_drm_iommu_cb(void *ptr, camsys_sysctrl_t *devctl) camsys_drm_dma_detach_device(camsys_dev); camsys_dev->dma_buf_cnt--; + camsys_dev->dma_buf[index].fd = -1; } return ret; @@ -1043,6 +1099,7 @@ int camsys_mrv_probe_cb(struct platform_device *pdev, camsys_dev_t *camsys_dev) np = of_find_node_by_name(NULL, "isp0_mmu"); if (!np) { + int index = 0; /* iommu domain */ domain = iommu_domain_alloc(&platform_bus_type); if (!domain) @@ -1070,6 +1127,8 @@ int camsys_mrv_probe_cb(struct platform_device *pdev, camsys_dev_t *camsys_dev) camsys_dev->domain = domain; camsys_dev->dma_buf_cnt = 0; camsys_dev->iommu_cb = camsys_mrv_drm_iommu_cb; + for (index = 0; index < CAMSYS_DMA_BUF_MAX_NUM; index++) + camsys_dev->dma_buf[index].fd = -1; } else { camsys_dev->iommu_cb = camsys_mrv_iommu_cb; } -- 2.34.1