Merge "gpio: qpnp-pin: map interrupts only when required"
diff --git a/arch/arm/boot/dts/msm8610.dtsi b/arch/arm/boot/dts/msm8610.dtsi
index 558f8c2..84adad4 100644
--- a/arch/arm/boot/dts/msm8610.dtsi
+++ b/arch/arm/boot/dts/msm8610.dtsi
@@ -240,7 +240,6 @@
 		qcom,hsusb-otg-otg-control = <2>;
 		qcom,hsusb-otg-disable-reset;
 		qcom,dp-manual-pullup;
-		qcom,ahb-async-bridge-bypass;
 		qcom,disable-retention-with-vdd-min;
 
 		qcom,msm-bus,name = "usb2";
diff --git a/arch/arm/mach-msm/cpufreq.c b/arch/arm/mach-msm/cpufreq.c
index 0978a2d..46505e0 100644
--- a/arch/arm/mach-msm/cpufreq.c
+++ b/arch/arm/mach-msm/cpufreq.c
@@ -254,6 +254,14 @@
 		|| cpu_is_msm8610() || (is_clk && is_sync))
 		cpumask_setall(policy->cpus);
 
+	cpu_work = &per_cpu(cpufreq_work, policy->cpu);
+	INIT_WORK(&cpu_work->work, set_cpu_work);
+	init_completion(&cpu_work->complete);
+
+	/* synchronous cpus share the same policy */
+	if (!cpu_clk[policy->cpu])
+		return 0;
+
 	if (cpufreq_frequency_table_cpuinfo(policy, table)) {
 #ifdef CONFIG_MSM_CPU_FREQ_SET_MIN_MAX
 		policy->cpuinfo.min_freq = CONFIG_MSM_CPU_FREQ_MIN;
@@ -292,10 +300,6 @@
 	policy->cpuinfo.transition_latency =
 		acpuclk_get_switch_time() * NSEC_PER_USEC;
 
-	cpu_work = &per_cpu(cpufreq_work, policy->cpu);
-	INIT_WORK(&cpu_work->work, set_cpu_work);
-	init_completion(&cpu_work->complete);
-
 	return 0;
 }
 
diff --git a/drivers/input/misc/bmp18x-core.c b/drivers/input/misc/bmp18x-core.c
index ae98469..6f82277 100644
--- a/drivers/input/misc/bmp18x-core.c
+++ b/drivers/input/misc/bmp18x-core.c
@@ -75,36 +75,6 @@
 #define ABS_MAX_PRESSURE	120000
 #define BMP_DELAY_DEFAULT   200
 
-struct bmp18x_calibration_data {
-	s16 AC1, AC2, AC3;
-	u16 AC4, AC5, AC6;
-	s16 B1, B2;
-	s16 MB, MC, MD;
-};
-
-/* Each client has this additional data */
-struct bmp18x_data {
-	struct	bmp18x_data_bus data_bus;
-	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;
-	u32	raw_pressure;
-	u32	temp_measurement_period;
-	u32	last_temp_measurement;
-	s32	b6; /* calculated temperature correction coefficient */
-#ifdef CONFIG_HAS_EARLYSUSPEND
-	struct early_suspend early_suspend;
-#endif
-	struct input_dev	*input;
-	struct delayed_work work;
-	u32					delay;
-	u32					enable;
-};
-
 static struct sensors_classdev sensors_cdev = {
 	.name = "bmp18x-pressure",
 	.vendor = "Bosch",
@@ -455,8 +425,15 @@
 					struct bmp18x_data, cdev);
 	struct device *dev = data->dev;
 
+	enabled = enabled ? 1 : 0;
 	mutex_lock(&data->lock);
-	data->enable = enabled ? 1 : 0;
+
+	if (data->enable == enabled) {
+		dev_warn(dev, "already %s\n", enabled ? "enabled" : "disabled");
+		goto out;
+	}
+
+	data->enable = enabled;
 
 	if (data->enable) {
 		bmp18x_enable(dev);
@@ -466,8 +443,9 @@
 		cancel_delayed_work_sync(&data->work);
 		bmp18x_disable(dev);
 	}
-	mutex_unlock(&data->lock);
 
+out:
+	mutex_unlock(&data->lock);
 	return 0;
 }
 
@@ -686,6 +664,8 @@
 	register_early_suspend(&data->early_suspend);
 #endif
 
