Merge "Revert "defconfig: sdm429w: [TBR] Enable logging of interrupts""
diff --git a/Documentation/media/kapi/cec-core.rst b/Documentation/media/kapi/cec-core.rst
index 88c33b5..106b112 100644
--- a/Documentation/media/kapi/cec-core.rst
+++ b/Documentation/media/kapi/cec-core.rst
@@ -194,6 +194,11 @@
 	void cec_transmit_done(struct cec_adapter *adap, u8 status, u8 arb_lost_cnt,
 		       u8 nack_cnt, u8 low_drive_cnt, u8 error_cnt);
 
+or:
+
+.. c:function::
+	void cec_transmit_attempt_done(struct cec_adapter *adap, u8 status);
+
 The status can be one of:
 
 CEC_TX_STATUS_OK:
@@ -231,6 +236,11 @@
 0 if the hardware provides no feedback of which errors occurred and how many
 times, or fill in the correct values as reported by the hardware.
 
+The cec_transmit_attempt_done() function is a helper for cases where the
+hardware never retries, so the transmit is always for just a single
+attempt. It will call cec_transmit_done() in turn, filling in 1 for the
+count argument corresponding to the status. Or all 0 if the status was OK.
+
 When a CEC message was received:
 
 .. c:function::
@@ -295,6 +305,14 @@
 address to CEC_PHYS_ADDR_INVALID before enabling the new physical address.
 
 .. c:function::
+	void cec_s_phys_addr_from_edid(struct cec_adapter *adap,
+				       const struct edid *edid);
+
+A helper function that extracts the physical address from the edid struct
+and calls cec_s_phys_addr() with that address, or CEC_PHYS_ADDR_INVALID
+if the EDID did not contain a physical address or edid was a NULL pointer.
+
+.. c:function::
 	int cec_s_log_addrs(struct cec_adapter *adap,
 			    struct cec_log_addrs *log_addrs, bool block);
 
diff --git a/arch/arm64/boot/dts/qcom/msm8905-camera-sensor-skub.dtsi b/arch/arm64/boot/dts/qcom/msm8905-camera-sensor-skub.dtsi
index d662415..80b5de1 100644
--- a/arch/arm64/boot/dts/qcom/msm8905-camera-sensor-skub.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8905-camera-sensor-skub.dtsi
@@ -47,7 +47,6 @@
 		qcom,torch-seq-val = <1 0>;
 		qcom,flash-seq-val = <0 1>;
 		qcom,duty-cycle = <0 30>;
-		qcom,clk-freq = <0 150000>;
 		linux,name = "flashlight";
 		linux,default-trigger = "flashlight-trigger";
 	};
diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/Makefile b/drivers/media/platform/msm/camera_v2/sensor/flash/Makefile
index 69be506..1121c6a 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/flash/Makefile
+++ b/drivers/media/platform/msm/camera_v2/sensor/flash/Makefile
@@ -2,5 +2,8 @@
 ccflags-y += -Idrivers/media/platform/msm/camera_v2
 ccflags-y += -Idrivers/media/platform/msm/camera_v2/common
 ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/io
+obj-$(CONFIG_MSMB_CAMERA) += msm_led_flash.o
+obj-$(CONFIG_MSMB_CAMERA) += msm_led_trigger.o
+obj-$(CONFIG_MSMB_CAMERA) += msm_led_torch.o
 obj-$(CONFIG_MSMB_CAMERA) += msm_flash.o
 obj-$(CONFIG_MSMB_CAMERA) += qm215_gpio_flash.o
diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.c b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.c
new file mode 100644
index 0000000..722ddb7
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.c
@@ -0,0 +1,126 @@
+/* Copyright (c) 2009-2014, 2020, 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__
+
+#include "msm_led_flash.h"
+
+#undef CDBG
+#define CDBG(fmt, args...) pr_debug(fmt, ##args)
+
+static struct v4l2_file_operations msm_led_flash_v4l2_subdev_fops;
+
+static long msm_led_flash_subdev_ioctl(struct v4l2_subdev *sd,
+	unsigned int cmd, void *arg)
+{
+	struct msm_led_flash_ctrl_t *fctrl = NULL;
+
+	if (!sd) {
+		pr_err("sd NULL\n");
+		return -EINVAL;
+	}
+	fctrl = v4l2_get_subdevdata(sd);
+	if (!fctrl) {
+		pr_err("fctrl NULL\n");
+		return -EINVAL;
+	}
+	switch (cmd) {
+	case VIDIOC_MSM_SENSOR_GET_SUBDEV_ID:
+		return fctrl->func_tbl->flash_get_subdev_id(fctrl, arg);
+	case VIDIOC_MSM_FLASH_LED_DATA_CFG:
+		return fctrl->func_tbl->flash_led_config(fctrl, arg);
+	case MSM_SD_NOTIFY_FREEZE:
+		return 0;
+	case MSM_SD_SHUTDOWN:
+		*(int *)arg = MSM_CAMERA_LED_RELEASE;
+		return fctrl->func_tbl->flash_led_config(fctrl, arg);
+	default:
+		pr_err_ratelimited("invalid cmd %d\n", cmd);
+		return -ENOIOCTLCMD;
+	}
+}
+
+static struct v4l2_subdev_core_ops msm_flash_subdev_core_ops = {
+	.ioctl = msm_led_flash_subdev_ioctl,
+};
+
+static struct v4l2_subdev_ops msm_flash_subdev_ops = {
+	.core = &msm_flash_subdev_core_ops,
+};
+
+static const struct v4l2_subdev_internal_ops msm_flash_internal_ops;
+
+int32_t msm_led_flash_create_v4lsubdev(struct platform_device *pdev, void *data)
+{
+	struct msm_led_flash_ctrl_t *fctrl =
+		(struct msm_led_flash_ctrl_t *)data;
+	CDBG("Enter\n");
+
+	if (!fctrl) {
+		pr_err("fctrl NULL\n");
+		return -EINVAL;
+	}
+
+	/* Initialize sub device */
+	v4l2_subdev_init(&fctrl->msm_sd.sd, &msm_flash_subdev_ops);
+	v4l2_set_subdevdata(&fctrl->msm_sd.sd, fctrl);
+
+	fctrl->pdev = pdev;
+	fctrl->msm_sd.sd.internal_ops = &msm_flash_internal_ops;
+	fctrl->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	snprintf(fctrl->msm_sd.sd.name, ARRAY_SIZE(fctrl->msm_sd.sd.name),
+		"msm_flash");
+	media_entity_pads_init(&fctrl->msm_sd.sd.entity, 0, NULL);
+	fctrl->msm_sd.sd.entity.function = MSM_CAMERA_SUBDEV_LED_FLASH;
+	fctrl->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x1;
+	msm_sd_register(&fctrl->msm_sd);
+
+	msm_led_flash_v4l2_subdev_fops = v4l2_subdev_fops;
+#ifdef CONFIG_COMPAT
+	msm_led_flash_v4l2_subdev_fops.compat_ioctl32 =
+		msm_led_flash_v4l2_subdev_fops.unlocked_ioctl;
+#endif
+	fctrl->msm_sd.sd.devnode->fops = &msm_led_flash_v4l2_subdev_fops;
+	CDBG("probe success\n");
+	return 0;
+}
+
+int32_t msm_led_i2c_flash_create_v4lsubdev(void *data)
+{
+	struct msm_led_flash_ctrl_t *fctrl =
+		(struct msm_led_flash_ctrl_t *)data;
+	CDBG("Enter\n");
+
+	if (!fctrl) {
+		pr_err("fctrl NULL\n");
+		return -EINVAL;
+	}
+
+	/* Initialize sub device */
+	v4l2_subdev_init(&fctrl->msm_sd.sd, &msm_flash_subdev_ops);
+	v4l2_set_subdevdata(&fctrl->msm_sd.sd, fctrl);
+
+	fctrl->msm_sd.sd.internal_ops = &msm_flash_internal_ops;
+	fctrl->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	snprintf(fctrl->msm_sd.sd.name, ARRAY_SIZE(fctrl->msm_sd.sd.name),
+		"msm_flash");
+	media_entity_pads_init(&fctrl->msm_sd.sd.entity, 0, NULL);
+	fctrl->msm_sd.sd.entity.function = MSM_CAMERA_SUBDEV_LED_FLASH;
+	msm_sd_register(&fctrl->msm_sd);
+
+	msm_led_flash_v4l2_subdev_fops = v4l2_subdev_fops;
+	fctrl->msm_sd.sd.devnode->fops = &msm_led_flash_v4l2_subdev_fops;
+
+	CDBG("probe success\n");
+	return 0;
+}
diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.h b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.h
new file mode 100644
index 0000000..66eff77
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_flash.h
@@ -0,0 +1,98 @@
+/* Copyright (c) 2009-2014, 2020 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef MSM_LED_FLASH_H
+#define MSM_LED_FLASH_H
+
+#include <linux/leds.h>
+#include <linux/platform_device.h>
+#include <media/v4l2-subdev.h>
+#include <media/msm_cam_sensor.h>
+#include <soc/qcom/camera2.h>
+#include "msm_camera_i2c.h"
+#include "msm_sd.h"
+
+
+struct msm_led_flash_ctrl_t;
+
+struct msm_flash_fn_t {
+	int32_t (*flash_get_subdev_id)(struct msm_led_flash_ctrl_t *, void *);
+	int32_t (*flash_led_config)(struct msm_led_flash_ctrl_t *, void *);
+	int32_t (*flash_led_init)(struct msm_led_flash_ctrl_t *);
+	int32_t (*flash_led_release)(struct msm_led_flash_ctrl_t *);
+	int32_t (*flash_led_off)(struct msm_led_flash_ctrl_t *);
+	int32_t (*flash_led_low)(struct msm_led_flash_ctrl_t *);
+	int32_t (*flash_led_high)(struct msm_led_flash_ctrl_t *);
+};
+
+struct msm_led_flash_reg_t {
+	struct msm_camera_i2c_reg_setting *init_setting;
+	struct msm_camera_i2c_reg_setting *off_setting;
+	struct msm_camera_i2c_reg_setting *release_setting;
+	struct msm_camera_i2c_reg_setting *low_setting;
+	struct msm_camera_i2c_reg_setting *high_setting;
+};
+
+struct msm_led_flash_ctrl_t {
+	struct msm_camera_i2c_client *flash_i2c_client;
+	struct msm_sd_subdev msm_sd;
+	struct platform_device *pdev;
+	struct msm_flash_fn_t *func_tbl;
+	struct msm_camera_sensor_board_info *flashdata;
+	struct msm_led_flash_reg_t *reg_setting;
+	/* Flash */
+	const char *flash_trigger_name[MAX_LED_TRIGGERS];
+	struct led_trigger *flash_trigger[MAX_LED_TRIGGERS];
+	uint32_t flash_num_sources;
+	uint32_t flash_op_current[MAX_LED_TRIGGERS];
+	uint32_t flash_max_current[MAX_LED_TRIGGERS];
+	uint32_t flash_max_duration[MAX_LED_TRIGGERS];
+	/* Torch */
+	const char *torch_trigger_name[MAX_LED_TRIGGERS];
+	struct led_trigger *torch_trigger[MAX_LED_TRIGGERS];
+	uint32_t torch_num_sources;
+	uint32_t torch_op_current[MAX_LED_TRIGGERS];
+	uint32_t torch_max_current[MAX_LED_TRIGGERS];
+
+	void *data;
+	enum msm_camera_device_type_t flash_device_type;
+	enum cci_i2c_master_t cci_i2c_master;
+	enum msm_camera_led_config_t led_state;
+	uint32_t subdev_id;
+	struct msm_pinctrl_info pinctrl_info;
+};
+
+int msm_flash_i2c_probe(struct i2c_client *client,
+	const struct i2c_device_id *id);
+
+int msm_flash_probe(struct platform_device *pdev, const void *data);
+
+int32_t msm_led_flash_create_v4lsubdev(struct platform_device *pdev,
+	void *data);
+
+int32_t msm_led_torch_create_classdev(struct platform_device *pdev,
+	void *data);
+
+int32_t msm_led_i2c_flash_create_v4lsubdev(void *data);
+
+int32_t msm_led_i2c_trigger_get_subdev_id(struct msm_led_flash_ctrl_t *fctrl,
+	void *arg);
+
+int32_t msm_led_i2c_trigger_config(struct msm_led_flash_ctrl_t *fctrl,
+	void *data);
+
+int msm_flash_led_init(struct msm_led_flash_ctrl_t *fctrl);
+int msm_flash_led_release(struct msm_led_flash_ctrl_t *fctrl);
+int msm_flash_led_off(struct msm_led_flash_ctrl_t *fctrl);
+int msm_flash_led_low(struct msm_led_flash_ctrl_t *fctrl);
+int msm_flash_led_high(struct msm_led_flash_ctrl_t *fctrl);
+#endif
diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_torch.c b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_torch.c
new file mode 100644
index 0000000..cc8e70b
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_torch.c
@@ -0,0 +1,83 @@
+/* Copyright (c) 2013-2014, 2020, 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__
+
+#include <linux/module.h>
+#include "msm_led_flash.h"
+
+static struct led_trigger *torch_trigger;
+
+static void msm_led_torch_brightness_set(struct led_classdev *led_cdev,
+				enum led_brightness value)
+{
+	if (!torch_trigger) {
+		pr_err("No torch trigger found, can't set brightness\n");
+		return;
+	}
+
+	led_trigger_event(torch_trigger, value);
+};
+
+static struct led_classdev msm_torch_led[MAX_LED_TRIGGERS] = {
+	{
+		.name		= "flashlight",
+		.brightness_set	= msm_led_torch_brightness_set,
+		.brightness	= LED_OFF,
+	},
+	{
+		.name		= "torch-light1",
+		.brightness_set	= msm_led_torch_brightness_set,
+		.brightness	= LED_OFF,
+	},
+	{
+		.name		= "torch-light2",
+		.brightness_set	= msm_led_torch_brightness_set,
+		.brightness	= LED_OFF,
+	},
+};
+
+int32_t msm_led_torch_create_classdev(struct platform_device *pdev,
+				void *data)
+{
+	int32_t i, rc = 0;
+	struct msm_led_flash_ctrl_t *fctrl =
+		(struct msm_led_flash_ctrl_t *)data;
+
+	if (!fctrl) {
+		pr_err("Invalid fctrl\n");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < fctrl->torch_num_sources; i++) {
+		if (fctrl->torch_trigger[i]) {
+			torch_trigger = fctrl->torch_trigger[i];
+			msm_torch_led[i].flags |= LED_KEEP_TRIGGER;
+			msm_led_torch_brightness_set(&msm_torch_led[i],
+				LED_OFF);
+
+			rc = led_classdev_register(&pdev->dev,
+				&msm_torch_led[i]);
+			if (rc) {
+				pr_err("Failed to register %d led dev. rc = %d\n",
+						i, rc);
+				return rc;
+			}
+		} else {
+			pr_err("Invalid fctrl->torch_trigger[%d]\n", i);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+};
diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_trigger.c b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_trigger.c
new file mode 100644
index 0000000..33224c3
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_led_trigger.c
@@ -0,0 +1,342 @@
+/* Copyright (c) 2012-2014, 2020,  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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__
+
+#include <linux/module.h>
+#include "msm_led_flash.h"
+
+#define FLASH_NAME "camera-led-flash"
+
+//#undef CDBG
+#define CDBG(fmt, args...) pr_debug(fmt, ##args)
+
+static enum flash_type flashtype;
+static struct msm_led_flash_ctrl_t fctrl;
+
+static int32_t msm_led_trigger_get_subdev_id(struct msm_led_flash_ctrl_t *fctrl,
+	void *arg)
+{
+	uint32_t *subdev_id = (uint32_t *)arg;
+
+	if (!subdev_id) {
+		pr_err("%s:%d failed\n", __func__, __LINE__);
+		return -EINVAL;
+	}
+	*subdev_id = fctrl->pdev->id;
+	CDBG("%s:%d subdev_id %d\n", __func__, __LINE__, *subdev_id);
+	return 0;
+}
+
+static int32_t msm_led_trigger_config(struct msm_led_flash_ctrl_t *fctrl,
+	void *data)
+{
+	int rc = 0;
+	struct msm_camera_led_cfg_t *cfg = (struct msm_camera_led_cfg_t *)data;
+	uint32_t i;
+	uint32_t curr_l, max_curr_l;
+
+	CDBG("called led_state %d\n", cfg->cfgtype);
+
+	if (!fctrl) {
+		CDBG("flash failed\n");
+		return -EINVAL;
+	}
+
+	switch (cfg->cfgtype) {
+	case MSM_CAMERA_LED_OFF:
+		/* Flash off */
+		for (i = 0; i < fctrl->flash_num_sources; i++)
+			if (fctrl->flash_trigger[i])
+				led_trigger_event(fctrl->flash_trigger[i], 0);
+		/* Torch off */
+		for (i = 0; i < fctrl->torch_num_sources; i++)
+			if (fctrl->torch_trigger[i])
+				led_trigger_event(fctrl->torch_trigger[i], 0);
+		break;
+
+	case MSM_CAMERA_LED_LOW:
+		for (i = 0; i < fctrl->torch_num_sources; i++)
+			if (fctrl->torch_trigger[i]) {
+				max_curr_l = fctrl->torch_max_current[i];
+				if (cfg->torch_current[i] >= 0 &&
+					cfg->torch_current[i] < max_curr_l) {
+					curr_l = cfg->torch_current[i];
+				} else {
+					curr_l = fctrl->torch_op_current[i];
+					pr_debug("LED torch %d clamped %d\n",
+						i, curr_l);
+				}
+				led_trigger_event(fctrl->torch_trigger[i],
+						curr_l);
+			}
+		break;
+
+	case MSM_CAMERA_LED_HIGH:
+		/* Torch off */
+		for (i = 0; i < fctrl->torch_num_sources; i++)
+			if (fctrl->torch_trigger[i])
+				led_trigger_event(fctrl->torch_trigger[i], 0);
+
+		for (i = 0; i < fctrl->flash_num_sources; i++)
+			if (fctrl->flash_trigger[i]) {
+				max_curr_l = fctrl->flash_max_current[i];
+				if (cfg->flash_current[i] >= 0 &&
+					cfg->flash_current[i] < max_curr_l) {
+					curr_l = cfg->flash_current[i];
+				} else {
+					curr_l = fctrl->flash_op_current[i];
+					pr_err(" i %d clamped %d\n",
+						i, curr_l);
+				}
+				led_trigger_event(fctrl->flash_trigger[i],
+					curr_l);
+			}
+		break;
+
+	case MSM_CAMERA_LED_INIT:
+	case MSM_CAMERA_LED_RELEASE:
+		/* Flash off */
+		for (i = 0; i < fctrl->flash_num_sources; i++)
+			if (fctrl->flash_trigger[i])
+				led_trigger_event(fctrl->flash_trigger[i], 0);
+		/* Torch off */
+		for (i = 0; i < fctrl->torch_num_sources; i++)
+			if (fctrl->torch_trigger[i])
+				led_trigger_event(fctrl->torch_trigger[i], 0);
+		break;
+
+	default:
+		CDBG("default set\n");
+		rc = -EFAULT;
+		break;
+	}
+	CDBG("flash_set_led_state: return %d\n", rc);
+	return rc;
+}
+
+static const struct of_device_id msm_led_trigger_dt_match[] = {
+	{.compatible = "qcom,camera-led-flash"},
+	{}
+};
+
+MODULE_DEVICE_TABLE(of, msm_led_trigger_dt_match);
+
+static int32_t msm_led_trigger_probe(struct platform_device *pdev)
+{
+	int32_t rc = 0, rc_1 = 0, i = 0;
+	struct device_node *of_node = pdev->dev.of_node;
+	struct device_node *flash_src_node = NULL;
+	uint32_t count = 0;
+	struct led_trigger *temp = NULL;
+
+	CDBG("called\n");
+
+	if (!of_node) {
+		pr_err("of_node NULL\n");
+		return -EINVAL;
+	}
+
+	fctrl.pdev = pdev;
+	fctrl.flash_num_sources = 0;
+	fctrl.torch_num_sources = 0;
+
+	rc = of_property_read_u32(of_node, "cell-index", &pdev->id);
+	if (rc < 0) {
+		pr_err("failed\n");
+		return -EINVAL;
+	}
+	CDBG("pdev id %d\n", pdev->id);
+
+	rc = of_property_read_u32(of_node,
+			"qcom,flash-type", &flashtype);
+	if (rc < 0) {
+		pr_err("flash-type: read failed\n");
+		return -EINVAL;
+	}
+
+	/* Flash source */
+	if (of_get_property(of_node, "qcom,flash-source", &count)) {
+		count /= sizeof(uint32_t);
+		CDBG("qcom,flash-source count %d\n", count);
+		if (count > MAX_LED_TRIGGERS) {
+			pr_err("invalid count qcom,flash-source %d\n", count);
+			return -EINVAL;
+		}
+		fctrl.flash_num_sources = count;
+		for (i = 0; i < fctrl.flash_num_sources; i++) {
+			flash_src_node = of_parse_phandle(of_node,
+				"qcom,flash-source", i);
+			if (!flash_src_node) {
+				pr_err("flash_src_node %d NULL\n", i);
+				continue;
+			}
+
+			rc = of_property_read_string(flash_src_node,
+				"linux,default-trigger",
+				&fctrl.flash_trigger_name[i]);
+
+			rc_1 = of_property_read_string(flash_src_node,
+				"qcom,default-led-trigger",
+				&fctrl.flash_trigger_name[i]);
+			if ((rc < 0) && (rc_1 < 0)) {
+				pr_err("default-trigger: read failed\n");
+				of_node_put(flash_src_node);
+				continue;
+			}
+
+			CDBG("default trigger %s\n",
+				fctrl.flash_trigger_name[i]);
+
+			if (flashtype == GPIO_FLASH) {
+				/* use fake current */
+				fctrl.flash_op_current[i] = LED_FULL;
+			} else {
+				rc = of_property_read_u32(flash_src_node,
+					"qcom,current",
+					&fctrl.flash_op_current[i]);
+				rc_1 = of_property_read_u32(flash_src_node,
+					"qcom,max-current",
+					&fctrl.flash_max_current[i]);
+				if ((rc < 0) || (rc_1 < 0)) {
+					pr_err("current: read failed\n");
+					of_node_put(flash_src_node);
+					continue;
+				}
+			}
+
+			of_node_put(flash_src_node);
+
+			 CDBG("max_current[%d] %d\n",
+				i, fctrl.flash_op_current[i]);
+
+			led_trigger_register_simple(fctrl.flash_trigger_name[i],
+				&fctrl.flash_trigger[i]);
+
+			if (flashtype == GPIO_FLASH)
+				if (fctrl.flash_trigger[i])
+					temp = fctrl.flash_trigger[i];
+		}
+
+	}
+	/* Torch source */
+	if (of_get_property(of_node, "qcom,torch-source", &count)) {
+		count /= sizeof(uint32_t);
+		pr_err("qcom,torch-source count %d\n", count);
+		if (count > MAX_LED_TRIGGERS) {
+			pr_err("invalid count qcom,torch-source %d\n", count);
+			return -EINVAL;
+		}
+		fctrl.torch_num_sources = count;
+
+		for (i = 0; i < fctrl.torch_num_sources; i++) {
+			flash_src_node = of_parse_phandle(of_node,
+				"qcom,torch-source", i);
+			if (!flash_src_node) {
+				pr_err("torch_src_node %d NULL\n", i);
+				continue;
+			}
+
+			rc = of_property_read_string(flash_src_node,
+				"linux,default-trigger",
+				&fctrl.torch_trigger_name[i]);
+
+			rc_1 = of_property_read_string(flash_src_node,
+				"qcom,default-led-trigger",
+				&fctrl.torch_trigger_name[i]);
+			if ((rc < 0) && (rc_1 < 0)) {
+				pr_err("default-trigger: read failed\n");
+				of_node_put(flash_src_node);
+				continue;
+			}
+
+			CDBG("default trigger %s\n",
+				fctrl.torch_trigger_name[i]);
+
+			if (flashtype == GPIO_FLASH) {
+				/* use fake current */
+				fctrl.torch_op_current[i] = LED_HALF;
+			} else {
+				rc = of_property_read_u32(flash_src_node,
+					"qcom,current",
+					&fctrl.torch_op_current[i]);
+				rc_1 = of_property_read_u32(flash_src_node,
+					"qcom,max-current",
+					&fctrl.torch_max_current[i]);
+				if ((rc < 0) || (rc_1 < 0)) {
+					pr_err("current: read failed\n");
+					of_node_put(flash_src_node);
+					continue;
+				}
+			}
+
+			of_node_put(flash_src_node);
+
+			CDBG("torch max_current[%d] %d\n",
+				i, fctrl.torch_op_current[i]);
+
+			led_trigger_register_simple(fctrl.torch_trigger_name[i],
+				&fctrl.torch_trigger[i]);
+
+			if (flashtype == GPIO_FLASH)
+				if (temp && !fctrl.torch_trigger[i])
+					fctrl.torch_trigger[i] = temp;
+		}
+	}
+
+	rc = msm_led_flash_create_v4lsubdev(pdev, &fctrl);
+	//if (!rc)
+		msm_led_torch_create_classdev(pdev, &fctrl);
+
+	return rc;
+}
+
+static struct platform_driver msm_led_trigger_driver = {
+	.probe = msm_led_trigger_probe,
+	.driver = {
+		.name = FLASH_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = msm_led_trigger_dt_match,
+	},
+};
+
+static int __init msm_led_trigger_init_module(void)
+{
+	int32_t rc = 0;
+
+	CDBG("called\n");
+	rc = platform_driver_register(&msm_led_trigger_driver);
+	if (rc)
+		pr_err("platform probe for flash failed");
+
+	return rc;
+}
+
+static void __exit msm_led_trigger_exit_module(void)
+{
+	platform_driver_unregister(&msm_led_trigger_driver);
+}
+
+static struct msm_flash_fn_t msm_led_trigger_func_tbl = {
+	.flash_get_subdev_id = msm_led_trigger_get_subdev_id,
+	.flash_led_config = msm_led_trigger_config,
+};
+
+static struct msm_led_flash_ctrl_t fctrl = {
+	.func_tbl = &msm_led_trigger_func_tbl,
+};
+
+module_init(msm_led_trigger_init_module);
+module_exit(msm_led_trigger_exit_module);
+MODULE_DESCRIPTION("LED TRIGGER FLASH");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/platform/msm/ep_pcie/ep_pcie_core.c b/drivers/platform/msm/ep_pcie/ep_pcie_core.c
index 1478e8b..10fa11a 100644
--- a/drivers/platform/msm/ep_pcie/ep_pcie_core.c
+++ b/drivers/platform/msm/ep_pcie/ep_pcie_core.c
@@ -1403,6 +1403,15 @@
 				ep_pcie_core_init(dev, true);
 				dev->link_status = EP_PCIE_LINK_UP;
 				dev->l23_ready = false;
