aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/platform/omap3isp/ispccdc.c51
-rw-r--r--drivers/media/platform/omap3isp/ispccdc.h8
2 files changed, 35 insertions, 24 deletions
diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c
index a907b20c2e8d..004a4f52d9d7 100644
--- a/drivers/media/platform/omap3isp/ispccdc.c
+++ b/drivers/media/platform/omap3isp/ispccdc.c
@@ -30,7 +30,6 @@
30#include <linux/device.h> 30#include <linux/device.h>
31#include <linux/dma-mapping.h> 31#include <linux/dma-mapping.h>
32#include <linux/mm.h> 32#include <linux/mm.h>
33#include <linux/omap-iommu.h>
34#include <linux/sched.h> 33#include <linux/sched.h>
35#include <linux/slab.h> 34#include <linux/slab.h>
36#include <media/v4l2-event.h> 35#include <media/v4l2-event.h>
@@ -578,7 +577,7 @@ static void ccdc_configure_fpc(struct isp_ccdc_device *ccdc)
578 if (!ccdc->fpc_en) 577 if (!ccdc->fpc_en)
579 return; 578 return;
580 579
581 isp_reg_writel(isp, ccdc->fpc.fpcaddr, OMAP3_ISP_IOMEM_CCDC, 580 isp_reg_writel(isp, ccdc->fpc.dma, OMAP3_ISP_IOMEM_CCDC,
582 ISPCCDC_FPC_ADDR); 581 ISPCCDC_FPC_ADDR);
583 /* The FPNUM field must be set before enabling FPC. */ 582 /* The FPNUM field must be set before enabling FPC. */
584 isp_reg_writel(isp, (ccdc->fpc.fpnum << ISPCCDC_FPC_FPNUM_SHIFT), 583 isp_reg_writel(isp, (ccdc->fpc.fpnum << ISPCCDC_FPC_FPNUM_SHIFT),
@@ -718,8 +717,9 @@ static int ccdc_config(struct isp_ccdc_device *ccdc,
718 ccdc->shadow_update = 0; 717 ccdc->shadow_update = 0;
719 718
720 if (OMAP3ISP_CCDC_FPC & ccdc_struct->update) { 719 if (OMAP3ISP_CCDC_FPC & ccdc_struct->update) {
721 u32 table_old = 0; 720 struct omap3isp_ccdc_fpc fpc;
722 u32 table_new; 721 struct ispccdc_fpc fpc_old = { .addr = NULL, };
722 struct ispccdc_fpc fpc_new;
723 u32 size; 723 u32 size;
724 724
725 if (ccdc->state != ISP_PIPELINE_STREAM_STOPPED) 725 if (ccdc->state != ISP_PIPELINE_STREAM_STOPPED)
@@ -728,35 +728,39 @@ static int ccdc_config(struct isp_ccdc_device *ccdc,
728 ccdc->fpc_en = !!(OMAP3ISP_CCDC_FPC & ccdc_struct->flag); 728 ccdc->fpc_en = !!(OMAP3ISP_CCDC_FPC & ccdc_struct->flag);
729 729
730 if (ccdc->fpc_en) { 730 if (ccdc->fpc_en) {
731 if (copy_from_user(&ccdc->fpc, ccdc_struct->fpc, 731 if (copy_from_user(&fpc, ccdc_struct->fpc, sizeof(fpc)))
732 sizeof(ccdc->fpc)))
733 return -EFAULT; 732 return -EFAULT;
734 733
734 size = fpc.fpnum * 4;
735
735 /* 736 /*
736 * table_new must be 64-bytes aligned, but it's 737 * The table address must be 64-bytes aligned, which is
737 * already done by omap_iommu_vmalloc(). 738 * guaranteed by dma_alloc_coherent().
738 */ 739 */
739 size = ccdc->fpc.fpnum * 4; 740 fpc_new.fpnum = fpc.fpnum;
740 table_new = omap_iommu_vmalloc(isp->domain, isp->dev, 741 fpc_new.addr = dma_alloc_coherent(isp->dev, size,
741 0, size, IOMMU_FLAG); 742 &fpc_new.dma,
742 if (IS_ERR_VALUE(table_new)) 743 GFP_KERNEL);
744 if (fpc_new.addr == NULL)
743 return -ENOMEM; 745 return -ENOMEM;
744 746
745 if (copy_from_user(omap_da_to_va(isp->dev, table_new), 747 if (copy_from_user(fpc_new.addr,
746 (__force void __user *) 748 (__force void __user *)fpc.fpcaddr,
747 ccdc->fpc.fpcaddr, size)) { 749 size)) {
748 omap_iommu_vfree(isp->domain, isp->dev, 750 dma_free_coherent(isp->dev, size, fpc_new.addr,
749 table_new); 751 fpc_new.dma);
750 return -EFAULT; 752 return -EFAULT;
751 } 753 }
752 754
753 table_old = ccdc->fpc.fpcaddr; 755 fpc_old = ccdc->fpc;
754 ccdc->fpc.fpcaddr = table_new; 756 ccdc->fpc = fpc_new;
755 } 757 }
756 758
757 ccdc_configure_fpc(ccdc); 759 ccdc_configure_fpc(ccdc);
758 if (table_old != 0) 760
759 omap_iommu_vfree(isp->domain, isp->dev, table_old); 761 if (fpc_old.addr != NULL)
762 dma_free_coherent(isp->dev, fpc_old.fpnum * 4,
763 fpc_old.addr, fpc_old.dma);
760 } 764 }
761 765
762 return ccdc_lsc_config(ccdc, ccdc_struct); 766 return ccdc_lsc_config(ccdc, ccdc_struct);
@@ -2574,8 +2578,9 @@ void omap3isp_ccdc_cleanup(struct isp_device *isp)
2574 cancel_work_sync(&ccdc->lsc.table_work); 2578 cancel_work_sync(&ccdc->lsc.table_work);
2575 ccdc_lsc_free_queue(ccdc, &ccdc->lsc.free_queue); 2579 ccdc_lsc_free_queue(ccdc, &ccdc->lsc.free_queue);
2576 2580
2577 if (ccdc->fpc.fpcaddr != 0) 2581 if (ccdc->fpc.addr != NULL)
2578 omap_iommu_vfree(isp->domain, isp->dev, ccdc->fpc.fpcaddr); 2582 dma_free_coherent(isp->dev, ccdc->fpc.fpnum * 4, ccdc->fpc.addr,
2583 ccdc->fpc.dma);
2579 2584
2580 mutex_destroy(&ccdc->ioctl_lock); 2585 mutex_destroy(&ccdc->ioctl_lock);
2581} 2586}
diff --git a/drivers/media/platform/omap3isp/ispccdc.h b/drivers/media/platform/omap3isp/ispccdc.h
index 20db3a060d8f..f65061602c71 100644
--- a/drivers/media/platform/omap3isp/ispccdc.h
+++ b/drivers/media/platform/omap3isp/ispccdc.h
@@ -46,6 +46,12 @@ enum ccdc_input_entity {
46 46
47#define OMAP3ISP_CCDC_NEVENTS 16 47#define OMAP3ISP_CCDC_NEVENTS 16
48 48
49struct ispccdc_fpc {
50 void *addr;
51 dma_addr_t dma;
52 unsigned int fpnum;
53};
54
49enum ispccdc_lsc_state { 55enum ispccdc_lsc_state {
50 LSC_STATE_STOPPED = 0, 56 LSC_STATE_STOPPED = 0,
51 LSC_STATE_STOPPING = 1, 57 LSC_STATE_STOPPING = 1,
@@ -140,7 +146,7 @@ struct isp_ccdc_device {
140 fpc_en:1; 146 fpc_en:1;
141 struct omap3isp_ccdc_blcomp blcomp; 147 struct omap3isp_ccdc_blcomp blcomp;
142 struct omap3isp_ccdc_bclamp clamp; 148 struct omap3isp_ccdc_bclamp clamp;
143 struct omap3isp_ccdc_fpc fpc; 149 struct ispccdc_fpc fpc;
144 struct ispccdc_lsc lsc; 150 struct ispccdc_lsc lsc;
145 unsigned int update; 151 unsigned int update;
146 unsigned int shadow_update; 152 unsigned int shadow_update;