+	pdata->set_power(data, 0);
+	data->power_enabled = 0;
 	dev_info(dev, "Succesfully initialized bmp18x!\n");
 	return 0;
 
@@ -720,10 +700,12 @@
 {
 	struct bmp18x_platform_data *pdata = dev->platform_data;
 	struct bmp18x_data *data = dev_get_drvdata(dev);
-	if (pdata && pdata->deinit_hw)
-		pdata->deinit_hw(&data->data_bus);
+	int ret = 0;
 
-	return 0;
+	if (pdata && pdata->set_power)
+		ret = pdata->set_power(data, 0);
+
+	return ret;
 }
 EXPORT_SYMBOL(bmp18x_disable);
 
@@ -731,10 +713,12 @@
 {
 	struct bmp18x_platform_data *pdata = dev->platform_data;
 	struct bmp18x_data *data = dev_get_drvdata(dev);
-	if (pdata && pdata->init_hw)
-		return pdata->init_hw(&data->data_bus);
+	int ret = 0;
 
-	return 0;
+	if (pdata && pdata->set_power)
+		ret = pdata->set_power(data, 1);
+
+	return ret;
 }
 EXPORT_SYMBOL(bmp18x_enable);
 #endif
diff --git a/drivers/input/misc/bmp18x-i2c.c b/drivers/input/misc/bmp18x-i2c.c
index abbe6e5..75edd0b 100644
--- a/drivers/input/misc/bmp18x-i2c.c
+++ b/drivers/input/misc/bmp18x-i2c.c
@@ -24,6 +24,7 @@
 #include <linux/i2c.h>
 #include <linux/err.h>
 #include <linux/regulator/consumer.h>
+#include <linux/delay.h>
 #include "bmp18x.h"
 
 struct sensor_regulator {
@@ -102,9 +103,13 @@
 
 static int bmp18x_init_hw(struct bmp18x_data_bus *data_bus)
 {
-	if (data_bus->client)
-		return bmp18x_config_regulator(data_bus->client, 1);
-	return 0;
+	int ret = 0;
+	if (data_bus->client) {
+		ret = bmp18x_config_regulator(data_bus->client, 1);
+		/* The minimum start up time of bmp18x is 10ms */
+		usleep_range(15000, 20000);
+	}
+	return ret;
 }
 
 static void bmp18x_deinit_hw(struct bmp18x_data_bus *data_bus)
@@ -113,6 +118,43 @@
 		bmp18x_config_regulator(data_bus->client, 0);
 }
 
+static int bmp18x_set_power(struct bmp18x_data *data, int on)
+{
+	int rc = 0;
+	int num_vreg = ARRAY_SIZE(bmp_vreg);
+	int i;
+
+	if (!on && data->power_enabled) {
+		for (i = 0; i < num_vreg; i++) {
+			rc = regulator_disable(bmp_vreg[i].vreg);
+			if (rc) {
+				dev_err(data->dev, "Regulator vdd disable failed rc=%d\n",
+						rc);
+				return rc;
+			}
+		}
+		data->power_enabled = false;
+	} else if (on && !data->power_enabled) {
+		for (i = 0; i < num_vreg; i++) {
+			rc = regulator_enable(bmp_vreg[i].vreg);
+			if (rc) {
+				dev_err(data->dev, "Regulator vdd enable failed rc=%d\n",
+						rc);
+				return rc;
+			}
+		}
+		/* The minimum start up time of bmp18x is 10ms */
+		usleep_range(15000, 20000);
+		data->power_enabled = true;
+	} else {
+		dev_warn(data->dev,
+				"Power on=%d. enabled=%d\n",
+				on, data->power_enabled);
+	}
+
+	return rc;
+}
+
 #ifdef CONFIG_OF
 static int bmp18x_parse_dt(struct device *dev,
 			struct bmp18x_platform_data *pdata)
@@ -198,6 +240,7 @@
 		}
 		pdata->init_hw = bmp18x_init_hw;
 		pdata->deinit_hw = bmp18x_deinit_hw;
+		pdata->set_power = bmp18x_set_power;
 		client->dev.platform_data = pdata;
 	}
 	return bmp18x_probe(&client->dev, &data_bus);
