Merge "kernel: enable internaldb on perf build"
diff --git a/arch/arm/configs/msm8610-perf_defconfig b/arch/arm/configs/msm8610-perf_defconfig
index 462b5c3..bd135b3 100644
--- a/arch/arm/configs/msm8610-perf_defconfig
+++ b/arch/arm/configs/msm8610-perf_defconfig
@@ -78,7 +78,6 @@
 CONFIG_KSM=y
 CONFIG_CC_STACKPROTECTOR=y
 CONFIG_KSM=y
-CONFIG_ENABLE_VMALLOC_SAVING=y
 CONFIG_CP_ACCESS=y
 CONFIG_USE_OF=y
 CONFIG_CPU_FREQ_GOV_POWERSAVE=y
diff --git a/arch/arm/configs/msm8610_defconfig b/arch/arm/configs/msm8610_defconfig
index 899ed30..f6ef804 100644
--- a/arch/arm/configs/msm8610_defconfig
+++ b/arch/arm/configs/msm8610_defconfig
@@ -79,7 +79,6 @@
 CONFIG_KSM=y
 CONFIG_CC_STACKPROTECTOR=y
 CONFIG_KSM=y
-CONFIG_ENABLE_VMALLOC_SAVING=y
 CONFIG_CP_ACCESS=y
 CONFIG_USE_OF=y
 CONFIG_CPU_FREQ_GOV_POWERSAVE=y
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 4b8d443..f84ea26 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -475,7 +475,6 @@
 	select MSM_RPM_LOG
 	select MSM_IOMMU_SYNC
 	select MSM_RPM_STATS_LOG
-	select ENABLE_VMALLOC_SAVINGS
 
 config ARCH_MSM8226
 	bool "MSM8226"
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index a1a2e51..669b10e 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -1500,7 +1500,9 @@
 		vm->flags = VM_LOWMEM | VM_ARM_STATIC_MAPPING;
 		vm->flags |= VM_ARM_MTYPE(type);
 		vm->caller = map_lowmem;
-		vm_area_add_early(vm++);
+		vm_area_add_early(vm);
+		mark_vmalloc_reserved_area(vm->addr, vm->size);
+		vm++;
 	}
 }
 
diff --git a/drivers/gpu/msm/adreno_dispatch.c b/drivers/gpu/msm/adreno_dispatch.c
index 2da36b6..ec5e57c 100644
--- a/drivers/gpu/msm/adreno_dispatch.c
+++ b/drivers/gpu/msm/adreno_dispatch.c
@@ -1515,8 +1515,14 @@
  */
 void adreno_dispatcher_start(struct kgsl_device *device)
 {
+	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+
 	complete_all(&device->cmdbatch_gate);
 
+	/* a305c GPU is slower than a330 and needs a larger timer */
+	if (adreno_is_a305c(adreno_dev))
+		_fault_timer_interval = 200;
+
 	/* Schedule the work loop to get things going */
 	adreno_dispatcher_schedule(device);
 }
diff --git a/drivers/hwmon/epm_adc.c b/drivers/hwmon/epm_adc.c
index f7cf2df..2f5ed9d 100644
--- a/drivers/hwmon/epm_adc.c
+++ b/drivers/hwmon/epm_adc.c
@@ -888,6 +888,12 @@
 	init_resp->num_dev		= rx_buf[6];
 	init_resp->num_channel		= rx_buf[7];
 
+	pr_debug("EPM PSOC response for hello command: resp_cmd:0x%x\n",
+							rx_buf[0]);
+	pr_debug("EPM PSOC version:0x%x\n", rx_buf[1]);
+	pr_debug("EPM PSOC firmware version:0x%x\n",
+			rx_buf[6] | rx_buf[5] | rx_buf[4] | rx_buf[3]);
+
 	return rc;
 }
 
diff --git a/drivers/input/misc/bmp18x-core.c b/drivers/input/misc/bmp18x-core.c
index 001a804..3949f6e 100644
--- a/drivers/input/misc/bmp18x-core.c
+++ b/drivers/input/misc/bmp18x-core.c
@@ -88,6 +88,7 @@
 	struct	device *dev;
 	struct	mutex lock;
 	struct	bmp18x_calibration_data calibration;
+	struct  sensors_classdev cdev;
 	u8	oversampling_setting;
 	u8	sw_oversampling_setting;
 	u32	raw_temperature;
@@ -113,9 +114,13 @@
 	.max_range = "1100.0",
 	.resolution = "0.01",
 	.sensor_power = "0.67",
-	.min_delay = 20000,
+	.min_delay = 20000,	/* microsecond */
 	.fifo_reserved_event_count = 0,
 	.fifo_max_event_count = 0,
+	.enabled = 0,
+	.delay_msec = 200,	/* millisecond */
+	.sensors_enable = NULL,
+	.sensors_poll_delay = NULL,
 };
 
 #ifdef CONFIG_HAS_EARLYSUSPEND
@@ -403,6 +408,19 @@
 static DEVICE_ATTR(sw_oversampling, S_IWUSR | S_IRUGO,
 				show_sw_oversampling, set_sw_oversampling);
 
