Merge "net: ipc_router: Handling msm ssr scenario"
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 c13c031..51b7d78 100644
--- a/arch/arm64/boot/dts/qcom/msm8905-camera-sensor-skub.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8905-camera-sensor-skub.dtsi
@@ -17,8 +17,17 @@
qcom,pin-func = <2>;
label = "SY7807_pins";
SY7807_default: en_default {
- drive-strength = <2>;
- bias-pull-down;
+ mux {
+ pins = "gpio32";
+ function = "gpio";
+ };
+
+ configs {
+ pins = "gpio32";
+ drive-strength = <0x2>;
+ bias-pull-down;
+ };
+
};
};
};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-audio.dtsi b/arch/arm64/boot/dts/qcom/sdm670-audio.dtsi
index 0ea1660..7990e91 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-audio.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-audio.dtsi
@@ -71,12 +71,11 @@
<&incall_music_2_rx>,
<&usb_audio_rx>, <&usb_audio_tx>,
<&dai_pri_tdm_rx_0>, <&dai_pri_tdm_tx_0>,
- <&dai_pri_tdm_tx_1>, <&dai_pri_tdm_tx_2>,
- <&dai_pri_tdm_tx_3>, <&dai_sec_tdm_rx_0>,
- <&dai_sec_tdm_tx_0>, <&dai_tert_tdm_rx_0>,
- <&dai_tert_tdm_tx_0>, <&dai_quat_tdm_rx_0>,
- <&dai_quat_tdm_tx_0>, <&dai_quin_tdm_rx_0>,
- <&dai_quin_tdm_tx_0>, <&afe_loopback_tx>;
+ <&dai_sec_tdm_rx_0>, <&dai_sec_tdm_tx_0>,
+ <&dai_tert_tdm_rx_0>, <&dai_tert_tdm_tx_0>,
+ <&dai_quat_tdm_rx_0>, <&dai_quat_tdm_tx_0>,
+ <&dai_quin_tdm_rx_0>, <&dai_quin_tdm_tx_0>,
+ <&afe_loopback_tx>;
asoc-cpu-names = "msm-dai-q6-dp.24608",
"msm-dai-q6-mi2s.0", "msm-dai-q6-mi2s.1",
"msm-dai-q6-mi2s.2", "msm-dai-q6-mi2s.3",
@@ -99,12 +98,11 @@
"msm-dai-q6-dev.32773", "msm-dai-q6-dev.32770",
"msm-dai-q6-dev.28672", "msm-dai-q6-dev.28673",
"msm-dai-q6-tdm.36864", "msm-dai-q6-tdm.36865",
- "msm-dai-q6-tdm.36867", "msm-dai-q6-tdm.36869",
- "msm-dai-q6-tdm.36871", "msm-dai-q6-tdm.36880",
- "msm-dai-q6-tdm.36881", "msm-dai-q6-tdm.36896",
- "msm-dai-q6-tdm.36897", "msm-dai-q6-tdm.36912",
- "msm-dai-q6-tdm.36913", "msm-dai-q6-tdm.36928",
- "msm-dai-q6-tdm.36929", "msm-dai-q6-dev.24577";
+ "msm-dai-q6-tdm.36880", "msm-dai-q6-tdm.36881",
+ "msm-dai-q6-tdm.36896", "msm-dai-q6-tdm.36897",
+ "msm-dai-q6-tdm.36912", "msm-dai-q6-tdm.36913",
+ "msm-dai-q6-tdm.36928", "msm-dai-q6-tdm.36929",
+ "msm-dai-q6-dev.24577";
};
tasha_snd: sound-tasha {
@@ -243,40 +241,6 @@
compatible = "qcom,msm-cpe-lsm";
qcom,msm-cpe-lsm-id = <3>;
};
-
- pri_tdm_tx: qcom,msm-dai-tdm-pri-tx {
- compatible = "qcom,msm-dai-tdm";
- qcom,msm-cpudai-tdm-group-id = <37121>;
- qcom,msm-cpudai-tdm-group-num-ports = <4>;
- qcom,msm-cpudai-tdm-group-port-id = <36865 36867 36869 36871>;
- qcom,msm-cpudai-tdm-clk-rate = <1536000>;
- qcom,msm-cpudai-tdm-clk-internal = <1>;
- qcom,msm-cpudai-tdm-sync-mode = <1>;
- qcom,msm-cpudai-tdm-sync-src = <1>;
- qcom,msm-cpudai-tdm-data-out = <0>;
- qcom,msm-cpudai-tdm-invert-sync = <1>;
- qcom,msm-cpudai-tdm-data-delay = <1>;
- dai_pri_tdm_tx_0: qcom,msm-dai-q6-tdm-pri-tx-0 {
- compatible = "qcom,msm-dai-q6-tdm";
- qcom,msm-cpudai-tdm-dev-id = <36865>;
- qcom,msm-cpudai-tdm-data-align = <0>;
- };
- dai_pri_tdm_tx_1: qcom,msm-dai-q6-tdm-pri-tx-1 {
- compatible = "qcom,msm-dai-q6-tdm";
- qcom,msm-cpudai-tdm-dev-id = <36867>;
- qcom,msm-cpudai-tdm-data-align = <0>;
- };
- dai_pri_tdm_tx_2: qcom,msm-dai-q6-tdm-pri-tx-2 {
- compatible = "qcom,msm-dai-q6-tdm";
- qcom,msm-cpudai-tdm-dev-id = <36869>;
- qcom,msm-cpudai-tdm-data-align = <0>;
- };
- dai_pri_tdm_tx_3: qcom,msm-dai-q6-tdm-pri-tx-3 {
- compatible = "qcom,msm-dai-q6-tdm";
- qcom,msm-cpudai-tdm-dev-id = <36871>;
- qcom,msm-cpudai-tdm-data-align = <0>;
- };
- };
};
&slim_aud {
diff --git a/drivers/bus/mhi/core/mhi_main.c b/drivers/bus/mhi/core/mhi_main.c
index 66cb2a9..1b81eb8 100644
--- a/drivers/bus/mhi/core/mhi_main.c
+++ b/drivers/bus/mhi/core/mhi_main.c
@@ -1285,6 +1285,10 @@
local_rp->ptr, local_rp->dword[0], local_rp->dword[1]);
chan = MHI_TRE_GET_EV_CHID(local_rp);
+ if (chan >= mhi_cntrl->max_chan) {
+ MHI_ERR("invalid channel id %u\n", chan);
+ continue;
+ }
mhi_chan = &mhi_cntrl->mhi_chan[chan];
if (likely(type == MHI_PKT_TYPE_TX_EVENT)) {
diff --git a/drivers/clk/msm/clock-gcc-8909.c b/drivers/clk/msm/clock-gcc-8909.c
index d96a398..caeb55a 100644
--- a/drivers/clk/msm/clock-gcc-8909.c
+++ b/drivers/clk/msm/clock-gcc-8909.c
@@ -817,6 +817,7 @@
};
static struct clk_freq_tbl ftbl_gcc_camss_gp0_1_clk[] = {
+ F( 150000, xo, 1, 1, 128),
F( 100000000, gpll0, 8, 0, 0),
F( 200000000, gpll0, 4, 0, 0),
F_END
diff --git a/drivers/iio/imu/st_asm330lhh/st_asm330lhh.h b/drivers/iio/imu/st_asm330lhh/st_asm330lhh.h
index 39a99a2..c3ea68b 100644
--- a/drivers/iio/imu/st_asm330lhh/st_asm330lhh.h
+++ b/drivers/iio/imu/st_asm330lhh/st_asm330lhh.h
@@ -181,6 +181,7 @@
u16 watermark;
u8 batch_mask;
u8 batch_addr;
+ struct mutex sensor_buff;
#ifdef CONFIG_ENABLE_ASM_ACC_GYRO_BUFFERING
bool read_boot_sample;
int bufsample_cnt;
@@ -191,7 +192,6 @@
int max_buffer_time;
struct input_dev *buf_dev;
int report_evt_cnt;
- struct mutex sensor_buff;
#endif
};
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index f931a2c..c42c846 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -705,6 +705,15 @@
variable brightness. It also supports outputting the Avdd supply for
AMOLED displays.
+config LEDS_MSM_GPIO_FLASH
+ tristate "Support for GPIO Flash LEDs"
+ help
+ This driver supports the leds functionality of GPIO Flash LED. It
+ includes flash mode and torch mode.
+
+ To compile this driver as a module, choose M here: the module will
+ be called leds-gpio-flash.
+
config LEDS_QPNP_HAPTICS
tristate "Haptics support for QPNP PMIC"
depends on LEDS_CLASS && MFD_SPMI_PMIC
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 31d29f0..e53ef7e 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -61,6 +61,7 @@
obj-$(CONFIG_LEDS_MAX8997) += leds-max8997.o
obj-$(CONFIG_LEDS_LM355x) += leds-lm355x.o
obj-$(CONFIG_LEDS_BLINKM) += leds-blinkm.o
+obj-$(CONFIG_LEDS_MSM_GPIO_FLASH) += leds-msm-gpio-flash.o
obj-$(CONFIG_LEDS_QTI_TRI_LED) += leds-qti-tri-led.o
obj-$(CONFIG_LEDS_SYSCON) += leds-syscon.o
obj-$(CONFIG_LEDS_VERSATILE) += leds-versatile.o
diff --git a/drivers/leds/leds-msm-gpio-flash.c b/drivers/leds/leds-msm-gpio-flash.c
new file mode 100644
index 0000000..6a5332e
--- /dev/null
+++ b/drivers/leds/leds-msm-gpio-flash.c
@@ -0,0 +1,516 @@
+/* Copyright (c) 2013-2014, 2017, 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.
+ */
+
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/leds.h>
+#include <linux/platform_device.h>
+#include <linux/of_gpio.h>
+#include <linux/gpio.h>
+#include <linux/of.h>
+#include <linux/printk.h>
+#include <linux/list.h>
+#include <linux/clk/msm-clk.h>
+#include <linux/clk/msm-clk-provider.h>
+#include <linux/pinctrl/consumer.h>
+
+/* #define CONFIG_GPIO_FLASH_DEBUG */
+#undef CDBG
+#ifdef CONFIG_GPIO_FLASH_DEBUG
+#define CDBG(fmt, args...) pr_err(fmt, ##args)
+#else
+#define CDBG(fmt, args...) do { } while (0)
+#endif
+
+#define LED_GPIO_FLASH_DRIVER_NAME "qcom,leds-gpio-flash"
+#define LED_TRIGGER_DEFAULT "none"
+
+#define GPIO_OUT_LOW (0 << 1)
+#define GPIO_OUT_HIGH (1 << 1)
+
+#define DUTY_CYCLE_BASE 100
+
+enum msm_flash_seq_type_t {
+ FLASH_EN,
+ FLASH_NOW,
+};
+
+enum msm_flash_gpio_type_t {
+ NORMAL_GPIO,
+ CLK_GPIO,
+};
+
+struct msm_flash_ctrl_seq {
+ enum msm_flash_seq_type_t seq_type;
+ uint8_t flash_on_val;
+ uint8_t torch_on_val;
+};
+
+struct led_gpio_flash_data {
+ int flash_en;
+ int flash_now;
+ struct clk *flash_en_clk;
+ struct clk *flash_now_clk;
+ int brightness;
+ atomic_t clk_enabled[2];
+ uint32_t clk_freq[2];
+ uint32_t duty_cycle[2];
+ enum msm_flash_gpio_type_t gpio_type[2];
+ struct led_classdev cdev;
+ struct pinctrl *pinctrl;
+ struct pinctrl_state *gpio_state_default;
+ struct msm_flash_ctrl_seq ctrl_seq[2];
+};
+
+static const struct of_device_id led_gpio_flash_of_match[] = {
+ {.compatible = LED_GPIO_FLASH_DRIVER_NAME,},
+ {},
+};
+
+static void led_gpio_brightness_set(struct led_classdev *led_cdev,
+ enum led_brightness value)
+{
+ int rc = 0;
+ int brightness = value;
+ int flash_en = 0;
+ int flash_now = 0;
+ struct led_gpio_flash_data *flash_led =
+ container_of(led_cdev, struct led_gpio_flash_data, cdev);
+
+ if (brightness > LED_HALF) {
+ flash_en =
+ flash_led->ctrl_seq[FLASH_EN].flash_on_val;
+ flash_now =
+ flash_led->ctrl_seq[FLASH_NOW].flash_on_val;
+ } else if (brightness > LED_OFF) {
+ flash_en =
+ flash_led->ctrl_seq[FLASH_EN].torch_on_val;
+ flash_now =
+ flash_led->ctrl_seq[FLASH_NOW].torch_on_val;
+ } else {
+ flash_en = 0;
+ flash_now = 0;
+ }
+
+ CDBG("%s:flash_en=%d, flash_now=%d\n", __func__, flash_en, flash_now);
+
+ if (flash_led->gpio_type[FLASH_EN] == NORMAL_GPIO) {
+ rc = gpio_direction_output(flash_led->flash_en, flash_en);
+ } else {
+ if (flash_en == GPIO_OUT_HIGH &&
+ !atomic_read(&flash_led->clk_enabled[FLASH_EN])) {
+ rc = clk_prepare_enable(flash_led->flash_en_clk);
+ atomic_set(&flash_led->clk_enabled[FLASH_EN], 1);
+ } else if (flash_en == GPIO_OUT_LOW &&
+ atomic_read(&flash_led->clk_enabled[FLASH_EN])) {
+ clk_disable_unprepare(flash_led->flash_en_clk);
+ atomic_set(&flash_led->clk_enabled[FLASH_EN], 0);
+ }
+ }
+
+ if (rc) {
+ pr_err("%s: Failed to set flash en.\n", __func__);
+ return;
+ }
+
+ if (flash_led->gpio_type[FLASH_NOW] == NORMAL_GPIO) {
+ rc = gpio_direction_output(flash_led->flash_now, flash_now);
+ } else {
+ if (flash_now == GPIO_OUT_HIGH &&
+ !atomic_read(&flash_led->clk_enabled[FLASH_NOW])) {
+ rc = clk_prepare_enable(flash_led->flash_now_clk);
+ atomic_set(&flash_led->clk_enabled[FLASH_NOW], 1);
+ } else if (flash_now == GPIO_OUT_LOW &&
+ atomic_read(&flash_led->clk_enabled[FLASH_NOW])) {
+ clk_disable_unprepare(flash_led->flash_now_clk);
+ atomic_set(&flash_led->clk_enabled[FLASH_NOW], 0);
+ }
+ }
+
+ if (rc) {
+ pr_err("%s: Failed to set flash now.\n", __func__);
+ return;
+ }
+
+ flash_led->brightness = brightness;
+}
+
+static enum led_brightness led_gpio_brightness_get(struct led_classdev
+ *led_cdev)
+{
+ struct led_gpio_flash_data *flash_led =
+ container_of(led_cdev, struct led_gpio_flash_data, cdev);
+ return flash_led->brightness;
+}
+
+static int led_gpio_get_dt_data(struct device *dev,
+ struct led_gpio_flash_data *flash_led)
+{
+ int rc = 0;
+ int i = 0;
+ const char *temp_str = NULL;
+ const char *seq_name = NULL;
+ uint32_t array_flash_seq[2];
+ uint32_t array_torch_seq[2];
+ struct device_node *node = dev->of_node;
+
+ flash_led->cdev.default_trigger = LED_TRIGGER_DEFAULT;
+ rc = of_property_read_string(node, "linux,default-trigger",
+ &temp_str);
+ if (!rc)
+ flash_led->cdev.default_trigger = temp_str;
+
+ rc = of_property_read_string(node, "linux,name", &flash_led->cdev.name);
+ if (rc) {
+ pr_err("Failed to read linux name. rc = %d\n", rc);
+ return rc;
+ }
+
+ /* Configure the gpio type as NORMAL_GPIO by default,
+ * the gpio type should be CLK_GPIO if the frequency
+ * is not 0.
+ */
+ flash_led->gpio_type[FLASH_EN] = NORMAL_GPIO;
+ flash_led->gpio_type[FLASH_NOW] = NORMAL_GPIO;
+ rc = of_property_read_u32_array(node, "qcom,clk-freq",
+ flash_led->clk_freq, 2);
+ if (!rc) {
+ if (flash_led->clk_freq[FLASH_EN])
+ flash_led->gpio_type[FLASH_EN] = CLK_GPIO;
+
+ if (flash_led->clk_freq[FLASH_NOW])
+ flash_led->gpio_type[FLASH_NOW] = CLK_GPIO;
+ }
+
+ if (flash_led->gpio_type[FLASH_EN] == NORMAL_GPIO) {
+ flash_led->flash_en =
+ of_get_named_gpio(node, "qcom,flash-en", 0);
+ if (flash_led->flash_en < 0) {
+ pr_err("Read flash-en property failed. rc = %d\n",
+ flash_led->flash_en);
+ return -EINVAL;
+ }
+ rc = gpio_request(flash_led->flash_en, "FLASH_EN");
+ if (rc) {
+ pr_err("%s: Failed to request gpio %d,rc = %d\n",
+ __func__, flash_led->flash_en, rc);
+ return rc;
+ }
+ } else {
+ flash_led->flash_en_clk =
+ devm_clk_get(dev, "flash_en_clk");
+ if (IS_ERR(flash_led->flash_en_clk)) {
+ pr_err("Failed to get flash-en clk.\n");
+ return -EINVAL;
+ }
+
+ flash_led->clk_freq[FLASH_EN] =
+ clk_round_rate(flash_led->flash_en_clk,
+ flash_led->clk_freq[FLASH_EN]);
+ rc = clk_set_rate(flash_led->flash_en_clk,
+ flash_led->clk_freq[FLASH_EN]);
+ if (rc) {
+ pr_err("%s: Failed to set rate for flash en.\n",
+ __func__);
+ return rc;
+ }
+ }
+
+ if (flash_led->gpio_type[FLASH_NOW] == NORMAL_GPIO) {
+ flash_led->flash_now =
+ of_get_named_gpio(node, "qcom,flash-now", 0);
+ if (flash_led->flash_now < 0) {
+ pr_err("Read flash-now property failed. rc = %d\n",
+ flash_led->flash_now);
+ return -EINVAL;
+ }
+ rc = gpio_request(flash_led->flash_now, "FLASH_NOW");
+ if (rc) {
+ pr_err("%s: Failed to request gpio %d,rc = %d\n",
+ __func__, flash_led->flash_now, rc);
+ return rc;
+ }
+ } else {
+ flash_led->flash_now_clk =
+ devm_clk_get(dev, "flash_now_clk");
+ if (IS_ERR(flash_led->flash_now_clk)) {
+ pr_err("Failed to get flash-now clk.\n");
+ return -EINVAL;
+ }
+
+ flash_led->clk_freq[FLASH_NOW] =
+ clk_round_rate(flash_led->flash_now_clk,
+ flash_led->clk_freq[FLASH_NOW]);
+ rc = clk_set_rate(flash_led->flash_now_clk,
+ flash_led->clk_freq[FLASH_NOW]);
+ if (rc) {
+ pr_err("%s: Failed to set rate for flash now.\n",
+ __func__);
+ return rc;
+ }
+ }
+
+ /* Configure the duty cycle if need. */
+ if (flash_led->gpio_type[FLASH_EN] == CLK_GPIO ||
+ flash_led->gpio_type[FLASH_NOW] == CLK_GPIO) {
+ rc = of_property_read_u32_array(node, "qcom,duty-cycle",
+ flash_led->duty_cycle, 2);
+ if (!rc &&
+ flash_led->duty_cycle[FLASH_EN] >= DUTY_CYCLE_BASE &&
+ flash_led->duty_cycle[FLASH_NOW] >= DUTY_CYCLE_BASE) {
+ pr_err("%s: the duty cycle value is invalid.\n",
+ __func__);
+ return -EINVAL;
+ }
+ }
+
+ /* Based on clk protocol, only RCG clks support duty cycle
+ * configuration, so if the used clk doesn't support set duty
+ * cycle, we use the clk's parent rcg clk to configure the
+ * duty cycle.
+ */
+ if (flash_led->duty_cycle[FLASH_EN]) {
+ struct clk *flash_en_duty_cycle_clk = NULL;
+
+ flash_en_duty_cycle_clk = devm_clk_get(dev,
+ "flash_en_duty_cycle_clk");
+ if (!IS_ERR(flash_en_duty_cycle_clk)) {
+ rc = clk_set_duty_cycle(flash_en_duty_cycle_clk,
+ flash_led->duty_cycle[FLASH_EN],
+ DUTY_CYCLE_BASE);
+ clk_put(flash_en_duty_cycle_clk);
+ } else {
+ rc = clk_set_duty_cycle(flash_led->flash_en_clk,
+ flash_led->duty_cycle[FLASH_EN],
+ DUTY_CYCLE_BASE);
+ }
+
+ if (rc) {
+ pr_err("Failed to set duty cycle for flash en.\n");
+ return rc;
+ }
+ }
+
+ if (flash_led->duty_cycle[FLASH_NOW]) {
+ struct clk *flash_now_duty_cycle_clk = NULL;
+
+ flash_now_duty_cycle_clk = devm_clk_get(dev,
+ "flash_now_duty_cycle_clk");
+ if (!IS_ERR(flash_now_duty_cycle_clk)) {
+ rc = clk_set_duty_cycle(flash_now_duty_cycle_clk,
+ flash_led->duty_cycle[FLASH_NOW],
+ DUTY_CYCLE_BASE);
+ clk_put(flash_now_duty_cycle_clk);
+ } else {
+ rc = clk_set_duty_cycle(flash_led->flash_now_clk,
+ flash_led->duty_cycle[FLASH_NOW],
+ DUTY_CYCLE_BASE);
+ }
+
+ if (rc) {
+ pr_err("Failed to set duty cycle for flash now.\n");
+ return rc;
+ }
+ }
+
+ rc = of_property_read_u32_array(node, "qcom,flash-seq-val",
+ array_flash_seq, 2);
+ if (rc < 0) {
+ pr_err("Failed to get flash op seq, rc = %d\n", rc);
+ return rc;
+ }
+
+ rc = of_property_read_u32_array(node, "qcom,torch-seq-val",
+ array_torch_seq, 2);
+ if (rc < 0) {
+ pr_err("Failed to get torch op seq, rc = %d\n", rc);
+ return rc;
+ }
+
+ pr_debug("%s: seq: flash: %d, %d torch:%d, %d\n", __func__,
+ array_flash_seq[0], array_flash_seq[1],
+ array_torch_seq[0], array_torch_seq[1]);
+
+ for (i = 0; i < 2; i++) {
+ rc = of_property_read_string_index(node,
+ "qcom,op-seq", i,
+ &seq_name);
+ CDBG("%s seq_name[%d] = %s\n", __func__, i,
+ seq_name);
+ if (rc < 0) {
+ pr_err("%s failed %d\n", __func__, __LINE__);
+ return rc;
+ }
+
+ if (!strcmp(seq_name, "flash_en")) {
+ flash_led->ctrl_seq[FLASH_EN].seq_type =
+ FLASH_EN;
+ CDBG("%s:%d seq_type[%d] %d\n", __func__, __LINE__,
+ i, flash_led->ctrl_seq[FLASH_EN].seq_type);
+ if (array_flash_seq[i] == 0)
+ flash_led->ctrl_seq[FLASH_EN].flash_on_val =
+ GPIO_OUT_LOW;
+ else
+ flash_led->ctrl_seq[FLASH_EN].flash_on_val =
+ GPIO_OUT_HIGH;
+
+ if (array_torch_seq[i] == 0)
+ flash_led->ctrl_seq[FLASH_EN].torch_on_val =
+ GPIO_OUT_LOW;
+ else
+ flash_led->ctrl_seq[FLASH_EN].torch_on_val =
+ GPIO_OUT_HIGH;
+ } else if (!strcmp(seq_name, "flash_now")) {
+ flash_led->ctrl_seq[FLASH_NOW].seq_type =
+ FLASH_NOW;
+ CDBG("%s:%d seq_type[%d] %d\n", __func__, __LINE__,
+ i, flash_led->ctrl_seq[FLASH_NOW].seq_type);
+ if (array_flash_seq[i] == 0)
+ flash_led->ctrl_seq[FLASH_NOW].flash_on_val =
+ GPIO_OUT_LOW;
+ else
+ flash_led->ctrl_seq[FLASH_NOW].flash_on_val =
+ GPIO_OUT_HIGH;
+
+ if (array_torch_seq[i] == 0)
+ flash_led->ctrl_seq[FLASH_NOW].torch_on_val =
+ GPIO_OUT_LOW;
+ else
+ flash_led->ctrl_seq[FLASH_NOW].torch_on_val =
+ GPIO_OUT_HIGH;
+ }
+ }
+
+ return rc;
+}
+
+static int led_gpio_flash_probe(struct platform_device *pdev)
+{
+ int rc = 0;
+ struct led_gpio_flash_data *flash_led = NULL;
+
+ flash_led = devm_kzalloc(&pdev->dev, sizeof(struct led_gpio_flash_data),
+ GFP_KERNEL);
+ if (flash_led == NULL)
+ return -ENOMEM;
+
+ flash_led->pinctrl = devm_pinctrl_get(&pdev->dev);
+ if (IS_ERR(flash_led->pinctrl)) {
+ pr_err("%s:failed to get pinctrl\n", __func__);
+ rc = PTR_ERR(flash_led->pinctrl);
+ goto error;
+ }
+
+ flash_led->gpio_state_default = pinctrl_lookup_state(flash_led->pinctrl,
+ "flash_default");
+ if (IS_ERR(flash_led->gpio_state_default)) {
+ pr_err("%s:can not get active pinstate\n", __func__);
+ rc = -EINVAL;
+ goto error;
+ }
+
+ rc = pinctrl_select_state(flash_led->pinctrl,
+ flash_led->gpio_state_default);
+ if (rc) {
+ pr_err("%s:set state failed!\n", __func__);
+ goto error;
+ }
+
+ rc = led_gpio_get_dt_data(&pdev->dev, flash_led);
+ if (rc) {
+ pr_err("%s: get device tree data failed.\n",
+ __func__);
+ goto error;
+ }
+
+ /* Add these atomic variables to make sure clk is disabled
+ * just after the clk has been enabled.
+ */
+ atomic_set(&flash_led->clk_enabled[FLASH_EN], 0);
+ atomic_set(&flash_led->clk_enabled[FLASH_NOW], 0);
+
+ platform_set_drvdata(pdev, flash_led);
+ flash_led->cdev.max_brightness = LED_FULL;
+ flash_led->cdev.brightness_set = led_gpio_brightness_set;
+ flash_led->cdev.brightness_get = led_gpio_brightness_get;
+
+ rc = led_classdev_register(&pdev->dev, &flash_led->cdev);
+ if (rc) {
+ pr_err("%s: Failed to register led dev. rc = %d\n",
+ __func__, rc);
+ goto error;
+ }
+ pr_err("%s:probe successfully!\n", __func__);
+ return 0;
+
+error:
+ if (flash_led->gpio_type[FLASH_EN] == CLK_GPIO &&
+ IS_ERR(flash_led->flash_en_clk))
+ devm_clk_put(&pdev->dev, flash_led->flash_en_clk);
+ else if (flash_led->gpio_type[FLASH_EN] == NORMAL_GPIO &&
+ flash_led->flash_en)
+ gpio_free(flash_led->flash_en);
+
+ if (flash_led->gpio_type[FLASH_NOW] == CLK_GPIO &&
+ IS_ERR(flash_led->flash_now_clk))
+ devm_clk_put(&pdev->dev, flash_led->flash_now_clk);
+ else if (flash_led->gpio_type[FLASH_NOW] == NORMAL_GPIO &&
+ flash_led->flash_now)
+ gpio_free(flash_led->flash_now);
+
+ if (IS_ERR(flash_led->pinctrl))
+ devm_pinctrl_put(flash_led->pinctrl);
+
+ devm_kfree(&pdev->dev, flash_led);
+ return rc;
+}
+
+static int led_gpio_flash_remove(struct platform_device *pdev)
+{
+ struct led_gpio_flash_data *flash_led =
+ (struct led_gpio_flash_data *)platform_get_drvdata(pdev);
+ if (IS_ERR(flash_led->pinctrl))
+ devm_pinctrl_put(flash_led->pinctrl);
+ led_classdev_unregister(&flash_led->cdev);
+ devm_kfree(&pdev->dev, flash_led);
+ return 0;
+}
+
+static struct platform_driver led_gpio_flash_driver = {
+ .probe = led_gpio_flash_probe,
+ .remove = led_gpio_flash_remove,
+ .driver = {
+ .name = LED_GPIO_FLASH_DRIVER_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = led_gpio_flash_of_match,
+ }
+};
+
+static int __init led_gpio_flash_init(void)
+{
+ return platform_driver_register(&led_gpio_flash_driver);
+}
+
+static void __exit led_gpio_flash_exit(void)
+{
+ return platform_driver_unregister(&led_gpio_flash_driver);
+}
+
+late_initcall(led_gpio_flash_init);
+module_exit(led_gpio_flash_exit);
+
+MODULE_DESCRIPTION("QTI GPIO LEDs driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("leds:leds-msm-gpio-flash");
diff --git a/include/linux/clk/msm-clk.h b/include/linux/clk/msm-clk.h
index baa8e52..f442538 100644
--- a/include/linux/clk/msm-clk.h
+++ b/include/linux/clk/msm-clk.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2009, 2012-2017, 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
@@ -55,6 +55,11 @@
/* Set clock-specific configuration parameters */
int clk_set_flags(struct clk *clk, unsigned long flags);
+/* Set clock duty-cycle as a ratio of numerator/denominator for the desired
+ * duty cycle
+ */
+int clk_set_duty_cycle(struct clk *clk, u32 numerator, u32 denominator);
+
/* returns the mux selection index associated with a particular parent */
int parent_to_src_sel(struct clk_src *parents, int num_parents, struct clk *p);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index e8d577af..25bd83b 100755
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -8972,6 +8972,7 @@
if (nla_get_flag(info->attrs[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT])) {
if (!info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
+ kzfree(connkeys);
return -EINVAL;
}
connect.flags |= CONNECT_REQ_EXTERNAL_AUTH_SUPPORT;