diff options
Diffstat (limited to 'drivers/media/platform/omap3isp/ispccdc.c')
-rw-r--r-- | drivers/media/platform/omap3isp/ispccdc.c | 107 |
1 files changed, 53 insertions, 54 deletions
diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c index 4d920c800ff..9f727d20f06 100644 --- a/drivers/media/platform/omap3isp/ispccdc.c +++ b/drivers/media/platform/omap3isp/ispccdc.c @@ -30,7 +30,6 @@ #include <linux/device.h> #include <linux/dma-mapping.h> #include <linux/mm.h> -#include <linux/omap-iommu.h> #include <linux/sched.h> #include <linux/slab.h> #include <media/v4l2-event.h> @@ -206,7 +205,8 @@ static int ccdc_lsc_validate_config(struct isp_ccdc_device *ccdc, * ccdc_lsc_program_table - Program Lens Shading Compensation table address. * @ccdc: Pointer to ISP CCDC device. */ -static void ccdc_lsc_program_table(struct isp_ccdc_device *ccdc, u32 addr) +static void ccdc_lsc_program_table(struct isp_ccdc_device *ccdc, + dma_addr_t addr) { isp_reg_writel(to_isp_device(ccdc), addr, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_TABLE_BASE); @@ -333,7 +333,7 @@ static int __ccdc_lsc_configure(struct isp_ccdc_device *ccdc, return -EBUSY; ccdc_lsc_setup_regs(ccdc, &req->config); - ccdc_lsc_program_table(ccdc, req->table); + ccdc_lsc_program_table(ccdc, req->table.dma); return 0; } @@ -368,11 +368,12 @@ static void ccdc_lsc_free_request(struct isp_ccdc_device *ccdc, if (req == NULL) return; - if (req->iovm) - dma_unmap_sg(isp->dev, req->iovm->sgt->sgl, - req->iovm->sgt->nents, DMA_TO_DEVICE); - if (req->table) - omap_iommu_vfree(isp->domain, isp->dev, req->table); + if (req->table.addr) { + sg_free_table(&req->table.sgt); + dma_free_coherent(isp->dev, req->config.size, req->table.addr, + req->table.dma); + } + kfree(req); } @@ -416,7 +417,6 @@ static int ccdc_lsc_config(struct isp_ccdc_device *ccdc, struct isp_device *isp = to_isp_device(ccdc); struct ispccdc_lsc_config_req *req; unsigned long flags; - void *table; u16 update; int ret; @@ -444,38 +444,31 @@ static int ccdc_lsc_config(struct isp_ccdc_device *ccdc, req->enable = 1; - req->table = omap_iommu_vmalloc(isp->domain, isp->dev, 0, - req->config.size, IOMMU_FLAG); - if (IS_ERR_VALUE(req->table)) { - req->table = 0; - ret = -ENOMEM; - goto done; - } - - req->iovm = omap_find_iovm_area(isp->dev, req->table); - if (req->iovm == NULL) { + req->table.addr = dma_alloc_coherent(isp->dev, req->config.size, + &req->table.dma, + GFP_KERNEL); + if (req->table.addr == NULL) { ret = -ENOMEM; goto done; } - if (!dma_map_sg(isp->dev, req->iovm->sgt->sgl, - req->iovm->sgt->nents, DMA_TO_DEVICE)) { - ret = -ENOMEM; - req->iovm = NULL; + ret = dma_get_sgtable(isp->dev, &req->table.sgt, + req->table.addr, req->table.dma, + req->config.size); + if (ret < 0) goto done; - } - dma_sync_sg_for_cpu(isp->dev, req->iovm->sgt->sgl, - req->iovm->sgt->nents, DMA_TO_DEVICE); + dma_sync_sg_for_cpu(isp->dev, req->table.sgt.sgl, + req->table.sgt.nents, DMA_TO_DEVICE); - table = omap_da_to_va(isp->dev, req->table); - if (copy_from_user(table, config->lsc, req->config.size)) { + if (copy_from_user(req->table.addr, config->lsc, + req->config.size)) { ret = -EFAULT; goto done; } - dma_sync_sg_for_device(isp->dev, req->iovm->sgt->sgl, - req->iovm->sgt->nents, DMA_TO_DEVICE); + dma_sync_sg_for_device(isp->dev, req->table.sgt.sgl, + req->table.sgt.nents, DMA_TO_DEVICE); } spin_lock_irqsave(&ccdc->lsc.req_lock, flags); @@ -584,7 +577,7 @@ static void ccdc_configure_fpc(struct isp_ccdc_device *ccdc) if (!ccdc->fpc_en) return; - isp_reg_writel(isp, ccdc->fpc.fpcaddr, OMAP3_ISP_IOMEM_CCDC, + isp_reg_writel(isp, ccdc->fpc.dma, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FPC_ADDR); /* The FPNUM field must be set before enabling FPC. */ isp_reg_writel(isp, (ccdc->fpc.fpnum << ISPCCDC_FPC_FPNUM_SHIFT), @@ -724,8 +717,9 @@ static int ccdc_config(struct isp_ccdc_device *ccdc, ccdc->shadow_update = 0; if (OMAP3ISP_CCDC_FPC & ccdc_struct->update) { - u32 table_old = 0; - u32 table_new; + struct omap3isp_ccdc_fpc fpc; + struct ispccdc_fpc fpc_old = { .addr = NULL, }; + struct ispccdc_fpc fpc_new; u32 size; if (ccdc->state != ISP_PIPELINE_STREAM_STOPPED) @@ -734,35 +728,39 @@ static int ccdc_config(struct isp_ccdc_device *ccdc, ccdc->fpc_en = !!(OMAP3ISP_CCDC_FPC & ccdc_struct->flag); if (ccdc->fpc_en) { - if (copy_from_user(&ccdc->fpc, ccdc_struct->fpc, - sizeof(ccdc->fpc))) + if (copy_from_user(&fpc, ccdc_struct->fpc, sizeof(fpc))) return -EFAULT; + size = fpc.fpnum * 4; + /* - * table_new must be 64-bytes aligned, but it's - * already done by omap_iommu_vmalloc(). + * The table address must be 64-bytes aligned, which is + * guaranteed by dma_alloc_coherent(). */ - size = ccdc->fpc.fpnum * 4; - table_new = omap_iommu_vmalloc(isp->domain, isp->dev, - 0, size, IOMMU_FLAG); - if (IS_ERR_VALUE(table_new)) + fpc_new.fpnum = fpc.fpnum; + fpc_new.addr = dma_alloc_coherent(isp->dev, size, + &fpc_new.dma, + GFP_KERNEL); + if (fpc_new.addr == NULL) return -ENOMEM; - if (copy_from_user(omap_da_to_va(isp->dev, table_new), - (__force void __user *) - ccdc->fpc.fpcaddr, size)) { - omap_iommu_vfree(isp->domain, isp->dev, - table_new); + if (copy_from_user(fpc_new.addr, + (__force void __user *)fpc.fpcaddr, + size)) { + dma_free_coherent(isp->dev, size, fpc_new.addr, + fpc_new.dma); return -EFAULT; } - table_old = ccdc->fpc.fpcaddr; - ccdc->fpc.fpcaddr = table_new; + fpc_old = ccdc->fpc; + ccdc->fpc = fpc_new; } ccdc_configure_fpc(ccdc); - if (table_old != 0) - omap_iommu_vfree(isp->domain, isp->dev, table_old); + + if (fpc_old.addr != NULL) + dma_free_coherent(isp->dev, fpc_old.fpnum * 4, + fpc_old.addr, fpc_old.dma); } return ccdc_lsc_config(ccdc, ccdc_struct); @@ -1523,7 +1521,7 @@ static int ccdc_isr_buffer(struct isp_ccdc_device *ccdc) buffer = omap3isp_video_buffer_next(&ccdc->video_out); if (buffer != NULL) { - ccdc_set_outaddr(ccdc, buffer->isp_addr); + ccdc_set_outaddr(ccdc, buffer->dma); restart = 1; } @@ -1662,7 +1660,7 @@ static int ccdc_video_queue(struct isp_video *video, struct isp_buffer *buffer) if (!(ccdc->output & CCDC_OUTPUT_MEMORY)) return -ENODEV; - ccdc_set_outaddr(ccdc, buffer->isp_addr); + ccdc_set_outaddr(ccdc, buffer->dma); /* We now have a buffer queued on the output, restart the pipeline * on the next CCDC interrupt if running in continuous mode (or when @@ -2580,8 +2578,9 @@ void omap3isp_ccdc_cleanup(struct isp_device *isp) cancel_work_sync(&ccdc->lsc.table_work); ccdc_lsc_free_queue(ccdc, &ccdc->lsc.free_queue); - if (ccdc->fpc.fpcaddr != 0) - omap_iommu_vfree(isp->domain, isp->dev, ccdc->fpc.fpcaddr); + if (ccdc->fpc.addr != NULL) + dma_free_coherent(isp->dev, ccdc->fpc.fpnum * 4, ccdc->fpc.addr, + ccdc->fpc.dma); mutex_destroy(&ccdc->ioctl_lock); } |