+static ssize_t bmp18x_poll_delay_set(struct sensors_classdev *sensors_cdev,
+						unsigned int delay_msec)
+{
+	struct bmp18x_data *data = container_of(sensors_cdev,
+					struct bmp18x_data, cdev);
+	mutex_lock(&data->lock);
+	data->delay = delay_msec;
+	mutex_unlock(&data->lock);
+
+	return 0;
+}
+
+
 static ssize_t show_delay(struct device *dev,
 				 struct device_attribute *attr, char *buf)
 {
@@ -416,17 +434,43 @@
 {
 	struct bmp18x_data *data = dev_get_drvdata(dev);
 	unsigned long delay;
-	int success = kstrtoul(buf, 10, &delay);
-	if (success == 0) {
-		mutex_lock(&data->lock);
-		data->delay = delay;
-		mutex_unlock(&data->lock);
-	}
-	return success;
+	int err = kstrtoul(buf, 10, &delay);
+	if (err < 0)
+		return err;
+
+	err = bmp18x_poll_delay_set(&data->cdev, delay);
+	if (err < 0)
+		return err;
+
+	return count;
 }
+
 static DEVICE_ATTR(delay, S_IWUSR | S_IRUGO,
 				show_delay, set_delay);
 
+static ssize_t bmp18x_enable_set(struct sensors_classdev *sensors_cdev,
+						unsigned int enabled)
+{
+	struct bmp18x_data *data = container_of(sensors_cdev,
+					struct bmp18x_data, cdev);
+	struct device *dev = data->dev;
+
+	mutex_lock(&data->lock);
+	data->enable = enabled ? 1 : 0;
+
+	if (data->enable) {
+		bmp18x_enable(dev);
+		schedule_delayed_work(&data->work,
+					msecs_to_jiffies(data->delay));
+	} else {
+		cancel_delayed_work_sync(&data->work);
+		bmp18x_disable(dev);
+	}
+	mutex_unlock(&data->lock);
+
+	return 0;
+}
+
 static ssize_t show_enable(struct device *dev,
 				 struct device_attribute *attr, char *buf)
 {
@@ -440,24 +484,17 @@
 {
 	struct bmp18x_data *data = dev_get_drvdata(dev);
 	unsigned long enable;
-	int success = kstrtoul(buf, 10, &enable);
-	if (success == 0) {
-		mutex_lock(&data->lock);
-		data->enable = enable ? 1 : 0;
+	int err = kstrtoul(buf, 10, &enable);
+	if (err < 0)
+		return err;
 
-		if (data->enable) {
-			bmp18x_enable(dev);
-			schedule_delayed_work(&data->work,
-						msecs_to_jiffies(data->delay));
-		} else {
-			cancel_delayed_work_sync(&data->work);
-			bmp18x_disable(dev);
-		}
-		mutex_unlock(&data->lock);
+	err = bmp18x_enable_set(&data->cdev, enable);
+	if (err < 0)
+		return err;
 
-	}
 	return count;
 }
+
 static DEVICE_ATTR(enable, S_IWUSR | S_IRUGO,
 				show_enable, set_enable);
 
@@ -628,7 +665,10 @@
 	if (err)
 		goto error_sysfs;
 
-	err = sensors_classdev_register(&data->input->dev, &sensors_cdev);
+	data->cdev = sensors_cdev;
+	data->cdev.sensors_enable = bmp18x_enable_set;
+	data->cdev.sensors_poll_delay = bmp18x_poll_delay_set;
+	err = sensors_classdev_register(&data->input->dev, &data->cdev);
 	if (err) {
 		pr_err("class device create failed: %d\n", err);
 		goto error_class_sysfs;
diff --git a/drivers/input/misc/cm36283.c b/drivers/input/misc/cm36283.c
index 5c89c0c..5f08da4 100644
--- a/drivers/input/misc/cm36283.c
+++ b/drivers/input/misc/cm36283.c
@@ -640,12 +640,6 @@
 	.unlocked_ioctl = psensor_ioctl
 };
 
-struct miscdevice psensor_misc = {
-	.minor = MISC_DYNAMIC_MINOR,
-	.name = "proximity",
-	.fops = &psensor_fops
-};
-
 void lightsensor_set_kvalue(struct cm36283_info *lpi)
 {
 	if (!lpi) {
@@ -793,13 +787,6 @@
 	.unlocked_ioctl = lightsensor_ioctl
 };
 
-static struct miscdevice lightsensor_misc = {
-	.minor = MISC_DYNAMIC_MINOR,
-	.name = "lightsensor",
-	.fops = &lightsensor_fops
-};
-
-
 static ssize_t ps_adc_show(struct device *dev,
 			struct device_attribute *attr, char *buf)
 {
@@ -844,7 +831,6 @@
 	return count;
 }
 
-static DEVICE_ATTR(ps_adc, 0664, ps_adc_show, ps_enable_store);
 
 static ssize_t ps_parameters_show(struct device *dev,
 			struct device_attribute *attr, char *buf)
@@ -888,10 +874,6 @@
 	return count;
 }
 
-static DEVICE_ATTR(ps_parameters, 0664,
-	ps_parameters_show, ps_parameters_store);
-
-
 static ssize_t ps_conf_show(struct device *dev,
 			struct device_attribute *attr, char *buf)
 {
@@ -917,7 +899,6 @@
 
 	return count;
 }
-static DEVICE_ATTR(ps_conf, 0664, ps_conf_show, ps_conf_store);
 
 static ssize_t ps_thd_show(struct device *dev,
 			struct device_attribute *attr, char *buf)
@@ -946,7 +927,6 @@
 
 	return count;
 }
-static DEVICE_ATTR(ps_thd, 0664, ps_thd_show, ps_thd_store);
 
 static ssize_t ps_hw_show(struct device *dev,
 			struct device_attribute *attr, char *buf)
@@ -969,7 +949,6 @@
 
 	return count;
 }
-static DEVICE_ATTR(ps_hw, 0664, ps_hw_show, ps_hw_store);
 
 static ssize_t ls_adc_show(struct device *dev,
 				  struct device_attribute *attr, char *buf)
@@ -983,8 +962,6 @@
 	return ret;
 }
 
-static DEVICE_ATTR(ls_adc, 0664, ls_adc_show, NULL);
-
 static ssize_t ls_enable_show(struct device *dev,
 				  struct device_attribute *attr, char *buf)
 {
@@ -1033,8 +1010,6 @@
 	return count;
 }
 
-static DEVICE_ATTR(ls_auto, 0664,
-	ls_enable_show, ls_enable_store);
 
 static ssize_t ls_kadc_show(struct device *dev,
 				  struct device_attribute *attr, char *buf)
@@ -1077,7 +1052,6 @@
 	return count;
 }
 
-static DEVICE_ATTR(ls_kadc, 0664, ls_kadc_show, ls_kadc_store);
 
 static ssize_t ls_gadc_show(struct device *dev,
 				  struct device_attribute *attr, char *buf)
@@ -1117,7 +1091,6 @@
 	return count;
 }
 
-static DEVICE_ATTR(ls_gadc, 0664, ls_gadc_show, ls_gadc_store);
 
 static ssize_t ls_adc_table_show(struct device *dev,
 			struct device_attribute *attr, char *buf)
@@ -1168,9 +1141,6 @@
 	return count;
 }
 
-static DEVICE_ATTR(ls_adc_table, 0664,
-	ls_adc_table_show, ls_adc_table_store);
-
 static ssize_t ls_conf_show(struct device *dev,
 				  struct device_attribute *attr, char *buf)
 {
@@ -1192,7 +1162,6 @@
 	_cm36283_I2C_Write_Word(lpi->slave_addr, ALS_CONF, lpi->ls_cmd);
 	return count;
 }
-static DEVICE_ATTR(ls_conf, 0664, ls_conf_show, ls_conf_store);
 
 static ssize_t ls_poll_delay_show(struct device *dev,
 		struct device_attribute *attr, char *buf)
@@ -1219,9 +1188,6 @@
 	return count;
 }
 
-static DEVICE_ATTR(ls_poll_delay, 0664, ls_poll_delay_show,
-		ls_poll_delay_store);
-
 static ssize_t ps_poll_delay_show(struct device *dev,
 		struct device_attribute *attr, char *buf)
 {
@@ -1247,9 +1213,6 @@
 	return count;
 }
 
-static DEVICE_ATTR(ps_poll_delay, 0664, ps_poll_delay_show,
-		ps_poll_delay_store);
-
 static ssize_t ls_fLevel_show(struct device *dev,
 				  struct device_attribute *attr, char *buf)
 {
@@ -1271,7 +1234,6 @@
 	fLevel=-1;
 	return count;
 }
