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);