+
+				/* enable pipe clock for early link init case*/
+				ret = ep_pcie_pipe_clk_init(dev);
+				if (ret) {
+					EP_PCIE_ERR(dev,
+					"PCIe V%d: failed to enable pipe clock\n",
+					dev->rev);
+					goto pipe_clk_fail;
+				}
 				goto checkbme;
 			} else {
 				ltssm_en = readl_relaxed(dev->parf
diff --git a/drivers/staging/media/cec/cec-adap.c b/drivers/staging/media/cec/cec-adap.c
index 75e6d5e..1a8e68e 100644
--- a/drivers/staging/media/cec/cec-adap.c
+++ b/drivers/staging/media/cec/cec-adap.c
@@ -28,6 +28,8 @@
 #include <linux/string.h>
 #include <linux/types.h>
 
+#include <drm/drm_edid.h>
+
 #include "cec-priv.h"
 
 static int cec_report_features(struct cec_adapter *adap, unsigned int la_idx);
@@ -540,6 +542,32 @@
 }
 EXPORT_SYMBOL_GPL(cec_transmit_done);
 
+void cec_transmit_attempt_done(struct cec_adapter *adap, u8 status)
+{
+	switch (status) {
+	case CEC_TX_STATUS_OK:
+		cec_transmit_done(adap, status, 0, 0, 0, 0);
+		return;
+	case CEC_TX_STATUS_ARB_LOST:
+		cec_transmit_done(adap, status, 1, 0, 0, 0);
+		return;
+	case CEC_TX_STATUS_NACK:
+		cec_transmit_done(adap, status, 0, 1, 0, 0);
+		return;
+	case CEC_TX_STATUS_LOW_DRIVE:
+		cec_transmit_done(adap, status, 0, 0, 1, 0);
+		return;
+	case CEC_TX_STATUS_ERROR:
+		cec_transmit_done(adap, status, 0, 0, 0, 1);
+		return;
+	default:
+		/* Should never happen */
+		WARN(1, "cec-%s: invalid status 0x%02x\n", adap->name, status);
+		return;
+	}
+}
+EXPORT_SYMBOL_GPL(cec_transmit_attempt_done);
+
 /*
  * Called when waiting for a reply times out.
  */
@@ -1169,6 +1197,18 @@
 }
 EXPORT_SYMBOL_GPL(cec_s_phys_addr);
 