-static DEVICE_ATTR(ls_flevel, 0664, ls_fLevel_show, ls_fLevel_store);
 
 static int lightsensor_setup(struct cm36283_info *lpi)
 {
@@ -1286,6 +1248,7 @@
 		return -ENOMEM;
 	}
 	lpi->ls_input_dev->name = "cm36283-ls";
+	lpi->ls_input_dev->id.bustype = BUS_I2C;
 	set_bit(EV_ABS, lpi->ls_input_dev->evbit);
 
 	range = get_als_range();
@@ -1298,17 +1261,8 @@
 		goto err_free_ls_input_device;
 	}
 
-	ret = misc_register(&lightsensor_misc);
-	if (ret < 0) {
-		pr_err("[LS][CM36283 error]%s: can not register ls misc device\n",
-				__func__);
-		goto err_unregister_ls_input_device;
-	}
-
 	return ret;
 
-err_unregister_ls_input_device:
-	input_unregister_device(lpi->ls_input_dev);
 err_free_ls_input_device:
 	input_free_device(lpi->ls_input_dev);
 	return ret;
@@ -1326,6 +1280,7 @@
 		return -ENOMEM;
 	}
 	lpi->ps_input_dev->name = "cm36283-ps";
+	lpi->ps_input_dev->id.bustype = BUS_I2C;
 	set_bit(EV_ABS, lpi->ps_input_dev->evbit);
 	input_set_abs_params(lpi->ps_input_dev, ABS_DISTANCE, 0, 1, 0, 0);
 
@@ -1337,18 +1292,8 @@
 		goto err_free_ps_input_device;
 	}
 
-	ret = misc_register(&psensor_misc);
-	if (ret < 0) {
-		pr_err(
-			"[PS][CM36283 error]%s: could not register ps misc device\n",
-			__func__);
-		goto err_unregister_ps_input_device;
-	}
-
 	return ret;
 
-err_unregister_ps_input_device:
-	input_unregister_device(lpi->ps_input_dev);
 err_free_ps_input_device:
 	input_free_device(lpi->ps_input_dev);
 	return ret;
@@ -1496,6 +1441,59 @@
 	return 0;
 }
 
+static int create_sysfs_interfaces(struct device *dev,
+		struct device_attribute *attributes, int len)
+{
+	int i;
+	int err;
+	for (i = 0; i < len; i++) {
+		err = device_create_file(dev, attributes + i);
+		if (err)
+			goto error;
+	}
+	return 0;
+
+error:
+	for (; i >= 0; i--)
+		device_remove_file(dev, attributes + i);
+	dev_err(dev, "%s:Unable to create interface\n", __func__);
+	return err;
+}
+
+static int remove_sysfs_interfaces(struct device *dev,
+		struct device_attribute *attributes, int len)
+{
+	int i;
+	for (i = 0; i < len; i++)
+		device_remove_file(dev, attributes + i);
+	return 0;
+}
+
+static struct device_attribute light_attr[] = {
+	__ATTR(ls_adc, 0664, ls_adc_show, NULL),
+	__ATTR(ls_kadc, 0664, ls_kadc_show, ls_kadc_store),
+	__ATTR(ls_gadc, 0664, ls_gadc_show, ls_gadc_store),
+	__ATTR(ls_conf, 0664, ls_conf_show, ls_conf_store),
+	__ATTR(ls_adc_table, 0664,
+			ls_adc_table_show, ls_adc_table_store),
+	__ATTR(poll_delay, 0664, ls_poll_delay_show,
+			ls_poll_delay_store),
+	__ATTR(enable, 0664,
+			ls_enable_show, ls_enable_store),
+};
+
+static struct device_attribute proximity_attr[] = {
+	__ATTR(enable, 0664, ps_adc_show, ps_enable_store),
+	__ATTR(ps_parameters, 0664,
+			ps_parameters_show, ps_parameters_store),
+	__ATTR(ps_conf, 0664, ps_conf_show, ps_conf_store),
+	__ATTR(ps_hw, 0664, ps_hw_show, ps_hw_store),
+	__ATTR(ps_thd, 0664, ps_thd_show, ps_thd_store),
+	__ATTR(poll_delay, 0664, ps_poll_delay_show,
+			ps_poll_delay_store),
+	__ATTR(ls_flevel, 0664, ls_fLevel_show, ls_fLevel_store),
+};
+
 static int cm36283_probe(struct i2c_client *client,
 	const struct i2c_device_id *id)
 {
@@ -1633,95 +1631,24 @@
 		goto err_psensor_setup;
 	}
 
