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