+void cec_s_phys_addr_from_edid(struct cec_adapter *adap,
+			       const struct edid *edid)
+{
+	u16 pa = CEC_PHYS_ADDR_INVALID;
+
+	if (edid && edid->extensions)
+		pa = cec_get_edid_phys_addr((const u8 *)edid,
+				EDID_LENGTH * (edid->extensions + 1), NULL);
+	cec_s_phys_addr(adap, pa, false);
+}
+EXPORT_SYMBOL_GPL(cec_s_phys_addr_from_edid);
+
 /*
  * Called from either the ioctl or a driver to set the logical addresses.
  *
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 0c51f91..eab0f17 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -629,6 +629,9 @@
 #define DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0   0x2003   /* 1.2 */
 
 #define DP_DEVICE_SERVICE_IRQ_VECTOR_ESI1   0x2004   /* 1.2 */
+# define DP_RX_GTC_MSTR_REQ_STATUS_CHANGE    (1 << 0)
+# define DP_LOCK_ACQUISITION_REQUEST         (1 << 1)
+# define DP_CEC_IRQ                          (1 << 2)
 
 #define DP_LINK_SERVICE_IRQ_VECTOR_ESI0     0x2005   /* 1.2 */
 
@@ -652,6 +655,62 @@
 #define DP_RECEIVER_ALPM_STATUS		    0x200b  /* eDP 1.4 */
 # define DP_ALPM_LOCK_TIMEOUT_ERROR	    (1 << 0)
 
