Merge "msm: camera: Refactor ISP RDI pipeline control"
diff --git a/arch/arm/boot/dts/msm-iommu-v0.dtsi b/arch/arm/boot/dts/msm-iommu-v0.dtsi
index c6eb1b9..59b2a90 100644
--- a/arch/arm/boot/dts/msm-iommu-v0.dtsi
+++ b/arch/arm/boot/dts/msm-iommu-v0.dtsi
@@ -130,14 +130,14 @@
 		qcom,iommu-ctx@fd860000 {
 			reg = <0xfd860000 0x1000>;
 			interrupts = <0 247 0>;
-			qcom,iommu-ctx-mids = <>;
+			qcom,iommu-ctx-mids = <0 1 3>;
 			label = "mdpe_0";
 		};
 
 		qcom,iommu-ctx@fd861000 {
 			reg = <0xfd861000 0x1000>;
 			interrupts = <0 247 0>;
-			qcom,iommu-ctx-mids = <>;
+			qcom,iommu-ctx-mids = <2>;
 			label = "mdpe_1";
 		};
 	};
@@ -155,14 +155,14 @@
 		qcom,iommu-ctx@fd870000 {
 			reg = <0xfd870000 0x1000>;
 			interrupts = <0 247 0>;
-			qcom,iommu-ctx-mids = <>;
+			qcom,iommu-ctx-mids = <0>;
 			label = "mdps_0";
 		};
 
 		qcom,iommu-ctx@fd871000 {
 			reg = <0xfd871000 0x1000>;
 			interrupts = <0 247 0>;
-			qcom,iommu-ctx-mids = <>;
+			qcom,iommu-ctx-mids = <1>;
 			label = "mdps_1";
 		};
 	};
diff --git a/drivers/base/sync.c b/drivers/base/sync.c
index 809d02b..a97a503 100644
--- a/drivers/base/sync.c
+++ b/drivers/base/sync.c
@@ -324,7 +324,6 @@
 
 		new_pt->fence = dst;
 		list_add(&new_pt->pt_list, &dst->pt_list_head);
-		sync_pt_activate(new_pt);
 	}
 
 	return 0;
@@ -356,7 +355,6 @@
 					new_pt->fence = dst;
 					list_replace(&dst_pt->pt_list,
 						     &new_pt->pt_list);
-					sync_pt_activate(new_pt);
 					sync_pt_free(dst_pt);
 				}
 				collapsed = true;
@@ -372,7 +370,6 @@
 
 			new_pt->fence = dst;
 			list_add(&new_pt->pt_list, &dst->pt_list_head);
-			sync_pt_activate(new_pt);
 		}
 	}
 
@@ -453,6 +450,7 @@
 				    struct sync_fence *a, struct sync_fence *b)
 {
 	struct sync_fence *fence;
+	struct list_head *pos;
 	int err;
 
 	fence = sync_fence_alloc(name);
@@ -467,6 +465,12 @@
 	if (err < 0)
 		goto err;
 
+	list_for_each(pos, &fence->pt_list_head) {
+		struct sync_pt *pt =
+			container_of(pos, struct sync_pt, pt_list);
+		sync_pt_activate(pt);
+	}
+
 	/*
 	 * signal the fence in case one of it's pts were activated before
 	 * they were activated
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index c78eec3..b43c13e 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -999,4 +999,13 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called synaptics_dsx_fw_update.
 
+config SECURE_TOUCH
+	bool "Secure Touch"
+	depends on TOUCHSCREEN_ATMEL_MXT
+	help
+	  Say Y here to enable Secure Touch support in the Atmel MXT
+	  driver.
+
+	  If unsure, say N.
+
 endif
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 1d56a0a..0c20815 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -38,6 +38,14 @@
 #define MXT_SUSPEND_LEVEL 1
 #endif
 
+#if defined(CONFIG_SECURE_TOUCH)
+#include <linux/completion.h>
+#include <linux/pm_runtime.h>
+#include <linux/errno.h>
+#include <asm/system.h>
+#include <linux/atomic.h>
+#endif
+
 /* Family ID */
 #define MXT224_ID	0x80
 #define MXT224E_ID	0x81
@@ -383,6 +391,11 @@
 	bool update_cfg;
 	const char *fw_name;
 	bool no_force_update;
+#if defined(CONFIG_SECURE_TOUCH)
+	atomic_t st_enabled;
+	atomic_t st_pending_irqs;
+	struct completion st_completion;
+#endif
 };
 
 static struct dentry *debug_base;
@@ -979,6 +992,23 @@
 		mxt_release_all(data);
 }
 
+#if defined(CONFIG_SECURE_TOUCH)
+static irqreturn_t mxt_filter_interrupt(struct mxt_data *data)
+{
+	if (atomic_read(&data->st_enabled)) {
+		atomic_cmpxchg(&data->st_pending_irqs, 0, 1);
+		complete(&data->st_completion);
+		return IRQ_HANDLED;
+	}
+	return IRQ_NONE;
+}
+#else
+static irqreturn_t mxt_filter_interrupt(struct mxt_data *data)
+{
+	return IRQ_NONE;
+}
+#endif
+
 static irqreturn_t mxt_interrupt(int irq, void *dev_id)
 {
 	struct mxt_data *data = dev_id;
@@ -992,6 +1022,9 @@
 		return IRQ_HANDLED;
 	}
 
