aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/omap3isp/isppreview.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/omap3isp/isppreview.c')
-rw-r--r--drivers/media/video/omap3isp/isppreview.c299
1 files changed, 199 insertions, 100 deletions
diff --git a/drivers/media/video/omap3isp/isppreview.c b/drivers/media/video/omap3isp/isppreview.c
index fd1807d36d4..5bdf9e742c8 100644
--- a/drivers/media/video/omap3isp/isppreview.c
+++ b/drivers/media/video/omap3isp/isppreview.c
@@ -649,12 +649,18 @@ preview_config_rgb_to_ycbcr(struct isp_prev_device *prev, const void *prev_csc)
649static void 649static void
650preview_update_contrast(struct isp_prev_device *prev, u8 contrast) 650preview_update_contrast(struct isp_prev_device *prev, u8 contrast)
651{ 651{
652 struct prev_params *params = &prev->params; 652 struct prev_params *params;
653 unsigned long flags;
654
655 spin_lock_irqsave(&prev->params.lock, flags);
656 params = (prev->params.active & OMAP3ISP_PREV_CONTRAST)
657 ? &prev->params.params[0] : &prev->params.params[1];
653 658
654 if (params->contrast != (contrast * ISPPRV_CONTRAST_UNITS)) { 659 if (params->contrast != (contrast * ISPPRV_CONTRAST_UNITS)) {
655 params->contrast = contrast * ISPPRV_CONTRAST_UNITS; 660 params->contrast = contrast * ISPPRV_CONTRAST_UNITS;
656 prev->update |= OMAP3ISP_PREV_CONTRAST; 661 params->update |= OMAP3ISP_PREV_CONTRAST;
657 } 662 }
663 spin_unlock_irqrestore(&prev->params.lock, flags);
658} 664}
659 665
660/* 666/*
@@ -681,12 +687,18 @@ preview_config_contrast(struct isp_prev_device *prev, const void *params)
681static void 687static void
682preview_update_brightness(struct isp_prev_device *prev, u8 brightness) 688preview_update_brightness(struct isp_prev_device *prev, u8 brightness)
683{ 689{
684 struct prev_params *params = &prev->params; 690 struct prev_params *params;
691 unsigned long flags;
692
693 spin_lock_irqsave(&prev->params.lock, flags);
694 params = (prev->params.active & OMAP3ISP_PREV_BRIGHTNESS)
695 ? &prev->params.params[0] : &prev->params.params[1];
685 696
686 if (params->brightness != (brightness * ISPPRV_BRIGHT_UNITS)) { 697 if (params->brightness != (brightness * ISPPRV_BRIGHT_UNITS)) {
687 params->brightness = brightness * ISPPRV_BRIGHT_UNITS; 698 params->brightness = brightness * ISPPRV_BRIGHT_UNITS;
688 prev->update |= OMAP3ISP_PREV_BRIGHTNESS; 699 params->update |= OMAP3ISP_PREV_BRIGHTNESS;
689 } 700 }
701 spin_unlock_irqrestore(&prev->params.lock, flags);
690} 702}
691 703
692/* 704/*
@@ -721,6 +733,75 @@ preview_config_yc_range(struct isp_prev_device *prev, const void *yclimit)
721 OMAP3_ISP_IOMEM_PREV, ISPPRV_SETUP_YC); 733 OMAP3_ISP_IOMEM_PREV, ISPPRV_SETUP_YC);
722} 734}
723 735
736static u32
737preview_params_lock(struct isp_prev_device *prev, u32 update, bool shadow)
738{
739 u32 active = prev->params.active;
740
741 if (shadow) {
742 /* Mark all shadow parameters we are going to touch as busy. */
743 prev->params.params[0].busy |= ~active & update;
744 prev->params.params[1].busy |= active & update;
745 } else {
746 /* Mark all active parameters we are going to touch as busy. */
747 update = (prev->params.params[0].update & active)
748 | (prev->params.params[1].update & ~active);
749
750 prev->params.params[0].busy |= active & update;
751 prev->params.params[1].busy |= ~active & update;
752 }
753
754 return update;
755}
756
757static void
758preview_params_unlock(struct isp_prev_device *prev, u32 update, bool shadow)
759{
760 u32 active = prev->params.active;
761
762 if (shadow) {
763 /* Set the update flag for shadow parameters that have been
764 * updated and clear the busy flag for all shadow parameters.
765 */
766 prev->params.params[0].update |= (~active & update);
767 prev->params.params[1].update |= (active & update);
768 prev->params.params[0].busy &= active;
769 prev->params.params[1].busy &= ~active;
770 } else {
771 /* Clear the update flag for active parameters that have been
772 * applied and the busy flag for all active parameters.
773 */
774 prev->params.params[0].update &= ~(active & update);
775 prev->params.params[1].update &= ~(~active & update);
776 prev->params.params[0].busy &= ~active;
777 prev->params.params[1].busy &= active;
778 }
779}
780
781static void preview_params_switch(struct isp_prev_device *prev)
782{
783 u32 to_switch;
784
785 /* Switch active parameters with updated shadow parameters when the
786 * shadow parameter has been updated and neither the active not the
787 * shadow parameter is busy.
788 */
789 to_switch = (prev->params.params[0].update & ~prev->params.active)
790 | (prev->params.params[1].update & prev->params.active);
791 to_switch &= ~(prev->params.params[0].busy |
792 prev->params.params[1].busy);
793 if (to_switch == 0)
794 return;
795
796 prev->params.active ^= to_switch;
797
798 /* Remove the update flag for the shadow copy of parameters we have
799 * switched.
800 */
801 prev->params.params[0].update &= ~(~prev->params.active & to_switch);
802 prev->params.params[1].update &= ~(prev->params.active & to_switch);
803}
804
724/* preview parameters update structure */ 805/* preview parameters update structure */
725struct preview_update { 806struct preview_update {
726 void (*config)(struct isp_prev_device *, const void *); 807 void (*config)(struct isp_prev_device *, const void *);
@@ -834,37 +915,6 @@ static const struct preview_update update_attrs[] = {
834}; 915};
835 916
836/* 917/*
837 * __preview_get_ptrs - helper function which return pointers to members
838 * of params and config structures.
839 * @params - pointer to preview_params structure.
840 * @param - return pointer to appropriate structure field.
841 * @configs - pointer to update config structure.
842 * @config - return pointer to appropriate structure field.
843 * @bit - for which feature to return pointers.
844 * Return size of corresponding prev_params member
845 */
846static u32
847__preview_get_ptrs(struct prev_params *params, void **param,
848 struct omap3isp_prev_update_config *configs,
849 void __user **config, unsigned int index)
850{
851 const struct preview_update *info = &update_attrs[index];
852
853 if (index >= ARRAY_SIZE(update_attrs)) {
854 if (config)
855 *config = NULL;
856 *param = NULL;
857 return 0;
858 }
859
860 if (configs && config)
861 *config = *(void **)((void *)configs + info->config_offset);
862
863 *param = (void *)params + info->param_offset;
864 return info->param_size;
865}
866
867/*
868 * preview_config - Copy and update local structure with userspace preview 918 * preview_config - Copy and update local structure with userspace preview
869 * configuration. 919 * configuration.
870 * @prev: ISP preview engine 920 * @prev: ISP preview engine
@@ -876,37 +926,41 @@ __preview_get_ptrs(struct prev_params *params, void **param,
876static int preview_config(struct isp_prev_device *prev, 926static int preview_config(struct isp_prev_device *prev,
877 struct omap3isp_prev_update_config *cfg) 927 struct omap3isp_prev_update_config *cfg)
878{ 928{
879 const struct preview_update *attr; 929 unsigned long flags;
880 struct prev_params *params; 930 unsigned int i;
881 int i, bit, rval = 0; 931 int rval = 0;
932 u32 update;
933 u32 active;
882 934
883 if (cfg->update == 0) 935 if (cfg->update == 0)
884 return 0; 936 return 0;
885 937
886 params = &prev->params; 938 /* Mark the shadow parameters we're going to update as busy. */
939 spin_lock_irqsave(&prev->params.lock, flags);
940 preview_params_lock(prev, cfg->update, true);
941 active = prev->params.active;
942 spin_unlock_irqrestore(&prev->params.lock, flags);
887 943
888 if (prev->state != ISP_PIPELINE_STREAM_STOPPED) { 944 update = 0;
889 unsigned long flags;
890
891 spin_lock_irqsave(&prev->lock, flags);
892 prev->shadow_update = 1;
893 spin_unlock_irqrestore(&prev->lock, flags);
894 }
895 945
896 for (i = 0; i < ARRAY_SIZE(update_attrs); i++) { 946 for (i = 0; i < ARRAY_SIZE(update_attrs); i++) {
897 attr = &update_attrs[i]; 947 const struct preview_update *attr = &update_attrs[i];
898 bit = 1 << i; 948 struct prev_params *params;
949 unsigned int bit = 1 << i;
899 950
900 if (attr->skip || !(cfg->update & bit)) 951 if (attr->skip || !(cfg->update & bit))
901 continue; 952 continue;
902 953
954 params = &prev->params.params[!!(active & bit)];
955
903 if (cfg->flag & bit) { 956 if (cfg->flag & bit) {
904 void *to = NULL, __user *from = NULL; 957 void __user *from = *(void * __user *)
905 unsigned long sz = 0; 958 ((void *)cfg + attr->config_offset);
959 void *to = (void *)params + attr->param_offset;
960 size_t size = attr->param_size;
906 961
907 sz = __preview_get_ptrs(params, &to, cfg, &from, i); 962 if (to && from && size) {
908 if (to && from && sz) { 963 if (copy_from_user(to, from, size)) {
909 if (copy_from_user(to, from, sz)) {
910 rval = -EFAULT; 964 rval = -EFAULT;
911 break; 965 break;
912 } 966 }
@@ -916,50 +970,59 @@ static int preview_config(struct isp_prev_device *prev,
916 params->features &= ~bit; 970 params->features &= ~bit;
917 } 971 }
918 972
919 prev->update |= bit; 973 update |= bit;
920 } 974 }
921 975
922 prev->shadow_update = 0; 976 spin_lock_irqsave(&prev->params.lock, flags);
977 preview_params_unlock(prev, update, true);
978 preview_params_switch(prev);
979 spin_unlock_irqrestore(&prev->params.lock, flags);
980
923 return rval; 981 return rval;
924} 982}
925 983
926/* 984/*
927 * preview_setup_hw - Setup preview registers and/or internal memory 985 * preview_setup_hw - Setup preview registers and/or internal memory
928 * @prev: pointer to preview private structure 986 * @prev: pointer to preview private structure
987 * @update: Bitmask of parameters to setup
988 * @active: Bitmask of parameters active in set 0
929 * Note: can be called from interrupt context 989 * Note: can be called from interrupt context
930 * Return none 990 * Return none
931 */ 991 */
932static void preview_setup_hw(struct isp_prev_device *prev) 992static void preview_setup_hw(struct isp_prev_device *prev, u32 update,
993 u32 active)
933{ 994{
934 struct prev_params *params = &prev->params;
935 const struct preview_update *attr;
936 unsigned int bit;
937 unsigned int i; 995 unsigned int i;
938 void *param_ptr; 996 u32 features;
939 997
940 if (prev->update == 0) 998 if (update == 0)
941 return; 999 return;
942 1000
1001 features = (prev->params.params[0].features & active)
1002 | (prev->params.params[1].features & ~active);
1003
943 for (i = 0; i < ARRAY_SIZE(update_attrs); i++) { 1004 for (i = 0; i < ARRAY_SIZE(update_attrs); i++) {
944 attr = &update_attrs[i]; 1005 const struct preview_update *attr = &update_attrs[i];
945 bit = 1 << i; 1006 struct prev_params *params;
1007 unsigned int bit = 1 << i;
1008 void *param_ptr;
946 1009
947 if (!(prev->update & bit)) 1010 if (!(update & bit))
948 continue; 1011 continue;
949 1012
1013 params = &prev->params.params[!(active & bit)];
1014
950 if (params->features & bit) { 1015 if (params->features & bit) {
951 if (attr->config) { 1016 if (attr->config) {
952 __preview_get_ptrs(params, &param_ptr, NULL, 1017 param_ptr = (void *)params + attr->param_offset;
953 NULL, i);
954 attr->config(prev, param_ptr); 1018 attr->config(prev, param_ptr);
955 } 1019 }
956 if (attr->enable) 1020 if (attr->enable)
957 attr->enable(prev, 1); 1021 attr->enable(prev, 1);
958 } else 1022 } else {
959 if (attr->enable) 1023 if (attr->enable)
960 attr->enable(prev, 0); 1024 attr->enable(prev, 0);
961 1025 }
962 prev->update &= ~bit;
963 } 1026 }
964} 1027}
965 1028
@@ -997,13 +1060,17 @@ preview_config_ycpos(struct isp_prev_device *prev,
997static void preview_config_averager(struct isp_prev_device *prev, u8 average) 1060static void preview_config_averager(struct isp_prev_device *prev, u8 average)
998{ 1061{
999 struct isp_device *isp = to_isp_device(prev); 1062 struct isp_device *isp = to_isp_device(prev);
1063 struct prev_params *params;
1000 int reg = 0; 1064 int reg = 0;
1001 1065
1002 if (prev->params.cfa.format == OMAP3ISP_CFAFMT_BAYER) 1066 params = (prev->params.active & OMAP3ISP_PREV_CFA)
1067 ? &prev->params.params[0] : &prev->params.params[1];
1068
1069 if (params->cfa.format == OMAP3ISP_CFAFMT_BAYER)
1003 reg = ISPPRV_AVE_EVENDIST_2 << ISPPRV_AVE_EVENDIST_SHIFT | 1070 reg = ISPPRV_AVE_EVENDIST_2 << ISPPRV_AVE_EVENDIST_SHIFT |
1004 ISPPRV_AVE_ODDDIST_2 << ISPPRV_AVE_ODDDIST_SHIFT | 1071 ISPPRV_AVE_ODDDIST_2 << ISPPRV_AVE_ODDDIST_SHIFT |
1005 average; 1072 average;
1006 else if (prev->params.cfa.format == OMAP3ISP_CFAFMT_RGBFOVEON) 1073 else if (params->cfa.format == OMAP3ISP_CFAFMT_RGBFOVEON)
1007 reg = ISPPRV_AVE_EVENDIST_3 << ISPPRV_AVE_EVENDIST_SHIFT | 1074 reg = ISPPRV_AVE_EVENDIST_3 << ISPPRV_AVE_EVENDIST_SHIFT |
1008 ISPPRV_AVE_ODDDIST_3 << ISPPRV_AVE_ODDDIST_SHIFT | 1075 ISPPRV_AVE_ODDDIST_3 << ISPPRV_AVE_ODDDIST_SHIFT |
1009 average; 1076 average;
@@ -1021,33 +1088,35 @@ static void preview_config_averager(struct isp_prev_device *prev, u8 average)
1021 * 1088 *
1022 * See the explanation at the PREV_MARGIN_* definitions for more details. 1089 * See the explanation at the PREV_MARGIN_* definitions for more details.
1023 */ 1090 */
1024static void preview_config_input_size(struct isp_prev_device *prev) 1091static void preview_config_input_size(struct isp_prev_device *prev, u32 active)
1025{ 1092{
1026 struct isp_device *isp = to_isp_device(prev); 1093 struct isp_device *isp = to_isp_device(prev);
1027 struct prev_params *params = &prev->params;
1028 unsigned int sph = prev->crop.left; 1094 unsigned int sph = prev->crop.left;
1029 unsigned int eph = prev->crop.left + prev->crop.width - 1; 1095 unsigned int eph = prev->crop.left + prev->crop.width - 1;
1030 unsigned int slv = prev->crop.top; 1096 unsigned int slv = prev->crop.top;
1031 unsigned int elv = prev->crop.top + prev->crop.height - 1; 1097 unsigned int elv = prev->crop.top + prev->crop.height - 1;
1098 u32 features;
1032 1099
1033 if (params->features & OMAP3ISP_PREV_CFA) { 1100 features = (prev->params.params[0].features & active)
1101 | (prev->params.params[1].features & ~active);
1102
1103 if (features & OMAP3ISP_PREV_CFA) {
1034 sph -= 2; 1104 sph -= 2;
1035 eph += 2; 1105 eph += 2;
1036 slv -= 2; 1106 slv -= 2;
1037 elv += 2; 1107 elv += 2;
1038 } 1108 }
1039 if (params->features & (OMAP3ISP_PREV_DEFECT_COR | OMAP3ISP_PREV_NF)) { 1109 if (features & (OMAP3ISP_PREV_DEFECT_COR | OMAP3ISP_PREV_NF)) {
1040 sph -= 2; 1110 sph -= 2;
1041 eph += 2; 1111 eph += 2;
1042 slv -= 2; 1112 slv -= 2;
1043 elv += 2; 1113 elv += 2;
1044 } 1114 }
1045 if (params->features & OMAP3ISP_PREV_HRZ_MED) { 1115 if (features & OMAP3ISP_PREV_HRZ_MED) {
1046 sph -= 2; 1116 sph -= 2;
1047 eph += 2; 1117 eph += 2;
1048 } 1118 }
1049 if (params->features & (OMAP3ISP_PREV_CHROMA_SUPP | 1119 if (features & (OMAP3ISP_PREV_CHROMA_SUPP | OMAP3ISP_PREV_LUMAENH))
1050 OMAP3ISP_PREV_LUMAENH))
1051 sph -= 2; 1120 sph -= 2;
1052 1121
1053 isp_reg_writel(isp, (sph << ISPPRV_HORZ_INFO_SPH_SHIFT) | eph, 1122 isp_reg_writel(isp, (sph << ISPPRV_HORZ_INFO_SPH_SHIFT) | eph,
@@ -1182,8 +1251,16 @@ int omap3isp_preview_busy(struct isp_prev_device *prev)
1182 */ 1251 */
1183void omap3isp_preview_restore_context(struct isp_device *isp) 1252void omap3isp_preview_restore_context(struct isp_device *isp)
1184{ 1253{
1185 isp->isp_prev.update = OMAP3ISP_PREV_FEATURES_END - 1; 1254 struct isp_prev_device *prev = &isp->isp_prev;
1186 preview_setup_hw(&isp->isp_prev); 1255 const u32 update = OMAP3ISP_PREV_FEATURES_END - 1;
1256
1257 prev->params.params[0].update = prev->params.active & update;
1258 prev->params.params[1].update = ~prev->params.active & update;
1259
1260 preview_setup_hw(prev, update, prev->params.active);
1261
1262 prev->params.params[0].update = 0;
1263 prev->params.params[1].update = 0;
1187} 1264}
1188 1265
1189/* 1266/*
@@ -1242,12 +1319,21 @@ static void preview_print_status(struct isp_prev_device *prev)
1242/* 1319/*
1243 * preview_init_params - init image processing parameters. 1320 * preview_init_params - init image processing parameters.
1244 * @prev: pointer to previewer private structure 1321 * @prev: pointer to previewer private structure
1245 * return none
1246 */ 1322 */
1247static void preview_init_params(struct isp_prev_device *prev) 1323static void preview_init_params(struct isp_prev_device *prev)
1248{ 1324{
1249 struct prev_params *params = &prev->params; 1325 struct prev_params *params;
1250 int i = 0; 1326 unsigned int i;
1327
1328 spin_lock_init(&prev->params.lock);
1329
1330 prev->params.active = ~0;
1331 prev->params.params[0].busy = 0;
1332 prev->params.params[0].update = OMAP3ISP_PREV_FEATURES_END - 1;
1333 prev->params.params[1].busy = 0;
1334 prev->params.params[1].update = 0;
1335
1336 params = &prev->params.params[0];
1251 1337
1252 /* Init values */ 1338 /* Init values */
1253 params->contrast = ISPPRV_CONTRAST_DEF * ISPPRV_CONTRAST_UNITS; 1339 params->contrast = ISPPRV_CONTRAST_DEF * ISPPRV_CONTRAST_UNITS;
@@ -1291,8 +1377,6 @@ static void preview_init_params(struct isp_prev_device *prev)
1291 | OMAP3ISP_PREV_RGB2RGB | OMAP3ISP_PREV_COLOR_CONV 1377 | OMAP3ISP_PREV_RGB2RGB | OMAP3ISP_PREV_COLOR_CONV
1292 | OMAP3ISP_PREV_WB | OMAP3ISP_PREV_BRIGHTNESS 1378 | OMAP3ISP_PREV_WB | OMAP3ISP_PREV_BRIGHTNESS
1293 | OMAP3ISP_PREV_CONTRAST; 1379 | OMAP3ISP_PREV_CONTRAST;
1294
1295 prev->update = OMAP3ISP_PREV_FEATURES_END - 1;
1296} 1380}
1297 1381
1298/* 1382/*
@@ -1321,8 +1405,17 @@ static void preview_configure(struct isp_prev_device *prev)
1321{ 1405{
1322 struct isp_device *isp = to_isp_device(prev); 1406 struct isp_device *isp = to_isp_device(prev);
1323 struct v4l2_mbus_framefmt *format; 1407 struct v4l2_mbus_framefmt *format;
1408 unsigned long flags;
1409 u32 update;
1410 u32 active;
1324 1411
1325 preview_setup_hw(prev); 1412 spin_lock_irqsave(&prev->params.lock, flags);
1413 /* Mark all active parameters we are going to touch as busy. */
1414 update = preview_params_lock(prev, 0, false);
1415 active = prev->params.active;
1416 spin_unlock_irqrestore(&prev->params.lock, flags);
1417
1418 preview_setup_hw(prev, update, active);
1326 1419
1327 if (prev->output & PREVIEW_OUTPUT_MEMORY) 1420 if (prev->output & PREVIEW_OUTPUT_MEMORY)
1328 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR, 1421 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
@@ -1343,7 +1436,7 @@ static void preview_configure(struct isp_prev_device *prev)
1343 1436
1344 preview_adjust_bandwidth(prev); 1437 preview_adjust_bandwidth(prev);
1345 1438
1346 preview_config_input_size(prev); 1439 preview_config_input_size(prev, active);
1347 1440
1348 if (prev->input == PREVIEW_INPUT_CCDC) 1441 if (prev->input == PREVIEW_INPUT_CCDC)
1349 preview_config_inlineoffset(prev, 0); 1442 preview_config_inlineoffset(prev, 0);
@@ -1360,6 +1453,10 @@ static void preview_configure(struct isp_prev_device *prev)
1360 1453
1361 preview_config_averager(prev, 0); 1454 preview_config_averager(prev, 0);
1362 preview_config_ycpos(prev, format->code); 1455 preview_config_ycpos(prev, format->code);
1456
1457 spin_lock_irqsave(&prev->params.lock, flags);
1458 preview_params_unlock(prev, update, false);
1459 spin_unlock_irqrestore(&prev->params.lock, flags);
1363} 1460}
1364 1461
1365/* ----------------------------------------------------------------------------- 1462/* -----------------------------------------------------------------------------
@@ -1448,25 +1545,30 @@ static void preview_isr_buffer(struct isp_prev_device *prev)
1448void omap3isp_preview_isr(struct isp_prev_device *prev) 1545void omap3isp_preview_isr(struct isp_prev_device *prev)
1449{ 1546{
1450 unsigned long flags; 1547 unsigned long flags;
1548 u32 update;
1549 u32 active;
1451 1550
1452 if (omap3isp_module_sync_is_stopping(&prev->wait, &prev->stopping)) 1551 if (omap3isp_module_sync_is_stopping(&prev->wait, &prev->stopping))
1453 return; 1552 return;
1454 1553
1455 spin_lock_irqsave(&prev->lock, flags); 1554 spin_lock_irqsave(&prev->params.lock, flags);
1456 if (prev->shadow_update) 1555 preview_params_switch(prev);
1457 goto done; 1556 update = preview_params_lock(prev, 0, false);
1557 active = prev->params.active;
1558 spin_unlock_irqrestore(&prev->params.lock, flags);
1458 1559
1459 preview_setup_hw(prev); 1560 preview_setup_hw(prev, update, active);
1460 preview_config_input_size(prev); 1561 preview_config_input_size(prev, active);
1461
1462done:
1463 spin_unlock_irqrestore(&prev->lock, flags);
1464 1562
1465 if (prev->input == PREVIEW_INPUT_MEMORY || 1563 if (prev->input == PREVIEW_INPUT_MEMORY ||
1466 prev->output & PREVIEW_OUTPUT_MEMORY) 1564 prev->output & PREVIEW_OUTPUT_MEMORY)
1467 preview_isr_buffer(prev); 1565 preview_isr_buffer(prev);
1468 else if (prev->state == ISP_PIPELINE_STREAM_CONTINUOUS) 1566 else if (prev->state == ISP_PIPELINE_STREAM_CONTINUOUS)
1469 preview_enable_oneshot(prev); 1567 preview_enable_oneshot(prev);
1568
1569 spin_lock_irqsave(&prev->params.lock, flags);
1570 preview_params_unlock(prev, update, false);
1571 spin_unlock_irqrestore(&prev->params.lock, flags);
1470} 1572}
1471 1573
1472/* ----------------------------------------------------------------------------- 1574/* -----------------------------------------------------------------------------
@@ -1552,7 +1654,6 @@ static int preview_set_stream(struct v4l2_subdev *sd, int enable)
1552 struct isp_video *video_out = &prev->video_out; 1654 struct isp_video *video_out = &prev->video_out;
1553 struct isp_device *isp = to_isp_device(prev); 1655 struct isp_device *isp = to_isp_device(prev);
1554 struct device *dev = to_device(prev); 1656 struct device *dev = to_device(prev);
1555 unsigned long flags;
1556 1657
1557 if (prev->state == ISP_PIPELINE_STREAM_STOPPED) { 1658 if (prev->state == ISP_PIPELINE_STREAM_STOPPED) {
1558 if (enable == ISP_PIPELINE_STREAM_STOPPED) 1659 if (enable == ISP_PIPELINE_STREAM_STOPPED)
@@ -1589,11 +1690,9 @@ static int preview_set_stream(struct v4l2_subdev *sd, int enable)
1589 if (omap3isp_module_sync_idle(&sd->entity, &prev->wait, 1690 if (omap3isp_module_sync_idle(&sd->entity, &prev->wait,
1590 &prev->stopping)) 1691 &prev->stopping))
1591 dev_dbg(dev, "%s: stop timeout.\n", sd->name); 1692 dev_dbg(dev, "%s: stop timeout.\n", sd->name);
1592 spin_lock_irqsave(&prev->lock, flags);
1593 omap3isp_sbl_disable(isp, OMAP3_ISP_SBL_PREVIEW_READ); 1693 omap3isp_sbl_disable(isp, OMAP3_ISP_SBL_PREVIEW_READ);
1594 omap3isp_sbl_disable(isp, OMAP3_ISP_SBL_PREVIEW_WRITE); 1694 omap3isp_sbl_disable(isp, OMAP3_ISP_SBL_PREVIEW_WRITE);
1595 omap3isp_subclk_disable(isp, OMAP3_ISP_SUBCLK_PREVIEW); 1695 omap3isp_subclk_disable(isp, OMAP3_ISP_SUBCLK_PREVIEW);
1596 spin_unlock_irqrestore(&prev->lock, flags);
1597 isp_video_dmaqueue_flags_clr(video_out); 1696 isp_video_dmaqueue_flags_clr(video_out);
1598 break; 1697 break;
1599 } 1698 }
@@ -2201,7 +2300,7 @@ error_video_in:
2201} 2300}
2202 2301
2203/* 2302/*
2204 * isp_preview_init - Previewer initialization. 2303 * omap3isp_preview_init - Previewer initialization.
2205 * @dev : Pointer to ISP device 2304 * @dev : Pointer to ISP device
2206 * return -ENOMEM or zero on success 2305 * return -ENOMEM or zero on success
2207 */ 2306 */
@@ -2209,8 +2308,8 @@ int omap3isp_preview_init(struct isp_device *isp)
2209{ 2308{
2210 struct isp_prev_device *prev = &isp->isp_prev; 2309 struct isp_prev_device *prev = &isp->isp_prev;
2211 2310
2212 spin_lock_init(&prev->lock);
2213 init_waitqueue_head(&prev->wait); 2311 init_waitqueue_head(&prev->wait);
2312
2214 preview_init_params(prev); 2313 preview_init_params(prev);
2215 2314
2216 return preview_init_entities(prev); 2315 return preview_init_entities(prev);