-	lpi->cm36283_class = class_create(THIS_MODULE, "optical_sensors");
-	if (IS_ERR(lpi->cm36283_class)) {
-		ret = PTR_ERR(lpi->cm36283_class);
-		lpi->cm36283_class = NULL;
-		goto err_create_class;
+	ret = create_sysfs_interfaces(&lpi->ls_input_dev->dev, light_attr,
+			ARRAY_SIZE(light_attr));
+	if (ret < 0) {
+		dev_err(&client->dev, "failed to create sysfs\n");
+		goto err_input_cleanup;
 	}
 
-	lpi->ls_dev = device_create(lpi->cm36283_class,
-				NULL, 0, "%s", "lightsensor");
-	if (unlikely(IS_ERR(lpi->ls_dev))) {
-		ret = PTR_ERR(lpi->ls_dev);
-		lpi->ls_dev = NULL;
-		goto err_create_ls_device;
+	ret = create_sysfs_interfaces(&lpi->ps_input_dev->dev, proximity_attr,
+			ARRAY_SIZE(proximity_attr));
+	if (ret < 0) {
+		dev_err(&client->dev, "failed to create sysfs\n");
+		goto err_light_sysfs_cleanup;
 	}
 
-	/* register the attributes */
-	ret = device_create_file(lpi->ls_dev, &dev_attr_ls_adc);
-	if (ret)
-		goto err_create_ls_device_file;
-
-	/* register the attributes */
-	ret = device_create_file(lpi->ls_dev, &dev_attr_ls_auto);
-	if (ret)
-		goto err_create_ls_device_file;
-
-	/* register the attributes */
-	ret = device_create_file(lpi->ls_dev, &dev_attr_ls_kadc);
-	if (ret)
-		goto err_create_ls_device_file;
-
-	ret = device_create_file(lpi->ls_dev, &dev_attr_ls_gadc);
-	if (ret)
-		goto err_create_ls_device_file;
-
-	ret = device_create_file(lpi->ls_dev, &dev_attr_ls_adc_table);
-	if (ret)
-		goto err_create_ls_device_file;
-
-	ret = device_create_file(lpi->ls_dev, &dev_attr_ls_conf);
-	if (ret)
-		goto err_create_ls_device_file;
-
-	ret = device_create_file(lpi->ls_dev, &dev_attr_ls_flevel);
-	if (ret)
-		goto err_create_ls_device_file;
-
-	ret = device_create_file(lpi->ls_dev, &dev_attr_ls_poll_delay);
-	if (ret)
-		goto err_create_ls_device_file;
-
-	lpi->ps_dev = device_create(lpi->cm36283_class,
-				NULL, 0, "%s", "proximity");
-	if (unlikely(IS_ERR(lpi->ps_dev))) {
-		ret = PTR_ERR(lpi->ps_dev);
-		lpi->ps_dev = NULL;
-		goto err_create_ps_device;
-	}
-
-	/* register the attributes */
-	ret = device_create_file(lpi->ps_dev, &dev_attr_ps_adc);
-	if (ret)
-		goto err_create_ps_device_file;
-
-	ret = device_create_file(lpi->ps_dev,
-		&dev_attr_ps_parameters);
-	if (ret)
-		goto err_create_ps_device_file;
-
-	/* register the attributes */
-	ret = device_create_file(lpi->ps_dev, &dev_attr_ps_conf);
-	if (ret)
-		goto err_create_ps_device_file;
-
-	/* register the attributes */
-	ret = device_create_file(lpi->ps_dev, &dev_attr_ps_thd);
-	if (ret)
-		goto err_create_ps_device_file;
-
-	ret = device_create_file(lpi->ps_dev, &dev_attr_ps_hw);
-	if (ret)
-		goto err_create_ps_device_file;
-
-	ret = device_create_file(lpi->ps_dev, &dev_attr_ps_poll_delay);
-	if (ret)
-		goto err_create_ps_device_file;
 
 	ret = sensors_classdev_register(&client->dev, &sensors_light_cdev);
 	if (ret)
-		goto err_create_ps_device_file;
+		goto err_proximity_sysfs_cleanup;
 
 	ret = sensors_classdev_register(&client->dev, &sensors_proximity_cdev);
 	if (ret)
@@ -1735,19 +1662,16 @@
 	return ret;
 err_create_class_sysfs:
 	sensors_classdev_unregister(&sensors_light_cdev);
-err_create_ps_device_file:
-	device_unregister(lpi->ps_dev);
-err_create_ps_device:
-err_create_ls_device_file:
-	device_unregister(lpi->ls_dev);
-err_create_ls_device:
-	class_destroy(lpi->cm36283_class);
-err_create_class:
-	misc_deregister(&psensor_misc);
+err_proximity_sysfs_cleanup:
+	remove_sysfs_interfaces(&lpi->ps_input_dev->dev, proximity_attr,
+			ARRAY_SIZE(proximity_attr));
+err_light_sysfs_cleanup:
+	remove_sysfs_interfaces(&lpi->ls_input_dev->dev, light_attr,
+			ARRAY_SIZE(light_attr));
+err_input_cleanup:
 	input_unregister_device(lpi->ps_input_dev);
 	input_free_device(lpi->ps_input_dev);
 err_psensor_setup:
-	misc_deregister(&lightsensor_misc);
 	input_unregister_device(lpi->ls_input_dev);
 	input_free_device(lpi->ls_input_dev);
 err_lightsensor_setup:
diff --git a/drivers/input/touchscreen/gt9xx/gt9xx.c b/drivers/input/touchscreen/gt9xx/gt9xx.c
index b39cb0d..7fa6c39 100644
--- a/drivers/input/touchscreen/gt9xx/gt9xx.c
+++ b/drivers/input/touchscreen/gt9xx/gt9xx.c
@@ -753,16 +753,13 @@
 	return ret;
 }
 #else
-/*******************************************************
-Function:
-	Enter sleep mode.
-Input:
-	ts: private data.
-Output:
-	Executive outcomes.
-	>0: succeed, otherwise failed.
-*******************************************************/
-static s8 gtp_enter_sleep(struct goodix_ts_data  *ts)
+/**
+ * gtp_enter_sleep - Enter sleep mode
+ * @ts: driver private data
+ *
+ * Returns zero on success, else an error.
+ */
+static u8 gtp_enter_sleep(struct goodix_ts_data *ts)
 {
 	int ret = -1;
 	s8 retry = 0;
@@ -784,16 +781,16 @@
 		ret = goodix_power_off(ts);
 		if (ret) {
 			dev_err(&ts->client->dev, "GTP power off failed.\n");
-			return 0;
+			return ret;
 		}
-		return 1;
+		return 0;
 	} else {
 		usleep(5000);
 		while (retry++ < 5) {
 			ret = gtp_i2c_write(ts->client, i2c_control_buf, 3);
 			if (ret == 1) {
 				dev_dbg(&ts->client->dev, "GTP enter sleep!");
-				return ret;
+				return 0;
 			}
 			msleep(20);
 		}
@@ -2031,7 +2028,7 @@
 
 	ret = gtp_enter_sleep(ts);
 #endif
-	if (ret <= 0)
+	if (ret < 0)
 		dev_err(&ts->client->dev, "GTP early suspend failed.\n");
 	/* to avoid waking up while not sleeping,
 	 * delay 48 + 10ms to ensure reliability
@@ -2268,8 +2265,15 @@
 }
 #endif
 
-static SIMPLE_DEV_PM_OPS(goodix_ts_dev_pm_ops, goodix_ts_suspend,
-					goodix_ts_resume);
+#if (!defined(CONFIG_FB) && !defined(CONFIG_HAS_EARLYSUSPEND))
+static const struct dev_pm_ops goodix_ts_dev_pm_ops = {
+	.suspend = goodix_ts_suspend,
+	.resume = goodix_ts_resume,
+};
+#else
+static const struct dev_pm_ops goodix_ts_dev_pm_ops = {
+};
+#endif
 
 static const struct i2c_device_id goodix_ts_id[] = {
 	{ GTP_I2C_NAME, 0 },
diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
index de098c9..c4a23ca 100755
--- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
+++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
@@ -200,7 +200,7 @@
 			ispif->base + ISPIF_VFE_m_INTF_CMD_0(i));
 		msm_camera_io_w(ISPIF_STOP_INTF_IMMEDIATELY,
 			ispif->base + ISPIF_VFE_m_INTF_CMD_1(i));
-		pr_debug("%s: base %x", __func__, (unsigned int)ispif->base);
+		pr_debug("%s: base %lx", __func__, (unsigned long)ispif->base);
 		msm_camera_io_w(0, ispif->base +
 			ISPIF_VFE_m_PIX_INTF_n_CID_MASK(i, 0));
 		msm_camera_io_w(0, ispif->base +
diff --git a/drivers/media/platform/msm/vidc/hfi_response_handler.c b/drivers/media/platform/msm/vidc/hfi_response_handler.c
index 3fd5d3a..189fca0 100644
--- a/drivers/media/platform/msm/vidc/hfi_response_handler.c
+++ b/drivers/media/platform/msm/vidc/hfi_response_handler.c
@@ -263,7 +263,9 @@
 		break;
 	case HFI_EVENT_RELEASE_BUFFER_REFERENCE:
 		dprintk(VIDC_INFO, "HFI_EVENT_RELEASE_BUFFER_REFERENCE\n");
-		hfi_process_evt_release_buffer_ref(callback, device_id, pkt);
+		if (!validate_session_pkt(sessions, sess, session_lock))
+			hfi_process_evt_release_buffer_ref(callback,
+				device_id, pkt);
 		break;
 	default:
 		dprintk(VIDC_WARN, "hal_process_event_notify:unkown_event_id");
diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c
index 9da1220..42ef64c 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc.c
@@ -717,6 +717,8 @@
 		return -EINVAL;
 
 	list_for_each_safe(ptr, next, &inst->registered_bufs) {
+		bool release_buf = false;
+		mutex_lock(&inst->lock);
 		bi = list_entry(ptr, struct buffer_info, list);
 		if (bi->type == buffer_type) {
 			buffer_info.type = bi->type;
@@ -734,19 +736,28 @@
 					buffer_info.m.planes[i].length);
 			}
 			buffer_info.length = bi->num_planes;
-			if (inst->session_type == MSM_VIDC_DECODER)
-				rc = msm_vdec_release_buf(instance,
-					&buffer_info);
-			if (inst->session_type == MSM_VIDC_ENCODER)
-				rc = msm_venc_release_buf(instance,
-					&buffer_info);
-			if (rc)
-				dprintk(VIDC_ERR,
-					"Failed Release buffer: %d, %d, %d\n",
-					buffer_info.m.planes[0].reserved[0],
-					buffer_info.m.planes[0].reserved[1],
-					buffer_info.m.planes[0].length);
-
+			release_buf = true;
+		}
+		mutex_unlock(&inst->lock);
+		if (!release_buf)
+			continue;
+		if (inst->session_type == MSM_VIDC_DECODER)
+			rc = msm_vdec_release_buf(instance,
+				&buffer_info);
+		if (inst->session_type == MSM_VIDC_ENCODER)
+			rc = msm_venc_release_buf(instance,
+				&buffer_info);
+		if (rc)
+			dprintk(VIDC_ERR,
+				"Failed Release buffer: %d, %d, %d\n",
+				buffer_info.m.planes[0].reserved[0],
+				buffer_info.m.planes[0].reserved[1],
+				buffer_info.m.planes[0].length);
+	}
+	mutex_lock(&inst->lock);
+	list_for_each_safe(ptr, next, &inst->registered_bufs) {
+		bi = list_entry(ptr, struct buffer_info, list);
+		if (bi->type == buffer_type) {
 			list_del(&bi->list);
 			for (i = 0; i < bi->num_planes; i++) {
 				if (bi->handle[i] && bi->mapped[i]) {
@@ -762,6 +773,7 @@
 			kfree(bi);
 		}
 	}
+	mutex_unlock(&inst->lock);
 	return rc;
 }
 
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index 7588994..8921b13 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -519,6 +519,14 @@
 					event_notify->packet_buffer,
 					event_notify->exra_data_buffer);
 
+				if (inst->state == MSM_VIDC_CORE_INVALID ||
+					inst->core->state ==
+						VIDC_CORE_INVALID) {
+					dprintk(VIDC_DBG,
+						"Event release buf ref received in invalid state - discard\n");
+					return;
+				}
+
 				/*
 				* Get the buffer_info entry for the
 				* device address.
@@ -2999,6 +3007,9 @@
 		dprintk(VIDC_INFO, "Input only flush not supported\n");
 		return 0;
 	}
+	mutex_lock(&inst->sync_lock);
+	msm_comm_flush_dynamic_buffers(inst);
+	mutex_unlock(&inst->sync_lock);
 	if (inst->state == MSM_VIDC_CORE_INVALID ||
 			core->state == VIDC_CORE_INVALID) {
 		dprintk(VIDC_ERR,
@@ -3009,7 +3020,6 @@
 	}
 
 	mutex_lock(&inst->sync_lock);
-	msm_comm_flush_dynamic_buffers(inst);
 	if (inst->in_reconfig && !ip_flush && op_flush) {
 		if (!list_empty(&inst->pendingq)) {
 			/*Execution can never reach here since port reconfig
diff --git a/drivers/media/radio/radio-iris.c b/drivers/media/radio/radio-iris.c
index 5dde469..d4ce343 100644
--- a/drivers/media/radio/radio-iris.c
+++ b/drivers/media/radio/radio-iris.c
@@ -3625,13 +3625,21 @@
 		break;
 	case V4L2_CID_PRIVATE_IRIS_RIVA_POKE:
 		if (radio->riva_data_req.cmd_params.length <= MAX_RIVA_PEEK_RSP_SIZE) {
-			memcpy(radio->riva_data_req.data, (void *)ctrl->value,
+			retval = copy_from_user(radio->riva_data_req.data,
+						(void *)ctrl->value,
 						radio->riva_data_req.cmd_params.length);
-			radio->riva_data_req.cmd_params.subopcode = RIVA_POKE_OPCODE;
-			retval = hci_poke_data(&radio->riva_data_req , radio->fm_hdev);
+			if (retval == 0) {
+				radio->riva_data_req.cmd_params.subopcode =
+									RIVA_POKE_OPCODE;
+				retval = hci_poke_data(&radio->riva_data_req,
+							radio->fm_hdev);
+			} else {
+				retval = -EINVAL;
+			}
 		} else {
 			FMDERR("Can not copy into driver's buffer. Length %d is more than"
-			 "the buffer size %d\n", ctrl->value, MAX_RIVA_PEEK_RSP_SIZE);
+			 "the buffer size %d\n", radio->riva_data_req.cmd_params.length,
+				MAX_RIVA_PEEK_RSP_SIZE);
 			retval = -EINVAL;
 		}
 		break;
diff --git a/drivers/net/wireless/wcnss/wcnss_wlan.c b/drivers/net/wireless/wcnss/wcnss_wlan.c
index 12c5704..8e695c3 100644
--- a/drivers/net/wireless/wcnss/wcnss_wlan.c
+++ b/drivers/net/wireless/wcnss/wcnss_wlan.c
@@ -45,6 +45,7 @@
 #endif
 
 #define DEVICE "wcnss_wlan"
+#define CTRL_DEVICE "wcnss_ctrl"
 #define VERSION "1.01"
 #define WCNSS_PIL_DEVICE "wcnss"
 
@@ -157,6 +158,14 @@
 #define WCNSS_MAX_FRAME_SIZE		(4*1024)
 #define WCNSS_VERSION_LEN			30
 #define WCNSS_MAX_BUILD_VER_LEN		256
+#define WCNSS_MAX_CMD_LEN		(128)
+#define WCNSS_MIN_CMD_LEN		(3)
+#define WCNSS_MIN_SERIAL_LEN		(6)
+
+/* control messages from userspace */
+#define WCNSS_USR_CTRL_MSG_START  0x00000000
+#define WCNSS_USR_SERIAL_NUM      (WCNSS_USR_CTRL_MSG_START + 1)
+#define WCNSS_USR_HAS_CAL_DATA    (WCNSS_USR_CTRL_MSG_START + 2)
 
 /* message types */
 #define WCNSS_CTRL_MSG_START	0x01000000
@@ -361,7 +370,9 @@
 	int	device_opened;
 	int	iris_xo_mode_set;
 	int	fw_vbatt_state;
+	int	ctrl_device_opened;
 	struct mutex dev_lock;
+	struct mutex ctrl_lock;
 	wait_queue_head_t read_wait;
 	struct qpnp_adc_tm_btm_param vbat_monitor_params;
 	struct qpnp_adc_tm_chip *adc_tm_dev;
@@ -1823,6 +1834,80 @@
 	.notifier_call = wcnss_pm_notify,
 };
 
+static int wcnss_ctrl_open(struct inode *inode, struct file *file)
+{
+	int rc = 0;
+
+	if (!penv || penv->ctrl_device_opened)
+		return -EFAULT;
+
+	penv->ctrl_device_opened = 1;
+
+	return rc;
+}
+
+
+void process_usr_ctrl_cmd(u8 *buf, size_t len)
+{
+	u16 cmd = buf[0] << 8 | buf[1];
+
+	switch (cmd) {
+
+	case WCNSS_USR_SERIAL_NUM:
+		if (WCNSS_MIN_SERIAL_LEN > len) {
+			pr_err("%s: Invalid serial number\n", __func__);
+			return;
+		}
+		penv->serial_number = buf[2] << 24 | buf[3] << 16
+			| buf[4] << 8 | buf[5];
+		break;
+
+	case WCNSS_USR_HAS_CAL_DATA:
+		if (1 < buf[2])
+			pr_err("%s: Invalid data for cal %d\n", __func__,
+				buf[2]);
+		has_calibrated_data = buf[2];
+		break;
+
+	default:
+		pr_err("%s: Invalid command %d\n", __func__, cmd);
+		break;
+	}
+}
+
+static ssize_t wcnss_ctrl_write(struct file *fp, const char __user
+			*user_buffer, size_t count, loff_t *position)
+{
+	int rc = 0;
+	u8 buf[WCNSS_MAX_CMD_LEN];
+
+	if (!penv || !penv->ctrl_device_opened || WCNSS_MAX_CMD_LEN < count
+			|| WCNSS_MIN_CMD_LEN > count)
+		return -EFAULT;
+
+	mutex_lock(&penv->ctrl_lock);
+	rc = copy_from_user(buf, user_buffer, count);
+	if (0 == rc)
+		process_usr_ctrl_cmd(buf, count);
+
+	mutex_unlock(&penv->ctrl_lock);
+
+	return rc;
+}
+
+
+static const struct file_operations wcnss_ctrl_fops = {
+	.owner = THIS_MODULE,
+	.open = wcnss_ctrl_open,
+	.write = wcnss_ctrl_write,
+};
+
+static struct miscdevice wcnss_usr_ctrl = {
+	.minor = MISC_DYNAMIC_MINOR,
+	.name = CTRL_DEVICE,
+	.fops = &wcnss_ctrl_fops,
+};
+
 static int
 wcnss_trigger_config(struct platform_device *pdev)
 {
@@ -2225,6 +2310,7 @@
 	}
 
 	mutex_init(&penv->dev_lock);
+	mutex_init(&penv->ctrl_lock);
 	mutex_init(&penv->vbat_monitor_mutex);
 	init_waitqueue_head(&penv->read_wait);
 
@@ -2237,6 +2323,9 @@
 	 * place
 	 */
 	pr_info(DEVICE " probed in built-in mode\n");
+
+	misc_register(&wcnss_usr_ctrl);
+
 	return misc_register(&wcnss_misc);
 
 }
diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c
index 3269eec..91c8798 100644
--- a/drivers/video/msm/mdss/mdss_mdp.c
+++ b/drivers/video/msm/mdss/mdss_mdp.c
@@ -546,6 +546,8 @@
 	if (clk) {
 		pr_debug("clk=%d en=%d\n", clk_idx, enable);
 		if (enable) {
+			if (clk_idx == MDSS_CLK_MDP_VSYNC)
+				clk_set_rate(clk, 19200000);
 			ret = clk_prepare_enable(clk);
 		} else {
 			clk_disable_unprepare(clk);
diff --git a/drivers/video/msm/mdss/mdss_mdp.h b/drivers/video/msm/mdss/mdss_mdp.h
index fad6b0c..8918df8 100644
--- a/drivers/video/msm/mdss/mdss_mdp.h
+++ b/drivers/video/msm/mdss/mdss_mdp.h
@@ -274,7 +274,6 @@
 	u32 hist_cnt_sent;
 	u32 hist_cnt_time;
 	u32 frame_cnt;
-	u32 is_kick_ready;
 	struct completion comp;
 	u32 data[HIST_V_SIZE];
 	struct mutex hist_mutex;
diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c
index 28d1b82..88af216 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pp.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pp.c
@@ -1307,10 +1307,7 @@
 		mutex_lock(&hist_info->hist_mutex);
 		spin_lock_irqsave(&hist_info->hist_lock, flag);
 		col_state = hist_info->col_state;
-		if (hist_info->is_kick_ready &&
-			((col_state == HIST_IDLE) ||
-			((false == hist_info->read_request) &&
-				col_state == HIST_READY))) {
+		if (col_state == HIST_IDLE) {
 			/* Kick off collection */
 			writel_relaxed(1, base + kick_base);
 			hist_info->col_state = HIST_START;
@@ -2893,11 +2890,10 @@
 	hist_info->hist_cnt_sent = 0;
 	hist_info->hist_cnt_time = 0;
 	spin_lock_irqsave(&hist_info->hist_lock, flag);
-	hist_info->read_request = false;
+	hist_info->read_request = 0;
 	hist_info->col_state = HIST_RESET;
 	hist_info->col_en = true;
 	spin_unlock_irqrestore(&hist_info->hist_lock, flag);
-	hist_info->is_kick_ready = true;
 	mdss_mdp_hist_intr_req(&mdata->hist_intr, 3 << shift_bit, true);
 	writel_relaxed(req->frame_cnt, ctl_base + 8);
 	/* Kick out reset start */
@@ -3018,7 +3014,6 @@
 	hist_info->col_en = false;
 	hist_info->col_state = HIST_UNKNOWN;
 	spin_unlock_irqrestore(&hist_info->hist_lock, flag);
-	hist_info->is_kick_ready = false;
 	mdss_mdp_hist_intr_req(&mdata->hist_intr, done_bit, false);
 	writel_relaxed(BIT(1), ctl_base);/* cancel */
 	ret = 0;
@@ -3268,7 +3263,6 @@
 	spin_lock_irqsave(&hist_info->hist_lock, flag);
 	/* wait for hist done if cache has no data */
 	if (hist_info->col_state != HIST_READY) {
-		hist_info->read_request = true;
 		spin_unlock_irqrestore(&hist_info->hist_lock, flag);
 		timeout = HIST_WAIT_TIMEOUT(hist_info->frame_cnt);
 		mutex_unlock(&hist_info->hist_mutex);
@@ -3308,9 +3302,11 @@
 		}
 		if (hist_info->col_state != HIST_READY) {
 			ret = -ENODATA;
+			spin_lock_irqsave(&hist_info->hist_lock, flag);
+			hist_info->col_state = HIST_READY;
+			spin_unlock_irqrestore(&hist_info->hist_lock, flag);
 			pr_debug("%s: state is not ready: %d",
 					__func__, hist_info->col_state);
-			goto hist_collect_exit;
 		}
 	} else {
 		spin_unlock_irqrestore(&hist_info->hist_lock, flag);
@@ -3323,9 +3319,7 @@
 		sum = pp_hist_read(v_base, hist_info);
 		mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
 		spin_lock_irqsave(&hist_info->hist_lock, flag);
-		if (!expect_sum || sum == expect_sum)
-			hist_info->read_request = false;
-		else
+		if (expect_sum && sum != expect_sum)
 			ret = -ENODATA;
 		hist_info->col_state = HIST_IDLE;
 	}
@@ -3337,8 +3331,9 @@
 
 int mdss_mdp_hist_collect(struct mdp_histogram_data *hist)
 {
-	int i, j, off, ret = 0;
+	int i, j, off, ret = 0, temp_ret = 0;
 	struct pp_hist_col_info *hist_info;
+	struct pp_hist_col_info *hists[MDSS_MDP_INTF_MAX_LAYERMIXER];
 	u32 dspp_num, disp_num;
 	char __iomem *ctl_base;
 	u32 hist_cnt, mixer_id[MDSS_MDP_INTF_MAX_LAYERMIXER];
@@ -3349,6 +3344,7 @@
 	u32 exp_sum = 0;
 	struct mdss_mdp_pipe *pipe;
 	struct mdss_data_type *mdata = mdss_mdp_get_mdata();
+	unsigned long flag;
 
 	if ((PP_BLOCK(hist->block) < MDP_LOGICAL_BLOCK_DISP_0) ||
 		(PP_BLOCK(hist->block) >= MDP_BLOCK_MAX))
@@ -3369,20 +3365,41 @@
 		ret = -EPERM;
 		goto hist_collect_exit;
 	}
+
 	if (PP_LOCAT(hist->block) == MDSS_PP_DSPP_CFG) {
-		hist_info = &mdss_pp_res->dspp_hist[disp_num];
 		for (i = 0; i < hist_cnt; i++) {
 			dspp_num = mixer_id[i];
-			hist_info = &mdss_pp_res->dspp_hist[dspp_num];
+			hists[i] = &mdss_pp_res->dspp_hist[dspp_num];
+		}
+		for (i = 0; i < hist_cnt; i++) {
+			spin_lock_irqsave(&hists[i]->hist_lock, flag);
+			/* mark that collect is ready to handle completions */
+			hists[i]->read_request = 1;
+			spin_unlock_irqrestore(&hists[i]->hist_lock, flag);
+		}
+		for (i = 0; i < hist_cnt; i++) {
+			dspp_num = mixer_id[i];
 			ctl_base = mdss_mdp_get_dspp_addr_off(dspp_num) +
 				MDSS_MDP_REG_DSPP_HIST_CTL_BASE;
 			exp_sum = (mdata->mixer_intf[dspp_num].width *
 					mdata->mixer_intf[dspp_num].height);
-			ret = pp_hist_collect(hist, hist_info, ctl_base,
-								exp_sum);
 			if (ret)
-				goto hist_collect_exit;
+				temp_ret = ret;
+			ret = pp_hist_collect(hist, hists[i], ctl_base,
+								exp_sum);
 		}
+		for (i = 0; i < hist_cnt; i++) {
+			/* reset read requests and re-intialize completions */
+			spin_lock_irqsave(&hists[i]->hist_lock, flag);
+			hists[i]->read_request = 0;
+			INIT_COMPLETION(hists[i]->comp);
+			spin_unlock_irqrestore(&hists[i]->hist_lock, flag);
+		}
+		if (ret || temp_ret) {
+			ret = ret ? ret : temp_ret;
+			goto hist_collect_exit;
+		}
+
 		if (hist->bin_cnt != HIST_V_SIZE) {
 			pr_err("User not expecting size %d output",
 							HIST_V_SIZE);
@@ -3398,19 +3415,19 @@
 			}
 			memset(hist_concat, 0, HIST_V_SIZE * sizeof(u32));
 			for (i = 0; i < hist_cnt; i++) {
-				dspp_num = mixer_id[i];
-				hist_info = &mdss_pp_res->dspp_hist[dspp_num];
-				mutex_lock(&hist_info->hist_mutex);
+				mutex_lock(&hists[i]->hist_mutex);
 				for (j = 0; j < HIST_V_SIZE; j++)
-					hist_concat[j] += hist_info->data[j];
-				mutex_unlock(&hist_info->hist_mutex);
+					hist_concat[j] += hists[i]->data[j];
+				mutex_unlock(&hists[i]->hist_mutex);
 			}
 			hist_data_addr = hist_concat;
 		} else {
-			hist_data_addr = hist_info->data;
+			hist_data_addr = hists[0]->data;
 		}
-		hist_info = &mdss_pp_res->dspp_hist[disp_num];
-		hist_info->hist_cnt_sent++;
+
+		for (i = 0; i < hist_cnt; i++)
+			hists[i]->hist_cnt_sent++;
+
 	} else if (PP_LOCAT(hist->block) == MDSS_PP_SSPP_CFG) {
 
 		hist_cnt = MDSS_PP_ARG_MASK & hist->block;
@@ -3446,14 +3463,50 @@
 				continue;
 			}
 			hist_info = &pipe->pp_res.hist;
+			spin_lock_irqsave(&hist_info->hist_lock, flag);
+			hist_info->read_request = 1;
+			spin_unlock_irqrestore(&hist_info->hist_lock, flag);
+		}
+		for (i = pipe_num; i < MDSS_PP_ARG_NUM; i++) {
+			if (!PP_ARG(i, hist->block))
+				continue;
+			pipe_cnt++;
+			pipe = mdss_mdp_pipe_get(mdata, BIT(i));
+			if (IS_ERR_OR_NULL(pipe) ||
+					pipe->num > MDSS_MDP_SSPP_VIG2) {
+				pr_warn("Invalid Hist pipe (%d)", i);
+				continue;
+			}
+			hist_info = &pipe->pp_res.hist;
 			ctl_base = pipe->base +
 				MDSS_MDP_REG_VIG_HIST_CTL_BASE;
+			if (ret)
+				temp_ret = ret;
 			ret = pp_hist_collect(hist, hist_info, ctl_base,
 								exp_sum);
 			mdss_mdp_pipe_unmap(pipe);
-			if (ret)
-				goto hist_collect_exit;
 		}
+		for (i = pipe_num; i < MDSS_PP_ARG_NUM; i++) {
+			if (!PP_ARG(i, hist->block))
+				continue;
+			pipe_cnt++;
+			pipe = mdss_mdp_pipe_get(mdata, BIT(i));
+			if (IS_ERR_OR_NULL(pipe) ||
+					pipe->num > MDSS_MDP_SSPP_VIG2) {
+				pr_warn("Invalid Hist pipe (%d)", i);
+				continue;
+			}
+			hist_info = &pipe->pp_res.hist;
+			spin_lock_irqsave(&hist_info->hist_lock, flag);
+			hist_info->read_request = 0;
+			INIT_COMPLETION(hist_info->comp);
+			spin_unlock_irqrestore(&hist_info->hist_lock, flag);
+		}
+		if (ret || temp_ret) {
+			ret = ret ? ret : temp_ret;
+			goto hist_collect_exit;
+		}
+
 		if (pipe_cnt != 0 &&
 			(hist->bin_cnt != (HIST_V_SIZE * pipe_cnt))) {
 			pr_err("User not expecting size %d output",
@@ -3551,8 +3604,10 @@
 			spin_lock(&hist_info->hist_lock);
 			hist_info->col_state = HIST_READY;
 			spin_unlock(&hist_info->hist_lock);
-			if (hist_info->read_request)
+			if (hist_info->read_request == 1) {
 				complete(&hist_info->comp);
+				hist_info->read_request++;
+			}
 		}
 		/* Histogram Reset Done Interrupt */
 		if ((isr_blk & 0x2) &&
@@ -4542,7 +4597,10 @@
 		pipe = mdss_res->vig_pipes + counter;
 		base = pipe->base;
 
-		if (ptr == base + MDSS_MDP_REG_SSPP_SRC_FORMAT) {
+		if (ptr == base + MDSS_MDP_REG_VIG_OP_MODE) {
+			ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
+			break;
+		} else if (ptr == base + MDSS_MDP_REG_SSPP_SRC_FORMAT) {
 			ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
 			break;
 		} else if (ptr == base + MDSS_MDP_REG_SSPP_SRC_CONSTANT_COLOR) {
@@ -4551,6 +4609,9 @@
 		} else if (ptr == base + MDSS_MDP_REG_SSPP_SRC_UNPACK_PATTERN) {
 			ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
 			break;
+		} else if (ptr == base + MDSS_MDP_REG_SSPP_SRC_OP_MODE) {
+			ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
+			break;
 		} else if ((ptr == base + MDSS_MDP_REG_VIG_QSEED2_SHARP)) {
 			ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
 			break;
@@ -4591,6 +4652,9 @@
 		} else if (ptr == base + MDSS_MDP_REG_SSPP_SRC_UNPACK_PATTERN) {
 			ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
 			break;
+		} else if (ptr == base + MDSS_MDP_REG_SSPP_SRC_OP_MODE) {
+			ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
+			break;
 		/* IGC range */
 		} else if ((ptr >= base + MDSS_MDP_REG_IGC_RGB_BASE) &&
 				(ptr <= base + MDSS_MDP_REG_IGC_RGB_BASE +
@@ -4622,6 +4686,9 @@
 		} else if (ptr == base + MDSS_MDP_REG_SSPP_SRC_UNPACK_PATTERN) {
 			ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
 			break;
+		} else if (ptr == base + MDSS_MDP_REG_SSPP_SRC_OP_MODE) {
+			ret = MDP_PP_OPS_READ | MDP_PP_OPS_WRITE;
+			break;
 		/* IGC range */
 		} else if ((ptr >= base + MDSS_MDP_REG_IGC_DMA_BASE) &&
 				(ptr <= base + MDSS_MDP_REG_IGC_DMA_BASE +
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index 7675a5c..500421f 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -136,6 +136,12 @@
 extern __init void vm_area_add_early(struct vm_struct *vm);
 extern __init void vm_area_register_early(struct vm_struct *vm, size_t align);
 extern __init int vm_area_check_early(struct vm_struct *vm);
+#ifdef CONFIG_ENABLE_VMALLOC_SAVING
+extern void mark_vmalloc_reserved_area(void *addr, unsigned long size);
+#else
+static inline void mark_vmalloc_reserved_area(void *addr, unsigned long size)
+{ };
+#endif
 
 #ifdef CONFIG_SMP
 # ifdef CONFIG_MMU
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index e174693..2e074aa 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -184,36 +184,6 @@
 	return ret;
 }
 
-#ifdef ENABLE_VMALLOC_SAVING
-int is_vmalloc_addr(const void *x)
-{
-	struct rb_node *n;
-	struct vmap_area *va;
-	int ret = 0;
-
-	spin_lock(&vmap_area_lock);
-
-	for (n = rb_first(vmap_area_root); n; rb_next(n)) {
-		va = rb_entry(n, struct vmap_area, rb_node);
-		if (x >= va->va_start && x < va->va_end) {
-			ret = 1;
-			break;
-		}
-	}
-
-	spin_unlock(&vmap_area_lock);
-	return ret;
-}
-#else
-int is_vmalloc_addr(const void *x)
-{
-	unsigned long addr = (unsigned long)x;
-
-	return addr >= VMALLOC_START && addr < VMALLOC_END;
-}
-#endif
-EXPORT_SYMBOL(is_vmalloc_addr);
-
 int is_vmalloc_or_module_addr(const void *x)
 {
 	/*
@@ -302,6 +272,47 @@
 
 static unsigned long vmap_area_pcpu_hole;
 
+#ifdef CONFIG_ENABLE_VMALLOC_SAVING
+#define POSSIBLE_VMALLOC_START	PAGE_OFFSET
+
+#define VMALLOC_BITMAP_SIZE	((VMALLOC_END - PAGE_OFFSET) >> \
+					PAGE_SHIFT)
+#define VMALLOC_TO_BIT(addr)	((addr - PAGE_OFFSET) >> PAGE_SHIFT)
+#define BIT_TO_VMALLOC(i)	(PAGE_OFFSET + i * PAGE_SIZE)
+
+DECLARE_BITMAP(possible_areas, VMALLOC_BITMAP_SIZE);
+
+void mark_vmalloc_reserved_area(void *x, unsigned long size)
+{
+	unsigned long addr = (unsigned long)x;
+
+	bitmap_set(possible_areas, VMALLOC_TO_BIT(addr), size >> PAGE_SHIFT);
+}
+
+int is_vmalloc_addr(const void *x)
+{
+	unsigned long addr = (unsigned long)x;
+
+	if (addr < POSSIBLE_VMALLOC_START || addr >= VMALLOC_END)
+		return 0;
+
+	if (test_bit(VMALLOC_TO_BIT(addr), possible_areas))
+		return 0;
+
+	return 1;
+}
+#else
+int is_vmalloc_addr(const void *x)
+{
+	unsigned long addr = (unsigned long)x;
+
+	return addr >= VMALLOC_START && addr < VMALLOC_END;
+}
+#endif
+EXPORT_SYMBOL(is_vmalloc_addr);
+
+
+
 static struct vmap_area *__find_vmap_area(unsigned long addr)
 {
 	struct rb_node *n = vmap_area_root.rb_node;