+/* HDMI CEC tunneling over AUX DP 1.3 section 5.3.3.3.1 DPCD 1.4+ */
+#define DP_CEC_TUNNELING_CAPABILITY            0x3000
+# define DP_CEC_TUNNELING_CAPABLE               (1 << 0)
+# define DP_CEC_SNOOPING_CAPABLE                (1 << 1)
+# define DP_CEC_MULTIPLE_LA_CAPABLE             (1 << 2)
+
+#define DP_CEC_TUNNELING_CONTROL               0x3001
+# define DP_CEC_TUNNELING_ENABLE                (1 << 0)
+# define DP_CEC_SNOOPING_ENABLE                 (1 << 1)
+
+#define DP_CEC_RX_MESSAGE_INFO                 0x3002
+# define DP_CEC_RX_MESSAGE_LEN_MASK             (0xf << 0)
+# define DP_CEC_RX_MESSAGE_LEN_SHIFT            0
+# define DP_CEC_RX_MESSAGE_HPD_STATE            (1 << 4)
+# define DP_CEC_RX_MESSAGE_HPD_LOST             (1 << 5)
+# define DP_CEC_RX_MESSAGE_ACKED                (1 << 6)
+# define DP_CEC_RX_MESSAGE_ENDED                (1 << 7)
+
+#define DP_CEC_TX_MESSAGE_INFO                 0x3003
+# define DP_CEC_TX_MESSAGE_LEN_MASK             (0xf << 0)
+# define DP_CEC_TX_MESSAGE_LEN_SHIFT            0
+# define DP_CEC_TX_RETRY_COUNT_MASK             (0x7 << 4)
+# define DP_CEC_TX_RETRY_COUNT_SHIFT            4
+# define DP_CEC_TX_MESSAGE_SEND                 (1 << 7)
+
+#define DP_CEC_TUNNELING_IRQ_FLAGS             0x3004
+# define DP_CEC_RX_MESSAGE_INFO_VALID           (1 << 0)
+# define DP_CEC_RX_MESSAGE_OVERFLOW             (1 << 1)
+# define DP_CEC_TX_MESSAGE_SENT                 (1 << 4)
+# define DP_CEC_TX_LINE_ERROR                   (1 << 5)
+# define DP_CEC_TX_ADDRESS_NACK_ERROR           (1 << 6)
+# define DP_CEC_TX_DATA_NACK_ERROR              (1 << 7)
+
+#define DP_CEC_LOGICAL_ADDRESS_MASK            0x300E /* 0x300F word */
+# define DP_CEC_LOGICAL_ADDRESS_0               (1 << 0)
+# define DP_CEC_LOGICAL_ADDRESS_1               (1 << 1)
+# define DP_CEC_LOGICAL_ADDRESS_2               (1 << 2)
+# define DP_CEC_LOGICAL_ADDRESS_3               (1 << 3)
+# define DP_CEC_LOGICAL_ADDRESS_4               (1 << 4)
+# define DP_CEC_LOGICAL_ADDRESS_5               (1 << 5)
+# define DP_CEC_LOGICAL_ADDRESS_6               (1 << 6)
+# define DP_CEC_LOGICAL_ADDRESS_7               (1 << 7)
+#define DP_CEC_LOGICAL_ADDRESS_MASK_2          0x300F /* 0x300E word */
+# define DP_CEC_LOGICAL_ADDRESS_8               (1 << 0)
+# define DP_CEC_LOGICAL_ADDRESS_9               (1 << 1)
+# define DP_CEC_LOGICAL_ADDRESS_10              (1 << 2)
+# define DP_CEC_LOGICAL_ADDRESS_11              (1 << 3)
+# define DP_CEC_LOGICAL_ADDRESS_12              (1 << 4)
+# define DP_CEC_LOGICAL_ADDRESS_13              (1 << 5)
+# define DP_CEC_LOGICAL_ADDRESS_14              (1 << 6)
+# define DP_CEC_LOGICAL_ADDRESS_15              (1 << 7)
+
+#define DP_CEC_RX_MESSAGE_BUFFER               0x3010
+#define DP_CEC_TX_MESSAGE_BUFFER               0x3020
+#define DP_CEC_MESSAGE_BUFFER_LENGTH             0x10
+
 /* DP 1.2 Sideband message defines */
 /* peer device type - DP 1.2a Table 2-92 */
 #define DP_PEER_DEVICE_NONE		0x0
diff --git a/include/media/cec.h b/include/media/cec.h
index fdb5d60..2f90e25 100644
--- a/include/media/cec.h
+++ b/include/media/cec.h
@@ -186,6 +186,11 @@
 	char input_drv[32];
 };
 
+static inline void *cec_get_drvdata(const struct cec_adapter *adap)
+{
+	return adap->priv;
+}
+
 static inline bool cec_has_log_addr(const struct cec_adapter *adap, u8 log_addr)
 {
 	return adap->log_addrs.log_addr_mask & (1 << log_addr);
@@ -196,6 +201,8 @@
 	return adap->phys_addr == 0;
 }
 
+struct edid;
+
 #if IS_ENABLED(CONFIG_MEDIA_CEC)
 struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
 		void *priv, const char *name, u32 caps, u8 available_las,
@@ -208,12 +215,20 @@
 		    bool block);
 void cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr,
 		     bool block);
+void cec_s_phys_addr_from_edid(struct cec_adapter *adap,
+			       const struct edid *edid);
 int cec_transmit_msg(struct cec_adapter *adap, struct cec_msg *msg,
 		     bool block);
 
 /* Called by the adapter */
 void cec_transmit_done(struct cec_adapter *adap, u8 status, u8 arb_lost_cnt,
 		       u8 nack_cnt, u8 low_drive_cnt, u8 error_cnt);
+/*
+ * Simplified version of cec_transmit_done for hardware that doesn't retry
+ * failed transmits. So this is always just one attempt in which case
+ * the status is sufficient.
+ */
+void cec_transmit_attempt_done(struct cec_adapter *adap, u8 status);
 void cec_received_msg(struct cec_adapter *adap, struct cec_msg *msg);
 
 #else
@@ -236,6 +251,24 @@
 {
 }
 
+static inline void cec_s_phys_addr_from_edid(struct cec_adapter *adap,
+					     const struct edid *edid)
+{
+}
+
 #endif
 
+/**
+ * cec_phys_addr_invalidate() - set the physical address to INVALID
+ *
+ * @adap:	the CEC adapter
+ *
+ * This is a simple helper function to invalidate the physical
+ * address.
+ */
+static inline void cec_phys_addr_invalidate(struct cec_adapter *adap)
+{
+	cec_s_phys_addr(adap, CEC_PHYS_ADDR_INVALID, false);
+}
+
 #endif /* _MEDIA_CEC_H */
diff --git a/kernel/sched/core_ctl.c b/kernel/sched/core_ctl.c
index bd64b1a..d906509 100644
--- a/kernel/sched/core_ctl.c
+++ b/kernel/sched/core_ctl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2018, 2020 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
@@ -75,8 +75,8 @@
 static unsigned int num_clusters;
 
 #define for_each_cluster(cluster, idx) \
-	for ((cluster) = &cluster_state[idx]; (idx) < num_clusters;\
-		(idx)++, (cluster) = &cluster_state[idx])
+	for (; (idx) < num_clusters && ((cluster) = &cluster_state[idx]);\
+		(idx)++)
 
 static DEFINE_SPINLOCK(state_lock);
 static void apply_need(struct cluster_data *state);