@@ -216,12 +259,24 @@
 #ifdef CONFIG_PM
 static int bmp18x_i2c_suspend(struct device *dev)
 {
-	return bmp18x_disable(dev);
+	int ret = 0;
+	struct bmp18x_data *data = dev_get_drvdata(dev);
+
+	if (data->enable)
+		ret = bmp18x_disable(dev);
+
+	return ret;
 }
 
 static int bmp18x_i2c_resume(struct device *dev)
 {
-	return bmp18x_enable(dev);
+	int ret = 0;
+	struct bmp18x_data *data = dev_get_drvdata(dev);
+
+	if (data->enable)
+		ret = bmp18x_enable(dev);
+
+	return ret;
 }
 
 static const struct dev_pm_ops bmp18x_i2c_pm_ops = {
diff --git a/drivers/input/misc/bmp18x.h b/drivers/input/misc/bmp18x.h
index d1b1ee7..6b6c4b1 100644
--- a/drivers/input/misc/bmp18x.h
+++ b/drivers/input/misc/bmp18x.h
@@ -18,6 +18,7 @@
 */
 #ifndef _BMP18X_H
 #define _BMP18X_H
+#include <linux/sensors.h>
 
 #define BMP18X_NAME "bmp18x"
 
@@ -46,13 +47,47 @@
 	void	*client;
 };
 
+struct bmp18x_calibration_data {
+	s16 AC1, AC2, AC3;
+	u16 AC4, AC5, AC6;
+	s16 B1, B2;
+	s16 MB, MC, MD;
+};
+
+/* Each client has this additional data */
+struct bmp18x_data {
+	struct	bmp18x_data_bus data_bus;
+	struct	device *dev;
+	struct	mutex lock;
+	struct	bmp18x_calibration_data calibration;
+	struct	sensors_classdev cdev;
+#ifdef CONFIG_HAS_EARLYSUSPEND
+	struct	early_suspend early_suspend;
+#endif
+	struct	input_dev	*input;
+	struct	delayed_work work;
+
+	u8	oversampling_setting;
+	u8	sw_oversampling_setting;
+	u32	raw_temperature;
+	u32	raw_pressure;
+	u32	temp_measurement_period;
+	u32	last_temp_measurement;
+	s32	b6; /* calculated temperature correction coefficient */
+	u32	delay;
+	u32	enable;
+	u32	power_enabled;
+};
+
 struct bmp18x_platform_data {
 	u8	chip_id;
 	u8	default_oversampling;
 	u8	default_sw_oversampling;
 	u32	temp_measurement_period;
+	u32	power_enabled;
 	int	(*init_hw)(struct bmp18x_data_bus *);
 	void	(*deinit_hw)(struct bmp18x_data_bus *);
+	int	(*set_power)(struct bmp18x_data*, int);
 };
 
 int bmp18x_probe(struct device *dev, struct bmp18x_data_bus *data_bus);
diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c
index a9521a1..035fc4b 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc.c
@@ -324,7 +324,6 @@
 	binfo->num_planes = b->length;
 	binfo->memory = b->memory;
 	binfo->v4l2_index = b->index;
-	binfo->dequeued = false;
 	binfo->timestamp.tv_sec = b->timestamp.tv_sec;
 	binfo->timestamp.tv_usec = b->timestamp.tv_usec;
 	dprintk(VIDC_DBG, "%s: fd[%d] = %d b->index = %d",
@@ -341,6 +340,7 @@
 	b->index = binfo->v4l2_index;
 	b->timestamp.tv_sec = binfo->timestamp.tv_sec;
 	b->timestamp.tv_usec = binfo->timestamp.tv_usec;
+	binfo->dequeued = false;
 	for (i = 0; i < binfo->num_planes; ++i) {
 		b->m.planes[i].reserved[0] = binfo->fd[i];
 		b->m.planes[i].reserved[1] = binfo->buff_off[i];
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index 8921b13..7ae2cb5 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -2960,9 +2960,6 @@
 				dprintk(VIDC_DBG,
 					"released buffer held in driver before issuing flush: 0x%x fd[0]: %d\n",
 					binfo->device_addr[0], binfo->fd[0]);
-				/*delete this buffer info from registered list*/
-				list_del(&binfo->list);
-				kfree(binfo);
 				/*send event to client*/
 				v4l2_event_queue_fh(&inst->event_handler,
 					&buf_event);