+	if (IRQ_HANDLED == mxt_filter_interrupt(data))
+		goto end;
+
 	do {
 		if (mxt_read_message(data, &message)) {
 			dev_err(dev, "Failed to read message\n");
@@ -1910,6 +1943,100 @@
 	return count;
 }
 
+#if defined(CONFIG_SECURE_TOUCH)
+
+static ssize_t mxt_secure_touch_enable_show(struct device *dev,
+				    struct device_attribute *attr, char *buf)
+{
+	struct mxt_data *data = dev_get_drvdata(dev);
+	return scnprintf(buf, PAGE_SIZE, "%d", atomic_read(&data->st_enabled));
+}
+/*
+ * Accept only "0" and "1" valid values.
+ * "0" will reset the st_enabled flag, then wake up the reading process.
+ * The bus driver is notified via pm_runtime that it is not required to stay
+ * awake anymore.
+ * It will also make sure the queue of events is emptied in the controller,
+ * in case a touch happened in between the secure touch being disabled and
+ * the local ISR being ungated.
+ * "1" will set the st_enabled flag and clear the st_pending_irqs flag.
+ * The bus driver is requested via pm_runtime to stay awake.
+ */
+static ssize_t mxt_secure_touch_enable_store(struct device *dev,
+				    struct device_attribute *attr,
+				    const char *buf, size_t count)
+{
+	struct mxt_data *data = dev_get_drvdata(dev);
+	unsigned long value;
+	int err = 0;
+
+	if (count > 2)
+		return -EINVAL;
+
+	err = kstrtoul(buf, 10, &value);
+	if (err != 0)
+		return err;
+
+	err = count;
+
+	switch (value) {
+	case 0:
+		if (atomic_read(&data->st_enabled) == 0)
+			break;
+
+		pm_runtime_put(&data->client->adapter->dev);
+		atomic_set(&data->st_enabled, 0);
+		complete(&data->st_completion);
+		mxt_interrupt(data->client->irq, data);
+		break;
+	case 1:
+		if (atomic_read(&data->st_enabled)) {
+			err = -EBUSY;
+			break;
+		}
+
+		if (pm_runtime_get(data->client->adapter->dev.parent) < 0) {
+			dev_err(&data->client->dev, "pm_runtime_get failed\n");
+			err = -EIO;
+			break;
+		}
+		atomic_set(&data->st_pending_irqs, 0);
+		atomic_set(&data->st_enabled, 1);
+		break;
+	default:
+		dev_err(&data->client->dev, "unsupported value: %lu\n", value);
+		err = -EINVAL;
+		break;
+	}
+
+	return err;
+}
+
+static ssize_t mxt_secure_touch_show(struct device *dev,
+				    struct device_attribute *attr, char *buf)
+{
+	struct mxt_data *data = dev_get_drvdata(dev);
+	int err;
+
+	if (atomic_read(&data->st_enabled) == 0)
+		return -EBADF;
+
+	err = wait_for_completion_interruptible(&data->st_completion);
+
+	if (err)
+		return err;
+
+	if (atomic_cmpxchg(&data->st_pending_irqs, 1, 0) != 1)
+		return -EBADF;
+
+	return scnprintf(buf, PAGE_SIZE, "%u", 1);
+}
+
+static DEVICE_ATTR(secure_touch_enable, 0666, mxt_secure_touch_enable_show,
+	mxt_secure_touch_enable_store);
+static DEVICE_ATTR(secure_touch, 0444, mxt_secure_touch_show, NULL);
+#endif
+
 static DEVICE_ATTR(object, 0444, mxt_object_show, NULL);
 static DEVICE_ATTR(update_fw, 0664, NULL, mxt_update_fw_store);
 static DEVICE_ATTR(force_cfg_update, 0664, NULL, mxt_force_cfg_update_store);
@@ -1918,6 +2045,10 @@
 	&dev_attr_object.attr,
 	&dev_attr_update_fw.attr,
 	&dev_attr_force_cfg_update.attr,
+#if defined(CONFIG_SECURE_TOUCH)
+	&dev_attr_secure_touch_enable.attr,
+	&dev_attr_secure_touch.attr,
+#endif
 	NULL
 };
 
@@ -2655,6 +2786,17 @@
 
 #endif
 
+#if defined(CONFIG_SECURE_TOUCH)
+static void __devinit secure_touch_init(struct mxt_data *data)
+{
+	init_completion(&data->st_completion);
+}
+#else
+static void __devinit secure_touch_init(struct mxt_data *data)
+{
+}
+#endif
+
 static int __devinit mxt_probe(struct i2c_client *client,
 		const struct i2c_device_id *id)
 {
@@ -2840,6 +2982,8 @@
 
 	mxt_debugfs_init(data);
 
+	secure_touch_init(data);
+
 	return 0;
 
 err_unregister_device: